Olá,
Já postei a dúvida no fórum Network, Protocols and Devices, mas como estão demorando um pouco para entender, posso ter um pouco de dificuldade em entender a resposta em inglês, e o pessoal do fórum em português são muito prestativos, decidi postar aqui também.
Resumindo: consigo fazer a comunicação Master -> Slave utilizando as funções do Nick Gammon, mas não consigo enviar o feedback. Tenho um loop no Master que fica aguardando a resposta, mas o Master fica parado neste loop.
Seguem os códigos:
Master:
#include "RS485_protocol.h"
//#include <NewSoftSerial.h>
const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;
int led;
byte msg[2];
// callback routines
void fWrite (const byte what)
{
Serial.write (what);
}
int fAvailable ()
{
return Serial.available ();
}
int fRead ()
{
return Serial.read ();
}
void setup ()
{
Serial.begin (28800);
pinMode (ENABLE_PIN, OUTPUT); // driver output enable
pinMode (LED_PIN, OUTPUT); // built-in LED
led = 0;
} // end of setup
void loop ()
{
if (led == 0)
memcpy (msg, (byte[]){1,1}, sizeof msg); // device 1, turn on
else if (led == 1)
memcpy (msg, (byte[]){2,1}, sizeof msg); // device 2, turn on
else if (led == 2)
memcpy (msg, (byte[]){1,0}, sizeof msg); // device 1, turn off
else if (led == 3) {
memcpy (msg, (byte[]){2,0}, sizeof msg); // device 2, turn off
led = -1;
}
led++;
// send to slave
digitalWrite (ENABLE_PIN, HIGH); // enable sending
sendMsg (fWrite, msg, sizeof msg);
while (!(UCSR0A & (1 << UDRE0))) // Wait for empty transmit buffer
UCSR0A |= 1 << TXC0; // mark transmission not complete
while (!(UCSR0A & (1 << TXC0))); // Wait for the transmission to complete
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 */
delay (500);
} // end of loop
Slave 1:
#include "RS485_protocol.h"
const byte ENABLE_PIN = 4;
const byte LED_PIN = 13;
const byte ERROR_PIN = 9;
const byte SLAVE_NUMBER = 1;
const byte GREEN_PIN = 8;
void fWrite (const byte what)
{
Serial.print (what);
}
int fAvailable ()
{
return Serial.available ();
}
int fRead ()
{
return Serial.read ();
}
void setup()
{
Serial.begin (28800);
pinMode (ENABLE_PIN, OUTPUT); // driver output enable
pinMode (ERROR_PIN, OUTPUT);
pinMode (GREEN_PIN, OUTPUT);
pinMode (LED_PIN, OUTPUT);
digitalWrite (ENABLE_PIN, LOW);
}
void loop()
{
byte buf [20];
byte received = recvMsg (fAvailable, fRead, buf, sizeof (buf) - 1);
if (received)
{
digitalWrite (ERROR_PIN, LOW);
if (buf [0] != SLAVE_NUMBER) {
digitalWrite (GREEN_PIN, HIGH);
return; // not my device
}
digitalWrite (GREEN_PIN, LOW);
digitalWrite (LED_PIN, buf[1]); // set light level
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);
while (!(UCSR0A & (1 << UDRE0))) // Wait for empty transmit buffer
UCSR0A |= 1 << TXC0; // mark transmission not complete
while (!(UCSR0A & (1 << TXC0))); // Wait for the transmission to complete
digitalWrite (ENABLE_PIN, LOW); // disable sending
} else { // if nothing received
digitalWrite (ERROR_PIN, HIGH);
} // end receive if
} // end of loop
No Master, o LED fica sempre aceso (indicando erro na leitura), e no Slave, o LED de erro acende entre comandos bem sucedidos.
Alguma idéia?