Forum: Mikrocontroller und Digitale Elektronik Auswahl zweier Arduino Sketches


von Schlonz K. (schlonz-klug) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hi

kurze erklärung: Ich habe einen Arduino an eine WS2812 LED strippe / 
Matrix angeschlossen und dieser soll das Ganze steuern. Ich möchte dabei 
mittels einem Schalter bei dem ich einen IO pin high oder low lege 
entweder das eine Sketch starten, bei dem der standart neopixel einfach 
random was generiert, oder das ganze mittels seriel über den pc 
ansteuern (Siehe angefügte Sketche)...

ich versuche bisher das zu kombinieren aber ich kriegs einfach nicht 
hin...

danke im Voraus für eure Hilfe

mfg
Leon

: Verschoben durch User
von Alex R. (itaxel)


Lesenswert?

Was hast du bisher gemacht und wie?
Poste mal dein versuch.

von Schlonz K. (schlonz-klug) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hier hab ich den Versuch was ich bisher unternommen habe... Ich hab 
zuerst versucht einfach den kompletten Code der beiden in eine if 
Schleife zu setzen die am Anfang den Pin abfragt... Dann hab ich mal 
versucht alle setups zusammenzulegen weil er da immer rum geheult 
hat.... Jetzt hab ich das Problem dass er sich wegen einer 
nichtdeklarierten Variable beschwert, bei dem WS2812 Skript, wobei ich 
den Code fast 1:1 übernommen habe...

mit freundlichen Grüßen
Leon

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Schlonz Klug schrieb:
> Hier hab ich den Versuch was ich bisher unternommen habe... Ich hab
> zuerst versucht einfach den kompletten Code der beiden in eine if
> Schleife

Es gibt keine if-'Schleifen'.

Das Wesen einer Schleife besteht darin, dass Code wiederholt wird. Darum 
heisst es Schleife, wie bei einem Tonband bei dem m an Anfang und Ende 
zusammenklebt und das daher immer wieder erneut abgespielt wird. Eben in 
einer Schleife.
In einem if wird nichts wiederholt. Ein if führt einen von 2 möglichen 
Codezweigen aus, abhängig von einer Bedingung.


> versucht alle setups zusammenzulegen weil er da immer rum geheult
> hat.... Jetzt hab ich das Problem

Dein Problemm fängt viel früher an. Dein eigentliches Problem ist, dass 
dir wer eingeredet hat, das man programmieren könnte, ohne es zuvor zu 
lernen.

> nichtdeklarierten Variable beschwert, bei dem WS2812 Skript, wobei ich
> den Code fast 1:1 übernommen habe...

übernehmen ohne zu verstehen geht praktisch immer schief.
Deinen Code, so ehrlich muss man sein, kann man so nur in die Tonne 
treten und neu machen. Was nicht heisst, dass man nicht zb den ganzen 
WS2812 Teil in seinen Grundzügen weiterverwenden kann. Aber den hast du 
ja nicht selbst geschrieben. Aber den Teil, den du geschrieben hast, der 
ist so weit von einem Programm entfernt, wie ich von einer erfolgreichen 
Herzoperation.

: Bearbeitet durch User
von Schlonz K. (schlonz-klug) Benutzerseite


Lesenswert?

Danke... Dass der Code nicht so funktioniert und dass ich au Grund von 
schlecht ausgebildeten Informatiklehrern nur Grundkenntnisse habe weiß 
ich auch... Dass mit der ifschleife war schlecht ausgedrückt aber deine 
Antwort hilft mir leider überhaupt nicht weiter.... Ich bräuchte eine 
Lösung bzw. Lösungsansatz an dem ich weitermachen kann und keinen der 
mir sagt was ich ohnehin Schon weiß...

Trotzdem Danke

von Karl H. (kbuchegg)


Lesenswert?

Schlonz Klug schrieb:
> Danke... Dass der Code nicht so funktioniert und dass ich au Grund von
> schlecht ausgebildeten Informatiklehrern

Sorry. Aber dein Machwerk hat auch nichts mit schlecht ausgebildeten 
Informatiklehrern zu tun.

> nur Grundkenntnisse

Und noch mal sorry. Aber das sind noch nicht mal Grundkennntnisse.

Ich sag das ja nicht um dich zu frustrieren. Aber ich halte hier auch 
nichts davon, die Dinge zu beschönigen. Das gibt dann erst recht nur 
Frust. Wenn in dem Code auch nur Ansätze erkennbar wären, dass es Sinn 
machen würde, dich da durchzusprechen. Aber in dem Machwerk fehlt es 
einfach überall an allem.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

PS:
Der schlimmere deiner beiden Ausgangssketsches ist der WS2812_Glediator.

Denn mit der Adafruit_NeoPixel Klasse hast du bereits eine Klasse, die 
mit WS2812 LED umgehen kann. D.h. der ganze Ansteuerungsteil aus dem 
Glediator ist komplett 'für die Wurst'. Den braucht kein Mensch, wenn 
man die Adafruit_NeoPixel Klasse zur Verfügung hat.

Anstatt aus diesem Code da zu versuchen etwas zusammenzukopieren, 
solltest du lieber lernen, mit der Adafruit_NeoPixel Library umzugehen 
und dann damit dein eigenes Programm schreiben. Die Klasse macht dir das 
sowieso recht einfach.

Ausserem sehe ich wirklich nicht, was du aus diesem Glediator Programm 
mitnehmen willst. Bytes von der UART auf die LEDs zu übertragen ist im 
Arduino System, mit einer fix fertigen Seriellen Klasse und eben dieser 
Adafruit_NeoPixel Klasse trivial. Das kriegen sogar Künstler hin, die in 
ihrem Leben noch nie einen Informatiklehrer gesehen haben.

: Bearbeitet durch User
von Schlonz K. (schlonz-klug) Benutzerseite


Lesenswert?

Ok und wie genau schleife ich die Glediator Daten dann mittels neopixel 
Library zu den LEDs durch?

Wenn mir da jemand nen Beispiel nennen könnte wär ich schon zufrieden...

von Karl H. (kbuchegg)


Lesenswert?

Schlonz Klug schrieb:
> Ok und wie genau schleife ich die Glediator Daten

Du hast nicht begriffen, dass es beim Glediator darum geht, Bytes von 
der Seriellen Schnittstelle auf die LEDs auszugeben. D.h. die Frage muss 
lauten: wie kann ich eigentlich von der Seriellen Schnittstelle Daten 
holen bzw. zur Weiterverarbeitung speichern?

> dann mittels neopixel
> Library zu den LEDs durch?

Du hast doch ein Beispiel, wie man die Klasse benutzt (den anderen 
Sketch). Versuch halt mal einfach zu verstehen, wie das funktioniert, 
bzw. wie man die Klasse verwendet. So schwer ist das nicht. Da gibt es 
Doku dazu und du hast auch einen Beispielsketch, der das alles in Aktion 
zeigt.

Und für die Serielle Schnittstelle und wie man die in der Arduino 
Umgebung anspricht, gibt es haufenweise Tutorien.

: Bearbeitet durch User
von Jürgen S. (jurs)


Lesenswert?

Schlonz Klug schrieb:
> ich versuche bisher das zu kombinieren aber ich kriegs einfach nicht
> hin...

Lernste was, dann kannste was,
kannste was, dann biste was,
biste was, dann haste was,
Neopixel-Farbenspass!

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Und für die Serielle Schnittstelle und wie man die in der Arduino
> Umgebung anspricht, gibt es haufenweise Tutorien.


OK. Den Teil nehm ich zurück.
Mit
1
 UBRR0H = 0;
2
  UBRR0L = 1; //Baud Rate 1 MBit (at F_CPU = 16MHz)
einer Baudrate von 1MBit wird das nichts mit der Arduino-Seriellen 
Klasse. Den UART Teil muss man tatsächlich vom Glediator übernehmen.
1
#define NUMBER_OF_PIXELS 60
2
3
unsigned char display_buffer[NUMBER_OF_PIXELS * 3];
4
static unsigned char *ptr;
5
static unsigned int pos = 0;
6
7
volatile unsigned char go = 0;
8
9
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMBER_OF_PIXELS, PIN, NEO_GRB + NEO_KHZ800);
10
11
void setup()
12
{
13
  strip.begin();
14
  strip.show(); // Initialize all pixels to 'off'
15
16
  // Initialize UART
17
  UCSR0A |= (1<<U2X0);                                
18
  UCSR0B |= (1<<RXEN0)  | (1<<TXEN0) | (1<<RXCIE0);   
19
  UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00)             ; 
20
  UBRR0H = 0;
21
  UBRR0L = 1; //Baud Rate 1 MBit (at F_CPU = 16MHz)
22
}
23
24
ISR(USART_RX_vect) 
25
{
26
  unsigned char b;
27
  b = UDR0;
28
  
29
  if (b == 1)  {pos=0; ptr=display_buffer; return;}    
30
  if (pos == (NUMBER_OF_PIXELS*3)) {} else {*ptr=b; ptr++; pos++;}  
31
  if (pos == ((NUMBER_OF_PIXELS*3)-1)) {go=1;}
32
}
33
34
void loop()
35
{
36
   ....
37
}

: Bearbeitet durch User
von Schlonz K. (schlonz-klug) Benutzerseite


Lesenswert?

Glediator unterstützt mehrere Geschwindigkeiten... Vielleicht ist es 
möglich hier ein wenig Geschwindigkeit heraus zu nehmen um dann dies zu 
kombinieren... Ich habe nur 25 LEDs angeschlossen da ließe sich auf 
jeden Fall Tempo raus nehme (denke ich)...

Probier das aus und melde mich nochmal

von Jürgen S. (jurs)


Lesenswert?

Schlonz Klug schrieb:
> Glediator unterstützt mehrere Geschwindigkeiten... Vielleicht ist es
> möglich hier ein wenig Geschwindigkeit heraus zu nehmen um dann dies zu
> kombinieren... Ich habe nur 25 LEDs angeschlossen da ließe sich auf
> jeden Fall Tempo raus nehme (denke ich)...
>
> Probier das aus und melde mich nochmal

Bis zu maximal 500000 Baud kannst Du mit "Serial" und der Arduino-Core 
Library nutzen.

Im Endeffekt brauchst Du doch in Deinem "strandtest" Sketch nur das 
"Serial" Objekt mit 500000 Baud (oder weniger) initialisieren und 
abhängig von der Schalterstellung dann entweder die dort vorhandenen 
Funktionen laufen lassen oder in einer Schleife so lange drei Bytes 
empfangen und als Farbe per strip.setPixelColor() an Deinen LED-Streifen 
zuweisen, bis Daten für alle LEDs empfangen wurden, und diese dann 
anzeigen.

Sogar den manuellen Umschalter kannst Du Dir dabei eigentlich sparen, 
wenn Du auf der Serial-Schnittstelle mit Timeout empfängst, etwa nach 
der Logik:
1. Wenn innerhalb 2x der Zeit, in der eigentlich Daten ankommen müßten, 
keine seriellen Daten ankommen, schalte auf das automatische 
Testprogramm.
2. Wenn nach Ablauf des Testprogramms serielle Daten vorhanden sind: 
Schalte auf das Glediator-Widergabeprogramm

Dann brauchst Du im Endeffekt nur das Kabel abstöpseln oder das 
Glediatorprogramm auf dem PC beenden, und der Streifen schaltet 
automatisch auf sein eigenes Programm um. Und wenn wieder Daten kommen, 
schaltet der Arduino wieder automatisch auf Glediator-Wiedergabe. Also 
automatische Umschaltung statt manuelle Umschaltung.

von Schlonz K. (schlonz-klug) Benutzerseite


Lesenswert?

Hallo nochmal,

hab jetzt mal versucht ne alternative zu schreiben. Allerdings habe ich 
ein paar probleme: Manchmal ließt das programm mehr ein als es sollte, 
hab zuerst versucht mit Serial.parseInt() statt mit Serial.read() zu 
arbeiten, habe aber nichts mehr raus bekommen...

das zweite problem das ich habe ist, dass die neopixel library 
zahlenwerte haben will und ich es nicht hinbekommen meine hex werte 
darin um zu wandeln.

Hab auch mit den Datenklassen rumexpiremtiert, bisher noch kein Erfolg
1
#include <Adafruit_NeoPixel.h>
2
Adafruit_NeoPixel strip = Adafruit_NeoPixel(25, 6, NEO_GRB + NEO_KHZ800);
3
const unsigned char numLED = 6;
4
unsigned char x = 0;
5
int red = 0;
6
int green = 0;
7
unsigned char blue = 0;
8
9
10
void setup(){
11
  Serial.begin(115200);
12
  strip.begin();
13
  Serial.setTimeout(100);
14
}
15
16
17
void loop(){
18
  if (Serial.find("") == true){
19
    Serial.print("OK");
20
    while(x==0 || x < numLED){
21
      x++;
22
      red = Serial.read();
23
      green = Serial.read();
24
      blue = Serial.read();
25
      strip.setPixelColor(x, red, green, blue);
26
      Serial.print(red, HEX);
27
      Serial.print(",");
28
      Serial.print(green,HEX);
29
      Serial.print(",");
30
      Serial.print(blue,HEX);
31
      Serial.print("\n");
32
    }
33
    x = 0; 
34
    
35
    
36
    
37
  }
38
  else {
39
    Serial.print("not\n");
40
    delay(100);
41
  }
42
  strip.show();
43
}

Sie serial.print habe ich rein gemacht um zu sehen was das programm 
bekommt, fliegen nachher natürlich raus...

danke im Voraus
Leon

: Bearbeitet durch User
von Jürgen S. (jurs)


Lesenswert?

Schlonz Klug schrieb:
> hab jetzt mal versucht ne alternative zu schreiben. Allerdings habe ich
> ein paar probleme

OK, Du scheinst also damit anzufangen, die Glediator-Empfangsroutine auf 
die Neopixel-Library umzuschreiben. Das erscheint mir auch sinnvoll.

Aber kannst Du vielleicht erstmal erklären, was Du da eigentlich hast. 
In Deinem Code sehe ich diese beiden Zeilen, die so keinen Sinn ergeben:
1
  // Deklariere einen LED-Streifen mit 25 LEDs an Pin-6
2
  Adafruit_NeoPixel strip = Adafruit_NeoPixel(25, 6, NEO_GRB + NEO_KHZ800);
3
4
  // Deklariere eine Anzahl von 6 LEDs
5
  const unsigned char numLED = 6;

Was denn nun: 25 LEDs an Pin-6? Oder 6 LEDs an welchem Pin?

Außerdem sieht mir Dein umgeschriebener Code so aus, als wenn Du die 
Synchronisierung nicht verstanden hast.

Ggf. kann ich ja mal versuchen, den Code umzuschreiben.

Aber am Ende funktionieren kann das natürlich nur, wenn Du genau weißt, 
wie viele LEDs an welchem Pin angeschlossen sind, und Du im selben Code 
nicht an einer Stelle 25 LEDs deklarierst und dann an anderer Stelle 
Daten für 6 LEDs einlesen möchtest, und das auch noch ohne jede 
Synchronisation zwischen Senden und Empfangen.

von Schlonz K. (schlonz-klug) Benutzerseite


Lesenswert?

Ok Danke das ist mir aus versehen nicht aufgefallen... Zum ende hin 
sollen 25 LEDs angesteuert werden, habe aber für den test 6 
verwendet.... habe jetzt einfach die numLED variable auch in die 
NeoPixel definition mit rein genommen...

Geldiator sendet die Daten in einem Strucktur. Jerder neue Datenstrang 
fängt mit dem Hexwert 01 an, dieser wird durch Seriell.find detektiert 
(ich hab einfach das zeichen reinkopiert aus meinem Hexeditor, man kann 
es nicht sehen aber es ist da und dieser part funktioniert auch 
zuverlässig) nach diesem 01 folgt ein wert zwischen 00 und FF, der die 
Intensität der ersten Farbe der ersten LED angibt, diese speichere ich 
dann in red ab.

Dankach folgt 2. Farbe der 1. LED und 3. Farbe der 1. LED.... diese 
werden dann der ersten led mittels adresse, die durch diel while 
schleife hochgezählt wird dieser zugeschreiben. Die rutine sollte dann 
die 1. Fareb der 2. LEd detektieren und dann so weiter, solange bis alle 
leds fertig sind, dann sollte alles ausgegeben werden mittles 
strip.show()

Wenn innerhalb 100 Millisekunden kein HEXwer 01 detektiert wird 
(doppelte zeit wie es sein sollte) dann wird else ausgeführt, da kommt 
dann irgendeine animation rein wenn das erstmal mit glediator 
funktioniert

von Jürgen S. (jurs)


Lesenswert?

OK, hier mal mein Versuch, die Glediator-Empfangsroutine auf die 
Adafruit-Neopixel-Library umzuschreiben.
1
#include <Adafruit_NeoPixel.h>
2
#define NUMLEDS 25
3
#define LEDPIN 6
4
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMLEDS, LEDPIN, NEO_GRB + NEO_KHZ800);
5
6
void setup()
7
{
8
  Serial.begin(115200);
9
  strip.begin();
10
}
11
12
13
byte rgb[3];       // RGB-Werte 
14
int activeLED=0;   // Die LED, deren Daten empfangen werden
15
int activeColor=0; // Der nächste zu empfangende Farbwert (0=rot, 1=grün, 2=blau)
16
17
void loop()
18
{
19
  if (!Serial.available()) return;
20
  while (Serial.available())
21
  {
22
    byte b=Serial.read();
23
    if (b==1) // Reset/Synchronisation
24
    {
25
      activeLED=0;
26
      activeColor=0;
27
      return;
28
    }
29
    rgb[activeColor]=b;
30
    activeColor++;
31
    if (activeColor>=3)
32
    {
33
      strip.setPixelColor(activeLED, rgb[0], rgb[1], rgb[2]);
34
      activeLED++;
35
      activeColor=0;
36
    }
37
    if (activeLED>=NUMLEDS)
38
    {
39
      activeLED=0;
40
      activeColor=0;
41
      strip.show();
42
    }
43
  }
44
}

Zeigen Deine LEDs damit was an (Baudrate 115200 oder wie Du es im Sketch 
und in der Glediator-Software einstellst)?

von Schlonz K. (schlonz-klug) Benutzerseite


Lesenswert?

Hallo, hab deinen Code ausprobiert und er funktioniert... VIELEN DANK

das einzige problem das ich jetzt noch habe ist, dass ich irgendwie 
feststellen muss ob überhaupt ein serielles signal anliegt, denn wenn 
nicht würde ich gerne einen alternativcode ausführen. Habe schon 
probiert das in die if(Serial.available rein zu packen, aber das spinnt 
dann rum wenn Daten ankommen, da da so ca 30ms Pause zwischen den Daten 
Strängen sind.

von Jürgen S. (jurs)


Lesenswert?

Schlonz Klug schrieb:
> das einzige problem das ich jetzt noch habe ist, dass ich irgendwie
> feststellen muss ob überhaupt ein serielles signal anliegt, denn wenn
> nicht würde ich gerne einen alternativcode ausführen. Habe schon
> probiert das in die if(Serial.available rein zu packen, aber das spinnt
> dann rum wenn Daten ankommen, da da so ca 30ms Pause zwischen den Daten
> Strängen sind.

Im Prinzip mußt Du Dir ein Timeout legen, das größer ist als die 
normalen Sendepausen zwischen den Datensendungen. Und dann nach einer 
Timeout-Logik entweder die eine oder die andere Effektschleife aufrufen 
oder das Timeout setzen. Etwa nach der Logik

- Serial.available() ==> Glediator-Loop starten und Timeout löschen
- wenn ein Timeout vorliegt ==> Default-Loop starten
- wenn beides nicht zutrifft ==> prüfen, ob das Timeout erreicht ist

Mit den einfach reinkopierten Testroutinen komme ich dann auf folgendes 
Programm:
1
#include <Adafruit_NeoPixel.h>
2
#define NUMLEDS 25
3
#define LEDPIN 6
4
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMLEDS, LEDPIN, NEO_GRB + NEO_KHZ800);
5
6
void setup()
7
{
8
  Serial.begin(115200);
9
  strip.begin();
10
}
11
12
13
/************************************************************
14
Glediator-Routinen
15
************************************************************/
16
byte rgb[3];       // RGB-Werte 
17
int activeLED=0;   // Die LED, deren Daten empfangen werden
18
int activeColor=0; // Der nächste zu empfangende Farbwert (0=rot, 1=grün, 2=blau)
19
20
void glediatorLoop()
21
{
22
  while (Serial.available())
23
  {
24
    byte b=Serial.read();
25
    if (b==1) // Reset/Synchronisation
26
    {
27
      activeLED=0;
28
      activeColor=0;
29
      return;
30
    }
31
    rgb[activeColor]=b;
32
    activeColor++;
33
    if (activeColor>=3)
34
    {
35
      strip.setPixelColor(activeLED, rgb[0], rgb[1], rgb[2]);
36
      activeLED++;
37
      activeColor=0;
38
    }
39
    if (activeLED>=NUMLEDS)
40
    {
41
      activeLED=0;
42
      activeColor=0;
43
      strip.show();
44
    }
45
  }
46
}
47
48
/************************************************************
49
Default-Routinen
50
************************************************************/
51
void defaultLoop()
52
{
53
  // Some example procedures showing how to display to the pixels:
54
  colorWipe(strip.Color(255, 0, 0), 50); // Red
55
  colorWipe(strip.Color(0, 255, 0), 50); // Green
56
  colorWipe(strip.Color(0, 0, 255), 50); // Blue
57
  // Send a theater pixel chase in...
58
  theaterChase(strip.Color(127, 127, 127), 50); // White
59
  theaterChase(strip.Color(127,   0,   0), 50); // Red
60
  theaterChase(strip.Color(  0,   0, 127), 50); // Blue
61
62
  rainbow(20);
63
  rainbowCycle(20);
64
  theaterChaseRainbow(50);  
65
}
66
67
/************************************************************
68
Unterfunktionen für verschiedene Effekte der defaultLoop
69
************************************************************/
70
// Fill the dots one after the other with a color
71
void colorWipe(uint32_t c, uint8_t wait) {
72
  for(uint16_t i=0; i<strip.numPixels(); i++) {
73
      strip.setPixelColor(i, c);
74
      strip.show();
75
      delay(wait);
76
  }
77
}
78
79
void rainbow(uint8_t wait) {
80
  uint16_t i, j;
81
82
  for(j=0; j<256; j++) {
83
    for(i=0; i<strip.numPixels(); i++) {
84
      strip.setPixelColor(i, Wheel((i+j) & 255));
85
    }
86
    strip.show();
87
    delay(wait);
88
  }
89
}
90
91
// Slightly different, this makes the rainbow equally distributed throughout
92
void rainbowCycle(uint8_t wait) {
93
  uint16_t i, j;
94
95
  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
96
    for(i=0; i< strip.numPixels(); i++) {
97
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
98
    }
99
    strip.show();
100
    delay(wait);
101
  }
102
}
103
104
//Theatre-style crawling lights.
105
void theaterChase(uint32_t c, uint8_t wait) {
106
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
107
    for (int q=0; q < 3; q++) {
108
      for (int i=0; i < strip.numPixels(); i=i+3) {
109
        strip.setPixelColor(i+q, c);    //turn every third pixel on
110
      }
111
      strip.show();
112
     
113
      delay(wait);
114
     
115
      for (int i=0; i < strip.numPixels(); i=i+3) {
116
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
117
      }
118
    }
119
  }
120
}
121
122
//Theatre-style crawling lights with rainbow effect
123
void theaterChaseRainbow(uint8_t wait) {
124
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
125
    for (int q=0; q < 3; q++) {
126
        for (int i=0; i < strip.numPixels(); i=i+3) {
127
          strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
128
        }
129
        strip.show();
130
       
131
        delay(wait);
132
       
133
        for (int i=0; i < strip.numPixels(); i=i+3) {
134
          strip.setPixelColor(i+q, 0);        //turn every third pixel off
135
        }
136
    }
137
  }
138
}
139
140
// Input a value 0 to 255 to get a color value.
141
// The colours are a transition r - g - b - back to r.
142
uint32_t Wheel(byte WheelPos) {
143
  WheelPos = 255 - WheelPos;
144
  if(WheelPos < 85) {
145
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
146
  } else if(WheelPos < 170) {
147
    WheelPos -= 85;
148
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
149
  } else {
150
   WheelPos -= 170;
151
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
152
  }
153
}
154
155
156
157
/************************************************************
158
Arduino loop mit Serial Timeout
159
************************************************************/
160
161
#define TIMEOUT 1000  // in Millisekunden
162
boolean timeout;
163
unsigned long lastSerial;
164
165
void loop()
166
{
167
  if (Serial.available())
168
  {
169
    glediatorLoop();
170
    timeout=false;
171
    lastSerial=millis();
172
  }
173
  else if (timeout)
174
  {
175
    defaultLoop();
176
  }
177
  else if (millis()-lastSerial>=TIMEOUT)
178
  {
179
    timeout=true;
180
  }
181
}

Nachteilig dran ist nur, wie die Effekte realisiert sind: Mit delay.

Das führt natürlich dazu, dass nach einem Timeout die recht lange 
laufende defaultLoop() immer erst zuende abgearbeitet werden muss, bevor 
wieder auf anliegende Serial-Daten reagiert und auf die glediatorLoop() 
umgeschaltet werden kann.

Wenn der Arduino nur ein Lichtprogramm steuern soll und das lahme 
reagieren auf anliegende Serial-Daten kein Problem ist, kann man seine 
Effekte natürlich auch mit delay() Aufrufen programmieren und den 
Programmablauf ständig blockieren.

Falls das Programm zwischendurch aber noch auf andere Dinge blitzschnell 
reagieren soll, z.B. angeschlossene Schalter, müssen die Effekte 
natürlich frei von jeglichem delay ganz anders programmiert werden.

: Bearbeitet durch User
von Schlonz K. (schlonz-klug) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hallo,

wollte mich nochmal kurz melden, hab jetzt das Projekt fertig, hab einen 
leicht abgewandelten Code verwendet, so kann ich jetzt über ein 
Funkmodul Glediatordaten einspeißen, wenn diese nicht vorhanden sind 
kann man mittels drei Potis die Farbe so einstellen:
1
#include <Adafruit_NeoPixel.h>
2
#define NUMLEDS 25
3
#define LEDPIN 6
4
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMLEDS, LEDPIN, NEO_GRB + NEO_KHZ800);
5
6
void setup()
7
{
8
  Serial.begin(115200);
9
  strip.begin();
10
  pinMode(A0, INPUT);
11
  pinMode(A1, INPUT);
12
  pinMode(A2, INPUT);
13
}
14
15
16
/************************************************************
17
Glediator-Routinen
18
************************************************************/
19
byte rgb[3];
20
int activeLED=0;
21
int activeColor=0;
22
23
void glediatorLoop()
24
{
25
  while (Serial.available())
26
  {
27
    byte b=Serial.read();
28
    if (b==1)
29
    {
30
      activeLED=0;
31
      activeColor=0;
32
      return;
33
    }
34
    rgb[activeColor]=b;
35
    activeColor++;
36
    if (activeColor>=3)
37
    {
38
      strip.setPixelColor(activeLED, rgb[0], rgb[1], rgb[2]);
39
      activeLED++;
40
      activeColor=0;
41
    }
42
    if (activeLED>=NUMLEDS)
43
    {
44
      activeLED=0;
45
      activeColor=0;
46
      strip.show();
47
    }
48
  }
49
}
50
51
/************************************************************
52
Default-Routinen
53
************************************************************/
54
void defaultLoop(){
55
  int rot = analogRead(A0);
56
  rot = map(rot, 0, 1023, 255, 0);
57
  int green = analogRead(A1);
58
  green = map(green, 0, 1023, 255, 0);
59
  int blau = analogRead(A2);
60
  blau = map(blau, 0, 1023, 255, 0);
61
  
62
  activeLED=0;
63
  
64
  while(activeLED < NUMLEDS){
65
    strip.setPixelColor(activeLED, rot, green, blau);
66
    activeLED++;
67
  }
68
  
69
  strip.show();
70
  activeLED = 0;
71
  delay(100);
72
    
73
}
74
75
76
77
/************************************************************
78
Arduino loop mit Serial Timeout
79
************************************************************/
80
81
#define TIMEOUT 1000
82
boolean timeout;
83
unsigned long lastSerial;
84
85
void loop()
86
{
87
  if (Serial.available())
88
  {
89
    glediatorLoop();
90
    timeout=false;
91
    lastSerial=millis();
92
  }
93
  else if (timeout)
94
  {
95
    defaultLoop();
96
  }
97
  else if (millis()-lastSerial>=TIMEOUT)
98
  {
99
    timeout=true;
100
  }
101
}

zum Schluss noch ein Danke, sonst hätte ich glaub ich ein wenig viel 
länger gebraucht...

mit freundlichen Grüßen
Leon

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.