Hi There,
Welcome for All, this is my first post.
I would like to make a small Rs485 lan with Nick Gammon's Rs485 Rolling Master packet transmit protocol.
Dear Nick, Thank you for your great works! These are very-very helpful for us!
I have already made connection with 2pcs of Mega2560 and they communicating perfectly with software serial.
I really sorry, but I need to use the softSerial port for other communication (arduino GSM), therefore I would like to change the RS485 to Serial2 HW port.
I changed the labels from SoftSerial to Serial2 where I found in the origial example code...
I rearranged the port pins RX,TX to the proper place...
All of the debug LEDs functioning, the "searching leds" blinks, but the modules can not communicate...
I think it need more modification than I can do...
Here is the modificated source code:
/*
Multi-drop RS485 device control demo.
Devised and written by Nick Gammon.
Date: 7 September 2015
Version: 1.0
Licence: Released for public use.
For RS485_non_blocking library see: http://www.gammon.com.au/forum/?id=11428
For JKISS32 see: http://forum.arduino.cc/index.php?topic=263849.0
*/
#include <RS485_non_blocking.h>
#include <EEPROM.h>
// the data we broadcast to each other device
struct
 {
 byte address;
 byte switches [10];
 int status;
 } message;
const unsigned long BAUD_RATE = 4800;
const float TIME_PER_BYTE = 1.0 / (BAUD_RATE / 10.0);Â // seconds per sending one byte
const unsigned long PACKET_LENGTH = ((sizeof (message) * 2) + 6); // 2 bytes per payload byte plus STX/ETC/CRC
const unsigned long PACKET_TIME =Â TIME_PER_BYTE * PACKET_LENGTH * 1000000;Â // microseconds
// software serial pins
// transmit enable
const byte XMIT_ENABLE_PIN = 5;
// debugging pins
const byte OK_PIN = 6;
const byte TIMEOUT_PIN = 7;
const byte SEND_PIN = 8;
const byte SEARCHING_PIN = 9;
const byte ERROR_PIN = 10;
// action pins (demo)
const byte LED_PIN = 13;
const byte SWITCH_PIN = A0;
// times in microseconds
const unsigned long TIME_BETWEEN_MESSAGES = 3000;
unsigned long noMessagesTimeout;
byte nextAddress;
unsigned long lastMessageTime;
unsigned long lastCommsTime;
unsigned long randomTime;
// what state we are in
enum {
 STATE_NO_DEVICES,
 STATE_RECENT_RESPONSE,
 STATE_TIMED_OUT,
} state;
// callbacks for the non-blocking RS485 library
size_t fWrite (const byte what)
 {
 Serial2.write (what);
 }
int fAvailable ()
 {
 return Serial2.available ();
 }
int fRead ()
 {
 lastCommsTime = micros ();
 return Serial2.read ();
 }
// RS485 library instance
RS485 myChannel (fRead, fAvailable, fWrite, 20);
// from EEPROM
byte myAddress;Â Â Â Â // who we are
byte numberOfDevices;Â // maximum devices on the bus
// Initial seed for JKISS32
static unsigned long x = 123456789,
          y = 234567891,
          z = 345678912,
          w = 456789123,
          c = 0;
// Simple Random Number Generator
unsigned long JKISS32 ()
 {
 long t;
 y ^= y << 5;
 y ^= y >> 7;
 y ^= y << 22;
 t = z + w + c;
 z = w;
 c = t < 0;
 w = t & 2147483647;
 x += 1411392427;
 return x + y + w;
 } // end of JKISS32
void Seed_JKISS32 (const unsigned long newseed)
 {
 if (newseed != 0)
  {
  x = 123456789;
  y = newseed;
  z = 345678912;
  w = 456789123;
  c = 0;
  }
 } // end of Seed_JKISS32
void setup ()
 {
 Â
 // debugging prints
 Serial.begin (115200);
 // software serial for talking to other devices
 Serial2.begin (BAUD_RATE);
 // initialize the RS485 library
 myChannel.begin ();
 // debugging prints
 Serial.println ();
 Serial.println (F("Commencing"));
 myAddress = EEPROM.read (0);
 Serial.print (F("My address is "));
 Serial.println (int (myAddress));
 numberOfDevices = EEPROM.read (1);
 Serial.print (F("Max address is "));
 Serial.println (int (numberOfDevices));
 if (myAddress >= numberOfDevices)
  Serial.print (F("** WARNING ** - device number is out of range, will not be detected."));
 Serial.print (F("Packet length = "));
 Serial.print (PACKET_LENGTH);
 Serial.println (F(" bytes."));
 Serial.print (F("Packet time = "));
 Serial.print (PACKET_TIME);
 Serial.println (F(" microseconds."));
 // calculate how long to assume nothing is responding
 noMessagesTimeout = (PACKET_TIME + TIME_BETWEEN_MESSAGES) * numberOfDevices * 2;
 Serial.print (F("Timeout for no messages = "));
 Serial.print (noMessagesTimeout);
 Serial.println (F(" microseconds."));
 // set up various pins
 pinMode (XMIT_ENABLE_PIN, OUTPUT);
 // demo action pins
 pinMode (SWITCH_PIN, INPUT_PULLUP);
 pinMode (LED_PIN, OUTPUT);
 // debugging pins
 pinMode (OK_PIN, OUTPUT);
 pinMode (TIMEOUT_PIN, OUTPUT);
 pinMode (SEND_PIN, OUTPUT);
 pinMode (SEARCHING_PIN, OUTPUT);
 pinMode (ERROR_PIN, OUTPUT);
 // seed the PRNG
 Seed_JKISS32 (myAddress + 1000);
 state = STATE_NO_DEVICES;
 nextAddress = 0;
 randomTime = JKISS32 () % 500000; // microseconds
 } // end of setup
// set the next expected address, wrap around at the maximum
void setNextAddress (const byte current)
 {
 nextAddress = current;
 if (nextAddress >= numberOfDevices)
  nextAddress = 0;
 } // end of setNextAddress
// Here to process an incoming message
void processMessage ()
 {
  Serial.print (F("process message"));
 // we cannot receive a message from ourself
 // someone must have given two devices the same address
 if (message.address == myAddress)
  {
  digitalWrite (ERROR_PIN, HIGH);
  Serial.print (F("** WARNING ** self address!!"));
 Â
  while (true)
   { } // give up
  } // can't receive our address
 digitalWrite (OK_PIN, HIGH);
 // handle the incoming message, depending on who it is from and the data in it
 // make our LED match the switch of the previous device in sequence
 if (message.address == (myAddress - 1))
  digitalWrite (LED_PIN, message.switches [0]);
 digitalWrite (OK_PIN, LOW);
 } // end of processMessage
// Here to send our own message
void sendMessage ()
 {
 digitalWrite (SEND_PIN, HIGH);
 memset (&message, 0, sizeof message);
 message.address = myAddress;
 // fill in other stuff here (eg. switch positions, analog reads, etc.)
 message.switches [0] = digitalRead (SWITCH_PIN);
 // now send it
 digitalWrite (XMIT_ENABLE_PIN, HIGH); // enable sending
 delay(10);
 myChannel.sendMsg ((byte *) &message, sizeof message);
 delay(10);
 digitalWrite (XMIT_ENABLE_PIN, LOW); // disable sending
 setNextAddress (myAddress + 1);
 digitalWrite (SEND_PIN, LOW);
 lastCommsTime = micros (); // we count our own send as activity
 randomTime = JKISS32 () % 500000; // microseconds
 } // end of sendMessage
void loop ()
 {
 // incoming message?
 if (myChannel.update ())
  {
  memset (&message, 0, sizeof message);
  int len = myChannel.getLength ();
  if (len > sizeof message)
   len = sizeof message;
  memcpy (&message, myChannel.getData (), len);
  lastMessageTime = micros ();
  setNextAddress (message.address + 1);
  processMessage ();
  state = STATE_RECENT_RESPONSE;
  } // end of message completely received
 // switch states if too long a gap between messages
 if (micros () - lastMessageTime > noMessagesTimeout)
  state = STATE_NO_DEVICES;
 else if (micros () - lastCommsTime > PACKET_TIME)
  state = STATE_TIMED_OUT;
 switch (state)
  {
  // nothing heard for a long time? We'll take over then
  case STATE_NO_DEVICES:
   if (micros () - lastCommsTime >= (noMessagesTimeout + randomTime))
    {
    Serial.println (F("No devices."));
    digitalWrite (SEARCHING_PIN, HIGH);
    sendMessage ();
    digitalWrite (SEARCHING_PIN, LOW);
    }
   break;
  // we heard from another device recently
  // if it is our turn, respond
  case STATE_RECENT_RESPONSE:
   // we allow a small gap, and if it is our turn, we send our message
   if (micros () - lastCommsTime >= TIME_BETWEEN_MESSAGES && myAddress == nextAddress)
    sendMessage ();
   break;
  // a device did not respond in its slot time, move onto the next one
  case STATE_TIMED_OUT:
   digitalWrite (TIMEOUT_PIN, HIGH);
   Serial.print (F("Timeout..."));
   setNextAddress (nextAddress + 1);
   lastCommsTime += PACKET_TIME;
   digitalWrite (TIMEOUT_PIN, LOW);
   state = STATE_RECENT_RESPONSE; // pretend we got the missing response
   break;
  } // end of switch on state
 } // end of loop
Thanks for your helps!
Greg