In voorbereidingATtiny Hardware Tips

Kant-en-klare bordjes met AVR processor? Kijk eens op de Arduino pages; is een uitgebreide gebruikers-community bij. Leuk bordje is bijvoorbeeld de Arduino Duemilanove (wel krachtiger dan de ATtiny).

Deze pagina is een vervolg op mijn Starten met de ATtiny2313 pagina... Het behandelt een aantal tips en trucks aan de hardwarekant voor mensen die met de 2313 willen werken (en dient eigenlijk voornamelijk als naslagwerk voor mezelf). Voor software/debuggen zie de ATtiny Software (en debugging) Tips.

Onderwerpen op deze pagina:

Geen garanties, maar hopelijk heeft naast mezelf nog iemand er iets aan.

Low-cost zero-CPU-load analog-to-digital converter voor de ATtiny2313

AD constant currentDe ATtiny2313 heeft zelf geen A/D-converter. In de applicatienote AVR401: 8-bit precision A/D converter van Atmel staat wel hoe er met de analoge comparator er zelf een te maken is, maar deze was mij te complex (ook qua software). Ik heb zelf een gestripte versie gemaakt met de volgende voordelen:

  • Minimaal aantal onderdelen: een low-cost transistor, twee weerstanden en een condensator
  • Gebruikt slechts twee pinnen op de ATtiny2313 (pin 12 en 13)
  • Minimale software; slechts een extra instructie in de timer interrupt routine (plus enkele initialisatie-instrucies)
  • Bereik praktisch 0.1 .. 4.9 Volt (bij 5 Volt supply)
  • Minimaal energiegebruik

Het principe is eenvoudig (zie schema 1 en ook de app note): de te meten spanning wordt op pin 12 (AIN0) aangeboden. Op pin 13 (AIN1) wordt een lineair stijgende spanning gemaakt: met behulp van een constante stroom (als ingesteld door de transistor Q1 en weerstand R2) wordt een condensator C1 opgeladen. Op hetzelfde moment is een timer gestart. Op het moment dat de spanning op de condensator dezelfde is als de spanning op de meet-ingang wordt de waarde van de timer in het timer capture register ingeklokt; dit is de gemeten waarde.

AD input protectionNa een vaste tijd wordt de condensator leeggemaakt (in ongeveer 20 µs), door pin 13 van de ATtiny2313 tijdelijk als output met waarde 0 te configureren (met de weerstand R1 als stroombegrenzer), en kan de cyclus opnieuw beginnen. Het geheel loopt op Timer1 die ik toch al had lopen voor andere taken (met name de PWM outputs, klok op 4 MHz/8 dus ~2 kHz PWM); kost dus geen extra resources. Het enige extra is een instructie in de interrupt routine die pin 13 van input (meten) naar output met waarde 0 (ontladen) schakelt, en weer terug (toggle: DDRB ^= _BV(PB1);). OK, niet helemaal zero-CPU-load, maar enkele instructies elke 500 µs (2 kHz) is verwaarloosbaar.

Op de meet-ingang wel nog wat onderdelen om deze te beschermen tegen te hoge spanningen en zo; of dit nodig is hangt af van je toepassing (schema 2, zener is 5.1 Volts).

Voor de precieze waarde van de condensator moet je wat experimenteren, afhankelijk van je timing, en met name de kwaliteit van je condensator en van de gebruikte transistor, waarvan de versterkingsfactor (en daarmee de stroom) niet voor elke transistor dezelfde is...

De meetwaarde is uit te lezen uit het Timer/Counter 1 capture register, ICR1L. De waarde wordt elke milliseconde bijgewerkt (1 kHz sample frequency). De meting is gekoppeld aan de voedingsspanning, ideaal voor weerstand-gebaseerde sensoren; maar calibratie is eventueel ook mogelijk: schakel de AIN0 input van de comparator naar de interne referentiespanning (1.1V) en meet deze; dit geeft je een schaalfactor. De ondergrens is niet helemaal 0 Volt, omdat de condensator niet helemaal leeg raakt (blijft een kleine laadstroom lopen, ook tijdens het ontladen, geeft een ondergrens van ongeveer 1 mA x 100 Ohm = 100 mV).

Initialisatie voor A/D conversie (exclusief de PWM-initialisatie op 2 kHz fast mode):

// Timer initialisation for PWM not shown
// TIMER 1 ADconv: noise filter, neg edge
TCCR1B |= (1 << ICNC1) | (0 << ICES1);
// ACO: output of comparator; ACIC enable timer capture; ACIS:2 -> pos edge
ACSR = (1 << ACO) | (1 << ACIC) | (1 << ACIS1) | (0 << ACIS0);
// only use as analog input; disable digital input (power reduction)
DIDR = (1 << AIN1D) | (1 << AIN0D);

Simpel, niet?

Stroomgebruik in een werkelijke schakeling

In mijn vuurvlieg-project, een batterij- en zonnecel-gevoed ontwerp, heb ik eens de stroom gemeten. De details zijn verhuisd naar de vuurvlieg-pagina...


Top of page Opmerkingen, commentaar, feedback: mail naar .
Nuttige site? Antwoorden gevonden? Zet dan een link naar mijn site op je eigen site, hebben anderen er misschien ook wat aan!