Solid State Relays

Please note – this blog is WELL out of date and all of my blog items and much, much more have now been moved to – visit the site – sign up for much more.

SSRYesterday I published a blog about some little DIP solid state relays – and was reminded by a friend that these… are cheaper and higher power if not so tiny – and he’s right – I have some and they work a treat. If you try them from GPIO0 on the ESP8266 however, make them + based not – based.. ie connect – to the output and + to the 3v3 supply of the ESP8266 which means you have to reverse your on/off logic.

I have one attached to a compact fluorescent light and it’s working a treat.

ESP8266 and Lost WIFI Connection

Please note – this blog is WELL out of date and all of my blog items and much, much more have now been moved to – many of the blog entries have been brought up to date – please visit the new site and register for much more.

Something those of you planning to use your ESP8266 units in remote installations might want to be aware of.  I’ve been working with TUAN who developed the MQTT software – now, I’m sure it has nothing to do with his code… but essentially, I’m using his latest software as the basis of a controller.

I’ve added a simple interrupt driven real time clock, refreshed by occasional MQTT message, I control output 0……GPIO0 – and I have a temperature sensor on GPIO2.

All of this works VERY nicely (some new updates from last night you might want to get from the GIT repository) – when the temperature drops below a certain level the output comes on etc, or I can manually turn the output on and off.  I can even store settings in FLASH having added a little section to the area that normally holds WIFI settings – all of this works perfectly.

BUT.. has anyone tried turning off the WIFI for a while…. and then turning it back on? Does your little board reconnect every time, reliably? Because in the real world of remote control that will happen.  I am finding that this is not always the case, that the code sits and tries to connect, maybe even seems to but ultimately fails. If the ESP SDK comes back with “STATION_CONNECT_FAIL” just what exactly should yo do about it?

Most of the time, simply disconnecting the ESP8266 board sorts the problem – if not the first time, the second time (and that in itself is a worry) – but that is no good if the board is actually controlling something – you can’t just reboot the board, you need to somehow reboot the WIFI while maintaining control over whatever it was you were doing…. or find another way to ensure that the WIFI reconnects every time.

The alternative is to use the board with an Arduino and have the Arduino reset the ESP8266 in the event of communication failure – but that’s really a bit of a cop out.

Thoughts?  (this is for C programmers, we’re not talking about LUA though I’m sure that is also worth testing).

Thanks to input here I’ve asked Tuan if it’s possible to update the code using the new 0.9.5 SDK + patch… and we’ll try again!

ESP8266 and JSON

Has anyone using the ESP8266 with the SDK had a go at using the JSON routines yet? I ask because I need to pass several MQTT messages to the board in a string.  I can of course do this the hard way, comma delimiter or similar, but it would be nice to try to use the JSON routines already in there. Anyone up for a simple example of use with 3 or 4 values passed to a string?

Please note – this blog is WELL out of date and all of my blog items and much, much more have now been moved to – visit the site – sign up for much more. There is a search facility in the new blog – and you can find all of these old items usually with a similar name.

For example…


This is my original blog – all of the material in here has been moved to the now very popular – you can find all the older material, some of it updated – and a whole load of new stuff – at

8-pin chipOne of the guys who looks in here re-blogged something of mine and I thought I’d take a look at his site – and discovered these:

The PR26MF22NSZ and it’s larger cousin the PR39MF22NSZ  are miniature 8-pin devices which look for all the world like any other 8-pin chip – but are able to switch mains power at up to 0.9amps – i.e. up to 200w. Seems unbelievable but that’s the claim – sensible you could certainly run a typical mains light.

Given the very small size of our ESP-01 boards and the equally small size of the mains power supplies I found earlier, these would appear to be an ideal companion. Right now they are marginally more expensive than the cheapest Chinese relays and even very slightly more expensive than some solid state relays – but the size has to make it all worthwhile?

Digikey have the larger one at 1.18 but the postage kills that option – you have to wonder what their marketing people are thinking about – 1.18 for the chip – 12.00 for postage – come on guys – it’ll fit in an envelope!!!

The best I’ve seen up to now is £1.97 with free postage here..

I’ve ordered one just to see what size it is – I’m hoping this surface mount version is the same size as the normal DIP… time will tell. If it is at works I could see a board coming on! Here is some more info and a diagram.


Has anyone had a go at making a set of macros or defines in C to make the programming of the GPIO pins easier?

(Please note this blog is now very old – for FAR more up to date information, visit

For people used to:


a cold sweat appears when confronted with


And if you’re only dealing with GPIO0 and GPIO2 then that’s not too hard, but we have commands to pull up pins, disable pull up, pull down, disable pull down, set as outputs etc…

Personally I’ve no idea which commands can be used on which pins and outside of GPIO0 and 2 I’m not even sure what commands CAN be used on which pins.

Is anyone aware of a simple concise set of documentation with examples for all the pins? Or has anyone done their own thing which would make life easier for others?

The nearest I’ve been able to find is this

and there are also some snippets of useful info here..

However I’m still not clear in my head what can and cannot be done with each pin.

ESP8266 and the Dallas DS18B20 and DS18B20P

Please note – this information has now been superseded by the info on the new blog at – please visit the new blog.

Having wasted half the night following up dodgy temperature readings for the DS18B20P only to realise I’d left existing code running for the DHT22 !!!  I managed in the process to reduce the necessary code down to a minimum.

If you look at a previous blog in here I referred to some simplified Arduino code I’d written back in the dark ages and wondering if I could get similar here.  I’m only interested in temperatures to the nearest degree C for thermostatic control and was very concerned about the typical 1 second delay to read these chips.

I reasoned that if you were to read the chip before conversion then start a conversion off, your first reading would be rubbish – but subsequent readings would be fine without the delays associated with the more normal code.

So, here is what I ended up needing for a library – very little as you’ll see… most of it is comments…


* Adaptation of Paul Stoffregen’s One wire library to the ESP8266 and
* Necromant’s Frankenstein firmware by Erland Lewin <>
* Paul’s original library site:
* See also
* Stripped down to bare minimum by Peter Scargill for single DS18B20 or DS18B20P integer read

static int gpioPin;

void ICACHE_FLASH_ATTR ds_init( int gpio )
//set gpio2 as gpio pin
//disable pulldown
//enable pull up R
// Configure the GPIO with internal pull-up
// PIN_PULLUP_EN( gpio );
gpioPin = gpio;

// Perform the onewire reset function.  We will wait up to 250uS for
// the bus to come high, if it doesn’t then it is broken or shorted
// and we return;

void ICACHE_FLASH_ATTR ds_reset(void)
//    IO_REG_TYPE mask = bitmask;
//    volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
uint8_t retries = 125;
// noInterrupts();
// DIRECT_MODE_INPUT(reg, mask);
// interrupts();
// wait until the wire is high… just in case
do {
if (–retries == 0) return;
} while ( !GPIO_INPUT_GET( gpioPin ));
// noInterrupts();
GPIO_OUTPUT_SET( gpioPin, 0 );
// DIRECT_WRITE_LOW(reg, mask);
// DIRECT_MODE_OUTPUT(reg, mask);    // drive output low
// interrupts();
// noInterrupts();
// DIRECT_MODE_INPUT(reg, mask);    // allow it to float
// r = !DIRECT_READ(reg, mask);
//r = !GPIO_INPUT_GET( gpioPin );
// interrupts();

// Write a bit. Port and bit is used to cut lookup time and provide
// more certain timing.
static inline void write_bit( int v )
// IO_REG_TYPE mask=bitmask;
//    volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
GPIO_OUTPUT_SET( gpioPin, 0 );
if( v ) {
// noInterrupts();
//    DIRECT_WRITE_LOW(reg, mask);
//    DIRECT_MODE_OUTPUT(reg, mask);    // drive output low
GPIO_OUTPUT_SET( gpioPin, 1 );
// DIRECT_WRITE_HIGH(reg, mask);    // drive output high
// interrupts();
} else {
// noInterrupts();
//    DIRECT_WRITE_LOW(reg, mask);
//    DIRECT_MODE_OUTPUT(reg, mask);    // drive output low
GPIO_OUTPUT_SET( gpioPin, 1 );
//    DIRECT_WRITE_HIGH(reg, mask);    // drive output high
//        interrupts();

// Read a bit. Port and bit is used to cut lookup time and provide
// more certain timing.
static inline int read_bit(void)
//IO_REG_TYPE mask=bitmask;
//volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
int r;
// noInterrupts();
GPIO_OUTPUT_SET( gpioPin, 0 );
// DIRECT_MODE_OUTPUT(reg, mask);
// DIRECT_WRITE_LOW(reg, mask);
// DIRECT_MODE_INPUT(reg, mask);    // let pin float, pull up will raise
// r = DIRECT_READ(reg, mask);
r = GPIO_INPUT_GET( gpioPin );
// interrupts();
return r;
// Write a byte. The writing code uses the active drivers to raise the
// pin high, if you need power after the write (e.g. DS18S20 in
// parasite power mode) then set ‘power’ to 1, otherwise the pin will
// go tri-state at the end of the write to avoid heating in a short or
// other mishap.
void ICACHE_FLASH_ATTR  ds_write( uint8_t v, int power ) {
uint8_t bitMask;
for (bitMask = 0x01; bitMask; bitMask <<= 1) {
write_bit( (bitMask & v)?1:0);
if ( !power) {
// noInterrupts();
GPIO_OUTPUT_SET( gpioPin, 0 );
// DIRECT_MODE_INPUT(baseReg, bitmask);
// DIRECT_WRITE_LOW(baseReg, bitmask);
// interrupts();
// Read a byte
uint8_t ICACHE_FLASH_ATTR ds_read() {
uint8_t bitMask;
uint8_t r = 0;
for (bitMask = 0x01; bitMask; bitMask <<= 1) {
if ( read_bit()) r |= bitMask;
return r;

and here is the code that ended up in my timer callback routine, sending off an MQTT message for the temperature every 5 seconds – this works with both chips and works reliably.

    ds_init(2); // one off for the DS18B20

The above goes in my INIT routine – note that I’ve referred to GPIO2  – this will not work for other port bits as the Port initialisations seems to be partly hard coded – if anyone cares to re-write that so that anyone can easily access any of the usable pins.. would be nice..

I’ve also renamed the  routines, adding ds_ at the start to avoid confusion with other routines.

And now  for the actual code.. I call this every 5 seconds for testing and as you’ll see there’s a little extra code to send this out via MQTT. The extra code is in bold. “Temperature” is an integer defined elsewhere.  As you can see, no search, no checksum, no delay for processing – this works with both the DS18B20 and the DS18B20P chips.

char *tBuf = (char*)os_zalloc(6);

if (temperature>100) temperature-=4096;
os_sprintf(tBuf, “%d”, temperature);
MQTT_Publish(&mqttClient, “temperature”,tBuf,strlen(tBuf), 0, 0);

And so how to test all of this. For the life of me I can’t find a simple, no-nonsense program to read MQTT and graph it – you would think there would be loads around – I have asked the writer of MQTT-SPY if he’d like to add something into the program – for what’s out there – you seem to have to sign up and go through a whole learning curve – a little excessive for what I wanted (i.e. MQTT in – graph out), so I hooked up Node-RED to simply store the incoming data in a file.

And now having that information in a simple text file, it was easy to graph in EXCEL but again a whole FAFF to simply update dynamically until I discovered Live-Graph – not the prettiest but set to read the file every 5 seconds and update the graph –  I have to say it works a treat.

Here is my little sensor, as it happens the P variety I was originally having problems with, happily monitoring the ambient air temperature with a little excitement added on two occasions from my Dust-off air blower which is able to freeze the life out of the sensor on demand!


As you can see, the code is working well – doesn’t even need averaging.

ESP8266 C FLASH Saving of Variables

While I’m off in search of a C one-wire library, has anyone saved any variables to FLASH (hence non-volatile) – and if so would they care to give the simplest C code example of how to do that?  I (and no doubt others) would like to save some strings and integers permanently or semi-permanently – or even perhaps some log info – we have loads of Flash but personally I’ve not idea which bits I can safely use or how to do the read and write….  So kind of like the equivalent of Arduino EEPROM library.

Please note – this information has now been superseded by the info on the new blog at – please visit the new blog.

Lua and the DS18B20/DS18B20P temperature sensor

DS18B20 or DS18B20PA long time ago, back in the dark ages when all we had were Arduinos (seems such a long time ago) I spent a bit of time playing with the Dallas DS18B20 chips.

There are a number of ways to read these and so I’ll explain my logic as I go along. Not everyone will agree with my conclusions and that’s fine. Works for me as they say.

The example that comes with the Lua interpreter caters for almost everyone by making the software check for missing chips, multiple chips and offering a range of output options including degrees C and F.  As the language subset does not include floats, it simulates that with two catenated numbers.

In order to avoid issues with delays stopping communications ( and I can confirm that delays WILL stop for example incoming MQTT messages), it also does away with the typical setup delay.

So –  a number of issues with this.  Firstly, for me, if I am reading temperature and maybe controlling something, I cannot for the life of me see the need for sub-degree precision. Accuracy yes but precision? Really, you’re going to keep the house at exactly 22.15c?   Probably not. I control 2 properties and this code will likely control the third – 24-7, 365 days as year if it works as reliably as the Arduino version.

Secondly, when I received my Dallas chips I got a mixed bunch on special offer and ended up with some with a P suffix. I quickly discovered that the delay is needed for these chips and today when using the example software with Lua I was set back temporarily before remembering this fact. The P suffix chips simply would not work AT ALL and constantly returned 85c. That delay is needed one way or another.

Because it has been removed, the first reading you take with the code will be incorrect.. and that’s not really a problem – you could take that during setup. There are ways around this but it’s not worth the bother when it’s so easy to circumvent.

Now personally I don’t see me using more than one chip per board and if I did I could always use another pin – so that whole search scenario is a waste of time, resources and RAM for me.

So given these criteria I have a MUCH simpler version of the driver for you – and one which will work without alteration with both chips. It’s also fast.

Instead of seeking the address of the chip, then starting the conversion, then reading the chip…  I assume one chip, simply read the value then start the conversion.

This seems utterly wrong but then remember your first reading is naff anyway. Assuming you don’t try to read the unit more than, say, once a second, the time in between reads will be more an enough to do the conversion for BOTH types of chip. I plan to stick this on a timer, say, every 10 seconds, dumping the value into a global variable so it’s “just there”.

Also as I’m just reading an integer, about the only check I have to do is for overflow so as to perhaps create a negative number (for freezing conditions) and finally all that CRC stuff and the buffer needed to store the data – why bother, with only one chip it’s not going to go wrong unless you have a long lead between the board and the chip. You only need to read 2 bytes!! Speed, storage…

So here’s the EASY version.

I have to say, I simply do not understand the registration system for LUA modules yet (wasn’t there last time I looked in) so those first few lines at the start I’ve copied verbatim.

Can you make it even simpler and also explain this stuff at the very first few lines to do with modname? Oh, I’m using all 3 leads (GND, D and VDD) of the Dallas chip and a 4k7 pull-up from D to VDD. I found the pull-up un-necessary on short leads but let’s not test fate?

Please note – this information has now been superseded by the info on the new blog at – please visit the new blog where you can search many hundreds of IOT-related entries.

— DS18B20 one wire module for NODEMCU
— Vowstar <>
— Dramatic simplification: Peter Scargill

— Set module name as parameter of require
local modname = …
local M = {}
_G[modname] = M
— Local used modules
— Table module
local table = table
— String module
local string = string
— One wire module
local ow = ow
— Timer module
local tmr = tmr
— Limited to local environment
— Implementation – you don’t get any shorter than this

function readNumber(pin)
ow.write(pin, 0xCC, 1)
ow.write(pin, 0xBE, 1)
data = nil
data = “”
for i = 1, 2 do
data = data .. string.char(
t = (data:byte(1) + data:byte(2) * 256) / 16
if (t>100) then
ow.write(pin, 0x44,1)
return t

— Return module table
return M

That’s it!!! So there’s the library done… now here’s the test code…

t = nil
ds18b20 = nil

Notice that this, too is simplified. “4” refers to GPIO2 in the Lua tables. I’m using an ESP-01 and I use GPIO0 to control a relay.

and here are the results showing a swing across through zero thanks to my handy liquid air spray. I do wish I could figure out how to turn the UART off except when I’m firing prints out – anyone know how to do this? Results buried in that mess are –2, 0, 1 and are degrees C (you could easily mod the code to F).  Suggest not trying to measure over 84C.

> t=require(“ds18b20”)
> t.setup(4)
> print(t.readNumber())
> t = nil
> ds18b20 = nil
> package.loaded[“ds18b20”]=nil
> t=require(“ds18b20”)
> t.setup(4)
> print(t.readNumber())
0t = nil
> ds18b20 = nil
> package.loaded[“ds18b20”]=nil
> t=require(“ds18b20”)
> t.setup(4)
> print(t.readNumber())
1t = nil
> ds18b20 = nil
> package.loaded[“ds18b20”]=nil

If you’re on Facebook why not LIKE here.

ESP8266 LUA and MQTT

After a few days break wherein work got in the way of interests (not a good thing) I got up early this morning, determined to do some work on my ESP-01 boards while I have a clear weekend ahead of me. I checked for updates for MQTT and there are none – which is fine – that indicates that nothing has gone wrong this week.

On a whim I decided to go check the LUA site. I already new that the latest MQTT had been imported from conversations with Minh  who’s been doing the MQTT work but I was delighted to see signs that also some more work had been done on integration with Eclipse.

Every single time I’ve tried to install the nodemcu LUA code into Eclipse there has been a problem – something not found, some path missing, some issue taking hours to resolve.

Yet this morning I downloaded the latest ZIP file (updated yesterday) and imported it into Eclipse. CLEAN – COMPILE – FLASH…  not a hiccup – it worked perfectly. Not only that but when I tried powering Lua up – it came up straight away without any hint of an issue. This is new for me as I’ve always had some trouble or other. Magic.

Though it is possible to debug Lua code using the simple terminal you can install into the Eclipse environment, I did develop my own serial terminal  and then subsequently discovered ESPLorer.

I powered up ESPlorer and checked the available RAM on my newly installed Lua installation on an ESP-01 (I’m still waiting for my new white board to turn up from China with all the pins available – meanwhile I have ESP-01, ESP-03 and ESP-12 boards to play with).

A quick node.heap() call showed that we’re starting off with 22,144 bytes of working RAM which is a good improvement on the earlier versions especially as MQTT is now incorporated.

First things first, I told the unit about my router and then my MQTT broker which regular readers will know is sitting on a Synology DiskStation and has been sitting there working flawlessly for weeks now despite my attempts to bombard it to death with messages.

I noted when using wifi.sta.getip() that the unit remembered my router from previous experiments (I wish someone would produce a nice graphical memory map to show where these various elements are stored and how to tinker with them). So that was easy.

I followed this example – obviously filling in the bits that apply to my installation..

— init mqtt client with keepalive timer 120sec
m = mqtt.Client("clientid", 120, "user", "password")

— setup Last Will and Testament (optional)
— Broker will publish a message with qos = 0, retain = 0, data = "offline"
— to topic "/lwt" if client don’t send keepalive packet
m:lwt("/lwt", "offline", 0, 0)

m:on("connect", function(con) print ("connected") end)
m:on("offline", function(con) print ("offline") end)

— on publish message receive event
m:on("message", function(conn, topic, data)
  print(topic .. ":" )
  if data ~= nil then

— for secure: m:connect("", 1880, 1)
m:connect("", 1880, 0, function(conn) print("connected") end)

— subscribe topic with qos = 0
m:subscribe("/topic",0, function(conn) print("subscribe success") end)

— publish a message with data = hello, QoS = 0, retain = 0
m:publish("/topic","hello",0,0, function(conn) print("sent") end)

— you can call m:connect again

(again ignore the IP address and port – I filled in my own) – I ran this and… connected no problem. All seemed well.   I had subscribed to “test” rather than “/topic” and had commented out the publish for now.

I tried publishing “test” to see what would happen – nothing. But then I guessed as the last line was “m:close()” I figured it reasonable that the ESP-01 would not be listening and so called the connect line again – after all – there is a comment in there “you can call m:connect again”.

The result (passwords have been changed to protect the innocent):

> m = mqtt.Client("peteluatestid", 120, "xxxxxx", "yyyyyyy")

NodeMCU 0.9.5 build 20150123  powered by Lua 5.1.4
lua: cannot open init.lua

Yes that’s a crash. Oh dear, this is not the first time I’ve seen Lua just die. I can handle error messages but this tendency to just simply reboot…

Meanwhile, my experiments with programming in C, using MQTT directly have, thanks to Minh Tuan’s constant vigilance in fixing things, produced rock-solid results. Indeed I’ve been away since last weekend and I turned off a perfectly working MQTT temperature sensor in order to give Lua another go. I thought the one-wire library in Lua might make the transition to a Dallas DS18B20 a little easier but I’m not going to start another round of failed experiments while Lua so easily crashes.

Incidentally, I had several attempts with this Lua installation – rebooting several times along the way. When I finally managed to get the whole thing to work and in commenting out the CLOSE – as you need the connection open to receive anything, I noted my wonderful 22k of RAM had dropped down to 17.2K.  I really do wish they’d put a little more RAM on that chip.

Having checked that the compilation had included all the modules (app/include/user_config.h) which as far as I can tell the default combination SHOULD do… I thought I’d try the DS18B20 module – the idea being to send an MQTT request – and get an MQTT message back with the temperature in it.

I thought I would avoid experiment and merely check the temperature first.  I duly attached a working SD18B20 unit and pull up resistor to GPIO2 (that’s input 4 according to the table).

The code looked simple enough..

t = nil
ds18b20 = nil

But no..

> t=require("ds18b20")
stdin:1: module ‘ds18b20’ not found:
    no field package.preload[‘ds18b20’]
    no file ‘ds18b20.lua’
    no file ‘’

Oh dear….

Thoughts? Am I missing the point here?

The Battle of the ESP-201 Giants

ESP-201This is a relatively new one – the ESP-201 – larger than other game-changing miniature WIFI boards (or miniature powerful programmable devices with WIFI as you prefer)  but with one big advantage – unless I’m mistaken this new WIFI board (which will be functionally identical to others as it has the same parts) appears to have 0.1” spacing which means for the first time other than the pin-challenged ESP-01 we’ll be able to experiment with this board on normal breadboard or with normal prototyping wire – and that has to be a good thing.

The only question is – do you want to pay £3.29 or £2.58 (that’s Pounds Sterling as I am UK based)

Here they are – if anyone has any CHEAPER links do let me know…

These boards like the others run on 3v3 and like some of the others have an on-board antenna – but there is also an option for an external antenna (I’ve not found the need for one myself).

The point is – unless SIZE is a big issue, these almost compete on cost-price alone with the ESP-01 but without the pin restrictions – let’s see what we get – and if anyone has done some work with one of these could they please let us know how these pin-mappings compare to somewhat more conventional pin names for these devices.  I expect I’ll have mine soon and am looking forward to taking the opportunity, perhaps even at the weekend, to mess with second UART debugging, I2C and a host of other features denied to ESP-01 users (except those with obscenely accurate soldering skills and very fine wire). Mind you, a planned BURNS night on Saturday might slow progress a little.