RS485_non_Blocking ...

Hello,

I have try to change the code from the Nick Gammon Sample and library,

The code for the Master i have change is:

#include <RS485_protocol.h>
#include <SoftwareSerial.h>

const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;
const byte But = 5;

SoftwareSerial rs485(2, 3);  // receive pin, transmit pin

byte msg [2];
byte buf [10];
byte received = 0;

bool flag_High, flag_Low = false;

// 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);

  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable
  pinMode (LED_PIN, OUTPUT);  // built-in LED
  pinMode(But,INPUT);

  Serial.begin(9600);
  Serial.println("Master starting ...");

}  // end of setup



void loop(){

  //Check_Button();

  if (digitalRead(But) == HIGH && flag_High == false){
	  Serial.println("Swithch HIGH ");
	  flag_Low = false;
	  flag_High = true;


			byte msg [2] = {
					1, // Address of device
					1 // Turn On
			};   // Switch on

			digitalWrite(LED_PIN,HIGH);

			digitalWrite (ENABLE_PIN, HIGH);  // enable sending
			sendMsg (fWrite, msg, sizeof msg);
			delayMicroseconds (800);
			digitalWrite (ENABLE_PIN, LOW);  // disable sending

			 byte buf [10];
			 received = recvMsg (fAvailable, fRead, buf, sizeof buf);


		}

		if (digitalRead(But) == LOW && flag_Low == false){
			 Serial.println("Swithch LOW");
			 flag_Low = true;
			 flag_High = false;

			byte msg [2] = {
					1, // Address of device
					0 // Turn Off
			};   // Switch off

			digitalWrite(LED_PIN,LOW);

			digitalWrite (ENABLE_PIN, HIGH);  // enable sending
			sendMsg (fWrite, msg, sizeof msg);
			delayMicroseconds (800);
			digitalWrite (ENABLE_PIN, LOW);  // disable sending

			 byte buf [10];
			 received = recvMsg (fAvailable, fRead, buf, sizeof buf);


		}

		//buf [10];
		//received = recvMsg (fAvailable, fRead, buf, sizeof buf);



  digitalWrite (LED_PIN, received == 0);  // turn on LED if error


}

And for the slave it is:

#include <RS485_protocol.h>
#include <SoftwareSerial.h>

const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;

SoftwareSerial rs485(2, 3);  // receive pin, transmit pin



// 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);
  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable

  pinMode (LED_PIN, OUTPUT);  // built-in LED


  Serial.begin(9600);
  Serial.println("Starting ...");


}  // end of setup

void loop(){

 byte buf[20];

 byte received = recvMsg(fAvailable,fRead, buf, sizeof (buf)-1);

 if (received){
	 if (buf [0] != 1){
		 return;
	 }
if (buf[1] == 0) digitalWrite(LED_PIN,LOW);
if (buf[1] == 2) digitalWrite(LED_PIN,HIGH);

 }

  // assemble message
  byte msg [] = {
     0,    // device master
     1,    // turn light on
  };

  delay(10);

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



}

The above example it use the library from the Nick site http://www.gammon.com.au/forum/?id=11428 (Thank you Nick for the Great Work)

My question is how can i modify the above to use the RS485_non_blocking.h library and if the above it is ok ....

Thank you in advance.

Best Regards,
Tasos

There is example code on that page:

In what way does that not help?

Goodmorning Dear Nick,

Thank you very much for the reply,

I want to use some button in master and on slave to control some relay's, on the above example i can't take this "Serial.write (myChannel.getData (), myChannel.getLength ()); " to campare, witch button pressed for witch relay.

like the example

Switch on

// assemble message
  byte msg [] = { 
     1,    // device 1
     1,    // turn light on
  };

or switch off

// assemble message
  byte msg [] = { 
     1,    // device 1
     0,    // turn light off
  };

Thank you in advance.

Best Regards,
Tasos

What was the question? Code tags please.

How to use this forum

I am sorry :frowning:

I want to have:

Board Address 0: 4 Relays (A,B,C,D) --> Master ( I believe)

Board Address 1: 4 Buttons (A,B,C,D) --> Slave ( i believe)
Board Address 2: 4 Buttons (A,B,C,D) --> Slave ( i believe)
Board Address 3: 4 Buttons (A,B,C,D) --> Slave ( i believe)

I want from deferent place to open or close the relay, and i would like to use the RS485_non_blocking to avoid the traffic collution.

Hello again,

I was try to make a test with the bellow code and it is not working can some one please help me ?

Master Code:

#include "Arduino.h"
#include <RS485_protocol.h>
#include <SoftwareSerial.h>

const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;
const byte But = 5;

SoftwareSerial rs485(2, 3);  // receive pin, transmit pin

byte msg [2];
byte buf [10];
byte received = 0;

bool flag_High, flag_Low = false;

// 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);

  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable
  pinMode (LED_PIN, OUTPUT);  // built-in LED
  pinMode(But,INPUT);

  Serial.begin(9600);
  Serial.println("Master starting ...");

}  // end of setup



void loop(){

  //Check_Button();

  if (digitalRead(But) == HIGH && flag_High == false){
	  Serial.println("Swithch HIGH ");
	  flag_Low = false;
	  flag_High = true;


			byte msg [2] = {
					1, // Address of device
					1 // Turn On
			};   // Switch on

			digitalWrite(LED_PIN,HIGH);

			digitalWrite (ENABLE_PIN, HIGH);  // enable sending
			sendMsg (fWrite, msg, sizeof msg);
			delayMicroseconds (800);
			digitalWrite (ENABLE_PIN, LOW);  // disable sending

			 byte buf [10];
			 received = recvMsg (fAvailable, fRead, buf, sizeof buf);


		}

		if (digitalRead(But) == LOW && flag_Low == false){
			 Serial.println("Swithch LOW");
			 flag_Low = true;
			 flag_High = false;

			byte msg [2] = {
					1, // Address of device
					0 // Turn Off
			};   // Switch off

			digitalWrite(LED_PIN,LOW);

			digitalWrite (ENABLE_PIN, HIGH);  // enable sending
			sendMsg (fWrite, msg, sizeof msg);
			delayMicroseconds (800);
			digitalWrite (ENABLE_PIN, LOW);  // disable sending

			 byte buf [10];
			 received = recvMsg (fAvailable, fRead, buf, sizeof buf);


		}

		//buf [10];
		//received = recvMsg (fAvailable, fRead, buf, sizeof buf);



  digitalWrite (LED_PIN, received == 0);  // turn on LED if error


}

Slave Code:

#include "Arduino.h"
#include <RS485_protocol.h>
#include <SoftwareSerial.h>

const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;

SoftwareSerial rs485(2, 3);  // receive pin, transmit pin



// 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);
  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable

  pinMode (LED_PIN, OUTPUT);  // built-in LED


  Serial.begin(9600);
  Serial.println("Starting ...");

  digitalWrite(LED_PIN,1);
  delay(500);
  digitalWrite(LED_PIN,0);


}  // end of setup

void loop(){

 byte buf[20];

 //byte received = recvMsg(fAvailable,fRead, buf, sizeof (buf)-1);
 byte received = recvMsg(fAvailable,fRead, buf, sizeof (buf));

 //Serial.println("Waiting to receive data");
 //Serial.println(received);

 if (received ){
	 //Serial.println("I receive data");

	 if (buf [0] != 1){
		 return;
	 }
	 Serial.write(buf[0]);

if (buf[1] == 0)
	digitalWrite(LED_PIN,LOW);
if (buf[1] == 1)
	digitalWrite(LED_PIN,HIGH);

 }

  // assemble message
  byte msg [] = {
     0,    // device master
     1,    // turn light on
  };

  delay(10);

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



}

I use max487.
Pin Map:

MAX 487 Arduino
1 2
2 Gnd
3 4
4 3

7 to other 7 of MAX487
6 to other 6 of MAX487
8 +5V
5 Gnd

Not working, huh?

What do you expect to happen?
What does happen?
What do the serial prints show you?

Goodmorning Dear Nick,

Thank you for the reply,

On master i have connect a button on pin 5 and i want when i press it to swith on a led on slave at pin 13, now when the pin 5 on master to LOW then the led13 goes off for a while and then on (on master side)

When i use on slave the code

Serial.println("Waiting to receive data");
 Serial.println(received);

i got always 0

I am using Arduino V1.0.4 and i include this #include <SoftwareSerial.h> and not the NewSoftSerial is it possibol to be from this ?

The code you posted had:

 //Serial.println("Waiting to receive data");
 //Serial.println(received);

Yes you are correct, the message i got is before the commends, i use the commend just in case if i had any conflig with the SoftSerial library.

I was try and you're sample with no success :frowning:

Master

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

const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;

NewSoftSerial rs485 (2, 3);  // receive pin, transmit pin

// 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);
  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;
  
  // 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);
  digitalWrite (ENABLE_PIN, LOW);  // disable sending

  // receive response  
  byte buf [10];
  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)
    old_level = level;

}  // end of loop

Slave

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

NewSoftSerial rs485 (2, 3);  // receive pin, transmit pin
const byte ENABLE_PIN = 4;

void fWrite (const byte what)
  {
  rs485.print (what);  
  }
  
