Iterate over serial1, serial2, ...?

I was wondering if / how it is possible to iterate over several functions?
For example, can some code like this

Serial1.print("test");
Serial2.print("test");
Serial3.print("test");

be replaced with something like this?

for (byte i=1; i++; i<4) Serial(i).print("test");

Or shorter, how could I make this work?

void print_at_serialport(byte number) Serial(number).print("test");
HardwareSerial *ports[3] = { &Serial1, &Serial2, &Serial3 };

for (int i=0; i<3; i++)
    ports[i]->print("test");

Regards,
Ray L.

Perfect, thank you very much!

Now what if instead of "Serial" I have some random functions "function1", "function2", ...?

Similar, but different. Function pointers are "typed" by the functions argument list and return value:

void (*funcptr)(int);

void foo (int val)
{
    Serial.print("val is ");
    Serial.println(val);
}

void setup()
{
    Serial.begin(9600);
    funcptr = &foo;
}

void loop()
{
    funcptr(12);
    *funcptr(12);
}

loop will print:

val = 12
val = 12

showing two different, but equivalent, options for calling syntax.

Regards,
Ray L.

loop will print:

Not unless some code changes are made:

sketch_jan12a.ino: In function 'void loop()':
sketch_jan12a:18: error: void value not ignored as it ought to be

PaulS:
Not unless some code changes are made:

It would be nice if, instead of just making unhelpful, and often insulting, comments, you actually helped people. Is it not obvious this was a simple typo?

void (*funcptr)(int);

void foo (int val)
{
	Serial.print("val is ");
	Serial.println(val);
}

void setup()
{
	Serial.begin(9600);
	funcptr = &foo;
}

void loop()
{
	funcptr(12);
	(*funcptr)(12);
}

Happy now?

Regards,
Ray L.

Thanks Ray. It looked wrong to me but I didn't understand what was wrong until you posted the correction.

void loop()
{
	funcptr(12);
	(*funcptr)(12);
}

I don't understand how that can work. Don't you need

foo(12);
(*funcptr)(12);

to demonstrate your method ?

michinyon:

void loop()

{
funcptr(12);
(*funcptr)(12);
}




I don't understand how that can work. Don't you need



foo(12);
(*funcptr)(12);




to demonstrate your method ?

No. funcptr is a pointer to a function which takes a single int argument, and returns nothing. In setup, funcptr is initialized to point to the function foo(). The two lines in loop() show two different, but exactly equivalent, ways of "de-referencing" funcptr to call foo(), passing 12 as the argument.

Function pointers is pretty advanced c, really not for beginners, but the question was asked....

Regards,
Ray L.

It would be nice if, instead of just making unhelpful, and often insulting, comments, you actually helped people. Is it not obvious this was a simple typo?

Well, yes, it was obvious that there was some typo made. As to what you intended, no, I'm not a mind reader, so I can't guess what you intended.

Sorry for tagging along with this post.

But i thought it was more relevant posting it here than starting a new post.

I was wondering, where can you find this syntax?
Is there a good book or tutorial you can recommend me?

Thanks

So I tried to modify Ray’s code in order to be able to iterate over an array of functions.
Yet, somewhere is an error, probably in one of the commented lines. What needs to be corrected?

void foo_a (int val){
  Serial.println("foo_a: " + val);
}
void foo_b (int val){
  Serial.println("foo_b: " + val);
}

void (*array_with_pointer_to_function[2])(int);  // create array containing pointers to functions

void setup() {
  Serial.begin(9600);
  array_with_pointer_to_function[] = {&foo_a, &foo_b};  // compiler error: primary expression before [ missing
}

void loop() {
  for (int i=0; i++; i<3){
    array_with_pointer_to_function[i](5);
    (*array_with_pointer_to_function[i])(6);
  }
}

If it all worked correctly, the output should be
“foo_a: 5”
“foo_a: 6”
“foo_b: 5”
“foo_b: 6”

void setup() {
  Serial.begin(9600);
  array_with_pointer_to_function[0] = foo_a;
  array_with_pointer_to_function[1] = foo_b;  // compiler error: primary expression before [ missing
}

When you get a compile error, scroll the error window up to the FIRST error. It tells you exactly where the error is. In this case:

sketch_jan13a.ino: In function 'void setup()':
sketch_jan13a.ino:12:34: error: expected primary-expression before ']' token

The 12:34 means line 12, character 34 in the source code. It found a ']' where it was not legal to have one, which is a strong clue that your initialization was not valid.

The function pointer syntax can get kinda ugly. It cleans up a lot if you use typedef to define a new type for the function pointer:

typedef void (*foo_ptr_t)( int );

This declares a new variable, foo_ptr_t, of type "pointer to function which takes a single int arguement, and returns nothing". You can now use this new type just as you do all built-in types.

The arrany of function pointers becomes:

foo_ptr array_with_pointer_to_function[];

And you can initialize and call one of the functions like this:

array_with_pointer_to_function[0] = foo_a;
array_with_pointer_to_function[1] = foo_b;
array_with_pointer_to_function[2](12);

Regards,
Ray L.

  for (int i=0; i++; i<3){

Back to school for you!

The order of clauses in that for statement is wrong. Even if it were correct, the loop would iterate 3 times, executing the three functions in the array. Of course, there AREN’T three functions, so who knows what the hell would happen when the third call was made.

@PaulS
Just a minor glitch.
Initially I had written the sketch and tested it with three functions, an array of three and of course the loop you mention with “…i<3”.

For clarity / not blowing up space for the post here I then removed the last function and shortened the array - but forgot to shorten the for loop.

@Kevin77: The Right-Left Rule can be found in my C Programming Guide book, but that's from the 1980's. It's used to parse complex data definitions. You can find a summary at:

http://jdurrett.ba.ttu.edu/3345/handouts/RL-rule.html

Near the bottom of the page are a couple of pointer-to-function examples. You gotta love his last one:

double (*(*pf)())[3][4];  // pf is a pointer to function that returns a pointer
                          // to a 3x4 array of doubles