leOS, pauseTask e restartTask!

Ciao a tutti, volevo sapere se qualcuno ha riscontrato problemi nell'utilizzo della libreria leOS, in particolare quando si mette in pausa un task e nel suo riavvio (restartTask).

Grazie a tutti.

Magari comincia spiegando i problemi che riscontri.

Si sto cercando di debuggare un po il tutto.. appena ho maggiori info comunico per ora volevo solo sapere se qualcuno ha riscontrato problemi nel mettere in pausa e riavviare un task..

Che versione usi? Nelle vecchie versioni c'era effettivamente un bug.

leo72:
Che versione usi? Nelle vecchie versioni c'era effettivamente un bug.

Quella prasa in fondo a questa pagina (il tuo sito) :slight_smile: :

http://www.leonardomiliani.com/?p=516#wpfb-file-31

quindi la versione 1.0.1a

Dici che questa versione non dovrebbe essere affetta da bug?

Non dovrebbe. In questo momento ho accanto una Leonardo con lo sketch di test "leOS_tasks_managin" che mette in pausa e riattiva ogni 5 secondi un task e sta funzionando correttamente.

leo72:
Non dovrebbe. In questo momento ho accanto una Leonardo con lo sketch di test "leOS_tasks_managin" che mette in pausa e riattiva ogni 5 secondi un task e sta funzionando correttamente.

Mmm allora in questo momento in non posso provare sull'arduino uno in cui mi si presenta il problema (dove sta anche collegato un display 16x2 e un'altro bel po di cose xD ). Ma credo di aver capito, ho appena aperto lo sketch che mi hai detto "leOS_tasks_managin" e ho notato che nei tasks sono stati utilizzati variabili con la parola chiave volatile prima. Io effettivamente nel task che ho bisogno utilizzo un paio di flag di tipo byte (tipo il tuo "volatile byte ledStatus") solo che effettivamente senza il volatile.
Il task funziona la prima volta, premendo un pulsante, questo pulsante mette in pausa i task in esecuzione e azzera i vari flag (si tratta in effetti di un ritorno al menu principale, per questo ho bisogno di fermare tutti i task e azzerare ogni tipo di variabile, tipo quelle che fanno rifermento al menu attuale..) ma se rientro la seconda volta, l'ultima cosa che ho notato prima di rientrare a casa è che, tramite un print entro nel task, ma il flag che dovrebbe servire a fare una cosa o un'altra diciamo che non risponde..

Comunque il task è questo:

void blink_delay()
{
Serial.println("sono in blink_delay"); 
if (inMenu == 1)
{
  text = !text; 
  if (text == true)
  { 
     digitalWrite(13,HIGH);
//Serial.println("testo");
    lcd.setCursor(4,1);
    lcd.print(intervalometer_delay);
  }

  if (text == false)
  {
     digitalWrite(13,LOW);
//Serial.println("spazio");
    lcd.setCursor(4,1);
    lcd.print("   ");
  }
}

}

text in questo caso è un booleano (l'ultima modifica che ho fatto)

boolean text;

La prima volta che avvio il task il led 13 si accende e si spegne, se premo il pulsante, fermo i task, rimetto text=false(anche se non dovrebbe servire), e azzero altre variabili che mi interessano, se rientro nel task, il led13 ne si accende e ne si spegne più..

Penso a qesto punto il problema sia che non uso il volatile giusto?

La parola chiave volatile impedisce al compilatore di applicare ottimizzazioni nella gestione delle variabili o delle funzioni segnate con essa. Essa è indispensabile quando si lavora con gli interrupt proprio per evitare che una variabile possa venir aggiornata all'esterno di una ISR quando essa è maneggiata dalla ISR stessa. Potrebbe essere il tuo caso.

Si deve essere per forza quello! Sennò non so più che pensare, le stavo provando di tutte fino a 3 ore fa! E ora devo aspettare fino a domani mattina per riprovare con volatile noooo...xD Darò notizie domani comunque!

Grazie!

Resto in attesa anche se prima di domani sera non ti potrò rispondere - domani giornata pienissima.

leo72:
Resto in attesa anche se prima di domani sera non ti potrò rispondere - domani giornata pienissima.

Ieri non ho potuto rispondere, allora ho risolto ma il problema non stava nel "volatile".
Procedo per passi:
-Entro la prima volta nella funzione che mi interessa.
-Si avviano i task leOS e tutto va bene.
-Si attiva tra questi un'altro task che rileva la pressione del pulsante per uscire dal menu.
-alla pressione di quel pulsante viene chiamata una funzione: returnToMenu();
-chiamato returnToMenu() la prima volta funzione tutto, ma returnToMenu() fa diverse cose, arresta i task, ripristina variabili, ed in più, spegne un led ir che utilizzo per mandare un segnale. Per spegnere il led chiamo un funzione turn_off_IR() che fa questo (se ricordi bene questa funzione mi fu data in un topic dove parlammo di una barriera ir, la funzione fa questo:

void turn_off_IR ()
{
// TCCR2A = 0; // Disconnect PWM
  //TCCR2B = 0; // Stops the timer
  //OCR2A = 0;  // No timer top
  digitalWrite(irLED, LOW);  // Ensure output is off
  
}

Ora non ho debuggato tutto ma così con quelle righe commentate non si blocca più! Uso turn_off_IR() per spegnere un led ir sul pin 11 che invia un segnale a 38Khz, credo che userò comunque il metodo che mi dicesti stesso tu per fermare il segnale ir a 38Khz, che se non ricordo male era mettere il pin 11 prima in input e poi in output..

In conclusione comunque, leOS non era, ed è sempre più un divertimento usare quei task a piacimento!:slight_smile:

Rinnovo quindi i miei complimenti per leOS :wink:

Il leOS usa il timer2 sull'Atmega328 per cui non puoi usare un'altra libreria che ne fa uso.
Vedo dalle righe di codice che hai postato che lo sketch lo modificava per cui era normale che andassero in conflitto.

Puoi in alternativa utilizzare il timer 1 impostato per generare un segnale PWM a 38 kHz.

PS:
grazie per i complimenti sul leOS, lo uso parecchio anche io perché mi semplifica tanti compiti banali :wink:

leo72:
Puoi in alternativa utilizzare il timer 1 impostato per generare un segnale PWM a 38 kHz.

Attualmente per attivare i 38khz e poi disattivarli uso queste due funzuini.

void turn_on_IR ()
{
  TCCR2A = _BV(WGM21) | _BV(COM2A0); // This mode toggles output once per timer cycle
  TCCR2B = _BV(CS20);  // Do not scale the clock down - use 16 MHz timer rate.
  OCR2A = 210; // Divide sys. clock by 210, 1/2 cycle = 76 khz, 1 cycle = 38 khz
    // Output pin 11 should now be emitting a 38 khz signal.
}

void turn_off_IR ()
{
// TCCR2A = 0; // Disconnect PWM
  //TCCR2B = 0; // Stops the timer
  //OCR2A = 0;  // No timer top
  digitalWrite(irLED, LOW);  // Ensure output is off
  
}

Quindi utilizzo il timer 2 per generare i 38khz. Se volessi quindi utilizzare il timer1 come dovrei procedere per modificare le due funzioni, o meglio, a questo punto solo l'accensione visto che turnOff() spegne solo il led..
Queste funzioni aimè sono copia e incolla quindi non saprei dove mettere mani..:confused:

Grazie

Va riscritto per il timer 1 che, però, è a 16 bit e quindi quelle istruzioni non sono immediatamente adattabili... spetta che guardo.

Ti potrebbe fare?
http://www.arduino.cc/playground/code/timer1
Puoi usare il timer 1 per impostare un segnale PWM su un qualsiasi pin, scegliendo la frequenza.

Ok, inizio a leggermi qualcosa, praticamente dovrei utilizzare quella libreria per creare i 38Khz tipo come avevi detto tu in un'altro topic:

"Ora, con la modalità FastPWM con tetto impostato da OCR2A la frequenza che si ottiene è data dalla formula:
Fpwm = Fclk / (prescaler * (max_val + 1)) / 2
La divisione per 2 è motivata dal fatto che in modalità FastPWM il canale A è cambiato di stato alternativamente per ottenere un duty cicle del 50%.

Sostituendo a max_val il valore di OCR2A+1, che è 212, abbiamo:
Fpwm = 16000000 / ( 1 * 212) = 37736 Hz"

..credo..:slight_smile:

Se usi la Timer1 non hai bisogno di modificare manualmente il timer, chiami il metodo Pwm e setti il pin e la frequenza direttamente, poi ci pensa la libreria ad impostare i registri.