What I Did in January

January turned out to be a good time for tidying up my gitHub repos, because it was cold and there was no incentive to travel, and I had to quarantine for a few days in the midst of it (no symptoms, thankfully). As a result, I updated a few things. All of this is going into my connected devices class this semester.

Just enough HTML for Connected Devices – If a device connects to your phone or laptop, you’re going to need to build an interface for it at some point, and the Document Object Model (HTML/CSS/JavaScript) is a quick way to do it. I put together some examples for various ways to do that. Most of this is a thin wrapper around the Mozilla Developer Network pages, with a focus on connecting. A couple of highlights:

MQTT Examples – I’ve been working on this one since last summer in bits and pieces, but now there’s enough there to be useful. All microcontroller examples were written with the Arduino Nano 33 IoT, though any of the WiFi-enabled Arduinos should do the trick. The browser-based stuff is all in p5.js, but I’ll add some plain vanilla JS examples soon. There are some nice GUI tools available now too, like MQTT Explorer and shiftr.io’s desktop broker. My favorite example in this repo is the WebMIDI to MQTT examples.

Websocket Examples – nothing special here, but the topic comes up enough that having a set of examples on hand was something I needed. Easy to compare and contrast Websockets and MQTT now too. A lot of folks don’t know the ArduinoHTTPClient library can also do websockets, so I threw that in.

Pi Recipes – this is an older repo, but I updated it to make it a bit easier to find things. Quite pleased with the timelapse webcam example that Nun Tansrisakul inspired me to write.

WiFi101/WiFiNINA Examples – another older repo, but a bit better organized now, I hope. Moved some things to their own repos when it was merited.

Display Examples – still working on this one, but I got obsessed with making QR code examples from an Arduino, so I wrote something using Richard Moore’s arduino qrcode library, then duplicated it for ePaper, TFT, and OLED screens. Figured it was as good a time as any to put together what experience I have working with screens and microcontrollers.

HID Examples – not prettied up yet, but put together a few more notes on using the HID examples for Arduino.

Node Examples – also not prettied up yet, but added notes for using these on Glitch or on a CLI.

Serial Communication: Sending a 10-Bit (or two-byte) Value

When communicating between a microcontroller and a personal computer using asynchronous serial communication, you often need to transmit a value that is greater than 255. For example, if you want to send the value from a 10-bit analog-to-digital converter (e.g. the result from the Arduino analogRead() command) as a binary value, here’s how you do it:

int sensor = analogRead(A0);

The int data type of this variable takes multiple bytes in the Arduino’s memory. Reading the value 1023 from the ADC, for example, this is the arrangement of the bits in the bytes in memory:

first bytesecond byte
Bit values of the byte:0 0 0 0 0 0 1 11 1 1 1 1 1 1 1
Decimal value of the byte3255

To separate the original value into two bytes, you divide by 256 to get the first byte, and take the remainder (or modulo) to get the second byte. For example, 1023 / 256 = 3, remainder 255. You can see this in the Arduino code below. To send this value as two bytes from Arduino, you do the following:

 // get a 10-bit ADC value:
  int sensor = analogRead(A0);
  // divide by 256 to get the first byte:
  // (result is an integer):
  byte firstByte = sensor / 256;
  // modulo by 256 to get the second byte:
  byte secondByte = sensor % 256;
  // send the first of the two bytes:
  Serial.write(firstByte);
  // send the second of the two bytes:
  Serial.write(secondByte);

When you receive this on the personal computer, you need to combine the two bytes back into a single value. To do this, you multiply the first byte by 256, then add the second byte. For example, 3 * 256 + 255 = 1023. Here’s how to do it in p5.js using p5.serial;ort:

  // wait until you have two bytes:
  if (serial.available() >= 2) {
    // read the first byte:
    var highByte = serial.read();
    // read the second byte:
    var lowByte = serial.read();
    // combine them into a single value:
    var result = (highByte * 256) + lowByte;
    // put the result in the text div:
    console.log("high byte: " + highByte +
      "  low byte: " + lowByte +
      "  result: " + result);
  }

Here are the two full sketches for both Arduino and p5.js:

Arduino:

void setup() {
  Serial.begin(9600);
}

