RS485 Master and Two Slaves, JSON applied and relay attack

By:
Posted: 11th January 2019
Category: Arduino
Comments: 0

Today I have decided to build on top of my previous project. One more slave has been added with a relay that is controlled via a smartphone. JSON has been used as the payload delivery structure to control the events. I did rewrite some of the web server parts so that it has become much more flexible for my future experiments with the arduino platform. Here is the video of the circuit in action (you can read about the technicalities below later if you want):

Now the technical bit...

JSON (library used):

I am able to send commands to both of the slaves with my own totally made up "action code". It consists of three modules:
- node: ID (integer) of the slave which is hardcoded into the code of that each slave and is UNIQUE.
- mod: ID (integer) of the module that the command is being sent to (0: build in LED, 1: relay etc).
- cmd: ID (integer) of the command to execute (0: off, 1: on etc)


Here is an example of a command that I use to enable the relay module on Slave 2:

{'node':'2','mod':'1','cmd':'1'}

When the Master sends the above "message" each of the Slaves picks it up and do the following (in order)
- does the node value match my ID.
- if it does => if the mod value matched to any of the actions I can perform (Slave 1 does not have a relay).
- if it does => perform that action using the cmd value.


In super simple terms this command says that Slave 2 (node 2) needs to enable (cmd 1) the relay (mod 1).

Hopefully you are with me so far. Below is the code I have used in the slave with the relay hardware. As you will obviously notice it does not have any code to control the LED (that is something on Slave 1. And sure, you could standardise this across all slaves but I don't think it would work well in a very diverse environment with many nodes having different hardware attached to it - unless you standardise the hardware, pin numbers that you send commands to etc... could be an idea maybe... hmmm...):

  if (RS485.available())
{
String trigger_val = RS485.readString();
Serial.println("String Received: " + trigger_val);

// Decode Json string !
StaticJsonBuffer<60> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(trigger_val);

// Test if parsing succeeds.
if (!root.success())
{
Serial.println("parse failed - ignoring packet !");
}
else
{
// Else Everything is ok and it has managed to parse the JSON string !!
// Fetch values.
int node_val = root["node"];
int mod_val = root["mod"];
int cmd_val = root["cmd"];

// First check if the message was sent to this node...
if (node_val == thisNodeID) // thisNodeId = 2 (declared above the scope of this snippet of code)
{

// Once we are here it means that the message was designed to reach this node => Do the checks !
if (mod_val == 1) // relay control
{
switch (cmd_val)
{
case 0: // switch relay off
Serial.println("Relay OFF");
digitalWrite(CH1, LOW);
break;
case 1: // switch relay on
Serial.println("Relay ON");
digitalWrite(CH1, HIGH);
break;
}
}

if (mod_val == 2) // relay MAD MODE !!!
{

switch (cmd_val)
{
case 0: // super fast switching
// just in case it was on by any chance !
digitalWrite(CH1, LOW);
delay(10);
for (int i=0; i <= 20; i++)
{
digitalWrite(CH1, HIGH);
delay(10);
digitalWrite(CH1, LOW);
delay(10);
}
break;
case 1: // slow on and off !
// just in case it was on by any chance !
digitalWrite(CH1, LOW);
delay(50);
for (int i=0; i <= 4; i++)
{
digitalWrite(CH1, HIGH);
delay(400);
digitalWrite(CH1, LOW);
delay(400);
}
break;
}
}

} // Node ID check end !

} // else end !!
}

This per slave implementation approach can give you quite a bit of flexibility at the expense of extra few hours of work. I am sure you have watched the video by now and seen how this all interacts with each other. I had few things go totally south as I struggled to find a proper manual how to wire up the RS485. So if I did get something wrong do let me know - happy to learn. I did also use the delay function in the slave and master just as a quick hack - it will need to be replaced with some sort of mills timer instead (or similar). Will do it another time maybe...
The main thing was to demonstrate that with a little bit a creativity anyone can create their own "protocol" that will be used for the devices to communicate.


Master:

Since the actual commands are coming from the web server (I am thinking to maybe clean it up and upload it on github..... very loose idea) the Master does not do much work really. It just receives the UDP packet from the network -> checks if it is a valid json payload (I could add some validation function to check if it does match my structure requirements I guess) -> sends it on the RS485 link for the Slaves to act on. It is the least complex part of this project really. However... since it is just an RS485 it is possible to make slaves send commands to each other when certain events occur + maybe send feedback to the master if the slaves have actually received the command that was sent.... If there will be demand (highly doubt that) I will compress the sketches for this project and provide a link here to download.

One more thing to note tho. In the video I have demonstrated two ways how to send a command to the slaves. At 0:27 I launch a command that sends several UDP packets from the web server and you can notice that the "circuit" is working rather slowly (led on -> 2 second delay, relay on-> 2 second delay etc). If I try to decrease the delay between packets being sent the circuit does not cope well (ethernet shield ability to process packets fast enough + arduino speed maybe are not sufficient for that). Hence a better solution is to implement the "command sequence" in the slave itself. This is shown in the code above and you can observe this at 0:43 of the video. You send one UDP packet and the set of commands are executed locally on the slave with the speed of your desire.

Hope this helps a little and good luck!

Hey, like this? Why not share it with a buddy?