Timer1 e arresti

Ciao a tutti, neofita di arduino e di C, programmatore di plc proprietari, da poco nell’open hardware e iot.
Mi servirebbe qualche consiglio da qualcuno che conosce la piattaforma e il suo micro. non sono riuscito a capire come sistemare lo sketch per far si che proceda fino in fondo.

Mi spiego, un led deve lampeggiare con frequenza variabile da 30 a 20 Hz per 200 secondi (la frequenza scala di un tot ogni 1000ms) , ho usato il TIMER1 in CTC, sembra funzionare tutto a parte che dopo un po’ smette di contare e di scalare la frequenza.

a f=28.40 si ferma.

Altra cosa, ricorsivamente ho uno spegnimento e accensione visibile chiaramente non in frequenza.

per il timer ho preso una parte di codice che ho prima testato funzionare a frequenza fissa.

ecco lo sketch…CHI MI SPIEGA?..grazie in anticipo:

//definisco i parametri di funzionamento
#define ledPin 11 //pin su cui sta il led
#define FHI 30 //freq di inizio lavoro
#define FLO 20//freq di fine lavoro
#define TTIME 200 //tempo di lavoro


int now = millis(); //variabile tempo istantanea
float fhi = FHI;  //trasferimento costante su vatiabile (pensavo non fosse necessario ma restituiva errore nelle operazioni matematiche)
float flo = FLO; //idem
int ttime = TTIME; //idem
float f =fhi; //definizione variabile frequenza iniziale
float freqStepdown = (float)(fhi-flo)/ttime; //valore di stepdown della frequenza per ogni 1000 ms di lavoro

void setup(){
             Serial.begin(115200);
             pinMode(ledPin, OUTPUT);                 

            }


ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine

{
digitalWrite(ledPin, digitalRead(ledPin) ^ 1); // toggle LED pin
}

void loop(){
 
int cnt1 = 0; /contatore per intervenire sul timer solo quando necessario

// aggiornaento ogni 1000ms del valore di frequenza, aggiornamento della variabile tempo istantanea e imposto alto il bit per la modifica del timer1
if(millis()==now+1000){
                       f = f-freqStepdown;
                       now = millis();     
                       cnt1 = 1;
                      }
 
 float ocr_val = (float)(16000000/256)/f; //valore da inserire in OCR1A ad aggiormaneto timer
 
if(cnt1==1){
 
         //noInterrupts(); // disable all interrupts
         TCCR1A = 0;
         TCCR1B = 0;
         TCNT1 = 0;
         OCR1A = ocr_val; // compare match register 16MHz/256/2Hz
         TCCR1B |= (1 << WGM12); // CTC mode
         TCCR1B |= (1 << CS12); // 256 prescaler
         TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
         //interrupts(); // enable all interrupts

         //debug
         Serial.print("f: ");Serial.println(f);
         Serial.print("ocr_val: ");Serial.println(ocr_val);
 
         }


 

}

Prima di tutto, essendo il tuo primo post nella sezione Italiana del Forum, nel rispetto del regolamento, ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione … possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO

… poi, in conformità al suddetto regolamento, punto 7, devi editare il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

Grazie,

Guglielmo

fatto! grazie

DanielePezzana:
fatto! grazie

Fatto a metà :smiling_imp: … manca la correzione del post !

Guglielmo

aridaje, vediamo se ora va bene

... SI, ora va bene :smiley:

Guglielmo

Edit: Ti rammento che, da regolamento, è permesso fare "up" solo dopo almeno 48 ore dall'ultimo post.

ciao DanielePezzana,

forse la variabile now è meglio dichiararla come unsigned long :wink:

ORSO2001:
forse la variabile now è meglio dichiararla come unsigned long :wink:

... senza il "forse" :smiley:

Guglielmo

E come disse Funari se uno è stronzo nun je poi dí stupidino....grazie..che errore da scemo...