void loop() {
  // get a 10-bit ADC value:
  int sensor = analogRead(A0);
  // divide by 256 to get the first byte:
  // (result is an integer):
  byte firstByte = sensor / 256;
  // modulo by 256 to get the second byte:
  byte secondByte = sensor % 256;
  // send the first of the two bytes:
  Serial.write(firstByte);
  // send the second of the two bytes:
  Serial.write(secondByte);
}

The p5.js sketch:

// variable to hold an instance of the serialport library:
let serial;
// HTML Select option object:
let portSelector;


function setup() {
  // new instance of the serialport library
  serial = new p5.SerialPort();
  // callback function for serialport list event
  serial.on('list', printList);
  // callback function for serialport data event
  serial.on('data', serialEvent);
  // list the serial ports
  serial.list();
  textDiv = createDiv('result will go here.')
}

// make a serial port selector object:
function printList(portList) {
  // create a select object:
  portSelector = createSelect();
  portSelector.position(10, 10);
  // portList is an array of serial port names
  for (var i = 0; i < portList.length; i++) {
    // add this port name to the select object:
    portSelector.option(portList[i]);
  }
  // set an event listener for when the port is changed:
  portSelector.changed(mySelectEvent);
}


function mySelectEvent() {
  let item = portSelector.value();
  // give it an extra property for hiding later:
  portSelector.visible = true;
  // if there's a port open, close it:
  if (serial.serialport != null) {
    serial.close();
  }
  // open the new port:
  serial.open(item);
}


function serialEvent() {
  // if you have received two or more bytes:
  if (serial.available() >= 2) {
    // read the first byte:
    var highByte = serial.read();
    // read the second byte:
    var lowByte = serial.read();
    // combine them into a single value:
    var result = (highByte * 256) + lowByte;
    // put the result in the text div:
    console.log("high byte: " + highByte +
      "  low byte: " + lowByte +
      "  result: " + result);
  }
}

Here’s the index.html page:

<!DOCTYPE html><html lang="en"><head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js" integrity="sha512-WIklPM6qPCIp6d3fSSr90j+1unQHUOoWDS4sdTiR8gxUTnyZ8S2Mr8e10sKKJ/bhJgpAa/qG068RDkg6fIlNFA==" crossorigin="anonymous"></script>
  <script language="javascript" type="text/javascript" src="https://cdn.jsdelivr.net/npm/p5.serialserver@0.0.29/lib/p5.serialport.js"></script>
    <meta charset="utf-8">
  </head>
  <body>
    <script src="sketch.js"></script>
</body></html>

You will also need the p5.serialcontrol app to connect the sketch in a browser to the serial port.

Glitch and p5.js and p5.serialport

David Bouchard of Ryerson University gave me a great tip: Glitch.com works well for p5.js projects. It’s a nice alternative to the p5.js editor, particularly because it supports sharing of live code. This can be handy when you’re working remotely with others. This means you and your remote partner can both be typing in the same sketch in real-time (well, network real-time).

It even works with p5.serialport library and the p5.serialcontrol app if you want to work on p5.js sketches that require asynchronous serial input. Each person sharing the sketch will be running a local instance of the sketch in their own browser. This means they will be able to connect with their local copy of p5.serialcontrol, to communicate with their own serial ports.

Here are the steps to make a p5.js serialport app work:

  • Set up a Glitch account if you don’t already have one.
  • Make a new project in Glitch. Use the “Hello Webpage” option
  • Replace the default HTML with the following:
<!DOCTYPE html><html lang="en"><head>
  <script src="p5.min.js"></script>
  <script src="p5.serialport.js"></script>
  </head>
  <body>
    <script src="sketch.js"></script>
</body></html>
  • Replace the two script tags with the latest CDN links for p5.js and p5.serialport.js. The p5.js CDN can be found at this link. The p5.serialport latest version is 0.0.29, as of this writing:
<script src="https://cdn.jsdelivr.net/npm/p5.serialserver@0.0.29/lib/p5.serialport.js"></script>
  • Replace the script.js file with a file called sketch,js and make it a p5.js sketch. Here’s the minimum:
function setup() {
  
}

function draw() {
 
}
  • Download the p5.serialcontrol app, connect to a microcontroller over a serial port, and you’re ready to go.
  • Once you’ve made your sketch click Share -> Code and share that link with your remote partner. That’s it! You’re ready to go.

To test this, I made a sketch that creates a serialport object, then gets the list of serial ports and makes a select menu so you can choose the serial port. Feel free to use it.

