Crazy ’80s – computer design with style

When I hear somebody talking that Apple is the pioneer in the computer design, I always want to show photo of Atari XL series:
Atari 800xl 600xl 1020 1050 1027 series case design

These ones are not the all, they are only ones from my personal collection. Remember, it was introduced in 1982! Full set of distinctive devices: two versions of computers, disk drive and two interesting printers (one is plotter, not printer).

Posted in Anything | Tagged , | Leave a comment

Capacitive soil moisture sensor – designed by retarded

There is a cheap, made in China product called “capacitive soil moisture sensor”. Some black PCB with few components and no coating:
Capacitive soil moisture sensor- crap from China
There are lots of “duino” projects for this sensor. But there are lots of comments about this sensor not working or working strangely and erratically. For my future project I need such a sensor, so I bought one to analyze.

Circuit diagram (schematics) for this “device” is something like this:
schematics of capacitive soil moisture sensor
It is a bit simplified schematics, but I think it is more real compared to internet ones.

The 555 timer is generating high frequency voltage (1.7MHz) to the sensor plate “capacitor” via R1 limiting resistor. This resistor and “moisture” capacitor C1(Cx) is AC voltage divider. Resulting voltage is rectified with diode D1 and smoothered with a C3 capacitor and loaded with a very high resistance R2 resistor (sometimes missing). Resulting DC voltage (with extreme low current) is directly fed to the ADC of the MCU. This is the first error- not all MCU ADC input have such high impedance (resistance), also some parasitic voltages may be present on ADC pin with such high resistance. Also, any contamination of the PCB will drastically change ADC readings. We need to add voltage follower (op amp) to keep impedance high and stable. Also, isolation of PCB is important. Not only in the ADC part, but also on 555 timer to keep it running stable.This sensor (at least mine) does not work from a 3V power source. Maybe there is a very fake 555 timer. Need to investigate it more.

Possible improvements:
1. isolating coating with varnish. Maybe even some epoxy or UV curing one.
2. Remake of AC source. Maybe some crystal oscillator here? Or use something from nearby MCU.
3. Add voltage follower for impedance matching.or… use completely other hardware. something like an advanced capacitive touch controller like MPR121.

The MPR121 uses a constant DC current capacitance sensing scheme. It can measure capacitances ranging from 10 pF to over 2000 pF with a resolution up to 0.01 pF. The device does this by varying the amount of charge current and charge time applied to the sensing inputs.

Posted in Anything, Vandalising | Tagged , | 1 Comment

ARM:0017 – go to sleep clock

This is a “gamers” clock. It sits near the monitor and shows the real time and time computer is on. This is achieved using USB as power supply. Also, the same USB port is used to set the clock. Battery (in this version- super capacitor) is used only to keep the RTC clock on while it is not displaying time.

All components are easily obtainable and are cheap. I think the box for the clock is the most expensive and labor intensive part.

RTC OLED clock bluepill
There are only few components: Bluepill bloard (STM32F103), small OLED screen on I2C bus (optional bus terminators – 10K resistors if missing on screen PCB), supercapacitor (or 3V backup lithium battery) with charging circuit (diode and current limiting resistor). I am using supercap because batteries are dying, meanwhile this capacitor is forever. Supercaps charge is smaller than battery and it keeps RTC for shorter time length, but this is a frequently used clock and it recharges every time the computer is on. Charging batteries is not recommended.

This clock uses a USB COM (CDC) device for communication with the computer and setting the time. To set time, send a time string to the clock and it will be current settings. To do it automagically use windows CMD script, only change port number:

set /p x=%TIME% \\.\COM12

This script is so strange as there are problems in Windows bat files when port numbers are big. This script eliminates possible problems with port naming, also it does not send extra data (like CRLF) to the clock. Clock’s firmware filters data, but there may be some bugs.
If the time is not set, do like with any other “windows” device- remove it and reattach to USB.

Full source code and compiled binaries for the Bluepill are here.

One notable moment in source code is adjusting RTC clock speed. There is a bug in the current version of the cubeMX software. So there is work around:

#define RTC_AUTO_1_SECOND 32767

To keep crystal clock division with a real crystal clock we need to redefine RTC_AUTO_1_SECOND value. Change it to your crystal clock frequency. Fine tuning of the clock is achieved using regular documented ways:


Zeroes are values not used in this MCU. Read manual for further information.

This is the final clock image:
Now it is in “alert” mode, indicating that the user is sitting near the computer for too long a time. Time to finish all games.

Close up of the OLED screen:

Posted in Anything, MCU | Tagged , , , | Leave a comment

ARM:0016 STM32CubeMX – problems with RTC

