Tutorial: Arduino Basics - Part 2

Content

Functions

In the previous part, we gave you an introduction to the if-then-else condition, the switch-case function and some Arduino-specific commands. This tutorial is intended to introduce beginners to programming in C in addition to the Arduino. In order to make their future projects tidier and more professional, we want to introduce functions at this point. In addition to keeping the code tidy and clear, functions also serve to reduce the programming effort, since certain algorithms are often used several times. Instead of writing them into the code each time, they can be written into a function and called.
There are two main types of functions, on the one hand functions that simply execute an algorithm and on the other hand functions that return a value to the caller. In addition, the caller can pass parameters to functions. For example, the brightness of an LED can be passed to the function that adjusts the brightness of the LED.
Both types of functions are listed below in their basic structure:

Function with no return value:
void [Name]([Variable type] [Name of the variable]){
//statements
}

Function with a return value:
int [Name]([Variable type] [Name of the variable]){
int value = 0;
//statements
return value;
}

The declaration of a new function begins with "void", if the function is to return a value, specify the type of a variable. This is followed by the name of the function, e.g. "LightOnOff". After that, you can define variables between the brackets, which, when executed, can be passed to the function and used in the function. If you want to return a value, end the function with return [value / variable]. This statement ends the function, all following lines are not executed!

In the further sections, we will write all algorithms in separate functions that are executed by other functions. To execute a function, write the name and brackets behind it, e.g. "LightOnOff()". If parameters have to be given to the function, insert them in the brackets, for example: LightOnOff(lightState).

We can extend the code with the light switch from part 1 of the tutorial with a function:

int redLED = 2;
int button = 5;
boolean buttonstate;  
int lightstate = 0;

void setup(){
	pinMode(redLED, OUTPUT);
	pinMode(button,INPUT);		
}

void loop(){
	buttonstate = digitalRead(button);
	if(buttonstate == true){
		//CHANGED:
		LightOnOff(lightstate);
    }

	delay(200); //MAYBE NOT NEEDED
}

void LightOnOff(int lightstate){
	switch(lightstate){
        case 0:
            digitalWrite(redLED,HIGH);
            lightstate = true;
			break;
        case 1:
            digitalWrite(redLED,LOW);
            lightstate = false;
			break;
    }
}

Traffic light control

We are starting with a new project. In our new project, we will program two LEDs (red/green) so that they work like a pedestrian traffic light. If you now think that we have had this project quite similar before, don't worry, we will add some additional functions. Therefore, a green LED will be added to the circuit diagram.

The traffic light control project is intended to serve as an exercise for you. Try to create a code with the following prerequisites so that the traffic light switches from red to green and back when the button is pressed:

  • All components (red and green LED and the button) have their own variable.
  • The variable TrafficLightState stores the current state of the traffic light.
  • The current state of the button is read out in the loop function and stored in the global variable buttonState.
  • The function checkButtonState with the passed parameters (btnState and trafficState) reads out whether the button was pressed and adjusts it according to the current TrafficLightState.
  • The function TurnLightsOnOff with the passed parameter trafficState switches the LEDs on or off according to the passed TrafficLightState.

If the code works for you, congratulations, there are multiple ways, so our solution is only one possibility:

int redLED = 2;
int greenLED = 3;
int button = 5;
boolean buttonState = false;
int TrafficLightState = 0;


void setup() {
  TrafficLightState = 0;
  pinMode(redLED,OUTPUT);  
  pinMode(greenLED,OUTPUT); 
  pinMode(button,INPUT);
}

void loop() {
  buttonState = digitalRead(button);
  checkButtonState(buttonState,TrafficLightState);
}

void checkButtonState(boolean btnState, int trafficState){
  if(btnState == true && trafficState == 0){
    TrafficLightState = 1;
    turnonofflights(TrafficLightState);
    delay(500);
  }
  else 
    if(btnState == true && trafficState == 1){
      TrafficLightState = 0;
      turnonofflights(TrafficLightState);
      delay(500);
  }
}

void turnonofflights(int trafficState){
  if(trafficState == 0){
    digitalWrite(redLED,HIGH);
    digitalWrite(greenLED,LOW);
  }
  else if(trafficState == 1){
    digitalWrite(redLED,LOW);  
    digitalWrite(greenLED,HIGH);
  }
}

Dimmer

We will change the circuit a little because not all pins are suitable for dimming LEDs. Change pin number two (red LED) to nine and three (green LED) to ten.
Please open a new sketch, because we will not use the traffic light functions in this tutorial any further. But at the end of the tutorial you will find some exercises in which you extend the traffic light circuit with the dimmer when changing from red to green. The circuit diagram remains the same.
Fortunately, it is not very difficult to dim an LED. We only need to learn two things. First, only the digital pins of our Arduino with this tilde symbol (~) are able to output different voltages. Secondly, that we now have to use the analogWrite() function because the digitalWrite() function can only send HIGH or LOW signals.
The analogWrite() function is similar to the digitalWrite() function. First you specify the pin and then the value of the voltage (in the range 0-255, but only integer numbers). You can also use HIGH (=255) or LOW (=0). For example, if you want to dim the red LED by 50%, write: analogWrite(redLED, 127).
In the following code we dim the red LED from 100% down in 25% steps in endless loops.

int redLED = 9;

void setup() {
  pinMode(redLED,OUTPUT);  
}

void loop() {
  analogWrite(redLED,HIGH); //100% - OR analogWrite(redLED,255);
  delay(500);
  analogWrite(redLED, 192); //75%
  delay(500);
  analogWrite(redLED, 127); //50%
  delay(500);  
  analogWrite(redLED, 64);  //25%
  delay(500);
}

Loop-Algorithms

After a few examples, now comes the last part of the theory in this tutorial: loops. Loop algorithms are needed to execute defined algorithms again and again with different values. For example, to check a list point by point for a certain value. There is the for loop on the one hand and the while loop on the other. The for loop increments a variable by a certain value and then executes the code contained in it. The while loop, on the other hand, repeats the code it contains until the defined termination condition occurs.

The structure of the for loop:
for (initialise variable and set first boundary; run-time condition (as long as the condition is met, the for loop is executed); increment steps) {
//statement(s);
}

Example to continuously increase the LED brightness:

for(int i = 0; i <= 255; i++){
	analogWrite(redLED, i);
}

In this example, we always increase the control variable i by one (i++ is short for i = i + 1) and set the variable as the red LED current (brightness).
So you can increase or decrease a value and run each value through the algorithm. You can also start other functions from the for loop. There are many ways to use this for loop.

The while loop has the following structure:
while(termination condition){
//statement(s)
}

As an example, a random number between 0 and 9 is generated until it has the value 2, then the while loop terminates.

int number;
while (number != 2){
	number = random(10);
}

(!= means unequal)

A while loop can also be constructed like a for loop, in which case a variable that is incremented must be introduced and the termination condition is the same as the runtime condition of the for loop. The for loop from the previous example then looks like this:

int i;
while (i<=255){
  analogWrite(redLED,i);
  i++;
}

However, the for loop is always recommended for continuously increasing a value. Furthermore, when using the while loop, it is important to note that the termination condition must be fulfilled, otherwise the programme will get stuck in it!

Chaser - for-loop

We will now apply the for loop in practice. For this we will program a chaser, which changes its brightness. For this we extend our circuit by a blue LED, so that the chaser gets a little more color. Try to program such a running light by yourself before you copy the following code. You will get it!

int redLED = 9;
int greenLED = 10;
int blueLED = 11;

void setup(){
	pinMode(redLED, OUTPUT);
	pinMode(greenLED, OUTPUT);
	pinMode(blueLED, OUTPUT);
}

void loop(){
	for(int i = 0; i <= 255; i++){
		analogWrite(redLED, i);		//SWITCH ON RED LED
		delay(100);					//WAIT FOR 100 ms
		analogWrite(redLED, 0);     //SWITCH OFF RED LED                      
		analogWrite(greenLED,i);	//SAME FOR GREEN LED
		delay(100);
		analogWrite(greenLED, 0);                           
		analogWrite(blueLED, i);	//SAME FOR BLUE LED
		delay(100);
		analogWrite(blueLED, 0);                           
	}                       
}

Further exercises

As an exercise, you can extend the previous sketches or use the setup with the LEDs for new tasks:

  • The traffic light dims the LEDs up and down when changing state
  • The chaser turns on for 10 seconds at the push of the button
  • Program the flashing light of a police car
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.