This Week in Code: MQTT Fun

Work’s been quite busy lately, with several things going on at once, and few things completed. Many pieces of what I am doing are scattered over the web, on my gitHub account, my various class sites, etc. Since I’m expecting students to keep a blog in my classes, I thought it might be useful to revive my own blogs as a place to keep track of some of the projects I’m in the midst of.

I’ve been having a good time making examples using the Message Queueing Telemetry Transfer (MQTT) protocol lately. MQTT is a lightweight networking protocol used in many industrial networking (read: internet of things) applications. There are a number of good libraries out there for it on a variety of platforms, and a couple of useful public brokers (read: servers) that you can test your apps with, like shiftr.io and mosquitto.org. I like Shiftr because of the fancy motion graphic (okay, call me shallow). I’ve got examples for Arduino using the ArduinoMqttClient library and p5.js using the Eclipse PAHO library. I just added one using p5.serialport as well, so you can connect Arduino projects to each other through p5.serialport -> p5.js -> MQTT.

MKR GSM 1400 Pre-flight Checklist

I’ve been getting to know the MKR GSM 1400 boards better the past few days, and in the process I’ve assembled a “pre-flight checklist” of things you’ll want to do first, in order to make sure everything is ready to go. It took a few errors and missteps to get here, so I’ll mention those along the way.

Make sure you have an antenna attached

I thought “I’ll be fine just to test, there’s good service in my city.” Wrong. Attach an antenna. You’ll need it to get a good signal even in a well-covered area. The GSM Antenna sold on the Arduino Store works well, though any GSM antenna with a SMA male connector should work.

Get a SIM card

I used Hologram.io, thanks to recommendations from the rest of the Arduino team and Don Coleman. Their Hologram Maker Edition service is affordable and easy to use. When you do set up an account, get a SIM card of course, and assign a phone number to it. That’s optional for their service, but needed if you want to send and receive SMS messages or phone calls.

You’ll also want to take note of the Device ID, APN info, and Device Key. You’ll need those later. When accessing GPRS services through the MKR 1400, the login is the Device ID and the password is the Device Key.

Download MKRGSM library

You can find this in the Arduino IDE’s LIbrary Manager. When you install it, you’ll get a new set of example sketches in the File Menu, Examples submenu called MKRGSM. You’ll need to have the right board chosen in the Tools menu (MKR 1400) in order for these examples to show up in the Examples submenu, though.

Run the TestModem Sketch

Click the File Menu, Examples submenu, MKRGSM submenu, Tools submenu to find the TestModem sketch. Upload this to your board and open the Serial Monitor. You should get the following output:

Starting modem test…

Then a slight delay, followed by:

modem.begin() succeeded
Checking IMEI…Modem's IMEI: XXXXXXXXXXXXXXX
Resetting modem…Modem is functoning properly

Your IMEI will be unique to your board, it’s the International Mobile Equipment Identifier. It’s written on the MKR1400, and encoded in the QR code there as well.

If you don’t get these messages, check that your SIM card is inserted properly, and that you’ve chosen the right board and serial port. Then upload the sketch again.

Run the BandManagement sketch

Click the File Menu, Examples submenu, MKRGSM submenu, Tools submenu to find the BandManagement sketch. Upload this to your board and open the Serial Monitor. You should get the following output:

Restarting modem…

Then a slight delay followed by:

Modem restarted.
Current band:EGSM_DCS_MODE
Want to change the band you’re on?
Select band:
1 : E-GSM(900)
2 : DCS(1800)
3 : PCS(1900)
4 : E-GSM(900)+DCS(1800) ex: Europe
5 : GSM(850)+PCS(1900) Ex: USA, South Am.
6 : GSM(850)+E-GSM(900)+DCS(1800)+PCS(1900)

Choose the right band for your region of the world. If you pick the wrong region, the MKR1400 will never connect to a network. I puzzled over this for several minutes before I thought to check the band, as I was in the US and the board came from Europe. Type the correct number in the Serial Monitor’s input field, then hit enter. You should get:

Configuring band GSM850_PCS_MODE

Or whatever mode is appropriate to your region. Then after a few seconds:

Success

Run the ScanNetworks sketch

Click the File Menu, Examples submenu, MKRGSM submenu, Tools submenu to find the GsmScanNetworks sketch. If your SIM card requires a PIN, enter it in the arduino_secrets.h tab. Upload this to your board and open the Serial Monitor. You should get the following output:

GSM networks scanner

Then a longer delay followed by:

Modem IMEI: XXXXXXXXXXXXXXX
Scanning available networks. May take some seconds.
Current carrier: T-Mobile
Signal Strength: 5 [0-31]
Scanning available networks. May take some seconds.
Current carrier: T-Mobile
Signal Strength: 5 [0-31]
Scanning available networks. May take some seconds.

This should be the first sketch that connects your MKR 1400 to the mobile network, so make sure you have an antenna attached. Your carrier name and signal strength will vary, of course. The scanning will run continually.

Once you see this, you know you’re on the mobile network. Now the fun begins.

Run the SendSMS sketch

Click the File Menu, Examples submenu, MKRGSM submenu, to find the SendSMS sketch. If your SIM card requires a PIN, enter it in the arduino_secrets.h tab. Upload this to your board and open the Serial Monitor. You should get the following output:

SMS Messages Sender

Then a delay followed by:

GSM initialized
Enter a mobile number:

Type your mobile phone number into the Serial Monitor’s input field, including the country code. For example, a typical US number would be +15551212. Then type enter. You should get the following output:

+15551212
Now, enter SMS content:

Type a message, something like this:

I like aardvarks and okapi, don't you too?

You should get the following output:

Message:
I like aardvarks and okapi, don't you too?

COMPLETE!

Enter a mobile number:

You should get the text on your phone number too, of course. Note that the sending phone number may not be the one associated with your SIM. This will depend on your carrier. Send a few more until you’ve exhausted that fun.

Run the ReceiveSMS sketch

Click the File Menu, Examples submenu, MKRGSM submenu, to find the ReceiveSMS sketch. If your SIM card requires a PIN, enter it in the arduino_secrets.h tab. Upload this to your board and open the Serial Monitor. You should get the following output:

SMS Messages Receiver

Then a delay followed by:

GSM initialized
Waiting for messages

Send a text message from your mobile phone to the number associated with your SIM card. You should get the following output:

Message received from:
+15551212
Oh, and llamas and bonobos are quite nice too.
END OF MESSAGE
MESSAGE DELETED

Now you know you’re successfully sending and receiving messages from the mobile network. Finally, test GPRS connectivity:

Run the GsmSSLWebClient sketch

Click the File Menu, Examples submenu, MKRGSM submenu, to find the GsmSSLWebClient sketch. Click the arduino_secrets.h tab and enter your APN info, login, and password. From Hologram.io, you hologram for the APN, use the Device ID as login and generate a Device Key as password. Hologram SIMs do not require a PIN. Check with your mobile provider for details on your own SIM. Upload this to your board and open the Serial Monitor. You should get the following output:

Starting Arduino web client.

Then a longer delay followed by:

