Liten bärbar LED kit - 12 PWM lysdioder från en reprogramable ATtiny85 (7 / 8 steg)
Steg 7: kod
Om du vill använda det på en 16 MHz Arduino sedan helt enkelt ändra den "Loop" konstanten högst upp till 128 i stället för 8. Denna konstant gör helt enkelt koden upprepa allt ett visst antal gånger. Vi kör vår ATtiny på 8 MHz men jag tror inre klocka delaren måste ställas in som standard eftersom det beter sig som om den körs på 1MHz.
För att få lämplig hastighet, multiplicera denna Loop konstant upp med hastigheten på din klocka (t.ex. göra det 64 för en "328 kör på 8MHz intern oscillator) etc. Se till att det är alltid en mångfaldig 8 eller koden sannolikt kommer att ha problem.
Den bifogade uppförandekoden är ganska enkel och har endast 4 lägen:
1 - udda & även omväxlande
2 - scanner medurs
3 - scanner moturs
4 - "Larsen" typ alternerande scanner.
Du kan enkelt lägga till många fler lägen och här kärna koden tar bara runt 1.6K, så att du har en annan 6K + att spela med.
Samma kod bör sammanställa mycket väl för en Arduino utan ändringsförslag. På en Arduino, PB0 till PB4 är digital "pins" 8 till 12 respektive. Det är 14-18 stift på den faktiska ATmega328 eller "168 chip. Detta är ganska användbart för testning eller om du kodar medan du väntar på delar att anländer.
Detta är min kod:
Test skiss
Slå på varje LED i sin tur
MIT License
Ugi 2012
Detta är min standard multiplikator så att jag kan justera skissen för olika timing och klockfrekvenser. 128 för Arduino
Gör det en multipel av 8!
CONST unsigned int Loop = 8.
Stift 8 till 12 karta till relevanta bitar av PORTB på 328. Eftersom vi kommer att använda direkta PORTB kommandon bör detta arbete på "328 och ATtiny85
Här används PORTB direkt tillgång - som är stift D0 att D4 på Tiny Arduino eller D8 till D12 på normala Arduino
Första set är nuvarande pin layout.
Andra set är gamla versionen:
//
Aktuell version:
byte DirMatrix [12] = {B10001, B10001, B10010, B10010, B10100, B10100, B01001, B01001, B01010, B01010, B01100, B01100}; Vilket stift är utgång och som är hög impedence
byte PolMatrix [12] = {B10000, B00001, B10000, B00010, B10000, B00100, B01000, B00001, B01000, B00010, B01000, B00100}; Vilket stift är hög och låg för varje LED
//
Gamla versionen:
byte DirMatrix [12] = {B00110, B00110, B01010, B01010, B10010, B10010, B00101, B00101, B01001, B01001, B10001, B10001}; Vilket stift är utgång och som är hög impedence
byte PolMatrix [12] = {B00010, B00100, B00010, B01000, B00010, B10000, B00001, B00100, B00001, B01000, B00001, B10000}; Vilket stift är hög och låg för varje LED
byte läge = 0; numrerade från noll
CONST byte MaxModes = 4; Verkliga antalet lägen (så 1 om bara läge 0 definieras). Om större än 12 kommer att behöva ändra ChangeMode()
booleska SwitchMode = false;
booleska ButtonPress = false; Detta kan nu vara överflödig.
void setup() {
Serial.BEGIN(9600); Det finns vissa felsökning seriell kommandon återstående men bortkommenterad. De arbetar på Ardu "men inte tiny85
Serial.println ("tiny85 test").
Serial.println ("Ugi 2012");
DDRB & = B11100000; Ange alla stift till höga impedence
}
void loop() {
Växla (läge) {
fall 0:
OddEvenFlash();
bryta;
fall 1:
Progressive(8,0);
bryta;
fall 2:
Progressive(8,1);
bryta;
fall 3:
Larsen(8);
bryta;
}
om (SwitchMode) {SwitchMode = false; ChangeMode();}
}
Detta är den centrala rutinen som lyser en LED.
Tar bara LED nummer (0 till 11)
använder direkt tillträde till hamn för lätthet och snabbhet
void LightLED(byte LEDno) {
DDRB & = B11100000; Ställa in alla stift ingång
PORTB & = B11100000; Lågt satt alla stift
PORTB| = PolMatrix [LEDno]; Ange relevanta pins hög & låg
DDRB| = DirMatrix [LEDno]; Ange två relevanta stift att produktionen
}
Kontrollerar status på knappen.
Inte kalla det alltför ofta ' cos det avfall tid.
booleska CheckButton() {
DDRB & = B11100000; Ställa in alla stift ingång
PORTB & = B11100000; Lågt satt alla stift
PORTB| = B00000100; Ställa in PB2 hög - set inre pullup
delayMicroseconds(100); Behovet av att låta sedimentera ökning om problem med knappen trycker
Serial.println (PINB & B00000100);
flyktiga booleska tryck = PINB & B00000100;
IF(!press) {/ / om drog ner av switch
medan (! tryck) {/ / vänta tills switch släppt
Serial.Print ("debounce"); Serial.println (PINB & B00000100);
Delay(20);
Tryck = PINB & B00000100;
}
return true;
}
returnera false;
}
Förskott variabeln "Mode".
void ChangeMode() {
Läge ++;
om (läge > = MaxModes) läge = 0;
Serial.println(mode);
för (byte flash = 0; flash < = läge, flash ++) {
LightLED(Mode);
Delay(5);
DDRB & = B11100000;
Delay(15);
}
}
Funktioner definieras nedan...
OddEvenFlash - utformad som standardfunktionen. Detta blinkar växelvis udda och jämna LED.
Bör vara användbart för felsökning hårdvara som ser OK.
void OddEvenFlash() {
CONST unsigned int Timer = 300;
ButtonPress = 0;
booleska udda = false;
tag (!. ButtonPress) {
för (unsigned int tid = 0; tid <(Loop*Timer); tid ++) {
för (byte LED = 0; LED < 12; LED + = 2) {
LightLED(LED+Odd);
}
}
Udda =! Udda;
SwitchMode=CheckButton();
om (SwitchMode) {
Serial.println ("SwitchMode uppsättning");
hemkomst.
}
}
}
Progressiv Looping
Skickar ett "öga" av 4 lysdioder runt loopen av tonar in och ut sekventiellt.
Andra funktionen - igen till stöd hårdvara felsökning & också ser cool!
void progressiv (byte mellanskillnad, booleska Reverse) {
byte EyePos [4] = {3,2,1,0}.
om (bakåt) {
EyePos [0] = 8.
EyePos [1] = 9.
EyePos [2] = 10;
EyePos [3] = 11;
}
byte EyeInt[4]={64,192,(192-Increment),(64-Increment)};
tag (!. ButtonPress) {
för (byte hastighet = 0; Speed < slinga; Snabba += 8) {/ / detta ska utjämna hastighet för klocka freq
för (byte Pos = 0; POS < 4; POS++) {/ / ljus 4 lysdioder enligt deras ljusstyrka
LightLED(EyePos[Pos]);
Serial.Print (EyePos [Pos], DEC); Serial.Print("="); Serial.Print(EyeInt[POS],dec); Serial.Print("");
byte skrot;
för (byte Count = 0; Greve < EyeInt [Pos]; Count++) {PORTB & = B11111111;}
}
Serial.println("");
EyeInt [0] += ökning;
EyeInt [1] += ökning;
EyeInt [2]-= Increment;
EyeInt [3]-= Increment;
om (EyeInt [3] < Increment) {
EyeInt [3] = EyeInt [2].
EyeInt [2] = EyeInt [1].
EyeInt [1] = EyeInt [0];
EyeInt [0] = 0;
EyePos [3] = EyePos [2].
EyePos [2] = EyePos [1].
EyePos [1] = EyePos [0];
IF(reverse) {
EyePos [0]--;
om (EyePos [0] > 200) {EyePos [0] = 11.}
}
annat {
EyePos [0] ++;
om (EyePos [0] > 11) {EyePos [0] = 0;}
}
SwitchMode=CheckButton();
IF(SwitchMode) {återvänder;}
}
}
}
}
Larsen scanner typ våg
Skulle kunna göra detta som en del av progressiv. Jag kunde inte göra det effektivt.
void Larsen(byte Increment) {
byte EyePos [4] = {3,2,1,0}.
byte EyeInt[4]={64,192,(192-Increment),(64-Increment)};
booleska bakåt = false;
tag (!. ButtonPress) {
för (byte hastighet = 0; Speed < slinga; Snabba += 8) {/ / detta ska utjämna hastighet för klocka freq
för (byte Pos = 0; POS < 4; POS++) {/ / ljus 4 lysdioder enligt deras ljusstyrka
LightLED(EyePos[Pos]);
Serial.Print (EyePos [Pos], DEC); Serial.Print("="); Serial.Print(EyeInt[POS],dec); Serial.Print("");
för (byte Count = 0; Greve < EyeInt [Pos]; Count++) {PORTB & = B11111111;} / / Håll lampan tänd i taget beroende på ögat intensitet
}
Serial.println("");
}
EyeInt [0] += ökning;
EyeInt [1] += ökning;
EyeInt [2]-= Increment;
EyeInt [3]-= Increment;
om (EyeInt [3] < Increment) {
EyeInt [3] = EyeInt [2].
EyeInt [2] = EyeInt [1].
EyeInt [1] = EyeInt [0];
EyeInt [0] = 0;
EyePos [3] = EyePos [2].
EyePos [2] = EyePos [1].
EyePos [1] = EyePos [0];
IF(reverse) {
EyePos [0]--;
om (EyePos [0] > 200) {EyePos [0] = 1; Omvänd = false;}
}
annat {
EyePos [0] ++;
om (EyePos [0] > 11) {EyePos [0] = 10; Omvänd = sant;}
}
SwitchMode=CheckButton();
IF(SwitchMode) {återvänder;}
}
}
}