Hi I have one master and ask in loop n slaves for data, for example sensor data, if is button clicked, ...
And for example, when I have info about button, I send same data to slave.
I ask data from slave, and also can send data to slave.
Is this possible do with UART RS485 MODBUS?, And if yes how?
// MASTER
#include <Wire.h>
const byte START_BYTE = 254;
const byte END_BYTE = 255;
enum {StartByte, Id, Type, ValueHight, ValueLow, EndByte};
// type: 1:button, 2:humidity, 3:temperaure
enum {TypeButton = 1, TypeHumidity = 2, TypeTemperaure = 3};
byte devices[] = { 2, 3, 66 } ;
byte message[6];
byte light1;
void setup() {
Serial.begin(9600);
Wire.begin();
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
for ( int i = 0; i < sizeof(devices); ++i ) {
int device = devices[i];
memset(message, 0, 6);
Wire.requestFrom(device, 6);
while (Wire.available()) {
message[StartByte] = Wire.read();
message[Id] = Wire.read();
message[Type] = Wire.read();
message[ValueHight] = Wire.read();
message[ValueLow] = Wire.read();
message[EndByte] = Wire.read();
}
// validation
if (message[StartByte] == START_BYTE and message[EndByte] == END_BYTE) {
int value = message[ValueLow] + message[ValueHight] * 256;
switch (message[Type]) {
case TypeButton:
processButton(device, message[Id], value);
break;
case TypeHumidity:
processHumidity(device, message[Id], value);
break;
case TypeTemperaure:
processTemperaure(device, message[Id], value);
break;
}
}
}
}
void processButton(int device, int id, int value) {
Serial.println("Button:" );
Serial.print(device);
Serial.print(".");
Serial.print(id);
Serial.print(" : ");
Serial.println(value);
Serial.println("-------------" );
if (device == 2 and id == 1) {
light1 = !light1;
processLight(LED_BUILTIN, light1);
Wire.beginTransmission(device);
Wire.write(light1);
Wire.endTransmission();
}
}
void processHumidity(int device, int id, int value) {
Serial.println("Humidity:" );
Serial.print(device);
Serial.print(".");
Serial.print(id);
Serial.print(" : ");
Serial.println(value);
Serial.println("-------------" );
}
void processTemperaure(int device, int id, int value) {
Serial.println("Temperaure:" );
Serial.print(device);
Serial.print(".");
Serial.print(id);
Serial.print(" : ");
Serial.println(value);
Serial.println("-------------" );
}
void processLight(byte no, byte value) {
digitalWrite(no, value);
}
// Slave
#include <util/delay.h>
#include <Wire.h>
enum {StartByte, Id, Type, ValueHight, ValueLow, EndByte};
// type: 1:button, 2:humidity, 3:temperaure
enum {TypeButton = 1, TypeHumidity = 2, TypeTemperaure = 3};
const byte MY_ADDRESS = 2;
const byte START_BYTE = 254;
const byte END_BYTE = 255;
const byte CLEAR_BYTE = 253;
byte button1[6];
byte humidity[6];
byte temperaure[6];
unsigned long previousMillis = 0;
const long interval = 10000; // reset sensors
unsigned long previousMillis2 = 0;
const long interval2 = 1000;
int ledState = LOW;
void setup() {
Wire.begin(MY_ADDRESS);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
Serial.begin(9600);
pinMode(8, OUTPUT);
pinMode(7, OUTPUT);
pinMode(2, INPUT);
attachInterrupt(digitalPinToInterrupt(2), checkTicks, RISING);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
memset(humidity, 0, sizeof(humidity));
memset(temperaure, 0, sizeof(temperaure));
}
unsigned long currentMillis2 = millis();
if (currentMillis2 - previousMillis2 >= interval2) {
previousMillis2 = currentMillis2;
ledState = !ledState;
digitalWrite(8, ledState);
}
if (humidity[StartByte] == 0 and humidity[EndByte] != CLEAR_BYTE) {
int value1 = random(0, 1023);
createMeaagage(humidity, 1, TypeHumidity, value1);
}
if (temperaure[StartByte] == 0 and temperaure[EndByte] != CLEAR_BYTE) {
int value2 = random(0, 1023);
createMeaagage(temperaure, 1, TypeTemperaure, value2);
}
}
void checkTicks() {
createMeaagage(button1, 1, TypeButton, sizeof(button1));
}
void createMeaagage(byte mb[6], byte id, byte type, int value) {
mb[StartByte] = START_BYTE;
mb[Id] = id;
mb[Type] = type;
mb[ValueHight] = (value - (value % 256)) / 256; //byte s vyšší hodnotou
mb[ValueLow] = value % 256; //byte s nižší hodnotou - 1
mb[EndByte] = END_BYTE;
}
void requestEvent() {
if (button1[StartByte] == START_BYTE and button1[EndByte] == 255) {
Wire.write(button1, 6);
clearMessage(button1);
} else if (temperaure[StartByte] == START_BYTE and temperaure[EndByte] == 255) {
Wire.write(temperaure, 6);
clearMessage(temperaure);
} else if (humidity[StartByte] == START_BYTE and humidity[EndByte] == 255) {
Wire.write(humidity, 6);
clearMessage(humidity);
}
}
void clearMessage(byte mb[6]) {
memset(mb, 0, 6);
mb[EndByte] = CLEAR_BYTE;
}
void receiveEvent(int howMany)
{
byte value = Wire.read();
digitalWrite(7, value);
}