Category Archives: C Programming

ESP8266 Debug

Light bulb momentsSo – I’ve learned quiet a lot in the past few days..

Watchdogs on the ESP8266

Since Espressif SDK 1.01 or thereabouts, watchdog timer operation seems to have changed – delays of any length even in init()  are out – or so it would seem? So I got onto Stanza Wang, the business Development Director of Espressif Systems who as always was most helpful and got a quick reply from one of the development engineers on this subject.

It turns out they’d prefer the use of these function:

void pp_soft_wdt_stop();    // close software watchdog
void pp_soft_wdt_restart();    // reset software watchdog

So for example use void pp_soft_wdt_stop();    before your delay and then use void pp_soft_wdt_restart(); 

Delays are not a good idea full stop if you’re using background processes such as WIFI – but you might not be!

Maximum use of FLASH

Thanks to Richard Burton, it is now possible to start programming right down at the bottom of memory – leaving LOADS of FLASH free (though iRAM continues to be a precious commodity – someone needs to do a “how to” on saving RAM. I’ve blogged on this elsewhere with a link.

Debugging and those Pesky Messages

ESP12-EAnd now…. debugging.  I have had it up to here with odd strange output from the Espressif SDK. TuanPM implemented a simple macro called INFO for outputting to the serial port for debugging and general information – but there was no way to control what came out – worse, the SDK kept throwing status information out which wasn’t wanted – so we’ve written our own.

If you’re outputting info to the serial line the best way as we’ve found is to disable Espressif’s messages using

system_set_os_print(0);

in your user_init function. This turns off all output to the serial – unfortunately that means that os_printf() no longer works – so you’re dead in the water. We wrote our own printf equivalent for the serial port and we call it iprintf().

You don’t HAVE to make it this complicated… if you want you can simply, having disabled os_printf() use ets_printf() where you want text to the serial port - but we wanted more control.

Here are a couple of definitions – bit masking – you might choose to make your own.

This is in our DEBUG.H file

extern int enable_debug_messages; // Needed by debug.h

#ifndef USER_DEBUG_H_
    #define USER_DEBUG_H_

    #define DEBUG 1
    #define INFO 2
    #define RESPONSE 4

#endif /* USER_DEBUG_H_ */

So somewhere in the init, set a variable (see above) to the level of debugging you want….

//int enable_debug_messages = INFO | DEBUG | RESPONSE;
int enable_debug_messages = INFO | RESPONSE;

 

And here is the function to use that…

void ICACHE_FLASH_ATTR iprintf(uint16_t debug_type, char *fmt, ... ){
  char buf[128]; // resulting string limited to 127 chars inc arguments – change if you like
  va_list args;
  va_start (args, fmt);
  ets_vsnprintf(buf, sizeof(buf), fmt, args);
  va_end (args);
  if (debug_type & enable_debug_messages) uart0_tx_buffer(buf,os_strlen(buf));
}

So basically you have a function you can call with a debug level..

iprintf(INFO,”Starting up the program”);

You can pass parameters to it just as you would with printf….

iprintf(RESPONSE,”The answer is %d”,answer);

etc.

Depending on the level of debugging you want you could expand on this greatly.   Someday we’ll convince Espressif to optionally turn off that start-up 78k rubbish and we’ll have totally clean output – for now this is a great start.

A shame you often have to hunt around for this stuff!

Facebooktwittergoogle_pluspinterestlinkedin

In a Far Distance Galaxy

A long, long time ago in a far distant…well, world, when I was pretty much using Arduinos for everything, the ESP-01 came along and my friend and colleague Aidan made a little board to handle a relay, an LCD display and.. an ESP-01. At the time we had no use for it, just seemed like a good idea.

Arduino board with ESP-01Today thanks to the likes of Tuan for his work on MQTT and the guys responsible for getting the ESP environment working on Windows via Eclipse (not to mention Espressif themselves) it is very tempting to think that we no longer need Arduinos.

When I say Arduino I mean of course any board based on the Atmel chips. In this case we used a 1284 chip which is an Arduino on steroids but completely compatible. Way more pins, 16K RAM, 128K FLASH – lovely. But as with most Arduinos, getting them to talk to the Internet is disproportionately expensive in terms of available FLASH and real cost.

Well, it was. Thanks to Tuan once again, we now have a way to merge the two. When I was talking to him a LOT about the MQTT software (as I kept finding bugs) he mentioned briefly that he was working on a serial protocol called SLIP so that the ESP boards could communicate efficiently and reliably with the likes of Arduinos.

Well, this evening I decided to revisit this and went off to his Github site here. You may be familiar with his esp_mqtt software which is superb and which I use as the base of my various ESP-12 boards. Well, in that link you’ll find another project of his called espduino. I suggest you take a look.

In essence there are a couple of binary files you blow into an ESP01.  The ESP-01 talks to the Arduino via serial and in the case of lesser Arduinos, that means talking via SERIAL (the only serial port) while doing debugging via a software serial port. Well, the `280 and 2560 based boards have more than one serial port, so I’ve taken his Arduino code and swapped things around… Serial1 for the connection between Arduino and ESP-01 – and Serial for debugging.

So basically once you’ve dumped the binaries into the ESP-01, you connect serial1 from the Arduino (in his example Serial) to the ESP8266 serial – taking into account any level shifting – best to run everything off 3v3 then you don’t have to worry about it.

He shows a wire from the ESP (CH_PD) to D4 on the Arduino but then doesn’t use it so tie CH_PD high as usual.

Run Tuan’s library examples on the Arduino and I can tell you that they just run – they work without issue – I’ve had the board send thousands of messages off to MQTT-Spy. The minimum setup takes in total around 9k, that’s including MQTT -  this is WAY better than anything you could achieve with Arduino Ethernet boards which, as far as I’m concerned are now dead in the water.

In my case we had this little board with the option to add an ESP-01 – took me minutes to get it working – I’ve now imported my command parser from the ESP-12 projects (they’re not that dissimilar if you are using C)  and now I have a board that asks my PI for the time (it’s in the blog somewhere – MQTT request – all my boards know and maintain the time, updated from a Pi on power up and every day otherwise) and can turn a relay off using the same protocols I discussed here.  All I need now is a boatload of libraries and if-then-else blocks to pad the board out into something really useful.

So why add this extra level of complexity?  Well, I use serial LEDs and PWM based lighting and the ESP-12 does NOT do PWM well AT ALL. If you control serial LEDs and say they are slowly fading out – any PWM in use fluctuates slightly. In addition I have serial LEDs working almost perfectly on the ESP8266 but every now and then there’s a timing-related flicker – almost never but you know it is going to do it just as the lights are fading out as you are going to sleep.

The Arduino on the other hand does multi-output PWM flawlessly and there is the great FastLed library for the serial LEDs – not to mention the ability to store data in FLASH easily which means that LCD fonts are easy to implement… and there are many LCD display libraries out there. The combination then is a matter of sense – and let’s face it you can get a bog-standard Nano Arduino from China for under £2 and the ESP-01 for WELL under £2 so using both together is hardly going to break the bank.

So there it is… that’s my Sunday offering – already the board is getting the time and controlling a relay… it won’t be long before I turn it into a kitchen sink.

Facebooktwittergoogle_pluspinterestlinkedin

Home Control The Next Step

NETIO screenAs regular readers will know I’ve pretty much gotten to grips with the whole home control thing having after much research settled on a largely MQTT-based setup using the excellent new Raspberry Pi2 as a hub with Node-Red.

Though it could just as easily have been any proper Linux or Windows based setup, I could not justify in my own mind using an expensive piece of kit to do this as I’d previously been using an ATMEGA1284-based controller of my own design which cost just about nothing – but was constantly worrying about running out of resources on this – and then along came the Raspberry Pi 2.

Funny how things like that make a step change in how you do things and so it is again with the controller side of things – read on.

I’ve messed around with a number of solutions for the remote hand-held part of home control, ranging from simple infra-red controls, through radio, but always coming back to the not-too-well supported NETIO. I say that as it takes AGES to get changes made. The product costs very little, sits on Android or IOS phones and makes for a very pretty button-and-icon interface for home control – a LOT prettier than most of the other solutions out there and a lot easier to use – basically you move items around on a browser-based IDE, change properties and Bob’s your uncle.

The problem with this up to now has been the way NETIO handles the interface with your home control. It can use HTTP and UDP but I prefer to use a simple TCP interface. Up until now, each button or icon on NETIO would send a message and expect a response. So a button would send a message when pressed and simply need an acknowledgement.  An icon to say show the state of a light would regularly request updates and expect the status to come back. The problem with that was – if you expected a quick response when pressing a button you would be disappointed – imagine the icon requesting a response every half second in order to stay updated – and you had a dozen of them on screen at once-  that’s a lot of updating and on a poor connection this was disappointing.

Until now there was no way for a button to talk to it’s own separate icon. That has now all changed. NETIO now features event-driven operations, that is the home control system once the TCP connection is made, can arbitrarily send a message to the phone and to one or more icons at the same time. Each icon is now responsible for checking to see if a message is for it.. and that is done with a simple regular expression.

Trust me – this is a major step forward for this program – as it enables almost instant feedback – rather handy if you’re not in line of sight of the item.

Ok this all sounds really painful but it isn’t.

If you take a look at my picture above – one of my test pages, there are a bunch of on-off buttons and indicators.. The indicators need to do two things… at power up they need to poll the state of whatever it is you are controlling – that is so as to set their initial state. From there on they need to be watching out for messages which could come at any time. Each one must have something unique so so to identify it.

NET Control

On the NETIO control page here on the left you will see there is a READ instruction – that is to read in this case the state of the GPIO control on the Raspberry Pi2.  I’ve adopted the vertical line as a separator. So gpio?|0 sends off a string to the Pi which is picked up by Node-Red and sent to a function, which then returns (let’s say the light state is 1) status1=1

The parseResponse field will only do anything if the incoming string contains “status1=” and then pulls out the value to determine which of two images to use for on or off. The point here being that not only can this icon request the status – but any other event can return status1=1 and affect the icon, so you get a one-off refresh on power up and then whenever you change the state of a button, a message is sent from the Pi to the phone to change the state of the icon, in most cases instantly – no more polling.

And there you have it – the ability now to have WAY more icons than before on a page without ridiculous amounts of polling – If ONLY the NETIO author would do this via MQTT it would be SO good but for now this is just about the easiest interface out there without the limits of some predefined program. There are plenty of icons in NETIO and you can add your own images at any time.

At the Node-Red end…

Node-Red

There is an incoming TCP connection from the mobile phone, that data is processed in a simple function (and in the case of the simple local IO pins I store the outputs in a database but that’s not relevant here, nor is the MQTT output) the outputs are controlled as requested and also a TCP reply is sent back out to the phone. In the case of queries, no outputs are modified, the state of the outputs is picked up from global variables and send off to the TCP output…. a simple string.

House-building is commencing in the new cottage – the electrician is putting in my networking cable and ensuring I have a wire coming from most lights etc. to offer an over-ride function to normal manual control – once our boards turn up they will be pressed into service using a vastly expanded version of what you see above. It is all coming together.

If you want to keep up, subscribe to this page – or subscribe to my Facebook page  https://www.facebook.com/esp8266wifi and if you have ideas for improvement – fire away – there are some great conversations in here.

Facebooktwittergoogle_pluspinterestlinkedin

C ? Construct

For the LIFE of me I do not know why this statement is failing.  There are two versions of settings for port outputs here – the one in red and the one in blue. If I choose the blue version it will only work in one direction, not the other.

If I choose the version in red – it works full stop.

The same ? construct is used in sending messages out and that works perfectly. This is C programming in Eclipse for the ESP8266 chips… “intvalue” is just the number 0 or 1

 

else if (strcmp(token,"out2")==0)
        {
            if (sysCfg.out_4_status!=intvalue) { sysCfg.out_4_status=intvalue; do_update=1; } // only update if actual change

            if (sysCfg.out_4_status==1) GPIO_OUTPUT_SET(LED_GPIO_4, OUT_ON); // on or off by default
            else GPIO_OUTPUT_SET(LED_GPIO_4, OUT_OFF);

            //GPIO_OUTPUT_SET(LED_GPIO_4, (sysCfg.out_4_status==1) ? OUT_ON : OUT_OFF); // doesnt work - don't know why
            strcpy(token,tBuf); strcat(token,"/out2"); MQTT_Publish(client, token,(sysCfg.out_4_status==0) ? "OFF" : "ON" ,(sysCfg.out_4_status==0) ? 3 : 2, 0, 0);
        }

Thoughts anyone? I must’ve been starting at this for too long.

Facebooktwittergoogle_pluspinterestlinkedin