Pages: 1 [2]   Go Down
Author Topic: Coda di bit  (Read 835 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 313
Posts: 21624
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Forse stai usando lo strumento sbagliato. Quella lib serve ad implementare una struttura di tipo FIFO, First In-First Out. A te serve un comune array dove andare a mettere i valori nelle celle che desideri.
Logged


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

Forse, allora cerco di spiegare meglio il problema. Ho 4 pulsanti che corrispondono a 4 relay. Premendo una sola volta ogni pulsante si scorre il menu e tenendo premuto si seleziona la voce. Selezionare la voce vuol dire attivare i relay per un certo periodo di tempo che varia a seconda della voce che si sceglie: 2, 4+4 o 8 ore. Attivare il relay per 8 ore ha più priorità del farlo per 4+4 o 2, 4+4 ha più priorità del 2. 4+4 significa che fa 4 ore e poi vede se gli altri 3 relay sono stati anche essi programmati per 8 o 4 e nel caso fa prima quelli per poi tornare a fare le sue altre 4 ore. Quindi serve una coda per gestire tutto questo, ma una coda che mi vada a inserire l'elemento che aggiungo nella giusta posizione, perché altrimenti si perderebbero le priorità. Gli elementi all'interno della coda sono byte che ho suddiviso in: primi due bit per etichettare i relay e gli altri 6 per le ore. Siccome la priorità è per le ore, devo tenere conto per l'ordine che andrò a fare sulla coda degli ultimi 6 bit che devono quindi essere in ordine decrescente. Dovrebbe essere questo lo scopo della struttura dati che mi serve... Non so se sia fattibile...
« Last Edit: August 26, 2013, 11:10:02 am by Hydrarian » Logged

ivrea (to)
Online Online
Faraday Member
**
Karma: 57
Posts: 3527
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ma i relay essendo 4, alla fine solo quattro valori devi al massimo memorizzare, giusto?
Cioè se da menu ti riselezionano es. rele2->tempo 8   mentre tu avevi già in code rele2->tempo 2  in questo caso devi togliere quel rele2->2 e mettere rele2->8 verificando anche la priorità in base al tempo?
Logged

my name is IGOR, not AIGOR

ivrea (to)
Online Online
Faraday Member
**
Karma: 57
Posts: 3527
miaaao ^-^
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Se i valori da memorizzare sono tutti, non solo quattro allora ti suggerisco di usare 3 code, una per ogni priorità.
Il programma servirà prima la coda ad alta priorità, se vuota la seconda, altrimenti la terza.
Se metti qualcosa in coda lo fai in quella con priorità giusta. A questo punto nelle varie code non devi più ordinare ma sono solo degli stack code (primo che entra primo che esce per essere servito)
mentre per i valori da memorizzare sono solo gli id dei rele (non devi più avere quella strutturazione dei bits)
Logged

my name is IGOR, not AIGOR

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

Io dico che un semplice array va più che bene. Ci sono solo 3 casi da controllare:
1) verificare se l'inserimento di un elemento porta l'array a crescere oltre la dimensione massima (e questo è facile da fare, basta usare un indice che punta all'ultima cella dell'array e quando l'indice è uguale alla dimensione, vuol dire che siamo alla situazione limite);
2) se il punto 1) è soddisfatto, controllare se la priorità dell'elemento e posizionarlo dove deve andare. Se va posto in fondo, basta aggiungerlo nella cella puntata dall'indice di cui sopra ed incrementarlo;
3) se va infilato tra gli altri elementi, basta localizzare la cella dove deve andare, spostare in avanti tutte quelle che seguono e mettere poi l'elemento nella cella.

Scrivendo un algoritmo fatto bene, i punti 2 e 3 possono diventare uno solo, dato che il caso dell'elemento da porre nell'ultima cella è identico al caso di un elemento da porre in mezzo alla lista dove, per far posto, va spostato un numero di elementi pari a 0.
Logged


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

Alla fine ho optato per 3 code perché con una era un po' un casino. Il problema ora è un altro. In una modalità , quella da 4+4 ore, in realtà devo fare devo fare in modo che le 8 ore vengano fatte consecutivamente se la coda con le modalità da 8 ore è vuota; se invece nel mentre faccio la modalità 4+4 viene premuto un altro pulsante modalità 4+4 ma per un altro relay allora vado a finire le prime quattro ore del primo per poi passare alle prime quattro del secondo e fatte queste ritornare al primo per finire il ciclo per poi andare ancora al secondo per finire anche il suo ciclo. Ho provato a stendere una funzione che lo faccia, però entrambi i relay non si fermano mai, continuano a switcharsi all'infinito. Magari è una banalità nel codice:

