Sniff is a "Scratch-like" programming language that's designed to help Scratchers move gently from Scratch to more conventional languages. They can start writing programs, without having to learn a new language because Sniff is based on Scratch. They learn a little more about variables, compiling, syntax errors (!), and they can have fun controlling real hardware while they're doing it.

Thursday, 13 October 2016

MQTT Part 2: Embedded!

MQTT is pretty handy for letting Sniff programs communicate just running on computers, but its real purpose is to pass messages between embedded devices like Arduino's which are sitting on the network, doing a single simple task - either measuring something (a temperature sensor?), or controlling something (a heating valve?).

The current Sniff implementation of MQTT runs great on Arduino, and it should run on other systems like MBED, though we've not had a chance to try that out yet. It requires a Wiznet5100 based ethernet interface, like the Arduino Ethernet Shield. Support to other network devices "real soon now".

So if you grab an Arduino, an Ethernet shield, and already have an MQTT broker set up from the previous tutorial, we'll begin.

Setup

First we need to set up the ethernet device:

make spi device
make ethernet device D10
make networkMAC string "b6:ee:63:ed:95:cb"
make networkIP string "192.168.0.200"
make networkConnected boolean
make networkPort number
make networkPeer string

Note that we also made an SPI device to handle the low level hardware, and we're using D10 as the select pin for the WizNet (as per Ethernet Shield). These chips come without a Mac address, so you'll need to generate one. It doesn't really matter what it is, but it has to be unique, so every board has its own. You also need an IP address, which you should get from your network administrator.

Subscribe

With that done, everything else is pretty much as it was previously.

make mqtt device
make clientid string
make message string
make topic string

when start
.set clientid to networkMAC
.set networkPeer to "192.168.0.108" #No DNS on Arduino!
.repeat until networkConnected
..tell mqtt to "connect"
.
.say "connected"
.
.set topic to "text"
.tell mqtt to "subscribe"
.forever
..tell mqtt to "loop"
..if not message = ""
...say message

I've done a couple of things slightly different, just because we're not running on a computer. First off I've used the MAC address as the clientID - you don't have to, but its a good way to ensure you've got a unique value. Next, I've used the raw IP address of the server rather than its hostname, as we don't have an easy way to look it up like we do on a "real" computer. In the desktop version I tried to connect, and gave up if I failed, but on an embedded device, we probably just want to keep trying until it works, which is what I've done here.

Control

Of course the real fun comes when we hook up some other hardware:

make i2c device
make display lcdi2c device 2 #2 line display
make displayFlush boolean

when start
etc
.
.forever
..tell mqtt to "loop"
..if not message = ""
...tell display to "show"

Now we're pushing the receive message onto an LCD screen connected via i2c. That's all it takes to do something really useful and exciting - now you can publish messages from any client, and they appear on the screen. You could have 1 screen, and dozens of sensors pushing alert messages to it, or dozens of screens with a central server sending messages to a dozen subscribers... or a thousand! This is essentially the architecture that bus and railway digital info boards would use.

You can publish from Arduino just as you would from the desktop too - once setup, MQTT works identically on both platforms, so setting up a sensor and publishing the results to the world is about as easy as it gets! However there are a few more tricks still to learn, so there's at least one more MQTT post to go...

No comments:

Post a Comment