WS2822 und Arduino

  • Hallo Freunde ,
    ich brauche mal eure Hilfe.
    Ich habe eine Reihe von 30 LED Pixel WS2822 .
    Folgendes soll Passieren, wenn ich das arduino Starte sollen alle 30 Pixel auf Grün sein, und wenn ich ein pin auf 5 Volt lege (Schalter) dann sollen die LEDS Orange Laufen.
    Allerdings macht das arduino störungen . habe den Taster an Pin 10 angeschlosen, aber wenn ich pin 8 oder 9 brücke geht das programm auch los. und wenn ich den pin 10 wieder löse (Schalter aus) geht das programm ab und zu sofort aus , aber manchmal auch später.
    Was mache ich falsch.


    Hier mein Code
    //*****************************************************************
    // WS2822S
    // 2015/01/29
    //
    // 色情報の設定 setColor(LEDの番号、赤、緑、青)
    // 色情報の送信 send()
    //
    //******************************************************************


    #include "Ws2822s.h"
    #define NUM_PIXELS 30// 使用するWS2822Sの数
    #define LED_PIN 3 // WS2822SのDAIピンにつなげるArduinoのピン番号
    const int buttonPin = 8;
    int buttonState = 0;
    Ws2822s LED(LED_PIN, NUM_PIXELS);
    void setup()
    {
    pinMode(buttonPin, INPUT);
    }


    void loop(){


    buttonState = digitalRead(buttonPin);
    delay(5);
    if (buttonState == HIGH) {
    for(int i = 0; i < NUM_PIXELS; ++i) {
    LED.setColor(i,0, 0, 0);
    LED.setColor((i +20) % NUM_PIXELS,55, 0, 255);
    LED.send();
    delay(100);
    }
    }
    else{ // Ansonsten
    for(int i = 0; i < NUM_PIXELS; ++i) {
    LED.setColor(i,255, 0, 0);
    LED.send();
    delay(50);
    }
    }
    }



    Wäre über eine Hilfe Dankbar


    Grüsse Dominic

  • Was mir auffält:
    Pin 10 ist mit dem Taster beschaltet, aber du legst Pin 8 als "buttonPin" fest.

    Code
    const int buttonPin = 8;


    Also entweder Taster an Pin 8 oder Pin 10 als buttonPin definieren.


    Zweitens:
    Du solltest für einen Eingangspin immer einen Pull-up oder pull-down Widerstand verwenden. Diese sind notwending um immer ein klaren HIGH oder LOW Pegel, also 0V oder 5V am Eingang anliegen zuhaben. In deinem Fall liegen bei drücken des Tasters 5V am Eingang an. Was passiert aber, wenn der Taster nicht gedrückt wird? Ohne Pull-down Widerstand hängt der Eingang quasi "in der Luft" und dem Arduino ist nicht klar ob jetzt wirklich 0V anliegen, wodurch es leicht zu Störungen kommt.


    Tipp: Der Arduino hat interne Pull-Up Widerstände; dafür müsstest du aber gegen GRD schalten, was auch kein Problem darstellen sollte. Dann kannst du dir einen externen Widerstand sparen.
    Zur Verwendung der internen Pull-Ups einfach im Setup folgendes setzen:

    Code
    digitalWrite(pin, HIGH); // Pull Up Widerstand aktivieren


    Zwischenfrage: Hast du den bisherigen Code selber geschrieben? Warscheinlich nicht, oder?


    Für weitere Projekte: Du solltest auf "Delays" möglichst verzichten. Diese dienen momentan nur dazu, den Taster zu entprellen. Funktioniert zwar und ist auch legitim wenn das Umschalten die einzige Aufgabe des Arduino bleibt. Wenn aber noch weitere Aufgaben dazu kommen, gibt es meistens mit "delay"s Probleme.

  • Hey super Hat geklappt Danke.
    den code habe ich mir zusammmen gesucht da es mein erstes project mit dem WS2822 ist.
    Sonst nehme ich immer UCS1903 und der ist ja in der Fastled.h vorhanden .


    Jetzt geht es soweit ohne Störung.
    Soweit ich jetzt gegen GND Schalte, fangen die led an zu laufen.
    Wenn ich den pin wieder öffne dauer es ca 2-3 sekunden und er geht auf Grün.
    Wie kann ich das noch verkürzen das er sofort auf grün geht ? ohne Verzögerung.


    Hier der code den ich jetzt nehme



    Grüsse Dominic


    //*****************************************************************
    // WS2822S
    // 2015/01/29
    //
    // 色情報の設定 setColor(LEDの番号、赤、緑、青)
    // 色情報の送信 send()
    //
    //******************************************************************


    #include "Ws2822s.h"
    #define NUM_PIXELS 30// 使用するWS2822Sの数
    #define LED_PIN 3 // WS2822SのDAIピンにつなげるArduinoのピン番号
    const int buttonPin = 8;
    int buttonState = 0;
    Ws2822s LED(LED_PIN, NUM_PIXELS);
    void setup()
    {
    pinMode(buttonPin, INPUT);
    digitalWrite(buttonPin, HIGH); // Pull Up Widerstand aktivieren
    }


    void loop(){


    buttonState = digitalRead(buttonPin);
    if (buttonState == LOW) {
    for(int i = 0; i < NUM_PIXELS; ++i) {
    LED.setColor(i,0, 0, 0);
    LED.setColor((i +20) % NUM_PIXELS,55, 0, 255);
    LED.send();
    delay(100);
    }
    }
    else{ // Ansonsten
    for(int i = 0; i < NUM_PIXELS; ++i) {
    LED.setColor(i,255, 0, 0);
    LED.send();

    }
    }
    }

  • Da bin ich überfragt. Nach deinem Code sollte die Verzögerung max. 100ms betragen. Eventuell ist die Ws2822 library der knackpunk; genauer kann ich das leider nicht begründen. Dazu fehlt mir einfach die Ahnung.


    Noch ein Tipp für die Verwendung von Code hier im Forum:
    Es gibt eine Code-Funtkion (<> Schaltfläche); damit kannst du den Code recht übersichtlich einbinden und die Zeilen sind nummeriert. Das macht es einfacher, sich durch den Code zu lesen.


    Gruß Hxg135

  • Zitat

    Da bin ich überfragt. Nach deinem Code sollte die Verzögerung max. 100ms betragen.


    Die Verzögerung beträgt meiner Meinung nach genau 3000ms = 3s



    Zitat

    Wie kann ich das noch verkürzen das er sofort auf grün geht ? ohne Verzögerung.


    Dir wurde schon gesagt wie schlecht delay() ist, warum benutzt Du es immer noch? Ich denke das ist hier der Fehler.

  • Zitat

    Würdest du mir/uns kurz erläutern, wie du auf die 3000ms kommst?


    Die 100ms delay() sind in einem for loop, der NUM_PIXELs mal läuft.
    Es sind also 30 x 100ms delay


    Eigentlich sollte so aber eine Art fill-Effekt erzeugt werden, vielleicht ist das aber auch der Fall, da müsste man auf die Antwort vom OP warten.


    Ist eh ziemlich krude gelöst, aber solange es dann läuft :)


    Zitat

    Wie kann ich die selbe function ohne delay machen ?


    Was passiert denn wenn du das delay rauslässt, bzw auf delay(1); verkürzt, was dann 30ms wären.


    Generell umgehen kann man delay mit timerzählen:


    https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

  • Ah okay, Vielen Dank!
    Jetzt versteh ich auch wie der Hase läuft. :thumbup:


    Statt dem Delay den millis() Befehl verwenden und die Zeit bei der ersten Abfrage zwischen speichern.



    EDIT:
    Ich würde eher saw0's Empfehlung zum Entprellen folgen. Ich hab die "Bounce" Library noch nicht getestet. ;)

  • Sorry, ich hatte das mit dem Lauflicht falsch gelesen. Das meinte ich mit Fill-Effekt.


    Das Problem ist aber trotzdem hier, dass du aus dem for loop nicht mehr rauskommst, bevor du den Schalter wieder abfrägst, also 3sec brauchst bis


    Code
    if (buttonState == LOW)


    wieder seinen State ändern kann.


    Schau mal ob sowas wie



    läuft. Nicht vergessen noch


    Code
    unsigned long previousMillis = 0;


    Code
    const long interval = xxxx;

    zu definieren.


    Das Problem ist halt hier, dass ich hier im Hotel nichts zum Testen habe, keine Arduino und keine WS28xx Chips, da ist Code umschreiben immer schwer.



    //EDIT:


    Zitat

    Dann aber den Taster nicht vergessen zu entprellen.


    Für Taster kann ich nur die Button lib empfehlen :)


    http://playground.arduino.cc/Code/Button

  • So haeb es getestet.
    wenn ich den knopf drücke fängt das licht an zu laufen wenfn ich bei xxx eine wert eingebe zum beispiel 1000 dann kommt organge dann wieder grün, orange grün als ob er in den else modus geht.


    wenn ich den Taster los lasse geht er sofort auf grün, so wie es seien soll.
    Nur das lauflicht geht nicht richtig



    Grüsse Dominic

  • //*****************************************************************

  • Zitat

    wenn ich den knopf drücke fängt das licht an zu laufen wenfn ich bei xxx eine wert eingebe zum beispiel 1000 dann kommt organge dann wieder grün, orange grün als ob er in den else modus geht.


    Hm, der Anfang ist gemacht, da müsstest du jetzt bisschen rumprobieren. Das meinte ich mit "schwer das ohne Hardware zu testen".

  • Das Problem sehe ich in der Reihenfolge der Abfragen.
    Momentan beginnt der loop mit der Abfrage der Intervall-Zeits Wenn die Intervall-Zeit erreicht ist, wird die Abfrage des Tasters ausgeführt. Falls nicht wird "else" ausgeführt.
    Endet die Taster-Abfrage mit "low" wird der erste Pixel Orange geschaltet. Dann geht der loop wieder von vorne los. Im nächsten Durchlauf des loops ist aber die Intervall-Zeit noch nicht erreicht und "else" tritt ein. Also wieder alle Pixel auf grün. Und das solange, bis die Intervallzeit erreicht ist und wenn derTaster immer noch gedrückt wird, dann wird erst der zweite Pixel Orange geschaltet....usw.


    Mir fällt aber gerade kein Lösungsweg ein. Denn wenn du die Tasterabfrage als erstes durchläufst und dann erst die Abfrage des Intervalls, bleibt trotzdem das Problem, dass bei nicht erreichen des Intervalls das Programm "else" ausführt. Man müsste also nach der Taster und Intervall Abfrage immer wieder von vorne beginnen, wenn "low" erkannt wird. Oder eine andere Bedingung einführen.... ?(

  • Ok werde das ganze mal ändern da ich in dem lauflicht auch nen fehler hab. Das lauflicht soll als bewegung dar gestell werden sprich wie nen 3kanal.lauflicht led 1/4/7/10/13/16/19
    2/5/8/11/14/17/20
    3/6/9/12/15/18/22


    Und so weiter ,es sollen halt pro kanal 10 segmente angehen