Arduino shields come in hand from time to time when you want to prototype some hardware.
As I had a Grove Base Shield from Seeed Studios I decided to give it a try to hack it together with one of our STKs and it actually turns out that this is possible.
The unfortunate candidate to receive surgery this time, was a Mighty Gecko WSTK. All the newer starter kits have the correct spacing between the rows, it was just a matter of getting the pin mapping right. This is what I ended up with. The green dots are where headers will be added, and the red stars are pins on the Arduino shield that will have to be cut:
So I started by cutting the top three pins on the short side (NC, IOREF and RST). I also removed the 5V pin, as the shield will only communicate using 3.3V:
Then you can see that the GND pins does not align properly. This was solved by grounding the pin next to it:
As I have just created a Connected Coffe Machine and had a Grove LED Bar lying around I thought I'd upgrade the receiver with a nice LED bar, going from all green to full red when the coffee machine needs to be emptied. The code I used can be found here: https://github.com/SiliconLabsLabs/ConnectedCoffee
Summary: You can use digital pins 0-7 and analog pins 0-5 on 3V Arduino shields with the Silicon Labs (W)STKs:
Our coffee maker is one of the most prized assets in the office, so naturally it's important to keep it on a regular maintenance schedule. One of the most important tasks is to make sure to empty the trashbin of coffee grounds at a regular interval, to make sure it does not overflow.
To solve this we added a digital scale underneath it, and connected that to one of our WSTKs. Torkil did all the difficult stuff here, but short summary: The scale sends out a pulse train where the duty cycle corresponds to the weight. We can then measure the high-period and knowing what it's like when empty and full we can then calculate a fill-level. Hereare some pictures of the process:
Opening the scale:
Figuring out what is where:
And we get a ratio between weight/fill-level and duty-cycle:
Final mounting of the scale/transmitter:
The fill level is expressed in one byte and transmitted wirelessly. I just took the bidirectional example in Simplicity Studio and use the first byte of the data struct for actually transmitting data. The next 15 bytes I just left there. The weight is measured every 200 ms, and the weight is transmitted every second. As the readings from the scale can be quite unstable, every reading is actually measuring 8 pulses, then I have a static variable which is updated using a super-simple filter:
value = newValue*0.1 + value*0.9;
The Thunderboard Sense then picks up this byte and display the byte as a color between green (0x0) and red (0xFF). Actually 0x0 holds a special meaning, that the WSTK cannot get a good reading so the fill-level actually starts at 0x1.
There are also a couple of other functions for testing.
1) Pressing a button on the WSTK sends a random weight. Useful for testing when it's not connected to the scale
2) Pressing a button on the Thunderboard Sense sends a packet to the WSTK and changes the color to purple when it receives an ACK. Useful for testing connectivity.
3) If more than 10 seconds passed without receivng a packet, the Thunderboard Sensestarts blinking yellow and will send a packet every second to try to re-initiate the connection.
4) If only 0x0's are received from the WSTK, Thunderboard Sense will blink blue to inform the user that something is probably wrong.
The files available on https://github.com/SiliconLabsLabs/ConnectedCoffee contains one example for the WSTK and one example for the Thunderboard Sense. The Thunderboard Sense example is the same bidirectional example, but updated to work with TB-S. As there is currently no support for Thunderboard Sense in the RAIL SDK, an additional board-folder is added, BRD4160A. The Thunderboard Sense example also contains some files copied from the BLE Thunderboard Sense example, such as the RGBLED driver.
In general these examples shows a simple use-case of the lower level radio functions coupled with RGBLED-drivers for the Thunderboard Sense and using the rtcdriver for timekeeping.
In the drawer under the coffee machine:
Thunderboard Sense on top of the machine:
The next steps are obviously to get it cloud connected. I'm hoping to use Thread for this. Just have to set up an internet connected Thread network here at the office. Why isn't there one here already?
Code is available here: https://github.com/SiliconLabsLabs/ConnectedCoffee
We created a modern Pinewood Derby Car that could be controlled with Silicon Labs' Thunderboard React MCU and app.
We wanted to utilize Silicon Labs' Thunderboard React MCU which contains a Bluetooth Low Energy module, two LEDs (green and blue), two switches, an accelerometer/gyroscope, and plenty of GPIO pins. The app can connect to the Thunderboard via Bluetooth and can display the orientation and speed of the car in real time. You can also turn the two LEDs on/off via the app. Initially we intended on using the orientation and speed data to trigger lights and sounds, i.e. when the car is accelerating a revving sound could play and when decelerating a braking sound/light could trigger. We quickly found out that accessing the real time car data was beyond our software skills, so as self respecting engineers we created a hack!
Since the only inputs we had access to via the app were turning the LEDs on/off, we decided to use those as triggers for our lights and sounds. When a LED was turned on, the respective GPIO pin would drop from 3.7 V to 0 V. This was used to send a signal to a connected Arduino that was then connected to an Adafruit Soundboard module. The Arduino would listen for either a high or low signal and send that signal to the Soundboard, which would play either the revving or braking sound file on loop.
You can check out the Arduino code and sound files on GitHub:
Derby Car Body:
Both the derby frame and outer shell were 3D printed (Ultimaker 2+) so that we could secure all the electronic hardware in an organized way. The wheels were machined on a desktop CNC (Nomad 883 Pro) out of acrylic sheets. Keeping with our pickup truck theme, we added a payload to the bed of the truck body using stainless steel balls. The idea was to increase the total mass of the car so that it would have higher inertia coming off the derby ramp. The front hood of the truck has vents cut out for the speaker underneath.
Thanks to Silicon Labs for providing the Thunderboard React module and thanks to everyone at the Derby Race that helped us win Hottest Design!
Hi everyone! And welcome to episode ten of my Bluetooth in Action series. Today, we are going to look into more advanced debugging, by using the serial port to view data.
Up until now, we haven’t really needed to visualize data; we’ve been blinking LEDs, turning on and off GPIOs, and mainly using visual references. For the next part of this series, we’ll be looking into more advanced features, and ones that will require some level of data output. This is also a question I get frequently, so today, we’re going to be quickly looking at serial output.
The BGM111 module is connected to a computer using a CMSIS device, one that allows us to flash the device, but also to use it as a serial port, simultaneously. For serial output, BGScript isn’t quite as easy to use as C, but with a few helper procedures, we can print a lot of data.
The command that we are going to be using is endpoint_send, which in the API reference is in the Endpoint section. Note that the API talks about the endpoint; UART1, UART0, or DROP. We’ll be using UART1, since that is what is connected to the CMSIS module, and to make thing easier, we will go ahead and create a const, called uart_ep for end point, and give it the value two, for UART1. It will make things easier later on.
Back to the documentation. The function we are interested in is an endpoint command, called “endpoint_send”. It takes three parameters; the endpoint is the UART port, data_len is the length of the data to send, and data_data is the buffer to send. So let’s say we want to send a “Hello, world!” to our computer. So, we copy and paste the system boot event from a file I prepared earlier, and we add the endpoint_send command. The first parameter is the UART port, which we called uart_ep. The second parameter is the length; we’ll get back to that. The third is the buffer, “Hello, world!”, for a total length of 13. Let’s add that number to the length parameter. Okay, we should be good.
In order to see the text, we need a serial console. There are a lot to choose from; I’m using Tera Term, because I’m used to it, but others exist. They all share the same principle; select a COM port, set up the connection parameters, and wait for data. I’ll be using 115200 baud, 8 bits of data, no parity, and one stop bit, shortened to 115200, 8N1. I’ll show you why in just a second.
So let’s compile that, and flash it. And… nothing happens. Why? Here’s the catch. We are using the right command, but remember that unless we set up the hardware, nothing is actually configured, so the UART port hasn’t actually been set up, it is up to us to correctly configure the I/O pins.
We will need two things to get us up and running. We will need to configure the serial port; by default, these devices are in 8N1, we’ll just specify the baud rate for easy viewing. This is done in the hardware file. The documentation file at Silicon Labs is UG119. All documentation files are available on the Silicon Labs website, or directly by installing Simplicity Studio, version 4 has just come out.
So, in UG119, section three point four, UART. This show us what parameters are needed. Index, baudrate and flowcontrol make sense, only bgapi needs explaining; “When an external host us used to control the Bluetooth module over UART, the BGAPI serial protocol must be enabled.” Well, we don’t need that, so we will leave it at false. Secondly, and this is sometimes the tricky part, the two GPIO pins need to be set correctly. A5 is Tx, A3 is Rx.
Let’s try to compile that again, and see what happens. This time, things change, we can see some serial output. If you get any corrupted text, or no text at all, make sure that you are using the right settings, as very few devices are able to automatically detect the baud rate.
This is a great way of printing text, but there are times when you will need to print something else; decimal, hexadecimal or even binary are frequently used types. There is no direct way to print out this kind of data, but with some simple helper procedures, you can print out just about anything. I didn’t create these procedures, they were actually available in some example programs, just hidden away. So for example, for debugging purposes, it is always interesting to know what hardware build we are using. To do this, we’ll use an endpoint send to print out some text, and then call the print int32 procedure, before calling endpoint send again, using a carriage return sequence.