Wednesday, March 18, 2015

Using HotPaw Basic with a LightBlue Bean Bluetooth LE device

HotPaw Basic 1.7.1 for iOS now includes direct support for communication with the LightBlue Bean.

This example HotPaw Basic program below lets you scan for Bluetooth LE devices, select a Bean, connect to it, blink the LED blue, read scratch bank 3, and read the temperature. Note that 1 or 2 second waits between all Bluetooth commands can be helpful or necessary (depending on your device model and how busy it is, etc.)

100 rem
102 print "starting scan for Beans"
120 fn bean.init()
140 fn sleep(1)
160 fn bean.list()
180 b$ = fn bean.selected()
190 print b$
192 if len(b$) < 20 then print "no bean selected" : end
200 fn bean.connect(1,b$)
210 for i = 1 to 20 : rem wait for bean to connect
212   if fn bean.connect(1) > 0 then exit for
214   fn sleep(0.5)
216 next i
220 print fn bean.name(1)
230 fn bean.led(1,0,0,1) :rem blink blue
246 fn bean.temp() :rem start temperature read
260 fn sleep(1)
270 fn bean.led(1,0,0,0) :rem off
280 fn sleep(1) : rem wait
300 fn bean.rdsc(1,3,0) :rem start scratch read
310 fn sleep(1)
320 s$ = fn bean.rdsc(1,3,1) :rem as a string
322 print len(s$),s$
340 s$ = fn bean.rdsc(1,3,16) :rem as a hex string
342 print len(s$),s$
374 print fn bean.temp()
950 fn sleep(1)
960 fn btle(9) :rem disconnect bluetooth devices
970 print "done"
990 end

Combine this with the MQTT sample app (from in an earlier post in this blog), and you can have your Bean send messages over the internet, using an iOS device as the relay to a broker.

The Bean serial protocol is also supported, see HotPaw Basic's built-in documentation for details. But don't expect a data rate much higher than 2400 baud (due to restrictions involving iOS built-in power saving and WiFi/BLE antenna sharing modes, etc.), so make sure your app sleeps a bit between sending small chunks of serial data.

Using HotPaw Basic with Bluetooth 4.0/BLE/BTLE devices

Bluetooth LE is a great way to get data from external sensors into your iPhone, and without needing any wires or cables. Bluetooth LE, also known as Bluetooth 4.0, BTLE or BLE, is a standardized short-range wireless communications protocol, designed so the tiny sensors can run for weeks to years on just a coin cell battery (or less!). It's now used by such devices as newer heart rate monitors and fitness trackers.

Here's a tutorial on BTLE (written by a former colleague of mine) with far more details: http://chapters.comsoc.org/vancouver/BTLER3.pdf

One inexpensive BTLE device, usable for experimentation, is the TI SensorTag (around $25 or $30 from TI), smaller than a matchbook, that contains tons of sensors. Another very popular device is the LightBlue Bean, which contains a programmable Arduino processor and a thermometer, as well as a BTLE radio. Runs on a 2032 coin cell and small enough that it ships in a matchbox.

Here's an example of connecting to the TI SensorTag using HotPaw Basic, and getting notified by any change in the status of button 1.

100 rem
120 fn btle.init()
130 fn sleep(2)
140 status = fn btle.list()
150 print status
160 if status < 0 then print "BTLE is off!" : end
170 uuid$ = fn btle.selected()
180 if len(uuid$ < 2) then print "No tag selected" : end
400 print "SensorTag Found!"
410 servic$ = "FFE0"
420 charac$ = "FFE1"
440 fn btle.connect(1,uuid$,servic$,charac$)
450 fn sleep(1)
460 print fn btle.connect(1) : rem connection status
500 dim r%(256) : rem array for characteristic data
520 while (1)
530   fn sleep(0.5)
540   n = fn btle.responsedata(1,1,r%(0))
550   if (n > 0)
560     print n,r%(0)
570   endif
582   if fn touch(0) > 0 then exit while
590 wend
950 fn btle.connect(-1) :rem disconnect
960 print "done"
990 end
Tap the display with 2 fingers to exit the while loop.

HotPaw Basic now supports MQTT messaging

MQTT support has been added to HotPaw Basic version 1.7.1 for iOS.

What is MQTT? It's one of the hottest new technologies for the Internet of Things. MQTT is a lightweight messaging protocol, where short messages, such as number from a temperature sensor, can get relayed though servers in the cloud, called Brokers. These messages can be relayed to an app somewhere else, such as the iPhone of someone on the road who want to check the latest home temperature reading. IBM is one of the major vendors supporting MQTT.

MQTT is "light-weight", meaning there's a lot less bits and bytes of overhead that need to get passed back and forth to send a message, much less than needed for accessing even a tiny web page. This makes MQTT more suitable for button-sized devices which can run off a tiny battery for over a year.

To send a message using MQTT, one needs to initialize a few details. You need to know at least two things so that the message knows where to start heading: the name of a MQTT host server in cloud and a port number for that broker. Optionally you will need a username and password a private broker, or for one of many MQTT brokers run as commercial services. IBM, cloudmqtt.com and hivemq.com provide commercial MQTT broker services. You can use Google to find "public MQTT brokers", or you can run a broker on your own server (even a Raspberry Pi). There are currently a few public brokers available for testing which need no password. One such is: "iot.eclipse.org", port 1883. Please don't use public brokers for more than a small amount of basic testing. Note that any the data one might send thru these public brokers is, well, completely public.

One needs to know 2 more things to identify the sending device and the message. A unique client ID helps the broker to not get confused between zillions of device trying to talk to it. IBM uses a MAC address as a unique ID. You can look up the MAC address for your iPhone in Settings:General:About:WiFi Address. You will also need a identifying topic so that a subscriber can find your devices messages out of the zillions of other messages sent by zillions of other devices. This is a short hierarchical string separated by slashes, such as "sample.corp/london.office/building.3/room.4/temperature".

And last, there is your short message itself, usually just a few characters, although IBM would like it packed into a JSON formatted string.

Here's an example HotPaw Basic program to send a message to an MQTT server.

100 rem MQTT test send
200 host$ = "iot.eclipse.org" :rem a public MQTT broker
210 port = 1883
220 client$ = "12345678" :rem Please put you MAC ADDR here.
300 fn mqtt.connect(host$,port,client$)
310 fn sleep(1)
320 print fn mqtt.connected()
400 topic$ = "hotpaw/test/randomdata/0"
410 msg$ = "hello 123"
500 fn mqtt.publish(topic$,msg$,1)
900 fn mqtt.disconnect()
910 print "done"
990 end

The JSON formatted version of the message would look more like this:

410 temperature = 22.5
412 msg$ = '{ "d": {"myName":"Arduino","temperature":'
414 msg$ = msg$ + str$(temperature) + " } }"

There are a few MQTT apps in the App store that can be used to check your message.

To see the message, you could run this HotPaw Basic program on another iOS device. Since these messages are relayed though a remote broker, the 2 iOS devices don't need to be on the same local network.

100 rem MQTT test subscribe
200 host$ = "iot.eclipse.org"
210 port = 1883
220 client$ = "12345678" :rem Please put you MAC ADDR here.
300 fn mqtt.connect(host$,port,client$)
310 fn sleep(1)
320 print fn mqtt.connected()
400 topic$ = "hotpaw/test/randomdata/0"
500 fn mqtt.subscribe(topic$)
520 for i = 1 to 10
530   fn sleep(10) : rem waits for message
535   print ".";
540   r$ = fn mqtt.message$()
560   if len(r$) > 0 then print : print "message = ", r$
570   if len(r$) > 0 then exit for
590 next i
900 fn mqtt.disconnect()
910 print "done"
990 end