Barriera Infrarossi

BrainBooster:
Ma non si poteva usare irsend della libreria iremote? (quella dei telecomandi a infrarossi)
Detecting an IR Beam Break with the Arduino IR Library

Probabilmente si, non conosco quella libreria e non so come lavora, però così non impari nulla di nuovo e non comprendi quali possono essere i limiti dell'ATmega/Arduino.
Con la mia soluzione hai imparato che si possono manipolare direttamente i timer dell'ATmega scavalcando Wiring e che è possibile utilizzarli per generare un'onda quadra di varie frequenze, il tutto con solo tre righe di programma :slight_smile:

BrainBooster:
Il codice della libreria permetteva di generare il carrier a 38khz con un comando. (essendo una libreria).

astrobeed:

BrainBooster:
Ma non si poteva usare irsend della libreria iremote? (quella dei telecomandi a infrarossi)
Detecting an IR Beam Break with the Arduino IR Library

Probabilmente si, non conosco quella libreria e non so come lavora, però così non impari nulla di nuovo e non comprendi quali possono essere i limiti dell'ATmega/Arduino.
Con la mia soluzione hai imparato che si possono manipolare direttamente i timer dell'ATmega scavalcando Wiring e che è possibile utilizzarli per generare un'onda quadra di varie frequenze, il tutto con solo tre righe di programma :slight_smile:

Già, come dicevo, al di là di aver risolto il problema, è l'aver imparato la tecnica che mi aiuterà a risolvere parecchi problemi

quindi è ufficialmente deprecato l'uso delle librerie perchè così non si impara nulla?
nessuno vieta di leggere (e capire) il codice delle librerie, non siamo mica su windows.
Trattavasi solo di non reinventre ruote.

BrainBooster:
quindi è ufficialmente deprecato l'uso delle librerie perchè così non si impara nulla?

Non ho detto questo, ho detto che se usi una libreria fatta da altri non impari nulla di nuovo, che è un pochino diverso dal deprecare l'uso delle librerie.

, non siamo mica su windows.

Questa te la potevi risparmiare, l'open source esiste anche con Windows.

Trattavasi solo di non reinventre ruote.

Non mi pare che spiegare come risolvere un problema programmando le periferiche direttamente tramite i registri macchina dell'ATmega sia un reinventarsi la ruota.

Complimenti per la risposta.

menniti:
Un'ultima domanda :blush: : questo metodo è applicabile in qualche modo al tiny85, che mi pare non abbia il doppio timer?

Per l'ATTiny85 è applicabile, devi usare i registri TCCR0A e TCCR0B per l'init, e OCR1A per il valore che determina la frequenza.
Purtroppo tocca usare il timer0 pertanto alterando il modo di funzionamento si altera la delay, la millis etc, da verificare l'errore reale.
In teoria il modo pwm del timer1 sull'ATTiny permette di variare la frequenza oltre che in funzione del prescaler anche in funzione del valore contenuto nel registro OCR1C.
Dato che non uso gli ATTiny non ho modo di verificare la cosa, però puoi fare un test semplice, dopo aver attivato il pwm nel modo classico modifica il valore in OCR1C, se cambia la frequenza e rimane costante il duty cycle abbiamo risolto, tocca solo vedere come reimpostare il prescaler del timer 1 per ottenere una frequenza iniziale adatta per ricavare i 38 kHz.

Purtroppo sì, dati i limiti dell'Attiny85, che ha solo 2 timer.

Però potresti ovviare a questo usando il timer1 come un contasecondi. Usando il giusto prescaler potresti aggiornare un unsigned long e replicarti millis. Tocca però usare un quarzo esterno perché l'oscillatore interno è altamente impreciso. Però usando un quarzo esterno ti "giochi" i pin 3 e 4. Considerando che usi anche il pin 0 per il timer0, ti restano solo 2 pin liberi.

