Go Down

Topic: Need help getting response from RS485 Slave (Read 988 times) previous topic - next topic

JT007

Mar 02, 2013, 01:58 pm Last Edit: Mar 02, 2013, 02:17 pm by JT007 Reason: 1
Code: [Select]
[code]With Nicks Gammons  RS485 Master code listed below (all be it played with by me)

http://www.gammon.com.au/forum/?id=11428  (from Nicks Site)

I want to have the slave send a response that contains data from a variable that when received by the Master can be used in my application,
the slave sends a response to a masters message but it only has a boolean response - successful transmission true/false, switching on pin 13 if false.

How can i get a  value passed back (Decimal/byte/string, any data)

My network works great for sending digital commands and i can change the channel and communicate with other slaves indepentantly.
i now want to iterogate a slave that will respond with value read from an analoge input.

I have not added the receive code as it is already available on Nicks site and would just fill the forum up with pointless amounts of code.
i would love to hear from anyone who has acheived two way comms using the RS485 Sketches and if possible could the send me a working master and slave sketch with two way communication.



[code]

#include "WConstants.h"
#include <NewSoftSerial.h>
#include "RS485_protocol.h"

NewSoftSerial rs485 (2, 3);  // receive pin, transmit pin
const byte ENABLE_PIN = 4;
int channel = 0;
int data=0;
const byte LED_PIN = 13;
int incomingByte=0; // for incoming serial data
int thousands=0; int hundreds =0; int tens =0; int ones=0;
int inByte=0;
// callback routines
 
void fWrite (const byte what)
 {
 rs485.print (what);  
 }
 
int fAvailable ()
 {
 return rs485.available ();  
 }

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

void setup()
{
 rs485.begin (28800);
  Serial.begin(9600);
 pinMode (ENABLE_PIN, OUTPUT);  // driver output enable
 pinMode (LED_PIN, OUTPUT);  // built-in LED
}  // end of setup
 
byte old_level = 0;

void loop()
{

 // read potentiometer

// byte level = analogRead (0) / 4;// commented out as it is now variable being written
 byte level = (incomingByte);
 // Serial.print(level);// print to serial monitor - for testing only
 
  if (Serial.available() > 0) {       //read value from host PC
   hostprotocol();
  }
 // no change? forget it
 if (level == old_level)
   return;
     
 // assemble message
 byte msg [] = {
    1,    // device 1
    2,    // turn light on
    level // to what level
 };

 // send to slave  
 digitalWrite (ENABLE_PIN, HIGH);  // enable sending
 sendMsg (fWrite, msg, sizeof msg);
 delayMicroseconds (660);
 digitalWrite (ENABLE_PIN, LOW);  // disable sending


The following code is where i beleive the response would arrive.
i have tried adding lines of code to read a particular buffer location ie Rxdata = (buf [1]);
and then do a println to see content but nothing happens.
any suggestions would be greatly appreciated :-

[Code:}


// receive response  
 byte buf [20];
 byte received = recvMsg (fAvailable, fRead, buf, sizeof buf);

 digitalWrite (LED_PIN, received == 0);  // turn on LED if error  
 
 // only send once per successful change
 if (received)
{
   if (buf
  • != channel)
         return;  // not my device
         
       if (buf [1] != 2)
         return;  // unknown command
       
    byte msg [] = {
          0,  // device 0 (master)
          data,  // turn light on command received
          //data

    };
     
       old_level = level;

    }

    }  // end of loop
    [/code]

    rest of master code

[Code:]

void hostprotocol()      //Serial commands received from host
{
 inByte = Serial.read();
   switch (inByte)
   {
     
case 79: //O  out

       DigitalOut();
  break;
 
 }
}
void DigitalOut() {
   
// send data only when you receive data:
Serial.print("Digital OK");
 
// only if there are bytes in the serial buffer execute the following code
 if(Serial.available()) {
 
    //keep reading and printing from serial untill there are bytes in the serial buffer
    //while (Serial.available()>0){
      if (Serial.available()>2){ // got 3 characters
       
// assume comes in as hundreds, tens, ones
hundreds = Serial.read() - 0x30;  // read the byte & convert from ASCII to a number
tens = Serial.read() - 0x30;
ones = Serial.read() - 0x30;

// now make into a digit
incomingByte =  hundreds*100 + tens*10 + ones;
   
}
Serial.print(incomingByte);
   }

//int value = (incomingByte);
}
[/code]

JT007

I copy and pasted the ifo from my last thread that was being ignored.
I know about putting the code in a code block etc.
sorry if it upsets anyone but i did try to edit the page correctly.
please dont insult me by telling me its wrong i already know
Thanks

PeterH


I know about putting the code in a code block etc.


It needs to be in [ code] [ /code] not in [ Code: } or [ Code: ]
I only provide help via the forum - please do not contact me for private consultancy.

astrofrostbyte

I would be better if you could strip down the code to its bare minimum,  it's hard to read somebody elses code , especially when its a long piece.
Can you strip down your project do a bare minimum that still has the problem you describe.

Gear: Arduino- Uno,Due,Ethernet,  OLS, Buspirate, J-Link, TDS1002, Rigol DG1022

JT007

PeterH,
did you really fail to read and understand my apology.

astrofrostbyte
The section below the code block is probably the most significant part of the code.
as wrote:

The following code is where i beleive the response would arrive.
i have tried adding lines of code to read a particular buffer location ie Rxdata = (buf [1]);
and then do a println to see content but nothing happens.
any suggestions would be greatly appreciated :-

the lines
Code: [Select]
// receive response 
  byte buf [20];
  byte received = recvMsg (fAvailable, fRead, buf, sizeof buf);

  digitalWrite (LED_PIN, received == 0);  // turn on LED if error 
 
  // only send once per successful change
  if (received)
{
    if (buf

    != channel)

     return;  // not my device
     
    if (buf [1] != 2)
      return;  // unknown command
   
byte msg [] = {
       0,  // device 0 (master)
       data,  // turn light on command received
       //data



are what happens when the slave device sends the acknowledge.

i sent the entire code because PaulS complains if i dont.

astrofrostbyte

Code: [Select]

  if (received)
  { if (buf != channel)                       <--- Do you mean buf[0]  here ?!
     return;
   ...etc....


Gear: Arduino- Uno,Due,Ethernet,  OLS, Buspirate, J-Link, TDS1002, Rigol DG1022

JT007

Hi astrofrostbyte,

yes you are right, it got messed up when i coppied it over.

The code actually works i just slipped up.

the main problem i am having is that sispite the message being returned and
The returned message being read, which it must be as the value in buffer
  • equals the channel and the result of this acknowledge is that the error LED does not light up.

    if (received)
      { if (buf
  • != channel) 
         return;
       ...etc....

    if i try to read the buffer values and print them to the monitor outside of the loop i get 0
    if i do the same inside the loop it wont compile.

    so if the values are sent and are there how can i transfer them to use them elsewher in my code
    ie. write them to variables.

    J.

PeterH

#7
Mar 03, 2013, 12:19 pm Last Edit: Mar 03, 2013, 12:25 pm by PeterH Reason: 1

did you really fail to read and understand my apology.


Did you really fail to understand that I'm explaining what the problem was? Since you were unable to put it right yourself, I thought you would want to know. Being able to post code correctly is pretty important when you're asking people for help with your code.

Your first post apparently has the complete code but this seems to be split into multiple pieces some of which are not in code sections, so it's hard to read. You need to post the whole of your actual code, within [ code ] [ /code ] tags.
I only provide help via the forum - please do not contact me for private consultancy.

astrofrostbyte

#8
Mar 03, 2013, 12:46 pm Last Edit: Mar 03, 2013, 01:08 pm by astrofrostbyte Reason: 1
Does the following line really compile ?
byte received = recvMsg (fAvailable, fRead, buf, sizeof buf);
As parameters you use a few function calls, they are missing '( )'
I don't even know the difference between  sizeof buf   and  sizeof(buf)

I would use fAvailable()  which I think will return an int stating the number of bytes in the buffer.
So before reading the buffer content , just check if there's anything there.
That should be > 0  ,  than you can read the buffer and start serial.printf the data you believe is in the buffer.

notes:
that  buf   is not the same as buf[0]

I know that PeterH is nagging a bit, but if you clean up and format your code nicely we might have found the problem already.

Gear: Arduino- Uno,Due,Ethernet,  OLS, Buspirate, J-Link, TDS1002, Rigol DG1022

Go Up