Leistungsstarke Arduino

Hallo zusammen,

Habe da mal eine kleine Frage,
Ich habe mir jetzt mit Hilfe eines RPi3b+ und einem Arduino Uno (davor war ein Mini vorhanden) eine LED Hintergrund Beleuchtung mit ws2812b zusammengebaut jetzt mein Problem:

Sobald ich hyperion und den arduino die 338 steuern lasse hackt es quasi. Meine Frage:

Liegt es daran das der arduino zu wenig rechen Leistung hat und wenn ja welchen soll ich dann nehmen damit es schön flüssig wird?

Den am RPi oder hyperion kanns ja nicht liegen ( habe schon andere Schaltungen mit etwas mehr leds dafür aber mit ws2801 aufgebaut die dann direkt vom rpi gesteuert werden)

Würde den arduino dann austauschen wenn ihr da was etwas besseres habt.

Schonmal Danke in voraus,

LG canx35

Wenn Du mehr Rechenleistung willst, nimm einen Teensy oder Esp8266/Esp32.

Meistens liegt ds Problem aber in der schlechten Programmierung.
Das können wir mangesls Code aber nicht bestimmen.

Gruß Tommy

Vermutlich liegt es am Speicher (Ram) des Uno.
Nimm einen Mega, dann geht es.

wie viele LEDs?
Wo ist der Sketch?
Was hakt?
Was ist knapp RAM, Flash, Clock???
Glaskugel kaputt?

Wieviele WS2812B willst Du ansteuern?

Hat das Netzteil genug Power?

Grüße Uwe

Hallo zusammen,

Erstmal ein dickes danke schön.

Also hier nochmal Paar Einzelheiten:

  1. 338 WS2812B Leds sollen gesteuert werden. (vorher mit 110 ausprobiert es war sehr flüssig dann umgestellt auf 338 und dann war es nicht mehr so flüssig).
  2. Was knapp ist kann ich nicht sagen denn der Arduino Uno hängt am RPI 3B+ ohne Netzteil, also zieht er nur die Leistung vom USB Port.
  3. Hier mal das Sketch:
#include "FastLED.h"

#define ANALOG_MODE_AVERAGE  0
#define ANALOG_MODE_LAST_LED 1

/**************************************
   S E T U P
   set following values to your needs
**************************************/

#define INITIAL_LED_TEST_ENABLED true
#define INITIAL_LED_TEST_BRIGHTNESS 255  // 0..255
#define INITIAL_LED_TEST_TIME_MS 500  // 10..

// Number of leds in your strip. set to "1" and ANALOG_OUTPUT_ENABLED to "true" to activate analog only
// As of 26/1/2017:
// 582 leaves ZERO bytes free and this
// 410 is ok
// tested with 500 leds and is fine (despite the warning)
#define MAX_LEDS 338

// type of your led controller, possible values, see below
#define LED_TYPE WS2812B

// 3 wire (pwm): NEOPIXEL BTM1829 TM1812 TM1809 TM1804 TM1803 UCS1903 UCS1903B UCS1904 UCS2903 WS2812 WS2852
//               S2812B SK6812 SK6822 APA106 PL9823 WS2811 WS2813 APA104 WS2811_40 GW6205 GW6205_40 LPD1886 LPD1886_8BIT
// 4 wire (spi): LPD8806 WS2801 WS2803 SM16716 P9813 APA102 SK9822 DOTSTAR

// For 3 wire led stripes line Neopixel/Ws2812, which have a data line, ground, and power, you just need to define DATA_PIN.
// For led chipsets that are SPI based (four wires - data, clock, ground, and power), both defines DATA_PIN and CLOCK_PIN are needed

// DATA_PIN, or DATA_PIN, CLOCK_PIN
#define LED_PINS 13      // 3 wire leds
//#define LED_PINS 6, 13  // 4 wire leds

#define COLOR_ORDER GRB  // colororder of the stripe, set RGB in hyperion

#define OFF_TIMEOUT 15000    // ms to switch off after no data was received, set 0 to deactivate

// analog rgb uni color led stripe - using of hyperion smoothing is recommended
// ATTENTION  this pin config is default for atmega328 based arduinos, others might work to
//            if you have flickering analog leds this might be caused by unsynced pwm signals
//            try other pins is more or less the only thing that helps
#define ANALOG_OUTPUT_ENABLED false
#define ANALOG_MODE           ANALOG_MODE_LAST_LED  // use ANALOG_MODE_AVERAGE or ANALOG_MODE_LAST_LED
#define ANALOG_GROUND_PIN     8                     // additional ground pin to make wiring a bit easier
#define ANALOG_RED_PIN        9
#define ANALOG_GREEN_PIN      10
#define ANALOG_BLUE_PIN       11

// overall color adjustments
#define ANALOG_BRIGHTNESS_RED   255              // maximum brightness for analog 0-255
#define ANALOG_BRIGHTNESS_GREEN 255              // maximum brightness for analog 0-255
#define ANALOG_BRIGHTNESS_BLUE  255              // maximum brightness for analog 0-255

#define BRIGHTNESS 255                      // maximum brightness 0-255
#define DITHER_MODE BINARY_DITHER           // BINARY_DITHER or DISABLE_DITHER
#define COLOR_TEMPERATURE CRGB(255,255,255) // RGB value describing the color temperature
#define COLOR_CORRECTION  TypicalLEDStrip   // predefined fastled color correction
//#define COLOR_CORRECTION  CRGB(255,255,255) // or RGB value describing the color correction

// Baudrate, higher rate allows faster refresh rate and more LEDs
//#define serialRate 460800      // use 115200 for ftdi based boards
#define serialRate 115200      // use 115200 for ftdi based boards
//#define serialRate 500000         // use 115200 for ftdi based boards


/**************************************
   A D A L I G H T   C O D E
   no user changes needed
**************************************/

// Adalight sends a "Magic Word" (defined in /etc/boblight.conf) before sending the pixel data
uint8_t prefix[] = {'A', 'd', 'a'}, hi, lo, chk, i;

unsigned long endTime;

// Define the array of leds
CRGB leds[MAX_LEDS];

// set rgb to analog led stripe
void showAnalogRGB(const CRGB& led) {
  if (ANALOG_OUTPUT_ENABLED) {
    byte r = map(led.r, 0,255,0,ANALOG_BRIGHTNESS_RED);
    byte g = map(led.g, 0,255,0,ANALOG_BRIGHTNESS_GREEN);
    byte b = map(led.b, 0,255,0,ANALOG_BRIGHTNESS_BLUE);
    analogWrite(ANALOG_RED_PIN  , r);
    analogWrite(ANALOG_GREEN_PIN, g);
    analogWrite(ANALOG_BLUE_PIN , b);
  }
}

// set color to all leds
void showColor(const CRGB& led) {
  #if MAX_LEDS > 1 || ANALOG_OUTPUT_ENABLED == false
  LEDS.showColor(led);
  #endif
  showAnalogRGB(led);
}

// switch of digital and analog leds
void switchOff() {
  #if MAX_LEDS > 1 || ANALOG_OUTPUT_ENABLED == false
  memset(leds, 0, MAX_LEDS * sizeof(struct CRGB));
  FastLED.show();
  #endif
  showAnalogRGB(leds[0]);
}

// function to check if serial data is available
// if timeout occured leds switch of, if configured
bool checkIncommingData() {
  boolean dataAvailable = true;
  while (!Serial.available()) {
    if ( OFF_TIMEOUT > 0 && endTime < millis()) {
      switchOff();
      dataAvailable = false;
      endTime = millis() + OFF_TIMEOUT;
    }
  }

  return dataAvailable;
}

// main function that setups and runs the code
void setup() {
  Serial.begin(serialRate);

  // analog output
  if (ANALOG_OUTPUT_ENABLED) {
    // additional ground pin to make wiring a bit easier
    pinMode(ANALOG_GROUND_PIN, OUTPUT);
    digitalWrite(ANALOG_GROUND_PIN, LOW);
    pinMode(ANALOG_BLUE_PIN , OUTPUT);
    pinMode(ANALOG_RED_PIN  , OUTPUT);
    pinMode(ANALOG_GREEN_PIN, OUTPUT);
  }

  int ledCount = MAX_LEDS;
  if (ANALOG_MODE == ANALOG_MODE_LAST_LED) {
    ledCount--;
  }

  #if MAX_LEDS > 1 || ANALOG_OUTPUT_ENABLED == false
    FastLED.addLeds<LED_TYPE, LED_PINS, COLOR_ORDER>(leds, ledCount);
  #endif
 
  // color adjustments
  FastLED.setBrightness ( BRIGHTNESS );
  FastLED.setTemperature( COLOR_TEMPERATURE );
  FastLED.setCorrection ( COLOR_CORRECTION );
  FastLED.setDither     ( DITHER_MODE );

  // initial RGB flash
  #if INITIAL_LED_TEST_ENABLED == true
  for (int v=0;v<INITIAL_LED_TEST_BRIGHTNESS;v++)
  {
    showColor(CRGB(v,v,v)); 
    delay(INITIAL_LED_TEST_TIME_MS/2/INITIAL_LED_TEST_BRIGHTNESS);
  }
  //for (int v=0;v<INITIAL_LED_TEST_BRIGHTNESS;v++)
  //{
   // showColor(CRGB(v,v,v)); 
   // delay(INITIAL_LED_TEST_TIME_MS/2/INITIAL_LED_TEST_BRIGHTNESS);
// }
  #endif
  showColor(CRGB(0, 0, 0));

  Serial.print("Ada\n"); // Send "Magic Word" string to host


  boolean transmissionSuccess;
  unsigned long sum_r, sum_g, sum_b;

  // loop() is avoided as even that small bit of function overhead
  // has a measurable impact on this code's overall throughput.
  for(;;) {
    // wait for first byte of Magic Word
    for (i = 0; i < sizeof prefix; ++i) {
      // If next byte is not in Magic Word, the start over
      if (!checkIncommingData() || prefix[i] != Serial.read()) {
        i = 0;
      }
    }

    // Hi, Lo, Checksum
    if (!checkIncommingData()) continue;
    hi = Serial.read();
    if (!checkIncommingData()) continue;
    lo = Serial.read();
    if (!checkIncommingData()) continue;
    chk = Serial.read();

    // if checksum does not match go back to wait
    if (chk != (hi ^ lo ^ 0x55)) continue;

    memset(leds, 0, MAX_LEDS * sizeof(struct CRGB));
    transmissionSuccess = true;
    sum_r = 0;
    sum_g = 0;
    sum_b = 0;

    int num_leds = min ( MAX_LEDS, (hi<<8) + lo + 1 );

    // read the transmission data and set LED values
    for (int idx = 0; idx < num_leds; idx++) {
      byte r, g, b;
      if (!checkIncommingData()) {
        transmissionSuccess = false;
        break;
      }
      r = Serial.read();
      if (!checkIncommingData()) {
        transmissionSuccess = false;
        break;
      }
      g = Serial.read();
      if (!checkIncommingData()) {
        transmissionSuccess = false;
        break;
      }
      b = Serial.read();
      leds[idx].r = r;
      leds[idx].g = g;
      leds[idx].b = b;
      #if ANALOG_OUTPUT_ENABLED == true && ANALOG_MODE == ANALOG_MODE_AVERAGE
          sum_r += r;
          sum_g += g;
          sum_b += b;
      #endif
    }

    // shows new values
    if (transmissionSuccess) {
      endTime = millis() + OFF_TIMEOUT;
      #if MAX_LEDS > 1 || ANALOG_OUTPUT_ENABLED == false
      FastLED.show();
      #endif

      #if ANALOG_OUTPUT_ENABLED == true
        #if ANALOG_MODE == ANALOG_MODE_LAST_LED
          showAnalogRGB(leds[MAX_LEDS-1]);
        #else
          showAnalogRGB(CRGB(sum_r/MAX_LEDS, sum_g/MAX_LEDS, sum_b/MAX_LEDS));
         #endif
      #endif
    }
  }
} // end of setup

void loop() {
  // Not used. See note in setup() function.
}

Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).

Gruß Tommy

Spekulativ könnte hier der Flaschenhals sein, weil nicht schnell genug Informationsnachschub kommt:

#define serialRate 115200

Ich habe Manipulationen gesehen, um auf eine höhre Geschwindigkeit zu kommen:

//##############################################################################
//                                                                             #
// Glediator to WS2812 pixel converter                                         #
// by R. Heller                                                                #
// V 1.0 - 07.01.2014                                                          #            
// wwww.SolderLab.de                                                           #
//                                                                             #
// Receives serial data in Glediator protocol format @ 1 MBit/s                #
// and distributes it to a connectect chain of WS2812 pixels                   #
//                                                                             #
// Adjust the correct DATA PIN and the correct NUMBER OF PIXELS you are using  # 
// in the definitions section below before uploading this sketch to your       #
// Arduino device.                                                             #
//                                                                             #
// Maxiumim number of supported pixeles is 512 !!!                             #
//                                                                             #
// In the Glediator software set output mode to "Glediator_Protocol",          #
// color order to "GRB" and baud rate to "1000000"                             #
//                                                                             #
//############################################################################## 
...
void setup()
{
  // Set data pin as output
  DATA_DDR |= (1 << DATA_PIN);
  
  // Initialize UART
  UCSR0A |= (1<<U2X0);                                
  UCSR0B |= (1<<RXEN0)  | (1<<TXEN0) | (1<<RXCIE0);   
  UCSR0C |= (1<<UCSZ01) | (1<<UCSZ00)             ; 
  UBRR0H = 0;
  UBRR0L = 1; //Baud Rate 1 MBit (at F_CPU = 16MHz)
  
  ptr=display_buffer;
  
  //Enable global interrupts
  sei();
}

@agmue wie soll ich das jetzt richtig verstehen bei 100 oder 110 leds war es ja kein Problem. Bzw. es war ohne ruckeln (z.b. das Regenbogen Effekt wurde flüssig dargestellt bei 338 leds ruckelt es). Muss ich dann einfach die baudrate hochziehen ?

canx35:
Muss ich dann einfach die baudrate hochziehen ?

Ja, das wäre meine Idee. Denn für die dreifache Datenmenge benötigst Du die dreifache Menge an Informationen. Ob es aber "einfach" geht, weiß ich nicht.

@agmue ich teste es einfach mal erst mal mit der doppelten Baudrate wenn es klappt dann ist ja eigentlich okay und gut. ansonsten den Mega habe ich schon bestellt.

@noiasca

Wohl war aber der mega hat 4 mb RAM und 2 mb eepronter oder so während der Uno nur 2mb und 1mb hat glaub ich. Zumindest an der baudrate liegt es nicht habe jetzt alles gut konfiguriert läuft mit 230400 aber ruckelt immer noch mit 338 leds. Meine Vermutung ist das der Uno zu wenig rechen Leistung hat. Deshalb mit dem mega probieren sollte dies klappen dann ist doch alles perfekt wenn nicht hoffen und beten das es was vergleichbares gibt dad mehr rechen Leistung hat und mit meinem Setup funktioniert. Zumindest funktioniert leider der RPi direkt mit den leds und dem program hyperion nicht deshalb der Arduino als pwm Adapter quasi

canx35:
@noiasca

Wohl war aber der mega hat 4 mb RAM und 2 mb eepronter oder so

Ich möchte auch einen solchen Arduino MEGA haben. mit 4 Megabyte RAM und 2 Megabyte EEprom.

Wollen wir mal richtigstellen.
Der Arduino MEGA 2560 (der Arduino MEGA mit dem ATmega1280 wird nicht mehr hergestellt) hat 8 Kilobyte RAM (8196 Byte) und 4 Kilobyte EEprom (4096 Byte)

Grüße Uwe

Oh genau dann war es so Sorry. Ist der Teensy auch mit der Software von arduino kompatibel oder ist das wieder eine eigene Sprache?

canx35:
Ist der Teensy auch mit der Software von arduino kompatibel oder ist das wieder eine eigene Sprache?

Es wird auch die Arduino IDE verwendet, darüber wird ein Zusatzprogramm installiert.
https://www.pjrc.com/teensy/td_download.html

Die Programmierung ist im wesentlichen gleich, die Software bringt von vielen Libs angepasste Versionen mit.

Einige Libs (z.B. USB-Keyboard usw.) sind etwas anders als die original Arduino Libs, aber meist nichts tragisches.

Manches ist gegenüber Standard-Arduino etwas erweitert (digitalReadFast, elapsedMillis, ...), es gibt auch eine Softwareemulation mancher AVR-Register, um Code für 8-Bit Portzugriffe auszuführen.

canx35:
@noiasca

Wohl war aber der mega hat 4 mb RAM und 2 mb eepronter oder so während der Uno nur 2mb und 1mb hat glaub ich. Zumindest an der baudrate liegt es nicht habe jetzt alles gut konfiguriert läuft mit 230400 aber ruckelt immer noch mit 338 leds. Meine Vermutung ist das der Uno zu wenig rechen Leistung hat. Deshalb mit dem mega probieren sollte dies klappen dann ist doch alles perfekt wenn nicht hoffen und beten das es was vergleichbares gibt dad mehr rechen Leistung hat und mit meinem Setup funktioniert. Zumindest funktioniert leider der RPi direkt mit den leds und dem program hyperion nicht deshalb der Arduino als pwm Adapter quasi

AVR Arduinos haben keine virtuelle Speicherverwaltung.
Es kann also NIE das Problem auftreten, dass ein Programm bei zu wenig physikalisch vorhandenem Speicher anfängt zu ruckeln.
Denn es findet keinerlei Auslagerung statt.

Solche Effekte zeigen sich nur bei "richtigen" Betriebssystemen.

Wenn bei AVR der Speicher nicht reicht, dann knallt es.
Nix ruckeln.

canx35:
2. Was knapp ist kann ich nicht sagen denn der Arduino Uno hängt am RPI 3B+ ohne Netzteil, also zieht er nur die Leistung vom USB Port.

Da deine gesamte Verkablung unbekannt ist und ich auch nicht durchblicke warum der Arduino benötigt wird was der Raspi nicht auch könnte, kann ich dir jedoch sagen das der Anschluss des Arduinos an den Raspi USB Port keine gute Idee ist. Der Raspi hat so schon mit sich selbst zu kämpfen und dann soll er noch etwas fremd versorgen was auch keine Spannungsschwankungen duldet. Kann zu unbekannten Aussetzern führen vielleicht Resets was sich vielleicht in Rucklern äußern könnte.

Hallo,

Hier nochmal eine Zeichnung von meinem verdrahtung mit den jeweiligen Geräte.

Steuern über den Raspberry ging nicht es hat dann nur geflackert.

Zwischen mega und raspberry habe ich leider immer noch eine zu kleine baudrate es ist fast perfekt die farben wechseln ziemlich nahtlos aber noch nicht komplett nahtlos.

https://mega.nz/#!o5pVWKRZ!hvLMd2H3QgEsaW9msFqFgOnePt9zPMaLwqQvD10CUHM

Setze die Bilder hier ins Forum und nicht auf irgendwelche fremden Server, die diese Bilder kurzfristig löschen.

Das Bild von canx35 aus #18:
Bild_8476584.jpg
(von 3 MB auf 39 kB) :slight_smile: