Először is elnézést ha rossz topikba nyitottam, de nem találtam hardverspecifikus fórumot, majd robert átteszi a megfelelő helyére ha itt nem jó.
A képeken az angol feliratért elnézést, de próbálkoztam a nagy arduino forumon is, de feladtam a harcot mikor folyton a forráskódomat szerették volna elkérni mikor hardver a problémám alapja.
Szóval:
RS485-ön szeretnék MODBUS kommunikációt megvalósítani. Környezet: 1.0.6. RS485 illesztés ezzel:


A "hálózat"
Master: Mega2560, ethernet shield, RS485: Serial1
Slave: Nano, RS485: SoftwareSerial
Amit tapasztalok, SLAVE oldalon kiiratom a vett frame-ket:

Logikai analizerrel nézve:

Kicsit bezoomolva:

A MODBUS specifikáció miatt, az egyes frame-ek adása után a MAX485 DE lábát még 3.5 karakter hosszúságig adásban kell tartani. Viszont ha a buszon bármely MAX485 DE lába aktív akkor az összes RO (ReceiverOutput) láb magas állapotot vesz fel. Ezek az RO lábak vannak összekötve a kontrollerek RX lábaival, és erre a magas állapotra a serial.available true-t ad vissza, és nullákat olvas be a buszról.
A soros monitoron látszódó szimpla nullák oka pedig szerintem az, hogy amikor a slave ad, akkor az ő RX lába is magas állapotra kerül a MAX485 által, az adást befejezi, majd a 3,5 karakter "kitartás" miatt, nulla (néha nullák) kerülnek a vételi bufferbe, a loop következő lépcsőjében pedig ezt visszaolvassuk, erről kép:

Mint látszik oda-vissza megvannak ezek a plusz nullák, mindkét eszközön, ezért kizárnám, hogy a SoftwareSerial okozza a galibát, hisz a megán hardveres soros portot használok.
A kódban semmi trükk nincs, csak annyi hogy:
MASTER:
Kód: Egész kijelölése
void waiting_for_reply()
{
if ((*ModbusPort).available()) // is there something to check?
{
unsigned char overflowFlag = 0;
buffer = 0;
while ((*ModbusPort).available())
{
// The maximum number of bytes is limited to the serial buffer size
// of BUFFER_SIZE. If more bytes is received than the BUFFER_SIZE the
// overflow flag will be set and the serial buffer will be read until
// all the data is cleared from the receive buffer, while the slave is
// still responding.
if (overflowFlag)
(*ModbusPort).read();
else
{
if (buffer == BUFFER_SIZE)
overflowFlag = 1;
frame[buffer] = (*ModbusPort).read();
buffer++;
}
// This is not 100% correct but it will suffice.
// worst case scenario is if more than one character time expires
// while reading from the buffer then the buffer is most likely empty
// If there are more bytes after such a delay it is not supposed to
// be received and thus will force a frame_error.
delayMicroseconds(T1_5); // inter character time out
}
// The minimum buffer size from a slave can be an exception response of
// 5 bytes. If the buffer was partially filled set a frame_error.
// The maximum number of bytes in a modbus packet is 256 bytes.
// The serial buffer limits this to 64 bytes.
if ((buffer < 5) || overflowFlag)
processError();
// Modbus over serial line datasheet states that if an unexpected slave
// responded the master must do nothing and continue with the time out.
// This seems silly cause if an incorrect slave responded you would want to
// have a quick turnaround and poll the right one again. If an unexpected
// slave responded it will most likely be a frame error in any event
else if (frame[0] != packet->id) // check id returned
processError();
else
processReply();
}
else if ((millis() - delayStart) > timeout) // check timeout
{
processError();
state = IDLE; //state change, override processError() state
}
}
Kód: Egész kijelölése
while (mySerial.available())
{
// The maximum number of bytes is limited to the serial buffer size of 128 bytes
// If more bytes is received than the BUFFER_SIZE the overflow flag will be set and the
// serial buffer will be red untill all the data is cleared from the receive buffer.
if (overflow)
mySerial.read();
else
{
if (buffer == BUFFER_SIZE)
{
overflow = 1;
}
frame[buffer] = mySerial.read();
buffer++;
}
delayMicroseconds(T1_5); // inter character time out
}A serial monitoron látszódó kép a beérkezés után egyből kiiratott frame[] tömb.
A delayMicroseconds(T1_5) pedig szintén a MODBUS szabvány miatti 1,5 karakter szünet a karakterek között miatt kell.
Valaki futott már bele ilyen hibába? Ötlet, hogy hogyan lehetne ezt az "RX láb fel van húzva amikor adás van a buszon" dolgot kiküszöbölni?
Azt már próbáltam, hogy levettem a MAX485 panelről a felhúzóellenállást, és lehúztam 1K-val, nem segített, a MAX485 erősebb volt