Part 3 - Using our own function

For this exercise we will use the same circuit as last time.

Using the Arduino language we can encapsulate our own function and call it from within the main loop. This can be very helpful in the layout of our code, simplify things greatly and allow us to reuse code, hence saving memory. For example, upload the code below and have a look at what it does. It makes use of a 'for' loop to fade our LED, have a look at the Arduino reference for the 'for statement' here. You can also pass a function values and use 'return' to get values back, more about using functions with Arduino here.  

/*  
 *   This sketch simply demonstartes how to create 
 *   your own function and call it within the main loop
 *  
 *  Luke Woodbury 11 January 2017
 *  dotLib.org
 *  
 */

//these are constants, they won't change
const int redPin = 10;  //the LED pins
const int grnPin = 6;
const int bluPin = 9;

void setup() {
  // declare the LED pins OUTPUTs
  pinMode(redPin, OUTPUT);
  pinMode(grnPin, OUTPUT);
  pinMode(bluPin, OUTPUT);
}

void loop() {
  //just run the LEDanimate function
  LEDanimate();
  //half a second delay
  delay(500);
}

//we have created our own function to animate
//the LEDs which we can call in the main loop
void LEDanimate(){
  //use a for loop to fade red up
  for (int i = 0; i<256; i++){
    analogWrite(redPin, i);
    delay(2);
  }
  //use a for loop to fade red down
  for (int i=255; i>0; i--){
    analogWrite(redPin, i);
    delay(1);
  }
  delay(250);
  digitalWrite(bluPin, HIGH);
  delay(250);
  digitalWrite(bluPin, LOW);
  digitalWrite(grnPin, HIGH);
  delay(250);
  for (int i=255; i>0; i--){
    analogWrite(grnPin, i);
    delay(1);
  }
}

 

  • Copy the code here and paste it into the Arduino IDE, it is a way to use a pot input as a colour mixer for an RGB LED
  • Change the pin numbers, upload and test
  • Now put the contents of the main loop into a function of its own, name it 'LEDanimate' and call it from within the main loop, test it works 
  • Now comes the tricky part... We want to ditch the pot and use the button to cycle through the 0-1023 value that the pot would have done.
  • Look at the 'Button' sketch in 'File > Examples > 02.Digital' section, you should be able to work out how to set up the pins and check the button state, you will need to incorporate this into your colour mixer sketch.
  • You will want to start a for loop to create a value from 0-1023 if the button is pressed, allocate it to potVal and run the 'LEDanimate' function. Before the loop finishes, you will want to to check the button state again, if it has been released then you will want to quit the for loop. In order to do this you should have a look at the 'break' function

+ Hint 1


Bring in the button pin constant and state variable, initialise the pin as an input in the setup and copy the ' if (buttonState == HIGH) { }' line into your main loop.

+ Hint 2


We want to start a for loop within our button check 'if'. It should:

  • count from 0 - 1023
  • replace potVal with our 'i' value
  • call 'LEDanimate'
  • do another digitalRead and store the result in buttonState
  • nest another 'if' to create a 'break' if the button is released

+ The solution


As usual, TIMTOWTDI:

/*
 * We have adapted Clay Shirky's colour mixer
 * code: https://www.arduino.cc/en/Tutorial/ColorMixer
 * and created a function out of it. We use a button
 * and a for loop to generate a value to send to it
 * in the place of the pot value.
 * 
 * Luke Woodbury 11 Jan 2017
 * dotLib.org
 * 
*/

int potVal = 0; // previously stored pot val, now used 

//LED pins
const int redPin = 10; 
const int grnPin = 6;  
const int bluPin = 9;  

// Program variables to store values
int redVal = 0;
int grnVal = 0;
int bluVal = 0;

//button pin and variable to store state
const int buttonPin = 12;
int buttonState = 0; 

void setup()
{
  pinMode(redPin, OUTPUT);   // sets the pins as output
  pinMode(grnPin, OUTPUT);   
  pinMode(bluPin, OUTPUT); 

  pinMode(buttonPin, INPUT);  //...and input
}


void loop(){
  //check the button state
  buttonState = digitalRead(buttonPin);
  //if it is pressed do something
  if (buttonState == HIGH){
    for (int i=0; i<1024; i++){
      //replace potVal with i value
      potVal = i;
      //call our LED function
      LEDanimate();
      //check the button state again
      buttonState = digitalRead(buttonPin);
      //if the button is released, quit the for loop
      if (buttonState == LOW){
        break;
      }
      delay(2);
    }
  }
  
}

void LEDanimate(){
  //we no longer need this next line so comment it out or delete
  //potVal = analogRead(potPin);  //read pot

  if (potVal < 341)  // Lowest third of the pot range (0-340)
  {                  
    potVal = (potVal * 3) / 4; // Normalize to 0-255

    redVal = 256 - potVal;  // Red from full to off
    grnVal = potVal;        // Green from off to full
    bluVal = 1;             // Blue off
  }
  else if (potVal < 682) // Middle third of pot range (341-681)
  {
    potVal = ( (potVal-341) * 3) / 4; // Normalize to 0-255

    redVal = 1;            // Red off
    grnVal = 256 - potVal; // Green from full to off
    bluVal = potVal;       // Blue from off to full
  }
  else  // Upper third of potentiometer"s range (682-1023)
  {
    potVal = ( (potVal-683) * 3) / 4; // Normalize to 0-255

    redVal = potVal;       // Red from off to full
    grnVal = 1;            // Green off
    bluVal = 256 - potVal; // Blue from full to off
  }
  analogWrite(redPin, redVal);   // Write values to LED pins
  analogWrite(grnPin, grnVal); 
  analogWrite(bluPin, bluVal);  
  
}

<Previous            Next >