Stap 3: De Chip Program
Hebben ingesteld dat uw programmeur in de laatste stap, laden de schets Throwduino basic voor de IDE. Het heeft geplakt hieronder en ook als bijlage verzonden.
Bewerken - kan er een fout in de code:drempel = (totaal >> 5); drempel gemiddelde punt (kloof totaal per 128) instellen.
waarschijnlijk moet worden:
drempel = (totaal >> 7); drempel gemiddelde punt (kloof totaal per 128) instellen.
Op heeft gehanteerd voor mij zoals het was, maar dit leiden problemen met de lichte sensing tot kan. Ik zal controleren en corrigeren indien nodig.
Als u zou willen veranderen van de flash-sequence van uw thowie is nu de tijd. Zorg ervoor dat uw code zal passen in het geheugen van de chip hebt. Het is niet waarschijnlijk een probleem voor iets groter dan een ATtiny25. De schets hieronder neemt niet veel meer dan 1K. De code hieronder toont de bekende "1-4-3" flash reeks. Dit kan natuurlijk niet uw ding, zo hack-weg.
De flash reeks wordt gehouden in de matrix en gewoon houdt een lijst van flash getallen. Deze worden gespeeld met een korte pauze tussen elk, gevolgd door een 2-seconden pauze voordat herhaald. Bijvoorbeeld voor:
De throwie knippert één keer onderbreken, flash 4 keer, onderbreken, flash 3 keer, wacht 2 seconden & Herh.
Zodra de schets klaar is, selecteer ATtiny85 1Mz (of welke ATtiny u gebruikt) uit de lijst van de planken in de IDE. Als u niet het juiste bord kan je (XXXX niet gedefinieerd in deze scope) treedt er een compileerfout. Als je dit krijgen, controleert dat u een ATtinyX5 hebt geselecteerd.
Druk op "upload" in de IDE. De Arduino Tiny maakt standaard gebruik van de Arduino ISP. U ziet de pin13 leidde op uw Arduino flikkeren als de schets is overgedragen.
Hoe werkt de schets?
We hebben een paar functies gedefinieerd die nuttige dingen doen, en u misschien wilt gebruiken in het hacken:
ongeldig flash(byte) - knippert de LED "byte" times.
int lightLevel() - geeft als resultaat een int met de lichte niveau meting van de LED tegen de 2.56v interne ref.
ongeldig setup_watchdog(int) - stelt de watchdog-timer met waarde "int". Er zijn 10 instellingen van 0 tot en met 9 overeenkomt met 16, 32, 64, 128, 250, 500, 1000, 2000, 4000 en 8000 ms.
ongeldig system_sleep() - zet het systeem om te slapen voor de tijd die is ingesteld in de watchdog.
Om te beginnen steken we op een paar registers dingen instellen en minimaliseren van verspilde macht. Daarna in setup wij flash 3 keer en 148 metingen van het lichtniveau. We gooien de eerste 20 en gemiddeld de resterende 128. Dit plaatst de drempel waarbij we zullen beoordelen wanneer het is donker. Wij van de flits de LED die drempel nummer alvorens te voeren op. Dit is meer voor foutopsporing dan iets nuttigs.
In de hoofdlus we meten het lichtniveau en vergelijken met de drempelwaarde. Als haar onder de waarde vervolgens flash wij de LED door onze vooraf ingestelde patroon. Als het licht niveau hoog is en we 8 seconden slapen (de langste die we kunnen) vóór de proef opnieuw.
Mijn dank aan InsideGadgets voor dit artikel , die vormden het uitgangspunt voor de code van de slaap. Het is vermeldenswaard als u gebruikt dat u wilt instellen van de interrupt enable vlag telkens die de WDT time-out of de chip zal volgende keer gereset.
Schets (dit moet compileren tot ongeveer 1262 bytes):
Throwduino basic
Ugi 2012
MIT-licentie
Geschreven voor ATtiny25/45/85 met behulp van de Arduino Tiny core - http://code.google.com/p/arduino-tiny/
Wordt niet gecompileerd voor andere Arduinos (ATMega168, ATMega328 etc)
Zorg ervoor dat u het juiste bord voordat je compileert.
Voor Ref:
ADC Pins:
ADC1 = PB2
ADC2 = PB4
ADC3 = PB3
Als u wilt gewoon de flash patroon wijzigen, moet u dat hier doen.
Standaard is:
//
Const byte flashSeq [3] = {1,4,3}; Flash patroon
//
Dit geeft 1 flash, pauze, vier flitsen, pauze, drie flitsen, pauze.
Als u gewoon een langere pauze wilt, gebruik 0 voor elke 500ms.
Na de reeks wachten we op 2s voordat herhaald.
Const byte flashSeq [3] = {1,4,3}; Patroon van de flits. Bewerk dit.
Hoeveel vermeldingen in de flash patroon.
Const byte seqLength = sizeof(flashSeq);
Nu laten we een throwie voor die reeks...
Const int LEDpin = 4; Hoewel dit in een constante, is er een heleboel directe poort toegang
Ik zou niet proberen om dit te veranderen zonder lopende throu' de hele code.
unsigned int drempel = 10; We zullen dit juist ingesteld tijdens de installatie
Dit stelt sommige libs en definities voor gebruik met de sluimer-timer
#include < avr/sleep.h >
#include < avr/wdt.h >
#ifndef cbi
#define cbi (sfr, bit) (_SFR_BYTE(sfr) & ~_BV(bit)) =
#endif
#ifndef sbi
#define sbi (sfr, bit) (_SFR_BYTE(sfr) | = _BV(bit))
#endif
ISR(WDT_vect) {WDTCR| = B01000000;} / / Watchdog-Timer reset naar Interrupt modus elke keer.
Knoeien over met sommige journalen die u wilt uitschakelen van spullen & set referenties.
VOID Setup {}
ADCSRB & = B10111111; uitschakelen van comparitor
ACSR | = B10000000; Schakel stroom comparitor
ADCSRA | = B10000000; / / ADC inschakelen
DDRB & = B11100000; Stel alle invoeren
DDRB| = B00011010; 1,3 en 4 stellen als uitvoerapparaat
PORTB & = B11110111; set PB3 lage - dit was voor de testfase. Waarschijnlijk kan nu worden weggelaten.
PRR & = B11111110; duidelijke ADC uitschakelen bits in macht vermindering Reg
analogReference(6); interne 2.56v verwijst naar met geen bypass - INTERNAL2v56NB-
Tonen dat we wakker zijn:
Flash(3); Drie flitsen - wij zijn gebruiksklaar.
De drempel voor lichte sensing tijdens eerste 40 seconden instellen
Wij nemen 148 metingen, bin van de eerste 20 en vervolgens het gemiddelde van de volgende 128.
unsigned int totaal = 0;
voor (byte rep = 0; rep < 148; rep ++) {}
int value=lightLevel();
int waarde = 10;
if(Rep>19) {}
Total += waarde; tatke totaal 128 lezingen
}
Flash(Value);
DDRB & = B11100000; Stel alle invoeren
setup_watchdog(4);
system_sleep(); / / tweede kwartaal slapen
DDRB| = B00011010; 1, 3 en 4 te stellen als uitvoerapparaat
PORTB & = B1110000; Alle laag ingesteld
}
drempel = (totaal >> 7); drempel gemiddelde punt (kloof totaal per 128) instellen.
Flash(Threshold); Dit is meestal voor foutopsporing.
}
Hoofdlus
We meten het lichtniveau. Als het is laag vervolgens flash wij onze volgorde dan slaap voor 2s.
Als licht niveau hoog, we voor 8s slapen.
void loop {}
analogReference(6); interne 2.56v verwijst naar met geen rondweg
Meten van lichtniveau en als het is laag genoeg, weergeven van onze flash reeks
Als (lightLevel() < drempel) {}
voor (bytevolgorde = 0; volgorde < seqLength; volgorde ++)
Flash(flashSeq[Sequence]);
Indien wij knipperen waren, slapen we nu voor 2s
DDRB & = B11100000; Stel alle invoeren
setup_watchdog(7);
system_sleep(); / / slaapstand gedurende twee seconden
DDRB| = B00011010; 1,3 en 4 stellen als uitvoerapparaat
PORTB & = B11110111; PB3 laag.
}
else {}
Als we niet waren knippert dan slapen we voor 8s
DDRB & = B11100000; Stel alle invoeren
setup_watchdog(9);
system_sleep(); / / slaapstand gedurende twee seconden
DDRB| = B00011010; 1,3 en 4 stellen als uitvoerapparaat
PORTB & = B11110111; PB3 laag.
}
} / / einde van de hoofdlus
Lichtniveau meten door te kijken naar spanning gegenereerd door LED verbonden met D4 (A2) op pin 3 van de chip.
Instellen van Output en laag om te beginnen om zich te kwijten van de opbouw van een kosten - niet zeker als we dit nodig
int lightLevel() {}
pinMode (LEDpin, uitvoer);
digitalWrite (LEDpin, laag);
delayMicroseconds(50);
pinMode (LEDpin, INPUT);
delayMicroseconds(100); laat het stabiliseren als input weer
unsigned int waarde = analogRead(A2);
retourwaarde;
}
Flitser routine - 70ms, 250 ms uit
Bepaald aantal keren herhalen en vervolgens onderbreken 500ms
VOID flash(byte No) {}
pinMode (LEDpin, uitvoer);
if (!. No) {/ / als wij een nul ontvangen, gewoon pauzeren.
DDRB & = B11100000; Stel alle invoeren
setup_watchdog(5);
system_sleep(); / / slapen voor 500 ms
DDRB| = B00011010; 1,3 en 4 stellen als uitvoerapparaat
PORTB & = B11110111; PB3 laag.
}
Als we een ander getal dan nul flitsen hadden, maken we ze nu
voor (byte rep = 0; rep < No; rep ++) {}
DDRB| = B00011010; 1,3 en 4 stellen als uitvoerapparaat
PORTB & = B11110111; PB3 laag.
PORTB| = B00010000; PB4 hoog
digitalWrite (LEDpin, hoge);
delay(70);
PORTB & = B11101111; PB4 laag.
DDRB & = B11100000; Stel alle invoeren
digitalWrite(LEDpin,LOW);
setup_watchdog(4); WDT 3 = 128MS
system_sleep();
}
Pauze (slaap)
DDRB & = B11100000; Stel alle invoeren
setup_watchdog(5); WDT 5 = 500MS
system_sleep(); / / slapen
DDRB| = B00011010; 1 en 3 instellen als output
PORTB & = B11110111; PB3 laag.
}
Watchdog-timer-installatie
Dit is specifiek voor de ATTiny85 (+ tiny45, & tiny25) en zal niet compileren voor ATMega328 enz.
0 = 16 MS, 1 = 32ms, 2 = 64ms, 3 = 128ms, 4 = 250ms, 5 = 500ms
6 = 1 sec, 7 = 2 sec, 8 = 4 sec, 9 = 8 sec
VOID setup_watchdog (int periode) {}
de waarde van de byte;
Als (periode > 9) periode = 9;
waarde = periode & B111;
Als (periode > 7) value| = (1 << 5);
Value| = (1 << WDCE);
MCUSR & = ~ (1 << WDRF);
Start 4-klok-cycle getimede opeenvolging
WDTCR | = (1 << WDCE) | (1 << WDE);
nieuwe waakhond-outwaarde instellen
WDTCR = waarde;
WDTCR | = _BV(WDIE);
}
systeem in de slaapstand
systeem wakker wanneer wtchdog een time-out opgetreden is
ongeldig system_sleep() {}
CBI(ADCSRA,ADEN); switch analoog naar Digitalconverter af
set_sleep_mode(SLEEP_MODE_PWR_DOWN); slaapstand ligt hier
sleep_enable();
SLEEP_MODE(); Systeem slaapt hier
sleep_disable(); Systeem blijft uitvoering hier als waakhond time-out
SBI(ADCSRA,ADEN); switch analoog aan Digitalconverter
PRR & = B11111110; duidelijke ADC uitschakelen bits in macht vermindering Reg
}