Forum: Mikrocontroller und Digitale Elektronik Codefrage für WS2801 RGB-Lichterkette


von Blinker (Gast)


Lesenswert?

Hallo zusammen,

da nächste Woche bei uns in der Stadt ein Lichterfest ist habe ich vor 
eine Lichterkette mit veränderbaren Farben zu bauen.
Dazu habe ich eine Lichterkette mit 50 RGB LEDS und WS2801 Controller.
Zum testen habe ich ein CT-COM-auf-LAN Board also ein ATmega8535 mit 
einem 14.7456 Mhz Quarz. Der Code soll erstmal alle LEDs einschalten und 
dann wieder aus in einer schleife um zu sehen ob er funktioniert - so 
der Plan. Das macht er auch irgendwie Blinken alle Leds im Sekunden Takt 
nur alle mit einer anderen Farbe und die Farbe wechselt auch mit jedem 
Blinken.
Woran kann das liegen, an dem _delay_ms?

Ich habe folgenden Code verwendet:
(Quelle:Beispielcode aus der Codesammlung)
1
#define F_CPU 14745600UL /* Quarz mit 14.7456 Mhz */
2
#include <avr/io.h>
3
#include <util/delay.h>
4
#define  CLOCK_DDR  DDRA
5
#define  CLOCK_PORT  PORTA
6
#define  CLOCK_PIN  PA3
7
8
#define  DATA_DDR  DDRA
9
#define  DATA_PORT  PORTA
10
#define  DATA_PIN  PA2
11
void ws2801_init()
12
{
13
  // Init Clock Pin
14
  CLOCK_DDR   |= (1<<CLOCK_PIN);
15
  CLOCK_PORT   &= ~(1<<CLOCK_PIN);
16
  
17
  // Init Data Pin
18
  DATA_DDR   |= (1<<DATA_PIN);
19
  DATA_PORT   &= ~(1<<DATA_PIN);
20
}
21
void long_delay(uint16_t ms) {
22
  for(; ms>0; ms--) _delay_ms(1);
23
}
24
void ws2801_sendRGB(uint8_t* rgb, uint16_t num)
25
{
26
  // Start transmission
27
  for(uint8_t i=0; i<(num*3); i++) // 3 Byte per LED
28
  {
29
    for(uint8_t bit=0x80; bit; bit >>= 1)
30
    {
31
      if(rgb[i] & bit)
32
      DATA_PORT |= (1<<DATA_PIN);
33
      else
34
      DATA_PORT &= ~(1<<DATA_PIN);
35
36
      CLOCK_PORT |= (1<<CLOCK_PIN);
37
      CLOCK_PORT &= ~(1<<CLOCK_PIN);
38
    }
39
  }
40
  
41
  // Send 1ms both pins low
42
  DATA_PORT   &= ~(1<<DATA_PIN);
43
  CLOCK_PORT   &= ~(1<<CLOCK_PIN);
44
  _delay_ms(1);
45
}
46
47
int main()
48
{
49
  ws2801_init();
50
  while(1){
51
  uint8_t color[3];
52
  color[0] = 255;
53
  color[1] = 255;
54
  color[2] = 255;
55
56
  ws2801_sendRGB(color, 50);
57
  long_delay(1000);
58
  uint8_t color2[3];
59
  color2[0] = 0;
60
  color2[1] = 0;
61
  color2[2] = 0;
62
63
  ws2801_sendRGB(color2, 50);
64
  long_delay(1000);
65
66
}
67
68
  return 0;
69
}

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Blinker schrieb:
>       CLOCK_PORT |= (1<<CLOCK_PIN);
>       CLOCK_PORT &= ~(1<<CLOCK_PIN);
>     }
>   }
>
>   // Send 1ms both pins low
>   DATA_PORT   &= ~(1<<DATA_PIN);
>   CLOCK_PORT   &= ~(1<<CLOCK_PIN);
>   _delay_ms(1);

 Vielleicht mal zur Sicherheit andersherum probieren ?
        CLOCK_PORT &= ~(1<<CLOCK_PIN);
    //****** kurzes Delay hier (paar CPU-Takte) ?
        CLOCK_PORT |= (1<<CLOCK_PIN);
    //****** und hier ?
 // Und dann beide auf Null
        DATA_PORT   &= ~(1<<DATA_PIN);
        CLOCK_PORT   &= ~(1<<CLOCK_PIN);
 // Nächster durchlauf
     }
 // Nächstes Byte
   }
 // Send 1ms both pins low
  DATA_PORT   &= ~(1<<DATA_PIN);
   CLOCK_PORT   &= ~(1<<CLOCK_PIN);
   _delay_ms(1);

 Auch wenn es unnötig erscheint, man sollte beim Fehler lieber
 etwas zweimal machen als einmal zu wenig. Erst mal zum Laufen
 bringen, dann kann die Geschwindigkeit erhöht werden.

von Blinker (Gast)


Lesenswert?

Hallo  Marc,

Das wars!

Vielen Dank für den Tipp.
Das Beispiel war von jemanden der nur eine LED angesteuert hat da ist es 
egal.

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.