Code:
while (codaPR.isEmpty()==true && codaRC.isEmpty()==false){
      if (esecuzionePRY==0){ // coda vuota e nessuna ricarica o priorità in esecuzione
        if (esecuzioneRC==0){ // controlla se è in esecuzione un'operazione di ricarica  
          Serial.println("PASSO UNO PRIMA RICARICA");
          startTimeRC=millis();
          esecuzioneRC=1;
        }
        durataRC =0;     // inizializzo la durata a 0. Questo mi serve perché altrimenti ad ogni iterazione durataRC avrebbe un modulo sempre maggiore e non soddisferebbe mai il prossimo while
        byte elementoRC=codaRC.pop();  // estraggo dalla coda il primo elemento e procedo col ciclo:
        int relayRC = elementoRC >> 6;
        //primo ciclo di ricarica
        
        while (durataRC < ricarica && esecuzioneRC==1 && codaPR.isEmpty()==true && numeroRicarica==0){    // finchè il contatore non raggiunge il tempo di ricarica e finché la ricarica è attiva
          buttonVal = analogRead(buttonPin);    // continua a leggere il valore dei pulsanti per interrompere la ricarica in caso di selezione di modalità priorità
          switchPulsanti();
          durataRC = millis() - startTimeRC;
          digitalWrite(relay[relayRC], HIGH);
          //Serial.println(durataRC);
          /*Serial.print("PRESA ");
           Serial.print(estrattaRC);
           Serial.println(" RC");
           lcd.setCursor(setC,setR);  
           lcd.print(stati[1]); */
        }
        numeroRicarica=1;
        Serial.println("FUORI IL CICLO WHILE ");
        digitalWrite(relay[relayRC], LOW);
        esecuzioneRC=0;
        
        
       if (codaPR.isEmpty()==true && codaRC.isEmpty()==true /*&& codaMN.isEmpty()==true*/ && numeroRicarica==1){  //se sia la coda priorità che ricarica sono vuote allora fai subito altre 4 ore di ricarica
          if (esecuzioneRC==0){ // controlla se è in esecuzione un'operazione di ricarica  
            Serial.println("PASSO DUE (SECONDA RICARICA)");
            startTimeRC=millis();
            esecuzioneRC=1;
          }
           //secondo ciclo di ricarica quando tutte le altre code sono vuote
          
          durataRC =0;     // inizializzo la durata a 0. Questo mi serve perché altrimenti ad ogni iterazione durataRC avrebbe un modulo sempre maggiore e non soddisferebbe mai il prossimo while
          while (durataRC < ricarica && esecuzioneRC==1 && codaPR.isEmpty()==true){    // finchè il contatore non raggiunge il tempo di ricarica e finché la ricarica è attiva
            //Serial.print("DENTRO IL CICLO WHILE ");
            buttonVal = analogRead(buttonPin);    // continua a leggere il valore dei pulsanti per interrompere la ricarica in caso di selezione di modalità priorità
            switchPulsanti();
            durataRC = millis() - startTimeRC;
            digitalWrite(relay[relayRC], HIGH);
          }
        Serial.println("FUORI IL CICLO DI SECONDA RICARICA ");
        digitalWrite(relay[relayRC], LOW);
        esecuzioneRC=0;
        numeroRicarica=0;
        }
        //secondo ciclo di ricarica quando la coda priorità o quella di ricarica sono occupate
      
        else if ((codaPR.isEmpty()==false || codaRC.isEmpty()==false) && numeroRicarica==1) {  
          codaRC.push(elementoRC);
          int nrelay = elementoRC >> 6;
          Serial.print("presa ");
          Serial.print(nrelay);
          Serial.print(" aggiunta alla coda ricarica ");
         numeroRicarica=0;
        }
      }
    }
« Last Edit: August 28, 2013, 06:04:08 am by Hydrarian » Logged

Offline Offline
God Member
*****
Karma: 8
Posts: 550
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

son d'accordo con leo72 che quella libreria è solo un buffer circolare fifo( esce per primo il primo elemento che hai inserito)..dato che ti trovi in una situazione semplice,puoi cavartela come t'han descritto gli altri utenti..

in una situazione con più priorità differenti, la soluzione ideale sarebbe una coda a priorità( gli elementi escono da essa in ordine di grandezza, indipendentemente dall'ordine di inserimento)..con arduino si potrebbe risolvere(con buone prestazioni) usando un albero AVL o RN mappato su array statico, ma non è il tuo caso..
Logged

Pages: 1 [2]   Go Up
Jump to: