Pages: 1 2 3 [4] 5 6   Go Down
Author Topic: 4 Arduino Master Slave in RS485  (Read 12304 times)
0 Members and 1 Guest are viewing this topic.
Battipaglia (SA)
Offline Offline
Jr. Member
**
Karma: 0
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Come promesso ho scritto un paio di sketch, uno per il master e uno per lo slave per fare qualche prova. Si tratta di poche righe di codice tanto per cominciare a partire. In particolare, a mio avviso bisogna rivedere il byte di start (attualmente un solo byte sempre 255) per fare in modo che la sequenza di start non possa presentarsi all'interno del pacchetto.

Il codice simula l'interrogazione di 16 slaves (numerati da 1 a 16 perchè 0 è il master...). Quando interroga uno slave, attende la risposta per 5 secondi, se non la riceve invia nuovamente la richiesta allo stesso slave. Questo è utile solo per questo semplice sketch, il protocollo finale dovrà funzionare in maniera diversa (tipo isolare lo slave che non risponde...).

Il protocollo è simile a quello già discusso. Probabilmente un solo byte di dati è poco ma, ancora una volta, è solo per provare.

La funzione RS485Write disabilita la ricezione della seriale e attiva il pin che abilita la trasmissione. Attende quindi la fine della trasmissione per ripristinare il funzionamento in ricezione.

Ho usato un Arduino Mega sfruttando la Serial2. Lo slave invece utilizza Serial1. Non c'e' alcun motivo per fare questo. Nel mio caso dipende semplicemente dal fatto che ho usato due shields autocostruiti in tempi diversi sui quali avevo utilizzato due seriali diverse. Basta modificare lo sketch facendo attenzione a modificare anche i flag utilizzati nella RS485Write.

Ecco il codice del master. Scrivo quello dello slave in un post successivo.

Code:
// Protocollo
// 0 - start = 255
// 1 - sender address
// 2 - destination address
// 3 - command
// 4 - data
// 5 - checksum

int pinEnableWrite = 5;
byte idxSlave;
byte idxRead;
byte command = 1;
bool nextRequest;
unsigned long lastRequest;
unsigned long last1;

void setup()
{
Serial.begin(9600);
Serial2.begin(115200);

pinMode(pinEnableWrite, OUTPUT);     
digitalWrite(pinEnableWrite, LOW);

idxSlave = 1;
idxRead = 0;

nextRequest = true;
}

void loop()
{
if (nextRequest)
{
                            if (idxSlave == 1) last1 = millis();
               
//Serial.print("Richiesta slave: ");
//Serial.println(idxSlave, DEC);

byte buffer[6];
buffer[0] = 255;
buffer[1] = 0;
buffer[2] = idxSlave;
buffer[3] = command;
buffer[4] = 0;
buffer[5] = buffer[1] ^ buffer[2] ^ buffer[3] ^ buffer[4];

RS485Write(buffer, 6);

nextRequest = false;
lastRequest = millis();
}
else
{
unsigned long Now = millis();
if (Now - lastRequest > 5000)
{
nextRequest = true;
}
else
{
if (Serial2.available())
{
byte B = Serial2.read();

//if (idxRead == 0) Serial.print("Risposta: ");

//Serial.print(B, DEC);
//Serial.print(" ");

idxRead++;
if (idxRead == 6)
{
//Serial.println(" ");

idxRead = 0;

idxSlave++;
if (idxSlave == 17)
{
Now = millis() - last1;
Serial.print("Durata ciclo = ");
Serial.println(Now, DEC);
idxSlave = 1;
}

nextRequest = true;
}
}
}
}

delay(1);
}

void RS485Write(byte* packet, byte len)
{
UCSR2B &= ~(1<<RXEN0);  //disable RX   
UCSR2A = UCSR2A |(1 << TXC0); 
Serial2.flush();

digitalWrite(pinEnableWrite, HIGH);
Serial2.write(packet, len);

while (!(UCSR2A & (1 << TXC0))); // attendi fine trasm.

digitalWrite(pinEnableWrite, LOW);
UCSR2B |= (1<<RXEN0);   //enable RX
}


Logged

Battipaglia (SA)
Offline Offline
Jr. Member
**
Karma: 0
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ecco invece il codice dello slave.

Non avendo 16 arduino, semplicemente il codice risponde sempre a prescindere dal destination address. Tanto per customizzare la risposta, il byte di dati è uguale all'ID slave moltiplicato per due.

Il byte di checksum viene calcolato (sia nel master che nello slave) ma non viene controllato.

Il codice però attende un byte 255 per memorizzare i byte ricevuti.

Code:
// Protocollo
// 0 - sender address
// 1 - destination address
// 2 - command
// 3 - data
// 4 - checksum

int pinEnableWrite = 5;
byte command = 2;
byte idxSlave;
byte idxRead;
byte buffer[6];

void setup()
{
Serial.begin(9600);
Serial1.begin(115200);

pinMode(pinEnableWrite, OUTPUT);     
digitalWrite(pinEnableWrite, LOW);

idxRead = 0;
}

void loop()
{
if (Serial1.available())
{
buffer[idxRead] = Serial1.read();
//if (idxRead == 0) Serial.print("Richiesta: ");
//Serial.print(buffer[idxRead], DEC);
//Serial.print(" ");
if (idxRead > 0  ||  buffer[0] == 255) idxRead++;
}

if (idxRead == 6)
{
//Serial.println(" ");
//delay(10);

idxSlave = buffer[2];
buffer[0] = 255;
buffer[1] = idxSlave;
buffer[2] = 0;
buffer[3] = command;
buffer[4] = idxSlave * 2;
buffer[5] = buffer[1] ^ buffer[2] ^ buffer[3] ^ buffer[4];

RS485Write(buffer, 6);

idxRead = 0;
}

delay(1);
}

void RS485Write(byte* packet, byte len)
{
UCSR1B &= ~(1<<RXEN0);  //disable RX   
UCSR1A = UCSR1A |(1 << TXC0); 
Serial1.flush();

digitalWrite(pinEnableWrite, HIGH);
Serial1.write(packet, len);

while (!(UCSR1A & (1 << TXC0))); // attendi fine trasm.

digitalWrite(pinEnableWrite, LOW);
UCSR1B |= (1<<RXEN0);   //enable RX
}
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

5 secondi mi sembrano un'eternità..
Ed in quei 5 secondi che cosa farebbe il master? resterebbe in attesa della risposta dallo slave? Ma così potrebbe ignorare eventuali segnali di allarme degli altri slave.
Logged


Battipaglia (SA)
Offline Offline
Jr. Member
**
Karma: 0
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

no, no, aspetta... come ho scritto, questa cosa l'ho inserita solo in questo sketch di prova e soltanto perchè all'inizio ho fatto qualche prova collegando lo slave solo in un secondo momento. Fatto così, il master mi interrogava sempre lo stesso slave fino a che non lo collegavo.

Gli sketch che ho postato non vogliono essere un esempio di funzionamento reale, ma solo un punto di partenza per vedere due arduino che parlano tra loro secondo una architettura master/slave, cioè con uno che interroga e l'altro che risponde.

Avrai notato che non viene nemmeno gestito un timeout entro il quale lo slave interrogato deve rispondere.

Come ho scritto, il protocollo reale deve provvedere per esempio ad isolare lo slave che non risponde ossia deve evitare di interrogarlo ulteriormente. In particolare, il comportamento potrebbe essere il seguente:

- quando uno slave non risponde entro pochissimi ms, l'evento viene ignorato per un certo numero di volte (per esempio 3) per gestire il caso in cui lo slave è momentaneamente occupato (se questo è possibile).
- se non risponde per 3 tentativi consecutivi, viene messo in stato "DOWN" ed il master passa ad interrogarlo solo ad intervalli molto più lunghi, per esempio ogni 10 secondi (per implementare una sorta di plug&play) oppure su richiesta di una supervisione (per gestire il collegamento di un nuovo slave in maniera manuale).
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cerco di riprendere l'argomento caduto in un sonno profondo...
Abbiamo detto che l'intento è quello di creare un simple RS485 protocollo...ovviamente io non sarei in grado di svilupparlo da solo ma m'immagino che la necessità primaria sia quella di sviluppare una libreria ad-hoc.

Il progetto è quello di scrivere una libreria per un sistema di domotica e controllo domestico che preveda:

1- Il cuore del sistema il(il MASTER)penso possa essere un'Arduino Mega o Arduino 1 che colloquia con almeno 8 dispositivi SLAVE,(altri Arduino 1 o anche Arduino mini...)

2- Il progetto deve prevedere l'uso dei PIN arduino Slave come semplici IN-OUT e per stardardizzare  si può anche stabilire che ogni Arduino 1 Slave debba prevedere 6 IN e 6 OUT digitali per l'interfacciamento con sensori fumo,sensori d'allarme,stati luce...e attuatori a relè.

3- Il terminale Master riceve in tempo reale lo stato degli ingressi e uscite PIN di ogni slave e ad ogni cambio di stato di un ingresso PIN slave deve processare l'evento e far corrispondere una risposta in base alla esigenze del costruttore...

Ora partiamo col far funzionare un semplice Arduino1 come Master che preveda questo:

MASTER Arduino1:

Pin 0,1 --- non usati per lasciare libera la seriale per il debug con l'IDE
Pin 2,3 --- usati come Tx Rx per la seriale da collegare ai Max485
Pin 4,5,6,7,8 --- configurati come ingressi digitali
Pin 9,10,11,12 --- configurati come uscite digitali


Supponiamo di usare  per cominciare solo due apparati Slave con altri due Arduino1 e di configurarli come di seguito :

SLAVE1 e SLAVE2

Pin 0,1 --- non usati per lasciare libera la seriale per il debug con l'IDE
Pin 2,3 --- usati come Tx Rx per la seriale da collegare ai Max485
Pin 4,5,6,7,8 --- configurati come ingressi digitali ( collegati a pulsanti luce )
Pin 9,10,11,12 --- configurati come uscite digitali (collegati a relè passo-passo per accensione luci)
Pin A0,A1,A2,A3 --- configurati come stato sensori analogici (stato luminosità,temperatura...)

A questo punto stabiliamo le prestazioni dell'impianto :

ARDUINO slave 1 :

-Se si preme un pulsante collegato al pin 4 e si passa dallo stato Low allo stato High si deve accendere un led sul pin9 in modalità passo passo ovvero premo pulsante---accendo luce....ripremo pulsante---spengo luce
-Manda in tempo reale il valore del Pin A0 al quale è collegato un sensore luce...

ARDUINO slave 2 :

-Se si preme un pulsante collegato al pin 5 e si passa dallo stato Low allo stato High si deve accendere un led sul pin9 per 5 secondi ovvero premo pulsante---accendo luce e dopo 5 secondi si spegne
-Manda in tempo reale il valore del Pin A0 al quale è collegato un sensore temperatura...

ARDUINO master

- Controlla in tempo reale lo stato dei pulsanti degli attuatori slave e comanda le accensioni dei led sui Pin9...

E' fattibile tutto ciò ???...sviluppiamo questo protocollo oppure direttamente la libreria e se mai iniziamo mai potremo dire di averlo fatto...
Ciao un saluto a tutti...
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Per quanto riguarda il protocollo da creare stò ancora incontrando molte difficoltà nel capire i criteri per stabilire una tabella dei comandi...

Volevo provare a stilare una tabella di comandi e un protocollo molto ma molto snello senza l'uso di byte superflui...
Purtroppo senza esempi su cui lavorare e sviluppare per migliorare l'idea del simple protocollo non riesco a proseguire ...
Il tempo purtroppo è barbaro e non mi lascia troppi spazi ma se qualcuno vuole aiutarmi ne sarei grato ma solo per poter aiutare insieme qualcun'altro nella realizzazione del progetto...

Nel frattempo ho continuato nelle prove di colloquio tra un master Arduino mega e 3 slave Arduino1 e sinceramente tra una nota intonata e una stonata ho capito che comunque la missione è ardua e ho provato ad usare le librerie Simple Modbus  e Modbus ma sono almeno per me molto complesse e non prevedono una gestione snella dei comandi di ingressi-uscite per una semplice domotica...

