Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Sincronizzazione

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[11] Re: Sincronizzazione

Messaggioda Foto UtenteWALTERmwp » 8 lug 2019, 22:21

TheMask ha scritto:(...) per adesso sono riuscito a mettere in piedi il discorso master e slave ritardando l’avvio (...)
ma lo status quale è ?
Noi che leggiamo siamo fermi al codice del [3].
Chiedo, perché non comprendo: se i programmi devono essere uguali non ha senso introdurre un ritardo a meno che l'inserimento di questo, a causa d'una eventuale differenza tra le basi dei tempi dei due micro, non finisca per tradursi nelle determinazione di due tempi diversi, come implementare un random.
TheMask ha scritto:(...) nonostante tutto risultano lo stesso sfasati (...)
non si può solo provare a contribuire con l'immaginazione e la fantasia, occorrerebbe qualcosa su cui ragionare.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
22,1k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6371
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[12] Re: Sincronizzazione

Messaggioda Foto Utenteboiler » 9 lug 2019, 14:20

TheMask ha scritto:Mi spiego meglio...i due led lampeggiano ogni 100ms, se vado con le sonde dell'oscilloscopio vedo che hanno un disallineamento nel fronte di salita e di discesa...


Si chiama skew. Quanto puoi accettarne?
10 ms?
1 us?
20 fs?

Sono problemi diversi che richiedono soluzioni diverse.
L'hardware è definitivo o si può adattare?

Ho letto che lavori con interrupt. In casi come questo possono essere rischiosi se interrupt con priorità maggiore li mascherano.

Boiler
Avatar utente
Foto Utenteboiler
14,7k 4 7 13
G.Master EY
G.Master EY
 
Messaggi: 2522
Iscritto il: 9 nov 2011, 12:27

0
voti

[13] Re: Sincronizzazione

Messaggioda Foto UtenteTheMask » 9 lug 2019, 19:23

Avete ragione, allora vi posto un paio di porzioni di codice
File Main.c
Codice: Seleziona tutto

void main(void)
{   
   /*Wait Random*/
   (Funzione per ritardo random)
   
   while (1)
   {
      Syncro();  --> Definisce chi è il master e chi lo slave
      //Avvio lo schedulatore
      Scheduler();
   }
}


Codice della funzione Syncro:
Codice: Seleziona tutto
void Syncro(void)
{
   while(SyncState < 4)
   {
      switch(SyncState)
      {
         case 1:
            if(GPIO_ReadInputPin(RX)==0)
            {
               GPIO_WriteHigh(TX);
               SyncState = 3;
            }
            else SyncState = 2;
            break;
         case 2:
            /*Sono lo Slave*/
            Status = SLAVE;
            GPIO_WriteLow(TX)
            SyncState = 4;
            break;
         case 3:
            /*Sono il Master*/
            Status = MASTER;
            GPIO_WriteLow(TX)
            SyncState = 4;
            break;
         default:
            break;
      }
   }
}


mentre nella funzione scheduler:
Codice: Seleziona tutto
void Scheduler(void)
{
   if (flag_50ms == 1)
   {
      disableInterrupts();
      GPIO_WriteReverse(LED);
      flag_50ms = 0;
      enableInterrupts();
   }
      
   if (flag_1000ms == 1)
   {
      disableInterrupts();
      if (Status == 1 && flag_50ms == 1) SyncroOUT();
      if (Status == 0 && flag_50ms == 1) SyncroIN();
      flag_1000ms = 0;
      enableInterrupts();
   }
}

void SyncroOUT(void)
{
   GPIO_WriteHigh(TX);
   tmrISR_50ms=0;
   GPIO_WriteLow(TX);
}

void SyncroIN(void)
{
   if(GPIO_ReadInputPin(RX)!=0)
   {
      tmrISR_50ms=0;
   }
}


La parte dell'interrupt
Codice: Seleziona tutto

void TIM4_UPD_IRQHandler(void)
{
   tmrISR_50ms++

   //Timer 50ms
   if(tmrISR_50ms == 25)
   {
      flag_50ms = 1;
      tmrISR_50ms = 0;
   }
   else flag_50ms = 0;

   //Timer 1000ms
   if(tmrISR_1000ms == 500)
   {
      flag_1000ms = 1;
      tmrISR_1000ms = 0;
   }
   else flag_1000ms = 0;
   
   TIM4_ClearFlag(TIM4_FLAG_UPDATE);
}


Per rispondere a te Accetterei uno sfasamento <500us

Partono così:
1.png


e dopo un po':
2.png
Avatar utente
Foto UtenteTheMask
35 3
New entry
New entry
 
Messaggi: 72
Iscritto il: 14 gen 2015, 16:05

1
voti

[14] Re: Sincronizzazione

Messaggioda Foto Utenteboiler » 10 lug 2019, 0:06

Quello che vedi è il classico caso di un sistema plesiocrono.
La frequenza di lavoro nominale è la stessa, ma in realtà sono leggermente diverse, cosa che porta con il tempo allo scorrimento della fase tra i due clock.

Hai due possibilità per risolverlo: distribuire un clock comune a tutte le schede o sviluppare un sistema che permetta alle schede di correggere il clock locale in base alla frequenza delle altre.

Puoi avere anche piú di due schede o sono sempre al massimo due?

Boiler
Avatar utente
Foto Utenteboiler
14,7k 4 7 13
G.Master EY
G.Master EY
 
Messaggi: 2522
Iscritto il: 9 nov 2011, 12:27

0
voti

[15] Re: Sincronizzazione

Messaggioda Foto Utentedadduni » 10 lug 2019, 9:07

Io non sono minimamente all'altezza di dare consigli al fianco di boiler, quindi ascolta lui ed ignora me. Però una volta stabilito chi è il master non puoi mandare su TX un segnale di sincronia che va alto e basso insieme al led del master e periodicamente risintonizzare lo slave? Lo slave potrebbe non aver bisogno neanche di un timer, switcha quando il master gli dice di switchare
Avatar utente
Foto Utentedadduni
1.655 2 6 12
Expert EY
Expert EY
 
Messaggi: 1028
Iscritto il: 23 mag 2014, 16:26

0
voti

[16] Re: Sincronizzazione

Messaggioda Foto Utenteboiler » 10 lug 2019, 10:14

Beh, guarda caso la soluzione che stavo per proporre è proprio la tua...

L'hardware dovrebbe essere qualcosa del genere:

Hai un bus di sincronizzazione che viene tenuto alto da un pull-up su ogni scheda.
Per tirarlo basso, ogni microcontroller ha un uscita open-drain collegata e un ingresso per campionarne lo stato (ci sono micro che offrono la stessa funzione usando un solo pin, non so se è il tuo caso).

I microcontroller lavorano alla loro frequenza nominale (24 MHz o qualcosa giú di lì).

Usa uno dei timer hardware per generare un clock lento che controllerà i LED. La frequenza di lavoro deve essere tale da permetterti di gestire lo skew massimo che ti sei preposto. Quindi, per 500 us, con un po' di oversampling, ci vogliono 20 kHz (piú o meno, non è un valore critico).

Questo clock lento governa un counter. Quando il counter raggiunge il valore prefissato (che devi calcolare in base al tempo tra due impulsi), il micro accende il led, resetta il counter e aspetta che sia passato il tempo durante il quale i led sono accesi, li spegne, e così via...

Con questo programma, ogni scheda funziona per conto suo e hai il problema che hai descritto.

Per implementare la sincronizzazione ci sono un paio di approcci diversi.

First-come, first-serve
Il microcontroller accende il led quando il primo di questi due eventi si verifica:
- il counter raggiunge il valore prefissato (in questo caso, il micro è il piú veloce e deve segnalarlo agli altri abbassando la linea sense)
- la line sense viene portata a 0

Fin qui è facile: il micro piú veloce detta il momento dell'accensione. Se ci sono piú micro che in contemporanea arrivano a questo punto... chissenefrega: la linea sense è un wired-or.
Inserisci all'accensione un ritardo pari a 3-4 cicli, durante i quali il micro ignora il suo counter e ascolta solo la linea sync. In questo modo puoi "hotpluggare" una scheda.
Ora, quando spegnere il led?
Anche qui ci sono diverse possibilità:
- ogni micro lo spegne autonomamente usando il suo counter. È la soluzione piú semplice. Causa skew sullo spegnimento, ma la domanda è "quanto?". Se i clock hanno una tolleranza di 30 ppm (tipica per un buon quarzo) e l'impulso dura 500 ms avrai uno skew massimo di 15 us. Probabilmente piú che accettabile.
- dopo un breve periodo di tempo che permetta a tutti i micro di rilevare la linea di sense a 0 e accendere il led, i micro che l'hanno abbassata rilasciano il bus. Questo periodo di tempo deve essere ovviamente minore della durata dell'impulso, ma non dovrebbe essere un problema. Quando il counter del micro piú veloce raggiunge il momento di spegnere il led, la linea viene abbassata nuovamente e tutti gli altri seguono. Questa soluzione elimina lo skew in spegnimento ma introduce un potenziale problema: se una scheda viene collegata a sistema acceso, non sa se è nella fase on o off. Il problema si potrebbe presentare anche nel caso in cui un'interferenza elettromagnetica faccia "perdere un colpo" ad una scheda. Questo problema è però piú che altro teorico: allo scadere del counter, anche questa scheda spegnerebbe il led. Il problema vero si risolve con una specie di comunicazione digitale sulla linea sync iniziata dal micro che la abbassa: se dopo 2 ms il bus viene rilasciato per 1 ms e poi nuovamente abbassato, allora è una fase ON, altrimenti OFF (o qualcosa di simile).

Soft-PLL
Stesso discorso come sopra, ma gli "slave" non si limitano ad accendere e spegnere il led. Quando si accorgono che la linea sync è stata tirata bassa, memorizzano lo stato del loro counter e lo usano come valore a cui commutare per il prossimo ciclo. In sostanza calibrano la durata dei loro impulsi in base a quella imposta dal micro piú veloce.
Questa soluzione ha un paio di vantaggi:
- se il master viene allontanato dal sistema, questo continua a funzionare alla stessa velocità. Con la soluzione FCFS, la velocità cambierebbe per adeguarsi a quella del micro piú veloce.
- la correzione del tempo di accensione può essere usata per correggere anche il tempo di spegnimento (dato che derivano dallo stesso clock). In questo modo la linea sync viene usata solo per segnalare l'accensione, cosa che risolve tutti i problemi citati sopra e rende il sistema decisamente piú robusto.
Questa soluzione ha però anche uno svantaggio:
- la correzione che apporti al tempo di commutazione ha una risoluzione finita e può quindi succedere che il micro X corregga per adattarsi al micro Y (piú veloce). Dopo la correzione X commuta prima di Y. Ora sarà quest'ultimo a correggersi accelerando, e così via. Devi quindi introdurre una banda morta dentro la quale (quando sei sufficientemente vicino alla sincronia) i micro non apportano nessuna correzione ai loro tempi di commutazione.

Saluti Boiler
Avatar utente
Foto Utenteboiler
14,7k 4 7 13
G.Master EY
G.Master EY
 
Messaggi: 2522
Iscritto il: 9 nov 2011, 12:27

0
voti

[17] Re: Sincronizzazione

Messaggioda Foto UtenteTheMask » 10 lug 2019, 14:15

Ciao Grazie della risposta, stasera che torno leggo tutto. Nel frattempo ti ho inviato un MP
Avatar utente
Foto UtenteTheMask
35 3
New entry
New entry
 
Messaggi: 72
Iscritto il: 14 gen 2015, 16:05

0
voti

[18] Re: Sincronizzazione

Messaggioda Foto UtenteWALTERmwp » 10 lug 2019, 15:07

Può darsi mi sfugga quindi ancora chiedo: in base a cosa pensi che l'effetto dell'esecuzione di SyncroOUT(), nell'ambito della funzione Scheduler, possa essere certamente rilevato dall'altro micro ?
Quello che fa lo Slave quando è tale non si vede, ma ho il dubbio che quella sincronizzazione (è il proposito di SyncroOUT() ?) alla quale si associa per logica SyncroIN() sortisca l'effetto auspicato.

A mio parere, oltre a quanto scritto da @boiler, si dovesse rimanere sull'originaria configurazione hw, anche quello riportato da @dadduni ha un senso.
La linea di sync potrebbe essere sufficiente a garantire, appunto, il sincronismo.
Quell'ingresso potrebbe essere asociato ad interrput e la sua interpretazione(come evento) gestita in modo coerente per rifasare il lampeggio.
Il tutto potrebbe essere governato con ordine in base allo stato in cui si trova il micro stesso con la funzione Syncro.
In questa, poi, irrobustirei il test per il passaggio da condizione iniziale(neutra ?) o Slave che sia, a Master.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
22,1k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6371
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

0
voti

[19] Re: Sincronizzazione

Messaggioda Foto Utentedadduni » 10 lug 2019, 15:36

Butto lì un'altra idea, credo più o meno simile a quella di Boiler in qualche senso.
Due linee: una Sync e l'altra "MasterElected". Se MasterElected è alta allora c'è già un master, il micro si mette in slave e legge solo la linea Sync. Se Master Elected è bassa vuol dire che siamo ancora in fase di "elezione" (magari una prima accensione) e quindi parte il timing random, il primo che arriva alza la linea MasterElected e tutti gli altri capiscono di essere Slave.
Anche in caso di hotPlug, il nuovo slave arriverebbe con un master già eletto e segnalato già dalla linea alta e capirebbe da solo di essere slave. Se il master per qualche motivo morisse, avverrebbe una nuova elezione pagando il tempo random in cui non si perde sincronismo e ognuno va un po'come gli pare.
Avatar utente
Foto Utentedadduni
1.655 2 6 12
Expert EY
Expert EY
 
Messaggi: 1028
Iscritto il: 23 mag 2014, 16:26

0
voti

[20] Re: Sincronizzazione

Messaggioda Foto UtenteWALTERmwp » 10 lug 2019, 15:57

Il mio approccio tenderebbe a sfruttare il più possibile lo status(hw) iniziale, credo ci sia margine di miglioramento ma è uno spazio che si ricava con la modifica del sw.

Saluti
W - U.H.F.
Avatar utente
Foto UtenteWALTERmwp
22,1k 4 8 13
G.Master EY
G.Master EY
 
Messaggi: 6371
Iscritto il: 17 lug 2010, 18:42
Località: le 4 del mattino

PrecedenteProssimo

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti