Vai al contenuto
PLC Forum


perchè mi sbaglia i tempi? Tiny13


kym

Messaggi consigliati

Buonasera ragazzi e non,

 

ho un problemino che mi sta cruciando da una nottata, questo codice dovrebbe fare questa cosa:

 

ACC-ON ------> accensione apparecchio dopo 10 secondi (simula la pressione di un pulsante momentaneo per 1s)

ACC-OFF-----> inibire l'accensione per 5 secondi entro i quali se ritorna ACC-ON non deve succedere nulla

 

dopo i 5 secondi perdurando il LOW il ciclo si ripeterà quando si riaccenderà l'auto.

 

Il pin 3 è collegato in pull down con una resistenza da 10K verso massa e con una da 1K al +15 dell'auto (il contatto diciamo sotto chiave del quadro) quindi è sempre LOW salvo quando viene attivato il quadro.

 

Succede questo: 

 

i 10 secondi sono almeno 14s

i 5 secondi sono meno di 1s (in pratica se ad auto accesa spengo-riaccendo si ripete il ciclo andando in realtà a spegnere tutto perchè la variabile LAST nonosante non siano passati assolutamente 5 secondi diventa TRUE

 

Il core usato è il 2.20 (core13) per tiny13 e mi viene il dubbio che il problema sia il core ma non ne sono sicuro.

 

Ho provato in tutte le combinazioni di clock, con il divider/8  e senza usando 9600-4800 (1200-600) e anche 128 che nella variante divisa/8 mi ha briccato il micro.... Non contento ho fatto altre prove e ne ho briccati 10 poi non avendone più ho dovuto montare su una breadboard un fuse resetter per ripristinarli tutti:roflmao:

 

Ma il problema non l'ho risolto nemmeno dopo, e son punto e a capo, il codice è questo:

 

int last = false;
int memotempo = 0;

void setup() {
  pinMode(0, OUTPUT);
  pinMode(3, INPUT);
  digitalWrite(0, HIGH);
}

void loop() {

  if ((digitalRead(3) == HIGH) && (last == false)) {
    delay(10000);
    digitalWrite(0, LOW);
    delay(1000);
    digitalWrite(0, HIGH);
    last = true;
  }


  if ((digitalRead(3) == LOW) && (last == true)) {
    memotempo = millis();
    if (millis() - memotempo >= 5000) {
      last = false;
    }
  }
}

 

Link al commento
Condividi su altri siti


Perchè invece di usare i delay() e altri metodo da luigi non fai le cose correttamente?

Un bel interrupt sul timer1 programmato in modo da avere, ad esempio, un interrupt ohni 10ms che te lo usi come clock di sitema.

Ti fai dei semplici contatori nella routine di servizio che programmi per avere 10" (100) e 5"(500).

 

Io ho sempre fatto così da almeno 40 anni e non ho mai avuto errori di temporizzazione con i micro.

Link al commento
Condividi su altri siti

Ciao Livio, ora ci guardo se non richiede tanti comandi (ho solo 1024 KB) lo provo non l'ho mai provato.

Però con i millis non dovrebbe sbagliare, i delay gli ho dovuti usare perchè se uso i millis anche li non ho lo spazio nel micro.

 

E comunque non dovrebbe sbagliare, perchè secondo te sbaglia?

 

Quindi se lo lego all'interrupt devo fare un pò di conti:

 

partendo dal clock originario 9600Khz ---> div/8 ----> 1200Khz = 1.200.000 cicli secondo (Hz)

devo dirgli che 10ms è 1 ciclo: come si fa? senza fargli fare calcoli e memorizzazioni di variabili varie

 

 

Link al commento
Condividi su altri siti

Ho guardato un poco meglio il tuo programma, i tempi son determinati dai delay() e dall'istruzione mills().

In teoria non dovrebbero esserci errori, solo che l'istruzione delay() è bloccante ed è basata sul timer0. Se tu non hai manipolato il timer0 per altri tuoi scopi, il programma arrivati a delay(10000) sta lì bello fermo ed attende che sian trascorsi 10", idem quando arriva a delay(1000) si ferma per 1".

 

Provalo al banco e verifica se si comporta differentemente.

 

Usando il temporizzatore che ti ho descritto risparmi anche codice, quindi non hai problemi di lunghezza di programma.

Link al commento
Condividi su altri siti

Ce l'ho a banco, ho il micro su una breadboard i fili ed un led con l'anodo al +5 e il catodo al pin 0 il pulsante dell'autoradio manda a massa un pin.

 

Non fa altro il codice è tutto quello che ho scritto, deve solo accendere l'autoradio/monitor in auto all'accensione del quadro.

L'apparecchio ha di serie l'autospegnimento dopo 5 secondi che viene a mancare il +15  (è alimentato anche al +30).

 

E' banale ma sbaglia alla grande, secondo me è colpa del core del tiny13 non mi viene in mente altro.

Approfondisco comunque il discorso interrupt che viene comunque sempre bene il "sapere".

Link al commento
Condividi su altri siti

Quote

E' banale ma sbaglia alla grande,

 

Fai un programmino, sul tipo di quello dell'esempio che fa blinkare un  LED e lo invii ad un'uscita. Poi misuri il tempo con un  contatore o con l'oscilloscopio 8anche se non è facile).
 

Quote


Approfondisco comunque il discorso interrupt

 

 

se vuoi ti metto le 4 righe di codice per programmare il timer e per servire l'interrupt.

Link al commento
Condividi su altri siti

Quote

se vuoi ti metto le 4 righe di codice per programmare il timer e per servire l'interrupt.

 

Si grazie Livio, soprattutto perchè non ho capito come fare il calcolo dei cicli per avere 1 ciclo 10ms come dicevi all'inizio.

 

Si ora provo a metterci il blink d'esempio e a misurare con l'oscilloscopio il blink se non ricordo male è 1on1off a ripetizione quindi dovrei vederlo nettamente.

Ora cosa che non ho fatto perchè voglio capire, provo ad usare lo stesso codice su un tiny85 o altro vediamo se è proprio un problema del tiny13 come penso perchè con atmega328 funziona perfettamente.

Link al commento
Condividi su altri siti

Allora, ecco le due righe promesse.
 

Quote

 


void setup

  {

     -----------------

     noInterrupts();

     TCCRIA = 0;

     TCCRIB = 0;
	 TCNT = 6491; //preset timer per avere 10 ms con clock da quarzo a 16MHz
	 TCCRIB |= (1 << CSI2);
	 TMSK1 |= (1 << TOIE1);
}

ISR (TIMER1_OVF_vect)
 {
	 TCNT = 6491; //ricarica timer

    ........
    scrivi eventuali conteggi come, ad esempio,
	tempo1--;
    if (tempo1 == 0);
      {
		tempo1 = 10; //ricarico temporizzatore per 100ms
		digitalWrite (9, digitalRead(9)^1); // genero un'oda quadra con periodo di 20ms su pin 9
	  }
 }

 

 

Link al commento
Condividi su altri siti

Livio non c'è verso il tiny 13 sbaglia i tempi anche così, il tiny85 invece va bene (altro core).

In più ho letto cercando e ricercando che il core13 (come avevo supposto io) è fatto male per questo i mils non vanno.

Se pensi che i giri che gli ho detto di contare fanno durare il led acceso dai 4 ai 7 secondi ........ ho detto tutto.

Fuse 6A & FF (default 9.6Mhz con div/8 = 1.2Mhz)

 

#include <avr/interrupt.h>;

int yellow = 3;
volatile long int giri = 0;

void setup()
{
  GIMSK = 0b00100000;    // turns on pin change interrupts
  PCMSK = 0b00000001;    // turn on interrupts on pins PB0
  sei();                 // enables interrupts
  pinMode(yellow, OUTPUT);
  digitalWrite(yellow, LOW);
}

void loop() {
  giri++;

   
  if ( giri == 240000 )
  {
    giri = 0;
    digitalWrite(yellow, LOW);
  }
}

ISR(PCINT0_vect)
{
  digitalWrite(yellow, HIGH);
}

Link al commento
Condividi su altri siti

Quote

In più ho letto cercando e ricercando che il core13 (come avevo supposto io) è fatto male

 

Ma io non ci credo che sia "fatto male". Ci saranno problemi di compatibilità, oppure c'è qualche altra cosa che sfrucuglia il timer0.

E' il solito problema di usare librerie che non si conoscono nel dettaglio.

Se usi la base di arduino timer0 te lo devi dimenticare.

Prova a programamre il timer1 come dal mio esempio e poi verifica.

Link al commento
Condividi su altri siti

Il tuo esempio e per atmega16mhz non va con i tiny. 

 

Non c'è niente nessuna libreria o altro l'include sopra penso nemmeno conti l'ho usato per altro esempio con i comandi arduino poi ho scritto proprio tutto come datasheet e poi conta solo i giri che fa il loop più semplice di così. Vuol dire che il loop non viene fatto girare alla frequenza del micro. Si Livio il core pare sia fatto male se cerchi in rete c'è un altro che si lamenta dei tempi sbagliati con il millis e delay. Con il tiny85 funziona ad esempio però usa un altro core. 

 

 

Link al commento
Condividi su altri siti

Un altra delle cose che non vanno con il core 13 e l'esportazione dell'hex ed ho dovuto modificare il file che lo configura altrimenti dava una sequenza di errori quando compilavi. Peccato. Pare sia pure abbandonato in favore di altri micro. Io ne ho presi una caterva di questi 13.... Per alcune cose piccole potevano andare bene e ti dirò nei delay non sballano tanto un paio di secondi con armel studio si può fare anche la calibrazione devo provare ma penso che poi se non carico l'hex con atmel studio si cancelli la calibrazione. 

 

Ti volevo chiedere una cosa sui sensori ottici conta pezzi mi pare tu li conosca bene apro altra discussione o ti chiedo qui? A me servono per una funzione bizzarra forse. 

Link al commento
Condividi su altri siti

Ma non ci credo che sia in commercio da anii un micro con il core diettoso.

Poi se il tiny ha dei contatori deve funzionare anche ilmio esempio, al limite ci sarà da variare il nome del registro. Confronta i data sheets dei 2 micro.

 

Apri un'altra discussione per i sensori ottici.

Link al commento
Condividi su altri siti

Livio quando dico core mi riferisco all'aggiunta che fa si che sia compatibile con l'ide di Arduino.

Quello è difettato, cioè non compila correttamente il micro.

Sicuramente se lo programmassi in atmel studio non ci sarebbero problemi.

Link al commento
Condividi su altri siti

Quote

Livio quando dico core mi riferisco all'aggiunta che fa si che sia compatibile con l'ide di Arduino.

 

Quando si parla di core di un micro si intende iol core Hw.:smile:

Se ci si riferisce Sw al limite si può parlare di kernel. ma in questo caso si tratta di un'applicazione dell'ide di arduino.

Il problema non credo che sia dell'applicazione ma delle librreire di arduino, anche quelle generali che non carichi in modo esplicito.

La funzione delay fa riferimento al contatore timer0, con un determinato rapporto di prescaler ed un ben preciso valore di clock.

Se tu cambiassi il quarzo di arduino e lo sostituissi con uno da 8Mhz, tutte le funzioni di delay sarebbero raddoppiate.

Idem se modifichi il prescaler del timer0, che se ricordo bene di default è pari a 64, i delay si allungano o si accorciano.

 

Se in vece usi l'interrupt del termine conta di un contatore, se non sbagli i conti sul clock, il tempo è quello. L'unica verifca che devi fare se accetta le istruzioni che ti ho indicato, ma se c'è ilmcontatore ed i registri son quelli non può non accettarle.

Link al commento
Condividi su altri siti

ora solo a scopo didattico e di curiosità ci studio ancora un pò.

boh io ho visto che nei files diciamo l'interfaccia software che fa vedere ad arduino gli attiny la chiamano "core" ed ho usato anche io lo stesso termine.

quello per gli 85 va benissimo sugli 85 ed 84/24 il problema non si verifica affatto

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...