Pages: [1]   Go Down
Author Topic: Need help getting response from RS485 Slave  (Read 810 times)
0 Members and 1 Guest are viewing this topic.
Lake District, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Electronics needs smoke to work, if it escapes its broken
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
[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]
« Last Edit: March 02, 2013, 08:17:35 am by JT007 » Logged

Lake District, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Electronics needs smoke to work, if it escapes its broken
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

UK
Offline Offline
Shannon Member
****
Karma: 222
Posts: 12524
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

It needs to be in [ code] [ /code] not in [ Code: } or [ Code: ]
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Belgium
Offline Offline
Full Member
***
Karma: 6
Posts: 135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Logged

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

Lake District, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Electronics needs smoke to work, if it escapes its broken
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
// 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.
Logged

Belgium
Offline Offline
Full Member
***
Karma: 6
Posts: 135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Logged

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

Lake District, UK
Offline Offline
Jr. Member
**
Karma: 0
Posts: 71
Electronics needs smoke to work, if it escapes its broken
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 222
Posts: 12524
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: March 03, 2013, 06:25:50 am by PeterH » Logged

I only provide help via the forum - please do not contact me for private consultancy.

Belgium
Offline Offline
Full Member
***
Karma: 6
Posts: 135
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

« Last Edit: March 03, 2013, 07:08:46 am by astrofrostbyte » Logged

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

Pages: [1]   Go Up
Jump to: