ho copiato i vari codici e ho creato questo
il tutto funziona abbastanza ma ogni tanto mi perde qualche dato ...
il byte ricevuto mi restituisce molto spesso ok , ogni tanto RX_WAIT e quando resta bloccato RX_TIMEOUT:
lo so con sara' chissa cosa ma per averlo adattato ed poi ho un problema con la codifica crc
per il momento vi ringrazio
modulo 1
- Codice: Seleziona tutto
#include <SoftwareSerial.h>
#include "supporto.h"
#define SSerialRX 10
#define SSerialTX 11
#define SSerialTxControl 3
#define RS485Transmit HIGH
#define RS485Receive LOW
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
int buttonState = 0;
byte ricevuto ;
byte old_ricevuto ;
int cont = 0;
unsigned long previousMillis = 0;
const long interval = 250;
typedef struct {
// id messaggio
uint32_t idmsg;
// id del destinatario
uint32_t destinatario;
// valori da comunicare al destinatario
uint32_t comando;
uint32_t valore;
} t_dati;
#define DIMDATI (sizeof(t_dati))
typedef struct {
t_dati dati;
uint32_t crc;
} t_pack;
#define DIMPACK (sizeof(t_pack))
//struct di ritorno
typedef struct {
uint32_t idmsg1;
uint32_t destinatario1;
uint32_t comando1;
uint32_t valore1;
} t_dati1;
#define DIMDATI1 (sizeof(t_dati1))
typedef struct {
t_dati1 dati1;
uint32_t crc;
} t_pack1;
#define DIMPACK1 (sizeof(t_pack1))
t_pack tx;
t_pack1 rx;
void setup() {
pinMode(5, INPUT_PULLUP);
pinMode(13, OUTPUT);
RS485Serial.begin(19200);
Serial.begin(9600);
Serial.println("\nTEST invio struct");
pinMode(SSerialTxControl, OUTPUT);
digitalWrite(SSerialTxControl, RS485Receive); // Init Transceiver
}
void loop() {
buttonState = digitalRead(5);
if (buttonState == HIGH) digitalWrite(13, HIGH);
else digitalWrite(13, LOW);
if (ricevuto!=old_ricevuto ){
switch (ricevuto) {
case RX_OK: // your hand is on the sensor
//lcd.setCursor(0, 1);
Serial.println("ok ");
break;
case RX_WAIT: // your hand is on the sensor
//lcd.setCursor(0, 1);
Serial.println("RX_WAIT ");
break;
case RX_TIMEOUT: // your hand is on the sensor
//lcd.setCursor(0, 1);
Serial.println("RX_TIMEOUT");
break;
case RX_HIGH: // your hand is on the sensor
//lcd.setCursor(0, 1);
Serial.println("RX_HIGH ");
break;
case RX_LOW: // your hand is on the sensor
//lcd.setCursor(0, 1);
Serial.println("RX_LOW ");
break;
}
}
old_ricevuto=ricevuto;
if (RS485Serial.available() > 0) {
ricevuto = Ricevi(RS485Serial, (unsigned char *)&rx, DIMPACK);
if (ricevuto == RX_OK) {
// i dati sono arrivati
// verifico il CRC
// if (rx.crc == calc_crc32((unsigned char *)&rx.dati, DIMDATI)) {
// i dati sono validi
// verifico che la richiesta sia per questo slave
if (rx.dati1.destinatario1 == 1) {
// faccio quello che devo fare
Serial.println(rx.dati1.valore1);
}
}
}
if (millis() - previousMillis >= interval) {
previousMillis += interval;
cont ++;
tx.dati.idmsg = millis();
tx.dati.destinatario = 1;
tx.dati.comando = buttonState;
tx.dati.valore = cont;
//tx.crc = calc_crc32((unsigned char *)&tx, DIMDATI);
digitalWrite(SSerialTxControl, RS485Transmit);
Trasmetti(RS485Serial, (unsigned char *)&tx, DIMPACK);
digitalWrite(SSerialTxControl, RS485Receive);
}
}
modulo 2
- Codice: Seleziona tutto
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#include <SoftwareSerial.h>
#include "supporto.h"
#define SSerialRX 9
#define SSerialTX 8
#define SSerialTxControl 7
#define RS485Transmit HIGH
#define RS485Receive LOW
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
byte ricevuto ;
int cont = 0;
unsigned long previousMillis = 0;
const long interval = 250;
typedef struct {
// id messaggio
uint32_t idmsg;
// id del destinatario
uint32_t destinatario;
// valori da comunicare al destinatario
uint32_t comando;
uint32_t valore;
} t_dati;
#define DIMDATI (sizeof(t_dati))
typedef struct {
t_dati dati;
uint32_t crc;
} t_pack;
#define DIMPACK (sizeof(t_pack))
//struct di ritorno
typedef struct {
uint32_t idmsg1;
uint32_t destinatario1;
uint32_t comando1;
uint32_t valore1;
} t_dati1;
#define DIMDATI1 (sizeof(t_dati1))
typedef struct {
t_dati1 dati1;
uint32_t crc;
} t_pack1;
#define DIMPACK1 (sizeof(t_pack1))
t_pack1 tx;
t_pack rx;
void setup() {
lcd.begin();
RS485Serial.begin(19200);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Menu demo");
Serial.begin(9600);
Serial.println("\nTEST invio struct");
delay(500); //wait 2 sec
pinMode(SSerialTxControl, OUTPUT);
digitalWrite(SSerialTxControl, RS485Receive); // Init Transceiver
lcd.clear(); //clear the whole LCD
}
void loop() {
switch (ricevuto) {
case RX_OK: // your hand is on the sensor
lcd.setCursor(0, 1);
lcd.print("ok ");
break;
case RX_WAIT: // your hand is on the sensor
lcd.setCursor(0, 1);
lcd.print("RX_WAIT ");
break;
case RX_TIMEOUT: // your hand is on the sensor
lcd.setCursor(0, 1);
lcd.print("RX_TIMEOUT");
break;
case RX_HIGH: // your hand is on the sensor
lcd.setCursor(0, 1);
lcd.print("RX_HIGH ");
break;
case RX_LOW: // your hand is on the sensor
lcd.setCursor(0, 1);
lcd.print("RX_LOW ");
break;
}
switch (ricevuto) {
case RX_OK: // your hand is on the sensor
lcd.setCursor(0, 1);
lcd.print("ok ");
break;
case RX_WAIT: // your hand is on the sensor
lcd.setCursor(0, 1);
lcd.print("RX_WAIT ");
break;
case RX_TIMEOUT: // your hand is on the sensor
lcd.setCursor(0, 1);
lcd.print("RX_TIMEOUT");
break;
case RX_HIGH: // your hand is on the sensor
lcd.setCursor(0, 1);
lcd.print("RX_HIGH ");
break;
case RX_LOW: // your hand is on the sensor
lcd.setCursor(0, 1);
lcd.print("RX_LOW ");
break;
}
if (RS485Serial.available() > 0) {
// sono in attesa di comandi dal master
ricevuto = Ricevi(RS485Serial, (unsigned char *)&rx, DIMPACK);
if (ricevuto == RX_OK) {
// i dati sono arrivati
// verifico il CRC
// if (rx.crc == calc_crc32((unsigned char *)&rx.dati, DIMDATI)) {
// i dati sono validi
// verifico che la richiesta sia per questo slave
if (rx.dati.destinatario == 1) {
// faccio quello che devo fare
}
lcd.setCursor(0, 0);
lcd.print(rx.dati.valore);
lcd.setCursor(0, 3);
lcd.print(rx.dati.idmsg/100);
lcd.setCursor(2, 2);
lcd.print(rx.dati.comando);
}
}
if (millis() - previousMillis >= interval) {
previousMillis += interval;
cont ++;
tx.dati1.idmsg1 = millis();
tx.dati1.destinatario1 = 1;
tx.dati1.comando1 = 99;
tx.dati1.valore1 = cont;
//tx.crc = calc_crc32((unsigned char *)&tx, DIMDATI);
digitalWrite(SSerialTxControl, RS485Transmit);
Trasmetti(RS485Serial, (unsigned char *)&tx, DIMPACK);
digitalWrite(SSerialTxControl, RS485Receive);
}
}
file supporto.h
- Codice: Seleziona tutto
//unsigned long calc_crc32(unsigned char* buf, unsigned int len)
//{
// unsigned long crc;
// unsigned int i;
// crc = 0xffffffff;
// for (i = 0; i < len; i++)
// #if defined(__SAM3X8E__)
// crc = ((crc >> 8) & 0x00ffffff) ^ crctab32[(crc ^ *buf++) & 0xff];
// #else
//crc = ((crc >> 8) & 0x00ffffff) ^ pgm_read_dword_near(&crctab32[(crc ^ *buf++) & 0xff]);
// #endif
// return (crc ^ 0xffffffff);
//}
#ifndef CHR_START
#define CHR_START '['
#endif
#ifndef CHR_STOP
#define CHR_STOP ']'
#endif
#ifndef CHR_SEP
#define CHR_SEP ','
#endif
#ifndef TIMEOUT
#define TIMEOUT 500
#endif
// - 0 = ricezione non completata
// - 1 = dati ricevuti correttamente
// - 2 = errore timeout
// - 3 = errore dati in arrivo oltre la dimensione massima
// - 4 = errore dati incompleti
#define RX_WAIT 0
#define RX_OK 1
#define RX_TIMEOUT 2
#define RX_HIGH 3
#define RX_LOW 4
// funzione che trasmette
// i dati vengono trasmessi un byte alla volta
// parametri:
// - seriale = canale su cui trasmettere (serial / HC12)
// - pacchetto = dati da trasmettere. serve un puntatore per scorrere la struttura dati un byte alla volta
// - dimensione = numero di byte da trasmettere
void Trasmetti(Stream &seriale, unsigned char * pacchetto, size_t dimensione) {
// invio il carattere di start
seriale.print(CHR_START);
// invio i dati
for (byte i = 0; i < dimensione; i++) {
seriale.print(*(pacchetto + i), HEX);
seriale.print(CHR_SEP);
}
// invio il carattere di stop
seriale.print(CHR_STOP);
return;
}
// funzion che riceve
// i dati arrivano sotto forma di caratteri che presi a 2 a 2 formano
// un byte rappresentato in HEX
// parametri:
// - seriale = canale da cui ricevere (serial / HC12)
// - pacchetto = contenitore dei dati da ricevere. serve un puntatore per scorrere la struttura dati un byte alla volta
// - dimensione = numero di byte massimo da ricevere
// ritorna:
// - 0 = ricezione non completata
// - 1 = dati ricevuti correttamente
// - 2 = errore timeout
// - 3 = errore dati in arrivo oltre la dimensione massima
// - 4 = errore dati incompleti
byte Ricevi(Stream &seriale, unsigned char * pacchetto, size_t dimensione) {
// dimensione array di appoggio
#define MAX 2
//indice del byte ricevuto all'interno della struttura di destinazione
//inizializzo con un valore fuori range massimo
static uint32_t i = dimensione;
// indice del carattere arrivato dentro l'array di appoggio
static uint8_t j = 0;
// array di appoggio per decodificare la stringa HEX in numero
static char stringa[MAX + 1] = "";
// valore millis per controllo timeout
static uint32_t inizio = millis();
// valore appena ricevuto
byte valore;
while (seriale.available()) {
valore = seriale.read();
// controllo che carattere è
switch (valore) {
case CHR_START:
// è il carattere di inizio trasmissione
// azzero gli indici
i = 0;
j = 0;
// azzero l'array di appoggio;
stringa[0] = '\0';
stringa[1] = '\0';
stringa[2] = '\0';
// faccio partire il tempo per il timeout
inizio = millis();
break;
case CHR_STOP:
// è il carattere di fine trasmissione
if (i == dimensione) {
return RX_OK;
} else {
//il terminatore è arrivato troppo presto
return RX_LOW;
}
break;
case CHR_SEP:
// è il carattere separatore
// salvo il byte
if (i < dimensione) {
*(pacchetto+i) = strtol(stringa, NULL, 16);
} else {
// ho superato la dimensione della struttura
return RX_HIGH;
}
// devo passare al byte successivo
i++;
j = 0;
// azzero l'array di appoggio;
stringa[0] = '\0';
stringa[1] = '\0';
stringa[2] = '\0';
break;
default:
// è un carattere da convertire
if (j < MAX) {
stringa[j] = valore;
j++;
}
break;
}
// controllo il timeout
if ((millis() - inizio) > TIMEOUT) {
// azzero tutto prima di restituire errore
i = 0;
j = 0;
// azzero l'array di appoggio;
stringa[0] = '\0';
stringa[1] = '\0';
stringa[2] = '\0';
return RX_TIMEOUT;
}
}
return RX_WAIT;
}

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)




