The SK9822 LED (also known as the “dotstar” LED) is a smart RGB LED similar to the WS2812B. It has some advantages however: It is controlled using a standard SPI interface which means it does not rely on the sort of critical timing the WS2812 needed. It also allows you separately control the brightness and the colour mix of the internal LED’s. The LED’s can be strung together; the data and clock output from one feeding the next. The LED’s require use two pins of the host microcontroller: MOSI and SCK as shown in the figure above. Power should be supplied from a separate source to the microcontroller. The SK9822’s are 5V devices but seem to accept 3V logic signals on their control inputs.
The LED’s I got came in the 50/50 surface mount format which makes them a little difficult to use with a breadboard. A TSSOP-20 adapter came in very handy however and I was able to mount 3 on the same board as shown below.
The LED’s are controlled using a data frame that begins with a sequence of the following form
0x00 0x00 0x00 0x00 ii bb gg rr 0xff 0xff 0xff 0xff
The leading 4 zeros are a start of data frame delimiter.
These are followed by a 1 byte intensity or brightness value which ranges from
0 to 31. The most significant 3 bits of the brightness field must be 1
Values in the range 0 to 255 follow for blue green and red
Finally an end of frame consisting of 4 bytes of 0xff is sent.
The test program below outputs signals that cycle 3 LED’s through a range of colours
The program was developed using an STM32F030F4P6 breakout board and ST-Link V2
Code is available for download from here on github
There is a moderate solar storm going on today and I noticed that there was a deflection of the electronic compass output around the same time. This is about the third time I’ve noticed something like this. Aurorawatch UK (https://aurorawatch.lancs.ac.uk/) showed this deflection around the same time:
Now, I know, the units are wrong and the signs are opposite but it is nevertheless a change at around the same time. Furthermore, the temperature of the sensor was stable at 16.7 degrees throughout the whole event so I think I can rule out a temperature effect. I need to investigate scaling and measurement direction to see if my results can relate directly to “official” ones.
AliExpress supply a really tiny OLED display driven by an SSD1306 controller.
The actual display area is 25mm wide by 14mm high and has 128×64 pixels. Pixels can be white, yellow or black. The display connects to the host microcontroller over an I2C bus which greatly simplifies wiring.
Pixels are mapped to graphics memory as follows:
Each graphics memory byte controls a column of 8 pixels. 128 bytes cover a strip of 128×8 pixels or “a page” as its called in the data sheet. This display has 8 pages giving a resolution of 128×64 pixels. To set a particular pixel, you need to identify which page it is on and which byte and bit connects to it within this page. In theory you could then drive this pixel on or off as desired however there is a problem: graphics memory is written in byte-sized chunks so if you want to set a particular pixel, you need to read the byte connected to it, modify the bit in question and then write it back. Unfortunately, the I2C interface for the SSD1306 does not permit reading of graphics memory.
The Adafruit driver for this display gets around this problem by maintaining a copy of the graphics memory in the host MCU. It then updates the whole display when things change. This consumes a fair amount of RAM in the host MCU (128×8 = 1024 bytes) and is slow as the whole display must be updated if a single pixel changes.
My first attempt at controlling this display takes a different approach. The display is treated as a text only device capable of displaying 25×8 characters. Screen updates are carried out at page level i.e. 128 byte chunks are written at a time which corresponds to a single line of text. An I2C driver buffers this data and outputs to the display on an interrupt driven basis. This greatly reduces RAM consumption and speeds updates.
Programming and debugging
Openocd version 0.10 or later is required for the STM32L031. You may get this ready built for your OS or download the source and compile yourself. In my case, I downloaded the source from openocd.org. This was extracted and compiled as follows (as the root user):
apt-get install libusb-1.0-0-dev
./configure –enable-stlink –enable-maintainer-mode
The STM32L031 was connected to the host PC using an ST-Link V2 clone and the debug/programming session was started this:
GDB was then used to upload and test the program.
Source code is evolving and can be found here:
I previously used a GY-652 module as the basis for a weather station. The module contains a BMP180 pressure/air sensor and a HMC5983 electronic compass. The weather station ran for about 4 months on 3 AAA batteries which was reasonable enough although the GY-652 had an unexpectedly large quiescent current of around 1mA.
Anyway, the batteries needed recharging and I decided it would be interesting to see if the HMC5983 could be useful in such an environmental monitoring test.
The Earth’s magnetic field varies from around 250 mG to about 650 mG. During solar storms, this can vary by as much as 170 milli-Gauss (source: http://www.spaceweather.gc.ca/svr-en.php). Daily variations in the magnetic field are of the order of 0.4 milli-Gauss. Are these measurable by the HMC5983 I wonder? According to its datasheet, the noise floor for the device is 2 mG so that probably rules out the detection of daily field variation. Storms are another matter however and these should be measurable by the device.
Batteries were recharged and code modified to make use of the HMC5983. The base-station for the weather station is now connected to a Raspberry Pi which relays the data up to Thingspeak. I’m going to leave it for a month or as long as the batteries hold out and, who knows, maybe it will spot a solar storm.
Click here to view the data on Thingspeak.
Update 20 January 2018
After a month or so in operation I think I *may* have seen some correlation between solar activity and magnetic reading variations. There is also some correlation between the magnetic field readings and temperature. The system had been using 3 rechargeable AAA batteries which have been drained twice (need to work on my low power mode :).
To overcome some of these shortcomings I’ve opted to move the sensor out of the attic and placed it under the stairs (unheated area, not too near any big electrical or magnetic fields). I’ve also replaced the AAA batteries with AA ones. Now just have to wait for a big solar storm…
On Saturday the 18th of November Breadboard games version 2 had its first outing in Bunclody library in Wexford. Shannon Chance from the RobosSlam team has documented the day here: https://shannonchance.net/2017/11/19/bread-board-games/
Assembly instructions and code can be found here: https://ioprog.com/bbg/bbgbunclody17/
I’ve been trying to program the STM32L432 Nucleo-32 board using the mbed compiler. It has not been working. I can program a range of other boards without any problem. I noticed that the programming LED did not change when I tried to program the device and remembered that I had seen this before. The problem seems to be as follows:
When you load a program on to an MBED enabled Nucleo-32 board the firmware in the loader checks to see if the first 32 bit word (which will form the initial stack pointer) lies within the available RAM on the target. The value output by the mbed compiler for the L432KC is 0x20010000 – the top of the 64kB of RAM. This should be ok (you would think) however it is rejected by the loader. Using a hex editor I changed the first word to 0x2000C000 (the top of a 48 kB block of SRAM1) and it worked.
So, either there is a bug with the mbed linker script and/or initialization files or the loader on the Nucleo board is misinterpreting the available RAM.
Anyway, I’ve posted this as a bug(/fix) to mbed and will see what happens.
Update: There is updated firmware for the STM32L432 Nucleo board over here:
http://www.st.com/en/evaluation-tools/nucleo-l432kc.html It fixes this problem and the board accepts an initial stack pointer that lies within SRAM2 now.
A previous post described the building of a weather station based around an STM32F030 and an NRF905 radio. I put 3 freshly charged AAA batteries into the station on August 7th (2017) and more than 10 weeks later, the system is still reporting atmospheric pressure and temperature every minute.