int fAvailable ()
  {
  return rs485.available ();  
  }

int fRead ()
  {
  return rs485.read ();  
  }
  
void setup()
{
  rs485.begin (28800);
  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable
}

void loop()
{
  byte buf [20];
  
  byte received = recvMsg (fAvailable, fRead, buf, sizeof (buf) - 1);
  
  if (received)
    {
    if (buf [0] != 1)
      return;  // not my device
      
    if (buf [1] != 2)
      return;  // unknown command
    
    byte msg [] = {
       0,  // device 0 (master)
       3,  // turn light on command received
    };
    
    delay (1);  // give the master a moment to prepare to receive
    digitalWrite (ENABLE_PIN, HIGH);  // enable sending
    sendMsg (fWrite, msg, sizeof msg);
    digitalWrite (ENABLE_PIN, LOW);  // disable sending
    
    analogWrite (11, buf [2]);  // set light level
   }  // end if something received
   
}  // end of loop

The only changes i do was

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

Replace with

#include "Arduino.h"
#include <SoftwareSerial.h>
#include <RS485_protocol.h>

Ok, i was correct the NewSoftSerial maybe do the tric, what i was do and i see working you're sample at least ? ( i will try and mine in a while)
I use an older version from arduino V0.19 with the NewSoftSerial library and then i see to be working :slight_smile:

Maybe you're library need's update to be working with the arduino > V1.0 ?

That page was written a while back. Nowadays use SoftwareSerial. However the library doesn't change.

Hello Dear Nick,

I try and my sample with the old version of the Arduino and working as expected, so that means should i change something to you're library ? or should i write something else to my code?

On master i have connect a button on pin 5 and i want when i press it to swith on a led on slave at pin 13, now when the pin 5 on master to LOW then the led13 goes off for a while and then on (on master side)

I don't see anything in your code about pin 5. Can you paste the actual code you are using please.

Goodmorning Dear Nick,

Here is the master code (working with arduino version until 0.23)

//#include <RS485_protocol.h>
//#include <SoftwareSerial.h>

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

const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;
const byte But = 5;

//SoftwareSerial rs485(2, 3);  // receive pin, transmit pin
NewSoftSerial rs485(2,3);

byte msg [2];
byte buf [10];
byte received = 0;

bool flag_High, flag_Low = false;

// 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);

  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable
  pinMode (LED_PIN, OUTPUT);  // built-in LED
  pinMode(But,INPUT);

  Serial.begin(9600);
  Serial.println("Master starting ...");

}  // end of setup



void loop(){

  //Check_Button();

  if (digitalRead(But) == HIGH && flag_High == false){
	  Serial.println("Swithch HIGH ");
	  flag_Low = false;
	  flag_High = true;


			byte msg [2] = {
					1, // Address of device
					1 // Turn On
			};   // Switch on

			digitalWrite(LED_PIN,HIGH);

			digitalWrite (ENABLE_PIN, HIGH);  // enable sending
			sendMsg (fWrite, msg, sizeof msg);
			delayMicroseconds (800);
			digitalWrite (ENABLE_PIN, LOW);  // disable sending

			 byte buf [10];
			 received = recvMsg (fAvailable, fRead, buf, sizeof buf);

                        digitalWrite (LED_PIN, received == 0);  // turn on LED if error

		}

		if (digitalRead(But) == LOW && flag_Low == false){
			 Serial.println("Swithch LOW");
			 flag_Low = true;
			 flag_High = false;

			byte msg [2] = {
					1, // Address of device
					0 // Turn Off
			};   // Switch off

			digitalWrite(LED_PIN,LOW);

			digitalWrite (ENABLE_PIN, HIGH);  // enable sending
			sendMsg (fWrite, msg, sizeof msg);
			delayMicroseconds (800);
			digitalWrite (ENABLE_PIN, LOW);  // disable sending

			 byte buf [10];
			 received = recvMsg (fAvailable, fRead, buf, sizeof buf);

                        digitalWrite (LED_PIN, received == 0);  // turn on LED if error

		}



}

and for slave

//#include <RS485_protocol.h>
//#include <SoftwareSerial.h>

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

const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;

//SoftwareSerial rs485(2, 3);  // receive pin, transmit pin
NewSoftSerial rs485(2,3);


// 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);
  pinMode (ENABLE_PIN, OUTPUT);  // driver output enable

  pinMode (LED_PIN, OUTPUT);  // built-in LED


  Serial.begin(9600);
  Serial.println("Starting ...");


}  // end of setup

void loop(){

 byte buf[20];

 byte received = recvMsg(fAvailable,fRead, buf, sizeof (buf)-1);

 if (received){
	 if (buf [0] != 1){
		 return;
	 }

if (buf[1] == 0) 
    digitalWrite(LED_PIN,LOW);

if (buf[1] == 2) 
    digitalWrite(LED_PIN,HIGH);

 }

  // assemble message
  byte msg [] = {
     0,    // device master
     3,    // turn light on
  };

  delay(10);

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



}

the above code is not working with the arduino version 1.05 even if i replace the NewSoftSerial with the new SoftwareSerial library. :frowning:

You send this to turn it on:

byte msg [2] = {
					1, // Address of device
					1 // Turn On
			};   // Switch on

And in the slave you test this to see if you should turn the LED on:

if (buf[1] == 2) 
    digitalWrite(LED_PIN,HIGH);

Do you see a problem here?

You are write :slight_smile: i will return from my work this afternoon and i will check, the working code it is on my laptop and i forgot to get it in my work this morning, and the code i post it is the same from the first post with the change on the library, i will upload the code later today.

I found some time and i rewrite and test it (for the old version of arduino) and here is the code ( i use to send latter this day).

Master Device

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


#define En 4
#define Led_Pin 13
#define but 5

bool flag_High,flag_Low = false;

//SoftwareSerial rs485 (2,3);
NewSoftSerial rs485 (2,3);

void fWrite (const byte what){
  rs485.print(what);
}

int fAvailable(){
  return rs485.available();

}

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

void setup()
{
  rs485.begin(28800);
  pinMode(En,OUTPUT);

  pinMode(Led_Pin,OUTPUT);
  Serial.begin(9600);
  pinMode(but,INPUT);

}

void loop(){

  if (digitalRead(but) == HIGH && flag_High == false) {
    Serial.println("Send High");
    flag_Low = false;
    flag_High = true;

    byte msg [] = {
      1, // Device 1
      1 // Turn light on
    };

    digitalWrite(Led_Pin,1);

    digitalWrite(En,HIGH);
    sendMsg(fWrite,msg,sizeof msg );
    delayMicroseconds(660);
    digitalWrite(En,LOW);

    // Receive respondd
    byte buf [10];
    byte received = recvMsg(fAvailable,fRead,buf,sizeof buf);
    digitalWrite(Led_Pin,received == 0);
  }


  if (digitalRead(but) == LOW && flag_Low == false) {
    Serial.println("Send Low");
    flag_Low = true;
    flag_High = false;

    byte msg [] = {
      1, // Device 1
      0 // Turn light on
    };

    digitalWrite(Led_Pin,1);

    digitalWrite(En,HIGH);
    sendMsg(fWrite,msg,sizeof msg );
    delayMicroseconds(660);
    digitalWrite(En,LOW);

    // Receive respondd
    byte buf [10];
    byte received = recvMsg(fAvailable,fRead,buf,sizeof buf);
    digitalWrite(Led_Pin,received == 0);
  }

}

and for Slave device

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

#define En 4     // Enable pin on Max487
#define led 13   // Light for check 

//SoftwareSerial rs485 (2,3);
NewSoftSerial rs485 (2,3);

void fWrite (const byte what){
  rs485.print(what);
}

int fAvailable(){
  return rs485.available();

}

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

void setup()
{
  rs485.begin(28800);
  pinMode(En,OUTPUT);
  Serial.begin(9600);
  pinMode(led,OUTPUT);
  digitalWrite(led,0);
  Serial.println("Startup ... ");

}

void loop()
{
  byte buf[20];
  byte received = recvMsg(fAvailable,fRead,buf,sizeof (buf)-1);


  if (received){
    if (buf [0] != 1) //1
        return;

    if (buf[1] == 0) //2
      digitalWrite(led,0);

    if (buf[1] == 1) //2
      digitalWrite(led,1);

    byte msg [] = {
      0, // Device 0 Master
      3  // turn received
    };

    delay(1);
    digitalWrite(En,HIGH);
    sendMsg(fWrite,msg,sizeof msg );
    digitalWrite(En,LOW);

  }
}

The above code it is compile with the old version of the arduino and working as i expect

I am very happy :slight_smile:

I make it to works with arduino 1.0.5

the solution is bellow ( i hoppe to help other peoples too because it is perfect library ! ! ! Thank you very much Nick for that ! ! !)

on the code

void fWrite (const byte what){
  rs485.print(what);
}

i do the bellow change and working :slight_smile:

void fWrite (const byte what){
  rs485.write(what);
}

Thank you Dear Nick for the replys ! ! !

Happy code to everyone :wink:

Thanks for reporting the solution. I upgraded my page to reflect that. That part was old anyway as it used NewSoftwareSerial rather than SoftwareSerial.