Friday Morning ESP8266

div class=”mycode” style=”color:blue; margin-left: 40px;”>

ESP8266This morning I saw a note from a Mr Steve Brown who pointed out this link for a little add-on board for the ESP-01. Our friends in America might be interested at $1.59 but sadly for the rest of the world the postage kills this one – $13+ to the UK – what WERE they thinking? I think this suffers in a couple of ways, firstly I don’t understand why 2 boards and also while it’s great to see a meaty 800ma regulator, there isn’t enough copper to let you run that at 800ma unless the input voltage is quite low..  what I would REALLY like to see is a low cost motherboard that contains a 3v3 regulator and level shifters on serial in and reset so that the ESP-01 board becomes usable on 5v systems without bodging. A little further down the line I can see a session with EAGLE PCB coming on.

10:38AM – Updates for you: Nothing new on the Frankenstein front, I asked Espressif about Windows based development and they just sent me a one-liner pointing me to the VM version – which unless you’re a Linux hack is a real nightmare and throws out error messages which mean nothing to most of us. As for the original web server, nothing new there to report, it’s still not picking up routers. 

On the LUA front – this wonderful high level language is coming along, the board will now perform trivial tasks like adding two numbers together – however the example of running a Telnet session falls over immediately and the web page example resets the ESP-01 board after 5 or 6 retries… so we’ve a little way to go.  He’s even put up a new version of the Telnet code and that won’t even load in without killing the interpreter.

However the latest attempt at a web server DOES work. Here’s the code – I loaded it in – pointed a web browser to it and it does work. Someone more advanced with LUA might want to offer a suggestion as to how to alter this so it ONLY returns any GET information – and only once as browsers tend to send several attempts..

srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
conn:on(“receive”,function(conn,payload)
   print(payload) print(node.heap())
   conn:send(“<h1> Hello there</h1>This is a test”)
   end)
conn:on(“sent”,function(conn) conn:close() end)
end)

 

No other updates for that this morning and I did write into here to detail what’s going wrong with the LUA code. I’m hoping we might see a fix over the weekend – but that’s just a hope. I guess what really excites me about the LUA option is the possibility to develop code for the board without having to worry about that whole convoluted compile/link/Linux/GCC process – maybe I’m dreaming…

I think part of the problem is that some of the developers, Expressif etc are Chinese and while that’s not a problem in itself it is really hard for some of us to get a dialog going with them – I get very short answers from Espressif and get the distinct feeling no-one understands my emails – though they are trying to improve the firmware.

Daver Allan's hacked ESP-01Hacks: A friend of mine, Dave Allan (who has been helping me with testing) has been working on hacking the ESP-01 to get back some valuable pins – oh yes, you can!! Mind you we’re talking accurate soldering but if you’re desperate for some I/O, just to prove it can be done.. here’s the picture. Please DON’T write in if you burn up your board!

When I find out more – I’ll be sure to write in here. For now… it’s winter in the UK and one of my little radio boards which controls the heating has given up and died. I was hoping by now to have a WIFI alternative – but I think we’re a little way off that. Time to get the soldering iron out (elsewhere on this blogsite I have details my home control efforts spanning quite some time now).

08:54AM – Got some feedback this morning indicating that there is a new tool (Python) for uploading scripts to the LUA interpreter… not used it as I find Cool Terminal does that easily for me – but it’s probably worth making a note of for those of you for whatever reason can’t or don’t want to use the latter.

Just to be clear on the pins – a zoom below..

Pete.

Comments from Dave:   For those of you with good soldering skills and a steady hand I’ve developed a system to give you 4 extra gpio pins that are on a firm socket rather than hanging wires off the pins. It consists of removing the existing pins (pcb), replacing the 2 rows of 4 pins with 2 rows of 7 pins. Remove the 5th pin on both rows and solder the 2 rows in with the extra pins to the left.
Next solder fine wire from these extra pins to pins 9,10,12,13.

The extra pins are GPIO14, GPIO12, GPIO13 and GPIO15.

You can now plug this into a 14 pin IDC socket or any other of your choosing.

See the attached photo.

I accept no responsibility for your lack of skill if you screw the board 😆

Zoomed ESP-01

Advertisements

Radio Remote Decoding

This article is about decoding radio remote controls using Arduino or similar hardware and a cheap 433Mhz radio receiver (£2 on Ebay) and was written to serve a purpose: NONE of the existing libraries I could find out there managed to detect all of my radio remote controls.

Cheap radio remotesI’m interested in adding radio remote for mains control to my house control system which is basically an Atmel 1284 chip with Ethernet and radio network.  Although it is easy to make a remote switching unit that will be part of a network and control mains lights, it is overkill and it is also quite difficult to find dirt cheap mains to 5v supplies to go into one of the limited range of plug-in-the-wall project boxes along with a controller and a relay.

With that in mind I started to look at the many mains switch remotes available out there. These generally work using simple 433Mhz radio receivers and accepting a code which could be almost any length but is normally somewhere between 10 bits and 50 bits.. the encoding techniques vary. Generally speaking these do not use any kind of “rotating” encoding for security and simply use a block of data, repeated as long as you hold the remote button.

BUYER BEWARE: If you want to control lighting using plug-in-the-wall 433Mhz controllers you should be aware of two things…

[a] the cheap controllers you find in the likes of B&Q use a single frequency which is EASILY blocked by other, similar transmitters.  I found when experimenting with a radio link at 433Mhz that it was easily blocked just by holding a button down on a mains remote controller.

[b] I found a nice cheap set of these plug-in-the-wall mains switches at ALDI recently, 3 remotes and a handset for £10 – what a bargain – but then looking at the fine print – you “train” them by turning them on and pressing a handset button within a few seconds – and that’s fine.. but, I thought, what about power cuts? Sure enough – you have to re-train them every time. What idiot came up with that brilliant idea? Going around the house re-training remotes every time the power fails? Surely not?  But I tested them and that is how they work. They are boxed up ready to be returned – not “fit for purpose”. That is, to be fair, the first time I’ve come across this but if you order online – beware!

ReceiverOk, so what could be difficult the handset lets out a 433Mhz modulated signal when a button is pressed – and the mains blocks pick up this signal, decode it and turn the plug on or off – so all you have to do is read the signal coming off the handset and use Arduino (or PIC etc) existing libraries to record and play back, right? Wrong – I had at least two handsets that use a code which was so long the existing learning libraries could not handle them AT ALL.

Eventually after much reading and learning I decided to do my own thing.

Scope with noise from radio receiverSo, easy enough, (both the transmitter and receiver which I’ve linked to below have ground, power and signal leads – nothing else – the receiver appears to have two signal leads but they are connected together – you need only use either one) assuming the output of the simple receiver is LOW on standby, press the remote and look for the start bit – capture the length of each change of state until the end?  Right?

Well, no… the package is sent over and over – so you have to look for gaps between packages. Easy? Well yes except for AGC – automatic gain control. When the receivers are receiving “nothing” they get more sensitive and in my office the spikes coming out of the output were horrendous. I tried ignoring narrow pulses with limited results then I twigged.. if you run the remote control near the receiver – the noise goes away as the AGC (automatic gain control) kicks in…

433Mhz transmitterSo – press the remote control button – THEN start scanning – and store the gaps between pulses – say, 300 of them.  I did this with some REALLY simple code looking for high and low using the micros() function in Arduino (millis() is way too course) and keeping the code tight by simply storing the actual value of MICROS() in a long array.. ok not efficient but for temporary storage it works and I can get consistent results.

I discovered that all the controls send repeated packages with a short absence of signal in-between. Given the noise issue, the first package often gets scrambled – the breakthrough came when analysing the stored values and realising the solution is to search for the first repeat – i.e. after the first BREAK –hence ignoring the first package – previous attempts to use that had yielded varying results at the start of the package. By the time the second package kicks in the AGC has adjusted and the noise has all but gone.

So this would give me an output like this typical one from a handset.

tmpBFEC

They vary of course in length (not from key to key in that case just the order of bits varies) but from handset manufacture to another model or manufacturer).

What I did notice were pairs of zeros… ie pulses twice the width of others. On reading up this is called Manchester coding (or a variation) – I chose to ignore this – but knowing there will never be more than TWO different pulse widths helps a lot… in reality I realise that there is only one period in this type of encoding.. see this for pictures and explanation if you are interested. http://en.wikipedia.org/wiki/Manchester_code

As you can see from that link, the clock and data are encoded into the one signal.

But for my purposes it’s really NOT important to either understand or use this knowledge. All that is necessary is to send that stream out – fixed width per pulse as per the original and if there are two identical adjascent values (ie 00 or 11, detected by longer and shorter pulses compared to a fixed value indicated by the first pulse) then obviously you simply send the status quo to the output bit for twice the length of time.

But this uses up a lot of storage.  Looking at various handsets I discovered the largest signal seems to be around 40 or so bits… I made up a 12-byte array and wrote a routine to bit-shift the entire array by one bit – hence allowing me to convert the string above to a more sensible set of bytes.

image

In addition I added a byte at the start which represents the width of the basic pulse – as this could be as high as 1200us, I divided this by 10 to fit into a byte. In the example below you see 33 added to the start – ie 330us pulse width. On experimenting, that slight loss of accuracy seems unimportant and it saves a byte.

tmp4A7F

And so for any given button – we now have 11 bytes (in this case) to encode it. I decided that was GOOD ENOUGH.  A little routine to read from the end backwards, sending out pulses (or no pulse) for the duration specified in the first byte – VOILA I was accurately switching mains lamps on and off via my cheap transmitter.

Most of the code is unique, some bits are variations on stuff I found on the web (thanks to all who’ve taken the time to put their ideas up on the web) – and is provided here UTTERLY without support – no comments on styling please – if you’re having trouble reading radio remotes for your purpose – I hope this is useful.

The transmitter and receiver are here

http://www.ebay.co.uk/itm/433Mhz-RF-Wireless-Transmitter-Receiver-Set-NEW-/131093418464?pt=UK_BOI_Electrical_Components_Supplies_ET&hash=item1e85c6d1e0

Change input and output pins to suit your project – any pin will do, if you get nothing having pressed your remote then sent A to the board via the Arduino serial monitor, then try messing with INTER_CMS-MS and MIN_POS_WIDTH but I suggest not before you do that, you check with a scope that something is actually coming in.

Clearly in any end gadget you make for your use, you’d not include the learning part or it’s huge TBUFF array. When I get a minute I plan to come up with a means to simply store the data in EEPROM and read from that…  mind you – if you use a 1284 chip instead of the old 328, memory isn’t quite the problem.

If you need more range, you could consider putting the transmitter (NOT the receiver) on a higher voltage up to 12v. I tested mine at 12v and the signal from the 5v logic still worked perfectly. The increase in range is noticeable – I’d say 50% better coverage.  If you blow up your board however, that’s your responsibility – don’t come back to me…

This is all suitable for short bursts to control stuff – don’t get any ideas about continuous home control signalling unless you can guarantee there are no other 433Mhz transmitters in use! I went down this route before realising it’s a non-starter and am now looking at the slightly more expensive frequency hopping chips for more sophisticated use – but if all you want to do is turn something on and off – this could be for you.

 

// I used a simple 433Mhz tx and RX pair - 1 pin each needed. Output of radio assumed 1 when something there ie active high
// No interrupts or clever tricks used
// Using F() in strings merely to keep RAM down, and PROGMEM for arrays - that's the data you see on the serial display for one particular button press... 
// Could store this in EEPROM or whatever... for now could get a lot of these for a particular application into ROM without using up precious RAM
// None of the PROGMEM stuff is essential - just there to minimise RAM use
// Coding Peter Scargill June 2014. www.scargill.net

#define PIN_DATA_IN 2
#define PIN_DATA_OUT 11
#define SERIAL_SPEED 115200
#define INTER_CMD_MS 100
#define CMD_REPEATS 5
#define COMPRESSED_ARRAY 12 // assume that's enough
#define MIN_POS_WIDTH 200 // used before we have the period - assumed minimum acceptable PERIOD less than which we ignore - in Microseconds
#define MAX_NEG_WIDTH 2000 // assumed maximum acceptable ZERO state in uS above which is assumed a gap between blocks of data
#define READINGS 300 // For temporary storage while learning, need 4 bytes per reading... so WATCH OUT - 328 only has 2k of RAM
#define TIMEOUT_VALUE 3000000 // Number of microseconds before we give up the ghost - ie 3 seconds - likely won't happen due to noise

// Byron reports 39us*10 for period - didn't work - so I put in 59 - works a treat.

const byte g0[]PROGMEM={59,77,211,36,73,146,52,73,210,52,1}; // Byron D2on
const byte g1[]PROGMEM={59,217,150,109,217,178,45,91,18};
const byte g2[]PROGMEM={59,219,182,109,217,178,45,91,18};

byte tbuf;

byte arr[12];

// Used to set a timeout
unsigned long start_time;
unsigned long timeout;
unsigned long current_time;

unsigned long calc;

// Stores all the values read here
unsigned long readings[READINGS];
int current_reading = 0;

// Collect serial data into an array - or timeout as you prefer
void readRadioPulses()
{
    for (int a=0;a<COMPRESSED_ARRAY;a++) arr[a]=0; // wipe the eventual storage array
    for ( current_reading = 0;  current_reading <READINGS; current_reading++) // store enough values for 2 or more packages - as long values for speed
    {
        // Waits until the input goes HIGH 
            while (!digitalRead(PIN_DATA_IN))
            {
                if (micros() > timeout) return;
            }
        // When the first value comes, save that period
        readings[current_reading] = micros();
        digitalWrite(13, HIGH);
        // Wait until the input goes low

            while (digitalRead(PIN_DATA_IN))
            {
                if (micros() > timeout) return;
            }
        current_reading++;
        readings[current_reading] = micros();
    }
}

void shiftArray(int x) // move the entire array toward the highest offset by 1 bit and add least new significant bit to offset 0
{
  for (int a=sizeof(arr)-1; a>0;a--)
    {
      arr[a]<<=1; arr[a]|=(arr[a-1]&128)>>7; 
    } 
  arr[0]<<=1; arr[0]|=x;
}

// Sends the data to the serial port
void displayRadioPulses()
{
  int speed;
  byte pickone=0;
 
  for ( current_reading = 0;  current_reading < (sizeof(readings)-1); current_reading++)
    {    
      calc=readings[current_reading+1]-readings[current_reading]; 
      if (((current_reading&1)==0)&&(calc<MIN_POS_WIDTH)) { current_reading++; continue; }      
      if ((calc>MAX_NEG_WIDTH) &&((current_reading&1)==1)) { pickone++; if (pickone==1) speed=readings[current_reading+2]-readings[current_reading+1]; }
      if (pickone==1) // extract string here
          {
          if ((current_reading&1)==0) 
              { 
              if (calc>(speed+(speed/2))) 
                    {
                    Serial.print("1"); shiftArray(1);
                    }
                Serial.print("1"); shiftArray(1);
              } 
              else 
              {
                if (calc>(speed+(speed/2))) 
                  {
                    Serial.print("0"); shiftArray(0);
                  }
                  Serial.print("0");  shiftArray(0);              
              } 
          }
    }
  Serial.println(""); 
  Serial.print(speed/10); Serial.print(",");
  for (int a=0;a<sizeof(arr);a++) { if (arr[a]) { Serial.print(arr[a]); if (a<(sizeof(arr)-3)) Serial.print(",");  } }  Serial.println("");
}

void sendRadio(const byte *m, int sz) // can't do sizeof a PROGMEM array so just pass the size
{
   int scount;
   int offs;
   int period;
   byte tmp;
   period=(int)pgm_read_byte(m)*10; // get the first value, multiply by 10 and that is your period
   for (scount=0;scount<CMD_REPEATS;scount++)
     {         
       for (offs=sz-1;offs>0;offs--) // start at the end and work backwards not including offset zero which is the (period/10)
          {
          tmp=pgm_read_byte(m+offs); Serial.print(".");
           for (int r=0;r<8;r++) { if (tmp&128) digitalWrite(PIN_DATA_OUT,HIGH); else digitalWrite(PIN_DATA_OUT,LOW); start_time=micros()+period; while (start_time>micros()); tmp<<=1; }
          } 
          Serial.println("");
        digitalWrite(PIN_DATA_OUT,LOW); delay(INTER_CMD_MS);
     } 
}

// Listens to SERIAL for inputs A=read, B=write demo - when reading press and hold handset FIRST
void SerialRequest()
{
   char c;
   while (Serial.available()==0);
   c=Serial.read();
    if (c=='A')
      {
        start_time = micros();
        timeout = start_time+TIMEOUT_VALUE;
        readRadioPulses();
        displayRadioPulses();
        Serial.flush();
      }
      
      if (c=='B') // try the example compressed code which includes (period/10) as first byte - can be any length
      {
       sendRadio(g0,sizeof(g0));
      } 

     if (c=='C') // toggle 2 codes back and forth for range testing
      {
       Serial.print(F("Test toggling..."));
       for (int a=0;a<200;a++)
       {
         sendRadio(g1,sizeof(g1));
         delay(1000);
         sendRadio(g2,sizeof(g2));
         delay(1000);
       }
       Serial.println(F("Done"));
      } 
}

void setup() // set serial speed, set output for the radio output - and put something on screen to show it's working - use built-in F() to save RAM
{
    Serial.begin(SERIAL_SPEED);    
    pinMode(PIN_DATA_OUT, OUTPUT);    
    digitalWrite(PIN_DATA_OUT, LOW);
    Serial.println(F("Send A to check or B to send example in PROGMEM"));
}

void loop() 
{
    SerialRequest(); // I could have just put the lot in here really
}

Home Control 3

This article is about home control – specifically controlling devices and reading sensors via the Internet – for example using a mobile phone – and internally via much lower cost short range radio boards. As it’s been a while since I did a write-up you could be forgiven for thinking the home control has gone off the boil. Nothing could be further from the truth.

A quick glance at the image below will confirm it’s coming along quite nicely. So – what’s new? Well, I quickly tired of struggling with space in the Atmega328p chips and moved onto the ATMEGA1284p chip. Why? Well, it’s still DIP so easy to work with, it is cheap, code-compatible, has lots of pins and is supported by Arduino (though all I’m using is the chip – fitted with the Optiboot loader). While the very cheap Ethercard boards were looking the favourite for a while, again a burst of common sense hit me – there’s only one in the system, it’s worth a couple of pounds more to have hassle-free operation – and I’m getting hassle-free operation. The ENCJ chips are just too much like hard work and using them with socket libraries just seems like asking for trouble.

I put some indicators on the master board to indicate flow of Ethernet data and radio data but got side-tracked when fretting about the number of wires it would take to wire up an LCD – I just happened to have one of the NANO boards available from China for around £3 I decided to stick one of those on the back of the LCD and make a general purpose LCD driver board. On the 16*2 boards it’s even possible to run the contrast and brilliance straight off the 328 – not so easy with larger boards due to greater power consumption – but works a treat for the former. Anyway to cut a long story short that little project is about to appear on Kickstarter as I decided to make the board do a whole lot more than just drive an LCD – and all off serial. It handles infra-red, de-bounced inputs, temperature sensing and far more. The board we’re working on right now will simply slot onto the back of a standard LCD board and you’re up and running.  More on that later, just waiting for prototype PTH boards to appear.

I looked at various mobile software solutions for this project but none of them visually hold a candle to what you can do with NETIO and so stuck with that.

The slave boards and again we had some proper boards made for these – come with 8 SMD LED indicators on for OUTPUTS, PWM OUT and a general purpose indicator – only recently did I discover the serially addressable RGB LEDS and in future boards I’ll use these as they only take one port bit to run the lot – no matter how many you use and the colour variations could be exceedingly useful. I’m still using RF24NETWORK, despite the poor range of the radio boards it is possible to create a network to expand that range. We are however looking to the more complex chips which include radio as these have far better range and yet can still be cheap in quantity – watch this space for an exciting development in that area.

At the time of writing – all is working well – I have two installations, one in Spain and one in the UK… and I’ve learned a LOT about programming Atmel chips and how to use Atmel Studio for debugging – which though I’ve no intention of becoming a “pro bore” like some guys I’ve seen in forums – Studio IS infinitely better than using the Arduino IDE… and as it is free – one has to ask – why not. More later on this one…

So below you see the current setup – way beyond my original wildest dreams but set to get a lot better. The Master board talks to Ethernet and takes in commands that way… it also talks via Ethernet to time servers to get the exact time- and given longitude and latitude figures up what time is lighting up time and dawn and offers this information to the slaves so that they can for example turn lights on and off accordingly rather than just straight on-off. Slave software includes the ability to read temperature and humidity from a variety of sensors as well as offer PWM output for LED strips.

Scargill's Home Control

So there you have it – working home control at low cost. While full Arduino boards can be expensive, DIY boards cost very little – ATMEGA328 chips can be had for a couple of pounds and the ATMEGA1284 for not much more.

Home Control Update

1284p main board with LCD panel up front

Just a quick update on the home control… the slaves are about as good as they can get – I’ve added memory for the state of the 3 PWM outputs and ALLOFF and ALLON commands so that one can set the brilliance of, say a 3-colour LED strip – and then turn the lights on and off accordingly. At some point I’ll put a global fader on all 3 colours….

I’ve switched my attention now to the master board. I was using a MEGA, having long since given up on the 328 due to constantly running out of memory. I had a few 1284p chips lying around – in case you don’t know these are the largest Arduino-type chips you can get in DIP format – 40 pins – and they have one great feature – 16K of RAM which means you can forget about penny-pinching RAM.  Accordingly – I’ve added SD logging – and just now for the sake of it, an LCD display. I’m using the new LCD library that lets you use an LCD module with a 74HC595 shift register on the back (on veroboard) to reduce the pins needed to talk to the processor down to 2 (clock and data). 

As you can see above, the LCD is echoing the Ethernet commands as they come in (and quickly too) and over on the left is the micro-SD card plugged into the Ethernet card…. which is also supplying the 3v3 to the radio board. All in all very few components – took me an hour or so to put this lot together and twice as long to remember how to use the various libraries.

All working well, not sure if there’s a REAL use for the LCD – I also have a 4-line version of that… overall current for the board is around 300ma – or 1.3 watts – that won’t break the bank running all the time and it should run off a standard USB plug-in-the-wall.

The next challenge is a box.  I have to say, it’s all working very well – once again for pinouts etc I keep referring back to ManicBug’s various articles.

Arduino Home Control Part 1

Background
A little background before I launch into a project I’m working on..

In the closing decades of the last century, just as the Internet age was about to start, I was one of two directors in a small company who innovated in electronics – we did it in a variety of ways, some projects were successful, some before their time and just occasionally came the odd project that was not completely thought out.

Home Control last-century style
Home control fell into the latter category. We were into using the PIC chips (from Microchip) at the time and we ended up with a bee in our bonnet about home control – wouldn’t it be nice to have little boards all over the house controlling stuff.  We developed the product before too deeply considering the market – but what a product it was for a time.

Essentially a small board with a PIC, a TRIAC output (for controlling lights and heaters – and yes we could handle compact florescent lamps without issue thanks to a VDR), a digital temperature sensor (Dallas), a couple of inputs and a simply transistor switch to control PWM sound output. The board was smaller than a pack of cigarettes, cheap, ran on 12v and had a unique ID number.  We could connect maybe 128 of these along a 4-core telephone wire (normal white twisted pair stuff commonly in use today).  We could manage maybe 100 metres.  At the end we had a little board which provided 12v power and interfaced by RS232 with a PC. A program on the PC showed a plan of the house and the boards showed as little coloured block superimposed on the map of the house. The colours changed depending on the input and output status of the boards in real time – and you could write a set of rules to control what the boards did. The 4th wire ran simple PWM sound from the PC speaker around and a transistor could be programmed on any board to turn on – hence enabling sound routing to any board.

Application Control
We called the system “Appcon” which immediately got us into trouble with someone in the apparel industry and we had to promise not sell competing products!! To give you an idea of how incredibly powerful this system was, in my home which had 40+ of these units, I had wall-mounted PIR movement sensors hooked to inputs, heating, lighting and alarm hooked to outputs as well as door magnetic sensors.

I could route cricket or bird sounds to speakers in the garden, I could detect open doors and turn the heating up depending on the time of year, with a closed switch I could enable an alarm system (all done by rules using nothing more than the basic devices and inputs – and my PC) and of course enable PIR triggered yard lighting only during certain hours of the day.

The Automated Home
A magical system and make no mistake, it  was successful in a small-business kind of way, we sold many hundreds of the units, we got in major PC magazines – for example PC-Answers May 1984 – “Wired Tales” heavily featured the system as did many others. We got the hobbyist market and that was it and really there was no way to make a fortune out of this – but we had great fun developing it, making new friends who were equally fanatical about home control – but then the problem was wires…

As I’ve found out in my cottage here in the country – with solid floors and 18-inch thick walls – you just can’t go putting wires all over the place – partners get really fidgety about this stuff.. but then the alternative, inexpensive radio doesn’t work too well through solid walls either and over-the mains control – well that tends to be limiting and expensive.

There are solutions out there today, lots of them, but they have severe limits and are relatively expensive. Somehow the idea of paying £20 to £30 for a board to control a light seems ludicrous to me and the cheaper systems are inflexible to say the least.

Moving ahead 28 years…

I’m into Arduino right now – which is merely a modern-day PIC (well, the PICs are still around and surprisingly little has changed there) and for some time I’ve been thinking of home control – the problem is that wiring just won’t work for me here… and radio modules generally are just too expensive to incorporate into boards – well, unless you want to throw away £30-40 all in just to control a lamp!!

Cheap Radio Solution
I recently discovered the NRF24L01 boards, available from China on Ebay for less than £2 (now THAT’s more like it) and if you’re into Arduino you’ll know that given the chip (the most expensive part and some suppliers really rip people off) you can put together a board for WELL under a tenner.

Line of Sight Radio
Ok, that’s a start, I looked up libraries to handle the radio chip and one, RF24, does a cracking job of one-to-one communication. Sending a small package of data from one device to another reliably is easy with these boards and the library. But we need to be realistic – the range is limited.

My pal and I did some tests a while ago – out in the open – MAYBE 60 metres on a nice day.. we tried the really cheap units and the ones costing 3 times as much with a nice stubby aerial – not that much difference amazingly so we stuck with the cheap units.  What does make a difference is speed – you can run them at up to 2Mbps – but drop that down to 256Kbps – and your range goes up to maybe 80 metres line of sight.

That’s open air – what about indoors? – OH DEAR ME… thick stone walls just about cripple the signal  – in my cottage I can just about manage to get through an 18” thick stone wall, you’re talking 20ft IF YOU ARE LUCKY. In other homes with thin internal walls  I’ve seen 40ft or more. It all depends on wall thickness and materials, on what other radio devices are operating etc. I was about to give up – but then started to think about networking – what if you could bounce the signal around as in networks – cellnet, Internet etc.. I thought I was asking too much of a small, cheap radio but the chips do have the basics of networking in them – they can LISTEN to up to 6 channels at once (but can’t listen AND send at the same time)  – maybe there was a future in this?

Networked NRF24L01?
I scoured the web, lots of half-arsed projects that went no-where and ONE project that looked like a starting point – it’s called RF24NETWORK.  It’s not a true network in so far as plugging in arbitrary units and having them relay stuff all over the place – but it’s a start and enough to make a practical system albeit for those who didn’t utterly fail maths.

I started playing with the library and with examples and had some teething problems – some of the examples would not work on the latest Arduino development environment (IDE) and some of the stuff was not too clear. I wrote to the developer. Nothing. I went to his website and wrote there – nothing. He’s either on holiday, or busy or dead – either way it looks like for now the one and only simple network is unsupported – but the good thing is – it works (there’s a caveat later). I wrote an article on the NRF24L01 and the RF24 library here originally.

Limited Network
I need to clarify… the NRF24L01 chips can listen to 5 other devices at once… that’s it. So how do you make use of that? The way RF24NETWORK code does this is to ask you to regularly call a function on all of your boards – this function transparently handles the networking. You have to number your boards. The boards are numbered in Octal (don’t let that put you off – the designer has used this to make best use of the 5-byte addressing) and Octal in Arduino is expressed with a leading 0. So, to express the Octal “222” you simply preface it with a zero – 0222.

This incredibly easy online convertor makes it all clear. 0222 is 146 in decimal for example. This is irrelevant of course but as this caught me out at first I thought I’d better explain why I’m prefacing numbers with zeros!!

There are numbers, then there are numbers
So, given that the boards can talk to 5 others – it makes sense to build a tree structure – any device can talk to a device further up the tree – and 5 devices below it. Device 1,2,3,4,5 can all talk to device zero (0) – and 0 can talk back to them – directly.  Moving outwards from there involves some hopping – BUT FEAR NOT as the software does that for you automatically – you just have to think about your numbering. In theory such a simple network should be easy to build but I can’t get my head around the acknowledge signals travelling up and down (how can you have unique packet numbering to ensure packets get there – when you can’t talk directly to the root!)… so for now, RF24NETWORK gets the job until someone comes up with a better solution.

It’s getting too complicated
The numbering system is well described in the RF24NETWORK pages so we’ll not go into that here. Suffice it to say you can attach thousands of units together – but I was thinking more of 2-100! I’m sitting here with device 0 talking to device 02 which is acting as a gateway to device 022.

Relax – you don’t need to know any more
So we’re talking hundreds of potential devices. Now it’s important to realise you just need to understand the numbers – nothing else as the networking software handles the rest.

If course all of this is ok but as units can’t talk and listen at the same time – I figured a controller was needed… and then what – you need to DO something with all of this… and I started a series of brainwaves which brings us to where I am now – developing a working home control system based on nothing more than cheap Arduino-type boards.

And that is the end of part 1 – in part 2 we’ll look at putting some meat on the bones – and yes, I’m sitting in front of a basic working system here, this isn’t going to be merely an academic effort – but there are some issues – read on.

See part 2.