Gerrit Niezen

Maker of open-source software and hardware.

I just received a WCH CH32V307 RISC-V development board as part of the Hack It! RISC-V Design Challenge. What follows is a simple tutorial in getting started with running an RT-Thread example on the CH32V307 development board.

Installing and setting up the IDE

Setting up the debugger

  • Go to Run –> Debug Configurations..
  • Select GDB OpenOCD WCH Debugging / rt-thread.elf
  • Click on the Debugger tab
  • Enter the following under Config options: -f wch-riscv.cfg
  • Click Apply and then Debug

Setting up debug options in MounRiver Studio

Running the example

  • Plug your development board into USB port P9
  • Make sure the project is selected in the left-hand pane
  • Click the arrow to the right of the Run button, and select Run As –> OpenOCD WCH Debug:

Screenshot of Run As

If all goes well, it should build and and start running the example. If not, you may need to click Project-> Rebuild. Now, open up rt-thread/user/main.c in the project, and you'll see that it is supposed to flash an LED and print to the terminal. Now you may wonder: “Why am I not seeing LED1 flashing on the board?” I wondered this too, and found this in the CH32V307 evaluation board manual:

  1. LED: Controlled by connecting the extension connector J3 to the IO port of the master MCU

What this actually means is that you need a jumper cable to connect pin LED1, which is on the extension connector J3, to pin PA0, which is on both the extension connector and the Arduino interface. If you wire this up correctly, you'll hopefully see the LED blinking:

Blinking LED on CH32V307 dev board

If you also want to see the RT-Thread terminal, just connect to the board using your favourite serial terminal at 115200 bps, e.g. using minicom:

minicom -b 115200 -D /dev/ttyACM0

RT-Thread terminal in minicom

You don't need a separate USB-serial adapter, as the serial interface is provided by the WC-Link onboard the development board.

Any feedback and comments are appreciated!

#riscv #wch #electronics #ch32v307 #rtthread


If your electronics projects needs to talk to other devices, but you don't have access to WiFi, LoRaWAN is a great alternative. The Things Network (TTN) is a global collaborative Internet of Things ecosystem which allows devices to use the network for free. No payment or SIM cards are required like with NB-IoT or Helium, you just need to keep to the usage limits.

The problem is that there are very limited options for LoRaWAN modules, given the current global chip shortage. As I'm based in the UK, I'm looking specifically for 868MHz modules.

The RN2483 LoRaWAN module from Microchip used to be the de facto option when you don't want to run a LoRaWAN stack on your microcontroller. Unfortunately they are out of stock until 2022 or later. Luckily there are other options, so let's have a look at what's out there.


RAK Wireless has a range of LoRaWAN modules where different microcontrollers are combined with LoRa chips. The RAK3172 is their first module that uses the STM32WL, combining a microcontroller and LoRa on the same chip. It comes preinstalled with a LoRaWAN stack, so you can use it with your own microcontroller over a UART interface.


Seeed Studio's LoRa-E5 module also uses the STM32WL chip, and is also controlled over a UART interface if you use the preinstalled stack.

Unfortunately both the RAK and Seeed modules suffer from a high transmit power consumption bug, which look like it may not be able to fix in firmware without reducing the range significantly.


Ai-Thinker's Ra-07H uses the ASR6501 chipset which also combines a LoRa transceiver with a microcontroller, and can also be controlled over a UART interface.


Ebyte's E78 module is also based on the ASR6501 chipset. It appears that both the Ra-07H and E78 modules are compatible with TTN v3.

There are other LoRaWAN modules out there, like Move Solutions' STM32WL-based MAWLE-C1, but the ones above are ones that were actually in stock at the time of writing.


The WHO Global Air Quality Guidelines mention five different pollutants, but what are they? Let's have a look.

Particulate matter (PM2.5 and PM10)

Particulate matter (PM) are inhalable particles smaller than 10 micrometer (PM10) and 2.5 micrometers (PM2.5) respectively. PM can consist of things like mineral dust, ammonia, nitrates and black carbon. The WHO limit is 15µg/m³ for PM2.5 and 45µg/m³ per 24 hours.

Carbon monoxide

Carbon monoxide is produced by burning wood and fossil fuels like natural gas, petrol and kerosene. You can't see, taste or smell it, but in high levels it can kill you. The WHO limit is 4mg/m³ per 24 hours.

Nitrogen dioxide

Nitrogen dioxide is reddish-brown in colour and is produced by fossil-fuel based heating, transport and power generation. It irritates airways and is linked to asthma and other respiratory diseases. The WHO limit is 25µg/m³ per 24 hours.

Ground-level ozone

When nitrogen oxides (NOx) react photochemically, they form ground-level ozone, which is a major component of smog. Ozone causes problems breathing, triggers asthma and leads to lung disease. The WHO limit is 100µg/m³ per 24 hours.

Sulfur dioxide

Sulfur dioxide is yet another pollutant produced by the combustion of fossil fuels like coal. It is a colourless gas that easily dissolves in water to form sulfuric acid. The WHO limit is 40µg/m³ per 24 hours.

