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); }