Yop yop,
Vive les boiboites bien propre histoire de cacher un montage dégueulasse (les miens).
Sinon pour changer un peux j'ai remis mon shield eth sur ma mega, pour la partie couplage contrôleur web/bus, j'arrive à envoyer une commande avec retour de statut assé rapidement (une 20 ène de millis sec, avec bus à 112500baud).
Par contre je suis moyennement satisfait au niveau de la réactivité en ce qui concerne les commande local et statut je suis obligé de scruter tout les x ms si il y à eu un changement c'est loin d'être optimal.
Je met mon code d’expérimentation.
Code arduino (brouillon pas propre et non optimisé) :
#include <SPI.h>
#include <Ethernet.h>
#include <util/crc16.h>
#include <util/delay.h>
#include <avr/wdt.h>
#define DATA_LENGTH 6
#define ADDRESS 0x12
#define RECEIVER 0x10
#define RE_DE_ON PORTK|=128
#define RE_DE_OFF PORTK&=~(128)
#define RE_DE_REG DDRK |= 128
#define BAUD 115200
#define _WAIT(_pres) _delay_us(_pres)
#define SERIAL_BUFFER_SIZE 16
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x6D, 0x86 };
byte ip[] = { 192,168,1,109 };
Server server(9390);
Client client = 0;
volatile uint8_t listener = 0;
volatile uint32_t delayWD = 0;
uint8_t bufferBusTx[DATA_LENGTH] = {0};
volatile uint8_t bufferBusRx[SERIAL_BUFFER_SIZE] = {0};
volatile uint8_t bufferTmp[32] = {0};
volatile uint8_t pos = 0;
volatile uint8_t available = 0;
uint32_t delayB = 0;
volatile uint8_t ack = 0;
uint8_t err = 0;
const uint32_t pres = 69120000/BAUD;
const uint32_t maxRec = 14000000/BAUD;
const uint32_t maxTrans = (32640000/(BAUD/100))+((ADDRESS*(pres*2)));
ISR(USART1_RX_vect)
{
if((UCSR1B & (1<<RXB81)))
{
listener = UDR1;
if(listener == ADDRESS || listener == 0x80 || (ack && listener == 0x81))
{
UCSR1A &= ~(1<<MPCM1);
pos = 0;
available = 0;
}
else
{
UCSR1A |= (1<<MPCM1);
}
delayWD = micros()+maxTrans;
}
else
{
bufferBusRx[pos] = UDR1;
if(pos == bufferBusRx[1]+4)
{
available = pos;
pos = 0;
}
else
{
++pos;
}
}
}
////////////////////////////////////////////////////////////////////////////
void setup()
{
Ethernet.begin(mac,ip);
server.begin();
delay(1000);
RE_DE_REG;
DDRK &= ~(64);
begin(BAUD);
}
////////////////////////////////////////////////////////////////////////
void loop()
{
client = server.available();
if(client.available())
{
int i = 0;
while(client.available() > 0)
{
bufferBusTx[i] = client.read();
i+=1;
}
if(bufferBusTx[1] == 0x12 && bufferBusTx[2] == 0x12)
{
if(bufferTmp[2])
{
writeAjax(client, bufferTmp);
bufferBusTx[2] = 0;
bufferTmp[2] = 0;
}
}
else
{
while(client.connected())
{
if(available)
{
readData();
available = 0;
}
else
{
sendData();
}
}
}
client.flush();
client.stop();
}
if(available)
{
readData();
available = 0;
}
else
{
sendData();
}
}
uint8_t sendData()
{
if(bufferBusTx[2] && !listener)
{
_WAIT(pres);
writeData(bufferBusTx);
ack = 1;
}
if(listener && micros() >= delayWD)
{
listener = 0x00;
ack = 0;
}
}
void readData()
{
if(bufferBusRx[0] == 0x02 && bufferBusRx[bufferBusRx[1]+4] == 0x03) //debut de trame
{
if(checkData()) //crc ok
{
action();
}
else //sinon on retourne directement un message d'erreur crc à l'envoyeur
{
ackError(0x02);
}
}
else //sinon on retourne directement un message d'erreur general de reception
{
ackError(0x01);
}
}
void action()
{
if(bufferBusRx[4] == 0xFF || err == 2)
{
bufferBusTx[2] = 0;
_WAIT(pres);
RE_DE_ON;
write(0x00, 1);
_WAIT(pres);
RE_DE_OFF;
ack = 0;
err = 0;
if(bufferBusRx[4] == 0xFF)
{
if(client.connected())
{
writeAjax(client, bufferBusRx);
}
else
{
for(int i = 0; i <= bufferBusRx[1]+1; i++)
{
bufferTmp[i] = bufferBusRx[i];
}
}
}
}
else
{
++err;
_WAIT(pres);
writeData(bufferBusTx);
}
}
void writeAjax(Client cli, volatile uint8_t* buf)
{
client.print("{");
for(int i = 0; i <= buf[1]; i++)
{
client.print("\"i");
client.print(i);
client.print("\":");
client.print((int)buf[i+1]);
if(i < buf[1])
{
client.print(",");
}
}
client.print("}");
client.flush();
client.stop();
}
void writeData(uint8_t* data)
{
uint16_t crc = 0xFFFF;
for(uint8_t i=0; i <= data[0]; i++)
{
crc = _crc16_update(crc, data[i]);
}
RE_DE_ON;
write(data[1], 1);
write(0x02, 0);
for(uint8_t i=0; i <= data[0]; i++)
{
write(data[i], 0);
}
write(((crc & 0xFF00) >> 8), 0);
write((crc & 0x00FF), 0);
write(0x03, 0);
_WAIT(pres);
RE_DE_OFF;
}
uint8_t checkData()
{
uint16_t crc = 0xFFFF;
uint16_t _crc = (bufferBusRx[bufferBusRx[1]+2]<<8);
_crc += bufferBusRx[bufferBusRx[1]+3];
for(uint8_t i=1; i <= bufferBusRx[1]+1; i++)
{
crc = _crc16_update(crc, bufferBusRx[i]);
}
if(crc == _crc)
{
return 1;
}
return 0;
}
void ackError(uint8_t ErrorNo)
{
uint8_t data[5] = {0};
data[0] = 0x04;
data[1] = 0x81;
data[2] = ADDRESS;
data[3] = 0xFE;
data[4] = ErrorNo;
_WAIT(pres);
writeData(data);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
void write(uint8_t data, uint8_t txb8)
{
while (!((UCSR1A) & (1 << UDRE1)))
;
if(txb8)
{
UCSR1B |= (1<<TXB81);
}
else
{
UCSR1B &= ~(1<<TXB81);
}
UDR1 = data;
}
void begin(uint32_t baud)
{
uint16_t baud_setting;
UCSR1A = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2;
UBRR1H = baud_setting >> 8;
UBRR1L = baud_setting;
UCSR1A |= (1<<MPCM1);
UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1)|(1<<UCSZ12);
UCSR1C = (3<<UCSZ10);
UCSR1B &= ~(1<<UDRIE1);
}