[SOLVED] Wrong values when accessing multidimensional array

You mean this bit?

  for (i=0; i<8; i++) {
    this->digitalWrite(i, d & (1 << i) ? HIGH : LOW);
  }

That’s easy.

“i” goes from 0 to 7.

“1 << i” is 0b00000001 shifted left “i” times, so as “i” progresses you have a walking bit:

i==0: 0b00000001
i==1: 0b00000010
i==2: 0b00000100
i==3: 0b00001000
i==4: 0b00010000
i==5: 0b00100000
i==6: 0b01000000
i==7: 0b10000000

The & masks the incoming byte with the walking bit, so for the byte 0b11011001 you get:

i==0: 0b00000001
i==1: 0b00000000
i==2: 0b00000000
i==3: 0b00001000
i==4: 0b00010000
i==5: 0b00000000
i==6: 0b01000000
i==7: 0b10000000

Then, the ? … : … is a compressed “if” statement:

if ("resultant value is anything but 0b00000000") {
  digitalWrite(i, HIGH);
} else {
  digitalWrite(i, LOW);
}

In my code it’s using an internal version of digitalWrite that feeds through I2C to an IO expander. You could get the pin number to use from an array, using “i” as the index.

Hi majenko,

I just now saw that you also posted an explanation about your code, thank you for that. However, when it comes to new stuff I’d rather figure it out myself so I can understand and do it myself next time.

For future reference, here’s my working example:

const unsigned char Digit::_bMap[NUM_NUMBERS] = {
  0b01110111, // 0
  0b00100100, // 1
  0b01011101, // 2
  0b01101101, // 3
  0b00101110, // 4
  0b01101011, // 5
  0b01111010, // 6
  0b00100101, // 7
  0b01111111, // 8
  0b01101111  // 9
};

void Digit::set (unsigned char num)
{
  if (_num != num)
  {
    _num = num;
    num = Digit::_bMap[num];

    for (unsigned char i = 0; i < 8; i++)
    {
      unsigned char state = (num & (1 << i)) ? 1 : 0;

      if (state == 1)
      {
        _part_on(i);
      }
      else
      {
        _part_off(i);
      }
    }
  }
}

void Digit::_part_on (unsigned char part)
{
  Serial.print(part);
  Serial.println(" is on");
}

void Digit::_part_off (unsigned char part)
{
  Serial.print(part);
  Serial.println(" is off");
}

I can probably condense and optimize this code even further, but I will refactor it when the rest of project is finished.

Thanks again majenko, you were a real lifesaver.

– Wouter

Alright, couldn’t help myself and refactored the code already. :stuck_out_tongue:

const unsigned char Digit::_bMap[NUM_NUMBERS] = {
  0b01110111, // 0
  0b00100100, // 1
  0b01011101, // 2
  0b01101101, // 3
  0b00101110, // 4
  0b01101011, // 5
  0b01111010, // 6
  0b00100101, // 7
  0b01111111, // 8
  0b01101111  // 9
};

void Digit::setPin(unsigned char pin)
{
  _pin = pin;
}

void Digit::setLeds(unsigned char leds_c[NUM_PARTS][NUM_LEDS])
{
  unsigned char a = 0;

  for (unsigned char i = 0;i < NUM_PARTS; i++)
  {
    for (unsigned char j = 0;j < NUM_LEDS; j++)
    {
      _leds[i][j] = leds_c[i][j];
    }
  }
}

void Digit::set (unsigned char num)
{
  if (_num != num)
  {
    _num = num;

    for (unsigned char i = 0; i < 8; i++)
    {
      toggle(i, (Digit::_bMap[num] & (1 << i)) ? 1 : 0);
    }
  }

}

void Digit::toggle (unsigned char part, unsigned char state)
{
  for (unsigned char i = 0; i < 2; i++)
  {
    if (state == 1)
    {
      // turn on led _leds[part][i]
    }
    else
    {
      // turn off led _leds[part][i]
    }
  }
}

By switching from the multidimensional array to the binary method, I was able to shave off close to 200 bytes off my memory usage. Since this program is going to run on an Arduino Micro, memory is quite scarce.

– Wouter

I think if you want to have an array with raggedy row-lengths like that, you would have to use dynamically allocated memory, which is probably a bad idea on the arduino.

think if you want to have an array with raggedy row-lengths like that

…you could research Iliffe vectors (though probably not worth the overhead here)

Because you guys helped me so much, here’s a sneak peak of the first test with working led(s).

It’s just a single ‘part’ of a digit so I can see how many I actually need to use per part. The part itself is a 3D-printed model I made.

– Wouter

led-test-part.jpg

Shiney...! 8)