Environmental sensing using the STM32G071

Full size image
This project displays information about the environment on an ST7789 display. There’s a text version of the data and a simple trend graph of the dust/pollen data. The sensors used are as follows:
Pressure/Temperature: BMP280
Light : TLS2561
Dust : DM501A

The BMP280 and TLS2561 connect back to the STM32G071 over the I2C1 bus. The DM501A light sensor connects back to a GPIO pin. This pin is sampled at 1kHz. When a dust particle is detected in the sensor this pin is driven low. The program simply counts the number of milliseconds (samples) that this pin is low over a 1 minute interval and displays this figure.

Environmental information is sent back to a host PC using a UART. It is also written to the ST7789 display.

Code is available over here on github.

Getting started with the STM32G071

I bought a couple of STM32G071’s about a month ago but didn’t do much with them as openocd as supplied in Ubuntu didn’t support them. There is however a snapshot of openocd that does. It’s a little out of the way for now and no doubt will be included in the next release so check before trying any of this. So the steps I followed are:

Download and extract : http://openocd.zylin.com/gitweb?p=openocd.git;a=snapshot;h=dcec354bfc756c4a4e1034c9461b5d3f4e55a63e;sf=tgz
Go in to this directory and run the following
git clone http://openocd.zylin.com/jimtcl
Now, I wasn’t expecting to have to do the next edit but I got compiler errors without it – I suspect my gcc version (8.3.0) is different from the original author’s.
Open file src/flash/nor/stm32g0x.c and starting at line 929 you will see the following code:
struct target *target = NULL;
//struct stm32g0x_flash_bank *stm32x_info = NULL; // <—— COMMENT OUT THIS LINE

if (CMD_ARGC < 1)

struct flash_bank *bank;
int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
if (ERROR_OK != retval)
return retval;

//stm32x_info = bank->driver_priv; // <—— COMMENT OUT THIS LINE

target = bank->target;

if (target->state != TARGET_HALTED) {
LOG_ERROR(“Target not halted”);


run ./bootstrap
run ./configure –enable-stlink –enable-maintainer-mode –disable-internal-libjaylink
sudo make install
This left me with an installation of openocd in /usr/local

Now that I had openocd I needed to get set up for blinky. The STM32G071 version I have is an LQFP32 so a breakout board is needed along with pin headers. Lots of flux and some solder wick was used to fix errors.

The picture below shows the finished circuit

Next step was to put together a simple blinky program. A little background work was needed first to get register definitions and so on. I dug around the web and found the appropriate SVD file for this chip and used svdconv to generate a header file. The final code and the openocd configuration script (stm32g0.cfg) can be found over on github. More examples will follow.

Dublin Maker and Apollo 11

As it happens, Dublin Maker 2019 will occur on the same day as the 50th anniversary of the Apollo 11 moon landing. Once I realized this I had to add a simple moon-lander style game to the Dublin Maker (unofficial) badge.
Flash memory usage is running at 99.98% so I suppose the software for the badge is now “done”
Final badge code is available over here on github.

Badge building in Tog

We had a 2 hour Dublin Maker badge building session in Tog on Monday the 27th. 10 people showed up to (partially) assemble 13 badges. The firmware will need to be finalized before the final build which should hopefully happen in the next couple of weeks. Hoping to get a total of 15 built.

DM 5 Euro badge : first build


The first build of the unofficial €5 badge is more or less done. The image above shows a front view. Two 3.5mm audio sockets act as communications ports and allow a stereo audio cable be used as a lanyard. A game-pad style interface is provided for the bundled games. Also provided is a 4 pin header for uploading and debugging new firmware. The badge is powered off a 1.5V AA battery which is stepped up to 3.3V using a boost converter (just below the left audio socket).

I attempted a previous version of this by soldering all components in place but quickly realized that was so difficult that there would be few successful builds. I’ve since switched to a mixed wire-wrap and soldered build as shown below (I know it’s a bit rough :). This approach is much easier and errors are easily corrected.

Remaining tasks:
Tidy up the back of the badge
Develop a multiplayer game
Get ready for the badge “make-a-thon” in Tog later in May

Code and docs are available over on github

Dublin Maker Badge (unofficial) OS nearing completion


Such as it is, the “operating system” for the unofficial Dublin Maker badge is nearing completion. The latest work has focused on the inter-badge communication. This is a wired protocol (the lanyard is the cable that links the badges together).
Inter Badge communications (IBC)
The protocol makes use of the USART in the STM32F030. The USART supports a single wire half duplex protocol. The TX pin only is used and is configured as an open drain with an internal pull-up. When it is transmitting it becomes an output. When not transmitting it is in receiver mode. Given the probably poor cabling and connections the communications speed will be set as low as possible but not so low that it gets in the way of game play. The protocol should therefore have as little overhead as possible.
Some applications will require sender and receiver to be identified so both addresses must be in each data packet. A single byte for device address – probably overkill to allow this but it is simpler to process and could have special addresses e.g. broadcast for certain situations.

Indicating start of packet
The hardware link as designed has two signal wires: One for half duplex data the other for indicating that the bus is busy. A sender pulls this line low just prior to starting a transmission. This is handy for a number of reasons:
* It allows us know when the bus is busy.
* It can be tied to an interrupt to put the chip into “packet receive mode”.
* When it goes high, packets are either processed or discarded.
* No special start or end of packet signals are necessary
* In some ways this is like the “carrier” in CSMA/CD
The packet format is as follows:
* tx/rx signal #########DST SRC FLG_LEN DATA0..DATAn CHK###########
* busy signal #######|__________________________________|#########

Flags/control byte
Following the address bytes a third byte will contain flags and length inforation. 4 bits for flags (such as : ACK, NAK, ANNOUNCE etc), 4 bits for length

Address assignment
How does each station get an address? It could be hard coded but that’s a separate firmware image for each badge – too much work. The user could be asked to enter it but this complicates the user interface. Automatic address assignment was chosen in the end and it works as follows.
On power up, send an ANNOUNCE broadcast packet (Broadcast address is 0xff):
0xff SRC 0x20 CHK
Where SRC is the address the station is attempting to use. If some other device has this address then a NAK will be sent and a new ANNOUNCE with the next address is sent.
NAKS may get lost but I’m not dealing with this – it’s not that critical a protocol
The image below shows the bus traffic when a station powers up and attempts to claim the address 0xfe. The current holder of this address sends a NAK to indicate that 0xfe is taken so a new announce packet is sent for the address 0xfd. This is successful.


Error detection
A simple 8 bit checksum byte will be used to provide some form of error detection – it’s not great but it’s better than nothing.
Difficulties encountered
The main problem was managing state (I’m still not sure it’s ok) and also one major gotcha. I tried using the Timer subsystem to manage delays in the communications code. The Timer uses the SysTick timer and interrupts to measure the passage of time. Unfortunately, some of the IBC code runs in interrupt context within which (nested) SysTick interrupts don’t happen. This might be possible but I decided not to get too adventurous with the NVIC and found another way to pace communications
What’s next?
Now that IBC works I have to come up with a game that requires it. This will require passing information from the badge communications layer up to an application layer – something I’m not quite clear on how to do yet.
Source code is as usual available over on github