Forum: Mikrocontroller und Digitale Elektronik Arduino FastLED LIB vs. WS28xx LIB


von Joachim B. (jar)


Angehängte Dateien:

Lesenswert?

kleines Problem,

habe etwas Software geschrieben unter Verwendung der FastLED LIB für 
einen Arduino nano(V3) mit Nokia LCD 5110, einer eigenen I2C Tastatur 
und DS1307new LIB.

Als der m328p zu eng wurde habe ich einen Arduino clone auf Basis des 
m1284p mit mighty optiboot aufgebaut

http://adventuresinarduinoland.blogspot.de/2011/04/minimal-arduinoxbeepachube-sensor.html

1. Problem,
meine funktionierenden Timer Routinen vom m328p auf dem Timer1 schienen 
am m1284p nicht mehr zu arbeiten, also auf Timer3 ausgewichen.
Bei Timer1 Nutzung versagte die LCD5110 Ansteuerung.
Anlage LIB: LCD5110_Basic.ZIP

2. Problem,
auf dem m328p arbeitet die FastLED Lib perfekt, eine WS2812b wird in 
30µs bedient, entspricht dem Datenblatt mit 1,5µs pro Bit x 24, die LED 
fühlt sich angesprochen. Auf dem m1284p wird genau dieses zu 33µs für 24 
bit, die LED fühlt sich nicht mehr richtig angesprochen, es leuchtet 
voll weiss!
Mit der WS28xx LIB von Tim CPLD hier klappt das zwar wieder auf 30µs 
aber es wären zu viele Änderungen im Sourccode.

hat jemand ne Idee wie man nur den Bitbang Code in der FastLED LIB 
tauscht oder die beiden LIBs kompatibel im Aufruf oder der 
Initialisierung bekommt?

Anlage LIB: FastLED.ZIP, light_WS2812.ZIP

: Bearbeitet durch User
von Mark H. (mark_haber)


Lesenswert?

Wie hast du das Problem mit FastLED behoben?

von Joachim B. (jar)


Lesenswert?

Mark Haber schrieb:
> Wie hast du das Problem mit FastLED behoben?

mit


#ifdef F_CPU
#undef F_CPU
#define F_CPU 1440000

// statt 16MHz,
// sind die Impulse 10% zu lahm
// definiere die CPU 10% langsamer,
// dann passt es wieder,
// natürlich gibt es Seiteneffekte
// bei UART und anderswo,
// aber wo es stört kann man immer noch
// (F_CPU+1600000) setzen.

#endif

PS der Autor von fastLED wollte oder konnte nicht helfen Begründung 
m1284p ist kein Arduino und er hat auch keinen, ich sollte ihm einen 
schicken.

https://github.com/FastLED/FastLED/issues/121

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

update

von Mark H. (mark_haber)


Lesenswert?

Sehr interessante Loesung. Das fuegst du am Anfang des Arduino 
Programmes ein, nehme ich an?





Zum PS: Hast oder wirst du ihm einen schicken?

von Joachim B. (jar)


Lesenswert?

Mark Haber schrieb:
> Sehr interessante Loesung. Das fuegst du am Anfang des Arduino
> Programmes ein, nehme ich an?

ja

> Zum PS: Hast oder wirst du ihm einen schicken?

nö, wer bin ich denn, habe weder die Zeit noch deswegen welche 
aufzubauen und versandfertig zu machen und zur Post zu trappern, noch 
übermäßig Geld diese zu versenden. Das Teil kann man bei ebay bestellen 
wenn es den Autor interessiert. Es gibt Aufbauanleitungen das auf einem 
Breadboard mit einem DIL40 zu bauen, also die Ausrede das der Autor das 
nicht verifiziern kann ist dünne.

von Mark H. (mark_haber)


Lesenswert?

Joachim B. schrieb:
> Mark Haber schrieb:
>> Sehr interessante Loesung. Das fuegst du am Anfang des Arduino
>> Programmes ein, nehme ich an?
>
> ja

Wie genau meinst du das mit dem temporaeren Ruecksetzten mit 
"(F_CPU+1600000)"? Kannst du ein Minimalbeispiel bringen?


>> Zum PS: Hast oder wirst du ihm einen schicken?
>
> nö, wer bin ich denn, habe weder die Zeit noch deswegen welche
> aufzubauen und versandfertig zu machen und zur Post zu trappern, noch
> übermäßig Geld diese zu versenden. Das Teil kann man bei ebay bestellen
> wenn es den Autor interessiert. Es gibt Aufbauanleitungen das auf einem
> Breadboard mit einem DIL40 zu bauen, also die Ausrede das der Autor das
> nicht verifiziern kann ist dünne.

Nur die Ruhe und fuer mich sind keine Rechtfertigungen noetig. Das war 
eine einfache Frage.

von Joachim B. (jar)


Lesenswert?

Mark Haber schrieb:
> Wie genau meinst du das mit dem temporaeren Ruecksetzten mit
> "(F_CPU+1600000)"? Kannst du ein Minimalbeispiel bringen?

OK ich versuche es und habe noch einen anderen Weg im Kopf......


ich nutze winXP

öffne im Explorer das Fenster C:\Programme\Arduino\libraries

klicke auf SUCHEN
Dateien und Ordner
Dateiname *.*
Ein Wort oder Begriff innerhalb der Datei
F_CPU

suchen in "libraries"

weitere Optionen

Haken setzen bei:
Systemordner durchsuchen
versteckte Elemente durchsuchen
Unterordner durchsuchen
Groß-/Kleinschreibung beachten

SUCHEN

finde z.B. in
C:\Programme\Arduino\libraries\Wire\utility\twi.c
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;

und möchte da korrigieren weil es vielleicht nicht mit der 10% 
Abweichung klappt (ist bei mir noch kein Problem gewesen)

könnte da nun einfügen:
1
#if ((F_CPU == 14400000L) && defined(__AVR_ATmega1284P__)) 
2
TWBR = (( (F_CPU+1600000L) / TWI_FREQ) - 16) / 2;
3
#else
4
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
5
#endif

so könnte ich das an allen LIBs machen die ich nutzen will oder wo diese 
"Korrektur" stört.

aber mir ist eingefallen das es eleganter wäre statt #undef nur in der 
fastLED Lib zu ändern:
z.B. C:\Programme\Arduino\libraries\FastLED\delay.h
1
// hier andere CPU als AVR
2
#if !defined(__MK20DX128__)
3
template<int CYCLES> __attribute__((always_inline)) inline void delaycycles() { 
4
  _delaycycles_AVR<CYCLES / 3, CYCLES % 3>();  
5
}
6
#else
7
// dann dürfte der Teil nur die AVR betreffen:
8
// ..... viel unbrauchbares
9
10
// ab hier wirds interessant:
11
12
// Macro to convert from nano-seconds to clocks and clocks to nano-seconds
13
// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L)))
14
15
#if F_CPU < 96000000
16
#define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000
17
#define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L)
18
19
20
#else // F_CPU > 96000000
21
22
// und da hätten wir wieder:
23
#define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000
24
und ergänzen:
25
26
#if defined(__AVR_ATmega1284P__) && (F_CPU==16000000L)
27
#define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / ( (F_CPU-1600000L) / 2000000L)
28
#else
29
// sonst lassen wir das unangetastet
30
#define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 2000000L)
31
#endif // #if defined(__AVR_ATmega1284P__) && (F_CPU==16000000L)
32
33
#endif // der ELSE Teil von #if !defined(__MK20DX128__)

ist ein mühsamer Weg alle Abhängigkeiten aller CPU und F_CPU zu finden 
würde aber nur auf fastLED wirken

noch ungetestet.

: Bearbeitet durch User
von Mark H. (mark_haber)


Lesenswert?

Vielen Dank fuer die Information. Ich muss darueber ersteinmal 
Nachdenken.

von Joachim B. (jar)


Lesenswert?

Mark Haber schrieb:
> Vielen Dank fuer die Information. Ich muss darueber ersteinmal
> Nachdenken

sag mal wie du dich entschieden hast und ob es läuft

von Mark H. (mark_haber)


Lesenswert?

Naja, das ist nur eine Frickelloesung die nicht Zukunftsbestaendig ist. 
Vermutlich sende ich dem Autor einen Controller, das dauert aber noch 
einige Wochen.

von Joachim B. (jar)


Lesenswert?

Mark Haber schrieb:
> Vermutlich sende ich dem Autor einen Controller, das dauert aber noch
> einige Wochen.

welchen baust du denn?

SMD DIL mega1284p oder 644?
eigenes Layout?

: Bearbeitet durch User
von Mark H. (mark_haber)


Lesenswert?

Ein ATMega1284p im Dip-Gehaeuse, mit einem eigenen Board.

von Joachim B. (jar)


Lesenswert?

Joachim B. schrieb:
> PS der Autor von fastLED wollte oder konnte nicht helfen Begründung
> m1284p ist kein Arduino und er hat auch keinen, ich sollte ihm einen
> schicken.
>
> https://github.com/FastLED/FastLED/issues/121

hihi nun die Antwort:

Closing this thread as I am not going to be doing any more AVR platform 
work for more platforms beyond the 32u4, mega328p, and mega 2560.

na ja, meine Frickellösung läuft

schon witzig die Arduino "Gemeinde" kommt das von gemeinsam oder 
Gemeinheit?

von Joachim B. (jar)


Lesenswert?

Joachim B. schrieb:
> noch ungetestet.

gilt nicht mehr:

"endgültige"  Lösung gefunden,

welche nur AVR m1284p und fastled anspricht und alle anderen F_CPU 
unangefasst lässt:

in delay.h in der fastLED LIB aus:
1
// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L)))
2
#if F_CPU < 96000000
3
  #define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000
4
  #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L)
5
#else
6
#define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000

einfach folgendes gemacht:
1
// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L)))
2
#if F_CPU < 96000000
3
#if defined(__AVR_ATmega1284P__) && (F_CPU==16000000)
4
  #define NS(_NS) ( (_NS * ( (F_CPU-1600000) / 1000000L))) / 1000
5
  #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / ((F_CPU-1600000) / 1000000L)
6
#else
7
  #define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000
8
  #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L)
9
#endif
10
#else
11
#define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000

für AVR 1284p und 16 MHz

könnte auf 8MHz erweitert werden

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

so, noch mal nachgedacht und in die Tasten gegriffen:

egal ob 16MHz oder 8 MHz oder anderes, getestet für 16 MHz
in fastLED delay.h
1
// Macro to convert from nano-seconds to clocks and clocks to nano-seconds
2
// __AVR_ATmega1284P__
3
// #define NS(_NS) (_NS / (1000 / (F_CPU / 1000000L)))
4
#if F_CPU < 96000000
5
    #if defined(__AVR_ATmega1284P__)
6
        #define NS(_NS) ( (_NS * ( ((long)(F_CPU*9L/10L)) / 1000000L))) / 1000
7
        #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (((long)(F_CPU*9L/10L)) / 1000000L)
8
    #else
9
        #define NS(_NS) ( (_NS * (F_CPU / 1000000L))) / 1000
10
        #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 1000000L)
11
    #endif
12
#else
13
    #define NS(_NS) ( (_NS * (F_CPU / 2000000L))) / 1000
14
    #define CLKS_TO_MICROS(_CLKS) ((long)(_CLKS)) / (F_CPU / 2000000L)
15
#endif

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.