Catching Up: Arduino MKR1000 WIFI

The switch from Raspberry Pi Zero W to Arduino MKR1000 WIFI was something I wanted to do for some time. I was curious to see if the operating system running on Raspberry Pi Zero was the culprit behind the low data rate. There were some other reasons too:

  • Arduino MKR1000 WIFI runs at 3.3V, unlike the majority of the other Arduino boards. It is excellent to know that you can’t burn a component by accident. Also, I enjoy the convenience of not having to shift voltages for the parts that can’t tolerate 5V.
  • It is even smaller than the Raspberry Pi Zero W.
  • It includes a Li-Po charging circuit. You can use this circuit to run the board on battery power or charge the battery when the board is powered through USB or an external power source.
  • It has seven channels of 12-bit ADC. I use eight flex sensors for the glove and two more for the joystick, meaning that I need 10 ADC input channels. Raspberry Pi Zero W didn’t have any, so I had to use two MCP3008s for this task. I planned to change one of them to a two-channel ADC (MCP3002) once the design was complete. On Arduino MKR1000 WIFI, I can ditch the second one altogether.
  • It has a low-power WiFi module on the board. Even better, it is compatible with the Arduino WiFi101 library initially made for the Arduino WiFi101 Shield, which makes it extremely easy to get started and program.

I liked the fact that the headers were included but not soldered to the board. After soldering the headers, I can use the board for prototyping. Once the design is complete, I can buy a new one, solder it to my circuit, and put it in the glove. Neat.

The board is programmed using Arduino language, which is essentially a framework built on top of C++. That said, I had to brush up on my C++. I tried to write the code that gathered quaternion and linear acceleration data from the BNO085, flex sensor values from MCP3008, joystick input from the built-in ADC, and connected to my router to send values over OSC. I could get individual modules to work; however, my Windows computer stopped recognizing the board after some experimentation. I tried it on my Mac computer, and it didn’t recognize the board either. I thought I bricked the board with some faulty code. A few hours of research taught me that double-clicking the button on the board forces the board to use another serial port to communicate with the computer. I’m glad I had to learn it that early in the process because I had to use this button quite a lot.

Anyway, I wrote the code: it pulled the values from sensors, bound them to specific OSC messages, sent the message over UDP. A Max patch received all these values, and a subpatch measured the average time elapsed in milliseconds and calculated the frequency of the data in Hz for each component. The results were much better than the previous setup that employed Raspberry Pi Zero W: everything was running at 60 Hz.

The results were better but confusing. I checked the way I structured the code, and it was pretty much like this:

  • Check for interrupts from the BNO085 at all times
    • When an interrupt is received, check for the type of data and change its flag
  • Check for the flags of both quaternion and linear acceleration data
    • If the flag is enabled
      • Read the data from the sensor
      • Bind the values to an OSC message
      • Send the OSC message
    • If the flag is disabled
      • Skip reading the data
  • Read analog inputs 0 and 1 on the board, bind the values to an OSC message, send it
  • Read all eight channels of the MCP3008, bind the values to an OSC message, send it

The only conclusion I could arrive at was that something in the code was slowing down the loop, so the flags for both IMU readings were getting enabled by that time the loop completed one cycle. As a result, the main loop was working just as it was polling the data instead of using interrupts, and the 60 Hz was the rate of the weakest link. I singled out every component for testing. They all worked at a reasonable rate: quaternion data at 166 Hz, linear acceleration at 211 Hz, MCP3008 at 391 Hz, and Arduino analog ins at 190 Hz. Then, I disabled the OSC part and printed the data directly to the Arduino Serial Monitor. I expected the data rate to be a little faster, but instead, I found where the bottleneck occurred. The data rate still wasn’t at the level it was supposed to be; however, it was acceptable for my application.

I began optimizing the code because OSC communication is something I can’t simply discard. I realized that binding all of the sensor values to an OSC bundle and sending it all at once can improve the data rate because I would send the UDP packet only once at the end of the loop cycle rather than doing it four times. I changed the code to this:

  • Check for interrupts from the BNO085 at all times
    • When an interrupt is received, check for the type of data and change its flag
  • Check for the flags of both quaternion and linear acceleration data
    • If the flag is enabled
      • Read the data from the sensor
      • Bind the values to an OSC bundle
    • If the flag is disabled
      • Skip reading the data
  • Read analog inputs 0 and 1 on the board, bind the values to an OSC bundle
  • Read all eight channels of the MCP3008, bind the values to an OSC bundle
  • Start UDP communication, send the OSC bundle, end UDP communication

In Max, I was getting all of the required data at once at these frequencies: quaternion data at 130 Hz, linear acceleration at 115 Hz, Arduino analog inputs at 110 Hz, and MCP3008 at 170 Hz. These values are not ideal, but they meet the criteria for this project.

Next, I started testing the OSC connection the other way around. I introduced an RGB LED to the circuit and sent RGB values from Max to Arduino. It worked pretty well and didn’t impede the data rates at all. Feeling triumphant, I decided to hook up an Adafruit DRV2605L Haptic Motor Controller through I2C and a vibrating motor disc to provide haptic feedback. It also worked pretty well.

In summary, I could bring the sensor values into Max at a good enough frequency, send different colour values for the RGB LED, and vibrate the disc from Max. Yet, I ordered a much powerful and, surprisingly, cheaper board, Teensy 4.0. I also ordered an ESP8266 12-F to add WiFi connectivity to it.

Let’s see if I will be able to use BNO085’s full potential this time.



Hello World!
Since I set about my PhD thesis research, I’ve meant to build a website and post updates about the project. However, building a website is a pain, and I postponed it until I can’t any longer. Also, I have been enjoying working on my PhD project more than undertaking a […]
Catching Up: Raspberry Pi Zero W
This post and the rest of the “Catching Up” series are the (long overdue) updates on the development process. They will not be thorough, but I will try to remember the essential details as much as I can. Initially, I started working on the project on a Raspberry Pi Zero […]
  • 1
  • 2