Home Control 2017

Introduction (Latest update July 19, 2017)

HomeSick of reading about other people’s home control? Want to make your own? Got some electronics and software experience? You’re going to LOVE THIS! Rock-solid home control – low cost, DIY.

If you’ve read my early blogs you’ll know that Aidan Ruff and I have been working in home control since the late 20th century. Together, we ran an electronics R&D company for many years and one of our products was a home control system called APPCON.

Home Control 2017

That range of products  achieved much coverage in the UK tech press at the time and many loved it but the design involved spouse-unfriendly WIRES – bad mistake. So now we’re back – this time for fun –  with a vengeance!

Add to that lot above, the SI1132 unit which returns light values for visible, UV and IR - and a host of other I2c boards around the corner.

By the time you look at the diagram above it will likely be out of date as new features are added and I’ve JUST fixed a longstanding issue with OTA which now works a TREAT – thankfully there’s a manual along with source code and diagrams available online and kept up to date. This is all free incidentally and without warranty. Software, diagrams, board layouts… and this blog has a range of articles on the subject.

The diagram pretty much says it all – a Raspberry Pi (2 or 3) or similar,  talking to your PC or smartphone via a range of potential technologies – and using a powerful communications protocol called MQTT over WIFI to talk to small yet incredibly powerful ESP8266 units – these can be bought very cheaply and programmed – or you can take our board designs and have some boards made in China if you really want to DIY (we do!).

There are no real limits to the number of boards you can have talking to the central controller – that is down, in the main, to your WIFI network which could cover one room or extend across the globe.

In my own system I have 3 properties talking to each other – one in the UK, one in Spain. No matter where I am I have full access – great fun, great utility, low cost. Who wants to pay £50 to control a light! This is definitely aimed at the DIYer.

In the coming link there is a complete project, suitable for Windows development using the ESP8266 “Unoffical Development Environment” for the ESP8266 – but that won’t stop Linux users from bending the makefile to their will!! Currently using SDK version 2.1.0

There is a DOC file here which is fully up to date with all commands – this blog entry just shows a selection. Even if you ignore or don’t understand the source and just download the ROMS available – you’ll be able to keep up to date via OTA (over the air updating) – and you’ll need that manual!

You may also need some new – and very useful skills as you’ll see the term Node-Red appear very often throughout the considerable range of blog entries in here – this is by NO means a single item – there’s a Nextion-based, prize-winning WIFI touch display blog and a range of discussions (and there are LOTS of valuable comments) throughout the blog – enjoy learning and please do feel free to share knowledge – there is SO much more we can do with this.

Update on flashing ROMS here:  https://tech.scargill.net/esp8266-home-control-update/  - Blog reader Jay has written a great blog on setting up the programming environment for Windows.

ESP8266-terminalWhat is missing from the diagram above is my first experiments with SPI. Using up GPIO13 to 16, I have a 320*240 display working experimentally as a fast scrolling terminal on the ESP8266. Handy for debugging the system without tying up your PC monitor.

How useful this is depends on how many other pins you need! We need an ESP8266 with many more IO pins – I guess that will be the ESP-32…Or of course you can use my “universal peripheral” – using a simple Arduino Nano clone at sub £2 from China, talking to the ESP8266 or indeed any I2c setup.

Background: I’ve been using ESP8266 chips since they first came out – and I have the development kit for their new ESP-32 –just waiting for some decent software tools to emerge but right now the ESP8266 is a lot of fun and that’s part of what keeps this all going.  In the summer of 2015 I made myself so visible on the ESP8266 front that I was invited to be part of an Espressif-led delegation to MIT in Boston for the FAB11 Conference – demonstrating the ESP8266 with MQTT and Node-Red and how to build this into practical systems. I’ve also recently been involved in a project in Spain for the MOD researching ESP8266 and IOT security and more.  If you wish, follow my ramblings on the subject of control using these chips in THIS blog – and also on Twitter (@scargill), Facebook (esp8266wifi and IOT pages) and LinkedIn.

Nextion DisplayRegular readers will know that for some time now, the ESP8266 boards have been turning the world of IOT upside-down. I’ve long-since scrapped various radio designs (NRF24L01 etc.), blighted by short range or lack of network ability - and have gone “hell for leather” into using these boards.

Home ControlThe original plan involved an Arduino Mega as a “master controller” and Arduino “slaves running over an NRF24L01 mesh network. Here in this link is one of my first attempts at blogging on the subject – along with pictures of the original “Appcon” system from back in the ‘90s.

The original Arduino-based system worked well worked and indeed controlled heating and lighting for a couple of years at my home, but the controller went out of the window when the Raspberry Pi 2 came out which was dirt cheap but with more than enough power to control a house or ten. Now of course we have the RPI3 and other exciting boards such as the tiny FriendlyArm NanoPi Neo.

Hardwired to Ethernet (or WIFI if you prefer), the system allows for a comprehensive wireless home control setup  and to answer any questions about ESP8266 reliability – with the code you’ll see in here,  I can say with a lot of experience, that the ESP8266 units given reliable power, are rock solid – stunning considering the price.

ESP-12The ESP8266 boards provide a REALLY low-cost entry solution into the world of IOT making it possible to create in the simplest sense an Internet-controlled LED for under £2 (it could just as easily be a 2KW heater of course for a little more outlay).

There are a number of variations on the ESP8266 boards, the first shot at this being the ESP-01 – a simple board with power, a couple of IO lines and serial in and out. The thing is – they all use the same chip and that particular board (the ESP-01) is very I/O and FLASH limited – and for no good reason – the ESP-12 and variants for example have access to the A/D converter, several IO lines, have more FLASH memory and cost the same amount!

The only downside to the latter is 2mm spacing pins but for VERY little you can buy adaptors to 0.1” – or of course use a board that will take the ESP-12 or the ESP-12E (which is the same – but with a few extra essentially useless pins) – same price. There are also a number of ESP-12-based boards today which offer 0.1” spacing. For this reason I’m giving up on supporting the ESP-01 with it’s limited FLASH memory though as you’ll see in another blog entry,  with a steady hand and fine soldering iron it is trivial to replace the old 1MB Flash on the ESP-01 with a cheap 4MB Flash making it more compatible with ESP-12 etc (well, you still have hardly any pins to use).

Oh, here’s a link to the various source files. Here are original Board files designed by Aidan Ruff. No guarantees – not even any guarantee they won’t change or disappear if we find bugs. Since this article was started I’ve added I2c and a software serial port (optional) on GPIO4 and 5 to control Nextion serial displays directly. Instructions here may not be fully up to date but always check the WORD document in the repository. You might also want to look at the Nextion WIFI touch display board and links – I discuss another control board in there as it can be used for general purpose. This board has neither a relay nor power supply (other than 5v to 3v3 conversion) on-board but it’s a better job for general use.

Also check elsewhere in the blog to see what we’ve done with the Itead Studio Sonoff boards and their plug-in-the-wall remote mains socket. All of this stuff works together as a whole or you can cherry-pick.

I’ve added i2c to the ESP8266 software which as you’ll see in the picture at the start of this blog as made a big difference to the number of supported devices. What a roller-coaster this has been an a great way to learn all about i2c – I’ve improved the original Espressif offering a lot!  I’ve recently added version numbering to power up info and a powerful debug command and also, the power-up info indicates which GPIO is currently used for Web setup and which pin for the visual LED or RGB LED indicator.  At the time of writing the code is using the latest Espressif SDK version 2.0

tmpA4AFThe later PCB you see here was designed (by Aidan Ruff) for my award-winning (ok I had to get that in) Nextion Serial Terminal which  in April 2016 grabbed second prize at the esp8266.com 1st Annual awards. The latest update to this board includes the option to use an RGB LED as the status indicator – something I see as becoming the standard – once you have a selection of colours an intensities to indicate status, all of a sudden a normal LED looks boring.

The Boards

For the reasons stated I’ll discuss here the ESP-12 (and variations, ESP-12F being the latest with a marginally better antenna) as that is my favourite sub-module - but the same code applies to other variations where pins allow. We have working software – and circuit boards to go with it. For reasons best known to my pal Aidan we called this original the Hackitt & Bodgitt board. We have a new board version with an RGB LED as the status indicator on GPIO13.

If you are in any way unhappy using 240v AC mains power, you may want to give this a miss or fit one of those 12v to 5v down-converters so cheap and popular on EBay – I do this to power them from a solar-charged deep-discharge battery in some cases. This version does NOT tie GPIO16 to reset (the saving in power on this board wasn't really worth the bother – and note that GPIO16 is usable as an output). Again in the latest version we’re moving to using GPIO16 as the default relay output – freeing up GPIO0 to be an input only (programming – and web-setup).

Front view

Here is the rear view. Note the MOSFETS on the back (this is looking straight through hence letter reversal)

rearview

Note that a particularly nice feature of this board is that it can be programmed from a standard, cheap 5v FTDI.

So in terms of “Features”, the diagram at the start of this blog entry says a lot – but for clarity:

  • Mains-powered WIFI controller board
  • FTDI-compatibility
  • Accommodation for solid state or mechanical relay output
  • Temperature sensing using DS18B20
  • Temperature and pressure sensing using the BMP280
  • Temperature, pressure and humidity sensing via the BME280
  • Temperature and humidity using the DHT-22 or DHT-11
  • All signals brought out to edge connectors
  • Uses inexpensive power supply (or DC/DC converter) available on EBay
  • De-bounced input with automatic debounce and messaging
  • Analog in for checking battery state etc., will handle up to 20v
  • Several Outputs expandable via I2c
  • RGB WS2812b output on most pins able to handle 300 or more serial LED STRIP
  • 3 outputs for high definition PWM – with MOSFETS to control LED STRIP
  • Talks WIFI and MQTT - ideal for being controlled by a Raspberry Pi or similar using, say, Node-Red
  • Flashing status (software supports both simple LED and serial RGB LED)  indication that the unit is functioning and has the correct time which it maintains internally in between updates*
  • Second serial output to support Nextion displays (see the Nextion WIFI Touch Display project)
  • Software mono-stable out for use as a watchdog
  • Outputs can be timers for watering systems for example
  • OTA updating from internal or external website
  • I2C support for an ever-increasing range of devices including a new Nano peripheral which adds truly inexpensive I/O, PWM, analog inputs and servo control
  • Hitachi LCD and Seeed OLED support
  • 16-channel 12-bit PWM support via I2c
  • 4-channel 16-bit ADC support via I2c
  • A new NANO-based peripheral via I2c with GPIO/PWM, ANALOG in and SERIAL OUT
  • A new SPi-based terminal (which fits on the ESP8266)
  • and more to come…

* (The time comes from an MQTT broker, for example using a Raspberry Pi or similar running Node-Red – see below)

** I now use Node-Red on the Pi to do thermostatic control. Consider the thermostat code to be legacy.

And another board: we’ve also put together a board for the Nextion displays - but WELL suited as a general purpose board and it is detailed on the WIFI Nextion  blog entry but I’ve included a picture here for reference. I can see a variation on this one being my main board eventually – just needs an add-on with a couple of relays and 3 MOSFETs to make it a perfect development board.  There is a cap on the reset line so that typically an FTDI is able to reset it automatically. Note: The current revision of the board has extra grounds and  4 way sensor connector (DS18B20, DHT22 etc.). Note that an even later version optionally uses an RGB LED for a status indicator – WAY better idea.

Nextion control board

The Controller

ESP-12We have chosen to commit to a communications protocol called MQTT as reliable code for this is freely available, MQTT “brokers” are also freely available and once you spend a little time on the subject it is both easy and the obvious way to control stuff in a network. Lookup “tuanpm mqtt” on Google.

As MQTT is so central to this, I’ll go into this in a little depth.  There are many ways you could have units talking to each other – a mesh network, a radio network, polling etc…over time I have come to see MQTT as the ideal tool for home control because it is simple, the tools are free and it WORKS.

Essentially an MQTT broker is a piece of software – a server if you like,  available online or (my preference) on the likes of a Raspberry Pi inside your network) which monitors incoming messages and sends messages out according to who they are for. Addresses are simply text. Messages are simply text. MQTT clients (software that receives MQTT messages for one unit and sends messages out to an MQTT broker) are available freely for the likes of Arduino, ESP8266 and in Node-Red. It really is all very simple once you get playing. So MQTT is an incredibly simple yet powerful format comprising a message “topic” and a message “payload” both in the form of simple text. Units can “subscribe” or listen for specific topics. A great way to play with this is to use an online free MQTT broker – and something like MQTT-SPY which is a free “client” which runs for example on a PC.

The ESP-12-based controller has a number of inputs and outputs which can be controlled equally well by MQTT commands or serial data - by the current software.

To talk to the unit wirelessly (WIFI) via the popular MQTT message protocol, a message can be sent to the topic “toesp” to send to all units in the network or to a specific unit by prefixing the topic with the unit ID, or example “kitchen_light/toesp”. The only difference between these two topics is that the former will go to all units yet never elicit a response from any unit, the latter will go to unit “kitchen_light” only and MAY, depending on the context, elicit a response from unit “kitchen_light” – unit ID is simple, programmable text.

Whatever controls these boards(Raspberry Pi?)  should now send

topic: toesp

payload: {heartbeat}

every minute. All the boards will see this - and all will pre-set a counter in themselves - which if allowed to drop to zero will re-initialise the MQTT code. In the event that boards lose the WIFI for some time, they may reset their WIFI  - then reset the MQTT code. Reset is used only as a last resort and the software can handle up to two SSIDs in case you happen to have two access points. If one fails it will try the other.

Hence in theory they should be bullet-proof. In practice they are bullet-proof unless of course the power goes off. Last summer in Spain I endured horrendous WIFI and power issues and the current code stood up to this and has done ever since – learned the hard way. That experience is also why I worked hard to ensure the OTA works so I can update the units remotely.

Each COMMAND or payload starts with an open brace and ends with a closing brace (my choice, kind of like JSON). In the case of MQTT, this information is stored in the message “payload”. For serial, there is no “topic” – just the message (payload) which you can fire into the serial port at 115k baud.

An example of a simple command might be to turn output 4 ON (output 4 goes to pin GPIO4).

{out4:1}

It is possible to send multiple commands at once by separating them with semicolons. i.e.

{out4:1;out4:0}

So to use serial – this is all that is required (newline delimiter) – for MQTT – the topic should be as referred to earlier and the payload should be in the format shown just above.

clip_image002[4]For more on MQTT go here. http://mqtt.org/

I chose to use a Raspberry Pi 2 (you could use 3 but 2 is ok) as my controller – and chose to use Node-Red as the controlling software when this was a project unknown to most  – turns out I picked a winner as Node-Red is now embedded in “Raspbian” on the Pi and is hence guaranteed a well-deserved and bright IOT future. It is also wonderful and really NOT hard to use. Want to play with Node-Red without even doing an install? https://fred.sensetecnic.com/ – enjoy.

The following document details the commands the units will respond to – the actions which will occur along with any return serial message or MQTT message created as a result of the incoming command. But please – read the manual.

The Pins

Here we see a drawing of the ESP-12 board, please note there is a question mark over the positioning of GPIO-4 and GPIO-5 – on many units, these are reversed.

You are looking at the FRONT of the unit with the metal cover visible.

clip_image002[6]clip_image004

Note: Contrary to the diagram, in prototyping I’m using a 1k to pull GPIO15 down as it’s still a grey area (some say the board won’t program unless GPIO15 is held down) – it does NOT have to be fully grounded and as you’ll see in fact I added PWM output on it (March 26, 2015).

Preliminaries

The ESP-12 units operate on 3v3 – NOT 5v. Extensive experience suggests a good 3v3 linear regulator fed from, say a 5v supply provides more reliable results than a 3v3 switched-mode supply – but that will vary with suppliers. I’ve recently been part of a project where we used WELL over 100 ESP-01 units all attached to one 20 amp switched mode power supply – they worked… but I prefer per-unit linear regulation.

We done just that in all our own boards, using a switched-mode 5v supply (or DC/DC convertor for 12v use) with a 3v3 linear regulator. I suspect most complaints about these boards boil down to power supplies. I can honestly say – that having used countless ESP boards since they came out – I’ve not once come across a bad board!!

To talk to these units from any 5v system through serial, you should ensure that inputs to the ESP-12 never exceed 3v3 (resistive divider). Typically the serial output will work just fine fed into, say the serial input of a 5v Arduino – I have NEVER had any trouble with this at 115k baud. Simple resistive level conversion can easily be implemented so that a 5v FTDI will talk to the serial without issue. In practice I’ve yet to see a 5v FTDI destroy an ESP8266 but if you go without the divider, be it on your head.

Certain pins are special and in particular, grounding GPIO-0 on power-up is used to trigger “flash” programming of the chips and also used to put the units into access point mode for setup – so you should be aware of this. When designing outputs I base all of mine on Vcc. So for example when driving a LED…

clip_image006

Why do I do that? Well, when the unit powers up – GPIOs are all input – and if you preset them to “1” on power up you’ll not get any flashing lights as the units boot up.

Below describes SOME of the commands currently implemented.  We have both WEB-based and SERIAL setup, full MQTT integration and the development focuses on using NODE-RED – specifically but not exclusively on Raspberry Pi (I’ve installed Node-Red on many SBCs and consider it as standard as adding Apache and PHP.  We’re using the free and excellent Mosquito for the MQTT “broker” on the Pi (i.e all units connect to this “broker” by address and password” and the broker stores and releases on request stored messages – hence any unit can talk to any other unit as well as making requests of the Pi).

The manual that comes on BitBucket with the code is way more comprehensive than this blog in terms of commands.

Command set

Controlling and monitoring outputs

The potential outputs are GPIO0 (that’s the one on the board with the relay – future boards will not use GPIO0), GPIO4, GPIO5, GPIO12[1]  GPIO13[2] and GPIO16. These are referred to as OUT0[3], OUT4, OUT5, OUT12 OUT13 and OUT16. You can also use GPIO2 as an output via a command – normally it is used with the likes of temperature sensors.

Typical outputs respond to the commands {outX:1} , {outX:0} etc where X is the GPIO number. If requesting the status of an output this form is used {out0?}

There are 3 variations on this:

{out13} (GPIO13) by default should not be used as its main purpose is that of a LED “status” indicator (though you can override that) (see the relevant command).

{out0:X} responds to the following for X:

0 – off (if command “invert=1” then the state of that output is inverted (for positive-based relays) – see the invert command…

1 – on (see above)

2 – on from dusk till midnight (see above)

3 – on from dusk till dawn (see above)

4 – on from dawn till dusk (see above)

5 – under local thermostatic control – see relevant command (see above)

6 – timer for output 0. Another parameter determines ON time in minutes – i.e. {out0,6,100} sets the output on for 100 minutes.

There are a set of related commands for reading the state of outputs – these are {out1?} {out2?} etc. Should unit “kitchen_light”  be asked for the state of out1 – the MQTT message sent back will be in the form

topic: kitchen_light/fromesp/out0

and the payload will contain the appropriate value.

Outputs can be inverted by the invert command by setting bits 0,1 and 2  etc., in the invert command. See the manual.

PWM

We’ve added PWM onto 4,5 and GPIO15 using the latest Espressif library which allows for up to around 95% duty cycle at very high resolution (14 bits) for the cheap 12v serial RGB LED STRIP though we have brought that down to 100 smoothly transitioning levels – but decent ones (i.e. non-linear – with more emphasis at the bottom end for smooth transition). Attached to a logic-level control MOSFET you can drive a 12v LED strip with this – initially off, use the command {pwm:X,Y,Z,I} where X,Y,Z are 0-99 for duty cycle and I is false if you want instant transition, or any value if you want a smooth transition.

For example if I =50 (50ms) then 0-99 would take 5 seconds. A lookup table is used to get a reasonably smooth fade (needs work).  Due to the Espressif library, you can get up to around 90% or so duty cycle at value 99 – but you really would not notice the extra on a light. Note also that the PWM even when off i still running – so if you run PWM with a board, don’t expect reliable SERIAL LED operation as the PWM has a minor effect on really critical timing as needed for serial LEDS.

Heating controls

In controlling heating, the unit will generally use the internally connectable (on GPIO2) temperature sensor DHT22 (which also handles humidity) or the Dallas DS18b20 or DS18b20p. These heating commands are deprecated as it is a lot easier to do heating controls in Node-Red.

It is possible right now to set the maximum temperature, the fall-back temperature, frost temperature and 2 on-off times per day locally. Of course using an external MQTT control the possibilities are endless.

Relevant commands are (X is general a value, degrees C or minute after midnight):

{peak:X}

{off-peak:X}

{frost:X}

{on_1:X}

{off_1:X}

{on-2:X}

{off-2:X}

Time settings

The units are able to keep time but clearly do not have a source of time – this can be provided to each unit separately or more sensibly to all units at once.

{time:X} standard Unix time value the number of seconds since January 1970

{dawn:X } number of minutes past midnight considered “dawn” or street lights off time

{dusk:X} number of minutes past midnight considered “dusk” or light up time

{When they power up, units attempt to log on. This is an ideal time to send them the time.

The ADC

The internal analog to digital convertor reads from 0 to 1.024 volts and outputs a signal accordingly. This can be read by the {adc?} command.

Debugging

From the serial console, we can view various settings by using the command {debug}.

Temperature and Humidity

The relevant commands here are {temperature?} and {humidity?} They will send out, by return, for example in the case of unit 999 :

Topic: 999/fromesp/temperature

Data: X where X is in degrees C

Humidity follows the same format but is a percentage.

Expansion

If we want the unit not to respond to a command but to pass everything on to the serial line to control, say an Arduino, use the EXT command followed by a string  – this can be used part way through a multi-line command if required.

{out0:1;out2:0;ext:”out0:1”}

The two outputs will be switched and the command {out0:1} will be send out of the serial port.

Of course, one COULD send these commands off to an Arduino – OR you could send them off to another ESP-12 with it’s WIFI disabled… the logic of that? It’s cheaper than an Arduino and faster!! You can develop in the C language for the ESP boards using the unofficial Eclipse development environment.

http://programs74.ru/udkew-en.html

and you can learn more about my own work at https://tech.scargill.net

clip_image008

Setting up for WIFI

There are commands to set the unit ID (defaults to “999” note this is a string not a number), ssid, ssid2, pass, pass2, mqtt_host, mqtt_port, mqtt_user and mqtt_pass. In each case surround the argument with double-quotes.

i.e.

{id:”123”}

You can also set “desc” for a short description and “attribute” for any short message like “Dallas” to indicate what facilities the board has.

The above can also be set by WIFI.  Turn the device on and immediately short GPIO0 to ground AFTER power up for several seconds. This will put the unit in to web setup mode. Have your laptop, tablet or phone browser log into Hack-setup and go to 192.168.4.1/wifi/wifi.tpl to set everything up.

There are two SSID and passwords – the idea being that if the unit fails to get through to an access point it will try the second one, if that fails it will go back to trying the first one etc.

Reset

If for any reason we want to reset the device, the {reset} command will do that.

Inputs

GPIO14 is an input. We can read the state with the {in14?} command.

It is also de-bounced and you can read (and simultaneously reset) the count using the in14_count? command. The inbounce:X command will let you set the bounce value in milliseconds.

When the state of the input changes (de-bounced) an MQTT message will be send out in the form of TOPIC: XXX/fromesp/in14 where XXX is the unit ID and  MESSAGE: 1 or 0

There is also a bounce value for in2 – i.e. {in2_count?}

Manual Override

If we wish to manually over-ride the status of GPIO-0 – for example wall control of a light – set {override:1} to do this – the input can then be attached to an on-off switch and will over-ride the output for a length of time in minutes determined by “override_time”.

RGB LEDs

One of the more useful features of the board is to be able to directly control an array of WS2812B LEDs. Right now, overall control is implemented including programmable fade-in and fade-out and a “rainbow” effect. However, buffer space is available to implement full individual control of up to 900 LEDs (warning use separate 5v supply for these – current can be up to 5amps for such a run). Note you cannot currently run PWM and RGB LEDS at the same time. Initiating PWM starts a timer that disrupts RGB timing and a reboot is needed between these. I’ve contacted Espressif about this.

The command takes the form of:

{rgb: port,red,green,blue,number,duration}

So if we want to go to bright red over 10 seconds and you’ve attached an array of 20 serial LEDs to the output GPI12, the command is:

{rgb:12,255,0,0,20,10}

And that will happen and we can do other things while it is fading in. The duration is a 32 bit number.

For amusement purposes we can also try {rainbow: port,number_of_leds,duration[,timer speed in ms]}

A neat toy: requires 60 RGB LEDs and can run on a port pin… a clock… {clock: port} if is 255, the clock is not running else runs on the relevant port.

If you want to just light up SOME LEDs in a strip – the command {rgbset: start_led, number, r, g, b} will let you set up various LEDS to various colours and the command {rgbgo: port,number_of_leds} will start the ball rolling. That number should not exceed 300 (not for any reason – I could have made it larger).

If you want to play with animation… {rgbstart: port,number_of_leds} will clear a command buffer so you can interactively add sequences {rgbadd: start_led,number_of_leds,r,g,b,milliseconds} and when you want it all to end, {rgbstop}. These commands can be sent via serial of MQTT.

Other

When the board powers up it sends a message “esplogin” and in the body the the name if its ID with a slash after it.. so “999/”. This can be read to send the board, say, the time. See the next section.

I’ve implemented {sleep:x} where x=microseconds (32 bit number) hence 10000000 is 10 seconds. You need GPIO16 attached to reset and that just isn’t worth the saving on this particular board but it’s in there for completeness. This is deprecated.

Node-Red

BlynkOriginally we’d planned on using something like OpenHab for home control and of course anyone armed with the software can do just that. But for our purposes we like Node-Red as it is extremely flexible and becoming more powerful by the day. If you have a Raspberry Pi2 or better – you can run Node-Red on that but it also runs on Linux, PCs etc.

Node-Red allows one to “program” using visual boxes via a web interface– so an MQTT input box can respond to a particular topic, you can then do something with that and send a message back – or elsewhere – or maybe send a TWEET, or store some info in a database or send an email – honestly it is VERY simple to use and very powerful once you get to grips with it.

If you look at my earlier blogs I’ve written about graphing locally, using data pulled in by Node-Red and stored in a MySQL database with ease. There are alternatives – I’ve written a “node” for Node-Red to let you simply send data to Grovestreams.com and others have written nodes for the likes of EmonCMS which has some very pretty dials.

Here’s a screenshot of my Emoncms data and yes, the battery is really flat – due to this being solar charged out in Spain – and it is 6am in the morning – clearly yesterday wasn’t that sunny.

EmonCMS used at Bedrock in Spain

Node-Red has a timing module… when lets you trigger things at certain times. It also has available a suncalc which sets a flag when it is sunset. I’ve improved this significantly in a node called BIGTIMER (see http://flows.nodered.org/ -  check out my bigtimer, esplogin and grove nodes– my contributions – for example – “npm install node-red-contrib-esplogin”) -  to produce an output directly suitable for the current design – to log the boards in and to tell them about the time, sunset and sunrise.

The esplogin node can send time updates when Node-Red powers up and on a regular basis (every 12 hours)to all boards – but also send to a specific board on request, and all boards will happily send that request when they power up – so typically a few seconds after power-up the boards know what time it is and what dusk and dawn times are.

Here’s what it looks like in action.. MQTT coming in from boards in the form of a json payload (purple), esplogin node in yellow doing the time/dusk/dawn updating and outputting the relevant MQTT back to the board (or in the case of time top-ups – all boards). The outputs from esplogin are, in order..

1. MQTT output

2. Output for a MYSQL database (legacy)

3. Output to a straight text logging file

4. Output to a SQLITE database

 

tmp3A16

All boards subscribe to “toesp” – and to a version of that with their name (ID) prefixed – so for example fred/toesp. That way I can talk to any board – or all of them.

When the board first powers up – it sends…  in the case of board “fred” which has description “my board”

Topic: esplogin

Payload: {“id”:”fred”,”desc”:”my board”,”attribute”:””}

Desc and attribute at not that important but can be shoved away in a database.  So that sets off the esplogin node  putting info to it’s outputs – I only use the SQLITE output and that ends up in a database – that’s up to you but my setup is in the Raspberry Pi script referred to elsewhere.

So assuming the node gets that login – it will send a bunch of time info back to the ESP board in question – and will then do that every day to all boards. This stops the boards from watchdog resetting and ensures they always have the correct time without needing a real time clock etc.

See the time, dusk and dawn commands – the ESPs can be updated though right now this isn’t necessary as the home control software on the Raspberry Pi is doing all the work.

How to get all the software the easy way

In order to use these boards effectively – you’ll need a Linux setup (a Raspberry Pi 2 or 3 for example) with MQTT, NODE-RED and preferably other stuff like PHP, SQLITE etc. Personally I’m not a Linux lover!!! And so I like things to be easy – so we made a SCRIPT. You can grab a Raspberry Pi(2) and put everything on there. The script works with JESSIE version of Raspbian. I made this script for “Jessie”. Follow the instructions precisely or it will not work. You must be user PI and NOT ROOT. Read more about the script here...  and

I use the Pi2 – after testing many boards this seemed a while ago to be the best for the job IMHO and for reliability use a good SD such as Samsung EVO and to make life really easy. If you have a Pi3 all the better.

For controlling and monitoring – I am currently using the Nextion (serial) touch display boards for the wall and vary between using Blynk Android/IOS app for remote control, the node-red-dashboard and ImperiHome.  All work well depending on your requirements.

You’ll read about all of this stuff elsewhere in the blog – use the search facility – there is a LOT of info.

Notes:

[1] GPIO5 (out5) can be manually over-ridden by the input and the “override” command.

[2] GPIO13 (out13) is generally used as an indicator to show that all is well. It activates on receipt of the correct time either serially or via MQTT and will flash briefly once every couple of seconds from there on. This activity can be disabled by a command. Increasingly we’re using a serial RGB LED on this pin to provide more comprehensive status info.

[3] GPIO0 (out0) is special in that it responds to more than “1” and “0” and can be used as part of a heating control system. Ultimately we will scrap using GPIO0 as an output and merely use it for programming and setup. GPIO16 makes a good relay output as it is not much use for other types of output.

Haptic feedback – when the board is being used in “Nextion” mode – we use GPIO12 as a beeper – simply fasten one of those cheap round haptic feedback devices to it and glue that to the back of the board. Also note that with limits (the line buffer is only 80 characters in length) you can concatenate commands so that for example if you want to turn GPIO12 on and get feedback as to the state at the same time {out12:1;out12?}  - note the two payloads are joined together by the semicolon.

But the REAL source of info on commands is in the WORD manual with the project – that is where you go to keep fully up to date.

 

Enjoy!

Facebooktwittergoogle_pluspinterestlinkedin

273 thoughts on “Home Control 2017

    1. Yes, once we get boards and actually have something real working [update - link for code is in this blog]. The last thing I want to do is to put out code that then encourages countless questions because of something we've messed up. Meanwhile some of the code is out there already - like the WS2812b code - I think our version which is little more than fix for what went before it, is the first to actually work and be tested to work flawlessly. I've done more of course - I have it sitting doing rainbow displays in the background but I wanted to put out the basics and see if anyone had any issues.

      1. I know, I've tried the code, worked perfectly! But I was wondering if the board is going to be open source, I would love to get my DirtyPCB order out of the door 🙂

        1. Excellent news... the board will become available but wait until we get the first lot back and tested. I've no plans to become a support centre and that's what'll happen if we put out something that isn't tested. The first board as you saw needed a couple of wires and over the weekend we went through the Eagle files to ensure that we were both using the same port bits etc. I want it to be perfect for my own peace of mind as I'm moving house and right now the house we're moving into is a building site - the ideal time to put boards etc into the rafters... but not without thorough checking. And yes, we're using DirtyPCBs...

      1. i suggest using HLK-PM01 as PSU , i tested my self for almost 4 months and running fine
        it's 5V 0.6A and i used MOSFET to drop it to 3.3V to power ESP8266 and some sensors and relays directly from the 5V.

        http://www.aliexpress.com/item/5-pcs-HLK-PM01-AC-DC-220V-to-5V-Step-Down-Power-Supply-Module-Intelligent-Household/32319202093.html?spm=2114.32010308.4.19.8oKfZg&aff_platform=aaf&sk=RnieI6Mr7%3A&cpt=1453904318699&aff_trace_key=68870308031c409585abf54584b84f70-1453904318699-07722-RnieI6Mr7

  1. Dear Pete,

    This is excellent. Not just the board but the entire write up. Meticulously done and explained. Most of the critical aspects and caveats related to ESP8266.

    The concept of board is awesome - even the concept of control of flashing by ATTiny. However, I was wondering about - if you would always (mostly) need to program and reprogram in a production environment. I was also working to make a slightly less functional board but with addition of a) external eeprom and rtc with backup button cell.

    I had one concern in mind related to mqtt client implementation and that is - configuring / reconfiguring of subscribed topics in real life (I guess, this might require occasional changes as per the need of the system? Will it? ) In that case, the ease of programming will be of help.

    Do you have any better idea for re-programming topics configuration, perhaps host, IP, ssid and password configs too ? I am keeping my fingers crossed.

    So long as you are not finalizing the pcb layout / design etc. Do you intend to share the schematic? Perhaps you may also get some suggestions from learned readers.

    1. The point of using only 2 MQTT topics means that the actual instructions are in the body. These can be passed to the board, activating build in functions - or sending out to external boards such as Arduinos etc for further processing. Aidan has done the bit of programming, based on existing code, to allow you to set host, IP, SSID etc without programming, ie using the board as a WIFI access point initially for setup. I've yet to test this part of it but I'm assured it works. I'm concentrating on the actual instructions in the ESP8266 and ensuring everything is reliable.

      1. I'm not sure that I understand your infrastructure. Surely you can 'advise' subscribers on which topics they should subscribe to? This is what I do. How do you identify newly connected devices?

        1. Hi

          What we have done is to subscribe each unit to a couple of topics such as:-
          '/toesp' - message to an individual device
          and 'toesp' - broadcast message to all devices

          Devices respond on '/fromesp' and can add additional subtopics such as 'temperature' - e.g. '/fromesp/temperature' to return values

          When a device first powers up, it sends a message to topic 'esplogon' which includes its' device name and any attributes that you have set in the web setup page on first connecting the device to the local wifi network, things like 'has_temperature_sensor'

          We currently use Node Red to trap all 'esplogon' messages and make an entry in a MYSQL database the first time the device is seen. A return message is sent to '<device_name'/toesp which includes things like the current local time, plus dawn and dusk times.

          The device will log on periodically and will receive the updated time. The last logon time is also noted, so that if a device isn't heard from for some time, you could log an error, send an error email or some such.

          The advantage of having an automatic database entry is that you can just keep on adding units to you database but the setup is done locally in the device when you install it

          Hope that helps!
          Aidan

        2. ...meant to add that we've also done a Node Red node which will take messages from /fromesp/temperature and put them straight into the MYSQL database with device_name, time/date and temperature reading.

          Pete is currently adding a periodic temperature reporting time which I will add as a parameter in the web setup.

          This means that you could define a temperature reporting time of, say, 15 minutes and every time it sends the temperature it will be automatically added to the temperature log in the MYSQL database.

          SO, you can then extract data along the lines of:-
          "select * from temperature_log where device_name = whatever"
          and then pass the info to a graphing routine for display.
          Aidan

  2. Hi there,

    Very interesting blogs, please keep on posting.
    I've ordered the exact same AC/DC switching power modules, but I can't find any footprint information. I would like to finish my PCB-design before I receive the modules (could take some weeks).
    Can you help me out sending the footprint (or info) of the power module?

    Another question... The Tantalums you placed on your board, have you placed them after meausuring the output of the AC/DC or are those a precaution? (i can't find any specs....)

    Best regards,

    Edjeed

    1. Thank you. I didn't to the PCB and Aidan who did is on a ski holiday. Tantalums - switched mode power supplies ALWAYS generate noise. Given that we're looking at a WIFI board (ie radio) - caps are pretty much essential I would suggest.

          1. Developing electronics for years also, if no specs or measurements are available a hunch is indeed the only way.
            Home projects with cheap chinese components is like using your intuition all the time 😉

  3. One of the big questions will be - reliability of the little power supplies... they seem to work fairly reliably in the UK but in rural Spain where I spend some of the summer, the mains power there is more rubbishy and the Chinese power supplies have a tendency to give up, especially the 12v ones used to power LED strip. I'm looking at these little devils now.... http://www.ebay.co.uk/itm/31-Types-Switch-Power-Supply-Driver-5-12-24-48V-1-2-3-10-15-20-30-40-50-60-70A-/311001005100?pt=LH_DefaultDomain_3&var=&hash=item48691abc2c

  4. Can't wait for this to ripen. So long I'll hack away at my ESP8266es. So lost my appetite for Arduinos.

    One thing that I'd love to see but know its not easy is a Heat Pump IR control. The hardware is easy but the commands a nightmare.

    Hasta la proxima
    Oliver

  5. I've kind of lost interest in Arduinos - I was keeping them around for PWM but I just figured out how to do that on the ESP - and it works well, I've a nice dimmer running as of 3am this morning (I know, sad).

    NOW - IR control - I see that as a problem - timing-wise if you're doing other stuff including WIFI.... I'd be happy to be proven wrong.

    1. Since you are including attiny85, is it possible to use the attiny85 for IR control or other timing-critical part?
      If the attiny85 is easily programmable and there is spare pin to be used for IR control then it might be useful there.

  6. It's such a pity these cannot be truely wire free. They use too much current, so your always going to have to have a mains power lead running to them 🙁

    1. Not sure I agree with you there Glen. On my boards I'm hooking up GPIO16 and as you know once you do that you can put them to sleep for long periods. I've not tested this yet but others say you can get reasonably low current. Given a lithium battery and half decent solar cell it may well be possible. For my purposes I'm not that bothered about supply because just about everything I'm going to hook them up to is going to need power anyway.

  7. Hi- I remember that in the previous (first) update about you pcb board you published the schematics also.
    Can you do that again or you aren't going to share it any more?
    Thanks

    1. Currently waiting for a set of boards to appear from China - which then need testing to make sure they work. I'll do a write up once we have them assuming there are no bugs (that's a big assumption). Right now I'm spending my time concentrating on getting to grips with Node-Red so that I can actually do something with them when they arrive.

  8. This is a far cry from those original "wired" One Time Programmable PIC based systems of yours that I had dotted around the house and you are right, not SWMBO approved. I think I went through about 3 reels of alarm cable to install them all and most of it was hidden along the edge of the carpets. 🙂

    Wireless of course is the only way to go these days. I also need battery powered so on the lookout for a suitable wireless system that can run off 2 AA batteries for touch panel input (Atmel cap touch) which fits in to some nice handheld enclosures that are held on the wall via neodymium magnets and a small metal plate fixed to the wall next to the light switches. It looks and gets SWMBO approval. 🙂

  9. Hi,

    I sent you a few msg on Facebook a while back was wondering if you got them. I was wondering if you might be able to give me some advice, or let me know if you've had any similar problems.

    I've been building a variety of devices using the ESP-07 and ESP-12 that involved switching a 5V relay module. These are the modules you get on eBay, both SSR and the usual coil ones that have opts-isolation in them. I've got some ESPs, powered by a small 700mA power supply that looks very similar to yours, with a 5V to 3.3V regulator, 4 100uF Caps on each side of the 3.3V regulator. The ESP has RST pulled high, with a capacitor. the esp has a 10nF ceramic cap across it.

    the problem is that when ever there is any power going through the coil relay Common-NC terminals of the relay the ESP reboots every few clicks. The moment I take away the live power, it runs just fine. This does not happen at all with the solid state relays. It occurs with independent power supplies. It happens with 3 different relay modules. Moving the components apart when >50cm seems to help, but it does not get rid of it.

    I'm at a bit of a loss. I was wondering if you've tried your PCB with mains power being switched by your relay? Have you come across this before. I'm guessing it is an EMF problem, but I'm totally stuck... the main different between your project and mine is that I want to provide live mains out using the mains that comes into the device to power the ESP.

    got any ideas? would appreciate some help, as my code is running like a dream... I'm just not able to make my idea!

    1. Sorry didn't see your messages - this is the place to discuss really I just use https://www.facebook.com/esp8266wifi as a place to announce updates etc. Well, I AM controlling mains gadgets with both solid state relays and normal 5v relays and I've not had issues. I'm assuming you've had a scope on the power supply of the ESPs when you are switching to see if there ia anything horrible going on? I have a 700ma or so supply and there is a 1000uf on the 3v3 linear regulator side - I would never consider running the ESP straight off a switched regululator. Up to now I'm not seeing any issues - I wonder if others have anything to say?

      1. Ah ok, no problem.

        I've scoped it, one of the first things I did and there was no changes that I could detect. I am using a linear 5V to 3.3V regulator AMS1117 i think it is. What I find curious is that there just has to be live power connected to the relay switching terminals for this to happen.

        I've just gone ahead and bought some 1000uF capacitors. But there really is nothing else that I can try I guess! so weird...

  10. I recently begun my project and I'm still deciding exactly what to use as I'm still waiting for several stuff to arrive from China(like a bunch of ESP-12Es). A question that came up to me is the following:

    Should I use a NoSQL DB like Mongo or should I stick with MySQL?

    A database like Mongo has the advantage of being pretty simple to use and that you can scale the setup easily(with a cost of a risk of things getting out of hand).

    A database like MySQL, considering you use it as it's intended and not with a VARCHAR 255 to store the whole msg.payload(so you have to parse it every single time), has to be designed with future expansions in mind from scratch.

    Now, the values you can get from ESP-12E are like 11, so setting up a table with id, timestamp, device-id and 11 more columns should be enough, right? Or for a more complex setup, you can have a table with the sensor values(temperature, humidity etc), one for the boolean values(lights on/off, open windows) and perhaps one for alerts(PIR sensors).

    But if for example you use a future ESP-1000(pretty creative name :P) that has 1000 outputs, then what? Restructure the whole database?

    On the other hand, and since MySQL is the usual database for everything, you can insert the data into tables inside a database that is used already by your front-end web application.

    I'm really confused on what is the best option for what I want to do.

  11. An update on this for interested bodies - we're awiting a new board having made some mistakes on the earlier ones - I want to be able to incorporate 12v-5v convertors as well as mains power supplies in the space allocated for a supply. Also the software while working pretty well up to now, is having issues with SDK 1.10 - more on that in another blog assuming they are resolvable.

    Brocashelm: Your queries - all I can say is that MYSQL works a treat - especially with Node-Red... I do have (as yet unfounded) concerns about SD lifespan when updating MYSQL, what I'd ideally like is the database held in RAM and updated nightly to SD.. if anyone has code for that do let me know. Yes, I have tables to store temperature and humidity - then I use a simple PHP/JS program using one of the many charts packages out there to display that data - I also log when a unit turns on and logs in - that all goes into SQL - to date I've had no problems at all and of course PHPMYADMIN is fine for creating tables etc - though I did just discover MYWEBSQL which on the surface looks even better.

    1. MySql has several storage engines... most common are MyISAM and InnoDB, but there is one called MEMORY (https://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.html)

      - You can use a temporary table with this storage engine, a once a day dump all data to final table, on normal storage engine, and thus, writing to SD.

      A few ideas on top of this:
      - partitioned table by range (for example, one partition for each day).
      - redundant data on some cloud to prevent data loss on power failure (because current day will always be in MEMORY only).

    2. I have an ideia to solve have MySQL to write to SD only once a day... mysql has several storage engines (myisam, innodb, etc) and one them is MEMORY (https://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.html).
      You can use a MEMORY table and once a day dump all data to the final table (myisam for example).

      a few ideias on top of this solution:
      - the final table can be partitioned by range (one partition a day, for example) and make dump simply by exchanging partitions.
      - have redundant data stored in some cloud for that MEMORY table, so that you never lose any data in case of power failure.

      1. Ok SFAM, you're NEARLY on my Christmas card list... for the benefit of those of us not 100% confident on the Pi yet (and for those who've not yet twigged that there is a problem) are you able to translate that into a simple, no-assumptions-made-about-Linux-knowledge series of instructions?

        The only issue I can think of - is that this is for NEW tables.... and there's a max-heap-table-size that might prove an issue. A way is needed to capture info - and then somehow dump it into the permanent tablets.. problem is - if you used SQL for this - ie updating the tablets in a loop - then you're actually no better off.

        1. Now, if the table size could be brought up to, say, 100 meg, I guess you could read the table from disk on power up /reset.... and every night overwrite the original table... there would need to be something that happens if you manually close down to ensure the table(s) is(are) updated.

          1. This solution has nothing to do with linux or raspberry pi... only mysql. The simplest solution is to have 2 tables like this (pseudo-code - not tested) :

            create table log_mqtt_today (
            ts timestamp,
            topic varchar(50),
            message varchar(200)
            ) ENGINE = memory;

            create table log_mqtt_all (
            ts timestamp,
            topic varchar(50),
            message varchar(200)
            ) ENGINE = myisam;

            - Each time a new mqtt message arrives:

            insert into log_mqtt_today values ( now(), msg.topic, msg.payload );

            - Trigger in node-red once a day (or manually before power down) something like:

            insert into log_mqtt_all
            select * from log_mqtt_today;
            commit;

            truncate table log_mqtt_today;

            - This is supposed to only write to SD only once a day... but not sure if would be any better than writing each message to SD individually.

          2. Sfam - I see your logic- and I see the concern - needs someone with more knowledge of MYSQL mechanics - would this result in LESS writes? I'm not sure. Good start though!!!

  12. This is coming along really well, the only differences between what you have here and what I'd want is switching out the relay for a dpdt bistable one (so it can man-in-the-middle a lighting circuit) and having the adc hooked up to a CT to detect the current status of the lights. I'm actually doing something very similar to this right now to address my specific needs and I've added a local RTC (although there should be one on board I don't know how to use it/where to put the crystal to make it reasonably accurate) set by NTP and the bistable relay. The CT is proving more difficult, the plan right now is to re-implement a subset of https://github.com/openenergymonitor/EmonLib specifically for the esp. Oh, and I'm doing this all in arduino because I'm lazy and it works fairly well.

    1. All of my boards maintain an RTC inside, topped up at power on and once a day via MQTT. There is software in the ESP SDK to set the time - but it doesn't do summer/winter time and it seems we are missing floating point maths functions - so that's out.

    2. Hello Evan, this has intrigued me, and sound like what I want to do, in that one wants to still be able to switch on/off at wall (replace with a push-button?), but be able to control lights from i.e. Node-Red with a UI, or some logic (switch all lights on). Your comment:

      "dpdt bistable one (so it can man-in-the-middle a lighting circuit) and having the adc hooked up to a CT to detect the current status of the lights"

      Could you elaborate further, maybe have you published the circuit somewhere, and could you point me to typical parts? Why not use an SPST bi-stable for instance? Could you please point me in the right direction? the ADC is also important to me, one needs to know if the lights ae on or off before switching from central. Thanks!

      1. Dropbox not working for me either. Seems that is your public download area. Dropbox asks for credentials when I click on the link. Of course, my credentials are not going to help because the file is not stored in my directory. Can you post a shared link for the file?

          1. That's it!

            Thank you. Nice work. I am new to your blog and I have been reading back through it. You have done a lot of work and made it available to the public. It is greatly appreciated!

  13. Hi Peter, looks nice! I've been doing something similar but my constraints are a little different to yours. I've produced a board which has DHT11/22, DS18B20, a SSD1306 OLED, BMP180 sensor (or another I2C device) a 3A relay & a LED.
    See it here: http://www.cse.dmu.ac.uk/~sexton/node/photos/newboard_a.jpg
    Ultimately I determined that the cheapest PSUs are phone chargers! Less than £1 a pop 🙂 And I use a USB cable to provide the power connection (my boards need to be student safe). A simple linear regulator provides the 3v3
    I also wanted to avoid surface mounted components AND stay within the 50x50 of DirtyPCBs. The USB connector & the regulator are the only SM components.
    It's looking good so far (got the PCBs last week)
    I have some super simple devices too. For example, this is a ESP01 with a DHT11/22 attached on the back: http://www.cse.dmu.ac.uk/~sexton/node/photos/iphone1.jpg

    Cheers

    1. Hi Ian

      Oled sounds good.. how many wires? Yes, cheapest usually are phone chargers but they vary SO VERY MUCH in quality - so easy to blow up - or rather make fail - the slightest issue and they're dead. It seems the phrase "overload protection" is not something the Chinese chip manufacturers appreciate.

      1. I'm using a SSD1306 I2C OLED - 4 wires in total: power & I2C 🙂
        These things are only £3 on ebay - tiny but very crisp.
        There's a couple of threads on the ESP8266 forum about using them. Thanks to a recent one I have the Adafruit library working now.
        Point taken re phone chargers!! I've had duds in the past...

  14. Great stuff Peter. My own little project is now months behind yours, so I'm a tad jealous. But mainly grateful that you've shared your experience with us all. Thanks, and continued success.

  15. Hi
    Your blog helped me a lot with developing for the esp.
    I can't figure out something.
    In the "hackitt_mqtt_separate" app in the user_main.c which function acts as the "loop" function?
    If I want to add functionality that listen to the serial port and if it detect something it does something, where best should I put it? Can't seem to find an implementation for this in the "hackitt_mqtt_separate".
    Thanks

    1. If you see any duplication in here it is because I have switched providers. Look at "Hackitt_mqtt" code - the original separate code is no longer being updated as it was basically the same but without the web support. Beware, right now I am making updates constantly to "hackitt_mqtt" as I find errors or add features. Use at your own risk and of course you'll need MQTT support for it.

      1. Hi Peter.
        I need a SSL implementation for the MQTT I added this to code and also add it to the wifi.tpl.
        I understand form another esp blog, that using SSL will need a lot more memory space than the 512 so my question is if the source code in the “hackitt_mqtt” - Makefile.windows will make use of the 4MB esp-12 module ?
        Also If I delete some of the files and shorten the source code so after compilation I get a much smaller firmware do I need to change something accordingly in the Makefile.windows so it will fit a smaller firmware?

  16. Peter,
    Since discovering your site I have dusted off the RPi installed node red, bought the netio app, yes bought!! and now I'm slowly moving forward getting things talking to each other.
    I want to learn about MQTT and I have a simple question but one that's so obvious I can't seem to Google the answer. My assumption is that I can install the mosquitto broker onto my RPi and run it stand alone from the RPi and configure node red MQTT nodes with the RPI IP address and port no.

    Thanks

  17. Your Dropbox page lists two board files, both named ESP-01 and 12 Development.brd. Which is the most current? Both say they were last modified 10 days ago.

  18. No, that's just one PCB - although we are into the 8th version at the moment! The PCB will handle either the ESP-01 or the ESP-12.

    The main reason for that is that if you put sockets in place of the ESP-01 and ESP-12 connectors then you can use the board as a programmer. There is an ATTINY-85 processor on board which handles the sequencing of the reset and GPIO0 signals to put the modules into programming mode. However, if you just want to use the board as a final, target unit, you can just drop in a pre-programmed ESP module and omit the ATTINY-85

    Aidan

  19. New version of board coming up - discovered that it's a good idea to put VDR on the relay contacts and for good measure we're putting a 0.1u cap to ground on the reset to minimise noise pickup.

  20. Hi Pete,
    Sorry to start off with a nag but I wish you would switch your code repository to github as there is no means of tracking any issues on bitbucket . . . frankly its a bit naff having to post this here in among 74 other posts.
    Problem compiling under Linux (the whole point of this is they should compile no matter which OS you are using, I had to modify the Makefile to closely resemble your windows one. I'm also on SDK 1.3.0 :- sorry about the long output but someone here may be able to help. ta

    john@dc7700p2 ~/hackitt_mqtt $ make clean
    john@dc7700p2 ~/hackitt_mqtt $ make
    CC driver/ds18b20.c
    driver/ds18b20.c: In function 'ds_init':
    driver/ds18b20.c:35:2: warning: implicit declaration of function 'PIN_PULLDWN_DIS' [-Wimplicit-function-declaration]
    PIN_PULLDWN_DIS(DS18B20_MUX);
    ^
    driver/ds18b20.c: In function 'reset':
    driver/ds18b20.c:206:3: warning: implicit declaration of function 'ets_delay_us' [-Wimplicit-function-declaration]
    os_delay_us(2);
    ^
    CC driver/gpio16.c
    CC driver/i2c.c
    driver/i2c.c: In function 'i2c_init':
    driver/i2c.c:60:5: warning: implicit declaration of function 'ets_isr_mask' [-Wimplicit-function-declaration]
    ETS_GPIO_INTR_DISABLE();
    ^
    driver/i2c.c:85:5: warning: implicit declaration of function 'ets_isr_unmask' [-Wimplicit-function-declaration]
    ETS_GPIO_INTR_ENABLE();
    ^
    driver/i2c.c: In function 'i2c_start':
    driver/i2c.c:100:5: warning: implicit declaration of function 'ets_delay_us' [-Wimplicit-function-declaration]
    os_delay_us(I2C_SLEEP_TIME);
    ^
    CC driver/uart.c
    driver/uart.c: In function 'uart_config':
    driver/uart.c:47:5: warning: implicit declaration of function 'ets_isr_attach' [-Wimplicit-function-declaration]
    ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff));
    ^
    driver/uart.c:53:3: warning: implicit declaration of function 'uart_div_modify' [-Wimplicit-function-declaration]
    uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));
    ^
    driver/uart.c: In function 'uart0_rx_intr_handler':
    driver/uart.c:230:3: warning: implicit declaration of function 'iprintf' [-Wimplicit-function-declaration]
    iprintf(DEBUG,"FRM_ERR\r\n");
    ^
    driver/uart.c:236:3: warning: implicit declaration of function 'ets_isr_mask' [-Wimplicit-function-declaration]
    ETS_UART_INTR_DISABLE();/////////
    ^
    driver/uart.c:266:2: warning: implicit declaration of function 'ets_isr_unmask' [-Wimplicit-function-declaration]
    ETS_UART_INTR_ENABLE();
    ^
    driver/uart.c: In function 'uart_init':
    driver/uart.c:289:3: warning: implicit declaration of function 'ets_install_putc1' [-Wimplicit-function-declaration]
    os_install_putc1((void *)uart0_write_char);
    ^
    CC user/aidan_and_petes.c
    In file included from user/auth.h:4:0,
    from user/aidan_and_petes.h:31,
    from user/aidan_and_petes.c:7:
    include/httpdconfig.h:6:0: warning: "ESPFS_POS" redefined [enabled by default]
    #define ESPFS_POS 0x70000
    ^
    :0:0: note: this is the location of the previous definition
    user/aidan_and_petes.c: In function 'iprintf':
    user/aidan_and_petes.c:14:3: warning: implicit declaration of function 'ets_vsnprintf' [-Wimplicit-function-declaration]
    ets_vsnprintf(buf, sizeof(buf), fmt, args);
    ^
    user/aidan_and_petes.c:16:3: warning: implicit declaration of function 'uart0_tx_buffer' [-Wimplicit-function-declaration]
    if (debug_type & enable_debug_messages) uart0_tx_buffer(buf,os_strlen(buf));
    ^
    CC user/aidans_code.c
    In file included from user/auth.h:4:0,
    from user/aidans_code.c:28:
    include/httpdconfig.h:6:0: warning: "ESPFS_POS" redefined [enabled by default]
    #define ESPFS_POS 0x70000
    ^
    :0:0: note: this is the location of the previous definition
    user/aidans_code.c: In function 'MQTTLogonTimerCb':
    user/aidans_code.c:50:12: warning: unused variable 'resetCnt' [-Wunused-variable]
    static int resetCnt=0;
    ^
    user/aidans_code.c: In function 'setupwebpage_init':
    user/aidans_code.c:88:5: warning: unused variable 'reset_count' [-Wunused-variable]
    int reset_count = 0;
    ^
    CC user/auth.c
    In file included from user/auth.h:4:0,
    from user/auth.c:21:
    include/httpdconfig.h:6:0: warning: "ESPFS_POS" redefined [enabled by default]
    #define ESPFS_POS 0x70000
    ^
    :0:0: note: this is the location of the previous definition
    user/auth.c: In function 'authBasic':
    user/auth.c:48:3: warning: implicit declaration of function 'iprintf' [-Wimplicit-function-declaration]
    iprintf(INFO,"Auth: %s-%s, %s\r\n", userpass, user, pass);
    ^
    CC user/base64.c
    CC user/cgi.c
    user/cgi.c: In function 'cgiLed':
    user/cgi.c:69:1: warning: pointer targets in passing argument 2 of 'strcmp' differ in signedness [-Wpointer-sign]
    if (!strcmp(buff, sysCfg.web_pass)) // Password OK
    ^
    In file included from /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:10:0,
    from user/cgi.c:16:
    /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:28:6: note: expected 'const char *' but argument is of type 'uint8_t *'
    int _EXFUN(strcmp,(const char *, const char *));
    ^
    user/cgi.c: In function 'tplLed':
    user/cgi.c:148:3: warning: pointer targets in passing argument 2 of 'ets_sprintf' differ in signedness [-Wpointer-sign]
    os_sprintf(buff, sysCfg.base);
    ^
    In file included from user/cgi.c:23:0:
    include/espmissingincludes.h:19:5: note: expected 'const char *' but argument is of type 'uint8_t *'
    int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
    ^
    user/cgi.c: In function 'cgiReadFlash':
    user/cgi.c:178:6: warning: implicit declaration of function 'iprintf' [-Wimplicit-function-declaration]
    iprintf(DEBUG,"Start flash download.\n");
    ^
    CC user/cgiwifi.c
    user/cgiwifi.c: In function 'cgiWiFiConnect':
    user/cgiwifi.c:220:4: warning: pointer targets in passing argument 1 of 'ets_strcpy' differ in signedness [-Wpointer-sign]
    os_strcpy(sysCfg.sta_ssid, essid); // Save the SSID into the main variables structure
    ^
    In file included from user/cgiwifi.c:26:0:
    include/espmissingincludes.h:22:7: note: expected 'char *' but argument is of type 'uint8_t *'
    char *ets_strcpy(char *dest, const char *src);
    ^
    user/cgiwifi.c:224:2: warning: pointer targets in passing argument 3 of 'httpdFindArg' differ in signedness [-Wpointer-sign]
    httpdFindArg(connData->postBuff, "sta_pwd", sysCfg.sta_pwd, sizeof(sysCfg.sta_pwd));
    ^
    In file included from user/cgiwifi.c:24:0:
    user/httpd.h:43:23: note: expected 'char *' but argument is of type 'uint8_t *'
    int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen);
    ^
    user/cgiwifi.c:226:2: warning: pointer targets in passing argument 2 of 'ets_strncpy' differ in signedness [-Wpointer-sign]
    os_strncpy((char*)stconf.ssid, sysCfg.sta_ssid, sizeof(sysCfg.sta_ssid));
    ^
    In file included from user/cgiwifi.c:26:0:
    include/espmissingincludes.h:25:7: note: expected 'const char *' but argument is of type 'uint8_t *'
    char *ets_strncpy(char *dest, const char *src, size_t n);
    ^
    user/cgiwifi.c:227:2: warning: pointer targets in passing argument 2 of 'ets_strncpy' differ in signedness [-Wpointer-sign]
    os_strncpy((char*)stconf.password, sysCfg.sta_pwd, sizeof(sysCfg.sta_pwd));
    ^
    In file included from user/cgiwifi.c:26:0:
    include/espmissingincludes.h:25:7: note: expected 'const char *' but argument is of type 'uint8_t *'
    char *ets_strncpy(char *dest, const char *src, size_t n);
    ^
    user/cgiwifi.c:229:2: warning: implicit declaration of function 'iprintf' [-Wimplicit-function-declaration]
    iprintf(INFO,"\r\nCONNECT: SSID=%s, PWD=%s\r\n",sysCfg.sta_ssid, sysCfg.sta_pwd);
    ^
    user/cgiwifi.c:236:2: warning: pointer targets in passing argument 3 of 'httpdFindArg' differ in signedness [-Wpointer-sign]
    httpdFindArg(connData->postBuff, "mqtt_pass", sysCfg.mqtt_pass, sizeof(sysCfg.mqtt_pass));
    ^
    In file included from user/cgiwifi.c:24:0:
    user/httpd.h:43:23: note: expected 'char *' but argument is of type 'uint8_t *'
    int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen);
    ^
    user/cgiwifi.c:237:2: warning: pointer targets in passing argument 3 of 'httpdFindArg' differ in signedness [-Wpointer-sign]
    httpdFindArg(connData->postBuff, "mqtt_user", sysCfg.mqtt_user, sizeof(sysCfg.mqtt_user));
    ^
    In file included from user/cgiwifi.c:24:0:
    user/httpd.h:43:23: note: expected 'char *' but argument is of type 'uint8_t *'
    int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen);
    ^
    user/cgiwifi.c:238:2: warning: pointer targets in passing argument 3 of 'httpdFindArg' differ in signedness [-Wpointer-sign]
    httpdFindArg(connData->postBuff, "mqtt_host", sysCfg.mqtt_host, sizeof(sysCfg.mqtt_host));
    ^
    In file included from user/cgiwifi.c:24:0:
    user/httpd.h:43:23: note: expected 'char *' but argument is of type 'uint8_t *'
    int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen);
    ^
    user/cgiwifi.c:240:2: warning: pointer targets in passing argument 3 of 'httpdFindArg' differ in signedness [-Wpointer-sign]
    httpdFindArg(connData->postBuff, "mqtt_device_name", sysCfg.base, sizeof(sysCfg.base));
    ^
    In file included from user/cgiwifi.c:24:0:
    user/httpd.h:43:23: note: expected 'char *' but argument is of type 'uint8_t *'
    int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen);
    ^
    user/cgiwifi.c:251:2: warning: pointer targets in passing argument 3 of 'httpdFindArg' differ in signedness [-Wpointer-sign]
    httpdFindArg(connData->postBuff, "mqtt_device_description", sysCfg.desc, sizeof(sysCfg.desc));
    ^
    In file included from user/cgiwifi.c:24:0:
    user/httpd.h:43:23: note: expected 'char *' but argument is of type 'uint8_t *'
    int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen);
    ^
    user/cgiwifi.c:252:2: warning: pointer targets in passing argument 3 of 'httpdFindArg' differ in signedness [-Wpointer-sign]
    httpdFindArg(connData->postBuff, "mqtt_device_attribute", sysCfg.attribute, sizeof(sysCfg.attribute));
    ^
    In file included from user/cgiwifi.c:24:0:
    user/httpd.h:43:23: note: expected 'char *' but argument is of type 'uint8_t *'
    int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen);
    ^
    user/cgiwifi.c:259:2: warning: pointer targets in passing argument 3 of 'httpdFindArg' differ in signedness [-Wpointer-sign]
    httpdFindArg(connData->postBuff, "web_user", sysCfg.web_user, sizeof(sysCfg.web_user));
    ^
    In file included from user/cgiwifi.c:24:0:
    user/httpd.h:43:23: note: expected 'char *' but argument is of type 'uint8_t *'
    int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen);
    ^
    user/cgiwifi.c:260:2: warning: pointer targets in passing argument 3 of 'httpdFindArg' differ in signedness [-Wpointer-sign]
    httpdFindArg(connData->postBuff, "web_pass", sysCfg.web_pass, sizeof(sysCfg.web_pass));
    ^
    In file included from user/cgiwifi.c:24:0:
    user/httpd.h:43:23: note: expected 'char *' but argument is of type 'uint8_t *'
    int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen);
    ^
    user/cgiwifi.c:203:6: warning: unused variable 'i' [-Wunused-variable]
    int i;
    ^
    user/cgiwifi.c:200:7: warning: unused variable 'passwd' [-Wunused-variable]
    char passwd[128];
    ^
    user/cgiwifi.c: In function 'tplWlan':
    user/cgiwifi.c:346:3: warning: format '%d' expects argument of type 'int', but argument 3 has type 'uint32_t' [-Wformat=]
    os_sprintf(s,"%d", sysCfg.mqtt_port);
    ^
    CC user/espfs.c
    In file included from user/espfs.c:48:0:
    include/httpdconfig.h:6:0: warning: "ESPFS_POS" redefined [enabled by default]
    #define ESPFS_POS 0x70000
    ^
    :0:0: note: this is the location of the previous definition
    CC user/heatshrink_decoder.c
    In file included from user/heatshrink_decoder.c:1:0:
    include/httpdconfig.h:6:0: warning: "ESPFS_POS" redefined [enabled by default]
    #define ESPFS_POS 0x70000
    ^
    :0:0: note: this is the location of the previous definition
    user/heatshrink_decoder.c:9:0: warning: "_STDINT_H" redefined [enabled by default]
    #define _STDINT_H
    ^
    :0:0: note: this is the location of the previous definition
    CC user/httpd.c
    CC user/httpdespfs.c
    user/httpdespfs.c: In function 'cgiEspFsHook':
    user/httpdespfs.c:60:2: warning: implicit declaration of function 'iprintf' [-Wimplicit-function-declaration]
    iprintf(DEBUG,"====OPENING THE FILE 1 ====\r\n");
    ^
    user/httpdespfs.c: In function 'cgiEspFsTemplate':
    user/httpdespfs.c:110:8: warning: unused variable 'p' [-Wunused-variable]
    char *p;
    ^
    user/httpdespfs.c: At top level:
    user/httpdespfs.c:35:16: warning: 'html_buf' defined but not used [-Wunused-variable]
    static uint8_t html_buf[1000];
    ^
    CC user/io.c
    In file included from user/auth.h:4:0,
    from user/aidan_and_petes.h:31,
    from user/io.c:19:
    include/httpdconfig.h:6:0: warning: "ESPFS_POS" redefined [enabled by default]
    #define ESPFS_POS 0x70000
    ^
    :0:0: note: this is the location of the previous definition
    CC user/petes_code.c
    In file included from user/auth.h:4:0,
    from user/aidan_and_petes.h:31,
    from user/petes_code.c:8:
    include/httpdconfig.h:6:0: warning: "ESPFS_POS" redefined [enabled by default]
    #define ESPFS_POS 0x70000
    ^
    :0:0: note: this is the location of the previous definition
    In file included from user/petes_code.c:10:0:
    ./include/driver/i2c_oled_fonts.h:14:2: warning: missing braces around initializer [-Wmissing-braces]
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
    ^
    ./include/driver/i2c_oled_fonts.h:14:2: warning: (near initialization for 'F6x8[0]') [-Wmissing-braces]
    user/petes_code.c: In function 'mqttDisconnectedCb':
    user/petes_code.c:222:16: warning: unused variable 'client' [-Wunused-variable]
    MQTT_Client* client = (MQTT_Client*) args;
    ^
    user/petes_code.c: In function 'mqttPublishedCb':
    user/petes_code.c:228:16: warning: unused variable 'client' [-Wunused-variable]
    MQTT_Client* client = (MQTT_Client*) args;
    ^
    user/petes_code.c: In function 'readDHT':
    user/petes_code.c:330:3: warning: implicit declaration of function 'ets_delay_us' [-Wimplicit-function-declaration]
    os_delay_us(250000);
    ^
    user/petes_code.c: In function 'WS2812OutBuffer':
    user/petes_code.c:581:4: warning: implicit declaration of function 'ets_intr_lock' [-Wimplicit-function-declaration]
    ets_intr_lock();
    ^
    user/petes_code.c:599:5: warning: implicit declaration of function 'ets_intr_unlock' [-Wimplicit-function-declaration]
    ets_intr_unlock();
    ^
    user/petes_code.c: In function 'mqttDataCb':
    user/petes_code.c:1077:7: warning: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Wpointer-sign]
    strcpy(sysCfg.base, strValue);
    ^
    In file included from /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:10:0,
    from /opt/esp-open-sdk/sdk/include/osapi.h:8,
    from user/aidan_and_petes.h:14,
    from user/petes_code.c:8:
    /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:30:8: note: expected 'char *' but argument is of type 'uint8_t *'
    char *_EXFUN(strcpy,(char *, const char *));
    ^
    user/petes_code.c:1098:7: warning: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Wpointer-sign]
    strcpy(sysCfg.desc, strValue);
    ^
    In file included from /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:10:0,
    from /opt/esp-open-sdk/sdk/include/osapi.h:8,
    from user/aidan_and_petes.h:14,
    from user/petes_code.c:8:
    /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:30:8: note: expected 'char *' but argument is of type 'uint8_t *'
    char *_EXFUN(strcpy,(char *, const char *));
    ^
    user/petes_code.c:1108:7: warning: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Wpointer-sign]
    strcpy(sysCfg.attribute, strValue);
    ^
    In file included from /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:10:0,
    from /opt/esp-open-sdk/sdk/include/osapi.h:8,
    from user/aidan_and_petes.h:14,
    from user/petes_code.c:8:
    /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:30:8: note: expected 'char *' but argument is of type 'uint8_t *'
    char *_EXFUN(strcpy,(char *, const char *));
    ^
    user/petes_code.c:1116:6: warning: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Wpointer-sign]
    strcpy(sysCfg.sta_ssid, strValue);
    ^
    In file included from /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:10:0,
    from /opt/esp-open-sdk/sdk/include/osapi.h:8,
    from user/aidan_and_petes.h:14,
    from user/petes_code.c:8:
    /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:30:8: note: expected 'char *' but argument is of type 'uint8_t *'
    char *_EXFUN(strcpy,(char *, const char *));
    ^
    user/petes_code.c:1120:6: warning: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Wpointer-sign]
    strcpy(sysCfg.sta_pwd, strValue);
    ^
    In file included from /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:10:0,
    from /opt/esp-open-sdk/sdk/include/osapi.h:8,
    from user/aidan_and_petes.h:14,
    from user/petes_code.c:8:
    /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:30:8: note: expected 'char *' but argument is of type 'uint8_t *'
    char *_EXFUN(strcpy,(char *, const char *));
    ^
    user/petes_code.c:1124:6: warning: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Wpointer-sign]
    strcpy(sysCfg.mqtt_host, strValue);
    ^
    In file included from /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:10:0,
    from /opt/esp-open-sdk/sdk/include/osapi.h:8,
    from user/aidan_and_petes.h:14,
    from user/petes_code.c:8:
    /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:30:8: note: expected 'char *' but argument is of type 'uint8_t *'
    char *_EXFUN(strcpy,(char *, const char *));
    ^
    user/petes_code.c:1132:6: warning: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Wpointer-sign]
    strcpy(sysCfg.mqtt_user, strValue);
    ^
    In file included from /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:10:0,
    from /opt/esp-open-sdk/sdk/include/osapi.h:8,
    from user/aidan_and_petes.h:14,
    from user/petes_code.c:8:
    /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:30:8: note: expected 'char *' but argument is of type 'uint8_t *'
    char *_EXFUN(strcpy,(char *, const char *));
    ^
    user/petes_code.c:1136:6: warning: pointer targets in passing argument 1 of 'strcpy' differ in signedness [-Wpointer-sign]
    strcpy(sysCfg.mqtt_pass, strValue);
    ^
    In file included from /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:10:0,
    from /opt/esp-open-sdk/sdk/include/osapi.h:8,
    from user/aidan_and_petes.h:14,
    from user/petes_code.c:8:
    /opt/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include/string.h:30:8: note: expected 'char *' but argument is of type 'uint8_t *'
    char *_EXFUN(strcpy,(char *, const char *));
    ^
    user/petes_code.c:1588:6: warning: implicit declaration of function 'sntp_get_current_timestamp' [-Wimplicit-function-declaration]
    current_stamp=sntp_get_current_timestamp();
    ^
    user/petes_code.c:1590:6: warning: implicit declaration of function 'sntp_get_real_time' [-Wimplicit-function-declaration]
    iprintf(RESPONSE,"sntp: %d %s \r\n",current_stamp, sntp_get_real_time(current_stamp));
    ^
    user/petes_code.c:758:12: warning: variable 'noArgs' set but not used [-Wunused-but-set-variable]
    uint8_t noArgs;
    ^
    user/petes_code.c:754:11: warning: unused variable 'argType' [-Wunused-variable]
    int8_t argType;
    ^
    user/petes_code.c: In function 'bounce_cb':
    user/petes_code.c:1802:10: warning: variable 'pin2changed' set but not used [-Wunused-but-set-variable]
    int8_t pin2changed;
    ^
    user/petes_code.c: In function 'mqtt_setup':
    user/petes_code.c:2150:5: warning: pointer targets in passing argument 2 of 'MQTT_InitLWT' differ in signedness [-Wpointer-sign]
    MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0);
    ^
    In file included from user/aidan_and_petes.h:15:0,
    from user/petes_code.c:8:
    mqtt/mqtt.h:127:24: note: expected 'uint8_t *' but argument is of type 'char *'
    void ICACHE_FLASH_ATTR MQTT_InitLWT(MQTT_Client *mqttClient, uint8_t* will_topic, uint8_t* will_msg, uint8_t will_qos, uint8_t will_retain);
    ^
    user/petes_code.c:2150:5: warning: pointer targets in passing argument 3 of 'MQTT_InitLWT' differ in signedness [-Wpointer-sign]
    MQTT_InitLWT(&mqttClient, "/lwt", "offline", 0, 0);
    ^
    In file included from user/aidan_and_petes.h:15:0,
    from user/petes_code.c:8:
    mqtt/mqtt.h:127:24: note: expected 'uint8_t *' but argument is of type 'char *'
    void ICACHE_FLASH_ATTR MQTT_InitLWT(MQTT_Client *mqttClient, uint8_t* will_topic, uint8_t* will_msg, uint8_t will_qos, uint8_t will_retain);
    ^
    user/petes_code.c: In function 'mqtt_init':
    user/petes_code.c:2186:2: warning: implicit declaration of function 'sntp_setservername' [-Wimplicit-function-declaration]
    sntp_setservername(0,"us.pool.ntp.org");
    ^
    user/petes_code.c:2188:2: warning: implicit declaration of function 'sntp_init' [-Wimplicit-function-declaration]
    sntp_init();
    ^
    CC user/stdout.c
    CC user/user_main.c
    In file included from user/auth.h:4:0,
    from user/user_main.c:56:
    include/httpdconfig.h:6:0: warning: "ESPFS_POS" redefined [enabled by default]
    #define ESPFS_POS 0x70000
    ^
    :0:0: note: this is the location of the previous definition
    user/user_main.c: In function 'user_init':
    user/user_main.c:66:2: warning: implicit declaration of function 'petes_initialisation' [-Wimplicit-function-declaration]
    petes_initialisation(); // Sets up the ports and initialises various values needed by the MQTT call backs, time etc
    ^
    user/user_main.c:67:2: warning: implicit declaration of function 'setupwebpage_init' [-Wimplicit-function-declaration]
    setupwebpage_init(); // Set up the configuration/control web pages - or not
    ^
    CC user/wifi.c
    user/wifi.c: In function 'wifiInit':
    user/wifi.c:22:2: warning: implicit declaration of function 'iprintf' [-Wimplicit-function-declaration]
    iprintf(DEBUG,"\r===== WiFi Init =====\r");
    ^
    user/wifi.c: In function 'setup_wifi_ap_mode':
    user/wifi.c:85:2: warning: pointer targets in passing argument 1 of 'ets_sprintf' differ in signedness [-Wpointer-sign]
    apconfig.ssid_len = os_sprintf(apconfig.ssid, WIFI_AP_NAME);
    ^
    In file included from user/wifi.c:5:0:
    include/espmissingincludes.h:19:5: note: expected 'char *' but argument is of type 'uint8 *'
    int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
    ^
    user/wifi.c:86:2: warning: pointer targets in passing argument 1 of 'ets_sprintf' differ in signedness [-Wpointer-sign]
    os_sprintf(apconfig.password, "%s", WIFI_AP_PASSWORD);
    ^
    In file included from user/wifi.c:5:0:
    include/espmissingincludes.h:19:5: note: expected 'char *' but argument is of type 'uint8 *'
    int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
    ^
    user/wifi.c: In function 'setup_wifi_st_mode':
    user/wifi.c:126:3: warning: pointer targets in passing argument 1 of 'ets_sprintf' differ in signedness [-Wpointer-sign]
    os_sprintf(stconfig.ssid, "%s", sysCfg.sta_ssid);
    ^
    In file included from user/wifi.c:5:0:
    include/espmissingincludes.h:19:5: note: expected 'char *' but argument is of type 'uint8 *'
    int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
    ^
    user/wifi.c:127:3: warning: pointer targets in passing argument 1 of 'ets_sprintf' differ in signedness [-Wpointer-sign]
    os_sprintf(stconfig.password, "%s", sysCfg.sta_pwd);
    ^
    In file included from user/wifi.c:5:0:
    include/espmissingincludes.h:19:5: note: expected 'char *' but argument is of type 'uint8 *'
    int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
    ^
    AR build/httpd_app.a
    LD build/httpd.out
    build/httpd_app.a(aidans_code.o):(.irom0.text+0x20): undefined reference to `MQTT_Connect'
    build/httpd_app.a(aidans_code.o):(.irom0.text+0x24): undefined reference to `MQTT_Disconnect'
    build/httpd_app.a(aidans_code.o): In function `MQTTLogonTimerCb':
    /home/john/hackitt_mqtt/user/aidans_code.c:58: undefined reference to `MQTT_Connect'
    /home/john/hackitt_mqtt/user/aidans_code.c:64: undefined reference to `MQTT_Disconnect'
    /home/john/hackitt_mqtt/user/aidans_code.c:74: undefined reference to `sysCfg'
    /home/john/hackitt_mqtt/user/aidans_code.c:82: undefined reference to `CFG_Save'
    build/httpd_app.a(aidans_code.o): In function `setupwebpage_init':
    /home/john/hackitt_mqtt/user/aidans_code.c:100: undefined reference to `CFG_Save'
    build/httpd_app.a(cgi.o):(.irom0.text+0xc): undefined reference to `sysCfg'
    build/httpd_app.a(cgi.o): In function `cgiLed':
    cgi.c:(.irom0.text+0x148): undefined reference to `sysCfg'
    build/httpd_app.a(cgiwifi.o): In function `cgiWiFiScan':
    /home/john/hackitt_mqtt/user/cgiwifi.c:126: undefined reference to `sysCfg'
    /home/john/hackitt_mqtt/user/cgiwifi.c:129: undefined reference to `sysCfg'
    /home/john/hackitt_mqtt/user/cgiwifi.c:131: undefined reference to `sysCfg'
    build/httpd_app.a(cgiwifi.o):/home/john/hackitt_mqtt/user/cgiwifi.c:134: more undefined references to `sysCfg' follow
    build/httpd_app.a(cgiwifi.o): In function `cgiWiFiConnect':
    /home/john/hackitt_mqtt/user/cgiwifi.c:227: undefined reference to `CFG_Save'
    build/httpd_app.a(petes_code.o): In function `mqttPublishedCb':
    petes_code.c:(.irom0.text+0x4c): undefined reference to `MQTT_Subscribe'
    petes_code.c:(.irom0.text+0x50): undefined reference to `MQTT_Publish'
    petes_code.c:(.irom0.text+0x76): undefined reference to `MQTT_Subscribe'
    build/httpd_app.a(petes_code.o): In function `mqttConnectedCb':
    /home/john/hackitt_mqtt/user/petes_code.c:206: undefined reference to `MQTT_Subscribe'
    /home/john/hackitt_mqtt/user/petes_code.c:211: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:216: undefined reference to `easygpio_pinMode'
    /home/john/hackitt_mqtt/user/petes_code.c:216: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:216: undefined reference to `easygpio_outputDisable'
    /home/john/hackitt_mqtt/user/petes_code.c:217: undefined reference to `easygpio_inputGet'
    /home/john/hackitt_mqtt/user/petes_code.c:217: undefined reference to `easygpio_pinMode'
    /home/john/hackitt_mqtt/user/petes_code.c:217: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:217: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:217: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:217: undefined reference to `easygpio_outputDisable'
    build/httpd_app.a(petes_code.o): In function `readDHT':
    /home/john/hackitt_mqtt/user/petes_code.c:316: undefined reference to `easygpio_inputGet'
    /home/john/hackitt_mqtt/user/petes_code.c:331: undefined reference to `easygpio_inputGet'
    /home/john/hackitt_mqtt/user/petes_code.c:332: undefined reference to `easygpio_inputGet'
    /home/john/hackitt_mqtt/user/petes_code.c:394: undefined reference to `easygpio_inputGet'
    build/httpd_app.a(petes_code.o): In function `lostThePlot_cb':
    /home/john/hackitt_mqtt/user/petes_code.c:1975: undefined reference to `easygpio_inputGet'
    build/httpd_app.a(petes_code.o):/home/john/hackitt_mqtt/user/petes_code.c:1985: more undefined references to `easygpio_inputGet' follow
    build/httpd_app.a(petes_code.o): In function `lostThePlot_cb':
    /home/john/hackitt_mqtt/user/petes_code.c:1985: undefined reference to `CFG_Save'
    /home/john/hackitt_mqtt/user/petes_code.c:1989: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1995: undefined reference to `easygpio_outputSet'
    build/httpd_app.a(petes_code.o): In function `startup_cb':
    /home/john/hackitt_mqtt/user/petes_code.c:1629: undefined reference to `MQTT_Connect'
    /home/john/hackitt_mqtt/user/petes_code.c:1630: undefined reference to `MQTT_Disconnect'
    build/httpd_app.a(petes_code.o): In function `convertTime':
    /home/john/hackitt_mqtt/user/petes_code.c:274: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:279: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:291: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:299: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:306: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:308: undefined reference to `MQTT_Publish'
    build/httpd_app.a(petes_code.o): In function `rtc_cb':
    /home/john/hackitt_mqtt/user/petes_code.c:2024: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:2033: undefined reference to `CFG_Save'
    /home/john/hackitt_mqtt/user/petes_code.c:2042: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:2046: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:2047: undefined reference to `easygpio_outputEnable'
    /home/john/hackitt_mqtt/user/petes_code.c:2052: undefined reference to `easygpio_pinMode'
    /home/john/hackitt_mqtt/user/petes_code.c:2059: undefined reference to `easygpio_inputGet'
    /home/john/hackitt_mqtt/user/petes_code.c:2061: undefined reference to `easygpio_outputEnable'
    /home/john/hackitt_mqtt/user/petes_code.c:2066: undefined reference to `easygpio_outputDisable'
    /home/john/hackitt_mqtt/user/petes_code.c:2082: undefined reference to `easygpio_outputEnable'
    /home/john/hackitt_mqtt/user/petes_code.c:2090: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:2096: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:2110: undefined reference to `easygpio_outputDisable'
    /home/john/hackitt_mqtt/user/petes_code.c:2118: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:2129: undefined reference to `easygpio_outputEnable'
    /home/john/hackitt_mqtt/user/petes_code.c:2134: undefined reference to `easygpio_outputDisable'
    /home/john/hackitt_mqtt/user/petes_code.c:2136: undefined reference to `easygpio_inputGet'
    build/httpd_app.a(petes_code.o): In function `ok':
    /home/john/hackitt_mqtt/user/petes_code.c:605: undefined reference to `sysCfg'
    build/httpd_app.a(petes_code.o): In function `HSV2RGB':
    /home/john/hackitt_mqtt/user/petes_code.c:690: undefined reference to `easygpio_pinMode'
    /home/john/hackitt_mqtt/user/petes_code.c:690: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:690: undefined reference to `easygpio_pinMode'
    build/httpd_app.a(petes_code.o): In function `mqttDataCb':
    /home/john/hackitt_mqtt/user/petes_code.c:719: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:849: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:876: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:886: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:919: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:928: undefined reference to `CFG_Save'
    /home/john/hackitt_mqtt/user/petes_code.c:932: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:996: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1016: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1019: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1095: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1142: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1146: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1146: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1156: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1162: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1176: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1180: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1200: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1204: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1226: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1237: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1257: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1266: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1269: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1271: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1284: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1286: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1307: undefined reference to `CFG_Save'
    /home/john/hackitt_mqtt/user/petes_code.c:1330: undefined reference to `MQTT_Connect'
    /home/john/hackitt_mqtt/user/petes_code.c:1336: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1351: undefined reference to `CFG_Save'
    /home/john/hackitt_mqtt/user/petes_code.c:1370: undefined reference to `easygpio_inputGet'
    /home/john/hackitt_mqtt/user/petes_code.c:1372: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1372: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1377: undefined reference to `easygpio_inputGet'
    /home/john/hackitt_mqtt/user/petes_code.c:1383: undefined reference to `easygpio_inputGet'
    /home/john/hackitt_mqtt/user/petes_code.c:1386: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1387: undefined reference to `MQTT_Publish'
    /home/john/hackitt_mqtt/user/petes_code.c:1387: undefined reference to `easygpio_inputGet'
    /home/john/hackitt_mqtt/user/petes_code.c:1398: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1401: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1429: undefined reference to `MQTT_InitConnection'
    /home/john/hackitt_mqtt/user/petes_code.c:1430: undefined reference to `MQTT_InitClient'
    /home/john/hackitt_mqtt/user/petes_code.c:1430: undefined reference to `MQTT_InitLWT'
    /home/john/hackitt_mqtt/user/petes_code.c:1430: undefined reference to `MQTT_OnConnected'
    /home/john/hackitt_mqtt/user/petes_code.c:1431: undefined reference to `MQTT_OnDisconnected'
    /home/john/hackitt_mqtt/user/petes_code.c:1431: undefined reference to `MQTT_OnPublished'
    /home/john/hackitt_mqtt/user/petes_code.c:1432: undefined reference to `MQTT_OnData'
    /home/john/hackitt_mqtt/user/petes_code.c:1433: undefined reference to `MQTT_InitConnection'
    /home/john/hackitt_mqtt/user/petes_code.c:1433: undefined reference to `MQTT_InitClient'
    /home/john/hackitt_mqtt/user/petes_code.c:1436: undefined reference to `MQTT_InitLWT'
    /home/john/hackitt_mqtt/user/petes_code.c:1437: undefined reference to `MQTT_OnConnected'
    /home/john/hackitt_mqtt/user/petes_code.c:1440: undefined reference to `MQTT_OnDisconnected'
    /home/john/hackitt_mqtt/user/petes_code.c:1440: undefined reference to `MQTT_OnPublished'
    /home/john/hackitt_mqtt/user/petes_code.c:1444: undefined reference to `MQTT_OnData'
    /home/john/hackitt_mqtt/user/petes_code.c:1472: undefined reference to `CFG_Load'
    /home/john/hackitt_mqtt/user/petes_code.c:1476: undefined reference to `CFG_Load'
    /home/john/hackitt_mqtt/user/petes_code.c:1476: undefined reference to `easygpio_pinMode'
    /home/john/hackitt_mqtt/user/petes_code.c:1483: undefined reference to `easygpio_pinMode'
    /home/john/hackitt_mqtt/user/petes_code.c:1484: undefined reference to `easygpio_pinMode'
    /home/john/hackitt_mqtt/user/petes_code.c:1485: undefined reference to `easygpio_pinMode'
    /home/john/hackitt_mqtt/user/petes_code.c:1486: undefined reference to `easygpio_pinMode'
    build/httpd_app.a(petes_code.o):/home/john/hackitt_mqtt/user/petes_code.c:1488: more undefined references to `easygpio_pinMode' follow
    build/httpd_app.a(petes_code.o): In function `mqttDataCb':
    /home/john/hackitt_mqtt/user/petes_code.c:1497: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1501: undefined reference to `easygpio_pinMode'
    /home/john/hackitt_mqtt/user/petes_code.c:1503: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1506: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1509: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1511: undefined reference to `easygpio_outputSet'
    /home/john/hackitt_mqtt/user/petes_code.c:1512: undefined reference to `easygpio_outputSet'
    build/httpd_app.a(petes_code.o):/home/john/hackitt_mqtt/user/petes_code.c:1514: more undefined references to `easygpio_outputSet' follow
    collect2: error: ld returned 1 exit status
    make: *** [build/httpd.out] Error 1
    [2]john@dc7700p2 ~/hackitt_mqtt $

    1. Hi John

      Ok, first off - Github - tried it, don't like it, prefer Bitbucket, sticking with it. So can't help there. Also apart from working on Raspberry Pi, everything I do it in Windows - when I started all of this everything for the ESP8266 was Linux so I'm happy to redress the balance - the code should compile no problem in the Eclipse environment on a PC - having said all that if I can be of help to anyone using Linux - I will do my best. The EASYGPIO stuff - I'm pretty sure in the Windows Make file it is referred to - I have never touched the Linux make file in there so it is likely of little use. If anyone wants to make it work I'll most certainly replace the one there. I added the easyGPIO stuff well after the makefiles were created and added the reference in only to the Windows version. Actually it's mainly cosmetic - but I find actually understanding commands helps 🙂

      CFG-Save is the relatively NEW function set in SDK 1.3.0 - was probably there earlier - it replaces TUANs original save functions. I note he's done the same now but I just fixed them myself.

      Some of the other items escape me - I hope someone else can help in here.

    1. Simple Johnny - I don't wish to use Github! Looked at it, didn't like it, preferred BitBucket. This is about having fun not doing something I don't want to 🙂 You're probably right about the forums though. Well, in the years I've been running this forum I've seen a very long post like that last (quite welcome) post once... so I guess it's not a big issue.

  21. Ok got a bit further today, Makefile for linux now as follows:

    [code language="bash"]
    # tnx to mamalala
    # Changelog
    # Changed the variables to include the header file directory
    # Added global var for the XTENSA tool root
    #
    # This make file still needs some work.
    #
    #
    # Output directors to store intermediate compiled files
    # relative to the project directory
    BUILD_BASE = build
    FW_BASE = firmware

    FLASH_OPTS ?= -fs 4m

    # Base directory for the compiler
    XTENSA_TOOLS_ROOT ?= /opt/esp-open-sdk/xtensa-lx106-elf/bin

    #Extra Tensilica includes from the ESS VM
    SDK_EXTRA_INCLUDES ?= /opt/esp-open-sdk/sdk/include
    SDK_EXTRA_LIBS ?= /opt/esp-open-sdk/sdk/lib

    # base directory of the ESP8266 SDK package, absolute
    SDK_BASE ?= /opt/esp-open-sdk/sdk

    #Esptool.py path and port
    ESPTOOL ?= esptool
    ESPPORT ?= /dev/ttyUSB0
    #ESPDELAY indicates seconds to wait between flashing the two binary images
    ESPDELAY ?= 3
    ESPBAUD ?= 115200

    # name for the target project
    TARGET = app

    USE_HEATSHRINK ?= yes

    # which modules (subdirectories) of the project to include in compiling
    #MODULES = driver user lwip/api lwip/app lwip/core lwip/core/ipv4 lwip/netif
    MODULES = driver mqtt user easygpio
    EXTRA_INCDIR = include \
    . \
    mqtt \
    easygpio/include \
    lib/heatshrink/ \
    $(SDK_EXTRA_INCLUDES)

    # libraries used in this project, mainly provided by the SDK
    LIBS = c gcc hal phy pp net80211 lwip wpa pwm upgrade main ssl
    #c gcc hal phy pp net80211 wpa main lwip

    # compiler flags using during compilation of source files
    CFLAGS = -Os -ggdb -std=c99 -Wpointer-arith -Wundef -Wall -Wl,-EL -fno-inline-functions \
    -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH -D_STDINT_H \
    -Wno-address -DESPFS_POS=$(ESPFS_POS) -DESPFS_SIZE=$(ESPFS_SIZE)

    #-DLWIP_OPEN_SRC -Wno-address -Werror

    # linker flags used to generate the main object file
    LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static
    #L--start-group$(SDK_EXTRA_LIBS)

    # linker script used for the above linkier step
    LD_SCRIPT = eagle.app.v6.ld
    #LD_SCRIPT = eagle.app.v6.ld

    # various paths from the SDK used in this project
    SDK_LIBDIR = lib
    SDK_LDDIR = ld
    SDK_INCDIR = include include/json

    # we create two different files for uploading into the flash
    # these are the names and options to generate them
    FW_FILE_1 = 0x00000
    FW_FILE_1_ARGS = -bo $@ -bs .text -bs .data -bs .rodata -bc -ec
    FW_FILE_2 = 0x40000
    FW_FILE_2_ARGS = -es .irom0.text $@ -ec

    # select which tools to use as compiler, librarian and linker
    CC := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
    AR := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-ar
    LD := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
    OBJCOPY := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-objcopy
    OBJDUMP := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-objdump

    ####
    #### no user configurable options below here
    ####

    [/code]

    Compiler output:
    [code language="bash"]

    make clean
    john@dc7700p2 ~/hackitt_mqtt $ make
    CC driver/ds18b20.c
    driver/ds18b20.c: In function 'reset':
    driver/ds18b20.c:206:3: warning: implicit declaration of function 'ets_delay_us' [-Wimplicit-function-declaration]
    os_delay_us(2);
    ^
    CC driver/gpio16.c
    CC driver/i2c.c
    driver/i2c.c: In function 'i2c_init':
    driver/i2c.c:60:5: warning: implicit declaration of function 'ets_isr_mask' [-Wimplicit-function-declaration]
    ETS_GPIO_INTR_DISABLE();
    ............

    WHOLE BUNCH MORE WARNINGS THEN
    AR build/app_app.a
    LD build/app.out
    /opt/esp-open-sdk/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: build/app.out section `.irom0.text' will not fit in region `irom0_0_seg'
    collect2: error: ld returned 1 exit status
    make: *** [build/app.out] Error 1

    [/code]

    So it now appears as the compiled code is too large to fit on the ESP ROM or I need to tell the compiler something else any help appreciated

    1. As you may have realised - we use a bootloader....which shoves everything down at the bottom - and we manage to fit the code in with lots of room to spare. The standard "stick it at 0x40000" is no good. Trust me there is lots of room. We use Richard Burton's RBOOT.

      eagle.app.v6.ld needs to look like this at the start..

      /* This linker script generated from xt-genldscripts.tpp for LSP . */
      /* Linker Script for ld -N */
      MEMORY
      {
      dport0_0_seg : org = 0x3FF00000, len = 0x10
      dram0_0_seg : org = 0x3FFE8000, len = 0x14000
      iram1_0_seg : org = 0x40100000, len = 0x8000

      irom0_0_seg : org = 0x40202010, len = 0x68000
      /* irom0_0_seg : org = 0x40220000, len = 0x58000 */
      }

  22. Hi Pete,

    I thought I'd take a look at your project again and downloaded the Hackitt_mqtt. It looks like you've been busy!

    I tried to compile it (with SDK 1.4.0) and it failed. I also read that you had had to make some header file changes - I wonder if they have been uploaded yet?

    The error I got was:

    In file included from mqtt/queue.c:38:0:
    mqtt/queue.c: In function 'QUEUE_Init':
    c:\espressif\include\mem.h:9:27: error: too many arguments to function 'pvPortZalloc'
    #define os_zalloc(s) pvPortZalloc(s, "", 0)
    ^
    mqtt/queue.c:42:25: note: in expansion of macro 'os_zalloc'
    queue->buf = (uint8_t*)os_zalloc(bufferSize);
    ^
    In file included from mqtt/queue.c:32:0:
    include/espmissingincludes.h:34:7: note: declared here
    C:/Users/john/Documents/ESP8266/hackitt_mqtt/Makefile:160: recipe for target 'build/mqtt/queue.o' failed
    void *pvPortZalloc(size_t);

    Does that look familiar??

    Thx John

    1. Oh dear.. yes I do indeed remember it, I just don't remember what the fix was. The thing is - I've just started using 1.4.0 - so it's not a fix to the SDK - and you've obviously grabbed the code I'm using..... which makes me wonder why that error would come up. Just to confirm, you have the latest SDK and the latest code - from bitbucket?

  23. Its wierd. I tried running the code under SDK 1.3 and got the same error. I thought you'd be running under 1.4 so I downloaded it and installed it and it did not produce that error - however it did throw up en error when trying to write out the compiled files down at line 132 of the Makefile.

    1. There was a change for 1.4 - I think I noted it when I updated the code... so under 1.4 are you getting that zalloc error or a different one?

      So I recall writing to my friend the following..

      ***********************************
      1.40 has an issue with a zalloc command – they’ve changed something and our code won’t work so I’m sticking with 1.3 until they fix it.
      void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE *queue, int bufferSize)
      {
      queue->buf = (uint8_t*)os_zalloc(bufferSize);
      RINGBUF_Init(&queue->rb, queue->buf, bufferSize);
      }
      Sadly as I have no idea what the zalloc command is actually returning I can’t replace it.
      ***************************

      But since then I HAVE moved onto 1.4 - hang fire while I go look to see how I found out how to change it..

      Ok, then I wroet this..

      ***********************
      Good evening
      Code updated – a change to ESPMISSINGINCLUDES.H was needed. Code will no longer compile with SDK 1.3 and earlier – grab SDK 1.4
      All seems to be working well.
      Pete.
      ***********************

      Ok, make sure your espmissingincludes.h is the same as this..

      #ifndef ESPMISSINGINCLUDES_H
      #define ESPMISSINGINCLUDES_H

      #include
      #include

      //Missing function prototypes in include folders. Gcc will warn on these if we don't define 'em anywhere.
      //MOST OF THESE ARE GUESSED! but they seem to swork and shut up the compiler.
      typedef struct espconn espconn;

      int atoi(const char *nptr);
      void ets_install_putc1(void *routine);
      void ets_isr_attach(int intr, void *handler, void *arg);
      void ets_isr_mask(unsigned intr);
      void ets_isr_unmask(unsigned intr);
      int ets_memcmp(const void *s1, const void *s2, size_t n);
      void *ets_memcpy(void *dest, const void *src, size_t n);
      void *ets_memset(void *s, int c, size_t n);
      int ets_sprintf(char *str, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
      int ets_str2macaddr(void *, void *);
      int ets_strcmp(const char *s1, const char *s2);
      char *ets_strcpy(char *dest, const char *src);
      size_t ets_strlen(const char *s);
      int ets_strncmp(const char *s1, const char *s2, int len);
      char *ets_strncpy(char *dest, const char *src, size_t n);
      char *ets_strstr(const char *haystack, const char *needle);
      void ets_timer_arm_new(ETSTimer *a, int b, int c, int isMstimer);
      void ets_timer_disarm(ETSTimer *a);
      void ets_timer_setfn(ETSTimer *t, ETSTimerFunc *fn, void *parg);
      void ets_update_cpu_frequency(int freqmhz);
      int os_printf(const char *format, ...) __attribute__ ((format (printf, 1, 2)));
      int os_snprintf(char *str, size_t size, const char *format, ...) __attribute__ ((format (printf, 3, 4)));

      //void pvPortFree(void *ptr);
      //void *pvPortMalloc(size_t xWantedSize);
      //void *pvPortZalloc(size_t);
      // void vPortFree(void *ptr);
      // void *vPortMalloc(size_t xWantedSize);

      // memory allocation functions are "different" due to memory debugging functionality
      // added in SDK 1.4.0
      void vPortFree(void *ptr, char * file, int line);
      void *pvPortMalloc(size_t xWantedSize, char * file, int line);
      void *pvPortZalloc(size_t, char * file, int line);
      void *vPortMalloc(size_t xWantedSize);
      void pvPortFree(void *ptr);

      void uart_div_modify(int no, unsigned int freq);

      uint8 wifi_get_opmode(void);
      uint32 system_get_time();
      //int os_random();
      int rand(void);
      void ets_bzero(void *s, size_t n);
      #endif

  24. Yay! That was it! Thank you.
    (NB - for any other readers - don't copy and paste the entire code above - just the bit with the notes "added in SDK 1.4.0". Otherwise the periods in the int os_snprintf(char *str, size_t size, const char *format, …) __attribute__ ((format (printf, 3, 4))); line will come out differently and cause an error.)

    Just back to the problem at line 132 of the Makefile now...

    FW firmware/app.bin
    C:/Users/john/Documents/ESP8266/hackitt_mqtt/Makefile:132: recipe for target 'firmware/app.bin' failed
    process_begin: CreateProcess(NULL, C:/esptools/esptool2.exe -quiet -bin -boot2 -512 build/app.out firmware/app.bin .text .data .rodata, ...) failed.
    make (e=2): The system cannot find the file specified.

    mingw32-make.exe: *** [firmware/app.bin] Error 2

  25. Pete & Aidan, this is great work 🙂

    What I'd *love* to see is something like this extended to control RF based radiator valves - take a look at Honeywell Evohome and you'll see what I mean.

    Cheers
    Robin

  26. That would be great and a doddle to implement if it wasn't for the power consumption of the ESP8266!
    However, if you could get either mains or 12V to the valve, then there's no reason why not

  27. Great article - and great HW/SW package!
    I can't build it to see it in action though as I'm missing this utility:
    WEBTOOL ?= c:\Espressif\utils\web_page_convert.py
    Looking at the commits it seems like you added this in after the initial commit few days ago. Seems like it's pushing the espfs content as a byte array into webpage.h. Can you share some background on what the benefit is vs. having ESPFS_POS unset so that the espfs content is automatically placed right after the code?

    1. The PY file should be up there now... if not I can make it available.

      The original system generates a separate file for web pages and that is inconvenient for OTA - so we figured, convert it into a FLASH array and make that an H file as part of the project - hence one file. If you have a better way while still generating one rom - happy to hear all about it 🙂
      And don't ask me any questions about MAKE files as I'm terrible at them.

      1. Here is what I did in another project to get a single bin file for code and filesystem. I don't recall where I got the idea from - could be the original esphttpd makefile...
        The trick is to transform the filesystem file generated with mkespfs into another library and then include it with the code libraries as part of the main linking process:

        $(FS_0): fs
        cd fs; find | ../../$(MKESPFS) > ../$(FS_0); cd ..

        $(FSLIB_0): $(FS_0)
        $(OBJCOPY) -I binary -O elf32-xtensa-le -B xtensa --rename-section .data=.irom0.literal $(FS_0) $(FSOBJ_0).tmp
        $(LD) -nostdlib -Wl,-r $(FSOBJ_0).tmp -o $(FSOBJ_0) -Wl,$(FSLD_0)
        $(AR) cru $@ $(FSOBJ_0)

        $(TARGET_0): $(FSLIB_0) $(APP_AR_0)
        @echo "LD $@"
        $(LD) -L$(SDK_LIBDIR) -L$(BUILD_BASE) $(LD_SCRIPT_0) $(LDFLAGS) -Wl,--start-group $(LIBS) $(APP_AR_0) -Wl,--end-group -o $@

        $(FW_ROM_0): $(TARGET_0)
        @echo "E2 $@"
        ../$(ESPTOOL2) $(ESPTOOL2_ARGS) $(TARGET_0) $@ $(ESPTOOL2_SECTS)

        1. Here's the most important part. I can share the full makefile but it's a sub-makefile only that is based on a lot of variables defined in the main makefile... Happy to help if questions!

          $(APP_AR_0): $(OBJ) $(FSOBJ_0)
          @echo "AR $@"
          $(AR) cru $@ $^

  28. Don't forget that web_page_convert.py should be placed in your \espressif\utils folder. I put it in there so that it would be available to other projects, but if you want to place it in the same folder as your project, you'll simply need to amend the WEBTOOL define at the top of the makefile to the correct location

    1. That explains a lot- here is the .py file.

      # Returns error codes:
      # 1 = couldn't open input file
      # 2 = couldn't open output file

      import sys

      # Do we have any arguments?
      if (len(sys.argv) == 1):
      print "Usage: web_page_convert.py 1):
      try:
      in_file = open(sys.argv[1], "rb")
      except IOError:
      print "Couldn't open ", sys.argv[1]
      exit(1)
      else:
      try:
      in_file = open("webpages.espfs", "rb")
      except IOError:
      print "Couldn't open webpages.espfs"
      exit(1)

      print "Input from webpages.espf in current directory"

      if (len(sys.argv) > 2):
      try:
      out_file = open(sys.argv[2], "w")
      except IOError:
      print "Couldn't open output file ", sys.argv[2]
      exit(2)
      else:
      try:
      out_file = open("webpage.h", "w")
      except IOError:
      print "Couldn't open output file webpage.h"
      exit(2)
      print "Output to webpage.h in current directory"

      out_file.write("#ifndef USER_WEBPAGE_H_\n")
      out_file.write("#define USER_WEBPAGE_H_\n")
      out_file.write("static const uint8_t ICACHE_RODATA_ATTR web_page[] = {")

      items_per_line = 30
      byte_count = 0
      beginning = 1

      while True:
      # if this isn't the start then put in a comma separator
      # - used to avoid a trailing comma at the end of the file
      if beginning != 1:
      out_file.write(", ")
      else:
      beginning = 0

      # read and output the next byte
      next_byte = in_file.read(1)

      # at EOF?
      if (next_byte == ''):
      break
      out_file.write(str(ord(next_byte)))
      byte_count += 1
      if byte_count > items_per_line:
      out_file.write("\n")
      byte_count = 0
      #end of while loop

      out_file.write("};\n")
      out_file.write("#endif /* USER_WEBPAGE_H_ */")

      in_file.close()
      out_file.close()

      print "File System Conversion finished"
      exit(0)

      1. Any chance you upload it to bitbucket? Python cares about indentation which got lost here and there seems to be an issue around line 9 as well where the string constant is not closed.

        I'm using an OTA approach that lets you update code and espfs separately (using an adjusted version of rboot but not using the rboot OTA capabilities).
        Especially during debugging that appeared to be beneficial to update only code or only espfs but thinking about it now that was probably driven by the long download time through UART which is less of an issue with OTA 🙂

        Excellent point. I'm using an OTA approach that lets you update code and espfs separately (using an adjusted version of rboot but not using the rboot OTA capabilities - scroll down for details).
        Especially during debugging it appeared to be beneficial to update only code or only espfs but thinking about it now that was probably driven by the long download time through UART which is less of an issue with OTA 🙂
        I can't find the python script on bitbucket. Where did you put it?

        I'm using a similar set of components (rBoot, Tuan's MQTT stack, espfs, ...) all modified to my needs but I've chosen a setup with three ROM slots where one is reserved for kind of a "factory default firmware" that lets you configure a fresh device (ssid, pw, mqtt broker, ota server, ...) and provides OTA capabilities to flash into the other two slots. As long as the factory FW is coded and tested properly it's almost bullet proof even if you push a very bad ROM through OTA because you don't rely on the OTA functionality being part of the other ROMs. I've adjusted rboot so that it always boots into the factory ROM on a power cycle and boots into the "last known good" ROM on all other reset causes... The factory rom checks with the "update server" if there is a newer version so all you need to recycle from a bad ROM is put a new version on the update server and do a power cycle (worst case pulling a fuse for devices that are not easily accessible). If there is no new version the factory ROM soft-resets the esp and rboot happily boots the last known good rom.
        So far so good - problem is the reset cause detection seems not to be really reliable which kind of breaks the entire concept 🙁

  29. Hi. Pete is travelling back from Spain tonight so he probably won't be able to publish the python file. I would do it myself, but our source files are a bit out of sync at the moment as I'm working on incorporating DNS lookup for the servers.

    I'm happy to email you the source file (complete with indentation!)

    Drop me an email to aidan@ruffs.org and I'll send it

  30. OK, I've actually managed to sync the repos and have pushed web_page_convert.py to the root folder of the repo. Just copy it into your \espressif\utils directory.

  31. Hi

    Can somebody explain the detailed steps for getting Petes code into a working Eclipse setup for the Eclipse challenged!

    I have a working Eclipse following CHERTS instructions and video and have managed to alter, compile and flash the mqtt example but with only a very basic understanding of how Eclipse works.

    Regards

    Ian

  32. Hi Pete,

    first of all I'd like to thank you for your incredibly valuable work, time and energy spent on this project.

    I am still on my learning curve on different home automation and its different systems, observing several solutions like OpenHab, MySensors, Souliss and EspEasy, but none of the documentations read brought me closer than yours.

    I wonder what your suggestions would be regarding the issues below:
    -first, I do agree with you that a home automation system must run as a standalone with no cloud services and such involved. Looking deeper to details, thinking about a light in a room I faced the same problem.
    What I'd like to have is a regular button on the wall (latching replaced to a momentary of course) we all got used to which triggers one pin on the very local node turns on the light using an other pin (through a relay, transistor etc...). Optionally the node reports the state-change of the pin to the controller via MQTT and makes remote controlling possible.
    It means as long as power is present I may control the light manually even if the wifi (node's connection, controller or the router itself) is down.

    As I see people suggest to give contoller total control, like pressing the button sends a request to the controller, then the controller turns on the light through the very same node... I don't really like that idea to be honest.
    Besides in some forum topics people report strange behaviour of their ESPs like spontaneous resets, unpredictable state of pins during and after reboot even in systems claimed to be pretty stable (not prototypes on breadboards with loose wires and such). Now these people suggest to use arduinos with ESP hooked onto them for nodes with critical tasks; -well, who would want to see the garage door opening without a reason just because the ESP went crazy for a moment? Have you experienced such things?

    The other issue is the possibility of multiple instances of controllers (whether it's NodeRed or other).
    When I get to the stage to set up my system, I'd like to have two. One in my home and an other one in my workshop. They would be separated, actually a half town away from each other and I'd like to be sure to chose the right system capable of handling both, obviously one at a time locally and the other through the internet; -or both through the internet in case I'm at a different location.
    Do you think it can be done with NodeRed?

    Thank you for your time in advance and sorry for my bad grammar. I am not native English.

    And yes, a forum would be a brilliant idea.

    Best regards,
    G.

    1. Gerley

      Some comments for you: if indeed people in some forums are reporting strange behaviour like spontaneous resets, unpredictable statef of pins etc - they are doing it wrong - or using the wrong tools or rubbish power supplies or no decoupling or any combination of the above - I have several ESPs running in 2 installations one of which has atrocious power reliability. They are all operating perfectly and have been for months.

      Two installations: Have an agreement between the two MQTT servers to send data back and forth - but only data that is relevant i.e. only certain topics go back and forth.

      There is no reason why you could not have an ESP with a relay and an input which allows for local control override but still allowing external setting and firing off the button state to MQTT

        1. So on machine 1... node red publishes items to server 2.. prefixing them with "server2/" for example...

          On the second machine it sees incoming message, strips off "server2/" and resends them locally. Any responses known to be for server1 - have "server1/" attached to the topic. etc etc...

          There is another way which I've never tried.. http://stackoverflow
          .com/questions/24109306/bridge-between-two-mosquitto-brokers

  33. I tend to prefer using RabbitMq - mainly because of its' lovely web admin and monitoring interface. You can set up a federation between two servers fairly easily I gather, but I haven't actually tried it 🙂

    1. Thanks.

      What I actually wanted is not to bridge the two systems as they don't really need to "know" of each other, but to have access to them simultaneously. Locally and/or remotely, possibly using the same UI.

    1. There is no reason you could not have both on the same board. I've just not implemented it as I chose to reserve GPIO2 for use with temperature sensing. As the DHT22 (NOT the 11 which is rubbish) gives as good a show as the DS18B20 I didn't see any point.

      1. I have a few DHT11 and wanted to pair them up with DS18B20. Now I ordered a few DHT22.

        There is a typo in the temperature example on topic you have "999/fromext/temperature" but should be "999/fromesp/temperature". I kind of lost a few minutes because of this! 🙂

        Anyway... thanks for this firmware, it make my life easier.

  34. Peter this is amazing work that I have just been turned on to. Having a simple set of commands makes automation so much easier. I do have a question, is it possible to define a default state for outputs? So that on power restore the output is placed in the default state. (I am using the ESP-12 to drive an LED strip and would like it to be back "on" if I have a power outage.)

    1. Well certainly in my software, the state of simple outputs is preserved - i.e. if GPIO0 is on and you get a power cut, it will come back on as it was before the power cut. That is implemented using the system command to store a block of data into Flash. There is a failsafe mechanism whereby it uses 2 blocks - and if the save fails it simply uses the previous version. I've never lost any settings.

  35. Hi Pete,
    I can't find anyway how to set board so when the input 14 changes to send a mqqt message. If I send {in14?} I get a message, but I need the board to send me automatically the status when it's changed.

    Any idea how to do that? Thanks

  36. Pete - any chance of a link to the 3 bins needed for this? I'm struggling with the makefile on OSX and eclipse!

    1. I know - I set them that way 🙂

      I'm thinking of pulling out the existing stuff and using the easyGPIO. For our purposes we're sticking with GPIO4 and 5 for our boards - others can do as they wish of course... the source is there...

  37. hi
    iv'e connected a DHT22 to GPIO2, when i send {temperature?} i seem to get a random -number, do i need to send somthing to esp to tell it to use that port for a particular sensor ?
    thanks Chris.

  38. If you look in the manual under temp_type, you'll see that you need to tell the board which type of sensor you're using.

    So, for a DHT22 send:-

    TOPIC my_module/toesp
    PAYLOAD: {temp_type:1}

    So, in this way you can select any of a DS18B20, a DHT11 or a DHT22 or over-ride the pin to be an output
    When you want to read values back, send:-
    TOPIC mymodule/toesp
    PAYLOAD {temperature?;humidity?}

    This will send back to messages reading the temperature and the humidty.

  39. Thanks
    i had been looking for a list of all commands and couldn't find it. Now i realise its in a word doc, as part of what i originally downloaded. I need to start reading through all the doc's and blogs about this instead of racing ahead of myself in exitment and asking dumb questions on here.

    1. Hi - thanks for that - took a quick look - at a bit of a loss actually as how that varies from a normal router. I connect all my Pis and other stuff together - and access remotely.... just a normal Draytek router..

  40. Have been through similar quest as Peter, looking for reliable and functional wireless "Mesh" networking automation system.
    Probably the most successful "commercial" system that I have used has been from Synapse Wireless
    http://www.synapse-wireless.com/iot-products/core-iot/ ,based on their proprietary 2.4Ghz RF modules (similar to Zigbee) using full Mesh protocol and minimum Python based operating system. My main issues with Synapse are generally expensive modules by 2016 standards about Us$30, locked to commercial proprietary product, limited signed 16bit integers and other functionality of limited Python OS system. Fully automated Mesh and self healing network generally works OK but for static network there are limited options to manually define routing. Lack of manual routing setup, Mesh will very frequently go through routing requests causing unnecessary latency.

    Anyway, I have been watching ESP8266 for a while now but have been concerned about using WIFI network for automation due to complexity and perceived possible reliability. I am now considering getting my feet wet by trying MQtt option using RPi as a local broker. In fact I am still investigating the setup of 2 brokers as a contingency for possible critical single point failure.

    I have red through Peters Blog and the comments which have provided a lot of valuable information.
    Since I have never really got deeply involved in detailed computer networking wired or wireless, I still have a fair bit to research and learn.

    Anyway, would appreciate if someone can answer couple of questions that have probably been covered to some degree but did not sink in yet.

    1. I am initially only looking at setting up "basic" Local only, wireless Mqtt based network using 1 and expanding to at least 2 (to eliminate single point network failure) Mqtt RPi (or compatible brokers) and multiple ESP8266 client nodes based on Arduino code.

    2. Have any of you set up your network with RPi set up as WiFi access point (AP) as well as Mqtt broker, without other external WiFi Router or AP? This would be my preference and would appreciate pointing in the right direction with RPi setup as WiFi access point plus Mqtt broker.

    3. As mentioned previously, have any of you set up 2 or more RPis as Access points and Mqtt brokers?
    I would like my network to be extra reliable by having more than one Mqtt broker, to eliminating single point of failure. At this stage I don't want to connect to the Internet and/or on line based Mqtt brokers.

    Regards
    John

    1. My quick comments as I am on mobile. Recommend WIRED Pi using best SD you can get.. Samsung EVO good. With new Debian you can now easily make identical backup. Just change hostname.. I have 2 setups like this, 100% reliability over months. Indeed I'd be more worried about wifi connections to my esps but now I am also getting 100% from them. Ensure Pi has battery backup as per my usb power article or similar.

      As for esp and mqtt and arduino IDE I cannot vouch for reliability long term you will have to suck it and see.

      Pete

  41. Peter,
    I have succesfully been able to control my WS8212 Led's using the rgb command, but having problems in getting the rgbset & rgbgo to work. Can you please confirm the parameters, as it appear to turn LED's off, but not to the colour selected.
    Should the command {rgbset: start_led, number, rgb} be {rgbset: start_led, number, r,g,b} or is that expecting a hex value.

    Thanks

  42. Im still having a problem understanding the {rgbset: start_led, number, r, g, b} and {rgbgo: port,number_of_leds} commands.
    My setup is:
    15 LED's working fine with {rgb:port,red,green,blue,number,duration}
    However when I try to use the rgbset / rgbgo commands the results are not as expected.
    I am assuming that {rgbset:5,5,255,0,0} means set LED5 to LED9 to RED but Im not sure what 'number_of_leds' means in the rgbgo command, as I assumed that is what 'number' meant in the previous command.
    I initially read rgbset as being able to preset different LED's to different colours, with multiple rgbset commands, then using the rgbgo to apply.
    I hope it's just me having a bad day.

    Thanks

  43. Hi
    i am trying to get my head round how you are controlling your heating. i ordered a Nextion display in April,
    that took over a month to come, but when it arrived i was so impressed i ordered 2 more. Just got back from a week in Spain, and they not only arrived, they sent 4! result. so back to the heating. i have a Nextion set up with your UI, and am slowly fumbleing my way along. i have the temperature/humidity updating every 5 mins from a dht, the time displaying (hh:mm)and updating every miniute. all my updating is done with inject nodes...(interval), but i'm sure there is a better way, but it will do for now.
    i also have now got the set temperature displaying and updating (changing) with a node red UI slider.
    when i press the up and down buttons on the Nextion it sends the respective up/down payload to topic "nextion" which i can see comming in in the debug panel.
    The next thing i am trying to do is increment / decriment a number (set temp) using these buttons that i can later compare to the actual room temp from the dht turning the heating on and off accordingly.
    But once again my very limited Java script is in the way.

    var j = 10;
    if (msg.payload === "up") {
    var j = ++j;
    msg.payload = j;
    return [msg];
    } else {
    if (msg.payload === "down") {
    var j = --j;
    msg.payload = j;
    return [msg];}

    return [ msg, null ];
    }
    this obviously does not work as it resets j to 10 every time it runs, so i get an 11 or 9. and if i remove the var j = 10 i get an NaN error. but looking at it, can you sort of see what i am trying to do ?.
    is there any more infomation on your blog how you have implemented your thermostat/heating?
    i am currently using http://harizanov.com/2015/02/wifi-thermostat-with-weekly-scheduler/ which is very good, except it looses connection now and again. it would be superb if it had the rock solid connection of yours. I think the scheduler part is open source maybe worth a look.
    I eventurly want to put a thermostat in every room, but just one going would be a start.
    thanks again for a great project. i have just ordered 20 of your new boards so goodbye vero board.
    Chris

  44. Hi
    My heating system is in the UK and I'm in Spain right now (no need for heating here). Its a while since I did the coding but why are you using three === ??

    my heating is implemented in node-red - with the Nextion merely being used as controls and visual feedback. I looked at Martin's wifi-thermostat - looks good but I'm quiet happy with the reliability I get out of Raspberry Pi + Nextion + my own code on the ESP8266s - which is rock solid (the PI is running hardwired as I was not happy with the reliability of early WIFI on the Pi - probably fine by now).

    I simply have a load of global variables - settable by buttons - for times and temperatures. I look up the current time - look to see what the current temperature should be, ensure I only turn the heat on or off no less than once per minute, add in any offset variable (manual override), flatten that variable every change of temperature time zone... that's about it.

  45. hi
    i was using three ===, because i didn't know better, copied this off node red help:
    if (msg.topic === "banana") {
    return [ null, msg ];..........
    trying to learn if,then,else in java.
    now got this far and all devices/UI's seem to increment/decrement in Sync, i have nextion, node red UI slider & gauge, plus a up and down inject in Node red itself. all synced. is there an easier way than lots of if's and then's to add upper and lower limits to the set temp?
    i will move on tomorrow to try and do the compare and switching.. then its on to incorperate your big timer!
    Don't know if you watched the election thing the other night, but the BBC were using what looked like a Node Red gauge and slider, to show how the voting was going !
    many thanks for all your work and help.
    Chris

  46. Forgot to put this in:
    var bed_temp = context.get('bed_temp')||16;
    if (msg.payload == "up") {
    bed_temp += 1;
    // store the value back
    context.set('bed_temp',bed_temp);
    msg.payload = bed_temp;
    return [msg];
    } else {
    if (msg.payload == "down") {
    bed_temp -= 1;
    // store the value back
    context.set('bed_temp',bed_temp);
    msg.payload = bed_temp;
    return [msg];
    }
    return [ msg, null ];
    }

  47. I am still looking at building a wireless control network, it has to be wireless and preferably WIFI because of the location/setup of various controlling devices.

    From what I have read so far, MQTT ticks most of the boxes in terms of integration and ease of operation, provided that it works reliably and there are no critical single point failures.

    With most typical WIFI star networks, Single AP or router is the critical single point. Add to this a single MQTT broker and you have another critical single point that can bring down the whole network if they fail. Clients should not be a major problem as multiple clients can exist on same MQTT network.

    How to deal with these possible single point failures when you want to implement an automatic fail-safe network?

    Multiple WIFI AP's can operate in sort of parallel with same SSID name, but clients still need capability to roam or switch from one failed AP IP to another.

    It is also possible to bridge MQTT brokers, but information for lower end setups becomes murky and very scarce.

    So far I can't find any meaningful information on how or if anyone has dealt with same issues, as far as building an automatic redundant MQTT WIFI network on a lower level like sort of home automation. I'm sure there will be commercial high end setups.

    Basically, would need a WIFI network with at least 2 AP's (Access points) and 2 MQTT brokers. If brokers are bridged, must exchange data or have same data. Clients to automatically connect/switch to active broker.

    Would appreciate if anyone has implemented something similar or has additional information.

    Regards
    John

    1. Well, my software uses 2 access points, if the board fails to get to one it will go to the other. It would be quite simple to add an optional second MQTT broker.

      With Raspberry Pi (and pretty much ONLY the raspberry Pi when it comes to these little Linux controllers) there is a DEAD-easy backup system as of just a few weeks ago so making a duplicate system is a snap. So here in the cave I run 2 Raspberryt Pi 2 machines - identical other than the fact that I keep experimenting on one of them. Both have my Node-Red setup, both have MQTT brokers - both are wired into the network so are immune to WIFI access point issues. Couple that with the stunning reliability I've been getting, might be something to add in at a future date - MQTT redundancy as well as access point redundancy. This of course would also mean that if the main PI fell over completely, the other one could take over. I'm not too concerned about that as I've never had one fall over (I use only the best SDs).

      But then if the main router fell over.... or the power went dead for any length of time...

      But as the main

  48. @John, Thanks for raising the practical concerns for a real life system. @Pete thanks for your replies and sharing your experience (in fact, all through this blog)

    I was also concerned about this and as of now do not have a clue for failsafe MQTT. Though redundant AP makes wifi more reliable. I was thinking on the lines of nodes publishing and subscribing to two brokers and modifying the codes to test the primary and making decisions accordingly. Still, this is just a primitive idea. Any better suggestion is welcome.

    And yes, Peter I am yet to check your contributions of node flows. I did refer to your page related to Orange PI. Now coming to your recent comment on the reliability, do you mean the reliability only in case of RasPi or either? After having overcome the installation and software / driver issues, do you consider Orange Pi PC as a viable alternative or only vouch for RasPi

    1. Hi - well as you know from the blog I have reviewed MANY boards and there are more coming - I just received the FriendlyArm M2 and a friend dropped off a CHIP and I have 2 more different boards on the way. My experience so far can be summarized as this.

      The Pi is not the fastest hardware - for example the FriendyArm T3 can run Android video FLAT OUT without thinking about it and for general use their M1 board - I have 2 of them running Node-Red 24 hours a day rock solid. But - facts are facts - there is more available community support for the Pi than just about any other board out there. The Orange Pi, now that recent changes have reduced the temperature a little - is no doubt excellent for the job - but I will not buy from them because their customer interaction is precisely ZERO - they have never answered any of the miriad of questions I've left - I suspect there is one hired in techie who can't be bothered but that's just a guess. Their operating system images are an unfinished MESS - but third parties have stepped in and I believe ARMBIAN works... so that's great (bear in mind the FriendlyArm stuff is just about as cheap). Right now I'm getting a little help from the Node-Red community in getting Firmata talking to the Pi - I doubt very much if I went to them with any of these other boards whether they'd be able to help.

      In addition to that, I have 1 PI in Britain that has ran night and day for a year now and 2 here in Spain that have been running since April - of course I sometimes reboot one of the two as I experiment on it but it has never failed of it's own accord. It may be that we can achieve similar reliability with other boards but I don't have that experience to vouch for them - I suspect the NanoPi M1s (which in addition are running on WIFI, not wired) will cut the mustard... looking forward to writing up the M2s I have in front of me.

  49. Pete and I were doing some software updates last week and we discussed the possibility of adding a fallback MQTT server as well as a fallback wifi access point.

    So, currently the software attempts to login every minute until it gets through and then logs in once per day to synchronise the time (Pete, can you confirm this, I'm not sure about the login interval).

    However, there's no reason that we couldn't add in a second MQTT server address to each of the units.

    Ideally, the servers would handle the switchover, but currently we can only connect to one MQTT server at a time. However, if we dropped the login time to say a couple of minutes, then perhaps after 3 unsuccessful attempts to re-login, the remote units would swap to the alternate server.

    So, after 5 minutes the system would recover as each individual unit swapped over to the backup server.

    If the 2 servers were subscribed to each other, then they could also have a timeout and could then send an email to inform that one of the servers had gone down if it stopped replying.

    We have already implemented a system whereby a mains unit is pinged to keep a mains unit active so long as Node Red can ping an external address and then cycles the power of the Raspberry Pi in an attempt at reseting it - mainly because Petes house in the UK has unreliable broadband, but this has been working for months now.

    If the primary server then came back up again, once it established comms with the backup server, the backup could issue a command via MQTT to tell all of the units to swap back again. This would be useful if you're doing any data logging to the primary unit.

    Does that all sound logical?

    1. Yes, attempts to log in every minute until it gets through -from there on in - it is sent the time every day by the node and of course when it logs in. There IS no reason why I can't add in a second MQTT unit - BUT.... let's say ONE of the units has an issue - whatever it is - and cannot get through - it might then try the second unit - bear in mind that the OTHER units will be talking to the original MQTT unit - that might pose a problem... it would take some thought as to under what circumstances the units would swap over.

  50. OK, let's imagine that we start with 2 working Pis running mosquitto. The main one is unit 1 and the backup is unit 2.

    All of the remote devices have unit 1 as the primary mqtt server and unit 2 as the backup.

    Initially they log on to unit 1, but fallback to unit 2 after a few failures to logon. They carry on using unit 2 until told otherwise or until unit 2 itself fails, at which point they have another go at unit 1.

    Unit 1 could subscribe to, say, 'reset_watchdog' topic on unit 2, and unit 2 could subscribe to 'reset_watchdog' on unit 1. They could send each other regular message to clear a watchdog timer. If this zeroed out, then the surviving server could send a failure email or pushbullet to the administrator.

    If Unit 1 failed, then within say 5 minutes all remote devices would be logged on to unit 2. If a mains watchdog managed to reset unit 1, then it would re-contact 'reset_watchdog' on unit 2 and then unit 2 would send a message to all of the units that were then logged on to it and tell them to go back to unit 1 - or we could add in a 'broadcast' subscription that all units would subscribe to when they log on, just like '/toesp'...call it'broadcast_command' for example.

    So,
    topic:broadcast_command
    payload:{revert_mqtt}

    or to avoid the extra subscription

    topic:/toesp
    payload:{revert_mqtt}

    In fact, both servers could have exactly the same flows loaded into Node Red, the determination of which server is which would be defined when you configure each remote device.

    Does any of that make sense to anyone else?

    1. It is VERY early in the morning as I read this - but looking near the start - the reset watchdog and messages... is that not the purpose of the last will and testament?

  51. Thanks Guys.

    Aidan your proposal looks plausible in principle. Although, I don't have practical experience with MQTT to evaluate the mechanics of the workable implementation.

    Mechanism of integrating 2 brokers and switching/selection between brokers and connection from clients would have to be automatic and reliable.

    As Aiden has pointed, would be important to generate alerts to the Administrator on different levels of abnormal operation.

    Regards
    John

  52. Thanks Pete
    But that code is for the full blown "queueing"
    I simply wanted to know what you did to parse the incoming login which is depicted above.

  53. My version is pretty simple:-

    I can't put up a graphic of the nodes, but here's a text version.

    [MQTT Node, with topic 'esplogon'] --->[Function to speak login] ---> [Ivona Speech Node]

    The function node to speak the login has the following code:-
    -----------------------------------------------------------------------------------------

    var load = JSON.parse(msg.payload);

    // Remove any special characters from the device ID
    load.id = load.id.replace("_", " "); // remove underscore
    load.id = load.id.replace("-", " "); // remove dashes

    if (load.attribute !== "")
    {
    load.attribute = load.attribute.replace(" ", ""); // remove any whitespace
    var attribList = load.attribute.split(','); // Split Separate out the various attributes

    for (i = 0; i < attribList.length; i++)
    {
    var attr = attribList[i].split('='); // Now extract the various values
    if (!attr[0].localeCompare("voice")) // Got a Voice directive
    msg.topic = "ivona/" + attr[1];
    }

    }

    msg.payload = load.id + " logged on";
    return msg;

    -------------------------------------------------------------------------------------------

    The above will generate the code to say whichever device has logged in. As a little extra, if you set one of the device attributes in your ESP device to 'voice=Emma' or whatever voice you want, then each of your nodes can different voices! Make sure that the voice name matches up with the Ivona voice types or it'll just use the default

    If you also want to save the the login to the database, then also feed the MQTT esplogon node output to an 'esplogin' node and take the bottom output to a MYSQL node. I think that Pete has detailed the standard form of the database elsewhere on the blog.

    If you want me to email you a picture of the nodes from Node Red, just send me your email address to aidan@ruffs.org

  54. Hi Pete. I've built up one of the boards with the Nextion attached and I can control it through serial and Nextion however I am struggling with the syntax in OpenHAB. Do you have any pointers? I have a relay attached to GPIO15 and want to setup a switch in OpenHAB to control it (board id MastBed) normally I would configure OpenHAB with a Switch Item and the MQTT instruction could be
    {mqtt=">[mymosquitto:MastBed/toesp/{out15:1}:command:ON], >[mymosquitto:MastBed/toesp/{out15:0}:command:OFF]"}... Is this correct? Normally OpenHAB knows how to control a switch and sends ON / OFF commands or 1 / 0 to control it, however because of the bracketed "{out15:1}" instruction it can't do that. Am I making sense? Anyone else out there with Openhab that can help me? Many thanks! Regards, Andrew

  55. i really love what you have done here. the Software works like an OS for the esp platform, and it has made my transition over from arduino soo much easier.
    I have written a little program that you may benefit from, see my home runs on solar (with a Diesel back up Generator) and i built a startup controller for it using a UNO and a Node MCU, it controls the operating functions so my inverter can start it when its req'd via mqtt.
    its very basic but i reckon it could well operate without the UNO, performing all functions on the NodeMCU.
    happy to share if it will be of use to anyone, might even fit in your ESP OS. id add it myself if i knew how .. lol. WAAAY to many if functions in that one for me to understand Peter!
    any how, one more idea i had was an esp8266 running an Mqtt broker.. is that even possible? dont reckon thered be much room for anything else but Like you Peter, i'm always interested in saving money!
    Cheers From Down Under!, Levi

    1. In reverse order - nothing is impossible but I would suggest that it is highly unlikely that an ESP8266 could run as an efficient MQTT host - but then you can get a FriendlyArm unit for a tenner that will do that - if a Raspberry Pi is considered too expensive.

      If you want to give us more details on what you've done in here - fire away.

      Pete.

  56. Hi Pete, here is my code, you may see any number of different ways to accomplish this, im not an experienced programmer but it gets done what i want of it.. heres the code..
    /* Generator Start Controller - BY LEVI MADELEY
    * Single pin input for ease of contol
    inputPin LOW/ HIGH for startup sequence and shutdown respectively
    * serial control for startup and shutdown based on single letter commands
    "S" for start, "s" for stop and "R" for reset arduino module

    UNO - ESP8266

    *
    --------------------------------------------------------------------------------------
    GLOW = glow timing

    using millis time the glow plugs for cold
    start sequence
    -----------------------------------------------------------------------------------------

    START = start timing

    * using a for loop to run through the start sequence until the alternatorPin reads voltage then go to Running state

    ----------------------------------------------------------------------------------------

    RUN = run state

    * running of engine
    * 8r timeout for fuel purposes

    --------------------------------------------------------------------------------------------
    SHUTDOWN - sequence for shutting down normally 15min minimum total run timer
    prevents shutdown straight after unit has started.
    ...FUTURE DEV.. 60second no load timed shutoff

    -------------------------------------------------------------------------------------------
    FAIL - shutdown and lockout sequence for when things go wrong
    or for when emergency stop button is pressed
    immediate shutdown

    ---------------------------------------------------------------------------------------------
    OFF
    sequence for any maintanance activity to be performed by controller whilst machine is off.
    ----------------------------------------------------------------------------------------
    */
    // system states
    #define OFF 1 // machine is off
    #define GLOW 2 // glow plug timing for cold start (comment out for petrol engine)
    #define START 3 // starter crank run
    #define RUN 4 // engine running, timer for fuel
    #define SHUTDOWN 5 // engine shutdown timers (15 minute minimum run time and 60sec no load
    #define FAIL 6 // emergency stop lockout mode

    #define GLOW_PLUG_HEAT_TIME 3000
    #define MIN_RUN_TIME 900000 // MINIMUM genset run time before shutdown
    #define RUNNING_TIMEOUT 28800000 //000 // changed from 10 min to 8 hrs.lm 28800000UL = 8hrs
    #define CRANKING_TIMEOUT 2500 //STARTER CRANKING TIMEOUT 2.5 SECONDS(2500).lm
    #define TOTCRANK_TIMEOUT 17000 //TOTAL STARTER CRANKING TIMEOUT 18 SECONDS.lm

    const int ledPin = 13; // to led display
    const int resetPin = 12; // to reset on board MUST BE SETUP AS output HIGH /pullup/
    const int starterPin = 11; // to Startermotor via Relay
    const int ignitionPin = 10; // to ignition via Relay
    const int inputPin = 9; // to initiate start/ stop sequences via NodeMCU
    const int emergencyPin = 8; //to Emergency stop button
    const int GlowPlugPin = 7; // to glow plug via Relay
    const int alternatorPin = 4;// yellow

    //Flags
    byte byteRead;
    byte last_state1 = 0;//flag for VOID LOOP
    byte last_state2 = 0;
    byte last_state3 = 0;
    byte last_state4 = 0;
    byte last_state5 = 0;
    byte last_state6 = 0;
    byte last_state7 = 0;
    byte last_state8 = 0;
    byte last_state9 = 0;
    byte last_state10 = 0; //flag for Serial.print
    byte last_state11 = 0; //flag for Serial.print
    byte last_state12 = 0; //flag for Serial.print
    byte last_state13 = 0; //flag for Serial.print
    byte last_state14 = 0; //flag for Serial.print
    byte last_state15 = 0; //flag for Serial.print
    byte last_state16 = 0; //flag for Serial.print

    int state = OFF; // master variable for the state machine
    unsigned long StartingTime; // When did we power up the engine? Need this to time the starter timing.lm
    unsigned long RunningTime = 0; // When did the engine start? Need this for the 8hr timeout

    boolean haveFailed = false; //flagged true if handleFAILstate is run
    boolean failPrompt = false; //serial print for reset module

    void setup()
    {
    digitalWrite(resetPin,HIGH);//pullup
    pinMode(ignitionPin,OUTPUT);
    pinMode(starterPin,OUTPUT);
    pinMode(ledPin,OUTPUT);
    pinMode(alternatorPin,INPUT);//pulldown
    pinMode(GlowPlugPin,OUTPUT);
    pinMode(inputPin,INPUT);
    pinMode(resetPin,OUTPUT);
    pinMode(emergencyPin,INPUT);
    // Make sure everything is set correctly
    Serial.begin(9600);

    }

    void loop()
    {

    if (last_state1 == 0)
    {
    Serial.println("Welcome to Generator Manager.... By Levi Madeley and James Smith");
    Serial.println(" ");
    Serial.println(" Serial commands list.. ");
    Serial.println(" 'S' = Start Genset");
    Serial.println(" 's' = Shutdown Genset");
    Serial.println(" 'R' = Reset Control Module");
    Serial.println(" 'e' = Emergency Shutdown");
    Serial.println(" Waiting 5 sec for wifi to boot and connect");
    delay(5000);
    // command();
    (last_state1 = 1); }

    command();
    switch(state)
    {

    case OFF:
    handleOFFstate();
    break;

    case GLOW:
    handleGLOWstate();
    break;

    case START:
    handleSTARTstate();
    break;

    case RUN:
    handleRUNstate();
    break;

    case SHUTDOWN:
    handleSHUTDOWNstate();
    break;

    case FAIL:
    handleFAILstate();
    break;
    }

    }

    void handleOFFstate()
    {
    if (digitalRead(alternatorPin)== HIGH && digitalRead(ignitionPin)== HIGH)
    {
    Serial.println("handleOFFstate state=SHUTDOWN");
    state=SHUTDOWN;
    }

    if (digitalRead(inputPin)== HIGH && digitalRead(ignitionPin)== LOW) // future -temp sensor code here
    {
    Serial.println("Wifi Start Sequence Initiated... .. .");
    delay(200);
    state=GLOW; }
    if (digitalRead(inputPin)==LOW && digitalRead(ignitionPin)== LOW) state=OFF;

    //if (digitalRead(inputPin)== HIGH) Serial.println("inputPin=HIGH"); //debugging
    if (digitalRead(inputPin)== HIGH && last_state16 == 0)
    {
    Serial.println("inputPin=HIGH"); //debugging
    last_state16 = 1;

    }

    if (last_state2 == 0)
    {
    Serial.println("Command to off state"); //DEBUGGING
    last_state2 = 1;
    Serial.flush();
    }

    }
    void handleGLOWstate(){

    if(haveFailed){
    if(failPrompt == 0 ){
    Serial.println("FAILED: Please Reset Controller");
    failPrompt = 1;
    }
    return;
    }
    Serial.println("Power up");
    StartingTime=millis();

    digitalWrite(ignitionPin,HIGH);
    Serial.println("Heating Glow Plugs");
    digitalWrite(GlowPlugPin,HIGH);
    delay(GLOW_PLUG_HEAT_TIME);
    digitalWrite(GlowPlugPin,LOW);
    state=START;

    if (last_state3 == 0)
    {
    Serial.println("Command to Glow State"); //DEBUGGING
    last_state3 = 1;
    Serial.flush();
    }
    }
    void handleSTARTstate()
    {
    if(haveFailed){
    if(failPrompt == 0 ){
    Serial.println("FAILED: Please Reset Controller");
    failPrompt = 1;
    }
    return;
    }
    Serial.println("Starter cranking");
    digitalWrite(ignitionPin,HIGH);
    int x;
    for( x = 1; x RUNNING_TIMEOUT)
    {
    Serial.println("handleRUNstate Running Timeout");
    state=SHUTDOWN;
    }
    }
    if (digitalRead(alternatorPin) == LOW && digitalRead(ignitionPin) == HIGH) //it has stopped by itself for one reason or another and needs to be physically attended to
    {
    state=FAIL;

    }
    //command();
    if (last_state6 == 0)
    {
    Serial.println("Command to run state");

    last_state6 = 1;
    Serial.flush();}

    }
    void handleSHUTDOWNstate()
    {
    if(millis()-RunningTime > RUNNING_TIMEOUT)
    {
    if (last_state4 == 0)
    {
    Serial.println("Running Timeout");

    last_state4 = 1;
    Serial.flush();}

    state=FAIL;
    }
    if (digitalRead(alternatorPin)==HIGH && digitalRead(ignitionPin)== HIGH && digitalRead(inputPin)== LOW)
    Serial.println("will shutdown but now in cooldown mode ");
    Serial.flush();
    {
    //WARM/COOLDOWN TIME --- LOAD DISCONNECT RELAYPIN GOES HERE(future development)
    if (RunningTime=millis() >= (MIN_RUN_TIME))
    {
    Serial.println("Shutting Down, after min runtime");
    digitalWrite(starterPin,LOW);
    digitalWrite(ignitionPin,LOW);
    delay(5000);
    state=OFF; }
    }

    if (last_state7 == 0)
    {
    Serial.println("Command to shutdown state");

    last_state7 = 1;
    Serial.flush();}
    }

    void handleFAILstate()
    {
    if (last_state8 == 0)
    {
    Serial.println("handlefailstate"); //DEBUGGING
    last_state8 = 1;
    Serial.flush();
    }

    if (last_state9 == 0)
    {
    Serial.println(" GENSET LOCKOUT MODE - CHECK FUEL AND/OR ENGINE!!");

    last_state9 = 1;
    Serial.flush();
    }
    // command();
    if (last_state10 == 0)
    {
    Serial.println("Command to fail state");

    last_state10 = 1;
    Serial.flush();}
    if(digitalRead(alternatorPin)==LOW)
    {
    digitalWrite(starterPin,LOW);
    digitalWrite(ignitionPin,LOW);

    digitalWrite(13, HIGH); // turn the LED on
    delay(2500);
    digitalWrite(13, LOW);
    delay(250);
    }

    state=FAIL;
    haveFailed = true;

    }
    void command() {

    if (last_state11 == 0)
    {
    Serial.println("Command interface"); //DEBUGGING
    last_state11 = 1;
    Serial.flush();
    }
    if (digitalRead(inputPin)==LOW && digitalRead(alternatorPin)== HIGH)
    {
    Serial.println("wifi initiated shutdown sequence");
    state=SHUTDOWN;
    }
    ;
    if (Serial.available())
    {
    /* read the most recent byte */
    byteRead = Serial.read();
    }
    if (byteRead==82)
    { /*Listen for R which equals byte code # 82 */
    Serial.println("Resetting Genset Control Module... .. .");
    digitalWrite(resetPin,LOW);
    delay(500);
    digitalWrite(resetPin,HIGH);
    }

    if (byteRead==115) { /*Listen for s which equals byte code # 115 */
    Serial.println("Shutdown Sequence Initiated... .. .");
    // delay(200);
    state=SHUTDOWN;
    Serial.println("Going to shutdown state");
    }
    if (byteRead==101) { /*Listen for e which equals byte code # 101 */
    Serial.println("Emergency Shutdown Triggered.. .. .");
    //digitalWrite(emergencyPin,HIGH);
    //delay(200);
    state=FAIL;
    Serial.println("Going to fail state");
    }
    if (byteRead == 83)
    {
    (digitalRead(alternatorPin)== LOW && digitalRead(ignitionPin)==LOW);
    Serial.println("Start Sequence Initiated... .. .");
    // delay(200);
    state=GLOW;
    failPrompt = 0;
    Serial.println("Going to glow state");
    }

    // next few lines are here incase of module RESET while genset running ..system STATE check.. and emergency shutdownPin..
    if (digitalRead(alternatorPin)==HIGH && digitalRead(ignitionPin)== HIGH) {
    state=RUN;
    if (last_state12 == 0)
    {
    Serial.println("going to run state");

    last_state12 = 1;
    Serial.flush();}

    if (digitalRead(alternatorPin)==LOW && digitalRead(ignitionPin)== HIGH) {
    state=FAIL;
    if (last_state13 == 0)
    {
    Serial.println("going to fail state...");

    last_state13 = 1;
    Serial.flush();}

    }
    if (digitalRead(alternatorPin)==LOW && digitalRead(ignitionPin)== LOW) {
    state=OFF;
    if (last_state14 == 0)
    {
    Serial.println("going to off state...");

    last_state14 = 1;
    Serial.flush();}
    }
    if (digitalRead(emergencyPin)==HIGH)
    {
    state=FAIL;
    if (last_state15 == 0)
    {
    Serial.println("going to fail state...");

    last_state15 = 1;
    Serial.flush();}
    }

    }
    }

  57. Hi Pete,

    I have just setup the development environment from scratch on a different PC and downloaded your repo and I am getting a build error:

    Makefile:113: recipe for target 'D:/scargill-esp-mqtt-dev/build/rboot-hex2a.h' failed
    mingw32-make.exe[1]: *** [D:/scargill-esp-mqtt-dev/build/rboot-hex2a.h] Error -1073741701
    mingw32-make.exe[1]: Leaving directory 'D:/scargill-esp-mqtt-dev/rboot'
    D:/scargill-esp-mqtt-dev/Makefile:204: recipe for target 'firmware/rboot.bin' failed
    mingw32-make.exe: *** [firmware/rboot.bin] Error 2

    I know this has come up in the past and I see some comments elsewhere online about it, but I can's see a specific fix so any help appreciated.

    Strangely enough compiling works on the old machine which was setup in the same way a few days back and also runs Win10.

    (Be gentle with me - I am new to the Eclipse environment!)

    1. I never set anything up in Eclipse - it always just ran - as the work is in the Makefile...

      I'm at a loss as to why RBOOT would be giving you any trouble - it's all there in the repo.

      Just for the sake of it -I doubt this is it - but my repo is in d:\git\esp-mqtt-dev

      Might want to stick it in there, import and compile?

      1. Hmm. I have redownloaded the repo....

        Opening the folder as project leads to the aforementioned error. If I import the project, compilation starts but I get a segfault!

        14:38:46 **** Build of configuration Default for project hackitt_mqtt_dev ****
        mingw32-make.exe -f D:/git/scargill-esp-mqtt-dev/Makefile all
        OC build/libmain2.a
        CC driver/i2c.c
        CC driver/ssd1306.c
        CC driver/i2c_master.c
        CC driver/BME280.c
        CC driver/spi.c
        CC driver/gpio16.c
        CC driver/uart.c
        CC driver/user_display.c
        CC driver/ds18b20.c
        CC mqtt/proto.c
        CC mqtt/utils.c
        CC mqtt/config.c
        CC mqtt/mqtt_msg.c
        CC mqtt/queue.c
        CC mqtt/ringbuf.c
        CC mqtt/mqtt.c
        CC user/aidans_code.c
        CC user/httpd.c
        CC user/heatshrink_decoder.c
        CC user/cgiwifi.c
        CC user/petes_code.c
        user/petes_code.c: In function 'readDHT':
        user/petes_code.c:723:5: internal compiler error: Segmentation fault
        temp_p /= 10.0;
        ^
        libbacktrace could not find executable to open
        Please submit a full bug report,
        with preprocessed source if appropriate.
        See for instructions.
        D:/git/scargill-esp-mqtt-dev/Makefile:296: recipe for target 'build/user/petes_code.o' failed
        mingw32-make.exe: *** [build/user/petes_code.o] Error 1

        14:38:52 Build Finished (took 5s.751ms)

        I might have to start from scratch - I wonder if something did not install properly?

  58. Some progress:

    If you don't have the MS Visual C++ redistributable bundle installed on your system (ie: on a fresh Win 10 box), you at least need the **32-bit** version of msvcr100.dll to accompany esptool2.exe in c:\esptools, otherwise the utility won't run and Eclipse just errors out without a helpful message.

    You can pick up the file from here (scroll down past the paying bit) https://www.dll-files.com/msvcr100.dll.html

    That fixes the 'make' issues with rboot

    I'm still getting the segfault in petes_code.c though 🙁

  59. Peter,

    Is there somewhere that talks about the actual setup of the environment - in particular i am looking at the ESPLOGIN node and what it is expecting in and what it is sending out (topic wise etc) - but i am sure there are many more of these interaction. Obviously the ESPLOGIN module is the start of the chain and then i am sure many more would come up after that ?

    Craig

  60. FYI Peter - the tab for this page shows the incorrect name ERSP8266 in Google Chrome - looks like the Title Element is incorrect

    Craig

  61. Hi Pete,
    Just stumbled on a small bug... The ota_port can not be changed via serial (or mqtt). Looking at the code, the port number is an integer, but the program is working hard writing a string to the memory, crashing the ESP without fail...

    Cheers

  62. Hi Peter,

    Long way since those old PIC boards of the APPCON but I am mightily impressed with Node-red and your work on the ESP12 code. At least I don't have to run miles of 4 core alarm cable anymore 🙂

    Anyway, what is needed to run this on an ESP8266 board (Sparkfun ESP8266 Thing)?

    I have ordered a couple of ESP12 based boards until my custom boards are ready and in the mean time I wanted to try things out with the ESP8266 I have lying around.

    PS. When I make changes to the user_config.h file and then use this to load to the board, the settings seem to still be from you original code. This could be an issue with the ESP8266 I am trying to run this on though.

    1. Yup, we've come a long way. So in total you need a Pi with Node-red and MQTT and my esplogin node.... and you need an ESP12 or similar... You would typically not make changes to the config.h file but through serial or the web interface (serial is easy - 115k with your FTDI or whatever you are using) just enter the commands (no topics needed as you're talking directly to the device) to set up ID, your SSID, pass, mqtt server address and pass.... erm, that's about it.

      1. I'll wait for the ESP12 modules to arrive and send off my custom boards soon.
        Node-Red is already up and running with your scripts etc. Using the Enocean switches I can switch the devices on and off. Totally with Node-red now as my choice for HA and the PC running Homeseer will be shutdown once I have migrated everything over to Node-red. Cheers for all the hardwork and taking the time to document and share it. I will owe you a few beers if we meet again.

  63. Hi Pete,
    are there any updates on a mains powered board since 2015, or you completely switched to the nextion one?
    And one more question: do you have a bill of materials for the mains powered board?

    Thank you.

    1. No updates - the boards work fine and we've had no reason to change it - talk to Aidan Ruff about boards - I'm guessing he'll say the part values are in the schematic. Funny I've just been updating the software on the mains ones here in Spain - I used these 24-7 without a hitch and have done since we made the first ones (well, not the VERY first one which shorted GPIO16 to +V).

      1. I also use the mains board with the 12v-5v DC convertor to run my external lighting from a 12v camping battery - every day winter and summer without issue. Would have been nice if we'd put just a couple more ground, 5v and 3v3 pins on them... and I'm not using GPIO2 as web programming button any more - so at some point we may revise the board - better to leave GPIO as an input for web programming and output toggling - like Sonoff do... and use say GPIO16 as relay output - because that's all it can be used for - can't be an input.

      2. Thanks, I'm going to order pack of them now, hope I'll be able to assemble them and they will work 24x7 for me too.

        BTW: In your dropbox there are two brd files. I opened them both with EAGLE and it seems that "ESP-01-and-12-Development.brd" is DEV6 board, while "ESP-01 and 12 Development.brd" is DEV7. Maybe you could rename them, so their names will be more distinct?
        And here is exported schematic for this board https://i.imgur.com/HXMGZZP.png
        (In your dropbox are two bottom images of the board and no schematics).

  64. Hi Peter, I cloned the latest code and then rebuilt it. When I flash this to an ESP8266 board and then reboot the device, I see the usual messages about wifi etc and after all that finishes, I see a series of + signs scroll up the display. I can't find reference to them but after little while they do stop.

    1. The + signs mean that whatever is set as the web programming button - it thinks it is held low. By default it is GPIO2 and you can change that to GPIO0. Reboot after you're done.

  65. Just trying out OTAUPDATE and I have put the file on my website server. From Chrome I can confirm that it does pass this as a binary file so I know that the web server can send the file. I get the following errors in the serial output.

    Attempting update
    bedroom1/fromesp/otaupdate=Attempting OTA
    E:M 5856
    Tick
    OTA succeeded to ROM 1
    ets Jan 8 2013,rst cause:2, boot mode:(3,6)

    load 0x40100000, len 1340, room 16
    tail 12
    chksum 0xe9
    ho 0 tail 12 room 4
    load 0x3ffe8000, len 660, room 12
    tail 8
    chksum 0xcb
    csum 0xcb

    rBoot v1.4.1 - richardaburton@gmail.com
    Flash Size: 32 Mbit
    Flash Mode: DIO
    Flash Speed: 40 MHz
    rBoot Option: Big flash

    Rom 1 is bad.
    Booting rom 0.
    „ãìÃgäÛsƒòn|ä$d$l`„ã{“dŒþ
    ---------------------
    ESP Starting...
    GPIO4 and 5 are outputs.
    Current web programming pin: 0
    GPIO13 is a LED indicator.
    Software version 1.6.0
    SDK Version: 2.0.0(5a875ba)
    Use the {debug} command for more information.
    STATION mode
    Web page control enabled
    Connected as 192:168:1:148
    MQTT connecting
    MQTT Broker connected
    Device ID is bedroom1
    -->
    Ok
    Ok
    -->
    Time: 00:00:00 00/00/00
    Time Code: 0
    Dusk: 11:52 Dawn: 11:46
    On1: 08:00 Off1: 12:00 On2: 15:00 Off2: 23:00 Peak: 23c Off-peak: 19c Frost: 14c

    IP: 192:168:1:148
    Internal ID: ARPS_0019487B
    ID: bedroom1
    DESC: empty
    FLAGS:
    SSID: ________ (Active) Pass: ________
    SSID2: ________ Pass2: ________
    MQTT Host: 192.168.1.146 Port: 1883 User: admin
    OTA Host: http://www.axoninstruments.biz Port: 80
    Code Version: 1.6.0
    SDK Version: 2.0.0(5a875ba)
    RSSI: -57
    Out0: 0 (1 with invert)
    Out4: 0 (0 with invert)
    Out5: 0 (0 with invert)
    Out12: 0 (0 with invert)
    Out15: 1 (1 with invert)
    Sensor Type: Dallas 1880
    Temperature Port: GPIO2
    GPIO13 available for general use: No
    GPIO2 is an input
    Sonoff setting=0
    WiFi button=0
    Invert settings=HEX( 1)
    Serial2 settings=0
    RGB Indicator=0
    Electrodragon=0
    No LED clock
    CPU frequency: 80Mhz
    Free Heap: 16592 bytes
    Up Time: 0:00:00

    1. But did you try the SAME code on my site FIRST? And did it work? And I have TWO files not one - rboot.com is also there. Only the one gets updated but I've never tried not having the other one there.

      1. Yes. I simply cloned and built it. No changes. The download only looks for the romx.bin if the large_flash option is enabled. These are 4MB devices.

        I'll go and download your binaries and give them a try just to be sure.

      2. I enabled some debugging in rboot_api.c and there is an error when it tries to write to an address. It's the same error and same location each time.

        write addr: 0x00234e58, len: 0x05b4
        write addr: 0x0023540c, len: 0x05b4
        write addr: 0x002359c0, len: 0x05b4
        E:M 5856
        write addr: 0x00235f74, len: 0x05b4
        write addr: 0x00236528, len: 0x05b4
        write addr: 0x00236adc, len: 0x05b4

        Bye the way, the very first time I used this new board (Amica ESP12) it worked and completed the OTA. The issue is that it won't work anymore. I've tried numerous times. It does the same on a second board of the same type and on 2 LoLin boards I have.

  66. Would it be possible to add a toggle option on the out command: Eg, using for example {out16:8} would toggle the output from it's current state? This would be handy for push button switches where we only have a single state output. My Enocean switches have 4 buttons so this would allow me to control 4 lamps from ON and OFF with 1 button.
    Of course, I could handle this in Node-red but it would be easier if this was in the module itself.

      1. Well, I was feeling generous this morning so I've added it to all outputs (not the I2c ones which are still experimental).

        It is command -1 as 7 onwards has other uses.

        So {out12:-1} will toggle 12 on and off.

  67. Just playing with your raspberrypi script with set up passwords for the mosquitto server and all the light switches disconnected from the mqtt network and would not reconnect.

    To save getting off the settee I thought that i'd remove the password requirement and set the mqtt user and password via mqtt with no success after rebooting.

    sad to say I had to get off the settee and go and get all the light switches and update mqtt user and password via the serial connection.

    Can this be performed over the mqtt link or did i miss something?

    As a side note i'm running the code on two standard sonoff's and one modified as per your info to 4MB software so far appears to be rock solid.

    1. It must be too early in the morning (I'm up doing emails before my good lady gets up as we're off on a long drive up Spain to meet friends today) - as it seems like you're asking if you can setup the MQTT user and password over MQTT. Well, if you're connected to MQTT you can indeed change the username and password - but you obviously need to be connected in the first place. You can set them up over WIFI but you'd still have to get off the settee to press the web programming button while applying power.... if I'm way off base try again but I may not answer immediately 🙂

  68. hi Peter, i had mqtt set up with no passwords required and and all the sonoff's connected and responding to commands.

    I wanted to just set the mqtt user and password via mqtt using mqtt_pass and mqtt_user. i tried and then issued a reset command even got off the settee and recycled power. enabled passwords in mqtt but they would not connect.

    did the same commands via the serial port without removing power and they connected no problem?

    safe trip no need for a quick response.

  69. Hi Peter, here reading all your good work, and testing some Wemos D1 mini Pro.
    A little correction, where it says:

    "Payload: {“id”:”fred”,”desc”:”my board”,”attribute”,””}"

    It should be:

    "Payload: {“id”:”fred”,”desc”:”my board”,”attribute”:””}" , with a colon , isn't it?

    Thanks for the info ! we'll be in touch!

    Javier Unamuno

  70. Hi,

    I'm looking into building a relay board (I'm really enjoying the SONOFFS... just bought loads of them) but I want to build some with an LCD, solid state relay and some other things.

    Is there are chance I can see your schematic. I want to try and work out why I'm getting rebooting when controlling a relay. so i'd like to study your schematic if possible.

    many thanks

    Andrew

  71. have you seen itead LED driver!

    Just ordered two as it looks like it will make a nice under cupboard lighting in the kitchen.

    just got to see if your code can be modified to suit it.

    side note! your code is running in an esp1 which fits nicely in an old 433MHz remote control plug. have 2 more to modify as general purpose switch units.

  72. hi peter,
    i want procces on hex string data like ...
    B6 F3 10 FD 00 00 FB CB BA 77 CA CA CA C0 0A CC 00
    how i can split every part of data in hex and procces in node red function
    Thanks

  73. Hi Peter,

    Brilliant set of pages that are so inspiring to read.

    I have created a small circuit with an ESP 12 module with a relay driven off GPIO4 and a switch on GPIO2. I would like to toggle the output with a debounced switch movement AND send a message back via MQTT about the change ( so that the unit will switch manually without the network being operational )

    I have read through the instructions and can't see a way to do this - am I missing something or could you make an adaptation?

  74. Hi Pete,

    please check your link to the SCRIPT in JESSIE Raspbian. It is a dead link now.

    I decide to start using your HomeControl for many reasons and especially because of the DIY possibilities in Node-Red.

    Got my Pi3B running and now I am reading, reading and reading about how to go on.

  75. I found it anyway by googling a bit, but this is better for newcomers like me.
    Came a little closer to a working Pi3B. There is the issue with the serialport which gives a fault when starting Node-Red. I do not know what to do to correct that. I have read and see the reason for the problem, but what to do to get this fixed for your system on a Pi3?
    I've read this http://spellfoundry.com/2016/05/29/configuring-gpio-serial-port-raspbian-jessie-including-pi-3/. I am not enough informed to understand all of it. I think it needs some text in your WORD doc.
    At least I want to have my Pi3 start without fault messages.
    I really are starting to learn about Node-Red and your contribtions to it. What I cannot find is the Flow for the Node-Red, but where can I find your central system??? Is it in one of your blogs referenced?

    1. I am absolutely not planning to put up my flows for the house control - because they are very much specialised for my own needs and would need WAY too much explaining.

      Serial port - likely using it before it is set up - put a delay initially on any serial port access of a couple of secs...

  76. Sorry to say, but that would be the only concise document to find out how things are working together! All "documentation"is loose sand scattered across the internet, blog, bitbucket, youtube all as separate items. Your doc is also not describing the procedure to come from scratch to a working system. I had to look at Peter Oakes's video to find out how to configure all ESP units. There are too many gaps in the description.

        1. Well, you'll obviously need to recompile the code - part of the problem there might be that the line parser accepts negative numbers however. i.e. xxx:-1 is valid. So you'd need to do a tiny bit of work in that area - it is all in the same area in petes_code.c

          Start looking around line 2503 and 2518 - those line numbers of course only apply to the current version which at the time of writing is 1.6.57

  77. Peter, any plan to add support for displays using MAX7219 or TM1637 chipsets? I think they're cool to display small info like temperature, umidity, etc... just asking 🙂

    max7219, 8 numbers, cascadable modules
    https://it.aliexpress.com/item/MAX7219-LED-Dot-Matrix-8-Digit-Digital-Tube-Display-Control-Module-For-Arduino/32638121832.html

    tm1637, 4 numbers, smaller display
    https://it.aliexpress.com/item/Free-shipping-4-digital-display-with-adjustable-brightness-LED-module-clock-Point-Accessories-Blocks-for-arduino/1961805015.html

    tm1637, 4 numbers, bigger display
    https://it.aliexpress.com/item/4-Digit-LED-Display-Tube-7-segments/32591091564.html

    1. Well, that would be good - but I can't go buying up every display and I2c gadget on the planet on the off-chance they may prove useful 🙂

      Currently that larger display from China would take 30-50 days to get here to the UK!

  78. On the subject displays. I could not get anything usefull from your seed class onto SSD1306 blue/yellow 128x64. However do you know about this: https://github.com/squix78/esp8266-oled-ssd1306?
    I have made very nice displays with it. Why not integrate in your MQTT software instead of the seed thing you are experimenting with. I use this https://www.aliexpress.com/item/Free-shipping-Yellow-blue-double-color-128X64-OLED-LCD-LED-Display-Module-For-Arduino-0-96/32665937977.html?spm=2114.13010608.0.0.mDEoS5 part(less than 3€!
    Here: https://drive.google.com/file/d/0B9JhUQDijic0X2gxNlVyTkRmaUU/view?usp=sharing is the ino with the code and this looks very much like your code which includes in assembler written routines. Detail, i have tried with fps=60 so very smooth and bright. For other applications this could be down to much lower fps.

    1. Hi Leo

      Two reasons I've not done this - I have one of those displays - ordered one to do just that - then I discovered that they have a short life - and lost interest. Also - the assembly code. I'm getting adept at converting C++ back to C for the Eclipse/unofficial compiler environment but last time I tried converting some assembler, I failed miserably.

  79. I have never done programming in C or C++, but what I understand from the differences you can read on Internet C++ is not the right language for this project. I'v done VBA and it looks like it's the difference like VB to .NET. So somehow I still like to use this display and control it from Node-RED. Any guidance what route to go? Maybe investigate MQTT libraries for Arduino?

    1. C++ (or C#) is basically what they use in the Arduino setup. I use C - using the unofficial development kit for ESP8266 on a Windows PC - it's all down to taste really. VBA is very different to either of them. The easiest route I guess would be the Arduino route as there will be libraries for it. There is an MQTT library for ESP8266 in the Arduino/ESP setup which seems pretty reliable (another reason I've stuck with the basic SDK and C is I get utter reliability from the WIFI and MQTT and don't want to chance going backwards).

  80. Sorry for the late follow up, but I have been working to correct this flaw.
    Have you seen my picture in the link? There you can see that the time in the time: toesp stays the same until the next minute+ 1 second. So in practice the clock is in average 30 seconds slow. I have now split your time/dusk/dawn message with a separate message for time and one for dusk/dawn.
    All my computers are in sync as I can see by looking to the detail and I can use it as a source. I suppose the Pi is synchronized to NTP at startup. I have this separate ESP with a synch to NTP that generates a Mqtt msg with time, so that will be my time master. I will communicate with that ESP for time to all ESP's in the home control. So Node-Red can generate a request to that time master to get the NTP time every 12 hour. Then this time master sends a Mqtt time master to all clients.
    All this is not yet realized but in the end I will generate dusk/dawn message from esplogin node and time from this timemaster.

  81. I have an issue with the status LEDs on the clients.
    Today I renamed my pi from raspberrypi to homepi with 2 clients connected and after restart the status leds keep on fast blinking although reconnected to WiFi and broker. When I power cycle client it keeps on fast flashing even after reconnecting.
    I already noticed before when connected and disconnected fom the broker or homeserver goes down they keep on slow blinking as if everything is OK.

    1. Just checking - you HAVE set them to the correct type? The board supports both RGB serial LED (default now) and normal LEDs - the output is very different depending on the setting.

      1. Sorry to be a bit late. Now I am so far to test normal 12V leds as a replacement of Halogen bulbs. I have made a very small driver with the help of a Mosfet and I am very happy with the very low resistance of it. You can switch Amps with it without noticing real heat on the surface. But I have to supply PWM to control the luminousity of them like a dimmer. I cannot figure out how your PWM command works. I have connected the control lead to GPIO15 and give the command {pwm:0,0,50} for 50% lum on the 3rd parameter(assuming this is GPIO15(BLUE). Nothing happens. I realise this is originally meant for RGB leds with 4 leads and I already used your clock on different ports with the 60 serial leds, but I like to use the ESP as a dimmer. How to??

        1. Hi - so firstly you cannot do PWM and serial LEDs at the same time - the PWM affects the timing on the serial LEDs. That is a limitation of the technology as the serial LEDS run at very high speed and that is not configurable as the LED timings are not flexible. The PWM should work as your example above.

        2. I found out 2nd parameter is GPIO15. Please define in doc the assignment of parameters! With a little bit of programming in a function we can make 3 dimmers. Works as expected!

  82. Hello Pete, I have a few questions:
    1) How to defferentiate different home control 2016 states/errors using the LED status indicator on GPIO13?
    2) MQTT /lwt message: could you please add board id before /lwt message so we one can differentiate LWT messages from different boards (e.g device1/lwt) ?
    3) I need one more input to use in my home project. Is it possible to add the functionality that changes/switches the output's (e.g GPIO4/GPIO5) to the input bahaviour like GPIO14 is?

      1. Thanks for your replies!
        Some more comments
        1) What is the purpose of the GPIO13 LED blinking? What does the blinking means – is it always blinking with constant frequency, could it stop blinking or could it be steady light on?
        2) Sometimes the unit stops sending stats to MQTT or just disconnects from WiFi - this feature will let me or someone else know that certain device is out of reach so and the commands send to this device won't be executed, you see?

        1. The LED blinks generally to let you know that all is well. This is now historical as the focus on the current boards and software is making use of an RGB LED to show different states in different colours.

          You can turn the LED off - see manual.

          It should NOT stop sending information to MQTT - check version is up to date and check your power supply. My units are on 24-7.

Comments are closed.