How can i add new [voids] functions to my code?

how can i make different voids other dan void setup and void loop?

If what you mean is when and why woud I add additional functions to my code the answer is 'it depends'.
In the classic payroll example, a routine/function might be appropriate for calculating income tax. Another use case is where you have the same chunk of code used multiple times in your main procedure. Putting that chunk in its own function makes the main code smaller and therefore more readily understood.
There are more reasons but I think that gives you the picture.

Firstly, what you are referring to as voids are actually functions. A function can return a value to the code that called it and the data type of the returned value is put before the name of the function. If the function does not return a value then it is indicated by using a data type of void

As to your question, try this sketch


void setup()
{
    Serial.begin(115200);
    Serial.println(multiply(11, 5));  //multiply 2 numbers and print the result
    Serial.println(multiply(3, 2));   //2 different numbers
}

void loop()
{
}

int multiply(int a, int b)  //multiply 2 integers and return the result as an integer
{
    return a * b;  //multiply the 2 integers and return the result
}

The multiply() function does what its name implies and the result is printed

What is it that you want your extra functions to do ?

1 Like
  • void isn't a section of code.
  • Void is the return type of a function.
    void means nothing is returned on leaving a function.
4 Likes

Here is an interesting sketch that was posted earlier today that has several more functions than just setup and loop. This is somewhat advanced code but maybe it will help you understand that there are many reasons for additional functions or procedures.


#define ProjectName "What is the fastest way to implement two taskNmrs selected in setup?"
constexpr uint8_t ButtonPin {A0};
void (*setups[])() {
  setup_Tsk_A, setup_Tsk_B
};
void (*loops[])() {
  loop_Tsk_A, loop_Tsk_B
};
uint8_t taskNmr;
//----------------------------------------------------------
void setup_Tsk_A()
{
  Serial.println(__func__);
}
void setup_Tsk_B()
{
  Serial.println(__func__);
}
//----------------------------------------------------------
void loop_Tsk_A()
{
  Serial.println(__func__);
}
void loop_Tsk_B()
{
  Serial.println(__func__);
}
//----------------------------------------------------------
void setup()
{
  Serial.begin(115200);
  Serial.println(ProjectName);
  pinMode (ButtonPin, INPUT_PULLUP);
  //taskNmr = digitalRead(ButtonPin)?LOW:HIGH;
  taskNmr = digitalRead(ButtonPin) == LOW ? 1:0;
  setups[taskNmr]();
}
//----------------------------------------------------------
void loop()
{
  loops[taskNmr]();
  delay(1000);  // for testing only
}
//----------------------------------------------------------
2 Likes
You cannot have more than one function with the same name, such as:

void setup() {}
void loop() {}

These two functions are required in an Arduino sketch and must each appear only once.

The keyword void indicates what the function returns—in this case, nothing. 
If a function is defined with void, it does not return a value
 to the calling code.

You can define as many additional functions as you want, as long as each
 has a unique name. For example:

void sharkvr69() {
  Serial.print("Hello sharkvr69");
}
this will print a hello message for you.

The best thing you can do is get a copy of the Arduino Cookbook and skim it cover to cover and stop, read and even try anything that looks interesting.

1 Like

Not quite true, but in the context of this topic it is a reasonable rule to follow

1 Like

Thanks for the comment, that is partially why I recommended the Arduino Cookbook, it will be a big help to the OP. It does a much better job of explain this then I can. Those are the things I got hung up years ago.

Please define a "void".

It is obvious that @sharkvr69 doesn't know what a void is. He has been told several times in this thread, but sadly has not replied back yet.

If by "voids" you mean functions, I like to use new tabs for my functions. Others prefer to put them directly in the main code sketch outside (above or below) of the setup and loop functions. I choose to use new tabs to keep my main code a little more clutter free and organized. The tabs are listed in a bar across the top of the IDE, so you can access them easily if needed.

In my IDE, 2.2.1, there are 3 dots near the upper right corner of the screen. Click on those and select "New Tab". Name the new tab whatever you want. I use the same name as the function I am about to create. After naming the tab and hitting enter, a new blank sketch area will appear. To create the "void" function, start with:

void functionName(){
write your code here;
}

Next, make sure to declare functionName(); wherever you are declaring your variables. I declare mine before setup. That might be the only place to declare variables, I am unsure of that. (I am new to coding, and assuming you are as well.)

Then to use the new function you simply call it in the code somewhere. For example maybe you need to do something when a button is pressed:

if (digitalRead(button) == HIGH){
functionName;
}

This is a very basic way of doing it, but it works for me. I have done quite a bit of button checking and motor control in separate functions that I wrote in different tabs with great success. I have seen posts about people saying the tabs get arranged in alphabetical order automatically by the IDE, but I have yet to see it. I can actually drag them to whatever order I want them in.

The tabs are not arranged in alphabetical order.

What happens is that any .ino files contained in tabs are concatenated into a single temporary .ino file before it is compiled. The order in which the code from the .ino files appear in the combined one is determined by the alphabetical order of the tab name but the main .ino file being first whatever its name is

1 Like

Can I attempt to dumb that down a little to make sure I understand?

Before compiling, the IDE arranges the .ino files alphabetically in the background where I can not see it happening into one alphabetical file? And then that one alphabetical file is compiled?

1 Like

That's right.

This should not be necessary. Strictly speaking, the compiler does a single pass, top to bottom, over your code. So before you can use a function, it has to have "seen it". The obvious way is to put it first

void wifiSetup() {
  // whatever
}

void setup() {
  Serial.begin(115200);
  wifiSetup();
  // etc
}

But you can also have

void wifiSetup();  // declared, but not defined

void setup() {
  Serial.begin(115200);
  wifiSetup();
  // etc
}

void wifiSetup() {  // defined later
  // whatever
}

With .ino files, the builder inserts all the necessary forward declarations for you when it "glues" all of them together, in main-plus-alphabetical order. Following your practice, with for example one.ino and nine.ino, alphabetically nine comes first, so the resulting .ino.cpp that is actually compiled looks like

#include <Arduino.h>
#line 1 "/Users/kenb4/Arduino/glue/glue.ino"
#line 1 "/Users/kenb4/Arduino/glue/glue.ino"
void setup();
#line 7 "/Users/kenb4/Arduino/glue/glue.ino"
void loop();
#line 1 "/Users/kenb4/Arduino/glue/nine.ino"
void nine();
#line 1 "/Users/kenb4/Arduino/glue/one.ino"
void one();
#line 1 "/Users/kenb4/Arduino/glue/glue.ino"
void setup() {
  Serial.begin(115200);
  one();
  nine();
}

void loop() {}

#line 1 "/Users/kenb4/Arduino/glue/nine.ino"
void nine() {
  Serial.println("nine");
}
#line 1 "/Users/kenb4/Arduino/glue/one.ino"
void one() {
  Serial.println("one");
}

(If you turn on "Show verbose output during compile", it lists the full path of the .ino.cpp in the command after "Compiling sketch...")

  • #include <Arduino.h> is inserted
  • Forward declarations for every function are added (unless already present)
  • #line directives are needed to display the correct line number for the original file when there are warnings and errors

Unfortunately, there are a few bugs with edge cases. I don't rely on the magic, other than not putting #include <Arduino.h> in my one-and-only .ino. When I put code in separate files, I use plain .cpp files with corresponding .h files; and I put the code in the right order so that each module compiles, only rarely with forward declarations. But I'm used to it.

You can declare types and global variables between/before every other top-level item, like functions. Again, you have to declare it (but not necessarily define it) before it is used. Unlike with functions, no magic is applied for these, so they tend to be all at the top. But it might make sense to declare stuff used only the loop after the setup -- "it depends"

2 Likes

I should clarify a statement I made to the original poster. Instead of saying this

I should have said "That might be the only place to declare GLOBAL variables." Though now I know better. Thanks kenb4.

I declare MOST of my functions globally because:

  1. If declaring them globally, I can use them anywhere. AND
  2. I just don't know any better!

I did not mean to hijack your topic. Let's get back to adding new voids! (functions!)

Anyway post#11 is basically how I do it.

That actually does nothing when the button is pressed.

a7

Indeed. I missed the parentheses. functionName();

Has gone away, so let's all stop trying to hijack the thread, or indeed supplying more information. He has had over 24 hours to respond but nothing.

You need to repair your watch :smiley: The opening post was made 8 hours ago.

Sorry but this was yesterday for me.