Throwduino Basic - ljus-Sensing blinkande Throwie med 1 extra del - nu med Morsealfabetet (3 / 7 steg)
Steg 3: Programmera Chip
Har ställt in din programmerare i det sista steget, ladda Throwduino grundläggande skissen till IDE. Det finns inklippt nedan och också bifogat.
Redigera - det kan finnas ett fel i koden:tröskel = (totalt >> 5); Ställ in tröskelvärdet i genomsnitt punkt (klyftan totala av 128).
bör nog vara:
tröskel = (totalt >> 7); Ställ in tröskelvärdet i genomsnitt punkt (klyftan totala av 128).
Det har fungerat för mig eftersom det var men detta kan orsaka problem med den lätta avkänning. Jag kommer att kontrollera och korrigera om det behövs.
Om du vill ändra flash-sekvensen av din thowie så är nu dags. Se till att din kod kommer att passa i minnet av chip du har. Det är inte sannolikt att vara en fråga för något större än en ATtiny25. Skissen nedan tar inte mycket mer än 1K. Koden nedan visar den välkända "1-4-3" flash sekvens. Detta, naturligtvis, kanske inte din sak, så hacka-away.
Flash sekvensen hålls i matrisen och helt enkelt har en lista med flash tal. Dessa spelas med en kort paus mellan varje, följt av en paus på 2 sekunder innan du upprepar. Till exempel för:
Throwie blinkar en gång, pausa, flash 4 gånger, pausa, flash 3 gånger, pausa i 2 sekunder och upprepa.
När skissen är klar, Välj ATtiny85 1Mz (eller beroende på vilken ATtiny du använder) från listan styrelser i IDE. Om du inte väljer rätt styrelsen du får ett kompileringsfel (XXXX inte definieras i detta scope). Om detta, kontrollera att du har valt en ATtinyX5.
Hit "ladda upp" i IDE. Arduino Tiny använder Arduino ISP som standard. Du bör se pin13 ledde på din Arduino flimmer som skissen överförs.
Hur fungerar skissen?
Vi har några funktioner definieras som gör bra saker och kanske du vill använda i hacking:
void flash(byte) - blinkar LED "byte" gånger.
int lightLevel() - returnerar ett heltal som innehåller ljus nivå mätningen från LED mot 2.56v inre ref.
void setup_watchdog(int) - ställer watchdog timer värdet "int". Det finns 10 inställningar från 0 till 9 motsvarar 16, 32, 64, 128, 250, 500, 1000, 2000, 4000 & 8000 ms.
void system_sleep() - sätter systemet att sova för den tidpunkt som angetts i inställningen för watchdog.
För att starta peta vi på några register att ställa saker och minimera slöseri makt. Sedan i setup vi flash 3 gånger och 148 mätningar av ljusnivån. Vi kasta bort de första 20 och genomsnittlig återstående 128. Detta anger den beloppsgräns som vi kommer att bedöma när det är mörkt. Vi flash LED tröskel numret innan. Detta är mer för felsökning än något användbart.
I det viktigaste kretsar vi mäter ljusnivån och jämför med tröskelvärdet. Om dess under värdet sedan vi flash LED av våra förinställda mönster. Om ljusnivån är hög då vi sover i åtta sekunder (den längsta vi kan) före testet igen.
Tack till InsideGadgets för denna artikel som utgjorde startpunkten för sömn koden. Det är värt att notera om du använder detta som du vill återställa avbrott Aktivera flaggan varje gång WDT timeout eller chip återställs nästa gång.
Skiss (detta bör sammanställa till omkring 1262 byte):
Throwduino grundläggande
Ugi 2012
MIT license
Skrivit att köra på ATtiny25/45/85 med Arduino Tiny core - http://code.google.com/p/arduino-tiny/
Kommer inte kompilera för andra Arduinos (ATMega168, ATMega328 etc)
Se till att du väljer rätt styrelsen innan du kompilera.
För Ref:
ADC stift:
ADC1 = PB2
ADC2 = PB4
ADC3 = PB3
Om du bara vill ändra flash mönster, göra det här.
standard är:
//
CONST byte flashSeq [3] = {1,4,3}. Blixt mönster
//
Detta ger 1 flash, paus, fyra blinkar, paus, tre blixtar, paus.
Om du bara vill ha en längre paus, Använd 0 för varje 500ms.
Efter sekvensen vänta vi på 2s innan du upprepar.
CONST byte flashSeq [3] = {1,4,3}. Blixt mönster. Redigera den här.
Hur många poster i det blixt mönstret.
CONST byte seqLength = sizeof(flashSeq);
Nu låt oss göra en throwie för att ordna...
CONST int LEDpin = 4; Även om detta i en konstant, finns det en hel del direkt port tillgång
Jag skulle inte försöka ändra på detta utan gå throu "hela koden.
unsigned int tröskel = 10; Vi ska ställa detta ordentligt under installationen
Detta sätter upp några libs och definitioner för användning med insomningstimern
#include < avr/sleep.h >
#include < avr/wdt.h >
#ifndef cbi
#define cbi (sfr, lite) (_SFR_BYTE(sfr) & = ~_BV(bit))
#endif
#ifndef sbi
#define sbi (sfr, lite) (_SFR_BYTE(sfr) | = _BV(bit))
#endif
ISR(WDT_vect) {WDTCR| = B01000000;} / / reset Watchdog Timer till avbrottsläge varje gång.
Röra om med några register till inaktivera grejer & Ange referenser.
void setup() {
ADCSRB & = B10111111; Inaktivera comparitor
ACSR | = B10000000; Stäng av strömmen till comparitor
ADCSRA | = B10000000; / / slå på ADC
DDRB & = B11100000; Ange alla att mata in
DDRB| = B00011010; Ange 1,3 och 4
PORTB & = B11110111; Ställ in PB3 låg - detta var för testfasen. Förmodligen kan släppas nu.
PRR & = B11111110; tydlig ADC disable bit i makt minskade Reg
analogReference(6); inre 2.56v referera med ingen bypass - INTERNAL2v56NB-
Visa vi är vakna:
Flash(3); Tre blixtar - vi är igång.
Ställ in tröskelvärdet för ljus sensing under första 40 sekunder.
Vi tar 148 mätningar, bin de första 20 och sedan genomsnittlig nästa 128.
unsigned int totala = 0;
för (byte rep = 0; rep < 148; rep ++) {
int value=lightLevel();
int värde = 10;
IF(rep>19) {
totala += värde; tatke totalt 128 avläsningar
}
Flash(Value);
DDRB & = B11100000; Ange alla att mata in
setup_watchdog(4);
system_sleep(); / / sova för kvartalet andra
DDRB| = B00011010; Ange 1, 3 och 4
PORTB & = B1110000; Allt låg
}
tröskel = (totalt >> 7); Ställ in tröskelvärdet i genomsnitt punkt (klyftan totala av 128).
Flash(Threshold); Detta är mest för felsökning ändamål.
}
Huvudloop
Vi mäter ljusnivån. Om den är låg blinkar vi våra sekvensen sedan sömn för 2s.
Om ljus nivå hög, vi sover för 8s.
void loop() {
analogReference(6); inre 2.56v referera med ingen bypass
Mäter ljusnivån och om det är tillräckligt låg, visar vår flash sekvens
om (lightLevel() < tröskel) {
för (byten ordningsföljd = 0; sekvens < seqLength; sekvens ++)
Flash(flashSeq[Sequence]);
Om vi blinkar, sova vi nu för 2s
DDRB & = B11100000; Ange alla att mata in
setup_watchdog(7);
system_sleep(); / / sova i två sekunder
DDRB| = B00011010; Ange 1,3 och 4
PORTB & = B11110111; PB3 låg.
}
annat {
Om vi inte blinkar då sover vi för 8s
DDRB & = B11100000; Ange alla att mata in
setup_watchdog(9);
system_sleep(); / / sova i två sekunder
DDRB| = B00011010; Ange 1,3 och 4
PORTB & = B11110111; PB3 låg.
}
} / / end huvudloop
Mät ljuset genom att titta på spänning genereras av LED ansluten till D4 (A2) å pin 3 chip.
Ställa in produktionen och låg att börja att släppa ut någon avgift för mycket - inte säker på om vi behöver detta
int lightLevel() {
pinMode (LEDpin, OUTPUT);
digitalWrite (LEDpin, låg);
delayMicroseconds(50);
pinMode (LEDpin, indata);
delayMicroseconds(100); Låt det stabilisera som indata igen
unsigned int värde = analogRead(A2);
returnera värdet;
}
Flash rutin - 70ms, 250 ms off
Upprepa visst antal gånger och sedan Pausa 500ms
void flash(byte No) {
pinMode (LEDpin, OUTPUT);
IF (!. Nej) {/ / om vi får en nolla, bara pausa.
DDRB & = B11100000; Ange alla att mata in
setup_watchdog(5);
system_sleep(); / / sova för 500 ms
DDRB| = B00011010; Ange 1,3 och 4
PORTB & = B11110111; PB3 låg.
}
Om vi hade ett noll antal blixtar, gör vi dem nu
för (byte rep = 0; rep < nej; rep ++) {
DDRB| = B00011010; Ange 1,3 och 4
PORTB & = B11110111; PB3 låg.
PORTB| = B00010000; PB4 hög
digitalWrite (LEDpin, hög);
Delay(70);
PORTB & = B11101111; PB4 låg.
DDRB & = B11100000; Ange alla att mata in
digitalWrite(LEDpin,LOW);
setup_watchdog(4); WDT 3 = 128MS
system_sleep();
}
Paus (sova)
DDRB & = B11100000; Ange alla att mata in
setup_watchdog(5); WDT 5 = 500MS
system_sleep(); / / sova
DDRB| = B00011010; Ange 1 och 3
PORTB & = B11110111; PB3 låg.
}
Watchdog timer setup
Detta är specifikt för den ATTiny85 (+ tiny45 & tiny25) och kommer inte att kompilera för ATMega328 etc.
0 = 16ms, 1 = 32ms, 2 = 64ms, 3 = 128ms, 4 = 250ms, 5 = 500ms
6 = 1 SEK, 7 = 2 sek, 8 = 4 SEK, 9 = 8 SEK
void setup_watchdog (int period) {
bytevärdet;
om (period > 9) period = 9.
värde = period & B111;
om (period > 7) value| = (1 << 5);
Value| = (1 << WDCE);
MCUSR & = ~ (1 << WDRF);
Start 4-klockcykel tt sekvens
WDTCR | = (1 << WDCE) | (1 << Mimmi);
Ange nya watchdog timeout-värde
WDTCR = värde;
WDTCR | = _BV(WDIE);
}
ställa in systemet i lågeffektläge enligt
systemet vaknar upp när wtchdog är timeout
void system_sleep() {
CBI(ADCSRA,ADEN); Växla Analog till Digitalconverter av
set_sleep_mode(SLEEP_MODE_PWR_DOWN); viloläge är inställd här
sleep_enable();
sleep_mode(); Systemet sover här
sleep_disable(); Systemet fortsätter utförande här när watchdog timeout
SBI(ADCSRA,ADEN); Växla Analog till Digitalconverter på
PRR & = B11111110; tydlig ADC disable bit i makt minskade Reg
}