This is a very short message about proper initialization of RTC (real time clock). There is one trick designed in HAL and in several internet resources it is wrongly described.
Proper RTC init:
Find “MX_RTC_Init(void)“, scroll to “USER CODE BEGIN Check_RTC_BKUP“. Now read one of the available user variables from “backup” RAM and open new “IF“:

if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)!= 0x5051)

Number “0×5051″ is random value, it can be any. Maybe only zero or max value is not good option, as it may be get from uninitialized ram.
Now scroll lots of code and add…

    } // Kitame user code virsuje yra IF komanda. Čia ji užsidaro. (closing IF from beginning)
// LAIKAS BUVO ISSAUGOTAS, NES USER REGISTRAS TURI MAGIC skaiciu 0x5051 (battery backup is valid- we received "magic" number)
// Čia galima ką nors padaryti iš tos laimės arba pagalvoti apie kalendoriaus atstatymą. Sako kad jis nelabai

//Čia įrašom tą MAGIC skaičių. Jis po pilno reseto ir RTC mirties turi neišlikti. (Write "magic" number to RAM)
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0x5051);//Write data to the specified backing area register
/* USER CODE END RTC_Init 2 */

All this stuff is made to force users to validate RTC status. In some internet examples there was even a recommendation to exit init code before full initialization. Meanwhile reading “magic” value ensures that the programmer checks RTC status and initializes it if it fails.

P.S. To start RTC second interrupt just execute this macro:


Posted in Anything, MCU | Tagged , , | Leave a comment

ARM:0015 STM32CubeMX screen libraries, part 2

Continued from Part 1.
There are lots of different LCD or OLED screens in the market. Typically, it is possible to define 3 types of screens according to interface type: I2C, SPI and parallel data bus. There are also analog and LVDS (HDMI) types too, but they are typically not used with weak MCU. Parallel types use many wires for the interface, but are much faster. I2C type is slow, but very useful for a small screen as it can be on the same bus as some sensors. Many I2C type screens do not have a RESET pin, so the init sequence may be very slow. SPI interface is fast (not very fast when refreshing the whole screen) and uses CS pin for device select and D/C pin for data or command selection. Some screens from China do not have CS pin.
The logic of graphic chips is the same, but init sequence and commands may be different. Also, there are some options about the “glass” type, so there is no universal screen driver. Here is some screen collection connected to the same STM32F103 chip and using all the screens simultaneously.
LCD SPI I2C color screens gcc library for STM32F103 ARM bluepill
From left to right: ILI9341 (320 x 240), ST7789W (240 x 240), oldest ST7735R (160 x 128, other configurations optional), SSD1306 (128 x 64), SSD1306 (128 x 32, I2C).

Small screens do not have a full graphics library implemented (who needs to draw a circle on a 32 lines screen?). The font in the library has an error (lost small “A”).
Typically library can do:

  • Draw arbitrary pixel
  • Draw color data to rectangle: fill with color or image data (sprite)
  • Draw horizontal or vertical lines
  • Draw rectangle
  • Print text using fixed size font
  • Print text using proportional font with lame sizing (vertical or horizontal)
  • Print large proportional text (limited font data)
  • Do some hardware tricks: scroll, inverse, change intensity, flip image…

Many libraries use source code from the internet, but some errors are fixed and I added optimization for speed and size. Also, I introduced my errors too.

For example there is some simplification in source code. First line is from popular “programming language”, second is mine:

 for (pixels = 0; pixels < x1 - x0 ; pixels++) { ili9341_send_word(color); }


We save one variable and useless calculations.

Other example. It is more important in speed optimization (for the screens it is very important):

//was, original:
 for(i=0;i < (w * h);i++)
 c1 = *buffer++;
 c2 = *buffer++;

 ILI9341_write_buffer(buffer, w*h*2);


Instead of sending thousand separated bytes, why not to use HAL library to send whole buffer using DMA or interrupt driven routine. Even sending buffer in blocking mode is much faster, than sending thousand of separate calls to procedure for just one byte of data.

There was problem in demo program- the function names for different screens used same variables and macros. In the real word program it is not the problem, because nobody use several different screens in the same project.

All source code for libraries, demo program for STM32F103 (bluepill), compiled binaries are included in archive.
Not all tricks are implemented in libraries- especially hardware scrolling and specific controller chip features.

Posted in Anything, MCU | Tagged , , | Leave a comment

ARM:0014 STM32CubeMX libraries for sensors and screens

In fact, any new program written for MCU is only copy-paste from older projects. Not real copy paste, but using the same libraries and subroutines. For some upcoming bigger project, I decided to use STM32 microcontroller, this means, I need to port several AVR libraries from older projects to the new ARM MCU. Due to historical reasons, older libraries were a bit chaotic. New versions are a bit improved, unified and much easier to use.

STM32CubeMX bluepill gcc libraries for sensors and various LCD screens
Porting somehow was very fast. Most of the problems were with the I2C bus- breadboard I used had some issues and I added additional termination resistors to keep everything stable. Maybe bigger capacitance of the breadboard or bad connections inside.

All sensors and screens are from China, only FM75 is from an old plasma TV set and MAX44007 donated by a friend. Have to notice that my bigger project is partly sponsored by Digitspace web shop. I had no idea what to create next and also I was a bit bored. And one day, I received a letter from them, with an offer to create some any project I wish and they will give some of the needed components. After this, I made a small poll about projects people need for now. I add some engineering touch to poll results and in a few posts I will start step by step articles about one smart thing.

Sensors and screens used in this test are:

  • LM75 temperature sensor, I2C (FM75 is advanced version, compatible with LM75)
  • MAX44007, I2C, digital calibrated light sensor.
  • PCF8574, I2C, 8bit I/O extender.
  • Old school txt LCD ekraniukas on PCF8574 extender. Free 5V – 3V level shifter.
  • SSD1306 OLED screen on I2C bus.
  • Analog input- not external module, but part of STM MCU chip.
  • RTC (real time clock)- also not external, but build in STM MCU.
  • BMP180 Atmospheric pressure sensor with temperature detection option.

Somehow I forgot to add DHT11 sensor code in this post. Sorry. I think in some future post it will be.
The OLED screen is using Commodore 64 font and there is error in font data. Will fix in future.

All libraries are compatible with GNU gcc and STM32CubeMX programs. All files compile without single warning.

Do download source code: OLED screen, sensors libraries compatible with STM32CubeMX and gcc. Compiled versions for STM32F103C8 (Bluepill PCB module).

Some data from sensors are shown on OLED and LCD screens and all data is sent using the USB virtual COM port for debug purposes.

Continued on Part 2.

Posted in Advert, Anything, MCU | Tagged , , | Leave a comment

ARM:0013 STM32CubeMX – USB HID keyboard

Now we will build a USB keyboard. This project is based on STM32CubeMX canned example, HID mouse (see previous article). But we will change mouse to keyboard. Both devices are from the same HID class. First we need to change the device descriptor. Descriptors are quite complex bunch of numbers with strict structure. For this example we will use another program and generate generic keyboard descriptor.

HID descriptor creator
This is a screenshot of a HID descriptor tool from
Continue reading

Posted in Anything, MCU | Tagged , , , | Leave a comment

ARM:0012 STM32CubeMX – USB HID mouse

Next canned project for STM32F103 MCU using the cube- USB HID mouse. HID (human interface device) means it is the standard device compatible with all computers with USB ports. STM32CubeMX has all device descriptors and init procedures already built in.
Select USB device tab and set mode to “Human Interface device class”:

STM32F103 USB mouse hid
Current version of cube software is not flexible- there are no options to change more settings and select HID devices. Also it is confusing- there is no mention that it is a mouse project.
Set all other options like in previous examples, generate code and copy files from previous PS2 project. Why? We need some input and we are preparing for the next project. If you think it is complicated, just download current project files at the bottom of this post.

Continue reading

Posted in Anything, MCU | Tagged , , , | Leave a comment

ARM:0011 STM32CubeMX – Pin interrupts

Next tutorial- interrupts, keyboard (PS2 input) and USB COM port.

I have a small keyboard in my stash. It was from some flop device made by Amstrad. This keyboard has a 4 pin connector and I had hoped that it would be the USB. But after examining, I found it is PS2 only. Good stuff for the tutorial.

Amstrad PS2 keyboard
First we will do the PS2 interface and simply connect this keyboard to a virtual COM port via USB. It is possible to build a direct PS2-USB HID keyboard connection, but this is only a tutorial and we shall do it step by step.
Continue reading

Posted in Anything, MCU | Tagged , , , | Leave a comment

ARM:0009a – bug in CubeMX makefile

First you generate code, then you regenerate code, do make and…

> "make.exe" all
make.exe all -C ..
make.exe[1]: Entering directory 'F:/MyDoks/elektronika/ARM/daiktas-cube/SINGLE_UART'
Makefile:118: *** missing separator.  Stop.
make.exe[1]: Leaving directory 'F:/MyDoks/elektronika/ARM/daiktas-cube/SINGLE_UART'
make.exe: *** [makefile:3: all] Error 2

> Process Exit Code: 2
> Time Taken: 00:00

The bug is in generated main makefile:

# C includes
-IInc \
-IDrivers/STM32F1xx_HAL_Driver/Inc \
-IDrivers/STM32F1xx_HAL_Driver/Inc/Legacy \
-IDrivers/CMSIS/Device/ST/STM32F1xx/Include \


There is a repeated line with “Include”. Just delete that line. Very interesting, but after next code generation this bug will not appear!

Posted in Anything, MCU | Tagged , , | Leave a comment