Es ist mal wieder soweit ich habe ein neues Projekt so gut wie fertiggestellt.
Da ich sowieso grade die Platinen Herstellung mit der Direkt-Toner-Methode ausprobieren wollte
habe ich für meine für meine Tochter eine kleine Spielerei gebaut.
Dabei kam dann diese Platine heraus … ein Tannenbaum der blinken kann.
Die ich dann noch mit einen Shift Register (74HC164N), einen ATtiny 85,
paar SMD(1206) LED´s und eine Taster bestückt habe.
Wenn der Baum eingeschaltet wird läuft er erstmal im Demo-Modus in dem er alle Blink Modis durchläuft,
wird der Taster gedrückt springt er aus dem Demo-Modus und man kann alle Modis einzelnd aufrufen.
Wird der Taster wieder 5 Sekunden gedrückt gehalten springt er wieder in dem Demo-Modus.
Hier noch paar Bilder dazu:
Hier einmal der Code:
#define ClockPin 4 #define DataPin 2 #define TrigerPin 3 #define StarPin 0 byte PushCount = 0; byte HoldCount = 0; long previousMillis = 0; long StarMillis = 0; long DemoMillis = 0; long ButtonMillis = 0; byte TempCount = 0; long currentMillis = 0; bool Reverse = false; byte Fade = 10; byte FadeSpeed = 5; bool DemoMode = true; bool ButtonPushed = false; byte LED[30] = { //0 - 5 B00000000, B00001010, B00011011, B10111011, B11111011, B11111111, //6 - 7 B11000011, B00111100, //8 - 15 B10000000, B00100000, B01000000, B00000100, B00010000, B00001000, B00000010, B00000001, //16 - 23 B10000000, B00100000, B01000000, B00000001, B00010000, B00000100, B00000010, B00001000, //24 - 29 B10100000, B01000000, B00010001, B00000100, B00001010, B00000000 }; void setup() { pinMode(StarPin, OUTPUT); pinMode(DataPin, OUTPUT); pinMode(ClockPin, OUTPUT); pinMode(TrigerPin, INPUT_PULLUP); } void loop() { currentMillis = millis(); // Püfen on der Button gedrückt wird if (!digitalRead(TrigerPin) && (currentMillis - ButtonMillis) > 200) { ButtonMillis = currentMillis; if (!ButtonPushed) { PushCount++; DemoMode = false; ButtonPushed = true; HoldCount = 0; } // DemoMode wieder aktivieren else if (HoldCount++ > 25) { DemoMode = true; shiftOut(DataPin, ClockPin, MSBFIRST, LED[0]); delay(200); } if (PushCount > 15) PushCount = 0; } else if (digitalRead(TrigerPin)) ButtonPushed = false; // Der Demo Modus Funktionswechsel alle 10 Sek. (wenn nichts gedrückt wurde) if (DemoMode && (currentMillis - DemoMillis) > 10000) { DemoMillis = currentMillis; PushCount++; if (PushCount > 14) PushCount = 0; } // Dauerhafter Fade für die Star-LED FadeStar(); // Den Taster auf Eingabe auswerten switch (PushCount) { case 0: TwoDance(); break; case 1: DriftInAndOut(); break; case 2: RoundAndRound(false); break; case 3: RoundAndRound(true); break; case 4: RandomLight(); break; case 5: RandomShiftLight(false); break; case 6: RandomShiftLight(true); break; case 7: RandomDualShiftLight(false); break; case 8: RandomDualShiftLight(true); break; case 9: Jumping(false, false); break; case 10: Jumping(false, true); break; case 11: Jumping(true, false); break; case 12: Jumping(true, true); break; case 13: Rain(false); break; case 14: Rain(true); break; default: AllOn(); break; } } void FadeStar() { if (currentMillis - StarMillis > 30) { StarMillis = currentMillis; analogWrite(StarPin, Fade); Fade = Fade + FadeSpeed; if (Fade == 10 || Fade == 255) { FadeSpeed = -FadeSpeed; } } } void TwoDance() { if (currentMillis - previousMillis > 650) { previousMillis = currentMillis; if (TempCount < 6 || TempCount > 7) TempCount = 6; shiftOut(DataPin, ClockPin, MSBFIRST, LED[TempCount]); TempCount++; } } void DriftInAndOut() { int Helper = TempCount; if (currentMillis - previousMillis > 250) { previousMillis = currentMillis; if (Reverse) Helper = 5 - TempCount; shiftOut(DataPin, ClockPin, LSBFIRST, LED[Helper]); TempCount++; if (TempCount > 5) { Reverse = !Reverse; TempCount = 0; } } } void RoundAndRound(bool Inverse) { if (currentMillis - previousMillis > 180) { previousMillis = currentMillis; if (TempCount > 15 || TempCount < 8) TempCount = 8; if (Inverse) shiftOut(DataPin, ClockPin, MSBFIRST, LED[TempCount] ^ B11111111); else shiftOut(DataPin, ClockPin, MSBFIRST, LED[TempCount]); TempCount++; } } void RandomLight() { if (currentMillis - previousMillis > 180) { previousMillis = currentMillis; shiftOut(DataPin, ClockPin, MSBFIRST, random(0, 255)); } } void RandomShiftLight(bool Inverse) { if (currentMillis - previousMillis > 160) { previousMillis = currentMillis; if (Inverse) shiftOut(DataPin, ClockPin, MSBFIRST, LED[15] << random(0, 8) ^ 255); else shiftOut(DataPin, ClockPin, MSBFIRST, LED[15] << random(0, 8)); } } void RandomDualShiftLight(bool Inverse) { if (currentMillis - previousMillis > 180) { previousMillis = currentMillis; byte lights = (LED[15] << random(0, 4)) | (LED[8] >> random(0, 4)); if (Inverse) shiftOut(DataPin, ClockPin, MSBFIRST, lights ^ 255); else shiftOut(DataPin, ClockPin, MSBFIRST, lights); } } void Jumping(bool _Reverse, bool Inverse) { if (currentMillis - previousMillis > 180) { previousMillis = currentMillis; if (_Reverse) { if (TempCount < 16 || TempCount > 23) TempCount = 23; } else { if (TempCount < 16 || TempCount > 23) TempCount = 16; } if (Inverse) shiftOut(DataPin, ClockPin, LSBFIRST, LED[TempCount] ^ 255); else shiftOut(DataPin, ClockPin, LSBFIRST, LED[TempCount]); if (_Reverse) TempCount--; else TempCount++; } } void Rain(bool Inverse) { if (currentMillis - previousMillis > 220) { previousMillis = currentMillis; if (TempCount < 24 || TempCount > 29) TempCount = 24; if (Inverse) shiftOut(DataPin, ClockPin, LSBFIRST, LED[TempCount] ^ 255); else shiftOut(DataPin, ClockPin, LSBFIRST, LED[TempCount]); TempCount++; } } void AllOn() { shiftOut(DataPin, ClockPin, MSBFIRST, LED[5]); }
Und noch ein Video:
1 Kommentar
Shojo · 19. November 2016 um 14:30
Auf Wunsch habe ich mal den Code dazugepackt !