7.0 Advanced Programming Concepts
As developers move beyond basic sketches, they encounter scenarios that require handling asynchronous events or introducing non-predictive behavior. A program that simply executes line-by-line in a loop cannot efficiently respond to sudden, time-critical inputs. Interrupts provide a mechanism to handle these events, while random number generation is key for creating applications with less predictable, more dynamic behavior.
7.1 Interrupts
An interrupt is a mechanism that temporarily stops the main program execution to handle a high-priority event. Think of it like a telephone call: you might be busy with a task (the main program), but when the phone rings (the interrupt), you stop what you are doing to answer it (the interrupt service routine). Once the call is finished, you resume your original task from where you left off.
Interrupts are handled by a special function called an Interrupt Service Routine (ISR). Because an ISR halts all other program activity, it should be kept as short and fast as possible.
- Variables shared between an ISR and the main program must be declared with the volatile keyword to ensure they are updated correctly.
- Most Arduino boards (like the UNO) have two external hardware interrupt pins: digital pins 2 and 3. The Arduino Mega has six (pins 2, 3, 18, 19, 20, 21).
The attachInterrupt() function is used to configure an interrupt.
- Syntax:
- Parameters:
- digitalPinToInterrupt(pin): Translates the pin number (e.g., 2) into the specific interrupt number required by the function.
- ISR: The name of the function to call when the interrupt occurs. This function must take no parameters and return nothing.
- mode: Defines when the interrupt should be triggered.
- LOW: Triggers the interrupt whenever the pin is low.
- CHANGE: Triggers whenever the pin changes value (from HIGH to LOW or LOW to HIGH).
- FALLING: Triggers when the pin goes from HIGH to LOW.
Example Sketch: This sketch toggles the state of the onboard LED (pin 13) every time a change is detected on interrupt pin 2.
int pin = 2; //define interrupt pin to 2
volatile int state = LOW; // To make sure variables shared between an ISR
// the main program are updated correctly, declare them as volatile.
void setup() {
pinMode(13, OUTPUT); //set pin 13 as output
attachInterrupt(digitalPinToInterrupt(pin), blink, CHANGE); //interrupt at pin 2
}
void loop() {
digitalWrite(13, state); //pin 13 equal the state value
}
void blink() { //ISR function
state = !state; //toggle the state when the interrupt occurs
}
7.2 Generating Random Numbers
Arduino provides two functions for generating pseudo-random numbers, which are useful for games, simulations, and creating unpredictable behavior.
- randomSeed(seed): This function initializes the pseudo-random number generator. Because the sequence of numbers generated by random() is predictable, randomSeed() should be used to “shuffle” the generator with a truly random starting point. A common practice is to use the noise from an unconnected analog pin as the seed.
- random(max) and random(min, max): This function generates a random number within a specified range.
- random(max) returns a random number between 0 and max – 1.
- random(min, max) returns a random number between min and max – 1.
Example Sketch: This sketch generates and prints random numbers to the Serial Monitor.
long randNumber;
void setup() {
Serial.begin(9600);
// Using noise from an unconnected analog pin to seed the generator
randomSeed(analogRead(0));
}
void loop() {
// Print a random number from 0 to 299
randNumber = random(300);
Serial.println(randNumber);
// Print a random number from 10 to 19
randNumber = random(10, 20);
Serial.println(randNumber);
delay(50);
}
After mastering advanced programming logic, the final step is to learn how the Arduino communicates with other devices.