connecting…
connected
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 19 Mar 2019 13:48:40 GMT
Content-Type: text/plain
Content-Length: 2263
Last-Modified: Wed, 02 Oct 2013 13:46:47 GMT
Connection: close
Vary: Accept-Encoding
ETag: "524c23c7-8d7"
Accept-Ranges: bytes
`:;;;,` .:;;:. .;;;;;;;;;;;` :;;;;;;;;;;: TM `;;;;;;;;;;;;;;;` :;;;;;;;;;;;;;;; :;;;;;;;;;;;;;;;;;; `;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;; .;;;;;;;;;;;;;;;;;;;;
;;;;;;;;:;;;;;;;;; ,;;;;;;;;..;;;;;;;; .;;;;;;, :;;;;;;; .;;;;;;; ;;;;;;; ;;;;;; ;;;;;;; ;;;;;;, ;;;;;;. ,;;;;; ;;;;;;.;;;;;; ;;;;;;
;;;;;. ;;;;;;;;;;;``` ;;;;;
;;;;; ;;;;;;;;;, ;;; .;;;;;
;;;;:;;;;;;;; ;;; ;;;;;
,;;;;,,,,,,,, ;;;;;;; .,,;;;,,, ;;;;;
:;;;;.;;;;;;;; ;;;;;, :;;;;;;;; ;;;;; :;;;; .;;;;;;;; ;;;;;; :;;;;;;;; ;;;;; .;;;;. ;;;;;;;. ;;; ;;;;; ;;;;; ;;;;;;;;; ;;; ;;;;; ;;;;; .;;;;;;;;;; ;;; ;;;;;, ;;;;;;;;;;;;;;;;;; ;;;;;
;;;;;, .;;;;;; ;;;;;;; ;;;;;; ;;;;;;: :;;;;;;. ;;;;;;; ;;;;;; ;;;;;;; .;;;;;;;, ;;;;;;;; ;;;;;;;:
;;;;;;;;;:,:;;;;;;;;;: ;;;;;;;;;;:,;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;. ;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;; :;;;;;;;;;;;;;;;;: ,;;;;;;;;;;;;;, ;;;;;;;;;;;;;; .;;;;;;;;; ,;;;;;;;;:
;;; ;;;;;` ;;;;: .;; ;; ,;;;;;, ;;. `;, ;;;; ;;; ;;:;;; ;;;;;; .;; ;; ,;;;;;: ;;; `;, ;;;:;;
,;:; ;; ;; ;; ;; .;; ;; ,;, ;;;,;, ;; ;; ;; ;: ;; ;; ;; ;; .;; ;; ,;, ;;;;;, ;; ;;.
;: ;; ;;;;;: ;; ;; .;; ;; ,;, ;;;;;, ;; ;;
,;;;;; ;;;; ;; ;; .;; ;; ,;, ;; ;;;, ;; ;; ;; ,;, ;; .;; ;;;;;: ;;;;;: ,;;;;;: ;; ;;, ;;;;;; ;; ;; ;; ;; ;;;;. `;;;: ,;;;;;, ;; ;;, ;;;;
disconnecting.

That text will appear as the ASCII-encoded Arduino logo in your Serial Monitor. Now you know you’ve got GPRS working, and should have enough functionality to proceed with your own sketches.

The MKRGSM library is based on similar principles as the WiFi101 and WiFiNINA libraries. Once you connect to the network, you use a variety of classes to do your business. The SMS class functions a bit like the Serial class, in that it’s based on the Stream class, so you can do things like see how many bytes are available(), you can read() and write(), and so forth. The GSMClient and GSMSSLClient classes function just like the TCP client classes in the WiFi libraries. Check the MKRGSM library documentation for more detail.

Programming a Christmas Tree

As we planned for Christmas this year, my partner suggested that maybe we should replace the lights for the tree. “While we’re at it,” she asked, “is there anything out there that’s more controllable than just the ones that twinkle on and off?”

“Well,” I said, “there are NeoPixels…”

We decided that it would be great to have a tree where the lights looked and acted like candles, flickering gently in a soft, warm glow, and fading from a bright orange down to a low reddish glow by the end of the evening. We also wanted to realize the cheesy quote from It’s A Wonderful Life that “every time a bell rings, an angel gets its wings.”

Here’s a timelapse of the tree in action:

When you ring the bell, this happens:

The process of making it gave a chance to work with:

You can find the code and circuit in the gitHub repository for this project.
Continue reading “Programming a Christmas Tree”

Node.js on the Arduino Yún

Recently, Federico Fissore added node.js to the package repository for the Arduino Yún. Here’s how you get node to communicate with the Arduino processor on the Yún via the Bridge library.

To do this, you’ll need an Arduino Yún, a microSD card, a microUSB cable and a wifi connection. You should be familiar with the basics of the Arduino Yún and node.js in order to get the most out of this post.

All of the code for this post can be found on my GitHub repository.

Continue reading “Node.js on the Arduino Yún”

What is “Real-Time”, Anyway?

Recently, a colleague of mine was working on a project with an Arduino Yún that involved reading a lot of sensor data using the Yún’s Arduino processor and writing it to the microSD card via the board’s Linux processor to be served to other devices via HTTP. She found that it took anywhere from 20 milliseconds  to several seconds to get the data from the sensors written to the SD card. “Why is it not real-time?” she asked me.

Welcome to the world of embedded operating systems. They are not realtime. “Realtime” can mean many things. In automotive systems, for example, your car’s braking system had better react in “realtime” or you’re dead. That might mean only a couple of milliseconds. When measuring high-speed rotation, it might even mean microseconds.

My colleague was measuring her function’s response time in tens to hundreds of milliseconds. That function read one controller’s analog input pin, sent the result via asynchronous serial to another controller, and then stored the result on an SD card. I haven’t measured it, but I’d wager you’ll see the same response times on a BeagleBone or Raspberry Pi, or any embedded Linux board.  Here’s why:

All computers run programs. In a microcontroller like the Arduino, there’s only one program running. That program is made up of instructions stored in memory, in a particular order. The computer moves through those instructions one at a time. Sometimes it jumps around in the

At the electrical level, all computers are made up of transistors, so in computing, the fastest version of “realtime” means “how fast can you read and act on a changing voltage on a transistor?” Some of the input/output pins of a microcontroller are usually hardware interrupt pins, meaning that they can be programmed such that if there’s a change on that pin, the program running on the controller is immediately interrupted and a special function is run. This function, called an interrupt service routine or ISR, is typically very short. Normally an ISR simply stores the result of the interrupt in a variable. Then the processor returns to the main program.  

Operating systems, both on small boards like this and on servers and personal computers, do not guarantee a minimum response time to physical I/O. They are written to optimize processor sharing between programs, so the scheduler, a core part of the operating system, doles out processor time to each program. Even before the programs you run get time, there are OS tasks that take time.  Disk writing is one of the most time-intensive tasks. Perhaps the only longer task is a network transaction, because the data is going through many computers, each with its own operating system.

In systems that have to have real-time response, you typically use one of two options:

1) no operating system. Your processor runs one program only. Like Arduino

2) a “realtime operating system” or RTOS. RTOSes are stripped-down operating systems that leave many core functions out. As of yet, all RTOSes are custom packages, not very user friendly, though there has been some work lately on realtime linux. I haven’t seen one running on any of the hobbyist boards, but i wouldn’t be surprised if we don’t see one in the next year or so.

When we designed the Yun, we decided we’d give users the benefits of both real-time and an operating system. What you do on the 32U4 (the Arduino processor) is real-time because there is no operating system. What you do on the linino side is not, because it’s running linux, an operating system. The typical approach to a networked project (whether a Yun or other system) is to do all the real-time operations on a non-OS micro controller, then send the results to an operating system computer in non-real-time, after the action has happened.

Here’s a use case that illustrates the use of real-time and an operating system together:

Let’s say you’re using a rotary encoder to measure the speed of a wheel on a remote control vehicle. You want to display the speed on a dashboard screen that’s networked to the vehicle over Wifi.

Rotary encoders measure rotation by counting pulses generated by a rotating shaft. When the rotation is fast, the pulses happen VERY fast, and you need real-time to catch them. On a micro controller, this is typically sensed using hardware interrupts. These are sub-circuits of the micro controller that can interrupt the program flow when a change happens on a given I/O pin. They force the program to jump to a function to handle the interrupt. You usually want that function to be very short — typically all it does it to increment or decrement a variable counting the changes. The Arduino Uno has two hardware interrupts, and Paul Stoffregen’s encoder library allows you to use them for reading encoders.

The way you’d build this app is to have the rotary encoder attached to the hardware interrupts of a micro controller. This controller is your physical I/O controller. You’d write a program for the micro controller that calculates the speed based on the pulse rate and sends that serially to another controller connected to a display. One function counts the pulses. That’d be done by the function called by the interrupt (these are called Interrupt service routines, or ISRs). Another function calculates a running speed based on the changing count. A third function might control the movement of the vehicle’s steering based on the value. A fourth function sends the calculated value over a serial connection to the display computer.

The serial connection of the physical controller be connected to a networked modem like the Wifi shield or a Bluetooth radio, but that modem is just another single-function controller. That transmission takes time, and you don’t want to take processor time away from counting the pulses, so your physical I/O controller doesn’t handle this transmission, it only counts pulses and sends the value on. The radio controller handles the network connection. It transmits the data on to a display computer or a server. That server is typically running an operating system, and not working in real time, but that’s okay, because humans aren’t going to react in more than a half-second or so most of the time.   What you see onscreen is typically a report of the sensor readings, but it’s an average or aggregated reading, not the raw, realtime reading.  The delay depends on the transmission time of the data. Perhaps you have a virtual steering wheel onscreen that then directs the card, but this is not real-time either. The user gets to steer the car, but what she’s really doing is affecting the gross movement of the steering, not the fine control over the axle. She’s changing the overall balance, but the physical I/o controller is the only part acting in real-time to the sensors.

It is possible for a controller that’s running an operating system to have hardware interrupts, and for it to have interrupt service routines. But those are typically part of the operating system kernel, not part of the user programs. You have to write custom kernel routines and restart the OS in order to use them. So unless you’re a kernel programmer, you typically won’t use these on BeagleBone, Raspberry Pi, or Arduino Yun. This is why there are many projects that combine the Pi or the Bone with an Arduino or other non-OS controller to do real-time sensing, and it’s why the Yun has a separate processor for that as well.

A typical personal computer is made up of several controllers, in fact. There’s normally a CPU, a network controller, a controller inside any disk drive (if it’s a drive with a motor), a graphics processor, a hardware bus controller, and more. These are usually tied together with synchronous serial communication like SPI or I2C or some other means of communication. The dedicated controllers handle their subsystems in realtime, and report back to the CPU, which reports in user time (not real time).

BlinkyTape using NeoPixel Library

Blinkinlabs is shipping their product now after their successful KickStarter campaign, and I got mine in the mail a couple days ago. I had a few minutes and thought I’d get a basic example up and running. The Blinkinlabs documentation was confusing to me, however. The “Simplest BlinkyTape Sketch” wasn’t. The code was more complex than I had hoped, and I couldn’t find documentation of the API, but I noticed there were some examples that used the Adafruit NeoPixel library. Those examples didn’t run for me, but I figured if there were NeoPixel examples in the BlinkyTape repository, it should be possible to run the thing with that library.

A quick look at the schematics for BlinkyTape confirmed that it was indeed running the Atmega32U4, same as the Arduino Leonardo (their documentation’s good on setting the tape up as a Leonardo). Furthermore, the data in of the lights is connected to pin 13.  From there, it was simply a matter of modifying the Adafruit NeoPixels to work on pin 13.

Like the BlinkyTape examples, most of the Adafruit NeoPixel library examples were all about color scrolling. I dislike color scrolling. Call me old and cranky, but I remember a time when lighting designers made color choices and stood by them; when the designers of lighting tools gave us controls that let us choose those colors easily. I’m hoping that someday we’ll look back on this era  see color scrolling as a lighting design choice the same way as we see the mullet in hairstyle choice: a bad idea we had to go through to get to something more pleasant. Now you kids, get outta my yard! </cranky old man rant>

My sketch works like this: you send a serial string to the Arduino starting with a capital C, followed by the pixel number, the red level (0-255), the green level (0-255) and the blue level (0-255). The NeoPixel library then sets the color of the pixel you chose. That’s it.

Now that I know this thing’s so simple to use, I can see a lot of projects with it. Love the built-in processor too, makes it even more convenient. Makes me want to order a whole lot more NeoPixels from Adafruit too.

Here’s the code. You can also get it from gitHub.


[github_cv url='https://github.com/tigoe/NeoPixel_examples/blob/master/BlinkyTape/BlinkyTape.ino']

Sending Data Serially To Arduino

One question I get all the time is this:

I know how to send data from Arduino to (Processing, OpenFrameworks, etc). But how to I send data from (Processing, OpenFrameworks, etc) to Arduino?

Many people don’t seem to know that Arduino has built-in functions for parsing streams of data. Back with version 1.0.1 Michael Margolis’ excellent TextFinder library was merged into the core Stream library. So you can send an ASCII string like this:

123, 456, 789

And Arduino can read it and convert the numeric characters back into numeric values.

For example, let’s say you want to send a string to set the values of two LEDs that you’re going to fade using the analogWrite() command. Your data might look like this:

P1, 255\n
P2, 127\n

(the \n represents a newline character, ASCII 10)

Using the parsing functions, you can look for the initial P character, then parse the numeric string that follows it until a non-numeric character (like the comma) comes along. Then you can do another parse until the next non-numeric character (like the newline at the end of the line) comes along. It’s as simple as this:

if (Serial.find("P")) {
    // read and parse characters before the comma:
    int ledNumber = Serial.parseInt(); 
    // read and parse characters after the comma:
    int brightness = Serial.parseInt();
}

Here’s a full example.

So the next time you’re trying to figure out how to read data in Arduino, first decide what your data looks like, then get to know the Stream functions. In addition to find() and parseInt(), there’s also readBytes(), readBytesUntil(), parseInt(), parsefloat(), and a few other goodies.

The really nice thing about these functions is that they work on any library based on Stream. So, for example, you can also use them on the Ethernet and WiFi and GSM Client and Server classes.  This makes parsing network data much simpler.