AVR: Rundumlicht Sketch

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Ich hab aus aktuellem Anlass für ein Flipperautomat eines Kumpels, mithilfe eines ATTiny84A (den ich aus dem Funk-Projekt noch zu genüge hier habe) ein Rundumlicht geschrieben.

    Zunächst hatte ich nur einen Modus, wo immer nur eine LED an war und dann nacheinander die nächste LED geschaltet wurde..
    Im laufe des ausprobierens hab ich dann noch einen Modus geschrieben bei der jeweils 2 gegenüberliegende LEDs gleichzeitig an sind.
    Der ein oder andere kennt das vielleicht dass manche Blaulichter entweder nur einen Spiegel haben welcher sich um die Lampe dreht und somit dem 2.Modus entsprechen würde - aber andere Blaulichter haben 2 Spiegel und lassen das Licht somit sowohl nach vorne als auch nach hinten durch - das wäre dann eben der 1.Modus ;)

    Im laufe der Bastel-Session haben wir uns dann dazu entschlossen mithilfe eines einfachen Schalters zwischen den beiden Modis umschalten zu können; da wir uns nicht auf nur einen Modus festlegen konnten - weil beide geil sind :D
    Also hab ich den Sketch dahingegend erweitert das einer der I/O Ports auf ein PinChange-Interrupt reagiert und man in real-time einfach zwischen den beiden Modis hin und her schalten kann :angel:


    Ich hab die Sketches so geschrieben dass man nur anzugeben brauch wie viele LEDs man nutzen möchte: es könnten mit dem ATtiny84 maximal 11 LEDs genutzt werden - wobei wir letztlich nur 8 nutzen.. (angeordnet in einem 8-Eck)

    In dem Sketch gibt es zwei Zeitwerte (Angabe in Millisekunden) die man einstellen kann:

    • ledONdelay -> Wie lange die LED an sein soll, also die Brenndauer
    • nextDELAY -> Die Pause zwischen den LEDs, also wie viel ms vergehen soll bis die nächste LED an geht

    Ein Video folgt später - kam gestern nicht mehr dazu ;)


    1. Modus:

    Spoiler anzeigen

    1. & 2. Modus:

    Spoiler anzeigen


    Viel Spass damit :cool:


    //EDIT: Final Sketch sowie Video siehe vorletzter bzw letzter Spoiler in Beitrag#13

  • Hab noch mehr als genug ATmega und ATtiny hier rumfliegen. LED's kann ich mich auch mit totwerfen.
    Mal gucken, wie eine blau-rot-rundumleuchte aussieht :)

  • Die obigen Sketches funktionieren gut sofern es nur darauf ankommt dem ATtiny Strom zu geben, also sobald er Power kriegt arbeitet er sein Programm ab... Nun haben wir aber leider feststellen müssen dass der Virtual-Pinball (für den wir das gebastelt haben) über den LEDwiz ein PWM Signal schickt (ständig "an/aus/an/aus" usw schaltet) und wir das Steuersignal als GND genutzt haben - das hat zur Folge dass der ATTiny ständig an/aus/an/aus geschaltet wird und sein Programm nicht durchlaufen kann, die LED1 also immer an/aus/an/aus geht aber sich nichts wie gewünscht 'dreht' :(

    Deshalb hab ich den Sketch jetzt nochmals überarbeitet und einen weiteren PinChange-Interrupt eingebaut - der dann für das Steuersignal dienen soll.
    Der ATTiny wird also nun dauerhaft mit Strom versorgt (5V, VCC und GND permanent beschaltet), der MOD Schalter dient zum auswählen der 2 verschiedenen Modi's und das Steuersignal ist im Sketch als INPUT deklariert.

    Zum testen habe ich das hier auf einem Steckbrett nachgebaut und nutze für MOD sowie INPUT einen kleinen Taster. Betätige ich nun ein mal kurz den INPUT Taster wird der 2.Modus gestartet (2 gegenüberliegende LEDs drehen wechseln sich jeweils ab) und nach Vollendung der Runde ist das Programm wieder aus. Halte ich den INPUT Taster gedrückt läuft das ganze so lange ich den Taster gedrückt halte ;)
    Drücke ich dann vorher noch den MOD Taster, läuft das ganze eben mit der einzelnen LED ab (2.Modus). Für einen Dauerbetrieb des 2.Modus muss der MOD- als auch INPUT- Taster aber beide immer gedrückt werden, was für unseren Fall aber i.O. ist da wir einen Schalter und keinen Taster nutzen :)

    Hier der Sketch:

    Spoiler anzeigen

    Die Timer sind höher gesetzt, damit man nicht geblitzdingst wird sondern besser sieht was passiert :D

    Video folgt morgen - bin jetzt zu müde das Handy ruhig genug zu halten :lol:

  • Hier das Video zum letzten Sketch:

    Externer Inhalt youtu.be
    Inhalte von externen Seiten werden ohne deine Zustimmung nicht automatisch geladen und angezeigt.
    Durch die Aktivierung der externen Inhalte erklärst du dich damit einverstanden, dass personenbezogene Daten an Drittplattformen übermittelt werden. Mehr Informationen dazu haben wir in unserer Datenschutzerklärung zur Verfügung gestellt.

  • Ich hab jetzt leider ein Problem und stehe ein wenig auf dem Schlauch =(

    Die bisherigen Sketches sind leider nicht so wie es sein sollte -> Es kommt oft vor dass das INPUT Signal (vom LEDwiz) einfach mitten in der "Drehung" aus geht und dann müsste/sollte das Rundumlicht auch stehen bleiben. Beim nächsten einschalten vom INPUT soll das Rundumlicht dann dort weiter machen wo es zuvor aufgehört hatte...

    Um das zu erreichen weiß ich das der lastState gespeichert werden müßte - nur hapert es wie immer an der Umsetzung :(

    Da ich ja nur eine bestimmte Anzahl an Ausgängen vom ATtiny nutze, dachte ich zunächst das ich beim initLEDS(); auch den lastState schonmal setze:

    Code
    int lastState[i] = 0;      // Speichert den letzten Zustand der LED (0=aus, 1=an)


    Soweit so gut, nur wie kann ich dann im loop() feststellen welche LED zuvor an war und dann bei der nächsten weiter machen? Und was ist wenn keine zuvor an war? Und wie sieht das bei den 2 unterschiedlichen Mods jeweils aus? :-/

    :helpnew:

  • Kann man denn gezielt nach der 1 suchen?

    Also das Problem was ich hab ist zum einen das Suchen ob eine LED zuvor An war - und zum andern was dann danach passieren soll also besonders in dem Fall von:

    Code
    if (modSwitchState == 1) {
           int i;
           for (i = 0; i < USE_LEDS; i++) {
             activityLed(LED[i], ledONdelay_ONE);
             delay(nextDELAY_ONE);
           }
        } else {
    • Offizieller Beitrag

    Ich finde den Weg über dieses laststate array auf jedenfall einen Versuch wert. Mal in C/Pseudocode mischmasch ;)

    Wahrscheinlich macht es mehr Sinn das Array immer komplett zu durchsuchen um zu wissen ob es im Modus 0 oder 1 betrieben wurde. Ich hoffe du erkennst was ich meine, bin mir grad selbst nicht mehr sicher und diese endlosen klammern und ; verwirren mein Gehirn :). Es gibt natürlich noch ein paar Sonderfälle die es zu betrachten gilt. Aber generell sollte das doch so klappen, oder?

  • Das ist ein Fuchs, dieser dbv :thumbs1: ... und dann auch noch Kobra ... äh Python ....

    Denkbar wäre imho den Modus auch irgendwie als Steuerinformation abzuspeichern.
    Also rechtsrum, linksrum, 2 gegenüberliegende im Uhrzeigersinn, 2 gegenüberliegende gegen den Uhrzeigersinn, ...
    Wenn Du dann den aktuellen Modus (sichern bei jedem Umschalten) und die leuchtenden LEDs kennst, kannst Du problemlos den aktuellen Zustand ermitteln und darauf aufsetzen. Und dann läuft es einfach weiter ...
    Ich denke, so ähnlich meinte dbv das auch ...
    Du machst das schon, Du alter Tüftler ...
    -ds-

  • Hm ich hab mich grad erst mal an den 1.Modus gesetzt da ich dachte der wär einfacher - aber leider scheint er lastState nicht zu beachten :(

    (1.Modus: MOD Taster nicht gedrückt also HIGH)

    Wenn ich den INPUT Taster für 2 Sekunden drücke damit das 2. oder 3. Paar LEDs an geht und dann wieder los lasse, geht beim erneuten drücken wieder das erste Pärchen (LED[0] und LED[4]) an =(


    Sieht jemand den Fehler?


    /EDIT: Hm strange, wenn mans beim erneuten drücken des INPUT Tasters genau trifft (also wenn er zum 2.Pärchen wechselt, aus geht und man dann rechtzeitig den Taster erneut drückt) dann macht er mit der nächsten LED weiter - verpasst man aber den passenden Zeitpunkt startet er wieder von vorne....
    Aber ich glaub das hat nichts mit lastState zu tun :huh: Kanns sein das der ATtiny beim durchlaufen des loop(); nicht wirklich etwas zwischenspeichert?

    /EDIT2: Ich glaub ich hab den Fehler:

    Code
    int getONstate() {
      int i;
      for (i = 0; i < USE_LEDS; i++) {
        if (lastState[i] == 1) { return i; } else { return -1; }
      }
    }


    das returned immer -1 weil lastState[0] nicht 1 sondern 0 ist, sobald er das nächste Pärchen geschaltet hat..

    Also müßte das hier gehen:

    Code
    int getONstate() {
      int i;
      for (i = 0; i < USE_LEDS; i++) {
        if (lastState[i] == 1) { return i; }
      }
      return -1;
    }

    Allerdings hab ich jetzt irgendein kuddelmuddel - manchmal schaltet er einfach in den 2.Modus um wärend er aber im 1.Modus is... Oder er macht einfach weiter obwohl INPUT nicht gedrückt is :(

    dbv: dein Code funktioniert so leider auch ned ;)

  • So ich glaub ich hab zumindest den 1.Mode hingekriegt - um den 2.Mode kümmer ich mich heute Abend :D

    Der 2.Mode funktioniert leider noch nicht so wie gewünscht - und selbtsamerweise verselbstständigt sich das Programm auch irgendwann durch den 2.Mod obwohl ISW_PIN nicht gedrückt wird :s :wallbash:


    Ich hab den Code auch etwas optimiert und verkürzt, initLEDS() zB ist viel kleiner, im loop(); wird nur noch modeONE(); und modeTWO(); aufgerufen und modeONE(); war vorher hardcoded und ziemlich lang das hab ich nun auch flexibler und kleiner gemacht :angel:

    Sketch:

    Spoiler anzeigen

    Und hier das Video zum 1.Mod:

    Spoiler anzeigen


    Externer Inhalt youtu.be
    Inhalte von externen Seiten werden ohne deine Zustimmung nicht automatisch geladen und angezeigt.
    Durch die Aktivierung der externen Inhalte erklärst du dich damit einverstanden, dass personenbezogene Daten an Drittplattformen übermittelt werden. Mehr Informationen dazu haben wir in unserer Datenschutzerklärung zur Verfügung gestellt.

    (das Geräusch im Hintergrund is btw nen Rasenmäher vom Nachbarn :D)

    /EDIT: Der 2.Mode funktioniert nun auch :)
    Nur wenn man mitten drin den Mode wechselt bleibt er seltsamerweise manchmal(!) im alten :(


    //EDIT2: Wenn man zwischen den beiden Modes wechselt, wärend INPUT an ist, macht er einfach weiter obwohl man INPUT los lässt :(

    Woran kann das liegen?? :helpnew:


    //EDIT3: Fürs bessere Verständnis hab ich die Modes getauscht:
    modeONE(); -> nur eine LED rotiert.
    modeTWO(); -> zwei gegenüberliegende LEDs rotieren.

    Dementsprechend gelten die Zeiteinstellungen ganz oben im Sketch auch für den jeweiligen Mode: *_ONE für modeONE und *_TWO für modeTWO

    Spoiler anzeigen

    Video von beiden Modes, wo am Ende leider auch noch der seltsame Bug zu sehen ist:

    Spoiler anzeigen

    Externer Inhalt youtu.be
    Inhalte von externen Seiten werden ohne deine Zustimmung nicht automatisch geladen und angezeigt.
    Durch die Aktivierung der externen Inhalte erklärst du dich damit einverstanden, dass personenbezogene Daten an Drittplattformen übermittelt werden. Mehr Informationen dazu haben wir in unserer Datenschutzerklärung zur Verfügung gestellt.

  • Ja hey alter Bastler ...
    also, ich hab jetzt Dein Arduino-Script (Programm??) ... überflogen.
    Das reagiert doch gar nicht auf eine Taste.
    Beide Tasten lösen bei fallender Flanke die Funktion wakeup() auf, und die tut ... nix.
    Sonderbar, dass trotzdem was passiert ... nun, vielleicht habe ich da was übersehen.

    Vielleicht mal was zu der Vorgehensweise, wie ich diese Geschichte angegangen wäre:
    Wir gehen mal von 8 LEDs maximal aus.
    Jetzt kann ich in einem char den Status für 8 LEDs hinterlegen, wenn es 10 sind, brauche ich halt 2 byte.
    Jetzt "verbinde" ich jeweils einen Pin "virtuell" mit einer LED.
    Ja ... Nun 1 = LED an, 0 = LED aus ... und Du kannst beliebige Muster definieren indem Du einfach die aktuellen Bytes auswertest und die Werte in die Register der Pins schreibst.
    char StateMod1[] = {
    // 00010001
    // 00100010
    // 01000100
    // 10001000
    // 00000000
    // 00000000
    // 00000000
    // 00000000
    };

    char StateMod2[] = {
    // 00000001
    // 00000010
    // 00000100
    // 00001000
    // 00010000
    // 00100000
    // 01000000
    // 10000000
    // 00000000
    };


    Merkst Du Dir das aktuelle Muster bzw. den aktuellen Modus und den aktuellen Index, kannst Du jederzeit genau da wieder aufsetzen.
    Mit sizeof() erhälst Du die Anzahl der Elemente.
    Jetzt kannst Du dann das nochmals in eine passende struct zusammenfassen mit Status-Bits/-Bytes und Merkern.

    cheers,
    -ds-


  • Ja hey alter Bastler ...
    also, ich hab jetzt Dein Arduino-Script (Programm??) ... überflogen.
    Das reagiert doch gar nicht auf eine Taste.
    Beide Tasten lösen bei fallender Flanke die Funktion wakeup() auf, und die tut ... nix.
    Sonderbar, dass trotzdem was passiert ... nun, vielleicht habe ich da was übersehen.

    Es funktioniert aber - wie du am Video unschwer erkennen kannst :D
    Das einzige Problem was zZt noch besteht ist, dass bei gedrücktem INPUT Taster sowie wechseln des MODes abunzu sich die Schaltung verselbstständigt und dann von alleine weiter macht obwohl man INPUT los lässt aber das laut Sketch nicht sein dürfte...

  • Tja ... mag sein dass es irgendwie geht.
    Aber dass es sich bei Tastendruck verselbsständigt deutet doch darauf hin, dass da irgendwo ein Bug ist.
    Und wenn eine Funktion aufgerufen wird, die nix tut und trotzdem was bewirkt, dann würde mich das schon stutzig machen ...

    cu,
    -ds-

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!