PowerBroker2/SerialTransfer

How i can use SerialTransfer with rs485 ?

YBeyin opened this issue · 11 comments

Hello everyone. I am trying to communicate 2 arduinos with rs485 (because of some long distance) how i can use SerialTransfer with rs485? I have read all examples, but can not find the solution. in uart , having an error as "'Serial1' was not declared in this scope" . So is it not possible use SerialTransfer with rs485? I want to transfer struct.

Target i want to hit : taking float values from a dht22 sensor every 2 seconds , send it with slave ar. nano + rs485 to master ar. nano +rs485. And at final display that values on a 20x4 graphic lcd display.

The result i get: values can not send to master, always getting the error message. And both serial port screen in the arduino ide are blank.

my rs485 and arduino connection is like :

// Arduino TX1 -> Rs485 DI
// Ardiuno RX0 -> Rs485 RO
// Arduino GND -> Rs485 GND
// Arduino 5V -> Rs485 VCC
// Arduino D2 -> Rs485 DE + RE

Here i am adding the codes:

master.txt
slave.txt

Also Codes:

Slave with rs485 (struct sender)

//DHT22 Slave Ardiuno Nano


//Connections :

// ****** RS485 ********
// Arduino TX1 -> Rs485 DI
// Ardiuno RX0 -> Rs485 RO
// Arduino GND -> Rs485 GND
// Arduino 5V -> Rs485 VCC
// Arduino D2 -> Rs485 DE + RE
// Slave Rs485 A -> Master Rs485 A
// Slave Rs485 B -> Master Rs485 B

// ****** DHT22 ********
// Arduino D3 -> DHT22 Data
// Arduino GND -> DHT22 GND
// Arduino VIN -> DHT22 VCC

#include <DHT.h>
#include <SimpleTimer.h>
#include <SerialTransfer.h>
#include <SoftwareSerial.h>

#define DHTPIN 3
#define DHTTYPE DHT22

DHT dht(DHTPIN,DHTTYPE); 
SimpleTimer timer;

SoftwareSerial mySerial(2, 3); // RX, TX
SerialTransfer myTransfer;

struct STRUCT {
 float temp;
 float hum;
} dhtData;

void setup() {
  Serial.begin(115200);
  mySerial.begin(9600); // changed baud from 115200 to 9600
  myTransfer.begin(mySerial);
  dht.begin();
  timer.setInterval(2000L,getDhtValues); 
  dhtData.temp=0;
  dhtData.hum=0; 
}

void loop() {
  timer.run();   
  digitalWrite(2,HIGH);
  uint16_t sendSize = 0;
  sendSize = myTransfer.txObj(dhtData, sendSize);
  myTransfer.sendData(sendSize);
  delay(500);
  digitalWrite(2,LOW);
}

void getDhtValues(){
  dhtData.temp=dht.readTemperature(); //get dht tempeture value
  dhtData.hum=dht.readHumidity();   //get dht humidity value
}

Master with rs485 (struct receiver)

//Dht22 Master Arduino Nano With 20x4 Graphic Lcd

// Connections : 

// ****** RS485 *****
// Arduino TX1 -> Rs485 DI
// Arduino RX0 -> Rs485 RO
// Arduino D8 -> Rs485 DE + RE
// Arduino GND -> Rs485 GND
// Arduino 5V -> Rs485 VCC
// Master Rs485 A -> Slave Rs485 A
// Master Rs485 B -> Slave Rs485 B

// ***** LCD DISPLAY ****
// Arduino A4 -> Display SDA
// Arduino A5 -> Display SCL
// Arduino GND -> Display GND
// Arduino 5V -> Display VCC


#include <Wire.h>
#include <LiquidCrystal_I2cTUR.h>
#include "SerialTransfer.h"
#include <SoftwareSerial.h>


SoftwareSerial mySerial(2, 3); // RX, TX
SerialTransfer myTransfer;

struct STRUCT {
 float temp;
 float hum;
} dhtData;




int displayColumns = 20;
int displayRows = 4;
int enablePin = 8; 
String msg;
LiquidCrystal_I2cTUR display(0x27, displayColumns, displayRows);  



void setup() {  
  Wire.begin();
  Serial.begin(115200);
  mySerial.begin(9600); // changed baud from 115200 to 9600
  myTransfer.begin(mySerial);
  display.init();                     
  display.backlight();
  pinMode(enablePin, OUTPUT);
}

void loop() {

  if(myTransfer.available())
  {
    // use this variable to keep track of how many
    // bytes we've processed from the receive buffer
    uint16_t recSize = 0;
    recSize = myTransfer.rxObj(dhtData, recSize);
    Serial.print(dhtData.temp);
    Serial.print(dhtData.hum);
    Serial.print(" | ");    
    msg="Serial Success";
  }
  else {msg="Serial Error";}
 
  display.clear();  
  display.setCursor(0,0);
  display.print("System Ready");  
  display.setCursor(0,1);
  display.print("Temp : "+String(dhtData.temp));  
  display.setCursor(0,2);
  display.print("Hum : "+String(dhtData.hum));
  display.setCursor(0,3);
  display.print(msg);  
  delay(1000);  
}

SerialTransfer is compatible with RS485. The error you describe is not due to the RS485, but due to your Arduino not having a supported UART port other than USB. I'm guessing you're compiling for an Uno? Either way, SerialTransfer is also compatible with software serial libraries such as SoftwareSerial.h. Use one of those libraries to setup a software serial port to connect to RS485 and then pass that software serial port to SerialTransfer instead of Serial1.

SerialTransfer is compatible with RS485. The error you describe is not due to the RS485, but due to your Arduino not having a supported UART port other than USB. I'm guessing you're compiling for an Uno? Either way, SerialTransfer is also compatible with software serial libraries such as SoftwareSerial.h. Use one of those libraries to setup a software serial port to connect to RS485 and then pass that software serial port to SerialTransfer instead of Serial1.

i am using two arduino nano.one is for slave, other one is for master. i just plugged my rs485 as i described at first message. i did figure out nano does not support serial1, but still can not figure out how to do it. I have searched for examples but had nothing. rx for receiver isn't it?

Something like this should work:

#include "SerialTransfer.h"
#include <SoftwareSerial.h>


SoftwareSerial mySerial(2, 3); // RX, TX
SerialTransfer myTransfer;

struct STRUCT {
  char z;
  float y;
} testStruct;

char arr[6];


void setup()
{
  Serial.begin(115200);
  mySerial.begin(9600); // changed baud from 115200 to 9600
  myTransfer.begin(mySerial);
}


void loop()
{
  if(myTransfer.available())
  {
    // use this variable to keep track of how many
    // bytes we've processed from the receive buffer
    uint16_t recSize = 0;

    recSize = myTransfer.rxObj(testStruct, recSize);
    Serial.print(testStruct.z);
    Serial.print(testStruct.y);
    Serial.print(" | ");

    recSize = myTransfer.rxObj(arr, recSize);
    Serial.println(arr);
  }
}

Something like this should work:

This is for slave (struck sender) right?

That's for receiving, but the initial setup is the same for the transmitting arduino

Okay thanks alot @PowerBroker2 i will try it. I hope so i can handle this. Your library is great. And i am so new at arduino.

@PowerBroker2 forgive me but that did not work. I have been updated the main question with all details and codes. Still need some help.

I need more context - what exactly is going wrong? Did you test the physical signal with a multimeter? Do you get a compiler error? How much % memory does the sketches use up? etc.

Also, I notice your rx sketch doesn't drive the RS485 direction pin low to receive.

I need more context - what exactly is going wrong? Did you test the physical signal with a multimeter? Do you get a compiler error? How much % memory does the sketches use up? etc.

Also, I notice your rx sketch doesn't drive the RS485 direction pin low to receive.

i am not having any compile error. even when i code the write the myTransfer.status on the screen that shows the value of status is 1. %60 arround memory does the sketches uses.
with these codes i can send data to master and that is works but i want to send data as struct. thats why i am asking your help.

here the codes that works with this connection:

Codes for slave :

//DHT22 Slave Ardiuno Nano


//Connections :

// ****** RS485 ********
// Arduino TX1 -> Rs485 DI
// Ardiuno RX0 -> Rs485 RO
// Arduino GND -> Rs485 GND
// Arduino 5V -> Rs485 VCC
// Arduino D2 -> Rs485 DE + RE

// ****** DHT22 ********
// Arduino D3 -> DHT22 Data
// Arduino GND -> DHT22 GND
// Arduino VIN -> DHT22 VCC

#include <DHT.h>
#include <SimpleTimer.h>


#define DHTPIN 3
#define DHTTYPE DHT22

DHT dht(DHTPIN,DHTTYPE); 
SimpleTimer timer;

float temp;
float hum;

void setup() {
  Serial.begin(9600);  
  dht.begin();
  timer.setInterval(2000L,getDhtValues);     
}

void loop() {  
  timer.run(); 
}

void getDhtValues(){
 temp=dht.readTemperature(); //get dht tempeture value
 hum=dht.readHumidity();   //get dht humidity value
 digitalWrite(2,HIGH);
  Serial.println(String(temp)); 
  delay(50);
  digitalWrite(2,LOW);
}

And the codes for master :

//Dht22 Master Arduino Nano With 20x4 Graphic Lcd

// Connections : 

// ****** RS485 *****
// Arduino TX1 -> Rs485 DI
// Arduino RX0 -> Rs485 RO
// Arduino D8 -> Rs485 DE + RE
// Arduino GND -> Rs485 GND
// Arduino 5V -> Rs485 VCC

// ***** LCD DISPLAY ****
// Arduino A4 -> Display SDA
// Arduino A5 -> Display SCL
// Arduino GND -> Display GND
// Arduino 5V -> Display VCC


#include <Wire.h>
#include <LiquidCrystal_I2cTUR.h>




int displayColumns = 20;
int displayRows = 4;
int enablePin = 8; 
String msg;
float temp;
LiquidCrystal_I2cTUR display(0x27, displayColumns, displayRows);  



void setup() {  
  Wire.begin();
  Serial.begin(9600); 
  display.init();                     
  display.backlight();
  pinMode(enablePin, OUTPUT);
}

void loop() {
 if(Serial.available()>0){
    msg=Serial.readString();      
    Serial.println(msg);      
  }
  display.clear();  
  display.setCursor(0,0);
  display.print("System Ready"); 
  display.setCursor(0,1);
  display.print(msg);   
  delay(1000);  
}

Here's some example code for RS485 that I've used with SerialTransfer:

https://github.com/PowerBroker2/RND_Flight_Code/blob/26ac84d0507d0c558e5866226c323ce6e4ebb9b5/src/operational/Arduino/Ground_Station/RS485.h

Note that I'm using one port for TX and one for RX, but in both cases I drive the enable pin either high or low.

As for your code, I think I see the problem: You wired up the RS485 transceiver to the one hardware UART port instead of the softwareserial port. You can do either, but if you want to keep your wiring the same, you can delete all the softwareserial stuff and simply do this:

myTransfer.begin(Serial);

simply do this:

myTransfer.begin(Serial);

Thank you so much. You saved my whole project and my mental healt 👯 Thats works now. I am so new at arduino world. But loving this oop coding. Great library with so much potential.