Serial Debugging & Independent Loops with Arduino
Download serial_debugging.txt file
New terms: Serial.begin(), Serial.print(), Serial.println();
// Serial_Debugging
// Using serial.println to debug your code
//
// Arduino can talk back to the computer with information
// about itself using serial communications. This can be really
// handy for debugging your code by checking the value of certain
// variable while the Arduino is running.
// Set variables
int myVariable = 0;
// Setup
void setup()
{
//"Serial.begin(somenumber)" tells the Arduino to start using serial
// communications. You have to tell it what "baud" rate to use.
// "baud" (named after Emile Baudot, a pioneer in telecommuncations
// from the 19th century) is the speed at which the data flows over
// pins 0 and 1 between the Arduino board and the Arduino application.
// The baud rates must match each other to work. You set the baud rate
// in the Arduino application by clicking on the Serial Monitor button
// in the top menu in the application window and chosing the rate
// from the popup menu in the lower left of this screen. 9600 is a
// mid-range speed and is pretty reliable.
Serial.begin(9600);
}
// Loop
void loop()
{
//"Serial.print" and "Serial.println" tells the Arduino board to send
// the value of whatever is in its parenthesis to the Arduino application.
//"Serial.println" is like "Serial.print" except it adds a "line"
// each time its called.
Serial.print("The value of myVariable is: ");
Serial.println(myVariable);
myVariable = myVariable + 1;
}
Download delay-free_timing01.txt file
New concept: Adding a custom function, and millis()
// Delay-Free Timing 01
//
// The Arduino has a built in clock that gives out the number of
// milliseconds the Arduino has been running since the last reset
// (it actually is a finite number, and resets to 0 after about
// 9 hours and 32 minutes). We can use this number, millis(), to
// check how long it has been since something has happened, like
// the last time an LED was turned on. This can eliminate the bottleneck
// caused by the delay() command.
// Set variables
// Set up three timers, each with a different offset to check against.
long timer1 = 0; // Timers are measured in milliseconds,
// which quickly get quite large.
// We'll use "long" instead of "int"
// because int can only store a number
// from -32,768 to 32,768, or + or - 2
// to the 15th power, or 2 bytes.
// "long" extends the range to 4 bytes,
// or +/- 2,147,483,684
int timer1offset = 1000; // timer1offest will hold the length
// of time were using instead of a delay()
// Setup pins
int ledPin1 = 11;
void setup() { // The standard stuff...
Serial.begin(9600); // Setup the serial communications so
// we can debug
pinMode(ledPin1, OUTPUT);
timer1 = millis(); // Setting the timer to the milliseconds
// since the board was reset
}
// Das Loop...
void loop() {
// Timer 1
if((timer1 + timer1offset) < millis() ) {
// In other words, if timer1 plus an
// offset, say 123 + 1000, is less than
// the current time, say 1300,
// then the timer is finished, so do
// something and reset the timer to
// the current time.
doFlash(); // doFlash is a custom function we wrote
// ourselves, as opposed to a
// built-in command.
timer1 = millis();
}
}
// A new function!
void doFlash() {
Serial.println(digitalRead(ledPin1)); // Output the status to
// the serial port
digitalWrite(ledPin1, !digitalRead(ledPin1));
// This is a neat trick. "!" means "not"
// in Arduino language. When we say
// !digitalRead(ledPin1) we're saying
// "make this statement the opposite
// of what is says"
}
Download delay-free_timing02.txt file
New concept: multiple independent timers !!!
// Delay-Free Timing 02
//
// In this case, we will set up a bunch of independent timers
// Set variables
// Set up three timers, each with a different offset to check against.
long timer1 = 0; // "long" variables are a special kind of number, which
// takes up 4 bytes of space to store (where "int" only takes
// up 2 bytes). Range of numbers are from
// -2,147,483,648 to 2,147,483,647. If we left it just an
// "int" we would likely run out of numbers after only a
// couple of minutes. "long" can last for days of continuous
// running.
int timer1offset = 1000;
long timer2 = 0;
int timer2offset = 900;
long timer3 = 0;
int timer3offset = 800;
long timer4 = 0;
int timer4offset = 700;
long timer5 = 0;
int timer5offset = 600;
long timer6 = 0;
int timer6offset = 500;
// Setup pins
int ledPin1 = 11;
int ledPin2 = 10;
int ledPin3 = 9;
int ledPin4 = 8;
int ledPin5 = 7;
int ledPin6 = 6;
void setup() { // The standard stuff...
Serial.begin(9600); // Setup the serial communications so we can debug
// Save some vertical space by combining lines
pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT); pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT); pinMode(ledPin6, OUTPUT);
timer1 = millis(); timer2 = millis(); timer3 = millis();
timer4 = millis(); timer5 = millis(); timer6 = millis();
// Start with all pins on
digitalWrite(ledPin1,HIGH); digitalWrite(ledPin2,HIGH);
digitalWrite(ledPin3,HIGH); digitalWrite(ledPin4,HIGH);
digitalWrite(ledPin5,HIGH); digitalWrite(ledPin6,HIGH);
}
// Das Loop...
void loop() {
if((timer1 + timer1offset) < millis() ) { //Timer 1
doLED1();
timer1 = millis();
}
if((timer2 + timer2offset) < millis() ) { //Timer 2
doLED2();
timer2 = millis();
}
if((timer3 + timer3offset) < millis() ) { //Timer 3
doLED3();
timer3 = millis();
}
if((timer4 + timer4offset) < millis() ) { //Timer 4
doLED4();
timer4 = millis();
}
if((timer5 + timer5offset) < millis() ) { //Timer 5
doLED5();
timer5 = millis();
}
if((timer6 + timer6offset) < millis() ) { //Timer 6
doLED6();
timer6 = millis();
}
}
// The doLED functions
void doLED1() {
Serial.print("LED 1: ");
Serial.println(!digitalRead(ledPin1));
digitalWrite(ledPin1,!digitalRead(ledPin1));
}
void doLED2() {
Serial.print("LED 2: ");
Serial.println(!digitalRead(ledPin2));
digitalWrite(ledPin2,!digitalRead(ledPin2));
}
void doLED3() {
Serial.print("LED 3: ");
Serial.println(!digitalRead(ledPin3));
digitalWrite(ledPin3,!digitalRead(ledPin3));
}
void doLED4() {
Serial.print("LED 4: ");
Serial.println(!digitalRead(ledPin4));
digitalWrite(ledPin4,!digitalRead(ledPin4));
}
void doLED5() {
Serial.print("LED 5: ");
Serial.println(!digitalRead(ledPin5));
digitalWrite(ledPin5,!digitalRead(ledPin5));
}
void doLED6() {
Serial.print("LED 6: ");
Serial.println(!digitalRead(ledPin6));
digitalWrite(ledPin6,!digitalRead(ledPin6));
}
Reading Assignment
More Code Examples
Update to delay-free timing 03
Download delay-free_timing03.txt file
Adding arguments to functions
// Delay-Free Timing 03
//
// In this case, we will set up a bunch of independent timers
// And, we'll use only one function instead of 6!
// Set variables
// Set up three timers, each with a different offset to check against.
long timer1 = 0;
int timer1offset = 1000;
long timer2 = 0;
int timer2offset = 900;
long timer3 = 0;
int timer3offset = 800;
long timer4 = 0;
int timer4offset = 700;
long timer5 = 0;
int timer5offset = 600;
long timer6 = 0;
int timer6offset = 500;
// Setup pins
int ledPin1 = 11; // Note: needed to change the number of the pins
int ledPin2 = 10; // from Delay-Free Timing 02, but the idea is the same.
int ledPin3 = 9;
int ledPin4 = 6;
int ledPin5 = 5;
int ledPin6 = 3;
void setup() { // The standard stuff...
Serial.begin(9600); // Setup the serial communications so we can debug
// Save some vertical space by combining lines
pinMode(ledPin1, OUTPUT); pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT); pinMode(ledPin4, OUTPUT);
pinMode(ledPin5, OUTPUT); pinMode(ledPin6, OUTPUT);
timer1 = millis(); timer2 = millis(); timer3 = millis();
timer4 = millis(); timer5 = millis(); timer6 = millis();
// Start with all pins on
digitalWrite(ledPin1,HIGH); digitalWrite(ledPin2,HIGH);
digitalWrite(ledPin3,HIGH); digitalWrite(ledPin4,HIGH);
digitalWrite(ledPin5,HIGH); digitalWrite(ledPin6,HIGH);
}
// Das Loop...
void loop() {
if((timer1 + timer1offset) < millis() ) { //Timer 1
doLED(ledPin1);
timer1 = millis();
}
if((timer2 + timer2offset) < millis() ) { //Timer 2
doLED(ledPin2);
timer2 = millis();
}
if((timer3 + timer3offset) < millis() ) { //Timer 3
doLED(ledPin3);
timer3 = millis();
}
if((timer4 + timer4offset) < millis() ) { //Timer 4
doLED(ledPin4);
timer4 = millis();
}
if((timer5 + timer5offset) < millis() ) { //Timer 5
doLED(ledPin5);
timer5 = millis();
}
if((timer6 + timer6offset) < millis() ) { //Timer 6
doLED(ledPin6);
timer6 = millis();
}
}
// The doLED functions
void doLED(int whichLED) {
Serial.print("LED");Serial.print(whichLED);Serial.print(": ");
Serial.println(!digitalRead(whichLED));
digitalWrite(whichLED,!digitalRead(whichLED));
}
Timer/ Fader
Download timer-fader01.txt file
// Timer/Fader 01
//
// A delay-free timer for a single LED that fades in and out
// Timer variables
long timer = 0;
int offset = 10; // Change this for faster or slower fades
// Pin variable
int pwm = 11;
// Direction variable
int upDown = 1;
// pwm value holding variable
int val1 = 0;
//Setup
void setup() { // The standard stuff...
Serial.begin(9600); // Setup the serial communications so
// we can debug
pinMode(pwm, OUTPUT);
timer = millis();
}
// Das Loop...
void loop() {
// Timer
if((timer + offset) < millis() ) {
doFade();
timer = millis();
}
}
// Fade function
void doFade() {
if(val1 >= 50) { upDown = -1; } // The LED on my board only appears to
// be getting brighter on pwm values up
if(val1 <= 0) { upDown = 1; } // to 50 (out of 255) so, I've set the
val1 = val1 + ( 1 * upDown); // max value to change the direction
analogWrite(pwm, val1); // to 50.
}
Download timer-fader02.txt file
Working with boolean flags
// Timer/Fader 02 // // A delay-free timer for a single LED that fades in and out // and cascades 6 faders // Timer variables long timer1 = 0; long timer2 = 0; long timer3 = 0; long timer4 = 0; long timer5 = 0; long timer6 = 0; int offset = 10; // Change this for faster or slower fades // Pin variables int pwm1 = 11; int pwm2 = 10; int pwm3 = 9; int pwm4 = 6; int pwm5 = 5; int pwm6 = 3; // Direction variable int upDown1 = 1; int upDown2 = 1; int upDown3 = 1; int upDown4 = 1; int upDown5 = 1; int upDown6 = 1; // pwm value holding variable int val1 = 1; int val2 = 1; int val3 = 1; int val4 = 1; int val5 = 1; int val6 = 1; // flag variables boolean flag1 = 0; boolean flag2 = 0; boolean flag3 = 0; boolean flag4 = 0; boolean flag5 = 0; boolean flagDoOver = 0; //Setup void setup() { // The standard stuff... Serial.begin(9600); // Setup the serial communications so // we can debug pinMode(pwm1,OUTPUT); pinMode(pwm2,OUTPUT); pinMode(pwm3,OUTPUT); pinMode(pwm4,OUTPUT); pinMode(pwm5,OUTPUT); pinMode(pwm6,OUTPUT); timer1 = millis(); } // Das Loop... void loop() { // Timer if( (timer1 + offset) < millis() ) { doFade1(); timer1 = millis(); } if(flagDoOver) { resetFade(); } } // Reset Fade Function void resetFade() { Serial.println("Resetting fade..."); // pwm value variables val1 = 1; val2 = 1; val3 = 1; val4 = 1; val5 = 1; val6 = 1; // Direction variables upDown1 = 1; upDown2 = 1; upDown3 = 1; upDown4 = 1; upDown5 = 1; upDown6 = 1; // flag variables flag1 = 0; flag2 = 0; flag3 = 0; flag4 = 0; flag5 = 0; flagDoOver = 0; } // Fade function void doFade1() { if(val1 >= 70) { upDown1 = -1; } if(val1 <= 0) { upDown1 = 0; } if(val1 == 30) { flag1 = 1; } val1 = val1 + ( 1 * upDown1); analogWrite(pwm1, val1); if(flag1) { if(val2 >= 70) { upDown2 = -1; } if(val2 <= 0) { upDown2 = 0; } if(val2 == 30) { flag2 = 1; } val2 = val2 + ( 1 * upDown2); analogWrite(pwm2, val2); } if(flag2) { if(val3 >= 70) { upDown3 = -1; } if(val3 <= 0) { upDown3 = 0; } if(val3 == 30) { flag3 = 1; } val3 = val3 + ( 1 * upDown3); analogWrite(pwm3, val3); } if(flag3) { if(val4 >= 70) { upDown4 = -1; } if(val4 <= 0) { upDown4 = 0; } if(val4 == 30) { flag4 = 1; } val4 = val4 + ( 1 * upDown4); Serial.println(val4); analogWrite(pwm4, val4); } if(flag4) { if(val5 >= 70) { upDown5 = -1; } if(val5 <= 0) { upDown5 = 0; } if(val5 == 30) { flag5 = 1; } val5 = val5 + ( 1 * upDown5); analogWrite(pwm5, val5); } if(flag5) { if(val6 >= 70) { upDown6 = -1; } if(val6 <= 0) { upDown6 = 0; flagDoOver = 1; } val6 = val6 + ( 1 * upDown6); analogWrite(pwm6, val6); } }
Adding Interactivity
Adds interactivity with a potentiometer
// Interactive Potentiometer Control
//
// An example of using analogRead and a potentiometer
// to control the how many LED's are on, as in a
// meter of some kind
// LED Variables
int ledPin1 = 11; int ledPin2 = 10; int ledPin3 = 9;
int ledPin4 = 8; int ledPin5 = 7; int ledPin6 = 6;
int ledPin7 = 5; int ledPin8 = 4; int ledPin9 = 3;
int ledPin10 = 2;
// Poteniometer variable
int potPin = 0;
// Value holder for potentiometer
int potVal = 0;
// Hook the Pot up like this:
// Analog Pin -----¡
// |
// V
// +5V ---------^v^v^v-------- GND
// pot
void setup() {
Serial.begin(9600); // Setup the Serial port
for(int i=2; i<12; i++) { // Do a for loop to set pins 2 thru 10
Serial.println(i);
pinMode(i, OUTPUT); // to OUTPUT
}
}
void loop() {
potVal = analogRead(potPin);
Serial.println(potVal);
if(potVal > 102) {
digitalWrite(ledPin1,HIGH);
}else{
digitalWrite(ledPin1,LOW);
}
if(potVal > 205) {
digitalWrite(ledPin2,HIGH);
}else{
digitalWrite(ledPin2,LOW);
}
if(potVal > 307) {
digitalWrite(ledPin3,HIGH);
}else{
digitalWrite(ledPin3,LOW);
}
if(potVal > 410) {
digitalWrite(ledPin4,HIGH);
}else{
digitalWrite(ledPin4,LOW);
}
if(potVal > 512) {
digitalWrite(ledPin5,HIGH);
}else{
digitalWrite(ledPin5,LOW);
}
if(potVal > 614) {
digitalWrite(ledPin6,HIGH);
}else{
digitalWrite(ledPin6,LOW);
}
if(potVal > 717) {
digitalWrite(ledPin7,HIGH);
}else{
digitalWrite(ledPin7,LOW);
}
if(potVal > 819) {
digitalWrite(ledPin8,HIGH);
}else{
digitalWrite(ledPin8,LOW);
}
if(potVal > 922) {
digitalWrite(ledPin9,HIGH);
}else{
digitalWrite(ledPin9,LOW);
}
if(potVal > 1020) {
digitalWrite(ledPin10,HIGH);
}else{
digitalWrite(ledPin10,LOW);
}
}
// Interactive Photosensor Control
//
// An example of using analogRead and a photoresistor
// to control the how many LED's are on, as in a
// meter of some kind
// LED Variables
int ledPin1 = 11; int ledPin2 = 10; int ledPin3 = 9;
int ledPin4 = 8; int ledPin5 = 7; int ledPin6 = 6;
int ledPin7 = 5; int ledPin8 = 4; int ledPin9 = 3;
int ledPin10 = 2;
// Poteniometer variable
int photoPin = 1;
// Value holder for potentiometer
int photoVal = 1;
// Hook the photoresistor up like this:
// Photo R 10K
// +5V o---/\/\/\--.--/\/\/\---o GND
//
// Depending on your setup, there will be a high and low value range
// You can use them to set the limits of your meter display
int photoMin = 700;
int photoMax = 1020;
void setup() {
Serial.begin(9600); // Setup the Serial port
for(int i=2; i<12; i++) { // Do a for loop to set pins 2 thru 10
pinMode(i, OUTPUT); // to OUTPUT
}
}
void loop() {
photoVal = analogRead(photoPin);
Serial.println(photoVal);
int photoRange = photoMax - photoMin; // Get the range of numbers
if(photoVal > photoMin + (photoRange/10)) {
digitalWrite(ledPin1,HIGH);
}else{
digitalWrite(ledPin1,LOW);
}
if(photoVal > photoMin + ((photoRange/10)*2)) {
digitalWrite(ledPin2,HIGH);
}else{
digitalWrite(ledPin2,LOW);
}
if(photoVal > photoMin + ((photoRange/10)*3)) {
digitalWrite(ledPin3,HIGH);
}else{
digitalWrite(ledPin3,LOW);
}
if(photoVal > photoMin + ((photoRange/10)*4)) {
digitalWrite(ledPin4,HIGH);
}else{
digitalWrite(ledPin4,LOW);
}
if(photoVal > photoMin + ((photoRange/10)*5)) {
digitalWrite(ledPin5,HIGH);
}else{
digitalWrite(ledPin5,LOW);
}
if(photoVal > photoMin + ((photoRange/10)*6)) {
digitalWrite(ledPin6,HIGH);
}else{
digitalWrite(ledPin6,LOW);
}
if(photoVal > photoMin + ((photoRange/10)*7)) {
digitalWrite(ledPin7,HIGH);
}else{
digitalWrite(ledPin7,LOW);
}
if(photoVal > photoMin + ((photoRange/10)*8)) {
digitalWrite(ledPin8,HIGH);
}else{
digitalWrite(ledPin8,LOW);
}
if(photoVal > photoMin + ((photoRange/10)*9)) {
digitalWrite(ledPin9,HIGH);
}else{
digitalWrite(ledPin9,LOW);
}
if(photoVal >= photoMax) {
digitalWrite(ledPin10,HIGH);
}else{
digitalWrite(ledPin10,LOW);
}
}
