Forum: Mikrocontroller und Digitale Elektronik WS2812 LED-Pixel immer weiss (Timing Problem)


von Kurt Immer (Gast)


Angehängte Dateien:

Lesenswert?

Hallo ich will eine Wortuhr bauen mit WS2812 LED Pixel als Anzeige.

Es gibt ja auf dieser Seite eine Zusammenfassung über die Ansteuerung:
https://www.mikrocontroller.net/articles/WS2812_Ansteuerung

Ich wollte einen Streifen aus ca 10 LEDs mal zum testen mit einem 
PIC16F887 ansteuern.

Es werden ja 24 Bits in einer Reihe gesendet für ein LED (G;R;B). Zum 
testen habe ich den Ausgang direkt im Code ohne Schleifen etc. 24-Mal 
ein und ausgeschaltet.

Für 0-Bits schalte ich den Ausgang ein und direkt wieder aus. Laut 
anderen Quellen spielt die Low-Dauer so gut wie keine Rolle.

Für ein 1 füge ich zwischen ein- und ausschalten 2 NOP() Aufrufe ein.

Beispiel:
Low-Bit:
Pin = 1;
Pin = 0;

High-Bit:
Pin = 1;
NOP();
NOP();
Pin = 0;

Ich habe eine Taktfrequenz von 8MHz (Interner Oszillator). Daher wäre 
das ja: 2x(1/(8MHz/4))=500ns. Alles über und um die 500ns High Time 
sollte eigentlich als 1 interpretiert werden.

Das LED schaltet sich dann auch ein, aber immer weiss. Auch wenn ich nur 
0-Bits zu senden versuche. Das heisst, jedes Bit wird eigentlich als 1 
erkannt, was heissen müsste, dass die Zeit zwischen ein- und ausschalten 
zu lang wäre.
Habe schon überlegt, ob meine Taktfrequenz zu niedrig ist.

Mit dem Multimeter messe ich am Ausgangspin um die 33kHz, wenn ich ihn 
im Programmcode ständig invertiere, was ja viel zu niedrig wäre. Weiss 
aber nicht, ob das Multimeter was taugt zum Frequenz messen.
Daher hier mal meine Konfiguration der Frequenz, vielleicht sieht jemand 
einen Fehler:

#include <xc.h>
#include <stdlib.h>
#include "../Include/ws2812.h"

#define _XTAL_FREQ 8000000

// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = OFF
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config LVP = OFF

// CONFIG2
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF

void main(void)
{
    ANSEL=ANSELH=0x00;
    OSCCON=0b01110001;

}

Im Anhang ist noch der entsprechende Datenblatt-Auszug für das OSCCON 
Register.

Hat jemand eine Ahnung, wo das Problem liegen könnte? Wäre sehr dankbar 
für irgendwelche hilfreichen Tipps.

MFG

von holger (Gast)


Lesenswert?

>Wäre sehr dankbar für irgendwelche hilfreichen Tipps.

Besorg dir einen Arduino.

von Thomas E. (thomase)


Lesenswert?

Kurt Immer schrieb:
> Beispiel:
> Low-Bit:
> Pin = 1;
> Pin = 0;
>
> High-Bit:
> Pin = 1;
> NOP();
> NOP();
> Pin = 0;

So wird das nichts. Siehst du ja selbst.

High:
Out = 1
Long Delay
Out = 0
Short Delay

Low:
Out = 1
Short Delay
Out = 0
Long Delay


Die Zeiten für ein ganzes Null- oder Einsbit müssen jeweils etwa gleich 
lang sein.

von Kurt Immer (Gast)


Lesenswert?

Habe das Programm jetzt so geändert wie du gesagt hast.

High Bit:
OUTPUT = 1;
NOP();
NOP();
OUTPUT = 0;
NOP();

Low Bit:
OUTPUT = 1;
NOP();
OUTPUT = 0;
NOP();
NOP();

Ein NOP müsste bei einer Frequenz von 8MHz 500ns entsprechen (habe es 
oben falsch berechnet.)

Somit liegt es laut Mikrocontroller.net überall in der Toleranz, sofern 
meine Taktfrequenz stimmt:

High Bit:
Th=1us
Tl=0.5us

Low Bit:
Th=0.5us
Tl=1us

Leider wird die LED nach wie vor nur weiss, was heissen müsste das 
mindestens der grösste Teil der Bits als 1 interpretiert wird.


Leider habe ich mit 8MHz Taktfrequenz keine feinere Auflösung als 500ns.

von Icke ®. (49636b65)


Lesenswert?

Forumsuche bemühen. Es gibt ausreichend funktionierenden Code für die 
WS2812, u.a.:

Beitrag "Lightweight WS2811/WS2812 Library"

von Harald (Gast)


Lesenswert?

Wenn du es selber machen möchtest, sprich ohne Lib - was ich durchaus 
nachvollziehen kann, ist ein Logic Analyzer an dieser Stelle eigentlich 
Pflicht. So ein Saleae Clone kostet <10€ und mit der Software Sigrok 
gibt es auch einen passenden WS2812 Dekoder.

von Thomas E. (thomase)


Lesenswert?

Kurt Immer schrieb:
> Leider habe ich mit 8MHz Taktfrequenz keine feinere Auflösung als 500ns.

Ich kenne deinen Controller nicht, aber das dürfte das Problem sein. Mit 
einem AVR ohne besondere Tricks in C schaffe ich die Ansteuerung mit 
min. 6MHz. Ein Instruction Cycle bei 6MHz ist beim AVR aber 167ns lang.

von Joachim B. (jar)


Lesenswert?

Kurt Immer schrieb:
> Ein NOP müsste bei einer Frequenz von 8MHz 500ns entsprechen

Thomas E. schrieb:
> Mit
> einem AVR ohne besondere Tricks in C schaffe ich die Ansteuerung mit
> min. 6MHz. Ein Instruction Cycle bei 6MHz ist beim AVR aber 167ns lang.

warum ist der PIC so lahm?

ich dachte die sind schneller, schliesslich wurden die ersten Propeller 
Clocks mit PIC gemacht.

http://pic-microcontroller.com/analog-digital-propeller-clock-using-pic16c84/

von Ralf G. (ralg)


Lesenswert?

Was ist eigentlich
1
NOP();
?
Ist das wie beim AVR
1
asm volatile ("nop");
?

Falls ja: Da werden tatsächlich vier Takte verbruzelt?

von Thomas E. (thomase)


Lesenswert?

Ralf G. schrieb:
> Falls ja: Da werden tatsächlich vier Takte verbruzelt?

Aus dem Datenblatt:

Operating speed:
-  DC – 20 MHz oscillator/clock input
-  DC – 200 ns instruction cycle

200ns bei 20MHz bedeuten 500ns bei 8MHz.

von Joachim B. (jar)


Lesenswert?

denn hängt doch einfach einen arduino mini 328p an den PIC und lässt den 
das Timing machen :)

: Bearbeitet durch User
von Kurt Immer (Gast)


Lesenswert?

Danke für die Antworten.

Das Ding ist, dass der Clock beim Pic durch 4 geteilt wird, das ist dann 
der Instruction Clock, der Grund ist mir auch nicht bekannt.

Und Ja, NOP kommt eigentlich vom Assembler, wurde aber beim XC8 Compiler 
als C Funktion implementiert glaube ich. Sollte also einen Taktzyklus 
verbrauchen.

Werde wohl mal einen Controller mit schnellerem Oszillator suchen und 
erneut versuchen.

Danke noch für den Tipp mit dem Logic Analyzer, werde ich mir anschauen.

von Ralf G. (ralg)


Lesenswert?

Kurt Immer schrieb:
> Werde wohl mal einen Controller mit schnellerem Oszillator suchen und
> erneut versuchen.

8MHz sollten eigentlich reichen.
Kannst du in einem Simulator den Code einfach mal Schritt für Schritt 
durchgehen und dabei die Takte zählen? Die Zuweisung an 'OUTPUT' dauert 
ja auch noch (ein paar Takte?).

von Joachim B. (jar)


Lesenswert?

Thomas E. schrieb:
> Aus dem Datenblatt:
>
> Operating speed:
> -  DC – 20 MHz oscillator/clock input
> -  DC – 200 ns instruction cycle
>
> 200ns bei 20MHz bedeuten 500ns bei 8MHz.

Ralf G. schrieb:
> 8MHz sollten eigentlich reichen.

wie kommst du darauf?
Thomas hatte doch schon ins DB geschaut

: Bearbeitet durch User
von Johnny B. (johnnyb)


Lesenswert?

Kurt Immer schrieb:
> Hat jemand eine Ahnung, wo das Problem liegen könnte?

Ohne Oszilloskop wirst Du da wohl das Problem nicht so schnell finden, 
da das Timing bei den WS2812 kritisch ist.

: Bearbeitet durch User
Beitrag #5219805 wurde vom Autor gelöscht.
von Kurt Immer (Gast)


Lesenswert?

Werde erstmal einen Arduino als Anzeigeprozessor verwenden, damit lief 
das ganze wie erwartet nach 10 Minuten :P. Habe mir noch den 
vorgeschlagenen Logic Analyser bestellt, scheint ein extrem geiles Ding 
zu sein.

Dann kann ich mal die Outputs der Arduino Library mit dem Output von 
meinem PIC vergleichen.

Sollte ein Weihnachtsgeschenk werden, daher habe ich keine Lust, mich 
ewigs mit diesem mühsamen asynchronen Protokoll zu beschäftigen.
Gruss

von Ralf G. (ralg)


Lesenswert?

Joachim B. schrieb:
> wie kommst du darauf?
> Thomas hatte doch schon ins DB geschaut
Für den Test könnte es reichen, wenn jeder Befehl nur diese 4 Takte 
braucht. Hmm, ja, okay, ist natürlich nicht realistisch. Es müssen ja 
normalerweise zwischendurch auch noch Daten 'nachgeladen' werden.

von Kurt Immer (Gast)


Lesenswert?

Habe noch einen PIC18F4685 als Test genommen, damit hätte ich 
theoretisch mit 32MHz 125ns Auflösung. Damit bekam ich aber das gleiche 
Resultat: weisse LED, auch wenn ich nur ein NOP() für das High Bit 
genommen habe.

Ich vermute, dass etwas mit meiner Taktfrequenz nicht stimmen muss, 
sonst müsste es doch gehen!

Obwohl ich meinte, dass das OSCCON Register und die Einstellung im 
Configuration Word eigentlich die einzigen massgebenden Einstellungen 
für die Taktfrequenz sind.

Ohne Logic Analyzer werde ich es wohl nicht herausfinden können, bis ich 
ihn erhalte.

Daher werde ich mal meinen PIC mit den restlichen Aufgaben beschäftigen 
und das Arduino Nano mit der FastLED Library die Anzeige steuern lassen.
Spart erst noch Zeit :).

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.