Category Archives: ESP-201

ESP12 and Memory

Anyone writing large projects with the ESP units in C (and probably in other languages without necessarily realising it) will have come across the problems of .TEXT memory. This is the RAM used to store functions.

Functions are stored in their own part of RAM called .TEXT memory and it is WAY too small. Now most of you will have made liberal use of the “ICACHE_FLASH_ATTR “ directive in your functions. This ensures that functions stay in FLASH until actually needed and this saves lots of .TEXT RAM – indeed without it, larger programs would be impossible.

Despite all of that I’ve been slowly running out, sitting at 7CFF  (you can only go up to 8000) recently and when the latest API came out – that was it – over the top – dead.

So for a while I stuck with the previous SDK and eventually got onto Espressif.

They asked me for a .DUMP file – which of course I neither had nor understood and they suggested that in the project directory I type:

xtensa-lx106-elf-objdump -x -s app_0.out > app_0.dump

WELL I was convinced this was another Linux tool that would not work in Windows – but it DID and produced the English-readable file app_0.dump which tells you where all your functions are sitting.

They suggested I add the "ICACHE_FLASH_ATTR"  to my EASYGPIO functions. Well of course as that was an existing library I’d not touched that – and sure enough – I got just enough memory back to be able to use the latest SDK!!   I was now sitting at 7B52 on the latest SDK – not good – but better… and at least I was using the latest SDK. They then suggested I use "os_memcpy, os_memset, os_strcpy" instead of "memcpy, memset, strcpy" so I systematically went through all the code and did this.

On recompiling – I now find the .TEXT RAM sitting at 79C2, the lowest it has been for AGES – another 512 bytes back just by using their functions instead of the standard ones!

I’m making no claims about reliability as I’ve not given this a thorough test – but that is for me a very worthwhile improvement in memory. Of course that means a tiny slow-down as functions have to be pulled out of FLASH to use… What speed would we have gotten out of these devices if they’d just done the RAM differently. Still – given the price of ESP devices I suppose we can’t complain.

Facebooktwittergoogle_pluspinterestlinkedin

EMW3265 ESP8266 KILLER

EMW3265Erm, no, though you might think so by this headline..  https://hackaday.com/2015/07/13/new-part-day-the-esp8266-killer

Read the comments – the $5 ESP8266 – where?  $2 ESP8266 more like it – less, even - http://goo.gl/VB0V9K

There’s even a claim that this new single-source board (Seeed Studio) has MORE memory – well at least one variation of ESP12 has 4Mbytes – and the EMW… according to the ad, 512K.

And what about the all important Windows and Linux support libraries? Erm, no.

Another comment – Chinese documentation? Well I don’t know about you guys but I have  raft of English documentation that until recently came with the Espressif SDK and which is now maintained online.

And the last – Chinese – guess where SEEED are!

Cheap, reliable, effective, more compatible variations of ESP and more suppliers than you can shake a stick at – and we want to move for what reason?

But – if you like spending money – there’s this – even more expensive - http://www.seeedstudio.com/depot/EMW3162-WiFi-Module-p-2122.html

Facebooktwittergoogle_pluspinterestlinkedin

Automatic Router Selection for ESP8266

I wonder if anyone who has done this can help.  As most of you know, I program my ESP8266 devices in C.  I've been having some issues with weak signal recently and it would be really nice to have a list of acceptable access points and their passwords - and have the ESP, if it loses the signal, check the list (including identical SSIDs) and reconnect.

Has anyone done this already and if so would they care to share code?

Facebooktwittergoogle_pluspinterestlinkedin

ESP8266 Remote Access

Notice I titled that remote access as against remote programming – but that’s part of it.

Years ago, having gotten sick and tired of dismantling my home control Arduinos just to upgrade the code, I purchased a couple of small units from China which I’ve just thrown in the bin.   One had a USB plug on it and plugged into the PC, the other had an FTDI output on it. Both had those black 2.4Ghz antenna.

So the purpose of these units was to wirelessly replace an FTDI – or serial programmer, the idea being that instead of bringing the Arduino project back to wherever one programs the devices, you plugged the unit into the project and over the air programmed it.

At the time I was using Arduinos and those CHEAP £1.50 radio modules – the NRF24L01s, the worst radio boards in the world who’s range could be so bad you’d be lucky to get through one wall. I had high hopes for them with a great mesh network called RADIOHEAD, but ultimately their range and lack of ability to read signal strength doomed them.   However, as you can imagine they were dotted all over the house and I thought this little radio pair would solve the issue of programming them without ripping everything up.

It turns out the “radio FTDI” had the same problem – it was based on the NRF24L01.

Fast forward to September 2015. Here I am in Spain with a new setup of ESP-12 modules controlling lights, watering system and a lot more.  I’ve made some improvements to our “home control 2015” software in the ESPs and once again I find myself having to dismantle kit.

Now, I know that is it possible to program over the air – a few guys have tackled this successfully and indeed much of the code is built into the Espressif SDK. Right now my friend Aidan is working on adding this to our code but there are two issues, he’s not had luck up to now and secondly as our code comes to something like 300k you’re never going to be able to add this to the ESP-01 modules (we use ESP-01 sometimes, ESP-12 other times…)  as you need as much spare storage as you have code for OTA programming!

It was with that in mind that last night I dragged out the old FTDI boards to see if I could save myself the effort of dismantling the Pergola lighting system to update it.  Suffice it to say that I managed to get a few bytes programmed before that all came to an end despite several attempts. With around 25 WIFI units of one description or another dotted around the place, the old wireless FDTI (same frequency range) simply could not handle more than a few feet.

Bin.

I figured it would not hurt to look around and see if someone has alternative wireless solutions – lots of time has passed since I bought that kit.

And so it was that I stumbled upon this.  https://github.com/jeelabs/esp-link – as it happens it is quite new – essentially what we are looking at is a single unit (yes, that had me going for a while) which will hook into the WIFI system and act like an FTDI – given that you can fire the serial out of your PC over TCP to a port – port 23.   I grabbed the code (the stable 1.04 version) and very excitedly blew it into an ESP-01 unit I had lying around.

Really, nicely done web interface (with remnants of Martin Hanzarov’s code in there) and a really good write-up – indeed there may be enough info in there to help us implement our own FOTO (over the air) updates to our code.

But this has far wider implications – a virtual serial link would also let you monitor the serial line of a remote unit for debugging info – and our units do indeed put out lots of serial debugging info. It would also let you remote program and monitor un-wirelessly enabled Arduino projects.

So the first problem was – I had this unit sitting as 192.168.1.27 on my network and I needed to blast info into port 23 to have it come out as 115K serial.  I have ECLIPSE sitting on the PC running my projects and there’s a line in the MAKE file that says “COM6”.  I have absolutely NO idea how to turn that into a TCP statement if indeed it can be done (FEEL FREE TO START TYPING IF YOU KNOW HOW).

So I turned to a 30 day trial of a PC program that promised to provide a “virtual com port” – and that it did. Serial/IP Redirector let me create a link to 192.168.1.27 port 23 and ship raw data back and forth to COM22 (which doesn’t exist on my PC)- LO AND BEHOLD I set it running, put PUTTY on the PC talking to COM22 and with a real FTDI attached to the little ESP-01 board on real COM6 I set that running on a terminal –at 115K. Utterly flawless raw serial communications – rock solid.

I was getting excited by now. I took my ESP-01 board and cross-connected the serial to an ESP-12 test board. I held GPIO0 to ground and turned the power on, putting the ESP12 into programming mode.

I punched COM22 into the ECLIPSE project and hit the FLASH button on the project. Lights flashed on both units. With a scope attached  to the serial in on the ESP-12 I could see clean 115k data going into my project and… nowt, zilch, nothing.

I was up until the early hours ensuring the baud rate was ok and that my level conversion wasn’t getting in the way – you see all my projects use a resistive divider on the serial input of ESP boards so the whole lot will work just fine with 5v logic on the FTDI and elsewhere.  I wondered if hooking two of these units together with serial cross connected might prove too much but the scope says no – it says I’ve a perfectly reasonable serial signal going into the ESP-12 – but it’s not having it – no responding output whatsoever. Eclipse tries sending out data over and over and eventually gives up just as if there’s nothing connected.

So near and yet so far.

I got up this morning and the unit was still rock-solidly connected to the WIFI and typing a few characters provided perfect results at the other end – but I cannot program ESP units – yet.

Very exciting, yet very frustrating.

Perhaps coffee and a new start to the day will help. BUT I had to bring this to you as the article is really good, the software seems to WORK and there’s a super-bumper version with it’s own OTA updating in the works for larger targets like an ESP-12 (more FLASH) than the ESP-01.

I’m sure this is going to be a winner – just need to get it to work. After all, the ability to add remote programming to any FTDI-enabled project for what, a couple of quid.. well, you just can’t ignore it.

Meanwhile if anyone reading this firstly knows how to set COMX on Eclipse (on Windows) to TCP – do let me know – and if you really think you know what I’m doing wrong here and want to jump in before I figure it out – by all means – you have the keyboard…

Facebooktwittergoogle_pluspinterestlinkedin

QD Tech Displays on the ESP8266

QDTECHI’ve seen a number of projects using an Arduino and an ESP8266 to drive LCD displays. You may know that my home control has used a 1284-based board (MEGA type) to run a nice Thermostat display for some time now. The displays look very pretty in the right box.

THIS article will tell you about the display but you’ve seen them on Ebay no doubt.  https://tech.scargill.net/samsung-s6d02a1-based-lcd-colour-display-and-arduino/

Banggood do the displays (I can’t help thinking the price has gone up – at £3 inc postage – but still cheap) http://www.banggood.com/1_8-Inch-Serial-SPI-TFT-LCD-Display-Module-With-Power-IC-SD-Socket-p-909802.html

MAKE SURE you get the display marked 1.8 TFT module using the s6d02a1 chip - there are some marked differently and using a different chip which does not work with my software. Anyway, they are 160*120 and very bright and colourful displays, excellent for simple stuff.

displayI’ve always wanted one of these to run on the ESP-12… on the Arduino assuming 5v you need series resistors for the outputs – as it’s a 3v3 device internally, but with an ESP you can run them directly. So, the device and it’s backlight go straight to 5v, the 4 inputs go straight to ESP8266 pins and the reset can go to the ESP8266 reset pin – again directly.

That’s the easy part – the software not so – there are not a lot of drivers out there for this board for the Arduino – one that does work offers a choice of hardware or software SPI and that’s where the magic comes in – if you eliminate the hardware SPI code it all starts to look quite easy. So yesterday I set about (with no anticipation of success) converting the code firstly from nicely object-oriented Arduino code – to basic C – and secondly to use ESP8266 port pins. I cheated slightly by using EASYGPIO to make the port operations a little more obvious but I don’t think that has cost too much in speed.

Anyway to cut a long story short at THIS point I’m off to the coast for a couple of days sunbathing and I’ll leave you with my work in progress. I’ve NOT added in the code to handle characters/fonts yet but I HAVE got this working completely reliably – drawing boxes and lines.  Right now there is some setup data in RAM, I’ll move that to FLASH shortly (you need a function to access 8-bit FLASH arrays to stop the ESP crashing so I left that until last). Why bother with FLASH? Well, you’ll definitely need to put fonts in FLASH as they get big, quickly.

I’m assuming you’re programming in C – don’t ask me about getting this running in Arduino code or Lua.

Here’s the header https://bitbucket.org/snippets/scargill/EA9zd/qdtech-display-header-modified-adafruit

Here’s the C code https://bitbucket.org/snippets/scargill/qRbpL/qdtech-display-header-modified-adafruit

I’ll assume you already have a project running and just want to add this to it. I’ve reduced includes to a minimum..

My test includes a red screen background, a green box and a blue diagonal line. So with the includes this is all I put in my code (I slightly altered the init code to include ports (not including RST line as you fasten that to the ESP reset – hence needing only 4 port bits – you’re not stuck with my choice – the last two parameters are the screen size).

QD_init(4,5,15,12,0,160,128);
QD_setRotation(1);
QD_setAddrWindow(0,0,160,128);
QD_fillScreen(QD_Color565(255,0,0));
QD_fillRect(30,30,90,90,QD_Color565(0,255,0));
for (int qq=0; qq<160;qq++) QD_drawPixel(qq,qq,QD_Color565(0,0,255));

There it is – a starter only.. but it works – if this were taken to an extreme it would include character handling and hardware SPI – I’m guessing compared to Arduino use it would be pretty FAST..

Now if anyone wants to take this on and add the bells and whistles..

Oh and how would you run the data in FLASH? not so hard… here’s a typical FLASH-based array snippet.

static const uint8_t ICACHE_RODATA_ATTR  kelvin[] = {
255,  51,   0, //    1000
255, 109,   0, //    1500
255, 137,  18, //    2000

And to access that…

// This routine courtesy Richard A Burton - way better than using 32 bit flash arrays (you can't directly
// access 8 bit FLASH arrays directly - will crash the processor)
uint8 ICACHE_FLASH_ATTR read_rom_uint8(const uint8* addr){
uint32 bytes;
bytes = *(uint32*)((uint32)addr & ~3);
return ((uint8*)&bytes)[(uint32)addr & 3];
}

Typical use

rgb.green=read_rom_uint8(kelvin+kel);
rgb.red=read_rom_uint8(kelvin+kel+1);
rgb.blue=read_rom_uint8(kelvin+kel+2);

 

So you can see it won’t be TOO hard to get a load of font data into FLASH – sure, it’ll slow things down a little accessing it – but how that actually affects operation is something we’ll discover in the future.

Facebooktwittergoogle_pluspinterestlinkedin

ESP8266 RAM

I recently put out a question about the RAM in the ESP8266. In a typical compile, for me I might see…

Sections:
Idx Name Size VMA LMA File off Algn
0 .data 00000894 3ffe8000 3ffe8000 000000e0 2**4
CONTENTS, ALLOC, LOAD, DATA
1 .rodata 0000275c 3ffe88a0 3ffe88a0 00000980 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .bss 00009a80 3ffeb008 3ffeb008 000030e8 2**4
ALLOC
4 .text 00007786 40100000 40100000 000030e8 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
5 .irom0.text 0003ce04 40202010 40202010 0000a870 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE

All very confusing.  So .irom0.text is FLASH – why they can’t just call it FLASH I’ll never understand. The rest are various kinds of RAM.

.data is used for “initialised” data, i.e. that which needs copying from FLASH on powerup. I’ve used 0x894 in the above example.

.rodata is used read only data – this is in ram (again I don’t understand, if it is read only why it’s not in flash – most likely for speed). I’ve used 0x275c.

.bss is used for variables which are not initiased. I’ve used 0x9a80.

.text is used for CODE that is not in FLASH – i.e. it is in FLASH on powerup – but gets copied to RAM for speed.  Sadly due to lack of RAM we usually end up using a directive to put code into FLASH to save space – but REALLY time critical code should be left in RAM. Of course it does get copied into RAM (cacheing) but that could mean execution times which are different first time around – not good for RGB LED lighting etc.

A fellow by the name of Don Kinzer replied and here’s what he had to say.. very useful.

“There are no individual limits for the sizes of .data, .rodata and .bss (but see caveat below). The ESP8266 has 80K of User Ram which is occupied by .data, .rodata, .bss, the stack and the heap. Basically, the space represented by (80K - sizeof(.data) - sizeof(.rodata) - sizeof(.bss)) is used by the heap growing from one end and the stack growing from the other end. If the heap and stack collide bad things will happen (probably an exception, eventually, and a reboot).

The caveat that I mentioned is that the .data and .rodata sections, along with the .text section (itself limited to 32K) must fit in the first 64K of Flash. The sizes of each of these sections is rounded up to an integral multiple of 4 bytes and an additional 8 bytes of overhead are added for each section plus an additional 8 bytes of overhead. Finally, space for the checksum is added (between 1 and 16 bytes) so that the overall size is an integral multiple of 16 bytes. The total of all that must be 64K or less. The image containing all of this data is often called app.v6.flash.bin but the name itself is not important.

As for the limit on the size of .irom0.text, that depends on 1) the size of your Flash chip (commonly 512K but can be 16MB or more), and 2) where you load it into Flash and 3) if you want OTA upgrade or not. For non-OTA upgrade, it is common to load the .irom0.text at 0x40000 but it can be loaded as low as 0x10000. Since the system parameter area exists at 16K from the end of the Flash chip, the size of .irom0.text is limited to sizeof(Flash) - 16K - loadAddress.

If you want to load the (non-OTA) .irom0.text at an address other than 0x40000 you'll need to modify the linker script accordingly.”

Facebooktwittergoogle_pluspinterestlinkedin

BASIC for ESP8266

Don’t get me wrong, we don’t yet have a fully working interpreter, but a link appeared on my ESP8266WIFI Facebook page thanks to Michael Molinari this morning and I thought I’d give it a whirl.

http://esp8266basic.com/

I grabbed the Windows loader (Windows 10 put up a SEVERE warning about this which I totally ignored), plugged an ESP-01 into my FTDI and blew in the interpreter, all of which took a couple of minutes and zero effort.

At first I didn’t know what to expect, I looked at the serial port – nothing.. then realised it outputs at 9600 baud, not my usual 115K…. I then started typing stuff into the serial – nothing – at which point I noted it already knew about my router – I can only assume that is because the WIFI passwords were already in the board, normally you’d have to use the board as an access point just to put in your WIFI details… anyway, I managed to bypass that.

I checked the examples on the page – hello world and a graphics example – which worked right out of the box!! Imagine that – simple BASIC commands putting out graphics on a web browser from a twopenny WIFI board all on it’s own!!

At this point, things went down a little. I tried editing the code (in the web browser!!) and it wasn’t having a SAVE – I noted on the serial that it had crashed… but then if you look at the dates this is all very new.

Seriously this has to be worth a few minutes of your time – assuming the project continues and these niggles go away, you just don’t get a quicker, simpler and cheaper way to get a web page with buttons into an embedded device – even if just to do some simple stuff. This is now ENTIRELY down to how much effort the author puts into this.

Go take a look! These images should enlarge on click/touch. Well impressed IF development comes quickly enough….

Basic Interpreter for ESP8266   Graphics on the ESP8266

Facebooktwittergoogle_pluspinterestlinkedin

RGB versus HSV

Image author SharkDIn implementing my own home control solution which you’ll find in this blog “home control 2015” the software has been and remains a work in progress – mainly because I keep finding bugs and adding new features.  I’m fairly confident that most of the bugs that have plagued me over the months are gone. For example NONE of my boards has failed in the last week – running constantly, turning things on and off, monitoring temperature and humidity, powering RGB LEDS…

And that brings me onto tonight’s subject.  You may have  noticed elsewhere that I’m getting fanatical about the Nextion displays because now at last I have the potential of a nice touch display for the wall to control things. You’ll also notice I’m realising their code is VERY early – but that’s another subject.

The first addition I made today to the home control system was to allow any of the ESP boards to send an MQTT message to any other board. Of course that is built into the MQTT library in the first place and there would not be a lot of use in having the Raspberry Pi brains send a message to one board to send a message to another.. but it occurred to me that an essential feature of a serial wall mounted display would be to control more than just the ESP8266 board that it is actually attached to!

So – in went a new command to send out an MQTT command from the serial input on the board so that the ESP board could pass the message on. That’s a little tougher than it sounds as I only had one string argument available in my line parser so I had to delve into that – however, it is now all done.

And that led me to thinking about how my wife Maureen would control the coloured lighting around the house, from the wall.

RGBObvious really, RGB sliders – you can make any colour or hue from RGB can’t you – any techy will tell you that for free.  Sadly the rest of the world does NOT know how to manipulate RGB. Any paper artist will tell you that the primary colours are red, yellow and blue! Not in my world they are not.

And so we have a problem – how to better enable any old user to play with colours – and hence I started reading and it is pretty clear that a better model is HSV, or hue, saturation and value - brilliance in other words – I looked up HSV on Google but the best I could find was Herpes Simples Virus. I’m going to continue to refer to brilliance as the word “value” means nothing to me in this context.  The problem with RGB is – let’s say you get a really nice pink. That’s fine at full brilliance but how would you keep that shade of pink as you turn down the brilliance… even for a techy that is not easy faced with 3 sliders.   With HSV it’s a snap.

And so I’ve been looking at code – I found some great Javascript code and in fact I now have that running on my little WEBSOCKETS project – but what about C to put into the home control project… I found this after much searching. http://www.ruinelli.ch/rgb-to-hsv  Excellent code and simple to implement – do I put that into the ESP C compiler? NOPE – it needed a couple of includes that screwed everything else up because of the FLOOR function… so then I found this…

int inline fasterfloor( const float x ) { return x < 0 ? (int) x == x ? (int) x : (int) x -1 : (int) x; }

That solved the floor function and I was up and running.   H values 0-359, saturation 0-255 and brilliance 0-255.

Thinking about a display, a simple colour wheel with touch points along the way, then 2 sliders… that’s it - full intuitive colour touch control.

Well, it was enlightening for me – I hope you found this useful.

Facebooktwittergoogle_pluspinterestlinkedin

Driving me NUTS

This has been driving me mad and I’ve only just found the answer – thanks to some clues people have given me – but as many of the responses were wrong – you might well find this interesting.

I have a an array of 180 bytes – for 60 serial LEDs – 3 bytes each for red, green and blue respectively.

So this routine calls back every second – and updates the 60 LEDs which are in a circle. The hour indicator is formed of 7 LEDs, bright in the centre, dimmer to the edges, the minutes indicator is 3 LEDs – again bright in the middle. The seconds are shown as 1 LED.

And it was working a treat – except at midnight where it bombed with all LEDs on – and for the LIFE of me I could not see why..

Ignore the bits in RED….

LOCAL void ICACHE_FLASH_ATTR clock_cb(void *arg)
{
if (sysCfg.clock!=255) // fancy clock on a port
    {
        wsBitMask = (uint8_t) sysCfg.clock;

        int hour12=(tm.Hour%12)*5;
        for (int a=0;a<180;a+=3)
            {
                rgb.buffer[a]=0;
                rgb.buffer[a+1]=0;
                rgb.buffer[a+2]=0;
            }
        rgb.buffer[(tm.Second*3+2)%180]=255; // seconds hand blue

        rgb.buffer[(tm.Minute*3-3)%180]=8; // minutes green
        rgb.buffer[(tm.Minute*3)%180]=255; // minutes green
        rgb.buffer[(tm.Minute*3+3)%180]=8; // minutes green

        int x=((hour12)+(tm.Minute/12))*3;

        rgb.buffer[(x-8)%180]=5;
        rgb.buffer[(x-5)%180]=16;
        rgb.buffer[(x-2)%180]=80;
        rgb.buffer[(x+1)%180]=255;
        rgb.buffer[(x+4)%180]=80;
        rgb.buffer[(x+7)%180]=16;
        rgb.buffer[(x+10)%180]=5;

        WS2812OutBuffer(rgb.buffer, 180,1); // 60 LEDs
    }
}

So here’s the thing – all these years I’ve been thinking % was a MOD operator – it’s NOT – it’s a simple remainder..

In order words..

(-3 % 180) which I had COMPLETELY expected to be returning 177 – was in fact returning –3  !!!!!

That explains a LOT. The solution – a simple MOD function.

LOCAL int ICACHE_FLASH_ATTR mod(int a, int b)
{
   int ret = a % b;
   if(ret < 0)
     ret+=b;
   return ret;
}

Hence mod(-3,180) returns the right answer. Here’s the final clock once-a-second callback routine for a 60-LED array.

LOCAL void ICACHE_FLASH_ATTR clock_cb(void *arg)
{
if (sysCfg.clock!=255) // fancy clock on a port
    {
        wsBitMask = (uint8_t) sysCfg.clock;
        int hour12=(tm.Hour%12)*5;

        int a;
        for (a=0;a<178;a+=3)
            {
                rgb.buffer[a]=0;
                rgb.buffer[a+1]=0;
                rgb.buffer[a+2]=0;
            }

        rgb.buffer[mod(tm.Second*3+2,180)]=255; // seconds hand blue
        rgb.buffer[mod(tm.Minute*3-3,180)]=8; // minutes green
        rgb.buffer[mod(tm.Minute*3,180)]=255; // minutes green
        rgb.buffer[mod(tm.Minute*3+3,180)]=8; // minutes green

        int x=((hour12)+(tm.Minute/12))*3;

        rgb.buffer[mod(x-8,180)]=5;
        rgb.buffer[mod(x-5,180)]=16;
        rgb.buffer[mod(x-2,180)]=80;
        rgb.buffer[mod(x+1,180)]=255;
        rgb.buffer[mod(x+4,180)]=80;
        rgb.buffer[mod(x+7,180)]=16;
        rgb.buffer[mod(x+10,180)]=5;

        WS2812OutBuffer(rgb.buffer, 180,1); // 60 LEDs
    }
}

Facebooktwittergoogle_pluspinterestlinkedin

EasyTransfer for ESP8266

I’m going to describe here the transmitting side of the EasyTransfer system as used in Arduino – the reason I did this was because I wanted to ship a bunch of binary data from the ESP8266 to the Arduino where I have a nice little wall mounted LCD display – no point in re-inventing the wheel.

EasyTransfer is a simple enough format – it starts with 0x6 and 0x85 followed by the length (all in bytes) of what you want to send, the data itself and a one-byte checksum which is the length XOR’d by every byte in the data (not including the checksum itself of the header 0x6 and 0x85.

So you point a structure to it – and off it goes and the structure is recreated at the other end. Or it is?

struct transmit_lcdX {
  //put variable definitions here for the data you want to receive
  //THIS MUST BE EXACTLY THE SAME ON THE DISPLAY BOARD
  uint8_t cmd;
  int16_t passed;
  uint8_t humidity;
  uint32_t thetime;
  int8_t internal;
  int8_t external;
  uint8_t pre;
  uint8_t heat;
  uint8_t hold;
  int8_t offset;
  uint8_t set;
  uint8_t fallback;
  uint8_t falltemp;
  uint8_t thermenable;
  uint8_t dusk_hour;
  uint8_t dusk_min;
  uint8_t dawn_hour;
  uint8_t dawn_min;
} ;

struct transmit_lcdX transmit_lcd;

 

//Sends out struct in binary, with header, length info and checksum
void ICACHE_FLASH_ATTR EasyTransfer_sendData( uint8_t *bfr, uint8_t size){
    uint8_t buf[40];
    uint8_t CS;
    CS = size;
    buf[0]=0x06;
    buf[1]=0x85;
    buf[2]=CS;
    for(int i = 0; i<size; i++){
        CS^=*(bfr+i);
        buf[i+3]=*(bfr+i);
    }
    buf[size+3]=CS;
    uart0_tx_buffer(buf,size+4);
}

There you go – what could be simpler – define the struct – make an instance of it called transmit_lcd – and call a function passing the address of the structure and it’s length.

Well the first bit I got wrong was to send it out in pieces. I did not realise that Espressif’s function uart0_tx_buffer(buf,len) doesn’t operate immediately – clearly it works in the background under interrupts – I guess the word “later” in the instructions should have made me twig but it didn’t.  So first things first, that structure buf[] has to be static – so that it stays there even after the function has done and cleaned up.

That was fine – and so I called my function – nothing… the LCD would not accept the data… I must’ve spent hours on this – I eventually grabbed a terminal with hex output and…. I’d set the time – and sure enough my checksum was working – but the time was in the wrong place.  2 8-bit integers and a 16-bit come to 4 bytes so what I should have seen was 06 86 0xff 00 00 00 00 aa bb cc dd   where ff is the checksum and aa bb cc dd is the 32 bit time.

But no – the time was much further on! How can this be! WELL it turns out that without a special optimisation, DESPITE the fact that I called some of those variables in the struct 8 bits – they were ACTUALLY being stored as 16 bits -   WHAT!!!

So here we have the version that WORKS – of course you can replace the struct data with any old variables – this just happens to be mine….

struct transmit_lcdX {
  //put variable definitions here for the data you want to receive
  //THIS MUST BE EXACTLY THE SAME ON THE DISPLAY BOARD
  uint8_t cmd;
  int16_t passed;
  uint8_t humidity;
  uint32_t thetime;
  int8_t internal;
  int8_t external;
  uint8_t pre;
  uint8_t heat;
  uint8_t hold;
  int8_t offset;
  uint8_t set;
  uint8_t fallback;
  uint8_t falltemp;
  uint8_t thermenable;
  uint8_t dusk_hour;
  uint8_t dusk_min;
  uint8_t dawn_hour;
  uint8_t dawn_min;
__attribute__((packed)) ;

struct transmit_lcdX transmit_lcd;

 

//Sends out struct in binary, with header, length info and checksum
void ICACHE_FLASH_ATTR EasyTransfer_sendData( uint8_t *bfr, uint8_t size){
    static uint8_t buf[40];
    uint8_t CS;
    CS = size;
    buf[0]=0x06;
    buf[1]=0x85;
    buf[2]=CS;
    for(int i = 0; i<size; i++){
        CS^=*(bfr+i);
        buf[i+3]=*(bfr+i);
    }
    buf[size+3]=CS;
    uart0_tx_buffer(buf,size+4);
}

Note the two additions in BOLD above – if either is missing – this does NOT work. 

So now, if you have some legacy stuff on an Arduino and you need to pass a struct back to it using EasyTransfer – you can. 

Facebooktwittergoogle_pluspinterestlinkedin

ESP8266 Arduino NetIO Server Demo

MIT

This week as regular readers know I was far away from our little home in Spain – in fact I was at MIT (Massachusetts Institute of Technology)  in Boston, helping promote ESP8266 technology (why? because I could).

IvanAlong the way I met up with Ivan Grokhotkov who as some of you know has done a lot of work to bring the Arduino environment to the ESP8266 community.  As part of what we were doing at MIT, Ivan and I decided to put together a simple demonstration – this would use NETIO (my favourite IOS/Android visual interface) and ESP8266-Arduino to help an ESP board drive a servo via wireless control. 

As it happens any old ESP board would do – an ESP-01 would be just as easy, however both there in America and here in Spain I just happen to have the NodeMCU boards handy and so this short blog will show this in action using pin D5 on the NodeMCU – but there is nothing clever about these boards – if you have something different, use it.

NETIO – so firstly what is NETIO? It is a very inexpensive APP for IOS/Android with a free visual web interface – I’ve discussed it before in here with examples. Essentially you create a free account at http://netio.davideickhoff.de/en/ and having logged in, you go to the online design editor and put together your dream interface. In this case a simple slider to control a solenoid will do – but more of that in a moment. You then sync your phone to the account and the control page becomes available to your device. The point being it is just SO easy to make pretty interfaces.

ESP8266/Arduino – this is a free add-in for the Arduino environment (which in turn is also free) to allow you to compile C++ code for the ESP8266 chips – just as easily as if you were using an Arduino. Indeed with the nodeMCU board you simply plug it into USB, fire up the environment, fire up an example – and you are up and running. I believe the forthcoming (Kickstarter) node.IT boards will be similarly easy to use.

In my case I firstly downloaded the standard Arduino 1.6.5 environment to my Windows PC – I then followed the instructions on Ivan’s GitHub page – everything you need to know is included in his readme file so I’ll just take you straight there. github.com/esp8266/Arduino

The example Ivan put together to control a servo is here. https://gist.github.com/igrr/9ef4d5c74355503e3b1f

The only thing you have to do to run this sketch is to put in the name and password of your router. Running the program and using the Arduino serial monitor yielded (in my case) this…

Image635745760775013702

As you can see the little board immediately connected to my router which gave it the address of 192.168.1.24 – this actual address will vary from system to system.

The demo program sets up a trivial web server which will work as follows: In a browser I typed http://192.168.1.24 and here’s what appeared in the browser…

browser

Check out the example code and you’ll see where this comes from.  The next step is to add an argument to that URL – so let’s try http://192.168.1.24/servo?value=120 (remember you likely won’t get that actual address)

browser2

You can see that the value has been extracted and passed back to the browser – meanwhile in the serial window…

debug

What you don’t see is that on pin D5 of the ESP8266, a constant pulse is being sent out and this pulse WIDTH has been altered. Values 0-180 work and turn the servo from 0-180 degrees.

It REALLY is that simple to drive a servo – in my case the 3-wire DIRT CHEAP servo is a Turnigy TG9e with 3 wires – ground, power (3v3 in my case) and signal (D5 – but doesn’t have to be that pin).

So by firing the argument (value 0-179) as above to that address I can control the servo – how about doing this remotely via a mobile – for now we’ll assume internal addresses so this would only work within the area covered by the router… but I’m sure you’ve already considered world-wide servo domination.

The image below pretty much covers it – in the web browser I dropped a slider into the NETIO main screen.

netio

The only thing missing here is the code for the slider. Click on the slider and…

netio2

(I’m pretty sure I should have made that max value 179 but whatever… it works) So I have set the slider to emit code /servo?value={value} where {value} gets replaced by the actual slider position as you run the app and move the slider around – add that to the address in the main panel and you have exactly the same result as we saw higher up this blog entering the value into a browser manually. Hence… here I am moving the slider around on my Android phone – the result in the debug serial window is:

slider

And as this happens the actual servo is rotating back and forth up to 180 degrees. Whether this powers a piece of paper or a ton of concrete is down to the servo!!!

This is of course trivial – the same APP could control a whole HOST of sliders and the ESP8266 code could perform all sorts of transforms on that data – an ESP8266 spider could be fun (I got that idea from the giant cockroach which appeared on the floor while we were experimenting at MIT)! A nice addition to that code might be a timing arrangement to smooth the value change as moving your finger across a phone tends to produce slightly jerky results.  If you were using this for a window opener or other visual toy…..

When I get a minute I’ll do a video of this for YouTube – in terms of development, if you have everything to hand you could have this all running from scratch within 10 minutes, it is that easy.

My thanks to Ivan for bringing the ESP8266-Arduino environment to my attention – I talked about this ages ago when it was new but at the time was not that impressed – today – hell yes this is a very easy way to get quick results with ESP8266. If you have any code issues, Ivan is really approachable.

 

servo

That’s it for now. Just back from the states to our little village and I’m thinking a pint is in order..

Facebooktwittergoogle_pluspinterestlinkedin