Category Archives: Hackitt & Bodgitt

Arduino Peripheral for HC2016

As many of you know, I don’t have a great deal of time for Arduino – I cannot tell you how many months I wasted on those daft cheap Ethernet boards for them which never really worked reliably no matter what I did – so I probably have a mental block by now.

However, there can be no arguing that a board costing £1.28 inc. postage has to be worth at least a second look. The picture below shows where this all fits into the scheme of things…

Home Control 2016

And so it was today, I’d just finished putting some polishing touches on the I2c code, fresh from having gotten the BMP280 working – and I was looking at A/D boards to add to the arsenal when I remembered that Arduinos have A/D in… not stunningly high definition but good enough for checking batteries and light levels etc.

Nano[6]At that point, mid-coffee I remembered I’d bought one of these little critters from AliExpress. Be careful – not all of these bring A4 and A5 out, some have micro-usb connectors, others don’t. Some have 3v3 regulators, some don’t.  I find the most useful ones just have the FTDI connector on them and no USB – but then I have FTDI connectors coming out of my ears.

For the purposes of this item – a 3v3 regulator is not needed as presumably if you’re fastening I2c devices to the ESP8266, you’ll feed 3v3 to the whole lot. Anyway, use whichever suits you best. I’m also assuming pullups are in place – the Arduino has pullups but I doubt they are strong enough.

SO – the point of this is – it is quite easy to make an Arduino into an I2c slave – so for £1.28 you can make a port extender, more inputs, some analog inputs, PWM outputs – just about anything really as long as whatever it is doing doesn’t take up any time as the board needs to respond to I2c commands quickly. I have a MUCH more powerful device on the way from China with lots more pins etc. but for now, the humble Chinese Nano gets the job.

The simple WIRE library with a little code turns the Nano or similar into a device – I’ve chosen to make it DEVICE 9 by default  – don’t REALLY want to use up ports making that programmable but then because the board has EEPROM I’ve made a hopefully reliable method to store the device number in EEPROM!

In the simplest example, sending I2c commands to this device from the home control software discussed elsewhere in this blog – let’s say to turn output 13 on…

{nano:9,1,13,1}

And indeed that was the very first command I made it respond to as an I2c slave – mainly because on these boards, port 13 has a LED attached to it!!!

Clearly turning it off would be:

{nano:9,1,13,0}

Or how about reading the state of input 10?

{nano:9,2,10}

So here I’ve chosen to create the command nano – command 1 is set ports (2 is read ports)… port is 13, last parameter is 1 or 0 for on or off.  Immediately we have a port expander with several useful ports. For ease, the software I put into the Nano checks to see if the port has already been setup correctly and does that if not – hence avoiding annoying setup code at the ESP end.

With the simplest code and assuming A4 is used as the SCL and A5 is used as SDA, you end up with a “nano i2c peripheral” able to offer (if you get the right board offering A0-A7):

  • 6 8-bit PWM channels
  • 6 8-bit ANALOG inputs
  • 6 DIGITAL INPUTS or OUTPUTS

i.e. ALL of that. You could instead choose to have 18 general purpose I/O lines etc.

I’m sure it would not take most of you too long to figure out ALL SORTS of other configurations but for the sake of this project and this board example– there are ports 2-21 where Arduino A0 is 14. Now,  if your board DOES have A6 and A7, note that they can ONLY be used as analog inputs – they cannot be used as ordinary inputs OR outputs – that’s just a simple feature of the board, not the software.

The point being – they are SO cheap and with this code make good general purpose I2c peripherals – you have to ask yourself – in some cases, why you would use anything else!

So before we start – this will only work for short strings or series of numbers with the standard WIRE library for Arduino – see the blog where I learned the hard way this weekend that WIRE has a 32 byte incoming buffer AND a 32 byte transfer buffer and if you try to send more than that – the Arduino crashes – I’ve updated my WIRE to 128 bytes (so that’s 192 bytes more than before ) and it is working a treat with long strings – the reason I want that is because though you won’t see it in this basic code, I’m now working on running QTECH 160*120 displays in the Arduino peripheral.

I’ve updated the code and here is the current state of affairs – evolving rapidly, for the Nano - expect this to change – again  -  this time tomorrow it will no doubt have changed - again.

 

//
// A simple i2c SLAVE - default device number 9 - reads instructions from
// master and either sets outputs or returns inputs accordingly.
//
// 
#include <Wire.h>
#include <EEPROM.h>

#define MAXPORTS 21
#define ADDR_LOC1 0
#define ADDR_LOC2 1

#define SET_OUTPUT  1
#define READ_INPUT  2
#define READ_INPUT_PULLUP 3
#define SET_PWM     4
#define READ_ANALOG 5
#define SET_ADDRESS 6

byte ports[MAXPORTS];
byte params[6];
byte paramp;
byte retParam;
byte bigcount;
byte device=9;

void setup() {

  byte eeprom1,eeprom2;
  eeprom1=EEPROM.read(ADDR_LOC1); eeprom2=EEPROM.read(ADDR_LOC2); 
  if ((eeprom1^eeprom2)==255) device=eeprom1; // programmable address
  bigcount=0;
  Wire.begin(device);           // join i2c bus with address #9 by default
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent); 
  for (int a=0;a<MAXPORTS;a++) ports[a]=0;
  paramp=0;
  retParam=0;
}

void loop() {}  // not used yet

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {

  Wire.write(retParam); // respond with message of 1 bytes as expected by master
  //Wire.write(34); // respond with message of 1 bytes as expected by master
  //Wire.write(45); // test
  //Wire.write("This is it you know",19);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void receiveEvent(int count) {
int tcount;
tcount=count;
paramp=0;
// no time consuming in here or the routine to send a byte back will be missed.
  while ((tcount--)&&(paramp<128))
   {
    params[paramp++]=Wire.read(); 
   }
  switch (params[0])
    {
    case SET_OUTPUT:
          if (ports[params[1]]!=1) { ports[params[1]]=1; pinMode(params[1],OUTPUT); } 
          digitalWrite(params[1],params[2]? HIGH : LOW); params[0]=0;
          break;
    case READ_INPUT:
          if (ports[params[1]]!=2) { ports[params[1]]=2; pinMode(params[1],INPUT); } 
          retParam=digitalRead(params[1]); params[0]=0;
          break;
    case READ_INPUT_PULLUP:
          if (ports[params[1]]!=3) { ports[params[1]]=3; pinMode(params[1],INPUT_PULLUP); } 
          retParam=digitalRead(params[1]); params[0]=0;
          break;          
    case SET_PWM:
          if (ports[params[1]]!=4) { ports[params[1]]=4; pinMode(params[1],OUTPUT); } 
          analogWrite(params[1],params[2]); params[0]=0;
          break;
    case READ_ANALOG:
          if (ports[params[1]]!=2) { ports[params[1]]=2; pinMode(params[1],INPUT); } 
          retParam=analogRead(params[1]); params[0]=0;
          break;    
    case SET_ADDRESS:
          EEPROM.update(ADDR_LOC1,params[1]); EEPROM.update(ADDR_LOC2,params[1]^255); 
          // update address - will take effect on next powerup of the device as you 
          // can only call "begin" once
          break;      
    default: break;  
    }
}

Facebooktwittergoogle_pluspinterestlinkedin

Blynking Wonderful

As of yesterday, a new release of the Blynk App has been released which makes me want to look at this  again.

Regular readers know that I’m into the idea of using a central controller for home control – so that instead of trying to give every peripheral every feature on the planet, I’ve chosen to use Node-Red on a Raspberry Pi or similar. This has the ability to send emails, send and receive data to and from peripherals and to handle a variety of functions – many as simple as dragging a box onto the screen – yet allows complex programming in the same environment if required.

There are as many ways to fit a UI to Node-Red as there are ways to talk to peripherals – node-red-contrib-ui is one of the leading candidates but you can easily talk to NR via HTTP, web sockets and other drop-in technologies. At one time, NETIO was a great candidate but I’ve not seen that improving for a long time – a shame as there’s a nice visual web editor. Node-Red-Contrib-UI is a very hot contender as it is easy to use but I suspect the sole developer is busy elsewhere right now.

BlynkMeanwhile there is Blynk – available for Android and IOS. The basic principle is that this app talks to a “blynk server” – either theirs or a local copy (a pair of JAR files), which keeps track of changes to devices. The likes of Arduino, ESP and others can talk to the Blynk server via special (and freely available) oftware.   Some time ago a set of nodes was released for Node-Red which would talk to the server and hence the Blynk app – but the nodes were not reliable – I spent ages talking to the author and was about to give up when he adopted a new approach – and suddenly the nodes became super-reliable – no doubt a combination of his work and improvements to the Blynk server.

The designers of Blynk had (I think) always imagined that only their APP would be controlling devices – it didn’t seem to occur to them that there might be people like me using Node-Red to perform all sorts of automation tasks on devices and merely using Blynk as a remote control mechanism. Until now, if changes were made to, say, the state of a relay while the Blynk app was on pause (perhaps the phone was handling emails, the App would not know about this until the user logged out and back in.

And so for some time I gave this a miss. That has all changed now and so it is time to look again.

So – the Blynk server – make sure you have at least Java 8 on whatever device you are running Node-Red on – in my case a Raspberry Pi 2 - http://docs.blynk.cc/#blynk-server

I created the directory  /home/pi/Blynk  and dropped in the server.jar and admin.jar files – and created a text file called server.properties.

The latter file contains nothing more than this.

#web sockets ssl port
ssl.websocket.port=8081
#web sockets plain tcp port
tcp.websocket.port=8082

I chose to give full permissions to the folder Blynk – if someone understands permissions better and would like to suggest a sensible minimum for that  - happy to get feedback You can also put gmail details in here if you want so the server can email you but we’ll leave that for now.

To activate this at powerup I went into a Pi terminal and typed..

crontab –e

As this was the first use of that command on the particular machine – it asked me which editor I’d like to use – sadly you don’t get the choice of Notepad++ on the Pi so I settled for Nano.

At the end of the file I added..

@reboot java -jar /home/pi/Blynk/server.jar -dataFolder /home/pi/Blynk &

and saved the file – and rebooted the Pi. Server now running locally. You can test that with the APP by (in the app) registering with the server.

Finally you need the Node Red nodes from here.

npm install node-red-contrib-blynk-websockets

The connection in the Node-Red-Node will look something like this.. depending on your port setup – and yes you could make it available externally via a port redirect..

ws://127.0.0.1:8082/websocket

and a long ID number you get off the app.

And that, in a nutshell just works – well it works for me. I now have this running on 2 Raspberry PIs and will tomorrow add it to my Orange Pi installation.

Apparently the App will not always be free so I’d be getting yours now while it is! I just hope when they go commercial, they remember all the people who have contributed to getting it this far – oh and GIVE US A SMALLER RGB controller!!

Let’s hope node-red-contrib-UI continues to develop to keep the competition healthy!

Facebooktwittergoogle_pluspinterestlinkedin

Home Control Reliability–Scheduler

HomeThis is a follow-on article from my blog Home Control 2015 which concerns itself with IOT around the home - you might want to read that first.

Many articles on DIY home control tend to scratch the surface and you don’t find out about reliability issues until you’ve wasted many hours building stuff just to discover that the authors never really got into real world subjects like “what happens if the router power-cyles”.

I’ve been working on this stuff for some time now along with my friend Aidan and having installed boards around the place I’m now getting into the “nitty gritty” of reliability.

schedulerSo for example, take my system here at Bedrock (so called because it is actually a real cave in the mountains of Andalusia). I have a Pergola – which has a 12v power system and an ESP8266-based relay board to turn the lights on and off. I also have flood lights around the place and an internal light which are controlled by another board. Finally I have a watering system which fires off twice a day for a few minutes.

My system as you’ll know from the main home control article is based on a Raspberry Pi2 running MQTT and Node-Red talking to ESP-8266 “Hackitt & Bodgitt” boards and of course my own software.

I have a little uninterruptable on the Pi2 and that has tests for WIFI failing and tests for MQTT failing and almost no matter what happens, the system stays up.

After 12 days of perfect operation while I was over in Boston with Espressif, last night the WIFI went off. I had no idea what it was so I power-cycled the router. Still nothing. We sat around for a while and the WIFI came back up – clearly some issue with the service provider.

I noted that it had just turned to DUSK and yet no lights.

And then it twigged. My Node-Red node I wrote called scheduler, sends MQTT messages out at dusk and other times to control the lighting… but of course if the WIFI is not connecting at the time, the opportunity is missed.

Now you could use a number of tricks, the various modes of MQTT include a mode to always get the message through. However I can see issues with that and so last night I did an update to my scheduler.

Instead of sending out commands to turn lights on and off at specific times – like dusk and dawn – I’ve added a checkbox to send the instructions out every minute as to the state that is expected. This is entirely optional, controlled by a tickbox.  But this way, if a message for whatever reason is missed – it will be sent regularly and the recipient units can then be assured of catching up.

Time will tell if this improves reliability – my gut feeling tells me it will. The scheduler is available on BitBucket and obviously requires Node-Red. It is probably the most comprehensive timing mechanism available for Node-Red – I would welcome being proven wrong here.

Facebooktwittergoogle_pluspinterestlinkedin