EDIT:
usando un quarzo a 4 MHz ed un prescaler di 16384 (il max possibile) ottieni il riempimento del timer ad 8 bit esattamente ogni secondo perché 4MHZ/16384=256 > 8 bit.
In parole povere 256 controlli al secondo (ammesso che la CPU riesca ad eseguire il tuo codice tra un colpo e l'altro del timer (ossia ogni 0,0039s). Sempre che non abbia sbagliato i conti XD

leo72:
In parole povere 256 controlli al secondo (ammesso che la CPU riesca ad eseguire il tuo codice tra un colpo e l'altro del timer (ossia ogni 0,0039s). Sempre che non abbia sbagliato i conti XD

"Also sprach Leo" :grin:

Cavolo ho dovuto usare il traduttore di Google.... ma com'è che scrivi in tedesco? Hai fatto un corso accelerato da Uwe? :wink:

leo72:
Cavolo ho dovuto usare il traduttore di Google.... ma com'è che scrivi in tedesco? Hai fatto un corso accelerato da Uwe? :wink:

Non mi dire che non conosci "also sprach zarathustra" ?

addesso suggerisco la classica soluzione fessa, scontata e semplice.
Ma usare un 74**04 un condensatore ed una resistenza per farsi un oscillatorino no?
Ti avanzerebbero anche altre porte che potresti usare per fare altro...
http://www.fairchildsemi.com/an/AN/AN-118.pdf
non sarà "così parlò zaratustra" ma è un'opzione... :slight_smile:

@ BB:
Mi pare che si stia dicendo tutti la stessa cosa, ma voglio farti un piccolo esempio dell'uso di una libreria, proprio in uno scambio di post con Astrobeed e proprio riguardo lo sleep: Lui mi diceva di aver ottenuto un consumo del micro 328 sull'ordine dei nA, mentre io, in qualsiasi condizione possibile non scendevo sotto i 200µA, feci centinaia di prove fino ad arrivare a piegare i pin Vcc e AVcc del micro su Arduino per le misurazioni, niente. Preso dalla disperazione andai a cercarmi dei link in materia e trovai che un americano urlava di gioia per essere arrivato ai miei stessi consumi, quindi a questo punto chiesi a astrobeed che cavolo era riuscito a combinare (lo sketch di prova me lo aveva fornito lui!!!), finché su un altro link trovo una riga di comando in più, la inserisco nel mio schecth, risultato 0,0-0,1µA cioé probabilmente una cinquantina di nA; quando glielo dissi lui andò a scovare nel suo pc una libreria che veniva (mi pare d'aver capito così) caricata in automatico e che eseguiva tale riga altrove. Tutto ciò a dimostrazione che non sempre le cose "fatte" risolvono tutto. Se lui è in grado di lavorare a quei livelli sui registri di un micro penso che ne godiamo tutti dei benefini ce ne risultano; d'altra parte se tutti ci fermassimo alle cose fatte, solo per non reinventare qualcosa, tu l'avresti mai realizzato il tuo fantastico Dude-UP?

@ Leo:
Allora, per un'applicazione seria userei il 328, al di là di ogni cosa parliamo di 1 euro di differenza e di una dimensione più grande, ma a questo punto si avrebbe di sicuro altra circuiteria.
Trattandosi di uno schema didattico non ho problemi ad usare tempistiche sballate, come ho fatto a suo tempo in altre applicazioni, prima di riuscire a programmare correttamente i fuses in base al clock che impostavo. Quindi niente quarzo

@ Astrobeed
Farò le prove che mi consigli, anche se mi sfugge qualche passaggio: nel tuo code ci sono: OCR2A = 211; TCCR2A = 0b01000011; TCCR2B = 0b00001001. Devo usare OCR1A invece del 2A? Poi mi consigli di variare l'1C, in pratica aggiungo unaltra riga in setup per vedere se variando questo valore è influenzato il duty cicle?

@ tutti e due: io mi ammazzo a scrivere un post e voi nel frattempo maroneggiate con lingue straniere? Già litigo con l'Inglese, mi manca pure il tedesco: Così parlò Zarathustra, nei miei ricordi filosofici è l'opera di Nietsche (non mi ricordo se si scrive propro così) a cui sembra si ispirò quello squinternato di Hitler dopo che da caporale diventò un politico "socialista".

BrainBooster:
addesso suggerisco la classica soluzione fessa, scontata e semplice.

Ovviamente si, ma volendo anche l'evergreen 555 da usarsi come oscillatore a 38 kHz con Enable.
Però le piccole MCU sono nate proprio per eliminare quella che viene detta glue logic e/o eventuale hardware esterno.
Con una piccola MCU puoi sostituire, come funzionalità, una manciata di 555 e di porte logiche varie svolgendo nel contempo varie funzioni accessorie, a maggior ragione non ha senso usare hardware esterno quando puoi fare la stessa cosa utilizzando le periferiche di un micro, ovviamente se le risorse disponibili lo permettono.

BrainBooster:
addesso suggerisco la classica soluzione fessa, scontata e semplice.
Ma usare un 74**04 un condensatore ed una resistenza per farsi un oscillatorino no?
Ti avanzerebbero anche altre porte che potresti usare per fare altro...
Intelligent Power and Sensing Technologies | onsemi
non sarà "così parlò zaratustra" ma è un'opzione... :slight_smile:

Evidentemente mi stai prendendo per il c... ]:smiley: Un po' di autoquote visto che proprio non ne vuoi di leggere i miei post:

Che dici metto un 555 e non se ne parla più? Anche se questo va contro l'idea del risparmio energetico, visto che il 555 in azione mi consuma più del micro, credo.

La seconda è quella che dicevo col 555, ripeto lo scopo è didattico, quindi il problema del consumo reale non si pone, vorrei però fare tutto col micro (un tiny85 in stand-alone)

Quote

Sicuro che non vuoi usare un 555?

Con quello ovviamente è già tutto risolto, il problema è che questo vorrebbe essere uno schema didattico per il risparmio energetico, anche se in realtà sarà alimentato con un alimentatore esterno; il 555 non lo posso spegnere e continuerebbe a consumare corrente.

Ora te ne esci con gli inverter ]:slight_smile: che poi lo 04 è più grande e moooolto meno preciso del 555 che riciede solo due R ed un C per generare la frequenza che mi servirebbe. Visto che la sorpresa è perduta e non posso più farti inczz sono costretto a fare :wink:
XD XD XD

a mia discolpa posso solo dire che non ho idea di quanti pin fai uso attualmente e se il tiny farà altro , oltre a quello che hai detto :stuck_out_tongue:
però pensaci..., ne hai 6 a disposizione in un dip,
potresti usare anche una porta come amplificatore/squadratore del segnale ir da trasmettere
un'altra o due per farci l'oscillatore (anche quarzato con una precisione di 20ppm)
non occuperesti pin sull'ic
non si andrebbero a toccare i timers.
Edit:
l'avevo visto il post sul 555 :slight_smile:
ma il 74hct04 consuma nell'ordine dei uW.

Per la serie non finisce qui tra poco arriva la soluzione numero 2.
Utilizzo del timer come contatore di tempo e dell'interrupt per ricaricarlo, soluzione che richiede un minimo impegno cpu, mentre quella tramite pwm no, che però consente un migliore controllo delle cose, sopratutto una precisione migliore, e permette anche di emettere un numero preciso di impulsi, utile per il Sonar.

astrobeed:
Per la serie non finisce qui tra poco arriva la soluzione numero 2.
Utilizzo del timer come contatore di tempo e dell'interrupt per ricaricarlo, soluzione che richiede un minimo impegno cpu, mentre quella tramite pwm no, che però consente un migliore controllo delle cose, sopratutto una precisione migliore, e permette anche di emettere un numero preciso di impulsi, utile per il Sonar.

Azz, oggi sei di battaglia :smiley: bene, bene, aspetto con ansia, se puoi rispondimi al dubbio sul tiny (OCR1A/C :fearful:)

@ BB:
In realtà pensavo anche che se mi capita tra le mani un certo amico, che abita nel profondo sud e lo impicco ad una robuasta quercia che sta dalle mie parti, una volta che smette di muoversi, mi basterebbe dargli un colpettino ai piedi per farlo oscillare, otterrei la frequenza desiderata ed in più entrambi i piedi(ni) sarebbero liberi ]:smiley:
Scherzi a parte (dipende da quanto la tiri :stuck_out_tongue_closed_eyes:): due pin per i led e carichi controllati, un pin (38KHz) per i due tx ed uno per i due rx; fino al suggerimento di astrobeed usavo un altro pin per l'interrupt, ora è libero, quindi me ne avanzano due, magari con uno potrei controllarci un missile terra-terra (non nel senso di scadente) per spararti su un piede, l'altro pin mi servirebbe per il "ritorno audio" anche se credo che ti sentirò in diretta..... pace?

