eForth for cheap STM8S gadgets

Turn cheap stuff from AliExpress into interactive development kits!

Similar projects worth following
STM8 eForth is a compact, structured and tested Forth framework for cheap µCs. Code and binaries are available for a range of STM8 devices and low-cost boards (e.g. the W1209 thermostat or the C0135 MODBUS board).

The list of supported Forth features include idle- and background-tasks, interrupt handlers, I/O redirection, 7S-LED and LCD drivers, analog and digital I/O, on-line evaluation, VOC and word list extensions, and the unique ALIAS feature.

STM8 eForth is based on Dr. C.H. Ting's STM8EF, an STC Forth that procuces machine code. The project uses a recent SDCC tool chain with STM8 assembler and linker for building the Forth kernel, and C can be integrated with Forth for scriptable applications.

The project supports a wide range of STM8 devices and serial interface options, provides a library, uses test automation with uCsim and Docker on Travis-CI, and enjoys e4thcom support for interactive programming.

What is it?

STM8 eForth is among the smallest user friendly Forth systems for µCs: it brings the simplicity of a 1980s style Forth to today's low-cost controllers. The project provides code for STM8 variants, board support for selected low cost targets, and docs. STM8 eForth has a long feature list but it uses very little memory. Innovative solutions, steady support, and an active community makes using it for new projects easy!

The code and binaries on GitHub can be used in many ways:

  • as an alternative firmware for Chinese commodity boards (e.g. thermostats, DCDC converters, and relay boards)
  • build embedded systems with an interactive shell (scriptable and extensible)
  • for creating smart sensors with SPI, I2C, or RS232 and a scripting shell, e.g. for RaspberryPi, Arduino, or ESP8266
  • as an interactive environment for exploring the STM8 architecture
  • for learning Forth - it's easy and fun (find out why in the text below!)
  • ...

Why a Forth for Cheap Chinese boards?

Because it's fun: cheap mass-produced imperfection is a playground for creativity :-)

The W1209 has long been my favourite target: it's a rather complete embedded control board with a UI at a very good price. It's as cheap as it looks, and the challenge is in it's imperfections: the guy who designed the board clearly didn't have a connected application in mind, and I had a lot of fun making it do things it was never intended to do.

There are challenges, like the lack of communication ports. The "sensor connector" can either be used as a a 2-wire RS232 "bus" or for sensing. If you need sensing and communication at the same time the project also provides a full-duplex 3-wire RS232 interface through the key pins (while keeping the keys functional). A plug-in system makes it easy to test new ideas, like using the "update connector" as a home brew field bus interface!

Which target boards are supported?

Besides generic targets for STM8S001, STM8S103, STM8S105, STM8S207 and STM8L051, there is currently support for the following boards:

Some more boards can be supported on request, e.g.

@Elliot Williams worked on using the ESP-14 as an IoT deviced (the ESP-14 module combines an ESP8266 with an STM8S003F3P6).

Programmable power supplies based on the XH-M188 and a cheap DC/DC converter are both work in progress. There are also several types of STM8S003F3 based voltmeters that are known to work.

Read more about possible future targets below.

Why Forth?

Again, because it's fun!

Forth starts out as a stack machine with a tiny instruction set and minimal hardware requirements. It fits in a few KiB, and the target, even a lowly µC, can even be used as the development system. The Forth stack machine is a minimalistic VM on a standard CPU, but there are also hardware implementations (e.g. for FPGAs, or a 144 core Forth processor). The VM is ideal for fast context switching and Forth easily meets hard-real-time requirements. It's no surprise that Forth was used in many NASA projects.

Consider this:

  • compared to other programming environments Forth is easy to understand fully
  • like Lisp, Forth has a REPL (Read-Evaluate-Print-Loop) which enables software testing in a way impossible with "Edit-Compile-Run-Debug" (e.g. Arduino)
  • it's easy to build Domain Specific Languages (one can literally program the compiler!)
  • the stack-oriented "factoring" method results in implicit data flow and modular code
  • Interpreter-compiler, basic OS functions fit in just 4K code :-)

A Forth programmer is in control of all levels of problem abstraction, a unique advantage in a...

Read more »

Original version of STM8EFalong with docs as received from Dr. C.H. Ting on 21/Nov/2016. The docs are worth reading, the eForth binary will run on the STM8S Discovery.

