W1209 Data Logging Thermostat

The W1209 thermostat is cheap, but it's about time that it learns new tricks!

Similar projects worth following
W1209 thermostats are incredibly cheap (below $1.50), and so "easy" to use that there about 30.000 YouTube videos that explain how to "program" one. This project is here to change that: using STM8 eForth the behavior of the board can be scripted. In fact, only a serial terminal program is needed to write a new program!

This project turns a W1209 into a thermostat with a programming console, and a data logger feature. It provides easy to follow instructions, and also gives a gentle introduction to Forth.

Features are:

  • heating thermostat, e.g. for building a chicken egg incubator
  • no special tool installation necessary:
    • ready-made binaries, and source code, are provided
    • new binaries can be built with the help of Travis-CI
    • interactive programming in Forth, even while the thermostat task is running!
    • any serial terminal program can be used, e.g. picocom, or cutecom (settings 9600-N-8-1)
  • data logger with 6 minutes (0.1h) to 10h interval, and a 144 entry ring-buffer with log access through a serial console:
    • Lowest temperature
    • Highest temperature
    • Heating duty cycle
    • Number of relay cycles
    • L.dump command prints the log through the serial console - the latest entry is in the last line
    • L.wipe command erases the log memory
  • basic sensor failure detection
  • easy to use parameters menu (no need to search for a manual!) for set-point, hysteresis, and trip-delay

  • 1 × W1209 Your favorite low cost thermostat unit!
  • 1 × USB-RS232 dongle with TTL interface CH340, FTDI, Prollific, or old cell phone cable. Should be compatible with 5V signals.
  • 1 × ST-Link V2 adapter Cheap if you're ready to wait for one to arrive from China. The cable that usually comes with it can be cut iin the middle and used to make the ICP and the serial port connections :-)

  • A Curse and a new Binary Release

    Thomas05/16/2020 at 09:02 0 comments

    Getting started with any new technology involves a learning curve. If more than one new concept is involved then the learning curve can appear "steep". A good part of that steepness comes from those talking about the technology: they assume too much about what the non-initiated will understand. That's known as the curse of knowledge.

    I got a good demonstration of the curse when helping someone to get started with the W1209 Data Logging Thermostat. Things I took for granted were everything but, and bugs were lurking behind them.

    You live and learn: if someone can't use the docs to get started find out why. Refactoring should not only look at the technical side, but also at how accessible the code is. One recent development that made maintaining and using STM8 eForth projects easier is the modular build: it's no longer necessary to develop board-support and core in lockstep since the board support code can be maintained in the application project. The result is easy to use binary releases for applications.

  • A W1209 Software for Cooling Food with a Peltier Element

    Thomas02/03/2019 at 20:44 0 comments

    @paulcrawfordgm turned the W1209 Data Logging Thermostat into a cooling controller with a serial interface:

    The project started here on HaD, continued with an STM8 eForth issue, and was completed in TG9541/W1209 issue #22.

    Paul achieved the following:

    • coping with a non-standard W1209 board variant (Nuvoton chip, 5K NTC pull-up)
    • set-up of Travis-CI for Paul's fork of the TG9541/W1209 repo
    • changed control.fs from heating to cooling
    • menu adapted and simplified, logger.fs removed
    • serial interface for temperature data with counter and CRC-16

    The process of problem resolution and the Forth learning process worth reading!

  • Menu problems while using serial console fixed

    Thomas02/02/2019 at 23:06 0 comments

    Among other things, e.g. using the W1209 firmware for cooling, a problem with the menu has been fixed: transmitting characters quite often resulted in erroneous key inputs.

    Now that has been fixed in the master branch. The discussion inIssue #22 is also quite interesting!

  • A different type of thermostat: a Solar Heating Controller

    Thomas09/26/2018 at 17:57 0 comments

    Solar heating controllers need at least two temperature sensors. Such a thing can be hacked using a W1209, but I decided to design a new PCB (mostly because I try to avoid relays in things that I expect to work for more than 10 years unattended).

    To keep a log of my progress I started a HaD project Solar Heating Controller. Maybe it catches your interest!

  • More-or-Less Compatible W1209 Clones

    Thomas02/09/2018 at 20:11 0 comments

    A GitHub user documented a W1209 clone with a common anode display. This issue describes how to spot such a clone, and it also contains code patched for using the CA display. This board will be supported in the near future.

    I found one more clone with a different PCB layout, and I ordered one for examination.

  • Which W1209 boards *not to buy* if you want to run the code here

    Thomas01/31/2018 at 20:11 0 comments

    @richard got a couple of W1209 boards, and some of them just couldn't be flashed. It turns out the at least one manufacturer (namely TENSTAR ROBOTS) makes boards with a nearly pin compatible 8051 based µC (a Nuvoton chip in a TSSOP20 package). Details are at the end of the GitHub Issue here.

    Mitigation: don't buy boards that look like one of these:

    Note that C5, the Vcc capacitor next to the µC, is unpopulated. The backside of the black board is bears the label "TENSTAR ROBOT W1209". The label on the back of the green board is "XH-W1209". The Nuvoton is quite fast, and if you like programming the 8051 it's maybe not the worst choice. However, please don't count on my help for programming it. I'm done with MCS51 ;-)

    @BigVulcanDeal let me know that there are boards with a 5k, instead of 20k, reference resistor. That's a good match for measuring temperatures in the range of 30°C to 50°C, but you'll need to replace the linearization table in measure.fs.

  • Release 0.2.0: improved Data Log, better Sensor Filtering

    Thomas12/17/2017 at 10:24 0 comments

    I've just release a new, improved version of the W1209 Data Logging Thermostat: now the data logger registers the following data:

    • relay activation cycles per log interval
    • relay duty cycle
    • lowest, and highest temperature in the cycle

    Used properly, this data can be used to improve the control behavior (heating power), or for getting clues on the effects of heat flow & thermal mass, sensor location, or quality of the insulation:

    w1209-log2Check out the README on Github for features, source, and instructions!

  • Temperature Logging with the W1209

    Thomas12/10/2017 at 09:45 0 comments

    By default, the firmware exploits the fact that the Value Line STM8S003F3 µC is just a STM8S103F3 with relaxed specs, and with only 128 bytes of EEPROM memory specified. All the chips I tested hat the full 640 bytes of the "Access Line - Low Density Devices" available, and I decided to use all but 64 bytes as a ring buffer, enough for more than 24 hours at a rate of 10 samples per second.

    The ring buffer requires a single head pointer, which, for practical reasons, must be in the EEPROM. The number of EEPROM write cycles of Value Line devices, however, is specified with 1x10^5, in the full temperature range with nominal data retention, that is. At a rate of 10 log entries per hour a 20ct µC is still good for 10.000 hours, more than a year.

    I have little doubt (not "little doubts", like my Indian colleagues usually say when the strongly disagree) that the number of write cycles at room temperature, and with random data, is more in the range of 1x10^6, more than 10 years. The "electrical life" of a Chinese low-end relay in a thermostat application is most likely much shorter.

  • Minimal Viable Product

    Thomas11/26/2017 at 16:41 0 comments

    There is finally the the first (pre-) release of the W1209 $1.50 data logging thermostat!

    It's based on the latest STM8 eForth (pre-release 2.2.20.pre.1), and the binary was automatically built in uCsim, and deployed, by Travis-CI.

    Features are:

    • heating thermostat, e.g. for building chicken egg incubators
    • basic sensor failure detection
    • parameters for set-point, hysteresis, and trip-delay
    • easy to use parameters menu (no need to search for a manual!)
    • temperature logger with 0.1h to 10h interval, and a 288 entry ring-buffer
    • logger access through a serial console
    • fully programmable in Forth, even while the thermostat is running!

    Although it's feature-complete, it's work in progress.

    For the future, the following feature are planned:

    • Improved logger with min/max temperature, and heating duty cycle
    • Field-bus feature for thermostats
    • more fail-safe features (parameter integrity, maybe a buzzer)

  • Dependencies up-to-date: the Makefile now installs STM8 eForth

    Thomas11/04/2017 at 18:57 0 comments

    It's been a while since I last worked on this little project. The reason was that I concentrated on the STM8 eForth foundations:

    • development framework with a Forth library
    • e4thcom support
    • with emulation of the e4thcom features #include, #require, and \res
    • automatic generation of "aliases" for unlinked words in STM8 eForth words
    • Continuous Integration/Test/Deployment with Travis-CI

    The GitHub W1209 repository now also uses these goodies, and the Makefile automatically installs the specified revision of STM8 eForth from the binary release.

View all 13 project logs

  • 1
    Set Parameters

    Press "set", and use the "+" and "-" keys to navigate the menu. Press "set" again to edit a parameter. Store with "set", or wait about 10s until the menu times out.

  • 2
    Apply the Thermostat with the help of the Data Logger

    Install the thermostat in your installation, as you would with the original firmware. The sometimes difficult task of optimizing the control behavior can be simplified by using logged data. Refer to the README for instructions.

  • 3
    Prepare the W1209

    Follow the instructions on the STM8 eForth W1209 wiki page to erase the original W1209 firmware, and program the thermostat binary in the file on the W1209 data logging thermostat releases page. After flashing, make sure it starts up (the display should show the temperature, or "DEF." if no sensor is connected. To initialize the parameters in the EEPROM press the W1209 "+" and "-" keys for about 5 seconds ("RES." should appear).

View all 3 instructions

Enjoy this project?



notsosure wrote 11/06/2023 at 01:10 point

Got clones with c5 unpopulated FT61E143 and these are factory set wrong. the factory temperature settings are unusable. p1 min 0.1 max 20. p2  min 24 max 120. p3 min -55 max 14, p4 min -10 max 10. p5 min 0.1 max 10 p6 ON OFF. no p7, no p8. the red light does come on on these but the relay does not get triggered at all while red light does light up. Can these be set to 'normal' settings? Will need STM8S003F3 and what to populate c5? How to trigger the relay.

sidenote:  have rex100 ac but want to use on 12v battery. what is a good cheap 12v to 220v converting option to use without loosing too much electricity from the battery? It has to last all night. Standard inverter gives up beeping loudly in small hours of night. 

  Are you sure? yes | no

Roy wrote 11/01/2023 at 19:38 point

Many years ago I had much success with the W1209 eForth. I just bought 4 more XH-W1209 from BG and the microcontroller is not an STM8S but a 16-pin SOIC (Fremont Micro Devices) FMD FT61E143.

  Are you sure? yes | no

Thomas wrote 11/05/2023 at 15:12 point

Yes, it's sad. The "era" of easily modifiable cheap modules is certainly over. Not long after I worked on the "logging W1209" the first variants with Nuvoton µCs appeared on the market. Now, after the COVID-lockdown induced chip-crunch, all bets are off.

  Are you sure? yes | no

paulcrawfordgm wrote 01/21/2019 at 20:48 point

I have installed "sdcc" on my MacBook Pro and it works (gives its version). I understand from other sites and the sdcc manual that I need to compile each source file separately and then link all of the .rel files together with another call to sdcc. I tried to compile only main.fs from the 15 April 2018 version and got the following error message:

at 1: error 119: don't know what to do with file 'main.fs'. file extension unsupported

which tells me that I can compile "c" source code files but not .fs source code files.

Is there anywhere an example of how the eforth source files for W1209 were compiled and linked to make W1209-FD.ihx? If I can do that I can easily flash that file onto my stm8 µC.

  Are you sure? yes | no

paulcrawfordgm wrote 01/20/2019 at 19:07 point

More review reveals that what I need is "sdcc" to do the compile. Why is "sdcc" not called from Makefile? I tried flashing the 15 Apr 2018 version of W1209-FD.ihx again and it still just gives garbage characters on the display. Why does it not work?

  Are you sure? yes | no

paulcrawfordgm wrote 01/19/2019 at 03:54 point

I ordered a W1209 from China making sure that C5 was soldered in place in the web site photo. When I got it though, it could not be programmed and I determined that the µC was not an STM8S003F3. So I ordered 10 STM8S003F3 chips and then desoldered the substitute chip and replaced it with the STM8S003F3. Then I was able to program the W1209. I found the same issues that @BigVulcanDeal found though: the temperatures were wrong and the log feature ran continuously rather than for 144 values. I really don't need the the log feature as I am going to send the temperature value serially to an ATMega328P but obviously I need correct temperatures to control a Peltier 12V cooler. The code I flashed to the W1209 was "W1209-FD-forth.ihx" from 17 Dec  2017. I am running this from a MacBook Pro with CoolTerm as my serial terminal. From it I can access eForth on the W1209: e.g. "2 2 * . 4 ok", so it seems that everything is working except the temperature value is wrong. I then cloned W1209-0.2.1 from GitHub and edited the source file "measure.fs"  to change the values in dig2tem. After running make all I flashed the µC but only 5226 bytes of data went in compared with 8192 bytes with the working hex file. There was no temperature shown on the display, only garbage characters. The file that got flashed was "out/W1209-FD/W1209-FD.ihx" but its date was 16 Dec 2017. I also got W1209 with a date of 15 Apr 2018 for the same file but it would not function on W1209 either. I was surprised after editing the source file and running "make" that the hex file date did not change. I am used to doing "make" on c files and the date always updates so clearly I am missing something fundamental here. Are there any pointers you can give me to make the W1209 work with an edited source code file? Thanks.

  Are you sure? yes | no

Thomas wrote 01/26/2019 at 10:24 point

Hi Paul, sorry for the late reply here - HaD didn't notify me about the messages.

To other readers of this thread:

Paul managed to figure out most of how this project differs from the norm, and got the STM8 eForth framework working (no small feat).

Please refer to the following GitHub issues:


If I don't react here, please open an issue on GitHub (notifications there work reliably).

  Are you sure? yes | no

BigVulcanDeal wrote 02/01/2018 at 04:49 point

I made a simple Google Docs spreadsheet that can be used to calculate the values for the dig2tem table if you have a "non-standard" pull-up resistor for the sensor.  Enter the resistor value in k-ohms in cell A2, copy the dig2tem values from M2:M15.  The digtem values will be about right .. then use the correction parameter to tune for best performance at the temperature range of interest.

  Are you sure? yes | no

BigVulcanDeal wrote 01/18/2018 at 06:32 point

I managed to install stm8flash and loaded the Dec 17th binary on my W1209, but the temperature is slightly ridiculous .. it shows up like -5.9 degrees.  Is there an easy way to correct this?  

As an aside, amazing project .. haven't used Forth in quite some time (well over 20 years).

  Are you sure? yes | no

BigVulcanDeal wrote 01/18/2018 at 06:39 point

Also, L.dump seems to print continuously.  Is this how it is supposed to work?

I will hunt around to see if I can answer my own questions .. you managed to put a lot of material together.

  Are you sure? yes | no

Thomas wrote 01/24/2018 at 19:27 point

Writing more stuff is faster than improving what's already there. If you find something that's hard to find, or that's not clear and needs better explanation, please let me know.

  Are you sure? yes | no

BigVulcanDeal wrote 01/19/2018 at 03:46 point

I guess this is a matter of changing the dig2tem array to map to the actual sensor that I have ... apparently this RTD, or the resistor used with it, is different.

Apart from the temperature weirdness, the flashed board seems to work properly.

  Are you sure? yes | no

BigVulcanDeal wrote 01/19/2018 at 05:09 point

So, I found that my W1209 has a 5.2 K resistor where most have a 20k resistor.  This is good from the standpoint that it makes the sensor more sensitive at the temperatures that I care about .. however, I am unclear on how to get the source for the latest W1209-FD, build it from scratch, and then flash the board.  Once I know how to do that, I can tweak the dig2tem array.  When I clone the repository and make all, I end up with what seems to be a generic FORTH image on the board.

  Are you sure? yes | no

BigVulcanDeal wrote 01/20/2018 at 02:51 point

And the answer is .. make load

  Are you sure? yes | no

Thomas wrote 01/24/2018 at 19:33 point

Building from scratch should work. Alternatively you can fetch version 2.2.20 from the tg9541/stm8ef Github releases page (you need the board variant W1209-FD in the zip file). However, the Makefile in the tg9541/W1209 repository resolves the dependencies for you when you run "make depend". Finally, if you just use the thermostat binary file you just need to run "reset" on the command line to remove the Forth application code. If you do that from e4thcom you only need to run "#i main.fs" to load your code.

  Are you sure? yes | no

BigVulcanDeal wrote 01/22/2018 at 03:58 point

After a bit of floundering, I managed to 

- flash the board, 

- figure out about "make load", 

- alter the code in measure.fs to change the dig2tem table to handle a 5k resistor for the RTD (as opposed to the 20 k resistor presumes in the script)

- add accessor functions that allow me to read/write the various EE values (EE.SET etc.)

The only issue remaining is that I was unable to get logger.fs to load .. so I just commented it out, along with the call to "logger' within "task"

  Are you sure? yes | no

Thomas wrote 01/24/2018 at 19:24 point

Hi, sorry, for some reason I didn't receive notifications about your posts!

I'm surprised about the 5K resistor, and it's good that it's now known that there are hardware variants on the market (which, of course complicates using the board).

It's good to see that you figured out how to load the code. I'd like to figure out why loading the last part of the code doesn't work. Did you try using e4thcom?

  Are you sure? yes | no

Thomas wrote 01/24/2018 at 20:57 point

After removing ".S" from line logger.fs line 18 uploading the file should work. The problem is due to the e4thcom feature "ignore debug output" missing in

The code in the GitHub repository has been updated!

  Are you sure? yes | no

BigVulcanDeal wrote 01/24/2018 at 21:39 point

Awesome!  Thanks Thomas!

  Are you sure? yes | no

Thomas wrote 01/27/2018 at 09:25 point

@BigVulcanDeal : issue #17 tracks changes (docs, software) required for the hardware variant. If you find the time, fork the W1209 thermostat repo and add your changes (e.g. new lookup table). I would also like to know more about the source of your W1209.

  Are you sure? yes | no

darko.lombardo wrote 12/10/2017 at 20:34 point

Hi Thomas.

I have uploaded the latest W1209-FD binary to W1209 board and attached USB/UART dongle to +/- buttons.

I get to the console at 9600bps.

How can I use it as temperature logger, I mean how to read the temperature on a PC?

  Are you sure? yes | no

darko.lombardo wrote 12/10/2017 at 21:13 point

I am able to use the logger:

1. "L.wipe<ENTER>" to wipe all the logger data and restart the minute counter

2. set logger period in LoG display menu to 0.1 (~ 6 min)

3. Read log using "L.dump<ENTER>" - all 288 entries from oldest reading (1) to newest reading (288)

But the W1209 does the measurements much more frequently and displays the result on the LCD.

How can I get the last (current) temperature value using serial console?

  Are you sure? yes | no

Thomas wrote 12/17/2017 at 11:11 point

Hi Darko,

Sorry, I didn't notice your message! I've added some features in the meantime, but I didn't realize that someone might actually need to use the temperature on the console :-)

Please try the following Forth definition:

: theta lpf.tem2 @ 2/ .0 ;

If you just want to use it as a temperature reader, you can of course strip the current software down. In that case you only need the following in the main.fs:

#include measure.fs
#include menu.fs
\ #include logger.fs
\ #include control.fs
: task ( -- )
  \ the application runs as a background task
  measure ( -- theta ) \ measure temperature
  \ logger ( theta -- theta ) \ data logging
  \ control ( theta -- theta ) \ temperature control
  menu ( theta -- theta ) \ menu and display code

Using uploading Forth code to the W1209 should also be possible under Windows. With Travi-CI you can build a new firmware even with a tablet PC!

Please write an GitHub Issue if you have a feature request.

  Are you sure? yes | no

Eelco wrote 09/30/2017 at 14:52 point

I had problems to upload files to the board with e4thcom and the stm8ef-release of  this projects repository (v2.2.13) so I flashed it with v2.2.16, BOARD=W1209-FD. This works fine. I really like these stm8ef projects. And the e4thcom support is a big improvement.

My experience with this board is that it is reasonable accurate in the 25 C range but at high temperatures it is not.  This is due to the fact that  at high temperatures  a change in temperature results in a tiny voltage difference (about 5C per 5V/1024) so the ADC is hardly capable of detecting temperature changes. I once put the censor in boiling water and the reading exceeded 110C hence error. I plan to use a  mindev board and multiple voltage deviders for the NTC to be able to switch for different temperature ranges. I think that would improve the resolution.

  Are you sure? yes | no

Thomas wrote 10/06/2017 at 18:54 point

Hi Eelco, you're right, at higher temperature the W1209 is inaccurate. Due to the a 20k pull-up resistor the NTC is best matched around 0 degC. An 1k pull-up resistor would match the NTC at 100 degC. I think that the optimum is somewhere in between, e.g. 3k. The "W1209 Sensor" page in the Wiki contains a table with the sensor values.

  Are you sure? yes | no

RigTig wrote 08/06/2017 at 10:58 point

And who better to teach the W1209 than this author. What a good use case to hack, and agile is the way to go. Cheap hardware and the addition of some smart software gives this project the opportunity for lots of variations, as other use cases arise.

  Are you sure? yes | no

Thomas wrote 08/06/2017 at 21:20 point

Thanks RigTig, you nailed it! Besides, this author learned quite a bit from you!

  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