Go Down

Topic: Pass array size to class constructor (Read 2209 times) previous topic - next topic


I'm creating a library to control an led ring board..  I have everything working perfectly without any classes..  The code allows the user to change the number of boards to control (they're running 5925's), so for the led status array I am using I won't know how many led boards there will be..  In normal procedural I used the fairly standard
Code: [Select]
#define NUM_RINGS 3
uint16_t ringState[NUM_RINGS] = 0;

however I am unsure how to proceed once I moved everything to it's own class...  Everything seems to be working, but it's not working... I have a feeling it has something to do with how the memory is getting allocated, but my knowledge in that area is severely lacking :(

I guess a tl;dr would be:

How would I create/define an object that would allow me to pass the size of a member array (two to be exact) in the constructor?

Code below:

Code: [Select]
  ledRings.h - Library for the Mayhew Labs Rotary Encoder LED Ring.
  Created by Nick Van Dorsten, April 03, 2011.
  Version 1: initial release
  Released into the public domain.

#ifndef ledRings_h
#define ledRings_h
#include "WProgram.h"

class ledRings {
    byte dutyCycle;
    byte oldDutyCycle;
    byte num_led_rings;
    byte sdi;
    byte clk;
    byte le;
    uint16_t ringState[];
    uint16_t lastRingState[];
//    static const byte _NUM_LEDS_RING_ARC = 15;
//    static const byte _LED_RING_BOTTOM = 15;

    ledRings(byte sdi, byte clk, byte le, byte numRings);
    void setRingBrightness(byte dC);
    void updateLEDRings();
    void allRingsOff();
    void setRingState(byte ringNum, uint16_t state);
    void setRingLed(byte ringNum, byte ledNum, boolean state);
    void ringAllArcLedsOn(byte ringNum);
    void blinkRing(byte ringNum, byte cnt, uint16_t dly);
    void blinkAllRings(byte cnt, uint16_t dly);

Main Class
Code: [Select]
  ledRings.cpp - Library for the Mayhew Labs Rotary Encoder LED Ring.
  Created by Nick Van Dorsten, April 03, 2011.
  Version 1: initial release
  Released into the public domain.

#include "WProgram.h"
#include "ledRings.h"

ledRings::ledRings(byte sdiPin, byte clkPin, byte lePin, byte numRings) {
  for (byte i=0;i<numRings;i++) {
    ringState[i] = 0;
    lastRingState[i] = 1;
  // Set SPI pins to output
  sdi = sdiPin;
  clk = clkPin;
  le = lePin;
  pinMode(sdi, OUTPUT);
  pinMode(clk, OUTPUT);
  num_led_rings = numRings;
  dutyCycle = 0;
  oldDutyCycle = 255;

void ledRings::setRingBrightness(byte dC) {
  dutyCycle = constrain(dC, 0, 255);

void ledRings::updateLEDRings() {
  // update the ring
  for (int currentRing = num_led_rings-1;currentRing >= 0;currentRing--) {
    shiftOut(sdi,clk,MSBFIRST,(ringState[currentRing] >> 8));    //High byte first
    shiftOut(sdi,clk,MSBFIRST,ringState[currentRing]);           //Low byte second

void ledRings::allRingsOff() {
  // turn all leds off;
  for (byte i=0;i<num_led_rings;i++) {
    lastRingState[i] = 1;
    ringState[i] = 0;

void ledRings::setRingState(byte ringNum, uint16_t state) {
  ringState[ringNum] = state;

void ledRings::setRingLed(byte ringNum, byte ledNum, boolean state) {
  bitWrite(ringState[ringNum], ledNum, state);

void ledRings::ringAllArcLedsOn(byte ringNum) {
  ringState[ringNum] = 0x7FFF;

void ledRings::blinkAllRings(byte cnt, uint16_t dly) {
  for (byte x=0;x<cnt;x++) {
    for (byte i=0;i<num_led_rings;i++) ringState[i] = 0xFFFF;
    for (byte i=0;i<num_led_rings;i++) ringState[i] = 0;

void ledRings::blinkRing(byte ringNum, byte cnt, uint16_t dly) {
  for (byte i=0;i<cnt;i++) {
    ringState[ringNum] = 0xFFFF;
    ringState[ringNum] = 0;


In your header, you have defined the arrays to have 0 elements. What you then do in the constructor can not change the size of those arrays. You need to use malloc and pointers, instead:

In the header:
Code: [Select]
    uint16_t *ringState;
    uint16_t *lastRingState;

In the source code, in the constructor:
Code: [Select]
ringState = (uint16_t *)malloc(sizeof(uint16_t) * numRings);
lastRingState = (uint16_t *)malloc(sizeof(uint16_t) * numRings);

After allocating the memory, you can access the memory as though it was an array (since it is), just like you are now doing.


Thanks again as always Paul.. That worked perfectly :)

Would you be so kind as to explain what the line does?  I get the malloc half, but the "(uint16_t *)malloc" half is a little confusing.  It looks as though you're casting the return of malloc, but that can't be right... Can it?


Would you be so kind as to explain what the line does?

Sure. The malloc function allocates bytes of memory, and returns a pointer to that memory. The type that it returns is void *, so it almost always needs to be cast to the correct type. In your case, the (uint16_t *) cast is doing just that.

Inside the parentheses, you need to define how many bytes to allocate. The number of bytes is defined by the number of elements that the pointer points to (numRings) times the number of bytes in each element (sizeof(uint16_t)).

Go Up

Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

via Egeo 16
Torino, 10131