Need to understand Serial-RS485 master/slave addressing

Im not to sure on how the talking actually happens between RS485 Master/Slave

I understand that the master sends a request with an address and the slave identifies with the address and then sends data back to the master.

Im mostly stumped on how sending something like this => sendMSG(byte address1,byte address2,byte data_type,byte code1,byte code2,byte Sign,byte data1,byte data2,byte data3,byte data4)

How does the slave take that, does it already understand which each byte is from start to finish?

Is there to be a response to the Master from the slave that it go its request and the information is coming soon? or does it just send it back all at once.

Im just not sure on what order you are to read each byte and confirm and send a response ect.

Any help will be great

How does the slave take that, does it already understand which each byte is from start to finish?

As KE7GKP stated you are confusing an electrical standard (RS-485) with whatever software protocol is being used on any one specific network using RS-485 hardware devices. Modbus is one popular protocol often used with RS-485 networks, and there are other software protocols that would also work.

The software protocol would define what the message bytes represent and how the remote devices would respond to the message. The RS-485 standard would just insure that all slaves will receive the same message and allow the slave device(s) to send back messages as defined by whatever software protocol is being used,

Lefty

Okay, thank you i will read up on MODbus.

i think i am just getting frustrated cause tech, i can approach this anyway i like as long as one unit is talking at a time. So i think im just getting flustered because i don't know where to start.

I think i will just do some more research and get back to you guys.

Thanks

btsp:
i think i am just getting frustrated cause tech, i can approach this anyway i like as long as one unit is talking at a time. So i think im just getting flustered because i don't know where to start.

I think i will just do some more research and get back to you guys.

Thanks

It's not really so bad. The protocol has somewhere in the message format an address byte(s) defined to state which slave device the message is for, so that while all the devices will receive the messeage only the device that detects it's address in the message format will respond to it. So back to your first post, yes each slave devices knows it's unique address and understands what the meaning of each byte in the message means and it has the software to respond properly to the message directed to it.

Lefty

I am getting multiple slave arduinos to respond to a master arduino,

The sendMSG was from the code on : Tinkering with Electronics...: Arduino and RS485 (ENGLISH VERSION)

I think i just need to start writing some code out and figure it all out.
I under stand the principal of everything,
I think i was just looking for a lib to do it all for me type of deal.

But i am going to take this on and write it out on my own i think haha Got to stop being lazy.

Ive attempted some code
I could make one send a message and the other receive it,

then i tried making a call and answer

I have the master sending out then goes into receive mode whats for a response
While the slave waits then receives then goes into send then back to receive

But the code i am running is not receiving the intial message like it did when i had it running in just a single transmission mode.

MASTER:

#include <Stdio.h>

#define dirPin 4
char charArray[5]

uint8_t HeadingData[] =     	{0x10, 0x01, 0x0A, 0x10, 0x2B};
uint8_t Angle[] =     		{0x10, 0x02, 0x0B, 0x10, 0x2C};
 void setup() 
	{
  	 Serial.begin(9600);
         pinMode(4, OUTPUT);
         Serial.println(sizeof(HeadingData));
	}

 void loop() 
	{
	digitalWrite(dirPin, HIGH);
        sendMSG(HeadingData);
        Serial.println("message sent");
        
        digitalWrite(dirPin, LOW);
        while(Serial.available() == 0);;
        recieveMSG();
        Serial.println("message recieved");
         
     
         }
        
       
        
        



 

 void recieveMSG()
	{
	 int charIndex = 0;

      while (Serial.available()) 
			{
			 int recieved = Serial.read();
      			 delay(5);
      			 charArray[charIndex] = recieved;  	// store everything that was read in charArray byte-by-byte
      			 //charArray[charIndex+1] = '\0';  	// add a NULL value
                         charIndex++;
                
    			}
                Serial.println(charArray[0], HEX);
                Serial.println(charArray[1], HEX);
                Serial.println(charArray[2], HEX);
                Serial.println(charArray[3], HEX);
                Serial.println(charArray[4], HEX);
                Serial.flush();
  		
          
	}



	

 void sendMSG(uint8_t Message[])
	{
         for(int i = 0; i < sizeof(HeadingData); i++)
			{
                         Serial.write(HeadingData[i]);
                         Serial.println(HeadingData[i], HEX);
                        }
  
	}

SLAVE:

#include <Stdio.h>

#define dirPin 4

char charArray[5];

uint8_t HeadingData[] =     	{0x10, 0x01, 0x0A, 0x10, 0x2B};
uint8_t Angle[] =     		{0x10, 0x02, 0x0B, 0x10, 0x2C};


 void setup() 
	{
  	 Serial.begin(9600);
         pinMode(4, OUTPUT);
	}


 void loop() 
	{
	digitalWrite(dirPin, LOW);
        while(Serial.available() == 0);;
        if (Serial.available())
            {
              recieveMSG();
              Serial.println("message received");
            }
        digitalWrite(dirPin, HIGH);
        sendMSG(HeadingData);
        Serial.println("message sent");
        }



 

 void recieveMSG()
	{
	 int charIndex = 0;
 	 int intIndex = 1;
  	 int max_intIndex;
  	 number = 0;
        
        
    
	 
		 while (Serial.available()) 
			{
			 int recieved = Serial.read();
      			 delay(5);
      			 charArray[charIndex] = recieved;  	// store everything that was read in charArray byte-by-byte
      			 //charArray[charIndex+1] = '\0';  	// add a NULL value
      		         charIndex++;
                
    			}
                Serial.println(charArray[0], HEX);
                Serial.println(charArray[1], HEX);
                Serial.println(charArray[2], HEX);
                Serial.println(charArray[3], HEX);
                Serial.println(charArray[4], HEX);
                Serial.flush();
  		
          
	}



	

 void sendMSG(uint8_t Message[])
	{
         for(int i = 0; i < sizeof(Angle); i++)
			{
            
     	 		 Serial.write(Angle[i]);
                         Serial.println(Angle[i], HEX);
                        }

the master is receiving this :

D
A
10
31
30

the slave is getting the same thing pretty much except for the last number which isn't 30 but something else.

Any ideas?

Just something i noticed i ran code to receive an entire message and it is getting all of this:

D
A
10
31
30
D
A
1
31
D
A
A
41
D
A
10
31
30
D
A
2B
32
42
D
A
6D
65
73
73
61
67
65
20
73
65
6E
74
message received

seems like the message is being sent but loks like always after a D A ....is some kind of protocol going on that i am not aware of?

it looks like you are filling the array while there is data
but always printing 5 values

suggest you initialise the array with 00
and only print non-zero

or something like that

FF may be better for you, depending on your actual data

or even, note how many characters are to be printed

Here's a hint

D = CR
A = LF
6D = m
65 = e
73 = s
73 = s
61 = a
67 = g
65 = e
20 = SPACE
73 = s
65 = e
6E = n
74 = t

I don't know what send/receiveMSG() does (can't find the source at that link) but I doubt you can use it on the same port at the same time as Serial.print/receive().


Rob

So even tho i am not talking to the computer it automatically does a carriage return?

oh!
i see where i am going wrong

Thank you for the hints.

cant use the serial for communication with computer and other units, going to have to use SoftSerial.

took out all the debugging Serial.prints and i am getting what i need, using LEDS to debug now.

Thanks again

I have basic communication going between the arduino, master calling slave slave responding to master.
I have a checksum procedure that is working and now i am trying to add a 'start byte' to indicate the beggining of the transmission.

void recieveMSG()
	{
	 int charIndex = 1;
 	 while(Serial.available() == 0);;
         if (Serial.available())
               {
                 if (Serial.read() == 0x10)
                     {
		 while (Serial.available()) 
			{
			 int recieved = Serial.read();
      			 delay(5);
      			 charArray[charIndex] = recieved;  	
      		         charIndex++;
                        }
              
  		       }
                   }  
	}

But for some reason it is getting the first reading, identifying it as 0x10, then it does not receive anymore of the message

am i taking to long to get to reading the rest of the message and it is then gone by the time i get there?

any ideas?

You get the 0x10

Serial.read() == 0x10)

then straight away test for another character

while (Serial.available()) {

}

when you do the "while" test the second character is still on it's way so the test fails and the function exits. That's the base of the problem.

Also (not your problem but should be fixed)

while(Serial.available() == 0);;
if (Serial.available())

you can only get to the if when a character is available, no need to test again. And then

int recieved = Serial.read();
delay(5);
charArray[charIndex] = recieved;
charIndex++;

No need for a delay, just stick the character in the array.

int charIndex = 1;

charIndex would normally start at 0 not 1.


Rob

Here are a couple of reworked versions of your function

void recieveMSG() {
    // 'clear" the frame in memory by dorking the last byte
    // so we can check the frame after it's been received
    charArray[3] = 0;
    while(Serial.available() == 0);          // wait for character
	if (Serial.read() == 0x10) {             // if it's a sync char read the rest of the frame
		for (int i = 0; i < 4; i++) {        // assumes 4 bytes in every frame
			while (Serial.available() == 0); // wait for next character
			charArray[i] = Serial.read();    // load char into array
		}  
		// test here for valid frame, something like
		if (charArray[3] != 0x2b || charArray[3] != 0x2c) {
			// bad frame	
		}
	}
}

void recieveMSG() {
    // 'clear" the frame in memory by dorking the last byte
    // so we can check the frame after it's been received
    charArray[3] = 0;
    while(Serial.available() == 0);            // wait for character
	if (Serial.read() == 0x10) {           // if it's a sync char read the rest of the frame
		while(Serial.available() < 4);    // assumes 4 bytes in every frame, wait for all 4
		for (int i = 0; i < 4; i++) {     
			charArray[i] = Serial.read();  // load chars into array
		}  
		// test here for valid frame, something like
		if (charArray[3] != 0x2b || charArray[3] != 0x2c) {
			// bad frame
		}
	}
}

It's late here so I hope I got them right, if not my apologies in advance :slight_smile:

NOTES:
In a real system you should do more testing for frame validity, for example what happens if you only get 3 bytes?
If the first char received is not 0x10 the func exits, maybe loop inside the func or maybe handle this outside by rapid calling of the func so you don't block on receiving a frame.
Probably should return a value indicating good/bad frame.
Other stuff I can't think of right now.


Rob

well before i read this i was working on your suggestions, had the "for" statement going,
just missed the waiting for the "Serial.available" in it .

for (int i = 0; i < 4; i++)
{ // assumes 4 bytes in every frame
while (Serial.available() == 0); // wait for next character
charArray = Serial.read(); // load char into array
The waiting for the availability is such a novice mistake, used to do PIC programming in college and serial communication all the time, i am now so out of practice i am missing the obvious things
Thank you so much once again