Zip Archive - 21.97 kB - 11/21/2016 at 20:13


  • 1 × ST-Link V2 ICP adapter (e.g. $2.00 from AliExpress) The ST-Link on an STM8S Discovery Board can be used, too
  • 1 × serial interface adapter /w 3.3V signal level (e.g. $0.60) e.g a USB interfacea with a CH340, or better a PL2303, chip
  • 1 × STM8S target device as listed in the GitHub Wiki (e.g. a $0.70 "STM8S103F3P6 minimal system board") e.g. "STM8S103F3P6 STM8S development board" from your favorite China source
  • 1 × Some headers, patchwires, breadboard etc (about $2.00) and other things you fancy, e.g. a RC-servo, SPI display, LEDs ...

  • STM8 eForth 2.2.24.pre1: improved modularity

    Thomas10/20/2019 at 20:21 0 comments

    STM8 eForth 2.2.24.pre1 allows creating new board variants in downstream projects.

    • the release archives contain source files and scripts for building a board configuration
    • the Makefile is now more modular so that application projects can have custom Forth binaries
    • the dictionary can be tailored more easily, e.g. for creating temporary dictionary entries for headerless core code

    On the application side I'm still experimenting (e.g. in the STM8 eForth Modbus project).

  • The STM8S001J3M3 is finally cheap (a small MODBUS sensor board)

    Thomas08/28/2019 at 19:44 2 comments

    Edit: there is now a HaD project for the STM8S001J3RS485 breakout!.

    It's been a while since I last worked with STM8S001J3 chips - ST's contested take on SO8 ATtiny85-like µCs.

    The STM8S001J3 is a member of the "STM8S Low Density" family but it's based on the "STM8S Access Line" cross-breed STM8S903 that offers some (undocumented) goodies.

    I ordered a 10pcs lot for $2.90 including shipping, and decided to make small RS485 nodes (e.g. for MODBUS RTU)  with DS1621S thermometer chips that I happen to have lying around.

    I made my last PCB with KiCad5.0 - updating to the latest version, especially the library handling, required some reading (I'm now using 5.1.4).

    A µC with merrily 5 GPIO pins is a good shield against feature creep, but the following things "had" to be included:

    • narrow PCB for a cylindrical sensor with less than 8mm diameter
    • 5V supply, 3.3V internal power supply
    • basic signalling LEDs
    • most GPIOs, including I2C bus and an analog input available on a header

    The design is really simple:

    Components occupy both sides of the PCB of 34mm x 1/4" (minimal width supported by @oshpark ).

    On the front side is the STM8S001J3M3, a LDO regulator and some caps:

    The RS485 transceiver and the thermometer chip live on the backside:

    The board has two intended applications: either a stand-alone bus coupled temperature sensor, or a minimal µC component, e.g. for a quick perfboard design.

    I ordered from @oshpark - uploading my KiCad 5.1.4 file worked right away, and creating Gerber files wasn't necessary!

    Files and docs are, as usual, on GitHub.

  • The STM8S003F3P6 is cheap again!

    Thomas08/03/2019 at 09:54 33 comments

    When I started this project the STM8S003F3P6, an STM8S Value Line µC with 8K Flash and 1K RAM in a TSSOP20 package, was the cheapest device in its class. Cheap enough to enable an industry of low-cost electronics control devices, e.g. thermostats or voltmeters, with the left-overs of mass production runs. This market for low-mid-range µCs encouraged Nuvoton to market the mostly pin-compatible N76E003AT20, an 8051 family device.

    For the initial goal of this project this was bad news:  from then on the Nuvoton chip was the go-to device on the spot market, a chip with an architecture utterly unsuitable for a self-contained Forth system!

    Right now, however, the STM8S003F3P6 is at a very low price point: I just received 10 pcs for $1.86, which is as low as it gets!

    Don't get me wrong, the Nuvoton chip won't disappear and it's very likely to receive a thermostat like the W1209 with an "non-hackable" chip but at least the TSSOP20 package can be soldered with ease.  

  • STM8 eForth 2.2.23 released

    Thomas05/28/2019 at 19:00 0 comments

    Don't expect  breaking changes - the STM8 eForth core is quite mature now.

    The default build environment got an update to SDCC 3.8.6 (but it was tested with SDCC 3.9.0, too), and the binary export from uCsim got an upgrade (it's a nice Python script now instead of a lean-and-mean AWK scriptlet).

    More internal constants can be exported with #require, STM8L chip got better support thanks to @Eelco. Coding with inline machine instructions is easier thanks to a number of bit copy and assembly interface words.

    And of course, there is more docs.

    More info is in the release notes:

  • GitHub Project for STM8EF-MODBUS

    Thomas02/10/2019 at 21:54 0 comments

    STM8EF-MODBUS deserved a GitHub project, of course with Travis-CI build automation, and docs.

    Some of the properties are rather cool, e.g. the modular architecture and the clear separation of concerns between MODBUS protocol and other application logic :-)


    Right now, on Aliexpress, the "MODBUS-RTU 4 way relay module STM8S103 MCU" is available at a good price: $6.65 incl. shipping.

  • STM8S eForth Interrupts Docs and other Wiki Updates

    Thomas01/20/2019 at 10:14 0 comments

    STM8 eForth is now a serious alternative to coding C coding for STM8 µCs, especially if Flash space is a premium or if interactive features or configuration in the field are required.

    Recently, many other pages got updates. Especially a lot of graft was moved from the STM8 eForth Programming introduction page to improved topic pages in the Wiki.

    The Forth VM makes context switching very efficient. In my opinion (I wrote many interrupt handlers for industrial and safety critical applications), implementing interrupts in Forth is easer than in C.

    The STM8 eForth Interrupts in the STM8 eForth Wiki explains the bit that there is to know. The MODBUS server and the nRFL01 libraries implement low level code using STM8 interrupts.

    As an example, here is the STM8S UART RX handler from the MODBUS library:

      \ RX ISR handler
        \ P1H
        UART1_DR C@  ( c ) 
        rxp @ ( c a ) DUP rxbuf - ( c a len ) RXLEN < IF
          ( c a ) SWAP ( a c ) OVER ( a c a ) C!
          ( a ) 1+ rxp !
        TIM tstamp !
        \ P1L

    This example contains many stack comments (the stuff in round brackets) and just a bit of code for copying characters from the UART to a buffer, protecting against buffer overrun, and providing a time stamp for the MODBUS "end of transmission" detection.

    The most striking point is that in this use case Forth is much more used as a macro assembler for a very simple virtual machine than as a programming language. The programmer builds the most simple "machine" that will do the job. No unnecessary abstractions.

    Links to these libraries are on the examples page.

  • New Pre-Release STM8 eForth 2.2.23.pre2

    Thomas01/12/2019 at 09:15 0 comments

    I kept STM8 eForth stable for a long time but now there is a good reason for preparing a new release:

    For the current work on a very lightweight MODBUS Server in STM8 eForth I needed some data from the target (e.g. clock frequency), and some other aides for low-level programming (e.g. an easy to use and stable interface between Forth and machine code).

    The implementation of MODBUS in Forth is a pleasant experience: Moore's problem oriented language approach works quite well for embedded control and protocol implementations. I simply design the machine so that it implements layers of a protocol, and I do that in a language that describes the problem well. Thereby a language emerges, because my abstractions either describe the problem well, or I change it so that it describes the problem better.

    It's safe to say that the implementation is very code efficient and highly functional at the same time (thanks to an interpreter-compiler on a MODBUS node).

    Before the release of STM8 eForth 2.2.23, I'd like to improve the compilation of Forth code in the continuous integration environment.

  • MODBUS RTU with STM8 eForth

    Thomas01/02/2019 at 17:30 0 comments

    Edit: there is now a GitHub project:

    One STM8 eForth needs something that I had planned to implement for a long time: a basic MODBUS server with RTU communication (serial binary protocol).

    Implementing a MODBUS RTU server requires some of the following:

    • understanding MODBUS vernacular,
    • writing test code (with JAMOD and,
    • ISR timing validation, and
    • fixing odd bugs

    I wrote the UART ISR code in Forth: on a 8bit µC that's fast enough for 115200 baud full-duplex, or for 240400 baud half-duplex MODBUS RTU!

    The diagram shows full-duplex mode at 115200 baud. The ISR do buffer bounds checking and media access control (including MODBUS timing requirements).

    A Forth "idle task" builds the MODBUS response. The "background task" is free for local logic (i.e. following the input-process-output pattern).

    Right now some simple MODBUS FCs are implemented (FC01 & FC05, some of FC02 & FC16). More FCs will be implemented when the need arises.

    The code is very compact: the basic implementation is in 300 lines of Forth code (including debug code). Before optimizations 1.4K Flash are needed .

    A (long) discussion around the development is here.

  • An STM8 eForth WS2812 Demo

    Thomas12/24/2018 at 12:45 0 comments

    Controlling the WS2812 with STM8 eForth was something I've had on my to-do list for a long time. The lore of W2812 timing is already long and twisted, and any new implementation, it seems, has to add a bit to it :-)

    Mine is the following: 

       Do it the Aristotle way: Relax the timing but maintain the balance!

    I coded the inner loop for a byte transfer and the bit timing in assembly (in a self balancing way). The outer loop is coded in Forth. The result is quite compact:

      : WS2812 ( a1 a0 -- )
         DO  [
               $1601 ,         \     LDW  Y,(1,SP)
               $90F6 ,         \     LD   A,(Y)
               $88   C,        \     PUSH A
               $A608 ,         \     LD   A,#8
               ] [ 1 PB_ODR 4 ]B! [
               $0901 ,         \     RLC  (1,SP)
               $9D  C,         \     NOP
               $2504 ,         \     JRC  1$
               ] [ 0 PB_ODR 4 ]B! [
               $9D  C,         \ 1$: NOP
               $9D  C,         \     NOP
               $9D  C,         \     NOP
               $2404 ,         \     JRNC 2$
               ] [ 0 PB_ODR 4 ]B! [
               $9D  C,         \ 2$: NOP
               $4A  C,         \     DEC  A
               $4D  C,         \     TNZ  A
               $26E5 ,         \     JRNE 0$
               $84 C,          \     POP  A
         ] LOOP ;

    I tested the code by comparing the sensitivity of the reshaped bit timing at the output of the WS2812B.

    The code and some findings are here.

  • Better Docs and Using C in STM8 eForth

    Thomas12/09/2018 at 09:32 0 comments

    I reviewed the STM8 eForth Wiki under and tried to make it more readable for the casual visitor. Also removing some of the Forth evangelizing hyperbole doesn't hurt. Forth is still amazing, not only for philosophical reasons, but nobody likes Forth extremists, right?

    Another activity is experimenting with interfacing STM8 eForth with SDCC C. Use-cases, approaches and the progress so far have been documented in Add/mix/graft STM8 eForth into a C project.

    I found no documentation on parameter passing in the SDCC STM8 port, and after some experiments I have the following hypothesis:

    • parameters are copied to the return stack in the relevant size, ready for access with "SP indirect addressing", and in the reverse order of the definition
    • 8bit return values are in A
    • 16bit return values are in X
    • 32bit return values are in MSW X - LSW Y

    SDCC passes most data on the (return) stack. The main difference to a stack oriented language is that this parameter passing behavior is not defined in the language, it's a mere implementation detail. The effect is that stack transfers have to be done over and over again, which creates a lot of waste.

    From the software engineering point of view it becomes apparent that a minor change of paradigm (maintaining the stack is the responsibility of in the called function instead of the calling function) can be the defining feature of the architecture.

View all 133 project logs

  • 1
    Step 1

    Get some cheap hardware (e.g. a STM8S103F3P6 breakout board for $0.65 and a ST-Link V2 dongle for $2). download the binary release, flash it, and have fun!

    If you like it, and you want to hack board support code for your favorite STM8China gadget, you need:

  • 2
    Step 2

    a Linux SDCC tool chain installation (installation instructions for SDCC & stm8flash are in the Wiki)

  • 3
    Step 3

    Clone the project on GitHub

View all 4 instructions

Enjoy this project?



jaromir.sukuba wrote 01/23/2017 at 05:17 point

Another tip for *possible* STM8 target

I didn't buy this one, haven't seen the schematics, but to me it totally smells like it could have STM8 under the display. Googling for XK-001T-1 didn't bring much info, though.

  Are you sure? yes | no

Thomas wrote 01/23/2017 at 06:18 point

Yes, that's possible. In most cases one won't find any schematics, and also the XH-, XK, M- or B monikers aren't always used the same. There is a small list of modules that are very likely STM8S based in the Details Section of this project (in the section "How can I spot suitable boards?"). If there is any interest, I can publish a list with advertised properties and the "street price".
Edit: here is a link with a picture showing the PCB legend:
Based on the outline of the µC I would expect it's not STM8 but a STC15 based, a µC which I've seen several times on "timer" boards (MCS51-like

  Are you sure? yes | no

Elliot Williams wrote 12/13/2016 at 23:13 point

Got my ESP-14 up and running last week, and then got distracted.  :)

Short story: it's just a STM8 chip and an ESP8266, like it says on the package.  The TX/RX lines are internally connected, so I was running your Forth on the STM8 with the ESP8266 powered down, and running all manner of software on the ESP with the STM8 powered down.

Been thinking about how to use both at once. 

a) Jeelink is a nice transparent serial port over ESP8266, which would provide remote wireless development of the Forth system on the STM8.  The idea of telnetting over WiFi into an STM8 is funny enough that I'm definitely going to do this.

b) Since the serial port is the only way in to the ESP8266, and the STM8 has only that one hardware serial port, I suppose that bit-banged serial or I2C/SPI could be used to talk to the console. I don't know how hard/easy this is. But then you'd have an STM8 that could issue AT WiFi commands, for instance, or run routines in NodeMCU, which might be very cool.

