Go Down

Topic: Question on Array of Functions vs. Standard Long Hand Code (Read 142 times) previous topic - next topic

Howdie,

Would someone be willing to weigh in on why this turned out like it did?

The hypothesis:

Array of functions should work just as if I wrote out the functions long hand.

The result:

It did work but the LEDs are not lighting up as brightly as when I use longhand code. LED refresh rate is similar and LED blink is not detectable under ordinary observation in both experiments.

The Process:

The scenario is that I am playing with LEDs (of course!) and experimenting with a 5 x 3 LED homemade digital display. I wrote the code out longhand and then I wondered if I could write the code by making arrays of vertical line outcomes (e.g. light all vertical LEDs on the center column but let the 1st and last columns be blank to form a "1" on the LED display. I will shorten this code from the full set of digits to just the numeral 1 for this question while leaving the full LOOP included. NOTE: The format of the ARRAY ONE is just a lit column vs. the formal format of the LONG HAND ONE.

My Thought (with no oscilloscope avail)....

  • Can this code can be improved without deviating from the main objective (Use of Arrays of Functions)?
  • The Arduino may process arrays of functions differently and return a less than normal voltage on PWM lines which control the five return path (- side) switch transistors (BC547) on all LED rows. This could explain the dimmer LEDs without any detectable refresh blinking.



Code: [Select]


//LONG HAND CODE

int digitLedDelay = 1;
unsigned long previousMillis = 0;

void setup(){
  Serial.begin(9600);
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}
void loop(){
  unsigned long currentMillis = millis();
  if(((unsigned long)(currentMillis - previousMillis) > 0) && ((unsigned long)(currentMillis - previousMillis) < 1000)){
  digitZero();
  }
  else if(((unsigned long)(currentMillis - previousMillis) > 999) && ((unsigned long)(currentMillis - previousMillis) < 2000)){
  digitOne();
  }
  else if(((unsigned long)(currentMillis - previousMillis) > 1999) && ((unsigned long)(currentMillis - previousMillis) < 3000)){
  digitTwo();
  }
  else if(((unsigned long)(currentMillis - previousMillis) > 2999) && ((unsigned long)(currentMillis - previousMillis) < 4000)){
  digitThree();
  }
  else if(((unsigned long)(currentMillis - previousMillis) > 3999) && ((unsigned long)(currentMillis - previousMillis) < 5000)){
  digitFour();
  }
  else if(((unsigned long)(currentMillis - previousMillis) > 4999) && ((unsigned long)(currentMillis - previousMillis) < 6000)){
  digitFive();
  }
  else if(((unsigned long)(currentMillis - previousMillis) > 5999) && ((unsigned long)(currentMillis - previousMillis) < 7000)){
  digitSix();
  }
  else if(((unsigned long)(currentMillis - previousMillis) > 6999) && ((unsigned long)(currentMillis - previousMillis) < 8000)){
  digitSeven();
  }
  else if(((unsigned long)(currentMillis - previousMillis) > 7999) && ((unsigned long)(currentMillis - previousMillis) < 9000)){
  digitEight();
  }
  else if(((unsigned long)(currentMillis - previousMillis) > 8999) && ((unsigned long)(currentMillis - previousMillis) < 10000)){
  digitNine();
  }
  else {
  digitZero();
  }
}


void digitOne(){
  //start of column 3
  digitalWrite(2, HIGH);
  digitalWrite(5, HIGH);
  delay(digitLedDelay);
  digitalWrite(5, LOW);
  digitalWrite(2, LOW);
 
  //start of column 2
  digitalWrite(3, HIGH);
  digitalWrite(5, HIGH);
  delay(digitLedDelay);
  digitalWrite(5, LOW);
  digitalWrite(6, HIGH);
  delay(digitLedDelay);
  digitalWrite(6, LOW);
  digitalWrite(9, HIGH);
  delay(digitLedDelay);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
  delay(digitLedDelay);
  digitalWrite(10, LOW);
  digitalWrite(11, HIGH);
  delay(digitLedDelay);
  digitalWrite(11, LOW);
  digitalWrite(3, LOW);
 
  //start of column one
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  delay(digitLedDelay);
  digitalWrite(5, LOW);
  digitalWrite(11, HIGH);
  delay(digitLedDelay);
  digitalWrite(11, LOW);
  digitalWrite(4, LOW);
}




Now I want to do this a different way.

Code: [Select]


//ARRAY OF FUNCTIONS CODE

int columns[] = {2, 3, 4};
int shapeVertLine[] = {6, 5, 6, 9, 10, 11};
int ledDelay = 5;


typedef void (* DigitalFuncPtr)();
DigitalFuncPtr numOne[] = {blankData, vertLine, blankData};

void blankData(){
}

void vertLine(){
  int x;
  for(x = 1; x < shapeVertLine[0]; x++){
    digitalWrite(shapeVertLine[x], HIGH);
    delay(ledDelay);
    digitalWrite(shapeVertLine[x], LOW);
    delay(ledDelay);
  }
}

void setup(){
  Serial.begin(9600);
  pinMode(5, HIGH);
  pinMode(6, HIGH);
  pinMode(9, HIGH);
  pinMode(10, HIGH);
  pinMode(11, HIGH);
}


void loop(){
  displayOne();
}

void displayOne(){
  int x;
  for(x = 0; x < 3; x++){
    digitalWrite(columns[x], HIGH);
    numOne[x]();
    digitalWrite(columns[x], LOW);
  }
}




ARRAY CODE VS. LONG CODE

Hackscribble

Hi VeronicaW

In the "long" code, it looks like you only delay after setting outputs HIGH.  There is no delay between setting them LOW and setting the next output HIGH. 

In the function array code, you delay after the HIGH and after the LOW. 

I think the effect is to give you proportionally more off time than in the "long" code.

Regards

Ray
Hackscribble.  Writing about making things.
arduino@hackscribble.com | www.hackscribble.com

Robin2

What you are describing is NOT an array of functions. It is an array of data.

An array of functions is something very different - and not relevant for your project.

...R

RayLivingston

What you are describing is NOT an array of functions. It is an array of data.

An array of functions is something very different - and not relevant for your project.

...R
No, he is using an array of function pointers:

Code: [Select]
typedef void (* DigitalFuncPtr)();
DigitalFuncPtr numOne[] = {blankData, vertLine, blankData};

Why he's doing it this way, I don't understand....

Regards,
Ray L.

Thank you for the responses  :)

Hack, I looked at that, thank you for the point out!
Robin, you keep me honest : ) You are right, I should move this operation to an IC!
Ray, thanks for the back up! :) I do it... because... I... Oh look! Shiny!

This is really an exercise into what is possible with the code and Arduino. I have been trying to take basic code and stretch the concepts as far as I can take them (and maybe save some space on the flash memory). Its been challenging and fun! I like to start with a little and then take a WHOLE LOT. My background is BA/IT Data Analyst & Reports Writer.

And..... I see the problem...  

So here is the brilliantly bad code on my part:

LONG CODE:

Void setup(){

 Serial.begin(9600);
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);
 pinMode(6, OUTPUT);
 pinMode(9, OUTPUT);
 pinMode(10, OUTPUT);
 pinMode(11, OUTPUT);
}

ARRAY CODE:

void setup(){
 Serial.begin(9600);
 pinMode(5, HIGH);
 pinMode(6, HIGH);
 pinMode(9, HIGH);
 pinMode(10, HIGH);
 pinMode(11, HIGH);
}

OOPS! :smiley-eek:   

First of all, I set the pinModes HIGH by mistake instead of OUTPUTS and then, I forgot a few pins at that...

And now it works equally well in both versions. Yay!  :smiley-grin: 

Hugs! ~ Veronica



The last inquiry I have will be to find if this is really economizing memory or a lame run around...

RayLivingston

The last inquiry I have will be to find if this is really economizing memory or a lame run around...
Not likely to save you much, if any, memory.  In fact, it almost certainly will use a bit more memory, as you now have to store the function pointers, and the CPU has to fetch them before using them from the array, instead of simply using a hard-coded function call.

Regards,
Ray L.

Robin2

No, he is using an array of function pointers:
Oops - I had not noticed that.

I only "saw" the function displayOne() which uses a "regular" array.

And while the array of function pointers is declared I don't see where it is used in the code in the original post.
I agree with you that I can't see the point of this complexity for the problem in question. I used function pointers in some code where I wanted to be able to change, at runtime, the function an interrupt calls.

...R

Quote
I used function pointers in some code where I wanted to be able to change, at runtime, the function an interrupt calls.
I am going to file that idea away for later. Thank you : ) ~ V

Coding Badly

First of all, I set the pinModes HIGH by mistake instead of OUTPUTS and then, I forgot a few pins at that...
Well spotted.   8)



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!

Arduino
via Egeo 16
Torino, 10131
Italy