Go Down

Topic: Neopixel AppInventor NodeMCU (Read 860 times) previous topic - next topic

Merzomann


postmaster-ino

#16
Dec 09, 2018, 06:35 pm Last Edit: Dec 09, 2018, 06:36 pm by postmaster-ino
Hi

int pause=10; Kommentar passt wohl nicht zum dort stehendem Wert - warum den Kommentar nicht sinnvoll nutzen und 'Pause in ms zwischen Einzel-LEDs' - also den Wert nicht erneut nennen, sondern sagen, was dieser Wert Da macht.

int status; - Wie viele Status hast Du? Können Die auch negativ werden? Byte bietet den Bereich 0...255, reicht z.Bl. auch für Pin-Definitionen.

DAS wird Dir loop() so lange neu starten, bis der Server endlich auch Mal läuft - sollte Er abschmieren, ist Dein loop() auch direkt wieder Müll, da NICHTS mehr ausgeführt wird, da loop() direkt beendet wird (return).
client = server.available();
if (!client) return;

Wenn Du alle Pixel auf die gleiche Farbe setzen möchtest, würde ich eine FOR-Schleife benutzen, ggf. eine eigene Funktion, wo ich die Farbe mit angeben kann - so hast Du bei den festen Farben NUR einen Funktionsaufruf und die Funktion (und den Platzverbrauch) nur 1x.

delay(pause) ist blöd, wenn Du mehrer Dinge quasi gleichzeitig machen willst - z.B. Serverdaten empfangen und LEDs ansteuern.
If (i==150) würde ich in NUMPIXELS (sollte man auch als const byte, statt #define angeben) ändern - so klappt der Code auch bei kürzeren/längeren Stripes
Da ALLE Deine Variablen genau das Gleiche machen - verpacke die Funktionalität in eine Funktion und rufe dann Diese mit den entsprechenden Parametern auf - eben dem Pixel, Der gerade gesetzt werden soll o.Ä..


Zu Deinem 'läuft nur 1x durch' - Du fragst Daten vom Server ab - ist Das gerade eine '5', wird das Lauflicht gestartet(?).
Blöd, daß im nächsten Durchlauf der Server keine erneute 5 sendet - Du musst Dir also MERKEN, daß das Lauflicht laufen soll und mit den Serverdaten diesen Merker setzen/löschen.

Alles in Allem: Viel Speicherplatz für nahezu identische Funktionalität - klar, unbenutzten Platz bekommt man auch nicht vergütet, aber SO muß ein Sketch nun auch wieder nicht aussehen - alleine die ganze Tipperei sollte Einen zur Funktionsnutzung bringen.

MfG

PS: Vll. nicht, was Du lesen wolltest - sorry dafür.
PPS: Habe ich was verpasst? Kommentarloser Sketch und dann ein Vielen Dank-Post ohne sonst was drum herum?
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Merzomann

Dank dir Postmaster für die ganzen Anmerkungen. Ich versuche sie umzusetzen. Allerdings bin ich kein Fachmann und mir fehlt da noch das Know-how. Aber folgender Teil ist genau mein Problem.

"Du musst Dir also MERKEN, daß das Lauflicht laufen soll und mit den Serverdaten diesen Merker setzen/löschen."

Wie mache ich das?


postmaster-ino

Hi

Code: [Select]

...
byte merker_lauflicht=0;  //=0 oberhalb setup(); unnötig, globale Variablen werden mit 0 initialisiert
...
if (data == '5'){
   //hier kommen wir NUR hin, wenn das Lauflicht gestartet werden soll
  merker_lauflicht=1;
}
//Im Gegenzug musst Du bei den anderen 'Befehlen' den Merker aber auch wieder zurück setzen
if (merker_lauflicht){  //wenn der Merker ungleich Null ist, kommen wir hier rein
  switch (merker_lauflicht){
    case 1: i=0;
               clear_stripe(); //löscht den Stripe - eigene Funktion, wirst Du schreiben müssen)
               lasttime=millis();
               merker_lauflicht=2; //nächste Status, Den wir abarbeiten wollen
               break;
    case 2:if (millis()-lasttime>=wartezeit){
                 set_pixel(i,0,0,0);  //lösche zuletzt gesetzten Pixel
                 i++;
                 lasttime+=wartezeit;  //=millis() ginge auch
                 if (i>=PixelCount){ //sind wir am Ende?){
                    merker_lauflicht=3;
                 }else{
                    set_pixel(i,r,g,b); //Pixel in Wunschfarbe setzen
                 }
                 break;
    case 3:if (millis()-lasttime>=wartezeit){
                 set_pixel(i,0,0,0);  //lösche zuletzt gesetzten Pixel
                 i--;
                 lasttime+=wartezeit;  //=millis() ginge auch
                 if (i==0){ //sind wir am Ende?){
                    merker_lauflicht=2;
                 }else{
                    set_pixel(i,r,g,b); //Pixel in Wunschfarbe setzen
                 }
                 break;
    default: Serial.print("Error");
   }
}

Das natürlich in loop() eingelassen - sollte dann die Pixel einzeln alle 'wartezeit' ms nach einander aufleuchten lassen.
Durch eine erneute '5' wird das Lauflicht neu gestartet.
Die ganzen globalen Variablen wie lasttime wirst Du erstellen müssen - entweder global, oder local mit static (damit Die erhalten bleiben - normale lokale Variablen gehen am Ende der Funktion verloren - und loop() ist auch nur eine Funktion.
Gerne Das in eine eigene Funktion ausgelagert, daß Du in loop() nur noch lauflicht(); aufrufen musst und diese Funktion sich darum kümmert, ob das Lauflicht laufen soll und wenn ja, was dabei gemacht werden soll.


MfG

PS: Mit dem Merker 'merkst' Du Dir nur irgend was, nicht mehr, nicht weniger. Manchmal ist die Welt wirklich so einfach :)
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Merzomann

Dank dir, ich werde es Morgen ausprobieren.

noiasca

#20
Dec 10, 2018, 07:43 pm Last Edit: Dec 10, 2018, 07:51 pm by noiasca
Dein Code hat zwei große Probleme.

Ich wiederhole in meinen Worten was Postmaster eh auch schon geschrieben hat:

Zunächst das

if (!client) return;

sorgt dafür, dass im Idle der restliche Code nicht mehr angesprungen wird - und du wunderst dich, dass das Lauflicht nicht läuft. Na super.

Wenn du das mal auskommentierst, wirst du festellen, dass zumindest alle 5000 millis das Lauflicht angesprochen wird.

Problem ist dann noch das

data = checkClient;

in der Folge kommt es dann im idle irgendwo zu einem 5000 millis timeout (zum Glück), wo genau weis ich nicht, aber vermutlich etwas aus der Ethernet-Lib. Egal, jedenfalls ist das auch suboptimal.

Ich hab daher das checkClient unter Bedingung gesetzt.

Dann setze ich data wieder auf leer zurück wenns einmal gültig war und eine Aktion ausgelöst hat.
Außerdem setze ich den Status (also den Merker) wieder auf 0, wenn eins der anderen Farbprogramme gewählt wurde. Kommt mir so logisch vor, dass wenn jemand rot wählt, es auch rot bleiben soll auch wenn vorher ein Lauflicht aktiv gewesen wäre.

So ist dein Code immer noch hässlich - es läuft aber:

Code: [Select]

// http://forum.arduino.cc/index.php?topic=581382.0

#include <ESP8266WiFi.h>
#include <Adafruit_NeoPixel.h>

#define PIN        15
#define NUMPIXELS  36

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

//Lauflicht_________________________________________________________________________
#ifdef __AVR__
#include <avr/power.h>
#endif

int i = 0;
int a = 2;
int b = 4;
int c = 6;
int d = 8;
int e = 10;

int pause = 10; // 100 Millisekunden Pause bis zur Ansteuerung der nächsten LED.
byte status;   //Statusvariable für Lauflicht________________________________________
//_________________________________________________________________________________


//ROUTER VERBINDUNG_____________________________________
/* define port */
WiFiClient client;
WiFiServer server(80);

// INTERNET Einstellungen
const char* ssid = "sdfsdfsfsdf";
const char* password = "sdfsdfsfsd";
IPAddress ip(172, 18, 67, 109); //set IP
IPAddress gateway(172, 18, 67, 230); //set getteway
IPAddress subnet(255, 255, 255, 0);

// Empfangene Daten von App
String  data = "";
//________________________________________________________


void setup() {
  pixels.begin();
  //ROUTER VERBINDUNG_________________________________________
  Serial.begin(115200);
  delay(10);
  // Verbindung zum Netzwerk
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.config(ip, gateway, subnet);
  WiFi.begin(ssid, password);
  if (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  server.begin();
  Serial.println("Server started");
  Serial.print("Type this address in URL to connect: ");
  Serial.print("http://");
  Serial.println(ip);
  Serial.println("/");
}

void loop()
{
  //Serial.print(F("."));
  // If the server available, run the "checkClient" function */
 
  client = server.available();
 
  //if (!client) return;  // WTF 1!
  //data = checkClient (); // WTF 2
  if (client) data = checkClient ();
 
  // Serial.print(millis()); Serial.print(F(" data="));Serial.println(data); // kannst testweise ausgeben
  // Eingehende Daten von App
  if (data == "1") {
    status = 0;
    data = "";
    Serial.println("Aus");
    pixels.setPixelColor(0, pixels.Color(0, 0, 0));
    pixels.setPixelColor(1, pixels.Color(0, 0, 0));
    pixels.setPixelColor(2, pixels.Color(0, 0, 0));
    pixels.setPixelColor(3, pixels.Color(0, 0, 0));
    pixels.setPixelColor(4, pixels.Color(0, 0, 0));
    pixels.setPixelColor(5, pixels.Color(0, 0, 0));
    pixels.setPixelColor(6, pixels.Color(0, 0, 0));
    pixels.setPixelColor(7, pixels.Color(0, 0, 0));
    pixels.setPixelColor(8, pixels.Color(0, 0, 0));
    //usw
    pixels.show();
  }
  else if (data == "2") {
    status = 0;
    data = "";
    Serial.println("Rot");
    pixels.setPixelColor(10, pixels.Color(255, 0, 0));
    pixels.setPixelColor(11, pixels.Color(255, 0, 0));
    pixels.setPixelColor(12, pixels.Color(255, 0, 0));
    pixels.setPixelColor(13, pixels.Color(255, 0, 0));
    pixels.setPixelColor(14, pixels.Color(255, 0, 0));
    pixels.setPixelColor(15, pixels.Color(255, 0, 0));
    pixels.setPixelColor(16, pixels.Color(255, 0, 0));
    pixels.setPixelColor(17, pixels.Color(255, 0, 0));
    pixels.setPixelColor(18, pixels.Color(255, 0, 0));
    pixels.setPixelColor(19, pixels.Color(255, 0, 0));
    pixels.setPixelColor(20, pixels.Color(255, 0, 0));
    pixels.show();
  }
  else if (data == "3") {
    status = 0;
    data = "";
    Serial.println("Blau");
    pixels.setPixelColor(10, pixels.Color(0, 0, 255));
    pixels.setPixelColor(11, pixels.Color(0, 0, 255));
    pixels.setPixelColor(12, pixels.Color(0, 0, 255));
    pixels.setPixelColor(13, pixels.Color(0, 0, 255));
    pixels.setPixelColor(14, pixels.Color(0, 0, 255));
    pixels.setPixelColor(15, pixels.Color(0, 0, 255));
    pixels.setPixelColor(16, pixels.Color(0, 0, 255));
    pixels.setPixelColor(17, pixels.Color(0, 0, 255));
    pixels.setPixelColor(18, pixels.Color(0, 0, 255));
    pixels.setPixelColor(19, pixels.Color(0, 0, 255));
    pixels.setPixelColor(20, pixels.Color(0, 0, 255));
    pixels.show();
  }
  // If the incoming data is "4", weiss
  else if (data == "4") {
    status = 0;
    data = "";
    Serial.println("Weiss");
    pixels.setPixelColor(10, pixels.Color(255, 255, 255));
    pixels.setPixelColor(11, pixels.Color(255, 255, 255));
    pixels.setPixelColor(12, pixels.Color(255, 255, 255));
    pixels.setPixelColor(13, pixels.Color(255, 255, 255));
    pixels.setPixelColor(14, pixels.Color(255, 255, 255));
    pixels.setPixelColor(15, pixels.Color(255, 255, 255));
    pixels.setPixelColor(16, pixels.Color(255, 255, 255));
    pixels.setPixelColor(17, pixels.Color(255, 255, 255));
    pixels.setPixelColor(18, pixels.Color(255, 255, 255));
    pixels.setPixelColor(19, pixels.Color(255, 255, 255));
    pixels.setPixelColor(20, pixels.Color(255, 255, 255));
    pixels.show();
    status = 0;
  }
  else if (data == "5")  //Lauflicht läuft leider nicht im Loop___________????????????????????????????
  {
    data = "";
    status = ! status;
    Serial.print(F("Status="));
    Serial.println(status);
  }
 
  if (status)
  {
    Serial.println("Lauflicht");
    pixels.setPixelColor(i, pixels.Color(0, 150, 0)); // Grün
    pixels.setPixelColor(a, pixels.Color(155, 0, 0)); // Rot
    pixels.setPixelColor(b, pixels.Color(0, 0, 150)); // blau
    pixels.setPixelColor(c, pixels.Color(150, 150, 0)); // gelb
    pixels.setPixelColor(d, pixels.Color(0, 150, 150)); // türkis
    pixels.setPixelColor(e, pixels.Color(150, 150, 150)); // weiss
    pixels.setPixelColor(i - 1, pixels.Color(0, 0, 0)); // Der vorherige Pixel wird abgeschaltet
    pixels.setPixelColor(a - 1, pixels.Color(0, 0, 0)); // Der vorherige Pixel wird abgeschaltet
    pixels.setPixelColor(b - 1, pixels.Color(0, 0, 0));
    pixels.setPixelColor(c - 1, pixels.Color(0, 0, 0));
    pixels.setPixelColor(d - 1, pixels.Color(0, 0, 0));
    pixels.setPixelColor(e - 1, pixels.Color(0, 0, 0));
    pixels.show(); // Durchführen der Pixel-Ansteuerung
    if (i == 0) pixels.setPixelColor(149, pixels.Color(0, 0, 0)); // Im Fall von Pixel "0" muss die vorherige (39) ausgeschaltet werden.
    if (a == 0) pixels.setPixelColor(149, pixels.Color(0, 0, 0));
    if (b == 0) pixels.setPixelColor(149, pixels.Color(0, 0, 0));
    if (c == 0) pixels.setPixelColor(149, pixels.Color(0, 0, 0));
    if (d == 0) pixels.setPixelColor(149, pixels.Color(0, 0, 0));
    if (e == 0) pixels.setPixelColor(149, pixels.Color(0, 0, 0));
    pixels.show(); // Durchführen der Pixel-Ansteuerung
    delay (pause);
    i = i + 1; // Die Variable "i" wird um eine Zahl vergrößert. Die neue Zahl "i" ist dann die nächste LED im Led-Ring
    a = a + 1;
    b = b + 1;
    c = c + 1;
    d = d + 1;
    e = e + 1;
    if (i == 150) i = 0; // Wenn die Variable den Wert 40 erreicht hat, wird die Variable auf den Wert "0" zurück gesetzt, da die Nummerierung der LEDs nur von 0 bis 39 geht.
    if (a == 150) a = 0;
    if (b == 150) b = 0;
    if (c == 150) c = 0;
    if (d == 150) d = 0;
    if (e == 150) e = 0;
  }
}

//Daten von der App
String checkClient (void)
{
  if (!client.available()) delay(1);
  String request = client.readStringUntil('\r');
  request.remove(0, 5);
  request.remove(request.length() - 9, 9);
  return request;
}
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

Merzomann

Vielen Dank noiasca,

es funktioniert alles perfekt!

noiasca

gern geschehen.
In 8 Monaten bringen andere Leute Kinder auf die Welt ;-)
DE: Wie man Fragen postet:
1. was hat man (Sketch und Hardware)
2. was SOLL es machen
3. was macht es: IST (Fehlverhalten, Fehlermeldungen, Serial.Output ...)
4. Eine Frage stellen bzw. erklären was man erwartet

Go Up