Certo
=(
ho appena finito di cospargermi il capo di cenere e di battermi il petto.
mea culpa mea culpa...
:stuck_out_tongue_closed_eyes:
dai, vediamo cosa tira fuori dal cilindro astrobeed :slight_smile:

Ed ecco la soluzione 2:

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

unsigned char out_bit = 0, c_puls = 0, riarma;

void setup()
{
  pinMode(11, OUTPUT);     
  pinMode(13, OUTPUT);  

  TCCR1A = 0b00000011;     // mode 15, fast pwm
  TCCR1B = 0b00011001;

  sbi (TIMSK1,TOIE1);      // enable Timer1 Interrupt
}

void loop()
{
  digitalWrite(13, HIGH);
  delay(1);
  digitalWrite(13, LOW);
  delay(1);
  riarma = 10;
  c_puls = 0;
  out_bit = 0;
}

ISR(TIMER1_OVF_vect)
{
  if (c_puls < riarma)  
  {
    out_bit ^= 1; 
    digitalWrite(11,out_bit);
    OCR1A = 209;
    c_puls++;
  }
}

In questo caso usiamo il timer 1 perché è quello a 16 bit e offre maggiore risoluzione, ma il tutto è applicabile a qualunque timer cambiando il nome dei registri, selezioniamo il modo 15, fast pwm, scollegando il timer dai pin di uscita in modo da poter usare il registro a 16 bit OCR1A come preset per il conteggio.
Attivando l'interrupt del timer 1, sbi (TIMSK1,TOIE1), ogni volta che questo arriva a 0 chiama la relativa ISR, ovvero la funzione ISR(TIMER1_OVF_vect) (timer 1 overflow), dove cambiamo lo stato di un pin a nostro piacere ogni volta che viene chiamato l'interrupt.
Introducendo due variabili di controllo, c_puls e riarma, per contare il numero di impulsi emessi è possibile far commutare il pin un numero predeterminato di volte in base ad un evento prestabilito, nel nostro caso un delay di 2 ms all'interno della loop.
Purtroppo questo metodo presenta uno svantaggio utilizzato all'interno di wiring, dato che sono attivi in simultanea altri interrupt su cui non abbiamo nessun controllo, la ISR(TIMER1_OVF_vect) è solo una porzione della ISR complessiva, ad alte frequenze è presente un leggero jitter, si verifica solo ogni tot us su alcuni impulsi e in modo aperiodico, se si genera un'onda quadra costantemente.
Nel caso dei 38 kHz per il diodo IR il jitter non è un problema, anche se viene perso un impulso perché va fuori periodo ogni qualche centinaio non è certo un problema, idem per il ping degli ultrasuoni, in questo caso il jitter è praticamente inesistente, mentre può essere un reale problema per altre applicazioni.

Ed ecco che ora ho da studiare per una settimana :astonished:
Grazie, ho ricopiato tutto in un file che sarà il soggetto del mio leggio finché fame/sonno non ci separino XD
Proverò entrambe le combinazioni, da giovedì e per almeno 8-9 giorni non dovrei avere più impegni quindi pop-corn, patatine, coca-cola e Arduino, credo che ingrasserò di brutto visto che mangerò fintanto che non capirò qualcosa :fearful: :drooling_face:

Senti, non esplodere, mi dai quella piccola dritta sul tiny, così posso fare le prove su entrambi i micro? :blush: :blush:

Comunque hai fatto un lavoro superlativo, questo Topic sarà da incorniciare, per la dimostrazione che hai dato di quanto ancora possano produrre questi piccoli scarafaggi, rispetto alle già ottime potenzialità di Arduino.