Difference between revisions of "Arduino Programming Fundamentals"

From Interaction Station Wiki
Jump to navigation Jump to search
Line 122: Line 122:
  
 
= Beyond the delay() =  
 
= Beyond the delay() =  
== A Scheduler ==
+
== Blink without delay ==
 
 
A scheduler is like writing down a list of when you are going to do something and a state machine is like keeping a record of how far through a task you have got.
 
 
 
If you use the function delay(1000) then the processor goes away and does nothing for one second. We say this delay() is a blocking function, that is it blocks further activity in the program. So in order for our code to do something whilst waiting for the delay time to expire, what we need is a scheduler, something that will call a specific task at a specific time. There are several ways to do this but this is perhaps the simplest.
 
To make a scheduler we need to call on the aide of the system clock. This keeps on ticking every millisecond and we can access the current tick count with the millis() function.
 
<br>
 
What we need to do is to set up a variable called say goTime that contains the time in milliseconds when we need to do the next operation. That is made from simply the time now plus how long from now you want to do the next operation. Then all we do in the main loop is check if it is time to do our operation and if it is do it. Finally before we exit that routine we need to set our variable goTime to reflect when we want to do it again.
 
<br>
 
  
 
<syntaxhighlight lang=c style="border:3px dashed orange">
 
<syntaxhighlight lang=c style="border:3px dashed orange">
  
//Start with the definition of a variable that determines how often we want to do our task
+
const int ledPin =  13;      // the number of the LED pin
int nextTime = 1000; // Do this every second or 1000 milliseconds
+
 
+
// Variables will change:
long int goTime;
+
int ledState = LOW;             // ledState used to set the LED
 
+
long previousMillis = 0;       // will store last time LED was updated
 
+
 
+
// the follow variables is a long because the time, measured in miliseconds,
void setup(){
+
// will quickly become a bigger number than can be stored in an int.
//Then in the setup we initialise the variable goTime to be the same value as the system clock
+
long interval = 1000;          // interval at which to blink (milliseconds)
goTime = millis();
+
 
+
void setup() {
}
+
  // set the digital pin as output:
 
+
  pinMode(ledPin, OUTPUT);    
 
 
 
 
void loop(){
 
//In the main loop all we do is check if it is time to do our function
 
//it will be time when the current time given by millis() is greater or equal to the time we want to fire things off
 
if(millis() >= goTime) functionGo();
 
 
 
 
}
 
}
 
+
 
+
void loop()
 
+
{
void functionGo(){
+
  // here is where you'd put code that needs to be running all the time.
 
+
//do what we want
+
  // check to see if it's time to blink the LED; that is, if the
//nothing happens here...its a placeholder:)
+
  // difference between the current time and last time you blinked
 
+
  // the LED is bigger than the interval at which you want to
goTime = millis() + nextTime; // set when to do it again
+
  // blink the LED.
 
+
  unsigned long currentMillis = millis();
 +
 +
  if(currentMillis - previousMillis > interval) {
 +
    // save the last time you blinked the LED
 +
    previousMillis = currentMillis; 
 +
 +
    // if the LED is off turn it on and vice-versa:
 +
    if (ledState == LOW)
 +
      ledState = HIGH;
 +
    else
 +
      ledState = LOW;
 +
 +
    // set the LED with the ledState of the variable:
 +
    digitalWrite(ledPin, ledState);
 +
  }
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
  
 +
As overly complicate as it seems, Blink without delay illustrates a very important concept known as a State Machine
  
 
== A State Machine ==
 
== A State Machine ==

Revision as of 09:17, 3 December 2018

Functions

In computer science, a subroutine or subprogram (also called procedure, method, function, or routine) is a portion of code within a larger program, which performs a specific task and is relatively independent of the remaining code.
A function is a way for programmers to reuse code without having to rewrite it, this is time saving, and often makes code more readable.
what we need to have a function:
1) each function must have a unique name
2) the function name is followed by parentheses()
3) functions have a return type, e.g. void
4) the body of a function is enclosed in opening and closing braces {}


Lets do a very simple example to see how it works

void setup() {
  Serial.begin(9600);
  
  DashedLine(); //here we are calling the function
  Serial.println("| BONJOUR |");
  DashedLine(); //here we call it again
}

void loop() {
}

void DashedLine() //here is where we create the function
{
  Serial.println("----------------");
}

Passing a value to a function

and a bit of for loop

void setup() {

  Serial.begin(9600);
  
  // draw the menu box
  DashedLine(24);
  Serial.println("| Program Options Menu |");
  DashedLine(24);
}

void loop() {
}
//a function needs to be able to accept an integer value that is passed to it, 
//the variable type and the name of the variable 
//are inserted between the opening an closing parentheses after the function name

void DashedLine(int len) 
{
  int i;
  
  // draw the line
  //The body of the sketch uses the len variable in a for loop 
  //to print out the correct number of dashes that make up the dashed line of the menu box
  for (i = 0; i < len; i++) {
    Serial.print("-");
  }
  // move the cursor to the next line
  Serial.println("");
}


let's try it with our usual Hello World blink

  pinMode(13, OUTPUT);
}
 
// the loop function runs over and over again forever
void loop() {
  blinkLed();
}
 
void blinkLed() {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}


now we can reuse the function multiple times

In this example, we’ll add a parameter to the function to allow the function to vary the speed of the blink

void setup() {
  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);
}
 
// the loop function runs over and over again forever
void loop() {
  blinkLed(200);
}
 
void blinkLed(int delayTime) {
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(delayTime);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
  delay(delayTime);              // wait for a second
}

Arrays and the for loop

Beyond the delay()

Blink without delay

const int ledPin =  13;      // the number of the LED pin
 
// Variables will change:
int ledState = LOW;             // ledState used to set the LED
long previousMillis = 0;        // will store last time LED was updated
 
// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)
 
void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);      
}
 
void loop()
{
  // here is where you'd put code that needs to be running all the time.
 
  // check to see if it's time to blink the LED; that is, if the 
  // difference between the current time and last time you blinked 
  // the LED is bigger than the interval at which you want to 
  // blink the LED.
  unsigned long currentMillis = millis();
 
  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   
 
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
 
    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}


As overly complicate as it seems, Blink without delay illustrates a very important concept known as a State Machine

A State Machine

A ‘state’ is the condition of a thing at a specific time. Something that can accomplish tasks and that utilizes states at its core is a state machine. They are also known as Finite State Machines (FSM), meaning that we know all possible states of the thing. The key to the state machine is the concept of time and history. The state of the machine is evaluated periodically. Each time it is evaluated, a new state is chosen (which could be the same state again), and the output is presented.

int ledPin =  13;      // the number of the LED pin
int ledState = LOW;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
long OnTime = 500;           // milliseconds of on-time
long OffTime = 500;          // milliseconds of off-time

void setup() 
{
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);      
}

void loop()
{
  // check to see if it's time to change the state of the LED
  unsigned long currentMillis = millis();
  unsigned long elapsed = currentMillis - previousMillis;  // elapsed is the time since the end of the last cycle

  if((ledState == HIGH) && (elapsed >= OnTime))
  {
    ledState = LOW;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    digitalWrite(ledPin, ledState);  // Update the actual LED
  }
  else if ((ledState == LOW) && (elapsed >= OffTime))
  {
    ledState = HIGH;  // turn it on
    previousMillis = currentMillis;   // Remember the time
    digitalWrite(ledPin, ledState);    // Update the actual LED
  }
}