Cerchiamo di non abbandonarlo il progetto...buona giornata a tutti...
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Per quanto riguarda il protocollo da creare stò ancora incontrando molte difficoltà nel capire i criteri per stabilire una tabella dei comandi...

Hai deciso quali saranno i comandi da trasmettere? Partiamo da lì.
Hai fatto un elenco? Pubblicalo e guardiamolo.
Logged


Battipaglia (SA)
Offline Offline
Jr. Member
**
Karma: 0
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Hai deciso quali saranno i comandi da trasmettere? Partiamo da lì.
Hai fatto un elenco? Pubblicalo e guardiamolo.

scusami leo, non sarebbe più opportuno cominciare con il definire il formato del pacchetto dati? Immagino infatti che i comandi possono anche essere aggiunti uno alla volta man mano che, durante lo sviluppo del software, si presenta la necessità di averne uno nuovo.

Tanto per essere concreti nella mia proposta sul modo di procedere, provo anche ad ipotizzare un primo formato (rivedendo e modificando quello già descritto qualche post fa...). Naturalmente se pensate sia più opportuno procedere diversamente facciamolo pure.

byte Start1;
byte Start2;
byte IDMittente;
byte IDDestinatario;
byte IDComando;
byte LunghezzaPacchetto;
... qui un numero di bytes pari a LunghezzaPacchetto
byte Checksum;

Start1 e Start2 devono avere un valore fisso, per esempio, 0xFFFF. Non so se conviene scegliere valori particolari, eviterei, per esempio, il doppio zero perchè mi sembra probabile che possa presentarsi all'interno dei dati.

Con un tale formato immagino che gli slaves restino in ascolto sulla seriale in attesa della coppia Start1/Start2. Quando la ricevono, si mettono in attesa dei quattro bytes che identificano il mittente, il destinatario, il comando e la lunghezza del pacchetto dati. Poi attendono tanti bytes quanti sono indicati nel campo LunghezzaPacchetto. Quindi attendono il Checksum e lo confrontano con quello che hanno calcolato sui dati ricevuti.

A questo punto scartano i dati ricevuti nei casi seguenti:

- l'ID destinatario non coincide con il loro (il pacchetto è destinato ad un altro slave... attenzione, non possiamo scartare subito il pacchetto perchè altrimenti rimarrebbero bytes non letti nel buffer di ricezione della seriale)
- il checksum non corrisponde (il pacchetto è corrotto...)
- durante la ricezione dei bytes attesi capita un timeout (in questo caso possono essersi persi alcuni bytes oppure la sequenza Start1/Start2 non identificava l'inizio di un pacchetto ma si è presentata all'interno dei dati e lo slave si è messo in ascolto a trasmissione iniziata. Caso estremo e forse improbabile ma da considerare per la robustezza del protocollo).

Come dicevo all'inizio del post, una volta identificato il formato, aggiungere nuovi comandi significa soltanto definire un nuovo IDComando (probabilmente l'ultimo usato + 1) ed il relativo pacchetto dati di cui avrà bisogno. Il fatto di aver definito un protocollo con pacchetto dati di lunghezza variabile ci consentirà di gestire comandi che non necessitano di parametri (LunghezzaPacchetto = 0) oppure di un numero arbitrario di bytes (LunghezzaPacchetto = n). L'interpretazione di ciascun comando poi si occuperà di capire il significato dei bytes di dati. La definizione degli IDComando avverrà nel codice del master che deve conoscerli tutti; gli slaves possono conoscere soltanto quelli che gli servono (magari ci sono slaves diversi che fanno uso di comandi diversi...) e scartano pacchetti che contengono comandi che non conoscono.

Aggiungo infine che dovremmo anche definire il comportamento del master e degli slaves in relazione ai timeout per gestire situazioni in cui uno slave interrogato non risponde. Ma questo magari è un aspetto successivo.
« Last Edit: March 04, 2013, 05:44:23 am by vittorio68 » Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Hai deciso quali saranno i comandi da trasmettere? Partiamo da lì.
Hai fatto un elenco? Pubblicalo e guardiamolo.

Caro Leo72 io in mente ho deciso quello che almeno per il momento devono essere i comandi da trasmettere e provo a pubblicare un'elenco...speriamo che possa essere comprensibile e possa essere lo spunto per iniziare finalmente a stilare uno sketch di prova molto ma molto basilare:

Arduino Mega MASTER  ID 0x00
Arduino1 SLAVE  ID 0x01
Arduino1 SLAVE  ID 0x02
Arduino1 SLAVE  ID 0x03

Ogni arduino SLAVE gestisce :
-4 Ingressi Digitali      pin 2,3,4,5
-4 Uscite Digitali        pin 6,7,8,9,10,11
-4 Ingressi Analogici    pin A0,A1,A2,A3

Arduino Mega MASTER gestisce:
-4 Ingressi Digitali    pin 2,3,4,5
-12 Uscite Digitali      pin 6,7,8,9,10,11,12,13,14,15,16,17
L'arduino Master interroga in tempo reale lo stato degli ingressi digitali,analogici e delle uscite di ogni SLAVE
Il legame che ci dovrà essere tra i 4 dispositivi almeno per adesso potrebbe essere semplicemente questo:

Step 1
ARDUINO1 Slave    Ingresso Pin2 Riposo LOW ----- Uscita Pin6 LOW ----- Master Mega  Uscita pin6 LOW
ARDUINO1 Slave    Ingresso Pin3 Riposo LOW ----- Uscita Pin7 LOW ----- Master Mega  Uscita pin7 LOW
ARDUINO1 Slave    Ingresso Pin4 Riposo LOW ----- Uscita Pin8 LOW ----- Master Mega  Uscita pin8 LOW
ARDUINO1 Slave    Ingresso Pin5 Riposo LOW ----- Uscita Pin9 LOW ----- Master Mega  Uscita pin9 LOW
ARDUINO1 Slave    Ingresso A0  ---- misura temperatura ---- trasmette il Byte all'Arduino Mega MASTER

Cambio di stato:

Step 2
ARDUINO1 Slave    Ingresso Pin2 Attivo HIGH ----- Uscita Pin6 HIGH ----- Master Mega  Uscita pin6 HIGH
ARDUINO1 Slave    Ingresso Pin3 Attivo HIGH ----- Uscita Pin7 HIGH ----- Master Mega  Uscita pin7 HIGH
ARDUINO1 Slave    Ingresso Pin4 Attivo HIGH ----- Uscita Pin8 HIGH ----- Master Mega  Uscita pin8 HIGH
ARDUINO1 Slave    Ingresso Pin5 Attivo HIGH ----- Uscita Pin9 HIGH ----- Master Mega  Uscita pin9 HIGH
ARDUINO1 Slave    Ingresso A0  ---- misura temperatura ---- trasmette il Byte all'Arduino Mega MASTER

Step 3
ARDUINO1 Slave    Ingresso Pin2 Riposo LOW ----- Uscita Pin6 LOW ----- Master Mega  Uscita pin6 LOW
ARDUINO1 Slave    Ingresso Pin3 Riposo LOW ----- Uscita Pin7 LOW ----- Master Mega  Uscita pin7 LOW
ARDUINO1 Slave    Ingresso Pin4 Riposo LOW ----- Uscita Pin8 LOW ----- Master Mega  Uscita pin8 LOW
ARDUINO1 Slave    Ingresso Pin5 Riposo LOW ----- Uscita Pin9 LOW ----- Master Mega  Uscita pin9 LOW
ARDUINO1 Slave    Ingresso A0  ---- misura temperatura ---- trasmette il Byte all'Arduino Mega MASTER

Idem per Arduino Slave 2,3, con l'unica differenza che sul Master Mega le uscite da pilotare sono per corrispondenza Slave2-pin10,11,12,13  e Slave3-pin14,15,16,17

Ora l'elenco dei comandi dovrebbe questo:

Cmd 1 = master interroga Pin  Ingresso ? Slave ?
Cmd 2 = master interroga Pin  Uscita ? Slave ?
Cmd 3 = master interroga Pin analogico ? Slave ?
Cmd 4 = master comanda stato LOW Pin Ingresso ? Slave ?
Cmd 5 = master comanda stato HIGH Pin Ingresso ? Slave ?
Cmd 6 = master .... e qui mi blocco perchè non saprei più andare avanti e comunque sia spero che quello che ho scritto sia comprensibile...

