Friday 27 July 2018

RS-485 Modbus IoT Gateway using ESP8266 NodeMCU ESP-12E Part 1 of 3

Clockwise from top: USB 3.0 powered hub, RS-485 USB dongle, Arduino RS-485 to TTL module and NodeMCU ESP-12E ESP8266
Many remote devices, especially for industrial use come with the RS-485 serial interface and use the Modbus protocol. These industrial remote devices are often easily converted to IoT devices using for example, an IoT Gateway that also has RS-485 interfaces.

The Schneider PM1200 3-phase Power Meter has an RS-485 interface and would make a great IoT device.

Schneider PM1200 Power Meter


Fuji FRENIC 15KW Inverter

The ESP8266 is incredibly tempting as such  an IoT gateway. It is low-cost, low-power and the WiFi module allows for a much safer non-galvanic, isolated data connection. Similar devices like the monster 10-30KW Inverters used in escalators, cranes, etc can be monitored safely from the cloud this way.

As usual I used a low-cost (RM3.38) Arduino RS-485 to serial TTL module. Now this is a 5V device and since the ESP8266 is strictly a 3.3V device, we should really use a logic level converter, but at a pinch it should work at 3.3V, especially if I powered  it from the ESP-12E.

I also used a modified version of the Trialcommand ESP8255 Master Modbus RTU (RS232) sketch. This in turn use the SoftwareSerial library, which essentially determined the wiring diagram.

RS-485 to 5V TTL module 

MOSFET-based Logic Level Converter

  The wiring diagram (sans level converter) is:

       ESP12-E    RS-485 PCB
            3V3
            GND
            D5 ------- *RE
            D6 ------- DE
            D7 ------- RO
            D8 ------- DI

NodeMCU ESP-12E Pinout

The wiring really makes sense when you look at the MAX485E IC datasheet:

Notice the MAX485E is a half-duplex device
I made a little ribbon cable with Moles 0.1" pitch Molex connectors:

Cable assembly. Right, top: data & control, right bottom: rs-485 power. Left: ESP-12E
When assembled the RS-485 module looked like this:


Download the libraries and copy them into your Arduino IDE libraries folder.

$ls -lt /root/Arduino/libraries
total 16
drwxr-xr-x 4 root  root  4096 Apr 26 20:44 Time-master
-rw-r--r-- 1 root  root    87 Feb 27 07:20 readme.txt
drwxr-xr-x 2 heong users 4096 Mar 15  2017 ModBusMaster232
drwxr-xr-x 3 heong users 4096 Mar 15  2017 SoftwareSerial

Since the ESP8266-Modbus-RTU-Master library uses full duplex TTL RS-232 I put in a tiny patch to convert it to half duplex required by the MAX485E. The file is ./libraries/ModBusMaster232/ModbusMaster232^Cpp and the change is in boldface at line 735:

#define not_RE 14 // D5. Enable receiver, active low
#define DE 12 // D6  Enable Transmitter, active high

  u16CRC = 0xFFFF;
  for (i = 0; i < u8ModbusADUSize; i++)
  {
  //Function  crc16  for ESP8266   - PDAControl
    u16CRC = _crc16_update2(u16CRC, u8ModbusADU[i]);
  }
  u8ModbusADU[u8ModbusADUSize++] = lowByte(u16CRC);
  u8ModbusADU[u8ModbusADUSize++] = highByte(u16CRC);
  u8ModbusADU[u8ModbusADUSize] = 0;

  // transmit request
  digitalWrite(not_RE, HIGH); // cmheong Set max485 to transmit
  digitalWrite(DE, HIGH);
  for (i = 0; i < u8ModbusADUSize; i++)
  {
                swSer.print(char(u8ModbusADU[i]));
                delay(2); // cmheong 2018-07-26
  }
  u16CRC = 0xFFFF;
  for (i = 0; i < u8ModbusADUSize; i++)
  {
  //Function  crc16  for ESP8266   - PDAControl
    u16CRC = _crc16_update2(u16CRC, u8ModbusADU[i]);
  }
  u8ModbusADU[u8ModbusADUSize++] = lowByte(u16CRC);
  u8ModbusADU[u8ModbusADUSize++] = highByte(u16CRC);
  u8ModbusADU[u8ModbusADUSize] = 0;

  // transmit request
  digitalWrite(not_RE, HIGH); // cmheong Set max485 to transmit
  digitalWrite(DE, HIGH);
  for (i = 0; i < u8ModbusADUSize; i++)
  {
                swSer.print(char(u8ModbusADU[i]));
                delay(2); // cmheong 2018-07-26
  }


I modified the Trialcommand sketch (patches in boldface):

#include <ModbusMaster232.h> 
#include <SoftwareSerial.h>  // Modbus RTU pins   D7(13),D8(15)   RX,TX
// MAX485 half duplex control lines
#define not_RE 14 // D5. Enable receiver, active low
#define DE 12 // D6  Enable Transmitter, active high

// Instantiate ModbusMaster object as slave ID 1
  ModbusMaster232 node(1);

void setup()
{
  pinMode(not_RE, OUTPUT);
  pinMode(DE, OUTPUT);
  // default to transmit mode to reduce noise
  digitalWrite(not_RE, HIGH); // disable receiver
  digitalWrite(DE, HIGH); // enable transmitter
  
  Serial.begin(9600);
  delay(100);  
  node.begin(9600);  // Modbus RTU
  delay(100);
  Serial.println("Connected "); 
  Serial.println("Modbus RTU Master Online");
  
}


