Using HIGH. LOW text from array to control output pins

Hello All. I've been doing some reading on C++ recently as a total newcomer to the language and Arduino. I got to the point in my reading that I sensed I ought to get my hands dirty in order to truly understand and reinforce some of what I was attempting to grasp. As an exercise, I want to map the analog input from a fuel gauge sending unit and have the Arduino outputs energize one of nine leds relative to the range of 'empty' to 'full'. The nine leds will be controlled as a matrix using 6 Arduino outputs. Right now I'm working on the output. The code I've come up with so far is below. Can an text from an array be used for this? I also thought that I might be able to use 1 and 0 in place of HIGH and LOW but I couldn't find any information that allowed me to think that that may be possible.

char* led_matrix [9] [6] = {
	{LOW, HIGH, HIGH, HIGH, LOW, LOW}
	{HIGH, LOW, HIGH, HIGH, LOW,LOW}
	{HIGH, HIGH, LOW, HIGH, LOW, LOW}
	{LOW, HIGH, HIGH, LOW, HIGH, LOW}
	{HIGH, LOW, HIGH, LOW, HIGH, LOW}
	{HIGH, HIGH, LOW, LOW, HIGH, LOW}
	{LOW, HIGH, HIGH, LOW, LOW, HIGH}
	{HIGH, LOW, HIGH, LOW, LOW, HIGH}
	{HIGH, HIGH, LOW, LOW, LOW, HIGH}
};


void setup()

{	
	pinMode (Wire1Pin, OUTPUT);
	pinMode (Wire2Pin, OUTPUT);
	pinMode (Wire3Pin, OUTPUT);
	pinMode (Wire4Pin, OUTPUT);
	pinMode (Wire5Pin, OUTPUT);
	pinMode (Wire6Pin, OUTPUT);
}





void loop()


int sequence;
	for(sequence = 0, <9, sequence++)
	{
		digitalWrite (Wire1Pin, led_matrix [sequence] [0]);
		digitalWrite (Wire2Pin, led_matrix [sequence] [1]);
		digitalWrite (Wire3Pin, led_matrix [sequence] [2]);
		digitalWrite (Wire4Pin, led_matrix [sequence] [3]);
		digitalWrite (Wire5Pin, led_matrix [sequence] [4]);
		digitalWrite (Wire6Pin, led_matrix [sequence] [5]);
	}

Looking forward to opinions and learning even more. - Scotty

RAM is a very precious commodity on a microcontroller; wasting it using text to store what could be represented in a single bit is perverse.
Of course, by now you've found that your code doesn't even compile - why you didn't try this before posting is beyond me.

@AWOL & scottyjr:
Using the macros "HIGH" and "LOW" translates in the code to 1 and 0, respectively - note, not even the text "1" and "0", but simply the binary values "1" and "0". So using the words HIGH and LOW in an array of chars is... well, improperly defined as a char (if it were to be text, it would have to be char[9][6][5] anyway - [5] for the 5 bytes of the longest word "HIGH" and its terminating null)... but aside from that, it's just an array of bytes "1" and "0" anyway.

Personally, since each segment is only 6 bits long anyway, I would just use binary digits:
byte led_matrix [9] = { B011100, B101100, B110100, B011010, B101010, B110010, B011001, B101001, B110001 };

... then in your code ...
(original code syntax errors corrected in bold)

void loop() [b]{[/b]

byte sequence;
for(sequence = 0, sequence <= 9 , sequence++) {
digitalWrite (Wire1Pin, bitRead(led_matrix[sequence],0));
digitalWrite (Wire2Pin, bitRead(led_matrix[sequence],1));
digitalWrite (Wire3Pin, bitRead(led_matrix[sequence],2));
digitalWrite (Wire4Pin, bitRead(led_matrix[sequence],3));
digitalWrite (Wire5Pin, bitRead(led_matrix[sequence],4));
digitalWrite (Wire6Pin, bitRead(led_matrix[sequence],5));
}
}

Either way is OK; the original code would use 54 bytes of "precious" RAM for the LED bits, whereas this would use 9 :slight_smile:

scottyjr:

char* led_matrix [9] [6] = {
{LOW, HIGH, HIGH, HIGH, LOW, LOW}

That's a big Oopsie: You have declared a 2-D array of pointers and you are initializing it with integer data type constants. (At least that is what you appear to be trying---you don't have the correct syntax for your initializer list).)

No matter how you decide to change things (to a 1-D array of packed bytes or whatever), you are not using, and do not need, an array of pointers for this. Really.

Regards,

Dave

davekw7x:

scottyjr:

char* led_matrix [9] [6] = {
{LOW, HIGH, HIGH, HIGH, LOW, LOW}

That's a big Oopsie: You have declared a 2-D array of pointers and you are storing integer data type constants. No matter how you decide to change things (to a 1-D array of packed bytes or whatever), you are not using, and do not need, an array of pointers for this. Really.

Oops... caught that too, but forgot to mention it. Yeah, you'd have fun trying to use an array of pointers ("char *led_matrix") instead of an array of actual values ("char led_matrix"). I think it might happen to work, in the very unlikely event that the byte values at address 0x1 and 0x0 happen to be >1 and 0, respectively :wink:

FalconFour:
...I think it might happen to work...

Not a chance. Trying to send a pointer as the second parameter to digitalWrite() is a sure-fire way to trigger a compiler error (Well, it will trigger an error after the other compiler errors before that are cleared so that it can get that far).

Of course there are a dozen (or so) other problems, mostly syntax errors that will become apparent when anyone actually tries to compile the program. We haven't actually got to the debugging stage yet; I just wanted to point out a conceptual error early on. An opportunity for the OP to read up a little more and try to figure out what the heck pointers would be used for here. After all, that little asterisk didn't just jump on the page did it? Why did he put it there?

I mean, experienced programmers will immediately spot and denigrate the use of 2-D array to hold bit values (instead of packing bits into bytes and having a 1-D array of bytes), but for beginners, I thing it's important to get the furshlugginer thing working first. Massage later (the program and yours truly could both use a little massaging right about now). Prettify later. (The program, that is.) Optimize the program later after learning about bit packing. The original concept seems valid to me, and I think it would be OK to try compiling it.

But maybe that's just me---I'm funny that way. Or maybe it's not just me. AWOL suggested the same thing: Try it. See what happens. See how many things can go wrong. That's when the real learning process begins. See Footnotes.

Regards,

Dave

Footnotes:
"I never learned anything from a man who agreed with me."
---Robert A. Heinlein

"I never learned anything from a program that compiled
correctly the first time."
---davekw7x

Totally correct... hell, I'm even still having trouble understanding how pointers work - particularly, if I have a 2D array in PROGMEM, do I send pgm_read_byte(&varName[varIdx]), or pgm_read_byte(varName[varIdx]), or pgm_read_byte(pgm_read_byte(varName)+varIdx)...??! Amusingly, the answer seems to be to use pgm_read_byte(varName[varIdx]), which seems pretty counter-intuitive, but I still keep running into problems every time I encounter pointer-manipulation... I still have no f'ing clue what "char **var" does with the double-asterisks. :stuck_out_tongue: And I've written some unbelievably optimized and complicated code that uses all 20 I/O pins and like 6 different libraries to run a sort of electronics orchestra... and it only took a day to write and debug, compiled to 15KB :wink:

I think an even better way to retrieve the packed bit values, now that I think of it... bitRead may not be necessary, just use "led_matrix[sequence] & _BV(5)" to "AND"-out the 6th bit. It'll equate to 32 instead of 1 if true, but 32 is still "true" for bitwise/boolean operations and would be "0" if false, so it's logically sound without needing to shift into place :wink:

edit: Love the footnotes! Haha... so true.

@FalconFour:
There is nothing in the C/C++ language to say that HIGH has to mean 1 and LOW 0.
At the point where the OP defined Wire1Pin etc (we weren't shown that bit) the OP could have written:

#undef HIGH
#undef LOW
#define HIGH "HIGH"
#define LOW "LOW"

or even

#undef HIGH
#undef LOW
#define HIGH "Hi-di-hi"
#define LOW "Lo-di-lo"

and that part (with the missing commas) would have made some sense.

However, posting code that couldn't compile for a host of other reasons was a bit of a waste of everyone's time.