Chiaramente lo scopo di tale progetto è prettamente per uso domestico dove l'Arduino MEGA farebbe da Nodo Master centrale di casa e gli Arduini1 dislocati nelle varie stanze per monitorare pulsanti e attivare luci e rilevamento temperatura ambientale...poi a progetto avviato lo scopo sarebbe quello di installare su Arduino Mega una shield Ethernet per far visualizzare da client browser lo stato delle temperature di ogni ambente e lo stato delle luci on-off...

Dai che forse partiamo...
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

scusami leo, non sarebbe più opportuno cominciare con il definire il formato del pacchetto dati? Immagino infatti che i comandi possono anche essere aggiunti uno alla volta man mano che, durante lo sviluppo del software, si presenta la necessità di averne uno nuovo.
Concordo.

Quote
byte Start1;
byte Start2;
byte IDMittente;
byte IDDestinatario;
byte IDComando;
byte LunghezzaPacchetto;
... qui un numero di bytes pari a LunghezzaPacchetto
byte Checksum;
Perché 2 byte di start? Mi sembra inutile. Tanto hai comunque il checksum finale che ti dice se hai intercettato dati spuri sulla linea oppure no.


Quote
A questo punto scartano i dati ricevuti nei casi seguenti:

- l'ID destinatario non coincide con il loro (il pacchetto è destinato ad un altro slave... attenzione, non possiamo scartare subito il pacchetto perchè altrimenti rimarrebbero bytes non letti nel buffer di ricezione della seriale)
Questo è ovvio, devi ricevere sempre tutto e poi solo dopo fare l'analisi.

Quote
- il checksum non corrisponde (il pacchetto è corrotto...)
- durante la ricezione dei bytes attesi capita un timeout (in questo caso possono essersi persi alcuni bytes oppure la sequenza Start1/Start2 non identificava l'inizio di un pacchetto ma si è presentata all'interno dei dati e lo slave si è messo in ascolto a trasmissione iniziata. Caso estremo e forse improbabile ma da considerare per la robustezza del protocollo).

Introdurrei comunque anche un massimo nella lunghezza del pacchetto dati. Oppure un timeout di uscita, per evitare che il ciclo di ricezione resti inutilmente in attesa di una trasmissione che si interrompe a metà.

Giusto anche questo. Ci vuole il timeout perché devi sempre prevedere che la trasmissione possa interrompersi. E ci vuole anche una dimensione max del pacchetto, visto che di default la seriale ha un buffer di 32 byte (dall'IDE 1.0 in poi) per cui se arrivano più byte ed il codice non li estrae subito dal buffer, rischi che gli ultimi sovrascrivano i primi.

Quote
Aggiungo infine che dovremmo anche definire il comportamento del master e degli slaves in relazione ai timeout per gestire situazioni in cui uno slave interrogato non risponde. Ma questo magari è un aspetto successivo.
Si potrebbero definire 2 o 3 livelli di allarme, ad esempio se il comando inviato è un comando critico, si richiede una risposta entro un certo lasso di tempo, altrimenti il master interpreta la mancanza di risposta come uno stallo o problema del relativo slave.

Logged


Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@pietro78:
il tuo post è arrivato mentre stavo rispondendo a vittorio68.
Con il suo metodo uno stabilisce un protocollo generico, adattabile poi alle esigenze dei singoli utenti.
Logged


Battipaglia (SA)
Offline Offline
Jr. Member
**
Karma: 0
Posts: 72
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Perché 2 byte di start? Mi sembra inutile. Tanto hai comunque il checksum finale che ti dice se hai intercettato dati spuri sulla linea oppure no.

Avevo pensato a due byte per ridurre la possibilità che la combinazione scelta come start potesse presentarsi all'interno del pacchetto. In effetti, lo start del pacchetto, ci serve per avviare l'automa a stati che deve interpretare il pacchetto. Se il valore di start si presenta all'interno del pacchetto, l'automa comincia ad interpretare i bytes in arrivo attribuendo loro un significato diverso. Pertanto, non capirà che un certo bytes ricevuto è il cheksum del pacchetto. In effetti però mi hai fatto riflettere sul fatto che non scarterà il pacchetto per checksum errato ma piuttosto per timeout.

Non so se sono stato chiaro... ma ti chiedo comunque: che ne pensi?

Quote
Si potrebbero definire 2 o 3 livelli di allarme, ad esempio se il comando inviato è un comando critico, si richiede una risposta entro un certo lasso di tempo, altrimenti il master interpreta la mancanza di risposta come uno stallo o problema del relativo slave.

Qui mi chiedo: è possibile che uno slave risponda tardi?

Mi spiego meglio: il master interroga lo slave ed attende un certo lasso di tempo (come hai suggerito anche tu...). Se lo slave non risponde il master farà qualcosa (i livelli di allarme che proponi...). E' possibile che lo slave risponda ma lo faccia fuori dal tempo normalmente previsto? In questo caso potrebbero verificarsi collisioni sul bus dato che la risposta dello slave potrebbe scontrarsi con un eventuale nuova trasmissione del master.

Provo a rispondermi da solo.

Uno slave non è un PC che fa mille cose contemporaneamente. Quindi dovrebbe essere possibile tarare i tempi in modo che lo slave risponda sempre in tempi certi, al limite impostando il timeout del master con una certa "abbondanza", confidando sul fatto che tale timeout sarà utilizzato completamente solo molto raramente (in pratica la risposta dello slave arriverà sempre molto prima). Vi pare accettabile?
Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Peppe91...dove sei...
Fortunatamente ho trovato un IPad dimostrativo a un centro commerciale connesso a internet per rispondere...
X Leo72 ... La tabella dei comandi che ho scritto puó andare???
Se sapessi programmare il protocollo avrei fatto felici molte persone....
Il metodo autodidatta per un linguaggio C é improponibile...
Comunque aspetto e spero che gli sketch di esempio arrivino..torno a lavorare...

Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 333
Posts: 22966
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Avevo pensato a due byte per ridurre la possibilità che la combinazione scelta come start potesse presentarsi all'interno del pacchetto. In effetti, lo start del pacchetto, ci serve per avviare l'automa a stati che deve interpretare il pacchetto. Se il valore di start si presenta all'interno del pacchetto, l'automa comincia ad interpretare i bytes in arrivo attribuendo loro un significato diverso. Pertanto, non capirà che un certo bytes ricevuto è il cheksum del pacchetto. In effetti però mi hai fatto riflettere sul fatto che non scarterà il pacchetto per checksum errato ma piuttosto per timeout.

Non so se sono stato chiaro... ma ti chiedo comunque: che ne pensi?
Se lo slave sta ricevendo un pacchetto, dati non deve interpretare i byte contenuti in esso. Lui deve solo riconoscere:
1) il byte di start, ed iniziare a leggere;
2) il byte contenente il numero di byte ulteriori che deve ricevere, e questo valore non può essere confuso con altri perché è in una posizione ben precisa, e poi i byte di stop e di checksum, che arrivano in determinate posizioni (dipendenti da quanti byte sono stati trasmessi).

Quote
Qui mi chiedo: è possibile che uno slave risponda tardi?
E' possibile, pensa se ad esempio va in crash per un errore logico del programma oppure perché gli è stato chiesto un accesso ad un sensore, immaginiamo, e questo sta impiegando più tempo perché anch'esso è difettoso.
Quindi è una catena da verifica con timeout in ogni operazione critica, come hai capito anche tu.
Logged


Messina
Offline Offline
Jr. Member
**
Karma: 1
Posts: 74
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Peppe91...dove sei...
eccomi...io ci sono...purtroppo ho avuto un po di impegni e ho trascurato questo topic...non mi ero nemmeno accorto che lo avevate "riesumato"...io ancora non ho sviluppato nulla...al momento mi sto concentrando sul webserver PHP da connettere via rs232 ad arduino master....purtroppo sulla seriale sto a zero...
Logged

Pages: 1 2 3 [4] 5 6   Go Up
Jump to: