San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« on: October 20, 2012, 11:37:53 pm » |
Salve ragazzi, come da titolo, sto cercando di realizzare un doppio dimmer (2 dimmer separati, ma con un unico micro), a 230v... ho preso spunto da questo... http://wiki.dxarts.washington.edu/groups/general/wiki/4dd69/AC_Dimmer_Circuit.htmlsolo che ho un problemino con la libreria timer1 sul tiny85... uso il tiny85 come descritto qui: http://hlt.media.mit.edu/?p=1695ho anche provato le librerie timedaction, e timer (che da quanto ho letto è derivata da timedaction), ma non mi funziona... ho bisogno di 2 processi sotto timer, indipendenti, lasciando invariato il loop, ed i delay/millis. sul datasheet del tiny85, ho letto che internamente ci sono 2 timer ciascuno con 2 compare_match. ora, vi chiedo: è possibile usare uno di questi timer usando sia il COMPA, che il COMPB? potreste per favore scrivermi un esempio di codice? P.S. il circuito, è molto simile a quello del progetto postato, ho solo aggiunto un ponte di diodi prima della resistenza da 33k che va al fototransistor, ed ho utilizzato il pilotaggio del triac con una sola resistenza (per carichi resistivi, è sufficiente). Grazie a tutti 
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 226
Posts: 16983
Don't know what I do
|
 |
« Reply #1 on: October 21, 2012, 04:02:29 am » |
Scrivi che hai bisogno di 2 processi sotto timer: che cosa devi fare esattamente? Quanto lunghi sono i processi? Se non sono molto complessi, potresti pensare di usare il mio scheduler leOS, che permette di inserire delle piccole funzioni da eseguire in automatico all'interno di un timer (con risoluzione di 1 ms).
|
|
|
|
|
Logged
|
|
|
|
|
BZ (I)
Offline
Brattain Member
Karma: 172
Posts: 16125
+39 349 2158303
|
 |
« Reply #2 on: October 21, 2012, 04:08:34 am » |
Ciao Ultra Phonic 2
Tu sai che quel circuito é fatto per 120VAC percui se non radoppi la resistenza R1 da 33kOHM hai una doppia corrente sul Optocoppler OK2. Ma l' errore di quel circuito é che il LED del OK2 non regge 120V o 230V in polarizzazione inversa. Quel problema hai risolto mettendo un ponte radrizzatore. Il secondo errore di quel circuito vedo che il MOC3020 viene pilotato con ca 4mA. Non é detto che il suo fototriac venga pilotato correttamente con cosí poca corrente/luce. Consiglio una corrente di almeno 10mA oppure cambiare modello e passare al MOC2023.
Ciao Uwe
|
|
|
|
|
Logged
|
|
|
|
|
San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« Reply #3 on: October 21, 2012, 04:36:07 am » |
@uwe, non ho problemi circuitali, perchè al posto della resistenza da 33k il mio prof, mi ha detto di metterla da 47k, riguardo il pilotaggio del triac, funziona alla grande, il led del fototriac è collegato con una resistenza da 330ohm quindi si accende pienamente. facendo delle prove tipo blink, le 2 lampade si accendono e spengono perfettamente... anche insieme... EDIT: uso moc3021...
@leo... non so dirti... se guardi il sorgente di quel circuito, vedi che il timer, serve a dare l'uscita in un determinato istante, tramite un contatore fatto nella sub del timer. il timer ha risoluzione di 65ms (perchè li sono 60hz), io ho fatto il calcolo per 50hz come scritto nello sketch, e mi esce circa 78ms...
quindi riepilogando... mi servono 2 timer indipendenti dal loop con risoluzione impostabile a 78ms, tenendo presente che non sto usando un ATMEGA168/328 ma un ATTINY85
|
|
|
|
« Last Edit: October 21, 2012, 04:48:11 am by Ultra Phonic 2 »
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 226
Posts: 16983
Don't know what I do
|
 |
« Reply #4 on: October 21, 2012, 10:42:36 am » |
Ho guardato il codice ma lì non usa 2 timer, usa il timer 1 ed un interrupt agganciato ad un pin esterno per rilevare il passaggio dal punto zero dell'onda. Viene usata la libreria TimerOne per schedulare un segnale per attivare il Triac. Però lì si parla di uS, che sono microsecondi, non ms, millisecondi. Che risoluzione devi avere?
|
|
|
|
|
Logged
|
|
|
|
|
San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« Reply #5 on: October 21, 2012, 11:51:53 am » |
si, scusami.. microsecondi...
mi servono 2 timer, perchè devo gestire 2 dimmer separati... con lo stesso micro.. ognuno è indipendente dall'altro...
mi potresti dare un piccolo spezzone di codice per usare i timer, perchè purtroppo le librerie non vanno... li timerone mi genera tantissimi errori, e le altre all'atto pratico non fungono... come hai detto c'è un'interrupt esterno, ma quello mi funziona... gli altri 2 timer devono essere indipendenti da esso, e dal loop...
EDIT: effettivamente, mi basterebbe anche un solo timer, che però abbia appunto risoluzione di 78uS (microsecondi)
|
|
|
|
« Last Edit: October 21, 2012, 12:19:42 pm by Ultra Phonic 2 »
|
Logged
|
|
|
|
|
BZ (I)
Offline
Brattain Member
Karma: 172
Posts: 16125
+39 349 2158303
|
 |
« Reply #6 on: October 21, 2012, 01:42:23 pm » |
@uwe, non ho problemi circuitali, perchè al posto della resistenza da 33k il mio prof, mi ha detto di metterla da 47k, riguardo il pilotaggio del triac, funziona alla grande, il led del fototriac è collegato con una resistenza da 330ohm quindi si accende pienamente. facendo delle prove tipo blink, le 2 lampade si accendono e spengono perfettamente... anche insieme... EDIT: uso moc3021...
Bene che hai tolto tutti le problematiche di quello schema. Comunque é giusto averlo detto perché se qualcuno legge questo post non faccia gli errori proposti da quel schema. Ciao Uwe
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 226
Posts: 16983
Don't know what I do
|
 |
« Reply #7 on: October 21, 2012, 03:32:03 pm » |
I Tiny85 hanno solo 2 timer, di cui uno viene usato dalle funzioni temporali di Arduino. Puoi ovviamente ridefinirlo per i tuoi scopi. L'altro è disponibile. La TimerOne è scritta per il 328, è normale che ti dia errori compilando per il Tiny85, cambiano i registri. Se vuoi studiarti un po' i timer c'è il datasheet e poi puoi leggere questo: http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.htmlParla di come generare segnali PWM ma va bene per capire l'uso dei registri
|
|
|
|
|
Logged
|
|
|
|
|
San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« Reply #8 on: October 21, 2012, 05:30:29 pm » |
@uwe certo  @leo vedrò che riesco a fare... purtroppo non posso provarlo fino a domani pomeriggio, perchè c'è la scuola di mezzo... grazie, vedrò se riesco a risolvere
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 226
Posts: 16983
Don't know what I do
|
 |
« Reply #9 on: October 22, 2012, 04:58:50 am » |
Se hai bisogno di una mano coi timer, fai un fischio. Se poi spieghi per bene cosa deve fare il tuo codice, magari possiamo risolvere con un unico timer.
|
|
|
|
|
Logged
|
|
|
|
|
San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« Reply #10 on: October 22, 2012, 12:10:58 pm » |
leo, ho bisogno di una mano... ho letto la guida che mi hai dato, ma purtroppo non ho ancora le competenze per comprenderla... ecco il codice che uso: volatile int i=0, y=0; // variabili contatore... volatile boolean zero_cross1=0, zero_cross2=0; // booleane per lo zero crossing int out1 = 0, out2 = 1; // Output >> ai moc... int pot1 = 3, pot2=4; // ingressi trimmer int bright1 = 0, bright2 = 0; // livello di luminosità (0-128) 0 = on, 128 = 0ff
int freqStep = 78; // ritardo del timer in microsecondi void setup() { pinMode(out1, OUTPUT); pinMode(out2, OUTPUT); attachInterrupt(0, zero_cross_detect, RISING); //zero crossing detection con interrupt esterno
}
void zero_cross_detect() { zero_cross1 = true; zero_cross2 = true; i=0; y=0; digitalWrite(out1, LOW); digitalWrite(out2, LOW); }
void br_check() { // SUB CHE DEVE ESSERE ESEGUITA OGNI "FREQSTEP [uS]" (78 microsecondi) if(zero_cross1 == true) { if(i>=bright1) { digitalWrite(out1, HIGH); i=0; zero_cross1 = false; } else { i++; } } if(zero_cross2 == true) { if(y>=bright2) { digitalWrite(out2, HIGH); y=0; zero_cross2 = false; } else { y++; } } }
void loop() { bright1 = analogRead(pot1) / 8; bright2 = analogRead(pot2) / 8; } come scritto nel codice, voglio che la sub br_check() venga eseguita indipendentemente dal loop, ogni 78uS. saresti in grado di inviarmi un pezzo di codice che possa risolvere il mio problema usando un timer? se possibile, potresti commentare lo sketch, così che io riesca a comprendere determinati passaggi, e se non chiedo troppo, anche una breve spiegazione sull'uso dei timer? Grazie 
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 226
Posts: 16983
Don't know what I do
|
 |
« Reply #11 on: October 22, 2012, 04:48:38 pm » |
Vediamo un po'... Sui Tiny85 c'è libero il timer 0, che è ad 8 bit. 1 us, se non ho fatto male i conti, sono 0,000001 secondi. Avere 78 uS dobbiamo avere una frequenza di overflow del timer di 1/0,000078=12820,50 volte al secondo. 1/12820,50=0,000078 us. Ok sì è questo  Allora, poniamo il clock del Tiny a 8 MHz, per avere tale periodo bisogna impostare il tutto così: (8000000*0,000078)/prescaler /8 = 78 Questo è il valore massimo che deve essere conteggiato dal timer per ottenere 1 overflow ogni 78 us, quindi avendo un contatore a 8 bit, con 256 valori, il valore da caricarci dentro è : 256-78=178 Rifacciamo i conti: 8000000/8/178=12820,5 Hz, perfetto  Prova con questo codice (richiamalo dal setup solo 1 volta): cli();//fermo gli interrupt TCCR0A &= ~((1<<COM0A0) | (1<<COM0A1)); //disattivi gli interrupt del timer //modalità contatore fino all'overflow TCCR0A &= ~((1<<WGM01) | (1<<WGM00)); TCCR0B &= ~(1<<WGM02); //prescaler a /8 TCCR0B &= ~((1<<CS02) | (1<<CS00)); TCCR0B |= (1<<CS01); TCNT0 = 178; //valore iniziale TIMSK |= (1<<TOIE0); //attivo un interrutp all'overflow sei(); //riattivo gli interrupt
Ora inserisci questa ISR per gestire l'overflow: ISR (TIM0_OVF_vect) { TCNT0 = 178; ....... //qui il resto del codice } Dove metti il resto del tuo codice. L'ho scritto senza poterlo provare, dimmi se va.
|
|
|
|
|
Logged
|
|
|
|
|
San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« Reply #12 on: October 23, 2012, 08:04:12 am » |
Ciao leo, ho provato il tuo codice, ma durante la verifica mi da quest'errore: core.a(wiring.c.o): In function `__vector_5': C:\Documents and Settings\user\Desktop\arduino-1.0.1\hardware\arduino\cores\arduino/wiring.c:49: multiple definition of `__vector_5' dimmer.cpp.o:C:\DOCUME~1\user\IMPOST~1\Temp\build3703977071899918311.tmp/dimmer.cpp:243: first defined here il codice è così adesso... volatile int i=0, y=0; // variabili contatore... volatile boolean zero_cross1=0, zero_cross2=0; // booleane per lo zero crossing int out1 = 0, out2 = 1; // Output >> ai moc... int pot1 = 3, pot2=4; // ingressi trimmer int bright1 = 0, bright2 = 0; // livello di luminosità (0-128) 0 = on, 128 = 0ff
//int freqStep = 78; // ritardo del timer in microsecondi void setup() { cli();//fermo gli interrupt TCCR0A &= ~((1<<COM0A0) | (1<<COM0A1)); //disattivi gli interrupt del timer //modalità contatore fino all'overflow TCCR0A &= ~((1<<WGM01) | (1<<WGM00)); TCCR0B &= ~(1<<WGM02); //prescaler a /8 TCCR0B &= ~((1<<CS02) | (1<<CS00)); TCCR0B |= (1<<CS01); TCNT0 = 178; //valore iniziale TIMSK |= (1<<TOIE0); //attivo un interrutp all'overflow sei(); //riattivo gli interrupt pinMode(out1, OUTPUT); pinMode(out2, OUTPUT); attachInterrupt(0, zero_cross_detect, RISING); //zero crossing detection con interrupt esterno
}
void zero_cross_detect() { zero_cross1 = true; zero_cross2 = true; i=0; y=0; digitalWrite(out1, LOW); digitalWrite(out2, LOW); }
ISR (TIM0_OVF_vect) { TCNT0 = 178; if(zero_cross1 == true) { if(i>=bright1) { digitalWrite(out1, HIGH); i=0; zero_cross1 = false; } else { i++; } } if(zero_cross2 == true) { if(y>=bright2) { digitalWrite(out2, HIGH); y=0; zero_cross2 = false; } else { y++; } } }
void loop() { bright1 = analogRead(pot1) / 8; bright2 = analogRead(pot2) / 8; } EDIT: confermo che il chip è stato settato ad 8mhz con quarzo interno... ho tolto il ckdiv EDIT2: seguendo questa guida: http://www.atmel.com/Images/doc2505.pdfa pagina 9 ho visto TIMER0_OVF0_vect, e l'ho modificato nel codice che mi hai dato... adesso non genera errori, ma provandolo, il loop è diventato velocissimo! e la funzione che dovrebbe farmi, non me la fa... Grazie
|
|
|
|
« Last Edit: October 23, 2012, 09:01:29 am by Ultra Phonic 2 »
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 226
Posts: 16983
Don't know what I do
|
 |
« Reply #13 on: October 24, 2012, 02:33:17 am » |
Scusa se ti rispondo solo ora ma in questi giorni ho poco tempo libero ed inoltre ieri sera sono stato anche escluso dal forum per problemi di login.
1) non mi torna il vettore che hai usato: TIM0_OVR_vect funziona benissimo, lo uso sia nella swRTC sia nel leOS. Perché a te dà errori? Ma stai usando il core Tiny oppure un altro core, per il Tiny85? Se usi il core Tiny, potresti controllare nel file /hardware/tiny/cores/tiny/core_build_options.h se intorno alla riga 112, nelle opzioni per il Tinyx5, la voce TIMER_TO_USE_FOR_MILLIS ha il valore 1? 2) che intendi per "il loop è diventato velocissimo"? Come fai ad accorgertene? Hai compilato per un micro ad 8 MHz, dopo aver impostato il chip a questa frequenza?
|
|
|
|
|
Logged
|
|
|
|
|
San Pier Niceto (ME), Sicily
Offline
Newbie
Karma: 0
Posts: 48
Scopriamo arduino...
|
 |
« Reply #14 on: October 24, 2012, 07:45:04 am » |
@leo non so che dirti... io ho solo visto quella stringa in quella guida che ho linkato, e in quel modo non genera errori. mettendo un semplice blink nel loop, disabilitando la routine ISR... ecc ecc, il loop è moolto veloce, cioè un delay di 1000mS è diventato di neanche metà... il core che uso l'ho preso da qui: http://hlt.media.mit.edu/?p=1695 e nella cartella "hardware" trovo la cartella "attiny" nella quale trovo "variants" e "boards.txt", in "variants" trovo "tiny8" e "tiny14" nelle quali c'è un file "pins_arduino.h". potresti cortesemente passarmi il core che usi tu ? il chip è stato impostato con internal rc osc ad 8mhz - startup 6ck/14ck + 64ms (quello di default), e settando i fuses tramite avrdude gui. ho tolto il ckdiv8, facendo così diventare il low fuse da 0x62 a 0xE2 se ti serve sapere altro, sono a disposizione
|
|
|
|
|
Logged
|
|
|
|
|
|