void loop()
{
//Website http://trialcommand.com
///////// Holding Register [0]  A [9]   = 10 Holding Registers Escritura
///////// Holding Register [0] A [9] = 10 Holding Registers Writing

int Mdelay = 500; // from 5 

node.readDiscreteInputs(0, 1); 
Serial.print("[0] ");
Serial.print(node.getResponseBuffer(0));
node.clearResponseBuffer();
delay(Mdelay);
  
node.writeSingleRegister(0x1001, 0xff); 
delay(Mdelay);
  
}

There you have it: the ESP8266 NodeMCU ESP-12E will now be able to request digital input from the modbus device as well as output to it. Having obtained the data it will now need to relay it to the Internet via its webpage, which will be shown in Part 2.

Happy Trails.

Thursday 5 July 2018

A Long Goodbye for Slackware


I first heard of Linux in the winter of 1995. I was writing a device driver for Microsoft's Windows NT intending to knock it into shape for industrial use. And complaining about the poor quality of the Windows code. Like all the time. I think just to shut me up, my friend (and boss) Wiljan Derks told me about this Finnish student who was writing a UNIX operating system all on his own. He called it Linux, just because his name was Linus Torvalds.

Linus Torvalds 1995 Amsterdam

I escaped on home leave back to balmy Malaysia in February 1996, and there in the sleepy backwater of Ipoh was this book on Linux, 'Slackware Unleashed'. At the back was glued a CDROM with Slackware release 1.1. It was an omen: I bought the only copy immediately.

And it has been Slackware for 22 years From the first install using 12 floppy disks (cdrom drives were hard to find then) on a suitcase-sized Zeos 80486DX2 souped up to a dizzying 66MHz 12MB DRAM to a tiny unassuming Raspberry Pi Zero W blazing along at 1GHz and 512MB.

Patrick Volkerding, Slackware's Benevolent Dictator for Life
Incredibly, through all these years, just like Linux, Slackware is run by one person: Patrick Volkerding.

Initially I ran a number of operating systems: Windows NT, Slackware and SuSE. But by 2004 I dropped Windows, which I had used since 1984. When Novell bought SuSE I dropped that too, and it had only been Slackware since then.

Slackware has always been slow to release new versions. The emphasis has always been stability, which is perfect for me: I had always been using a mainline Linux as an embedded device, and Slackware was a lot less work.

True it required a much bigger footprint, but hardware got better all the time and since elevator projects had a development time of two years anyway, all it needed was a leap of faith: start development immediately using a desktop and bet on the embedded hardware being able to run Slackware by the time I needed it.

Happily, in 14 years Slackware and Moore's Law has not let me down. Slackware progressed from an Advantech Industrial PC to the Via EPIA to the Intel-based fanless boxes with aplomb.

Advantech IPC
Via EPIA
Quanmax Qbox: Intel-based fanless CPU

But then came the ARM-based CPUs like the Beagleboard and the Raspberry Pi. Now a mainline Linux can fit in the palm of your hand.
Beagleboard
Raspberry Pi 3

All this required a fair amount of updates. Despite its manual nature we could cope with Slackware updates, until now: browser vulnerabilities sometimes needed three or more upgrades a year. Browsers like Firefox and Chrome were huge applications and a real pain to upgrade manually, so Debian's siren call beckoned.

When the last two installs of Raspbian went without a hitch, it is time to test my main development laptops on Debian. I started with a spare laptop: an ancient Acer Aspire 5050. Debian 9 'Stretch' installed and ran with great ease. 

Debian 9 'Stretch' on an ancient Acer Aspire 5050

True the speakers did not work and the graphics were slower than my tiny Raspberry Pi Zero W's, but Firefox is up to to the minute, so I think this is the start of Slackware's long goodbye.


On second thought, it is more like au revoir, Slackware.
 



Monday 2 July 2018

Give your old audio amplifiers a new lease of life with this RM11.90 bluetooth audio receiver


Chinese no-name Bluetooth Audio Receiver
Over the years we kept upgrading the living room audio systems: first turntable gave way to the cassette tape deck, which then changed to the CD player, then mp3 player. This resulted in a few orphaned amplifiers and speakers, especially if they have odd impedances like 4 or 6 Ohms.

These days we play most of our music from smartphones; why not convert them to bluetooth speakers? I used this RM11.90 sgrobot bluetooth audio receiver.

Note the LED, resistor and capacitor
It came with some loose parts: an LED, 100 Ohm resistor and an electrolytic capacitor. Somehow it reminded me of excess bluetooth audio receiver modules off a PCB mainboard for a bluetooth speaker or somesuch now sold off cheaply. The IC markings C7THN5004 did not come up on an Internet search; they look like custom markings. Never mind, better this than discarding it in the municipal landfill.

gameinstance.com has a good write-up on it:




I soldered the parts on it; it literally took one minute.


The pinouts are printed on the PCB, but here they are anyway:



3rd pin from top: left speaker, 4th pin: right speaker
I powered it from my trusty D-link USB3 hub, which puts out a whopping 2A at 5V.

To test, I connected it to yet another one of my orphaned PC analog speakers with integrated audio amplifier. I used my Raspberry Pi Zero W with a brand-new version of Raspbian (Debian 'stretch') and omxplayer. It worked without fuss.  It came up as WIN-668 and paired without asking for a PIN.

I had less luck with my Raspberry Pi B+. It had built-in analog and HDMI audio and omxplayer just would not work out of the box. I'm sure that is fixable, but that is another blog post.

As usual, if you can't be bothered with this DIY malarkey, you can buy it ready-made for RM16.90:
RM29: Bluetooth audio receiver. The USB connector is for power only
Once the speakers are bluetooth-enabled, especially combined with the Raspberry Pi Zero W, it becomes and Internet of Things (IoT) device. Now applications like your very own DIY Google Home becomes possible.

Not bad for something one step from the rubbish heap. Happy Trails.