c) The other option is to code up the ESP and STM8 to take turns based on control characters: 0xFE toggles the ESP on/off the line, and 0xFF toggles the STM8, for instance.   This requires modifying _both_ firmwares, but would allow for the console, ESP, and STM8 to share the UART lines and talk to each other.

Just brainstorming so far. No real hacking yet. 

The breakout board I made for the module just fit it onto a breadboard, because I didn't really know what to expect from the module. It will probably want a transistor so that the STM8 can turn off the ESP8266 for power-saving when necessary, and will certainly want at least a jumper for flashing the ESP.  

Thanks for the case insensitive addition, and for do loops! This is a fun system to play around with.

  Are you sure? yes | no

Thomas wrote 12/14/2016 at 19:31 point

Options a) and b) look good to me, especially in combination. How about connecting a PNP transistor for the ESP8266 power supply to PD1/SWIM? Normally one would access the STM8 serial port through ESP-Link, and the ICP interface could be used for direct access to the ESP8266 serial interface by simply pulling down both NRST and PD1/SWIM. Direct serial access to the STM8 could be acchieved by telling it to power the ESP8266 down (this might even work using PD1/SWIM once more, e.g. by using an RC element which can be detected testing its timing).

Option c) would also be possible, but at least one of the devices would have to be able to swap RxD and TxD, and the other devices would need a "tristate" mode on TxD. The Bus approach I took for the W1209 might also work for more than two devices.

A fourth option could be to have a Forth word that issues the initialization AT commands on the STM8, and execute it with 'BOOT.

I hope to find the time for some hardware hacking in the holiday season :-)

  Are you sure? yes | no

Elliot Williams wrote 12/16/2016 at 21:22 point

"esp-link" not jeelink.  Tried it and had a telnet / web-console controllable STM8 running your Forth.  Took like 10 minutes.

Then I spent 3 hours trying to implement something like c) in NodeMCU.

First, I thought I'd set up two TCP connections: one for the ESP to be executed locally, and one to pass through to the STM8.  Didn't work b/c NodeMCU can only do one TCP connection, it seems.

Then I thought I'd use MQTT as the transport mechanism.  But there's some glitch there with MQTT and the UART port not working right.  I'll hack more at it before I give up, but it might be time to move on to MicroPython or ESP Basic for the interactive ESP part.

Anyway, try out the esp-link for the ESP when you get around to it.  It's kinda fun.  It _does_ however leave me wanting a more capable microchip on the remote end.  For another couple bucks, I could get a lot more flash, peripherals, and etc to tether to the ESP.

All of this playing around has helped me refine what's needed in a breakout board for this thing, though.  :)

  Are you sure? yes | no

Thomas wrote 12/16/2016 at 22:35 point

Again great news, and I'm going to test esp-link too. Multiplexing communication through MQTT topics was the first thing that came to my mind. About a year ago I tried working with MQTT and NodeMCU, but I was disappointed with the stability of the platform (though I really liked working with Lua).
I guess that the case for ESP-14 is rather thin: as I mentioned before, it looks more like proof that the ESP8266 wasn't able to meet customer requirements than like the solution the world's been waiting for. But who cares as long as it's fun hacking.
In my opinion, a decent Forth environment on the ESP8266 would be rather attractive: C.H. Ting hacked something recently, but it was just the kernel, not a complete framework with persistent vocabulary (and maybe even with source stored in the Flash memory, and maybe even a JavaScript based IDE served from an embedded web server on the chip).

  Are you sure? yes | no

Thomas wrote 11/28/2016 at 21:33 point

Hi Elliot, it's great to hear that someone got it running, and that the docs were good for a smooth start. Anyhow, congrats for the "STM8EF Blinky"! Did you try to do that BG style, too? 

I had a look at the CAPS issue (yes, I've been thinking about that for a while ;-) ). There are some potential clashes (e.g. PARSE/parse, NEXT,next, ABORT"/abort") but the lowercase words are the hidden "implementation part", and I don't see that their name is set in stone. I decided to name them after their assembly labels (pars, donxt, and aborq). 

New code with lowercase support is on GitHub (just set CASEINSENSITIVE = 1 in If you'd like to give it a try without building, please let me know (I can drop a binary into the files section here). If there are no issues I'll make it the default.

The ESP-14 will be one of my next targets. However, I didn't find the time to make a breakout PCBs with power supply for this module. Controlling the ESP8266 supply through the STM8S003F3 would be cool. If someone with good access to PCB prototyping could do that job I'd be more than happy to contribute some ideas about the schematics.

  Are you sure? yes | no

Elliot Williams wrote 11/29/2016 at 15:57 point

I just got an ESP-14 in the mail from ebay today.  I'll be making a breakout for it sometime in early Dec.  (Right now, I'm churning out HaD articles like mad.)  I'll share when I do.

I still have no idea if it makes any sense to run a (powerful) ESP8266 off of a (much smaller) STM8 chip.  But I'm willing to find out.  :)

I also ordered one of those LED/relay boards. Again, just for fun, but maybe I'll do something with it.

Thanks for thinking about caps.  I'll definitely rebuild and reflash. 

No, I didn't get into the multitasking / backgrounding. I just got the thing up and running, not much more.

  Are you sure? yes | no

Thomas wrote 11/29/2016 at 19:13 point

The ESP-14 is quite strange. I can only guess that an OEM required a solution from Espressif that meets non-functional constraints (e.g. dependability, power consumption, or periphery set) that could not be met by the ESP8266. I don't think that a lack of skilled programmers was the reason. The power consumption of the STM8S003F3 in "active halt mode" is quite low, and for a data logging sensor node a battery life of a year or more with a 100mAh battery might be feasible.

The W1209 boards are really fun, especially with a background task. When you try using STM8EF with it, please let me know if the docs for the single wire half-duplex solution are sufficient.

About the case-insensitive input: you're welcome (the option has a price tag with "23 bytes" on it :-) )

  Are you sure? yes | no

RigTig wrote 12/15/2016 at 10:44 point

I've created an adapter for ESP14 (and ESP12) to 22-pin DIL, if you haven't done anything else yet (see new project here called 'ESP-12 and ESP-14 adapter to DIL'). My ESP14s arrived today!

  Are you sure? yes | no

Elliot Williams wrote 11/28/2016 at 13:54 point

Hiya! Been following along, finally got a few minutes to flash stuff to one of those min-dev boards.  Great fun!  I haven't done anything useful with it yet, but I've gotten the LED blinking, naturally.

One thing that's driving me nuts is the ALL CAPS commands.  Is there an easy way to either a) lower-case them all or b) make it run case insensitively?  Or would that cause namespace clashes? It makes my shift-finger hurt. 

And that's it for now.  I have to say that your directions (combined with some of the links that you list) made it very easy to get up and running with the system.  Thanks!

I'm planning a few Forth columns for HaD, and I'm still collecting chips that have working implementations.  You've added one more to the list. 

Oh, and I've ordered an ESP-14.  We'll see how that goes.  Looks like fun. 

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates