what I'm missing here

Hello folks

I’m trying to build a RS485 library and I’m testint it now.I’m using Visual Basic to inject some packets on the RS485 BUS and debug the outuput using a Saleae Logic Analiser.
I only have one function on the main loop for now but I should expect to see the answer from the microcontroller when is ID is called on the BUS right after he received the message and then answer back.It works most of the time but looking on the Saleae Software sometimes he ignores some stream packects and don’t give the answer.For now I just have one slave on the BUS.
Here is the output from the software.
Channel 0 is connect to the RX atmega328 pin and the channel 1 is connect to TX Pin.Channel 3 is connect to the Pin 2 and 3 from the MAX485(when is low is on receive mode, when is High on seend Mode)
I don´t figure out why is a gap in some answer as I can see on the image
Also here is my code and the library in working on

#include "RS485.h"

RS485 bus;
void setup()
{
Serial.begin(9600);
bus.begin(2,3); //Device address and hardware pin connected to MAX485 enable Pins 2 and 3 
bus.rxMode();      //Set de Bus on receive mode
}
void loop()
{
bus.listen();
}

RS485.cpp (4.31 KB)

RS485.h (1.16 KB)

RS485::RS485(){}

If you constructor isn’t going to do anything you can omit it.


//________________________________________________
void RS485::listen()
{
  
  if(Serial.read() ==  startByte)//Probe if first byte is the start Byte 
  {
    //Serial.println("Recebido StartByte");
    while(Serial.available()<=6);//Waits for the remaining 7 bytes
    if(Serial.read() == slaveID)//Check the Slave ID 
    {
     dataReceived[0] = startByte;
     dataReceived[1] = slaveID;
     for (uint8_t i = 0; i<= 5; i++) dataReceived[i+2] = Serial.read(); 
     byte tempCRC = dataReceived[7];
     dataReceived[7] = tempCRC;
     if(verify_checkSum(tempCRC,dataReceived))functionTable(dataReceived);//Go to the Function Table
    } 
   else while(Serial.read() != -1);
  }
 else while(Serial.read() != -1);
}

I don’t like this for a number of reasons. If you don’t get a startByte you then keep reading until you get nothing. What if the startByte is the second byte? You have now skipped it. What if two packets come in quick succession, but there is noise in the very first byte? You have now skipped two packets. Also I prefer to test for if Serial.available rather than checking if you get -1 back.

I recently did a non-blocking RS485 library here:

http://www.gammon.com.au/forum/?id=11428

In that I use a “state machine” where you transition from “no packet” to “filling the packet” to “calculate the CRC”. That code will work even if the bytes come at odd intervals.

Hi Nick,

I found the above page you wrote about a week ago and its one of the best descriptions of implementing RS485 that I could find online. Just want to thank you for the effort you have put into it, It is inspirational.

Glad you like it, and thanks for the complimentary remarks. :)

Hallo sir…
I’m sorry to disturb you and sorry if i’m not very good at English.

Since i new to arduino, and i have i project using RS-485 with 1 master and 2 slave…
I’ve already succeed communicate between two arduino with rs485…i just have a problem when i’ve to send structure message, so i try to using your library using RS485 non blocking sir…
but confused when i encountered compile error…
i’ ve trying to make chance the code to see whats wrong in the code…but i dont have any idea… :disappointed_relieved:

this is my code

#include <SoftwareSerial.h>
#include <RS485_non_blocking.h>

#define SerialControl     7
#define Transmit          HIGH
#define Receive           LOW
#define RX45              2
#define TX45              3

#define RXID              8
#define TXID              9

#define LED              13

SoftwareSerial RS485 (RX45, TX45);
SoftwareSerial RFID (RXID, TXID);


size_t fWrite (const byte what)
{
  return RS485.write (what);
}

int fAvailable ()
{
  return RS485.available();
}

int fRead ()
{
  return RS485.read();
}

RS485 myChannel (fRead, fAvailable, fWrite,20);

void setup()
{
  RS485.begin(9600);
  pinMode (SerialControl, OUTPUT);
  pinMode (LED, OUTPUT); 
  
}
const byte msg [] = "Hello world";

void loop()
{
  RS485.sendMsg (msg,sizeof(msg));
  delay(1000); 
}

This report would have more information with

  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Windows 7), Board: "Arduino Uno"
sketch_jan22a:34: error: 'RS485' does not name a type
sketch_jan22a.ino: In function 'void loop()':
sketch_jan22a:47: error: 'class SoftwareSerial' has no member named 'sendMsg'

Could you give me idea why this happened?
could you give me an example?

thank you very much for your time…
God bless you

Please edit your post, select the code, and put it between [code[/code] tags.

You can do that by hitting the “Code” button above the posting area (It looks like a scroll with < > inside it).

It looks to me like the library is not installed properly or at all.

Hi Nick .
Thanks for replying my post :slight_smile:
and I’m sorry for my post earlier…

sketch_jan22a:47: error: 'class SoftwareSerial' has no member named 'sendMsg'

i thought that something not suitable between library rs485 non blocking and SoftwareSerial…

Can you post some sketch RS485 non blocking and SoftwareSerial? :frowning:
I’m confuse about this part

RS485 myChannel (fRead, fAvailable, fWrite,20);

Is it because the my library didnt installed correctly?
I’ve reinstall both of my arduino IDE and your library…but still same error appear.
But when i compile your example sketch in your web (Gammon Forum : Electronics : Microprocessors : RS485 communications) not using SoftwareSerial, Arduino IDE can compile it properly… nothing wrong…

I do make changes to my sketch, still error

#include <RS485_non_blocking.h>
#include <SoftwareSerial.h>

#define SerialControl     7
#define Transmit          HIGH
#define Receive           LOW
#define RX45              2
#define TX45              3

#define RXID              8
#define TXID              9

#define LED              13

SoftwareSerial RS485 (RX45, TX45);
SoftwareSerial RFID (RXID, TXID);


size_t fWrite (const byte what)
{
  return RS485.write (what);
}

int fAvailable ()
{
  return RS485.available();
}

int fRead ()
{
  return RS485.read();
}

RS485 myChannel (fRead, fAvailable, fWrite,20);

void setup()
{
  RS485.begin(9600);
  pinMode (SerialControl, OUTPUT);
  pinMode (LED, OUTPUT); 
  
}
const byte msg [] = "Hello world";

void loop()
{
  myChannel.sendMsg (msg,sizeof(msg));
  delay(1000); 
}

error message

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Windows 7), Board: "Arduino Uno"
sketch_jan22a:34: error: 'RS485' does not name a type
sketch_jan22a.ino: In function 'void loop()':
sketch_jan22a:47: error: 'myChannel' was not declared in this scope

What’s this?

SoftwareSerial RS485 (RX45, TX45);

...

RS485 myChannel (fRead, fAvailable, fWrite,20);

RS485 isn’t a type, it is an instance of a SoftwareSerial type.

You are using the same name for two purposes. This compiles:

#include <RS485_non_blocking.h>
#include <SoftwareSerial.h>

#define SerialControl     7
#define Transmit          HIGH
#define Receive           LOW
#define RX45              2
#define TX45              3

#define RXID              8
#define TXID              9

#define LED              13

SoftwareSerial otherArduino (RX45, TX45);
SoftwareSerial RFID (RXID, TXID);


size_t fWrite (const byte what)
{
  return otherArduino.write (what);
}

int fAvailable ()
{
  return otherArduino.available();
}

int fRead ()
{
  return otherArduino.read();
}

RS485 myChannel (fRead, fAvailable, fWrite,20);

void setup()
{
  otherArduino.begin(9600);
  myChannel.begin();
  pinMode (SerialControl, OUTPUT);
  pinMode (LED, OUTPUT); 
  
}
const byte msg [] = "Hello world";

void loop()
{
  myChannel.sendMsg (msg,sizeof(msg));
  delay(1000); 
}

Hi Nick ! Thank you so much for your time.. you replay any question so fast.. I'm sorry if i bothering you.

I wanna say thank you..thank you so much!

Your Library and your tutorial work like a charm !! thanks.. :) :) :) !

Hi Nick and everyone !

I'm sorry that i'm still adapting to arduino, I've many things to learn, structure of data, syntax and so on..

I want to ask about how send array data like RFID tags..

The data comes like

2 52 66 48 48 65 57 55 70 57 51 48 69 13 10 3

i'm aware that there are header and stop bytes in order to calculate the checksum..what i need to do is send the value that i got to other arduino.. (I'm using Nick library ofcourse)

i want to add some "indicator" of the packet data (like header to whom i sent the data, if not match to other machine header, they will flush it)

What i'm supposed to do first? convert the entire array to string?

Nick already show the example using array of byte [1,2,level_of_potentiometer] http://www.gammon.com.au/forum/?id=11428 but i still have no idea.. :(

If i get the message from serial into array char

char i = Serial.read();
.................
tag[bytesread] = i;

and then convert it to string String packet = tag, why i got additional junk packet? original packet via serial monitor

4B00A97F930E

and the printed value from packet in serial monitor

4B00A97F930Eò

Thanks ~ :)

Better post the code from both Arduinos.

Thanks for replying Nick ! :)

Right now i'm figured out why i got junk packet, right now i declare my tag variable like this

char tags [13] = {0,0,0,0,0,0,0,0,0,0,0,0,'\0'
.....
String packet = String((char *)tags)

but i also can use String packet = String(tags)

If i've any question about sending and receiveng the data, i will post it again

Thanks ~ :)

Hi Nick and everyone

I want to ask question again :stuck_out_tongue:

I thought i can send directly my String variable using your non-blocking library…
I’m sorry that i dont understand arduino enough :frowning:
How do i convert the packet to match with format from your library Nick

Here’s my code

// RFID - ARDUINO (MASTER & SLAVE)

#include <RS485_non_blocking.h>
#include <SoftwareSerial.h>
//#include <ReceiveOnlySoftwareSerial.h>

// DEFINE
// ======== SERIAL =============
// == RFID
#define RXID  8
#define TXID  9
SoftwareSerial RFID (RXID,TXID);

// == RS 485
#define RX45           2
#define TX45           3
#define SerialControl  7
#define Transmit       HIGH
#define Receive        LOW
SoftwareSerial toSlave (RX45, TX45);
//================================

size_t fWrite (const byte what)
{
  return toSlave.write (what);
}

int fAvailable ()
{
  return toSlave.available();
}

int fRead ()
{
  return toSlave.read();
}

RS485 myChannel (fRead, fAvailable, fWrite, 20);

// ============ GLOBAL VARIABLE
char tag[13] = { 
  0,0,0,0,0,0,0,0,0,0,0,0,'\0'        };
String packet;
boolean readtag;

void setup(){
  RFID.begin(9600);
  toSlave.begin(9600);
  pinMode (SerialControl, OUTPUT);
  digitalWrite(SerialControl,Receive);
  Serial.print(F("System Started !"));
  Serial.println();
}

void ReadRFID(){
  byte val;
  byte bytesread;

  if (RFID.available()>0)
  {
    if((val = RFID.read()) == 2)
    {
      Serial.print("Tag Konsumen =  ");
      bytesread = 0;
      while (bytesread <12)
      {
        if (RFID.available()>0)
        {
          tag[bytesread] = RFID.read();
          delay(1);
          bytesread++;
        }
      }
      RFID.flush();
      packet = String(tag);
      Serial.print(packet);
      Serial.println();
      boolean readtag = true;
      SendingData();
    }
  }
}

void SendingData(){
  if (readtag){
    delay(1);
    digitalWrite(SerialControl,Transmit);
    myChannel.sendMsg(packet,sizeof(packet));
    delay(50);
    digitalWrite(SerialControl,Receive);
    delay(1);

    Serial.println(F("Tag"));
    Serial.print(packet);
    Serial.print(F("  Sent !");
    boolean readtag = false;
  }
  else{
    return;
  }
}


void loop(){
  ReadRFID();
}

and these the error message

 This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Windows 7), Board: "Arduino Uno"
test.ino: In function 'void SendingData()':
test:88: error: no matching function for call to 'RS485::sendMsg(String&, unsigned int)'
----\Arduino\libraries\RS485_non_blocking/RS485_non_blocking.h:87: note: candidates are: void RS485::sendMsg(const byte*, byte)
test:94: error: initializer fails to determine size of '__c'
test:95: error: expected `)' before ';' token

Thanks ~

No you can't send String types directly because they involve memory allocation locally. You could try converting them to a string. I personally wouldn't use String.

char tag[13] = { 
  0,0,0,0,0,0,0,0,0,0,0,0,'\0'        };
...
      packet = String(tag);

Why not just send tag, instead of packet? What do you achieve by converting it?

Hello Nick, thanks for your quick response..i'm very grateful

The reason why i was converting to String is just because i want to see the data via Serial monitor..hehe

I've tried sending char,

        myChannel.sendMsg(tag,sizeof(tag));

but i got these error message

Arduino: 1.0.6 (Windows 7), Board: "Arduino Uno"
TrySendRFID.ino: In function 'void SendingData()':
TrySendRFID:110: error: invalid conversion from 'char*' to 'const byte*'
TrySendRFID:110: error: initializing argument 1 of 'void RS485::sendMsg(const byte*, byte)'

Am i wrong at my structure of programming or something?

Thanks Nick :) ~

Well, cast it:

        myChannel.sendMsg((byte *) tag,sizeof(tag));

Hi Nick !

Thank you for your reply.. Thats great ! thank you :) Whoa i dont know there's a way to do that.. I'll find refference about that, i also not understand when saw some example code of declaring variable like

char *somevariable [][] ;

what's the differences with

char somevariable[][];

Thank you very much ! :D

orthho: Hi Nick !

Thank you for your reply.. Thats great ! thank you :) Whoa i dont know there's a way to do that.. I'll find refference about that, i also not understand when saw some example code of declaring variable like

char *somevariable [][] ;

what's the differences with

char somevariable[][];

Thank you very much ! :D

The first is a 2D array of pointers to char, while the second is a 2D array of char.

Regards, Ray L.

Hi Ray ! Thank you for your replay :)

Uhm, is still try to figure it out.. Do you know anny refference like example of code to using that? Sorry because I'm not good at programming hehe :P

Thanks again Ray !

char somevariable[][];

This doesn't make any sense. You are declaring an array with no stated bounds.