Go Down

Topic: what I'm missing here (Read 733 times) previous topic - next topic

HugoPT

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
Code: [Select]
#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();
}
Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

Nick Gammon

Code: [Select]

RS485::RS485(){}


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




Code: [Select]

//________________________________________________
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.
http://www.gammon.com.au/electronics

Protoneer

#2
Dec 30, 2012, 03:51 am Last Edit: Dec 30, 2012, 08:12 am by Protoneer Reason: 1
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.
Delta 3D Printer with Auto Bed Leveling - http://www.kickstarter.com/projects/ttstam/openbeam-kossel-pro-a-new-type-of-3d-printer/posts
http://blog.Protoneer.co.nz

Nick Gammon

Glad you like it, and thanks for the complimentary remarks. :)
http://www.gammon.com.au/electronics

Go Up