Here I'm again.
I desided to create 2 RS485 networks. But I think the libray I use don't support this.
RS485a connection with slave 2 and slave 6: Both slaves gets the messages and send the response, but the master don't receive the response message.
Even when I disconnect the cable to Slave 2. Then RS485a is only connected between Master and slave 6.
RS485b connection with slave 4: This is working perfect.
Here is the Master Code declarations:
// Needed for RS485
#include <SoftwareSerial.h>
#include "RS485_protocol.h"
// rs485a Communication with Slave 2 and 6
#define SSerialTXa 50 // 42 Serial Transmit pin Groen DI
#define SSerialRXa 51 // 43 Serial Receive pin Oranje RO
const byte ENABLE_PINa = 49; // 41 Enable sending rs485 Geel DE
SoftwareSerial rs485a (SSerialRXa, SSerialTXa); // receive pin, transmit pin
// RS485b Communication with Slave 4
#define SSerialTXb 42 // 50 Serial Transmit pin Groen DI
#define SSerialRXb 43 // 51 Serial Receive pin Oranje RO
const byte ENABLE_PINb = 41; // 49Enable sending rs485 Geel DE
SoftwareSerial rs485b (SSerialRXb, SSerialTXb); // receive pin, transmit pin
elapsedMillis timerRS485;
Callback routines
// callback routines rs485
void fWritea (const byte what)
{
rs485a.write (what);
}
int fAvailablea ()
{
return rs485a.available ();
}
int fReada ()
{
return rs485a.read ();
}
// callback routines RS485b
void fWriteb (const byte what)
{
rs485b.write (what);
}
int fAvailableb ()
{
return rs485b.available ();
}
int fReadb ()
{
return rs485b.read ();
}
Setup code
rs485a.begin (19200); // Initialize serial communications with MAX485
pinMode (ENABLE_PINa, OUTPUT); // driver output enable
digitalWrite (ENABLE_PINa, LOW); // disable sending
rs485b.begin (19200); // Initialize serial communications with MAX485
pinMode (ENABLE_PINb, OUTPUT); // driver output enable
digitalWrite (ENABLE_PINb, LOW); // disable sending
Code in the Loop
int received;
if (arduino == 4) {
sendarduinoB ();
received = recvMsg (fAvailableb, fReadb, buf, sizeof(buf), 600);
} else {
sendarduinoA ();
received = recvMsg (fAvailablea, fReada, buf, sizeof(buf), 600);
}
void sendarduinoA () {
digitalWrite (ENABLE_PINa, HIGH); // enable sending
delay(2);
sendMsg (fWritea, msg, msg[3] + 4);
rs485a.flush();
digitalWrite (ENABLE_PINa, LOW); // disable sending
}
//===========================================================================
void sendarduinoB () {
digitalWrite (ENABLE_PINb, HIGH); // enable sending
delay(2);
sendMsg (fWriteb, msg, msg[3] + 4);
rs485b.flush();
digitalWrite (ENABLE_PINb, LOW); // disable sending
}
What is wrong is this code
Here again the library
RS485.protocol.h
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WConstants.h"
#endif
typedef void (*WriteCallback) (const byte what); // send a byte to serial port
typedef int (*AvailableCallback) (); // return number of bytes available
typedef int (*ReadCallback) (); // read a byte from serial port
void sendMsg (WriteCallback fSend,
const byte * data, const byte length);
int recvMsg (AvailableCallback fAvailable, ReadCallback fRead,
byte * data, const byte length,
unsigned long timeout = 500);
and the RS485_protocol.cpp
/*
RS485 protocol library.
Devised and written by Nick Gammon.
Date: 14 November 2011
Version: 1.1
Version 1.1 reset the timeout period after getting STX.
Can send from 1 to 255 bytes from one node to another with:
* Packet start indicator (STX)
* Each data byte is doubled and inverted to check validity
* Packet end indicator (ETX)
* Packet CRC (checksum)
To allow flexibility with hardware (eg. Serial, SoftwareSerial, I2C)
you provide three "callback" functions which send or receive data. Examples are:
void fWrite (const byte what)
{
Serial.write (what);
}
int fAvailable ()
{
return Serial.available ();
}
int fRead ()
{
return Serial.read ();
}
PERMISSION TO DISTRIBUTE
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
LIMITATION OF LIABILITY
The software is provided "as is", without warranty of any kind, express or implied,
including but not limited to the warranties of merchantability, fitness for a particular
purpose and noninfringement. In no event shall the authors or copyright holders be liable
for any claim, damages or other liability, whether in an action of contract,
tort or otherwise, arising from, out of or in connection with the software
or the use or other dealings in the software.
*/
#include <RS485_protocol.h>
const byte STX = '\2';
const byte ETX = '\3';
// calculate 8-bit CRC
static byte crc8 (const byte *addr, byte len)
{
byte crc = 0;
while (len--)
{
byte inbyte = *addr++;
for (byte i = 8; i; i--)
{
byte mix = (crc ^ inbyte) & 0x01;
crc >>= 1;
if (mix)
crc ^= 0x8C;
inbyte >>= 1;
} // end of for
} // end of while
return crc;
} // end of crc8
// send a byte complemented, repeated
// only values sent would be (in hex):
// 0F, 1E, 2D, 3C, 4B, 5A, 69, 78, 87, 96, A5, B4, C3, D2, E1, F0
void sendComplemented (WriteCallback fSend, const byte what)
{
byte c;
// first nibble
c = what >> 4;
fSend ((c << 4) | (c ^ 0x0F));
// second nibble
c = what & 0x0F;
fSend ((c << 4) | (c ^ 0x0F));
} // end of sendComplemented
// send a message of "length" bytes (max 255) to other end
// put STX at start, ETX at end, and add CRC
void sendMsg (WriteCallback fSend, const byte * data, const byte length)
{
fSend (STX); // STX
for (byte i = 0; i < length; i++)
sendComplemented (fSend, data [i]);
fSend (ETX); // ETX
sendComplemented (fSend, crc8 (data, length));
} // end of sendMsg
// receive a message, maximum "length" bytes, timeout after "timeout" milliseconds
// if nothing received, or an error (eg. bad CRC, bad data) return 0
// otherwise, returns length of received data
int recvMsg (AvailableCallback fAvailable, // return available count
ReadCallback fRead, // read one byte
byte * data, // buffer to receive into
const byte length, // maximum buffer size
unsigned long timeout) // milliseconds before timing out
{
unsigned long start_time = millis ();
bool have_stx = false;
// variables below are set when we get an STX
bool have_etx;
byte input_pos;
bool first_nibble;
byte current_byte;
while (millis () - start_time < timeout)
{
if (fAvailable () > 0)
{
byte inByte = fRead ();
switch (inByte)
{
case STX: // start of text
have_stx = true;
have_etx = false;
input_pos = 0;
first_nibble = true;
start_time = millis (); // reset timeout period
break;
case ETX: // end of text
have_etx = true;
break;
default:
// wait until packet officially starts
if (!have_stx)
break;
// check byte is in valid form (4 bits followed by 4 bits complemented)
if ((inByte >> 4) != ((inByte & 0x0F) ^ 0x0F) )
return -1; // bad character
// convert back
inByte >>= 4;
// high-order nibble?
if (first_nibble)
{
current_byte = inByte;
first_nibble = false;
break;
} // end of first nibble
// low-order nibble
current_byte <<= 4;
current_byte |= inByte;
first_nibble = true;
// if we have the ETX this must be the CRC
if (have_etx)
{
if (crc8 (data, input_pos) != current_byte)
return -2; // bad crc
return input_pos; // return received length
} // end if have ETX already
// keep adding if not full
if (input_pos < length)
data [input_pos++] = current_byte;
else
return -3; // overflow
break;
} // end of switch
} // end of incoming data
} // end of while not timed out
return 0; // timeout
} // end of recvMsg