Interesting how many of these air pollutants are fossil fuel based, and if we just stop burning stuff, it helps to prevent climate change too. Who knew?

#AirQuality #AirPollution

You already know that air pollution is a big problem, but you're not sure what you can do about it personally? Instead of waiting on the government or other people to solve the issue, here are 4 practical things you can do to improve air quality:

Stop burning stuff

Wood-burning stoves are one of the leading causes of air pollution in countries like the UK. Even a candle in your living room emits particulates. While we may have romantic or cozy feelings towards burning stuff, it's not great for our lungs.

Get on your bike

Even electric cars emit particulates when braking, so the best way to get yourself from A to B is on a bicycle or by walking. For longer journeys, public transport is the way to go.

Grow plants

Back in the 1980s NASA did this study to show that plants are great at purifying the air. Though later studies didn't quite replicate their results, having some beautiful green plants in your house is never a bad thing.

Switch to an induction stove

Gas stoves generate a lot of particulates during cooking, and you can cut down on this by using an induction stove instead. Is the convenience of a gas hob really worth the risk to your family's health? You may just find that a modern induction stove is just as convenient as the gas version.

With the current global chip shortage it can be challenging to find the right chip for your project that's actually in stock. I want to share some of my own challenges and what the options are. First up: What LiPo battery charger chips can be used with solar panels?


I first came across Texas Instrument's BQ24074 while looking at Adafruit's Universal USB / DC / Solar LiPo charger, which replaced their earlier MCP73781-based charger. It's relatively inexpensive ($0.81) and has an input voltage of up to 10V. Unfortunately this chip was out of stock when I ordered my board for SMT assembly, so I had to consider alternatives.


Analog Device's LT3652 is used in Sparkfun's Sunny Buddy (MPPT Solar Charger), but it's a lot more expensive (around $5) than other chips and was also out of stock at the time of ordering.

CN3065 / CN3063

Consonance Electronic's CN3065 is used in Seeed Studio's LiPo Rider boards, as well as many low-cost solar battery charger boards on eBay. It's even cheaper than the BQ24074 at around $0.50, and it was available in its SOP8 package version CN3063 at JLCPCB when I placed my order. While it has been working great so far, it only has an input voltage of 6V, which could cause issues if you get high peak voltages on your solar panel over an extended period of time.

What are your favourite tools when building hardware?


If you're working with electronics, you need to be able to measure voltages, current, resistance and continuity. I mostly use a $10 multimeter to check if voltages are at the right levels and if there's continuity between various parts of the circuit. You'll notice there's no oscilloscope on this list. If you're only working with digital electronics, an oscilloscope feels like an unnecessary luxury. Most of what you need to figure out can be done with a multimeter and a logic analyser.

Logic analyser

My $10 logic analyser from eBay only measures up to 24MHz, but I've been able to successfully decode USB traffic that typically would be done with a USB analyser costing 50 times as much. The open-source Sigrok PulseView software supports a wide range of protocols for decoding, and is surprisingly easy to use.

Digital calipers

If you have a 3D printer, you're going to find digital calipers useful. It makes it so much easier to measure the dimensions of enclosures, components and circuit boards. I bought a super-cheap plastic digital caliper for $7, and so far it's been working just fine. I find myself using it so often that I could easily spend a little bit more on one that allows for finer adjustments.

USB-to-TTL converter

If there's any kind of UART serial communication between your microcontroller and peripherals, a $5 USB-to-TTL converter is a very useful addition to your toolbox.

Software-defined radio

This may sound like an unusual addition to this list, but being able to use a $10 DVB-T USB stick as a software-defined radio is priceless if you're working on a wireless project. I've used mine to measure the length of pulses while building a circuit to communicate with a remote control socket, and to check that what I'm building is actually sending data over the air.

#electronics #OpenHardware

Moisture sensor

To know when I need to water my seedlings in the propagator, I got an analogue capacitive soil moisture sensor for £3.67 (including P&P).

The pinout is a simple three-wire interface, with Vcc, ground and the analogue output pin. To read the values, I just needed to do the following in Espruino:

const moistureSensorPin = A5;
const airMoisture = 955;
const waterMoisture = 670;

pinMode(moistureSensorPin, 'analog');

const moisture = Math.round(analogRead(moistureSensorPin) * 1000);
const moisturePercent = Math.round(map(moisture, airMoisture, waterMoisture, 0, 100));
console.log(`Moisture is ${moisture} ~ ${moisturePercent} %`);

if (moisturePercent < 16) {
  console.log('Needs more water');
  // TODO: alarm notification

To get airMoisture and waterMoisture, I took readings from the sensor when it was dry and placed in a glass of water respectively. The map() function I got from the Arduino libraries:

function map(x, in_min, in_max, out_min, out_max) {
  // from
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;

I place the sensor directly under the rockwool cubes of the seedlings to measure the moisture content.

Water level sensor

To detect the height of the water level sensor, I'm using a VL53L0X LIDAR sensor, that uses a laser and time-of-flight measurements to accurately measure distances between 50mm and 1200mm. It's pretty amazing that they can fit a laser and a detector into a package that's barely larger than a grain of rice.

The sensor uses an I2C interface, so I connected the pins as follows:

  • SDA pin to Espruino B3
  • SCL pin to Espruino B10
  • GND pin to ground
  • VIN pin to Espruino 3.3V
  • X pin to Espruino 3.3V (maybe not necessary)

To set it up in Espruino, you just do:

  I2C2.setup({ sda: B3, scl: B10 } );
  laser = require("VL53L0X").connect(I2C2);

To then perform a measurement, you do:

// measure water level
const distance = laser.performSingleMeasurement().distance;
if (distance > 20) {
  console.log(distance, 'mm');
  // TODO: minimum water level notification

I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting

#100DaysToOffload #day67 #hydroponics

For my hydroponics setup there are a bunch of reasons why I would want to be notified of an issue, e.g.:

  • Temperature of range
  • Lights on/off outside of schedule
  • Water overflow
  • Humidity out of range
  • Water level too low

Since my setup is based around using Bluetooth LE for wireless communication, that means I need to think about how to get notified about these issues on my mobile device.

It used to super simple to get mobile notifications in Android from Bluetooth using Eddystone-URLs, but Google disabled this in 2018 due to abuse by marketers. Eddystone and iBeacons are now only supported in native apps.

It is possible to send web push notifications from a PWA, but this requires service worker support, which is not supported by Web Bluetooth yet.

This leaves having a web server somewhere within range of the Bluetooth device, that can subscribe to Bluetooth notifications an send send these out as web push notifications to your mobile device.

Edit: There is also another option: The Physical Web Association now provides an unbranded native app that can be used to interact with Eddystone-URL beacons. Maybe this app can then launch the PWA?

I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting

#100DaysToOffload #day66 #hydroponics

For my hydroponics setup, I want to be able to turn on and off both the LED grow lights and the water pump using a microcontroller. This is typically done using relays, and is the implementation I described in yesterday's blog post.

I've been thinking it over more and realising that having a solution that can be implemented by anybody shouldn't rely on dealing with AC mains voltages and wiring. Smart plugs using Bluetooth or WiFi having been coming down in price a lot, to the extent that they're a viable alternative to relays, especially if you take the cost of AC sockets and enclosures into account. If you don't want to have exposed wiring, you may want to consider putting your electronics inside a plug case.

Smart plug options

Bluetooth LE smart plugs are used by HomeKit and Philips Hue, but they're still a bit expensive at around £30 per plug. They also don't make use of the standardised Bluetooth profiles and services, but implemented their own proprietary BLE services.

WiFi smart plugs are around £10 each, and you can buy a WiFi power Strip with 3 outlets for £30. Unfortunately these smart plugs are getting more locked down, where you may be forced to use the manufacturer's app and proprietary API to get access to the plugs.

Thanks to Espruino's excellent documentation, I found another option: remote control sockets at around £5 each. They operate in the 433MHz range, which means you use a dirt cheap 433MHz transmitter to talk to them.

I really like this last option, as they use a simple wireless protocol that's easy to implement, and they're almost cheaper than using relays.

I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting

#100DaysToOffload #day65 #hydroponics

For my ebb-and-flood (also called flood-and-drain, or ebb-and-flow) hydroponics system, I need to pump water over the flood table at regular intervals. The time between flooding depends on various things, of which the growing medium is the deciding factor:

  • Expanded clay pebbles: 4 to 8 times a day (every 2 to 4 hours)
  • Coconut coir: 3 to 5 times a day (every 3 to 5 hours)
  • Rockwool: 1 to 5 times a day (once a day to every 3 hours)

I'm going to put rockwool starter cubes in expanded clay pebbles, so every 3 hours sounds like a good idea. I then also need to figure out how long to flood the table for, which depends on how quickly the pump floods the table. Let's say it's around 30 seconds, which then leads to the following Espruino script for my Pixl.js:

const floodIntervalMinutes = 180;
const floodDurationSeconds = 30;

const pumpPin = B15;
const waterSensorPin = B3;

setInterval(() => {
  if (!digitalRead(waterSensorPin)) {
    console.log('Water detected!');
    digitalWrite(pumpPin, 0);
}, 1000);

setInterval(() => {
  // TODO: check if daylight
  // TODO: max delay between floodings

  digitalWrite(pumpPin, 1);

  setTimeout(() => {
    digitalWrite(pumpPin, 0);
  }, floodDurationSeconds * 1000);

}, floodIntervalMinutes * 60 * 1000);

function onInit() {
  pinMode(waterSensorPin, 'input');
  pinMode(pumpPin, 'output');

  console.log('Current time:', (new Date()).toString());
  digitalWrite(pumpPin, 0); // make sure pump is off

Note that I also added a water sensor for switching off the pump in case there's an overflow.

What I still need to do is to add a light sensor to check if there's daylight, and then only flood during daylight hours. I then also need add a maximum delay between floodings, so that the plants don't go for more than 12 hours without water. Thanks to ChilliChump for these ideas.

I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting

#100DaysToOffload #day64 #hydroponics

Enter your email to subscribe to updates.