RS485 Communication Help £20

Hello,

I am trying to send data from an SD card on one arduino to another arduino using RS485. I have been slowly adding to the code below and currently know it can read data from the SD card correctly and that the RS485 is wired up correctly. I have managed to get single numbers to bounce between the two using example codes online. Ideally I am trying to send a “float” or an “int” however I have spent the day looking online with no success.

Any help would be greatly appreciated.

The code i am using on the transmit side is the:

/*
  SD card sending info over RS485
 */

/*-----( Import needed libraries )-----*/
#include <SoftwareSerial.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define RS485rx    7 // RS485 Receive pin
#define RS485Tx   8 // RS485 Transmit pin
#define RS485inout  3 // RS485 Transmit or Receive status

#define RS485Transmit HIGH
#define RS485Receive  LOW
#define ledPin      13
#define baudRate    4800

/*-----( Declare objects )-----*/
SoftwareSerial RS485(RS485rx, RS485Tx); // RX, TX

/*-----( Declare Variables )-----*/
int check;


/*-----( SD Card )-----*/
#include <SPI.h>
#include <SD.h>
File myFile;
const int chipSelect = 10;

float T;  // Checking temp previous 
float P1;  // Checking temp previous 
float test;
int i;
int z;

/*+++++++++++++++++++++++++++++++   RTC Setup   +++++++++++++++++++++++++++++++*/
#include "RTClib.h"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int Sec;


// -----------------------------------------------------------------
// SETUP         SETUP         SETUP         SETUP         SETUP
// -----------------------------------------------------------------
void setup() {      /****** SETUP: RUNS ONCE ******/
  /*-----( RS485 )-----*/
pinMode(RS485inout, OUTPUT);
// Set RS485 device to read initially
  digitalWrite(RS485inout, RS485Receive);
  // MUST BE THE SAME AS THE SENDER UNIT!
  RS485.begin(baudRate);
  
   /*-----( SD Card )-----*/ 
  pinMode(chipSelect, OUTPUT);
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
 // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("TEST1.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
Serial.println("Worked...");
 myFile.close();
 } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

/*+++++++++++++++++++++++++++++++   RTC Start Up   +++++++++++++++++++++++++++++++*/
  rtc.begin(); 

}


// -----------------------------------------------------------------
// LOOP     LOOP     LOOP     LOOP     LOOP     LOOP     LOOP
// -----------------------------------------------------------------
void loop() {
  



 /*-----( SD Card Code )-----*/  
myFile = SD.open("TEST1.txt");
if (myFile) {
File TEST1; // The file with your data in it.

 /*-----( For loop which now continuosly runs )-----*/
//for (i=0; i < 8000; i=i+19){
for (i=0; i < 98000; i=i+19){


//if(Sec==00||Sec==05||Sec==10||Sec==15||Sec==20||Sec==25||Sec==30||Sec==35||Sec==40||Sec==45||Sec==50||Sec==55){



    DateTime now = rtc.now();
    Sec = ((now.second()));
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();


Serial.println(i);


uint32_t fileSize = myFile.size();
myFile.seek(fileSize - (fileSize-i)); 


char temp [9];
char oldRecord [18];
myFile.read(oldRecord, 18); // Read 18 bytes.
oldRecord[18] = 0; // Null termination (may not be needed)  
strncpy(temp, oldRecord, 9); // Read 9 characters from line starting at the 1st character and copy this into char array temp.
T = atof(temp);
Serial.println("Temp");
Serial.println(T,4);

char press1 [9];
strncpy(press1, oldRecord + 9, 9);
P1 = atof(press1);
Serial.println("Pressure");
Serial.println(P1,4); // print the first 4 digits 




/*-----( Should make RS485 Transmit )-----*/ 
// Set the RS485 to transmit mode and send the value
   digitalWrite(RS485inout, RS485Transmit);
   check = (P1);
   RS485.write((check));
  //check = String(P1); 
  //check = (P1,3); 
  Serial.println("check");
  Serial.println((check));
  Serial.println("check");
  
delay(abs(5000));
}
}
}

The receiving side has the following very simple code:

/*-----( Import needed libraries )-----*/
#include <SoftwareSerial.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define SSerialRX        00  //Serial Receive pin
#define SSerialTX        01  //Serial Transmit pin

#define SSerialTxControl 3   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW

#define Pin13LED         10

/*-----( Declare objects )-----*/
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX

/*-----( Declare Variables )-----*/
int byteReceived;
int byteSend;

void setup()   /****** SETUP: RUNS ONCE ******/
{
  // Start the built-in serial port, probably to Serial Monitor
  Serial.begin(9600);
  Serial.println("SerialRemote");  // Can be ignored
  
  pinMode(Pin13LED, OUTPUT);   
  pinMode(SSerialTxControl, OUTPUT);  
  
  digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver
  
  // Start the software serial port, to another device
  RS485Serial.begin(4800);   // set the data rate 
}//--(end setup )---


void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  //Copy input data to output 
  digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver 
  if (RS485Serial.available()) 
  {
    digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver
    byteSend = RS485Serial.read();   // Read the byte 

    delay(10);              

    Serial.println(byteSend);    

  }// End If RS485SerialAvailable
  
}//--(end main loop )---

I would be happy with any code that can send and receive a float over Rs485. If not a float a string that can be converted back into a float.

I can modify it later for my needs later just need something to start with.

I don’t have RS485’s at hand but i think the following code should work: on transmit the following helped.Software serial send issues

#include <Wire.h>

/*
  SD card sending info over RS485
 */

/*-----( Import needed libraries )-----*/
#include <SoftwareSerial.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define RS485rx    7 // RS485 Receive pin
#define RS485Tx   8 // RS485 Transmit pin
#define RS485inout  3 // RS485 Transmit or Receive status

#define RS485Transmit HIGH
#define RS485Receive  LOW
#define ledPin      13
#define baudRate    4800

/*-----( Declare objects )-----*/
SoftwareSerial RS485(RS485rx, RS485Tx); // RX, TX

char toSendWithMarkers [11]="";
/*-----( Declare Variables )-----*/
float check;


/*-----( SD Card )-----*/
#include <SPI.h>
#include <SD.h>
File myFile;
const int chipSelect = 10;

float T;  // Checking temp previous 
float P1;  // Checking temp previous 
float test;
int i;
int z;

/*+++++++++++++++++++++++++++++++   RTC Setup   +++++++++++++++++++++++++++++++*/
#include "RTClib.h"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {
  "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int Sec;


// -----------------------------------------------------------------
// SETUP         SETUP         SETUP         SETUP         SETUP
// -----------------------------------------------------------------
void setup() {      /****** SETUP: RUNS ONCE ******/
  /*-----( RS485 )-----*/
  pinMode(RS485inout, OUTPUT);
  // Set RS485 device to read initially
  digitalWrite(RS485inout, RS485Receive);
  // MUST BE THE SAME AS THE SENDER UNIT!
  RS485.begin(baudRate);

  /*-----( SD Card )-----*/
  pinMode(chipSelect, OUTPUT);
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("TEST1.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.println("Worked...");
    myFile.close();
  } 
  else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  /*+++++++++++++++++++++++++++++++   RTC Start Up   +++++++++++++++++++++++++++++++*/
  rtc.begin(); 

}


// -----------------------------------------------------------------
// LOOP     LOOP     LOOP     LOOP     LOOP     LOOP     LOOP
// -----------------------------------------------------------------
void loop() {




  /*-----( SD Card Code )-----*/
  myFile = SD.open("TEST1.txt");
  if (myFile) {
    File TEST1; // The file with your data in it.

    /*-----( For loop which now continuosly runs )-----*/
    //for (i=0; i < 8000; i=i+19){
    for (i=0; i < 98000; i=i+19){


      //if(Sec==00||Sec==05||Sec==10||Sec==15||Sec==20||Sec==25||Sec==30||Sec==35||Sec==40||Sec==45||Sec==50||Sec==55){



      DateTime now = rtc.now();
      Sec = ((now.second()));
      Serial.print(now.year(), DEC);
      Serial.print('/');
      Serial.print(now.month(), DEC);
      Serial.print('/');
      Serial.print(now.day(), DEC);
      Serial.print(" (");
      Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
      Serial.print(") ");
      Serial.print(now.hour(), DEC);
      Serial.print(':');
      Serial.print(now.minute(), DEC);
      Serial.print(':');
      Serial.print(now.second(), DEC);
      Serial.println();


      Serial.println(i);


      uint32_t fileSize = myFile.size();
      myFile.seek(fileSize - (fileSize-i)); 


      char temp [9];
      char oldRecord [18];
      myFile.read(oldRecord, 18); // Read 18 bytes.
      oldRecord[18] = 0; // Null termination (may not be needed)  
      strncpy(temp, oldRecord, 9); // Read 9 characters from line starting at the 1st character and copy this into char array temp.
      T = atof(temp);
      Serial.println("Temp");
      Serial.println(T,4);

      char press1 [9];
      strncpy(press1, oldRecord + 9, 9);
      P1 = atof(press1);
      Serial.println("Pressure");
      Serial.println(P1,4); // print the first 4 di
      /*-----( Should make RS485 Transmit )-----*/
      // Set the RS485 to transmit mode and send the value
      digitalWrite(RS485inout, RS485Transmit);
      //convert to int by mutiplying with 10000
      convertForSending(P1); //convert before sending

      RS485.write(toSendWithMarkers);
      Serial.print("val : ");
      Serial.println((toSendWithMarkers));
      delay(abs(5000));
    }
  }
}
void convertForSending(float test)
{
  boolean complete = false;
  int x = 0;
  char temp[9]= {
    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL  };

  dtostrf(test,6,3,temp);
  while(x < 11 && !complete)
  {

    if(x==0)
    {
      toSendWithMarkers[0] = '<';
    }
    else if(temp[x-1] == NULL)
    {
      toSendWithMarkers[x] = '>';
      complete = true;
      break;
    }
    else
    {
      toSendWithMarkers[x] = temp[x-1];
    }

    ++x;
  }
  Serial.println(temp);
  Serial.println(toSendWithMarkers);

}

For receive there is an awesome post by Robin2 Receiving serial data

/*-----( Import needed libraries )-----*/
#include <SoftwareSerial.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define SSerialRX        8  //Serial Receive pin
#define SSerialTX        7  //Serial Transmit pin

#define SSerialTxControl 3   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW

#define Pin13LED         10

/*-----( Declare objects )-----*/
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
boolean newData = false;

/*-----( Declare Variables )-----*/
//float byteReceived;
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; 


float floatFromPC = 0.0000;
float byteSend;

void setup()   /****** SETUP: RUNS ONCE ******/
{
  // Start the built-in serial port, probably to Serial Monitor
  Serial.begin(9600);

  pinMode(Pin13LED, OUTPUT);   
  pinMode(SSerialTxControl, OUTPUT);  


  // Start the software serial port, to another device
  RS485Serial.begin(4800);   // set the data rate 
  digitalWrite(SSerialTxControl, RS485Receive);

}//--(end setup )---

void loop()   
{
  readRS485();
  if (newData == true) {
    parseData();
    showParsedData();
    newData = false;
  }

}//--(end main loop )---
void parseData(){
  floatFromPC = atof(receivedChars);     // convert this part to a float

}
void readRS485()
{
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (RS485Serial.available() > 0 && newData == false) {
    rc = RS485Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}
void showParsedData() {
  Serial.print("Float ");
  Serial.println(floatFromPC);
}

transmitRS485.ino (5.02 KB)

sendfile2.ino (2 KB)

Float to string:

float f = 1.23;
char buff[5]; // make sure you have enough space for all digits, the decimal point and the \0 terminator.
dtostrf(4, 2, f, buff); // convert float to string.

dtostrf reference here

Then just transmit this string, and on the receiving end convert it back to float value:

float f = atof(buff);

Of course it can also be transmitted in binary format if you prefer. Look at memcpy() in that case.