Understanding Dotstar.cpp - pixels , *pixels

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
littlebot
 
Posts: 5
Joined: Wed Jul 14, 2021 1:18 am

Understanding Dotstar.cpp - pixels , *pixels

Post by littlebot »

Hi, I'm trying to understand the code for the Dot Star LEDs and I'm having a hard time understanding how pixels(NULL) is changed in order to pass the values on for numLEDs and each of the pixel colors (R,G,B).
So initially, it's set up here(?):

Code: Select all

Adafruit_DotStar::Adafruit_DotStar(uint16_t n, uint8_t data, uint8_t clock,
                                   uint8_t o)
    : numLEDs(n), dataPin(data), clockPin(clock), brightness(0), pixels(NULL),
      rOffset(o & 3), gOffset((o >> 2) & 3), bOffset((o >> 4) & 3) {
  updateLength(n);
}
And then you use "show" in your sketch :

Code: Select all

void Adafruit_DotStar::show(void) {

  if (!pixels)
    return;

  uint8_t *ptr = pixels, i;            // -> LED data
  uint16_t n = numLEDs;                // Counter
  uint16_t b16 = (uint16_t)brightness; // Type-convert for fixed-point math
However, you don't seem to get past the "if (!pixels)" because it would just "return;" because of pixels(NULL) .
I see there's a pointer "*ptr = pixels" that takes each value for R, G, and B (later in the code)

Code: Select all

 for (i = 0; i < 4; i++)
      sw_spi_out(0);      // Start-frame marker
    if (brightness) {     // Scale pixel brightness on output
      do {                // For each pixel...
        sw_spi_out(0xFF); //  Pixel start
        for (i = 0; i < 3; i++)
          sw_spi_out((*ptr++ * b16) >> 8); // Scale, write
      } while (--n);
    } else {              // Full brightness (no scaling)
      do {                // For each pixel...
        sw_spi_out(0xFF); //  Pixel start
        for (i = 0; i < 3; i++)
          sw_spi_out(*ptr++); // R,G,B
      } while (--n);
    }
    for (i = 0; i < ((numLEDs + 15) / 16); i++)
      sw_spi_out(0xFF); // End-frame marker (see note above)
BUT I can't find where *pixels is pointing to, or where it's value/address is defined.

I seem to be missing something?

FYI....I'm referencing these two files:
https://github.com/adafruit/Adafruit_Do ... otStar.cpp
https://github.com/adafruit/Adafruit_Do ... _DotStar.h

User avatar
dastels
 
Posts: 15660
Joined: Tue Oct 20, 2015 3:22 pm

Re: Understanding Dotstar.cpp - pixels , *pixels

Post by dastels »

pixels is set to point to a dynamically allocated buffer in update_length:

Code: Select all

void Adafruit_DotStar::updateLength(uint16_t n) {
  free(pixels);
  uint16_t bytes = (rOffset == gOffset)
                       ? n + ((n + 3) / 4)
                       :      // MONO: 10 bits/pixel, round up to next byte
                       n * 3; // COLOR: 3 bytes/pixel
  if ((pixels = (uint8_t *)malloc(bytes))) {
    numLEDs = n;
    clear();
  } else {
    numLEDs = 0;
  }
}
If, for some reason, enough memory can't be allocated (malloc returns NULL) then pixels is NULL and numLEDs is 0. The code continues happily with no pixels, and no errors. This, to me, is a flaw... it should error out if it can't allocate memory for the pixels buffer... no idea why it's this way. In your code (that uses the library), you could always call numPixels() which returns the value of numLEDs and check that it's correct (i.e. what you specified and not zero).

Dave

User avatar
littlebot
 
Posts: 5
Joined: Wed Jul 14, 2021 1:18 am

Re: Understanding Dotstar.cpp - pixels , *pixels

Post by littlebot »

Hi Dave, thanks so much for the reply! :)

I saw that in the updatelength() section and didn't realize it was being defined within the if statement. My mind kept reading it as pixels == x and not pixels = x, managed to confuse myself. I wasn't aware that malloc would return NULL (not familiar with memory allocation). That being said, is there any advice or starting point I can look into to try and fix this?

I did walk thru my code to see what was happening, everything seems to be ok until I hit the if statement:
Stepping into IF statement, shows numLEDs and n to be 34
Stepping into IF statement, shows numLEDs and n to be 34
pixels_malloc.JPG (155.39 KiB) Viewed 140 times
Then my numLEDs drops to 0
After running IF statement, n is 34, but numLEDs drops to 0
After running IF statement, n is 34, but numLEDs drops to 0
pixels_malloc_1.JPG (161.63 KiB) Viewed 140 times
Any help would be greatly appreciated. Thanks

User avatar
dastels
 
Posts: 15660
Joined: Tue Oct 20, 2015 3:22 pm

Re: Understanding Dotstar.cpp - pixels , *pixels

Post by dastels »

That's it. pixels is NULL (i.e. (void*)0). C/C++ plays fast and loose with integers and pointers at times. It's one of the corners of the language(s) that gets people in lots of trouble.

What are you running on?

It all depends on how much heap (ram left over from static variables and thus available to be allocated dynamically) there is and what else is trying to allocate from it.

Dave

User avatar
littlebot
 
Posts: 5
Joined: Wed Jul 14, 2021 1:18 am

Re: Understanding Dotstar.cpp - pixels , *pixels

Post by littlebot »

So eventually I want to control the Dotstars thru Bluetooth. I ended up really liking the Feathers and decided to use the nRF52840 (for future design). Based on Nordic's site they recommended using the Segger Embedded Studio IDE (for ARM). That's what I'm currently running the code on (Windows 10). You can use it with J-link or a simulator for debug.

As far as I know, it shouldn't be taking up too much memory. I have a very simple sketch as of this moment (only data for one LED) as you can see:

Code: Select all

#include "Adafruit_DotStar.h"

// number of pixels on the board
#define NUMPIXELS 34 

//Use these pin definitions for Data
#define DATAPIN    9
#define CLOCKPIN   10


Adafruit_DotStar strip(NUMPIXELS, DATAPIN, CLOCKPIN); // DOTSTAR_BRG);

void setup() {
  //digitalWrite(PIN_LED1, HIGH);   //Set LED Gate pin to high
  strip.begin(); // Initialize pins for output
  //strip.updateLength(34);
  strip.setBrightness(80);
  strip.show();  // Turn all LEDs off ASAP
}

void loop() {
  //strip.setPixelColor(0, 255, 0, 0);
  //strip.numPixels();
  strip.setPixelColor(2, 0, 255, 0);
  //strip.setPixelColor(4, 0, 0, 255);
  strip.show();
}
Here's a screen shot after Build/Compile:
Screen shot after build and compile
Screen shot after build and compile
pixels_ram_rom.JPG (282.54 KiB) Viewed 134 times
I don't think it's trying to allocate anything else, unless it's happening in the background outside of my code??
Could the problem be a setting in a library/header somewhere?
or could the problem be a setting within the IDE? (I'm not glued to it so if there's a better method, I'm all ears, I was going based on their recommendations.)

Thanks again....any insight is really helpful

User avatar
littlebot
 
Posts: 5
Joined: Wed Jul 14, 2021 1:18 am

Re: Understanding Dotstar.cpp - pixels , *pixels

Post by littlebot »

Any ideas?
Very stuck...don't know how to get around this problem.
Thanks again for the help

User avatar
littlebot
 
Posts: 5
Joined: Wed Jul 14, 2021 1:18 am

Re: Understanding Dotstar.cpp - pixels , *pixels

Post by littlebot »

For anyone interested (or future reference)....I found the issue.

The SES IDE by default was setting my heap to zero. (cannot imagine why it does this!)
Heap by default set to zero
Heap by default set to zero
heap_zero.JPG (67.25 KiB) Viewed 86 times
Once I changed this value, everything started working
Heap modified, non zero value
Heap modified, non zero value
heap_fix.JPG (63.54 KiB) Viewed 86 times
Cheers!!!! :)

Locked
Please be positive and constructive with your questions and comments.

Return to “Glowy things (LCD, LED, TFT, EL) purchased at Adafruit”