Hassan S. Arduino Programming Essentials. A Practical Handbook...2024
Hassan S. Arduino Programming Essentials. A Practical Handbook...2024
First Edition
Enhance Your Programming Knowledge
By Sarful Hassan, MechatronicsLAB
Preface
Welcome to Arduino Programming Essentials, where you'll find everything
you need to get started with Arduino programming and beyond. Whether
you're new to Arduino or looking to refine your skills, this book is designed
to guide you through essential concepts, functions, and real-world
applications in a clear, structured manner.
Who This Book Is For
This book is for anyone interested in learning Arduino programming,
regardless of their background. It is particularly useful for:
● Students and hobbyists new to Arduino
● Engineers and designers looking to prototype projects
● Educators seeking teaching materials for Arduino programming
● Professionals in robotics, automation, or IoT (Internet of Things)
No prior programming or electronics experience is required. All you
need is curiosity and the willingness to learn by doing.
How This Book Is Organized
This book is structured to gradually introduce key programming concepts
and functions in Arduino, starting from the basics and building toward
more advanced topics. Here's an overview of the chapters:
1. Introduction to Arduino
Learn the basics of what Arduino is, how it works, and how to
set up your environment.
2. Understanding the Arduino IDE
Explore the Integrated Development Environment (IDE) for
writing and uploading code to your Arduino board.
3. Basic Functions for Digital and Analog Input/Output
Dive into foundational functions like digitalRead() ,
digitalWrite() , analogRead() , and analogWrite() that are
essential for controlling components and sensors.
4. Control Structures
Learn how to use loops, conditionals, and functions to make your
programs more efficient.
5. Working with Sensors
Interface with sensors to read environmental data such as
temperature, humidity, light, etc.
6. Actuators and Outputs
Control motors, LEDs, and other output devices to build
interactive systems.
7. Advanced Topics
Explore more advanced topics like communication between
multiple Arduinos, wireless modules, and Internet of Things (IoT)
projects.
Disclaimer
The information contained in this book is provided on an “as-is” basis
without any warranties of any kind, either express or implied. While
every effort has been made to ensure the accuracy and completeness of
the information in this book, the author and publisher are not liable for
any errors, omissions, or inaccuracies. Readers are advised to use the
content responsibly and apply caution when working with electronics
and electrical components. Always refer to the latest safety guidelines
and consult product documentation before proceeding with any Arduino
projects or experiments.
The examples provided in this book are for educational purposes only.
The author and publisher are not responsible for any damages, injuries,
or losses that may arise from the use of the materials in this book,
whether in personal or professional contexts.
digitalRead(pin)
Parameters:
● pin: The digital pin you want to read.
Example Code:
Explanation:
This program reads the button state connected to pin 7. If the button is
pressed (HIGH), the LED connected to pin 13 turns on. If the button is
not pressed (LOW), the LED turns off.
Real-Life Application: Reading a Button State to Control an LED
Component List:
● Arduino Uno or Nano
● LED
● Resistor
● Pushbutton
● Breadboard
● Jumper wires
● USB cable
● Computer with Arduino IDE
Circuit Connection:
● Connect the LED to pin 13 with a resistor in series.
● Connect the pushbutton to pin 7, ensuring one side is connected to
ground.
Code:
Explanation:
This program turns the LED on or off based on the button's state. When
the button is pressed, the LED lights up.
Practical Exercise:
● Modify the code to turn on the LED only when the button is pressed
and turn it off when released.
● Experiment with adding more buttons to control multiple outputs.
Hints:
Make sure the pin you’re reading from is either connected to a pull-up or
pull-down resistor to avoid random values from an unconnected pin.
You can also use the analog pins as digital pins.
digitalWrite(pin, value)
Parameters:
● pin: The number of the pin you want to control.
● value: Either HIGH (turn on) or LOW (turn off).
Example Code:
void setup() {
pinMode(13, OUTPUT); // Set pin 13 as an output
}
void loop() {
digitalWrite(13, HIGH); // Turn on pin 13 (LED on)
delay(1000); // Wait 1 second
digitalWrite(13, LOW); // Turn off pin 13 (LED off)
delay(1000); // Wait 1 second
}
Explanation:
This code turns an LED connected to pin 13 on for 1 second and off for
1 second. It repeats this forever.
void setup() {
pinMode(13, OUTPUT); // Set pin 13 as output
}
void loop() {
digitalWrite(13, HIGH); // Turn on LED
delay(500); // Wait half a second
digitalWrite(13, LOW); // Turn off LED
delay(500); // Wait half a second
}
Explanation:
The LED will blink on and off every half a second using the
digitalWrite() function.
Practical Exercise:
● Try controlling two LEDs on different pins using digitalWrite().
● Change the delay to make the LED blink faster or slower.
Hints:
Always remember to use pinMode() to set a pin as OUTPUT before
using digitalWrite(), or the pin might not work as expected.
pinMode(pin, mode)
Parameters:
● pin: The pin number to set up.
● mode: INPUT, OUTPUT, or INPUT_PULLUP.
Example:
void setup() {
pinMode(13, OUTPUT); // Set pin 13 as an output
}
void loop() {
digitalWrite(13, HIGH); // Turn on pin 13 (LED on)
delay(1000); // Wait 1 second
digitalWrite(13, LOW); // Turn off pin 13 (LED off)
delay(1000); // Wait 1 second
}
Explanation:
This code sets pin 13 as an OUTPUT and then turns the LED on and off
every second.
Code:
int buttonPin = 7;
int ledPin = 13;
void setup() {
pinMode(buttonPin, INPUT); // Set pin 7 as input for button
pinMode(ledPin, OUTPUT); // Set pin 13 as output for LED
}
void loop() {
int buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
digitalWrite(ledPin, HIGH); //
} else {
digitalWrite(ledPin, LOW); //
}
}
Explanation:
This program reads a pushbutton connected to pin 7 and turns on an
LED on pin 13 when the button is pressed.
Practical Exercise:
● Try setting up multiple pins with pinMode() for controlling multiple
devices, like several LEDs.
● Experiment with using INPUT_PULLUP for buttons and see how it
works compared to INPUT.
Hints:
Use pinMode() to configure each pin before you use it with
digitalRead() or digitalWrite(). You can even use analog pins as digital
pins (e.g., A0).
analogRead(pin)
Parameters:
● pin: The analog pin you are reading from (e.g., A0, A1, etc.).
Example:
Explanation:
This code reads the analog value from pin A3 and prints it to the Serial
Monitor. The value will be between 0 and 1023, depending on the input
voltage.
Code:
Explanation:
This program reads a sensor connected to A0 and prints the value to the
Serial Monitor every second.
Practical Exercise:
● Try connecting different analog sensors (e.g., temperature or light
sensors) to the analog pins.
● Modify the code to convert the analog reading to voltage (multiply
the reading by 5.0 / 1023 to get the voltage).
Hints:
If nothing is connected to the analog pin, the analogRead() value will
fluctuate randomly. Always ensure a proper connection when reading
sensor values.
5 The analogReadResolution()
The analogReadResolution() function changes the size (in bits) of the
value returned by analogRead(). Normally, Arduino reads analog input
in 10 bits (values between 0 and 1023), but on some boards, you can
increase the resolution up to 12 bits (values between 0 and 4095) or
even 16 bits on certain advanced boards.
Where to Use:
Use analogReadResolution() when you need more accuracy from the
analogRead() function on boards that support higher resolutions, such as
Arduino Zero, Due, MKR Family, or Portenta.
Why It’s Useful:
This function is important for projects that need more precise sensor
readings. Instead of being limited to a range of 0-1023, you can read
values with much finer detail, like 0-4095 or even up to 0-65535 on
advanced boards.
Syntax:
analogReadResolution(bits)
Parameters:
● bits: The number of bits for the resolution (1 to 32). Most boards
support 10, 12, or 16 bits.
Example:
void setup() {
Serial.begin(9600);
}
void loop() {
// Read analog pin A0 with 10-bit resolution
analogReadResolution(10);
Serial.print("10-bit: ");
Serial.print(analogRead(A0));
// Read analog pin A0 with 12-bit resolution
analogReadResolution(12);
Serial.print(", 12-bit: ");
Serial.print(analogRead(A0));
// Read analog pin A0 with 16-bit resolution
analogReadResolution(16);
Serial.print(", 16-bit: ");
Serial.println(analogRead(A0));
delay(1000);
}
Explanation:
This program reads the value from A0 using different resolutions (10-bit,
12-bit, and 16-bit) and prints the result. The higher the bit resolution, the
more detailed the reading.
Code:
Explanation:
This program reads a sensor using 12-bit resolution, providing more
detailed values than the default 10-bit reading.
Practical Exercise:
● Try using different resolutions (e.g., 10-bit, 12-bit, 16-bit) and see
how the sensor readings change.
● Use the analogReadResolution() function to improve the precision
of sensor data for more accurate measurements.
Hints:
If you set a resolution higher than your board’s capability, the board will
pad the extra bits with zeros. If you set a resolution lower than the board
supports, some data will be lost.
Parameters:
● pin: The pin number where you want to send the signal.
● value: The duty cycle value (between 0 and 255). A value of 0 means
the pin is always off, while 255 means it’s always on.
Example:
Explanation:
This code reads the value from a potentiometer connected to A0 and
uses analogWrite() to dim or brighten an LED connected to pin 9. The
analogRead() function returns values between 0 and 1023, so we divide
by 4 to match the analogWrite() range of 0 to 255.
Code:
Explanation:
This program adjusts the speed of a motor connected to pin 9 based on
the position of a potentiometer connected to A0. The higher the value
from the potentiometer, the faster the motor spins.
Practical Exercise:
● Try connecting an LED and a motor to control both brightness and
speed using analogWrite().
● Experiment with different PWM pins to control multiple devices.
Hints:
● You don’t need to call pinMode() for PWM pins; analogWrite()
automatically sets the pin as an OUTPUT.
● Avoid using pins 5 and 6 for low duty cycles (near 0), as they might
not fully turn off due to interactions with other timers.
analogWriteResolution(bits)
Parameters:
● bits: The number of bits (from 1 to 32) for the resolution. The
maximum supported resolution depends on your board.
Example:
void setup() {
Serial.begin(9600);
pinMode(11, OUTPUT); // Set pin 11 as output
pinMode(12, OUTPUT); // Set pin 12 as output
pinMode(13, OUTPUT); // Set pin 13 as output
}
void loop() {
int sensorVal = analogRead(A0); // Read analog input
// Set PWM resolution to 8 bits (0-255)
analogWriteResolution(8);
analogWrite(11, map(sensorVal, 0, 1023, 0, 255));
Serial.print("8-bit PWM: ");
Serial.print(map(sensorVal, 0, 1023, 0, 255));
// Set PWM resolution to 12 bits (0-4095)
analogWriteResolution(12);
analogWrite(12, map(sensorVal, 0, 1023, 0, 4095));
Serial.print(", 12-bit PWM: ");
Serial.print(map(sensorVal, 0, 1023, 0, 4095));
// Set PWM resolution to 4 bits (0-15)
analogWriteResolution(4);
analogWrite(13, map(sensorVal, 0, 1023, 0, 15));
Serial.print(", 4-bit PWM: ");
Serial.println(map(sensorVal, 0, 1023, 0, 15));
delay(1000); // Wait for 1 second
}
Explanation:
This code reads the sensor value from A0 and outputs it as a PWM
signal on different pins using different resolutions. It shows how the
output changes with 8-bit, 12-bit, and 4-bit resolutions.
Code:
void setup() {
pinMode(9, OUTPUT); // Set pin 9 as output
}
void loop() {
int potValue = analogRead(A0);
// Set resolution to 12 bits for smoother motor control
analogWriteResolution(12);
analogWrite(9, map(potValue, 0, 1023, 0, 4095}
Explanation:
This code uses analogWriteResolution() to set a 12-bit resolution for
controlling the motor speed more precisely based on the potentiometer
input.
Practical Exercise:
● Test different bit resolutions (like 8-bit, 10-bit, and 12-bit) and
observe how they affect LED brightness or motor speed.
● Use the map() function to adapt sensor values to the resolution you
choose.
Hints:
● If you choose a resolution higher than your board supports, the extra
bits will be discarded.
● If you choose a resolution lower than the hardware can handle, the
Arduino will pad the missing bits with zeros.
Chapter-3 Timing Functions in Arduino
Programming
Overview:
This chapter explores the various timing functions available in Arduino,
focusing on delay() , delayMicroseconds() , micros() , and millis() . These
functions allow you to control how long your Arduino waits before performing
the next action or to track time without pausing the entire program.
● delay(): Pauses the program for a specified amount of time in milliseconds,
ideal for simple tasks like blinking an LED.
● delayMicroseconds(): Pauses the program for very short, precise intervals in
microseconds, commonly used in fast signal processing or pulse generation.
● micros(): Returns the number of microseconds since the program started,
useful for high-precision timing tasks.
● millis(): Returns the number of milliseconds since the program started,
enabling long-term timing and event scheduling without blocking the rest of
the program.
These functions are essential for managing time delays, creating non-blocking
code, and ensuring accurate timing in projects involving sensors, LEDs, motors,
or other components. Understanding their uses and limitations will help you
design more responsive and efficient Arduino applications.
delay(ms
)
Parameters:
● ms: The number of milliseconds to pause the program.
Example:
Explanation:
This program turns an LED on for 1 second, then turns it off for 1 second,
creating a blinking effect.
Code:
int ledPin = 13; // LED connected to pin 13
void setup() {
pinMode(ledPin, OUTPUT); // Set pin as output
}
void loop() {
digitalWrite(ledPin, HIGH); // Turn on LED
delay(500); // Wait for half a second
digitalWrite(ledPin, LOW); // Turn off LED
delay(500); // Wait for half a second
}
Explanation:
The LED will blink on and off every half a second using the delay() function.
Practical Exercise:
● Try changing the delay time to see how fast or slow the LED blinks.
● Test using delay() with other components, like a buzzer.
Hints:
While delay() is useful for simple timing, it stops the program from doing other
tasks while waiting. For more advanced timing, you can use the millis()
function to keep your program responsive.
Parameters:
● us: The number of microseconds to pause the program.
Example:
Explanation:
This code toggles a pin on and off every 50 microseconds, generating a fast
pulse signal.
Code:
int ledPin = 8; // LED connected to pin 8
void setup() {
pinMode(ledPin, OUTPUT); // Set pin as output
}
void loop() {
digitalWrite(ledPin, HIGH); // Turn on LED
delayMicroseconds(500); // Wait for 500 micro
digitalWrite(ledPin, LOW); // Turn off LED
delayMicroseconds(500); // Wait for 500 micro
}
Explanation:
This program creates very fast blinking for the LED, with each cycle taking
500 microseconds. You could use an oscilloscope to measure the speed more
precisely.
Practical Exercise:
● Try changing the delay time to different microsecond values and observe
the effect on your output (e.g., LED or motor speed).
● Experiment with generating a square wave signal using
delayMicroseconds() for different frequencies.
Hints:
● Use delayMicroseconds() for very short delays (3 to 16,383
microseconds). For longer delays, use delay().
● This function is very precise for delays above 3 microseconds, but for
smaller or larger values, accuracy may not be guaranteed.
time = micros()
Parameters:
● None
Example:
Explanation:
This code prints the number of microseconds since the program started
running, updating every second.
Code:
Explanation:
This program uses micros() to measure the time between button presses in
microseconds.
Practical Exercise:
● Modify the code to measure how long it takes for different sensor signals or
events to occur.
● Use micros() to track fast-changing inputs, such as reading data from a
high-speed sensor.
Hints:
● Keep in mind that micros() rolls over to zero after about 70 minutes.
● For very precise timing, avoid using delay() alongside micros(), as it can
affect accuracy. Instead, try using millis() for longer timing intervals.
time = millis()
Parameters:
● None
Example:
Explanation:
This program prints the number of milliseconds since the program started
running, updating every second.
Code:
Explanation:
This program blinks an LED every second without using delay(), allowing the
rest of the program to keep running.
Practical Exercise:
● Modify the code to blink the LED at different intervals (e.g., every 500
milliseconds).
● Use millis() to keep track of multiple events happening at different times,
such as blinking multiple LEDs with different delays.
Hints:
● millis() will reset to 0 after 50 days, but it usually won't affect most projects.
● Avoid using smaller data types like int with millis(), as it could cause logic
errors due to the large values millis() can return (use unsigned long).
These functions are essential for managing complex signals, handling serial data
communication, and working with external devices in Arduino projects. Through
practical examples, you'll learn how to incorporate these functions into your
projects, whether you're generating sound, reading sensors, or expanding your
output capabilities.
noTone(pin);
Parameters:
● pin : The Arduino pin where the sound is being generated.
Example Code:
int buzzerPin = 8;
void setup() {
tone(buzzerPin, 1000); // Play a tone at 1000 Hz
delay(2000); // Wait for 2 seconds
noTone(buzzerPin); // Stop the tone
}
void loop() {
// No actions here
}
Explanation:
This code plays a tone on pin 8 at 1000 Hz for 2 seconds, then stops the tone
using noTone() .
int buzzerPin = 8;
int buttonPin = 7;
int buttonState = 0;
void setup() {
pinMode(buttonPin, INPUT);
tone(buzzerPin, 1500); // Play tone at 1500 Hz
}
void loop() {
buttonState = digitalRead(buttonPin); //
if (buttonState == HIGH) {
noTone(buzzerPin); // Stop the sound when button is pressed
}
}
Explanation:
● The buzzer plays a tone at 1500 Hz.
● When the button connected to pin 7 is pressed, the noTone() function stops
the buzzer.
Practical Exercise:
● Modify the code to play multiple tones in sequence and stop each using
noTone() .
● Try using a sensor to trigger the sound, and stop it after a certain event (e.g.,
using a PIR motion sensor to start and stop the buzzer).
Hints:
● Always call noTone() before switching to another sound or when you want
to stop the tone.
● Use noTone() when you need precise control over sound generation.
pulseIn(pin, value);
pulseIn(pin, value, timeout);
Parameters:
● pin: The Arduino pin where you want to read the pulse.
● value: The type of pulse to read, either HIGH or LOW.
● timeout (optional): The maximum time in microseconds to wait for the pulse
to start. By default, it is set to one second.
Example Code:
This example measures and prints the duration of a HIGH pulse on pin 7.
int pin = 7;
unsigned long duration;
void setup() {
Serial.begin(9600);
pinMode(pin, INPUT);
}
void loop() {
duration = pulseIn(pin, HIGH);
Serial.println(duration);
}
Explanation:
● The code waits for a HIGH pulse on pin 7 and measures how long that pulse
lasts.
● The Serial.println(duration); command prints the measured duration in
microseconds to the serial monitor.
Code:
int trigPin = 9;
int echoPin = 7;
unsigned long duration;
float distance;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
// Trigger the sensor by sending a HIGH pulse of 10 microseconds
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
Explanation:
● The ultrasonic sensor sends out a sound wave when the TRIG pin is triggered.
● The ECHO pin receives the reflected sound wave and generates a pulse
proportional to the distance of the object.
● The pulseIn() function measures this pulse duration, which is then converted
into distance.
Practical Exercise:
1. Try changing the timeout value in the pulseIn() function to see how it
affects the behavior when no pulse is detected.
2. Modify the code to measure multiple pulse widths (both HIGH and
LOW pulses) and print their durations.
Hints:
● Use pulseIn() for sensors or devices that communicate using pulse width
signals, like ultrasonic sensors or infrared remote controls.
● When measuring long pulses, ensure your timeout is large enough to avoid
returning 0 too early.
pulseInLong(pin, value);
pulseInLong(pin, value, timeout);
Parameters:
● pin: The Arduino pin where the pulse is being measured (int).
● value: The type of pulse to measure (HIGH or LOW).
● timeout (optional): The maximum time to wait for the pulse in microseconds.
The default is one second (1,000,000 microseconds).
Example Code:
This example measures the length of a HIGH pulse on pin 7 and prints the result.
int pin = 7;
unsigned long duration;
void setup() {
Serial.begin(9600);
pinMode(pin, INPUT);
}
void loop() {
duration = pulseInLong(pin, HIGH); // Measure the pulse duration
Serial.println(duration); // Print the duration in microseconds
}
Explanation:
● The code waits for a HIGH pulse on pin 7 and measures how long that pulse
lasts.
● The measured duration is then printed in microseconds on the serial monitor.
Code:
int trigPin = 9;
int echoPin = 7;
unsigned long duration;
float distance;
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
// Trigger the sensor by microseconds
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
Explanation:
● The ultrasonic sensor sends a sound wave when the TRIG pin is activated.
● The ECHO pin receives the reflected sound wave and generates a pulse.
● The pulseInLong() function measures the length of the pulse from the echo
pin.
● The pulse duration is then converted into a distance in centimeters and printed
to the serial monitor.
Practical Exercise:
1. Modify the pulseInLong() function to include a timeout value, and
observe what happens when no pulse is detected.
2. Use multiple sensors and measure the pulses from different pins at the
same time using the pulseInLong() function.
Hints:
● The pulseInLong() function is better for long pulses or when interrupts might
disrupt your timing, making it a reliable choice for longer intervals.
● The function relies on the micros() timer, so it should not be used in a
situation where interrupts are disabled (such as within noInterrupts()
contexts).
Where to Use:
The shiftIn() function is useful when communicating with devices like shift
registers or sensors that send data in a serial format. For instance, some
temperature or pressure sensors, or even other digital devices, communicate with
the microcontroller one bit at a time. You use shiftIn() to read the data coming
from such devices.
Why is it Useful:
shiftIn() allows you to read data bit by bit from external devices using just two
pins: one for data and one for clock. It gives you flexibility when working with
serial data communication, especially if your device communicates in either
MSB-first or LSB-first order. This function is perfect when you need to collect
data from sensors or shift registers but don’t want to use more complex or faster
methods like SPI.
Syntax:
● incoming: The byte of data that was shifted in from the external device.
● dataPin: The pin where the data is read from.
● clockPin: The pin that toggles to signal when data is ready to be read.
● bitOrder: The order in which the bits are read. This can be either
MSBFIRST (most significant bit first) or LSBFIRST (least significant bit
first).
Parameters:
● dataPin: Pin where the bits are read from (int).
● clockPin: Pin used to toggle and signal data reading (int).
● bitOrder: Order of the bits to shift in: MSBFIRST or LSBFIRST (most or
least significant bit first).
Example Code:
This code demonstrates how to use shiftIn() to read a byte from a device using
two pins: one for data input and one for the clock.
int dataPin = 2;
int clockPin = 3;
byte incomingData = 0;
void setup() {
pinMode(dataPin, INPUT);
pinMode(clockPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
incomingData = shiftIn(dataPin, clockPin,
MSBFIRST); Serial.println(incomingData, BIN);
delay(1000);
}
Explanation:
● The code reads a byte of data from a device connected to dataPin (pin 2) and
uses clockPin (pin 3) to signal when to read each bit.
● The shiftIn() function collects the data and stores it in incomingData , which
is then printed to the serial monitor in binary format.
Explanation:
● The shift register reads input from multiple pins and shifts out the data serially
to the Arduino.
● The Arduino uses shiftIn() to collect the binary data from the shift register
and prints the result to the serial monitor in binary format.
Practical Exercise:
1. Use multiple shift registers to expand the number of inputs and read more
than one byte of data at a time.
2. Experiment with reading the data using LSBFIRST to see the effect on
the incoming data.
Hints:
● Ensure that the clock pin is low before using shiftIn() . This ensures the timing
starts correctly.
● Use the SPI library if you need faster communication, but keep in mind that it
only works on specific hardware pins.
Syntax:
Parameters:
● dataPin: Pin used to send the data (int).
● clockPin: Pin used to toggle the clock, signaling each bit (int).
● bitOrder: Order of the bits to shift out ( MSBFIRST or LSBFIRST ).
● value: The byte of data to be sent (byte).
Example Code:
This example shows how to use the shiftOut() function with a 74HC595 shift
register to count from 0 to 255.
// Pull the latch pin high to signal that the data has been sent
digitalWrite(latchPin, HIGH);
Explanation:
● The code controls a 74HC595 shift register using three pins on the Arduino:
latch, clock, and data pins.
● It sends values from 0 to 255 to the shift register, one bit at a time.
● After the data is sent, the latch pin is pulled high to tell the shift register that it
can update its outputs with the new data.
Code:
int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
byte leds = 0; // Variable to store the LED states
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
// Count through different LED states
leds = leds + 1; // Increment LED states
digitalWrite(latchPin, HIGH);
delay(500);
Explanation:
● The code controls 8 LEDs connected to the 74HC595 shift register. Each time
through the loop, the LED states are updated.
● The LEDs will light up in sequence, shifting from one LED to the next,
controlled by the shift register and the shiftOut() function.
Practical Exercise:
1. Try changing the order of the bits from LSBFIRST to MSBFIRST and
see how the behavior of the LEDs changes.
2. Use multiple shift registers to control more than 8 LEDs or other devices.
This is called daisy-chaining, and it allows you to control many outputs
using just a few Arduino pins.
Hints:
● Ensure the clock pin is low before using shiftOut() for the first time.
● For larger values (above 255), you can shift out the data byte by byte by using
multiple shiftOut() calls.
Chapter-5 Essential Math Functions for
Arduino Programming
Overview:
This chapter introduces key mathematical functions in Arduino, which are
essential for handling calculations in a wide variety of projects. These
functions include abs() , constrain() , map() , max() , min() , pow() , sq() ,
sqrt() , and trigonometric functions like cos() , sin() , and tan() .
Understanding these functions will enhance your ability to process data,
control devices, and solve mathematical problems in your projects.
1. abs(): Calculates the absolute value of a number, ignoring whether it
is positive or negative.
2. constrain(): Limits a value to be within a specified range, ensuring it
doesn't exceed set boundaries.
3. map(): Re-maps a number from one range to another, useful for
scaling sensor readings to control outputs like LEDs or motors.
4. max(): Returns the larger of two numbers, ensuring a value is at least
a certain minimum.
5. min(): Returns the smaller of two numbers, limiting a value to a
specified maximum.
6. pow(): Raises a number to a specified power, useful for exponential
calculations.
7. sq(): Squares a number (multiplies it by itself), commonly used in
physics or geometry calculations.
8. sqrt(): Finds the square root of a number, important for distance or
geometric calculations.
9. cos(), sin(), and tan(): Perform trigonometric calculations, essential
for applications involving angles, rotations, and wave patterns.
abs(x
)
Parameters:
● x: The number whose absolute value you want. It can be positive or
negative.
Example Code:
void setup() {
Serial.begin(9600);
int x = 42;
Serial.print("The absolute value of ");
Serial.print(x);
Serial.print(" is ");
Serial.println(abs(x));
x = -42;
Serial.print("The absolute value of ");
Serial.print(x);
Serial.print(" is ");
Serial.println(abs(x));
}
void loop() {
}
Explanation:
This code checks the absolute value of x. When x is 42, it prints 42; when x is
-42, it prints 42 because the absolute value of a negative number is its positive
equivalent.
Real-Life Application: Using abs() for Distance Calculation
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No additional components are needed; just connect the Arduino to your
computer via the USB cable.
Code:
Explanation:
This program converts the negative distance value to its absolute (positive)
value and displays it on the Serial Monitor.
Practical Exercise:
● Modify the code to calculate the absolute value of several numbers and
print the results.
● Test how abs() handles different negative and positive values, and try
adding other operations outside the abs() function.
Hints:
Avoid putting other functions inside the abs() brackets, as it may lead to
incorrect results. Keep math operations outside the function to ensure
accurate calculations.
constrain(x, a,
b)
Parameters:
● x: The number you want to constrain.
● a: The lower limit of the range.
● b: The upper limit of the range.
Example Code:
Explanation:
In this code, sensorValue (200) is constrained between 10 and 150. Since 200
is higher than 150, it returns 150.
Real-Life Application: Using constrain() for Safe Motor Speed Control
Component List:
● Arduino Uno or Nano
● Motor
● Motor driver
● Power supply
● Jumper wires
● USB cable
● Computer with Arduino IDE
Circuit Connection:
Connect the motor to the Arduino through a motor driver, and ensure the
motor driver is powered by an appropriate power supply.
Code:
Explanation:
This program constrains the motor speed between 0 and 255 to ensure it stays
within the safe range for PWM control.
Practical Exercise:
● Modify the code to control LED brightness using constrain().
● Test how constrain() works with different input values and ranges, and
observe the output.
Hints:
Avoid using other functions inside constrain() as it may lead to incorrect
results. Always perform other operations outside the function to ensure
accuracy.
3 The map() Function
The map() function re-maps a number from one range to another. For
example, if you want to change a value from a 0-1023 range (like from a
sensor) to a 0-255 range (like for controlling an LED), you use map() to do
that conversion.
Where to Use:
Use map() when you need to convert a value from one set of limits to another.
This is useful for sensor readings, motor speeds, or LED brightness where
values need to be scaled.
Why It’s Useful:
The map() function makes it easy to convert values between ranges without
manually calculating each step. This is especially important when working
with devices that output values in one range but require control inputs in
another.
Syntax:
Parameters:
● value: The number you want to map.
● fromLow: The lower limit of the current range.
● fromHigh: The upper limit of the current range.
● toLow: The lower limit of the target range.
● toHigh: The upper limit of the target range.
Example Code:
void setup() {}
void loop() {
int val = analogRead(0); // Read a sensor value
val = map(val, 0, 1023, 0, 255); // Map the value from 0-1023 to 0-255
analogWrite(9, val); // Use the mapped value to control an LED
}
Explanation:
This code reads a value from a sensor (which outputs in the range 0-1023) and
uses map() to convert it into the range 0-255. The result controls the
brightness of an LED.
Real-Life Application: Mapping Sensor Data to Control a Motor
Component List:
● Arduino Uno or Nano
● Motor
● Motor driver
● Sensor (e.g., potentiometer)
● Power supply
● USB cable
● Computer with Arduino IDE
Circuit Connection:
● Connect the motor to the motor driver, and the driver to the Arduino.
● The sensor should be connected to analog pin A0.
Code:
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(A0); // Read sensor value
int motorSpeed = map(sensorValue, 0, 1023, 0, 255);
analogWrite(9, motorSpeed); // Control motor speed
Serial.println(motorSpeed); // Print the motor speed
delay(100);
}
Explanation:
This code reads the value from a sensor, maps it from a 0-1023 range to 0-
255, and then uses that value to control the speed of a motor.
Practical Exercise:
● Modify the code to map the sensor value to different ranges and observe
the effect on motor speed or LED brightness.
● Test mapping negative ranges or reversing a range (e.g., mapping from
1023 to 0).
Hints:
The map() function uses integer math, so fractions might be lost. If you
need precise decimal calculations, you might need to manually adjust the
math for your project. Consider using constrain() alongside map() if you
want to limit values within a specific range.
max(x, y)
Parameters:
● x: The first number to compare.
● y: The second number to compare.
Example Code:
Explanation:
This code checks if sensVal is at least 20. If it’s smaller, it sets sensVal to 20.
Real-Life Application: Using max() to Ensure a Minimum Sensor Value
Component List:
● Arduino Uno or Nano
● Sensor (e.g., temperature or light sensor)
● USB cable
● Computer with Arduino IDE
Circuit Connection:
● Connect the sensor to one of the analog pins on the Arduino (e.g., A0).
● Connect the sensor's ground and power as needed.
Code:
Explanation:
This program reads a sensor value and ensures that it's at least 100. If the
sensor gives a value below that, the max() function ensures it stays at 100.
Practical Exercise:
● Modify the code to check multiple values and ensure they all meet a
minimum value.
● Experiment with using max() for different types of input, such as motor
speeds or light intensity.
Hints:
Keep other calculations outside the max() function, as putting them inside the
brackets may cause incorrect results. For example, don’t decrement or
increment variables inside the max() function; do it afterward.
min(x, y)
Parameters:
x: The first number to compare.
y: The second number to compare.
Example Code:
Explanation:
This code ensures that sensVal doesn’t go above 100. If it's higher, min() sets
it to 100.
Real-Life Application: Using min() to Limit Sensor Values
● Component List:
● Arduino Uno or Nano
● Sensor (e.g., temperature or light sensor)
● USB cable
● Computer with Arduino IDE
Circuit Connection:
● Connect the sensor to an analog pin (e.g., A0) on the Arduino.
Code:
Explanation:
This program reads a sensor value and uses min() to make sure the value
doesn’t go above 500.
Practical Exercise:
● Modify the code to set different upper limits using min() for different
inputs.
● Experiment with combining min() and max() to keep values within a
specific range.
Hints:
Keep other calculations outside the min() function. Avoid using operations
like a++ inside the function, as it can lead to incorrect results. Always
perform additional math outside the function after using min().
pow(base,
exponent)
Parameters:
● base: The number to be raised.
● exponent: The power to raise the base to.
Example Code:
float x = 2.0;
float y = 3.0;
float result = pow(x, y); // Calculates 2 raised to the power of 3
Serial.println(result); // Prints 8.0
Explanation:
This code raises x (2.0) to the power of y (3.0) and prints the result, which is
8.0.
Real-Life Application: Using pow() for Exponential Brightness Control
Component List:
● Arduino Uno or Nano
● LED
● Resistor
● Breadboard
● USB cable
● Computer with Arduino IDE
Circuit Connection:
● Connect the LED to pin 9 on the Arduino with a resistor to limit the
current.
Code:
Explanation:
This program uses pow() to exponentially control the LED brightness. The
brightness value is raised to the power of 3 to create a smooth exponential
curve in brightness.
Practical Exercise:
● Modify the code to experiment with different exponent values and see how
it affects brightness or other parameters.
● Use pow() to calculate other curves, such as for motor speed control or
volume adjustment.
Hints:
Remember that pow() can handle fractional powers, making it ideal for
creating smooth transitions or gradual curves in your project. Be mindful
that the function returns a double type, so you may need to convert the result
for certain operations.
Parameters:
● x: The number you want to square.
Example Code:
int base = 4;
int result = sq(base); // Squares 4 to get 16
Serial.println(result); // Prints 16
Explanation:
This code takes base (which is 4), squares it to get 16, and prints the result.
Real-Life Application:
Title: Using sq() for Calculating Light Intensity
Component List:
● Arduino Uno or Nano
● Light sensor
● Resistor
● Breadboard
● USB cable
● Computer with Arduino IDE
Circuit Connection:
● Connect the light sensor to an analog pin (A0) on the Arduino.
● Connect power and ground to the sensor.
Code:
int sensorValue;
void setup() {
Serial.begin(9600);
}
void loop() {
sensorValue = analogRead(A0); // Read light sensor value
int intensity = sq(sensorValue);
Serial.println(intensity); // Print the squared value
delay(1000);
}
Explanation:
This program reads the value from a light sensor, squares it using sq(), and
prints the result, which can represent the intensity.
Practical Exercise:
● Try using sq() to calculate other squared values in a different context, like
distance or speed.
● Modify the code to constrain the squared value using the constrain()
function.
Hints:
Avoid putting other functions inside the sq() brackets, as it can lead to
incorrect results. Always handle additional calculations outside of the sq()
function to ensure proper results.
sqrt(x)
Parameters:
● x: The number for which you want to find the square root.
Example Code:
Explanation:
This code calculates the square root of 16, which is 4, and prints the result.
Real-Life Application: Using sqrt() for Calculating Distance Between Two
Points
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No extra components needed—just the Arduino and your computer.
Code:
float x1 = 3.0;
float y1 = 4.0;
float x2 = 0.0;
float y2 = 0.0;
void setup() {
Serial.begin(9600);
}
void loop() {
float distance = sqrt(sq(x2 - x1) + sq(y2 - y1));
Serial.print("Distance: ");
Serial.println(distance); // distance between the two points
delay(1000);
}
Explanation:
This code calculates the distance between two points using the Pythagorean
theorem and the sqrt() function.
Practical Exercise:
● Modify the code to calculate the square root of sensor values.
● Experiment with using sqrt() to solve different math problems, like
finding the diagonal length of a square.
Hints:
Use sqrt() to easily calculate square roots in math or real-world
applications. Remember that it returns a double, so make sure to handle the
decimal points if needed.
cos(rad
)
Parameters:
● rad: The angle in radians.
Example Code:
Explanation:
This code calculates the cosine of an angle in radians and prints the result.
Real-Life Application: Using cos() for Robot Arm Movement Calculation
Component List:
● Arduino Uno or Nano
● Servo motor
● Resistor
● USB cable
● Computer with Arduino IDE
Circuit Connection:
● Connect the servo motor to the Arduino using pin 9 for control and a
resistor for protection.
Code:
#include <Servo.h>
Servo myServo;
float angle = 0.0;
void setup() {
Serial.begin(9600);
myServo.attach(9); // Attach servo to pin 9
}
void loop() {
float cosineValue = cos(angle);
int servoPosition = (cosineValue + 1) * 90;
myServo.write(servoPosition); // Move the servo
Serial.println(servoPosition); // Print the servo position
angle += 0.1; // Increment angle in radians
delay(100);
}
Explanation:
This program uses cos() to calculate the cosine of an angle and adjusts the
position of a servo motor based on that value, simulating smooth rotational
movement.
Practical Exercise:
● Modify the code to use cos() for calculating wave patterns.
● Test different radian values and observe the effect on the servo motor.
Hints:
Ensure the angle you pass to cos() is in radians, not degrees. If you have
angles in degrees, convert them to radians by multiplying by PI/180 before
using cos().
sin(rad)
Parameters:
● rad: The angle in radians.
Example Code:
Explanation:
This code calculates the sine of a given angle (in radians) and prints the result.
Real-Life Application: Using sin() to Create a Wave Pattern for LED
Brightness
Component List:
● Arduino Uno or Nano
● LED
● Resistor
● Breadboard
● USB cable
● Computer with Arduino IDE
Circuit Connection:
● Connect the LED to pin 9 on the Arduino with a resistor in series to limit
current.
Code:
Explanation:
This program uses sin() to create a wave pattern that controls the brightness
of an LED, making it fade in and out smoothly.
Practical Exercise:
● Modify the code to use sin() for controlling other components, like a servo
motor or buzzer.
● Experiment with different angle increments to change the speed of the
wave pattern.
Hints:
Remember that sin() works with radians, not degrees. If you have angles in
degrees, convert them to radians by multiplying by PI/180 before using sin().
tan(rad)
Parameters:
● rad: The angle in radians.
Example Code:
Explanation:
This code calculates the tangent of a given angle (in radians) and prints the
result.
Real-Life Application:
Title: Using tan() for Calculating Slopes or Angles
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No additional components needed, just the Arduino and computer.
Code:
Explanation:
This program calculates and prints the tangent of an angle, which could
represent a slope in real-life scenarios.
Practical Exercise:
● Modify the code to calculate the tangent for a range of angles.
● Use tan() in a project where you need to calculate slopes or angles in
robotics or navigation.
Hints:
Ensure that the angle is in radians. To convert degrees to radians, multiply by
PI/180. Keep in mind that tan() has undefined values at certain angles (like
90° or 270° in degrees).
Chapter-6 Generating Randomness with
Arduino
Overview:
This chapter covers two essential Arduino functions for generating
random numbers: random() and randomSeed() . These functions are
useful for creating unpredictable behavior in your projects, such as
randomizing delays, controlling LEDs, or simulating game mechanics.
1. random(): Generates pseudo-random numbers within a specified
range. It’s perfect for introducing variability in your code, such
as random event generation, dynamic control of LEDs, or
simulating random inputs.
2. randomSeed(): Initializes the random number generator with a
seed, making the sequence of random numbers less predictable.
This is particularly helpful when you want different sequences
each time the program runs.
random(max)
random(min,
max)
Parameters
● min (optional): The lower bound of the random value (inclusive).
● max: The upper bound of the random value (exclusive).
Example Code This code generates random numbers and prints them to
the serial monitor.
long randNumber;
void setup() {
Serial.begin(9600);
// If analog input pin 0 is unconnected, random analog
// noise will cause randomSeed() to generate different
// seed numbers each time the sketch runs.
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);
}
Explanation
● randomSeed(analogRead(0)): This seeds the random number
generator, ensuring the sequence of random numbers is different each
time the program runs by using random noise from an unconnected
pin.
● random(300): Generates a random number between 0 and 299.
● random(10, 20): Generates a random number between 10 and 19.
Real-Life Application
Imagine you are creating a game where each time the player takes a step,
something random happens—this could be a change in scenery, an
enemy appearing, or a reward. By using the random() function, you can
generate these unpredictable events.
Practical Example with Arduino Generating Random Numbers for
Dynamic LED Behavior
Component List:
● Arduino Uno or Nano
● LEDs
● Resistors
● Jumper wires
● Breadboard
Circuit Connection:
● Connect the LEDs to digital pins 2, 3, and 4 on the Arduino.
● Use resistors to limit current to the LEDs.
Code
void setup() {
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
randomSeed(analogRead(0));
}
void loop() {
int randomLED = random(2, 5);
digitalWrite(randomLED, HIGH); // Turn it on
delay(random(100, 1000)); // time
digitalWrite(randomLED, LOW); // Turn it off
delay(500); // random LED
}
Explanation:
● random(2, 5): Randomly selects one of the LEDs connected to pins 2,
3, or 4.
● delay(random(100, 1000)): The LED stays on for a random duration
between 100 and 1000 milliseconds.
Practical Exercise
● Modify the code to randomly blink two LEDs at the same time.
● Adjust the timing so that the LEDs blink at different random intervals.
Hints:
● Use randomSeed() with a random input (like from an unconnected
pin) if you want different random numbers each time you run the
sketch.
● If you want the same sequence of numbers for testing, use a fixed
value for randomSeed().
The randomSeed() Function
isAlpha(thisChar)
Parameters:
● thisChar : The character to be checked (data type: char ).
Example Code:
Explanation:
In this code, the isAlpha(myChar) function checks if myChar is a letter. If it
is, the message "The character is a letter" is printed; otherwise, the message
"The character is not a letter" is displayed.
Real-Life Application:
Imagine you're building a form where the user can only input letters for their
name. You can use isAlpha() to make sure no numbers or special characters
are entered, making the input validation process simpler.
Practical Example with Arduino: Checking for Letters Only
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Code:
Explanation:
This code checks if the character inputChar is a letter. If it's a letter, the
message "The character is a valid letter" is printed; otherwise, it shows
"Invalid input, not a letter."
Practical Exercise:
● Modify the code to allow user input through the serial monitor and check if
each entered character is a letter.
● Extend the program to keep a count of valid letter entries and non-letter
entries.
Hints:
● Use isAlpha() to handle only alphabetic characters and filter out other
inputs.
● Combine it with other string functions for more advanced text handling.
isAlphaNumeric(thisChar)
Parameters:
● thisChar : The character to be checked (data type: char ).
Example Code:
Explanation:
In this example, the isAlphaNumeric(myChar) function checks if myChar is
either a letter or a number. If it is, the message "The character is alphanumeric"
is printed; otherwise, the message "The character is not alphanumeric" appears.
Real-Life Application:
When building login systems, you might want to restrict user input to only
letters and numbers for a username or password. The isAlphaNumeric()
function ensures that no special characters are entered, making the input safer
and more consistent.
Practical Example with Arduino: Validating Alphanumeric Input
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Code:
Explanation:
This code checks if the character inputChar is either a letter or a number. If it
is alphanumeric, it prints "The character is alphanumeric"; otherwise, it prints
"The character is not alphanumeric."
Practical Exercise:
● Modify the code to allow input from the serial monitor and check if each
character entered is alphanumeric.
● Add a counter to keep track of how many alphanumeric and non-
alphanumeric characters are entered.
Hints:
● Use isAlphaNumeric() to ensure only letters and numbers are processed.
● Combine it with other functions to handle more complex inputs like
passwords or form fields.
isAscii(thisChar
)
Parameters:
● thisChar : The character you want to check (data type: char ).
Example Code:
Explanation:
This example checks if the character myChar is part of the ASCII set. If the
character is ASCII, it prints "The character is Ascii"; otherwise, it prints "The
character is not Ascii."
char inputChar;
void setup() {
Serial.begin(9600); // Start serial communication
Serial.println("Please enter a character to check if it's ASCII:");
}
void loop() {
// Check if data is available in the Serial Monitor
if (Serial.available() > 0) {
inputChar = Serial.read();
// Check if the character is an ASCII character
if (isAscii(inputChar)) {
Serial.print("The character '");
Serial.print(inputChar);
Serial.println("' is an ASCII character.");
} else {
Serial.print("The character '");
Serial.print(inputChar);
Serial.println("' is NOT an ASCII character.");
}
}
}
Explanation:
● This program checks if the character entered through the Serial Monitor is
an ASCII character. It prints whether the character is ASCII or not.
● The Serial.read() function is used to capture user input from the Serial
Monitor.
Practical Exercise:
1. Modify the code to check multiple characters in a string input,
confirming if all characters are ASCII.
2. Create a counter that tracks how many ASCII and non-ASCII
characters are entered and display the results in the Serial Monitor.
Hints:
● ASCII characters include common letters, numbers, and symbols that you
see on your keyboard.
● Use this function when you need to work with characters that must be
universally supported across different systems.
isControl(thisChar)
Parameters:
● thisChar : The character you want to check (data type: char ).
Example Code:
Practical Exercise:
1. Modify the code to accept multiple characters and check if any are
control characters.
2. Add functionality to replace control characters with a visible marker
like [CTRL] .
Hints:
● Control characters like newline ( \n ) or tab ( \t ) don't show up visibly but
change how text is handled. Use this function to find and handle them in
your code.
isDigit(thisChar
)
Parameters:
● thisChar: The character you want to check. Data type: char .
Example Code:
Explanation:
This code checks whether myChar is a digit. If it is, it prints "The character is
a number." If not, it prints "The character is not a number."
Real-Life Application: Checking if User Input is a Number
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No additional components needed—just connect the Arduino to your computer
using the USB cable and use the Serial Monitor.
Code:
Explanation:
This program reads a character from the user, checks if it’s a number, and
displays the result.
Practical Exercise:
● Modify the code to check multiple characters in a row and see if they are all
numbers.
● Add a feature that stores only digits and ignores non-numeric characters.
Hints:
Use isDigit() to ensure you’re working with numbers before using them in
your program, helping to prevent errors.
isGraph(thisChar)
Parameters:
● thisChar: The character to check. Data type: char.
Example Code:
Explanation:
This code checks if myChar is a printable character with visible content and
prints the result.
Real-Life Application: Detecting Printable Characters with Content
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No extra components needed—just connect the Arduino to your computer
using the USB cable and use the Serial Monitor.
Code:
char inputChar; // Character input from the Serial Monitor
void setup() {
Serial.begin(9600); // Start serial communication
Serial.println("Enter a character to check if it's printable with content:");
}
void loop() {
if (Serial.available() > 0) {
inputChar = Serial.read(); // Read the character from the Serial Monitor
if (isGraph(inputChar)) {
Serial.println("The character is printable with visible content.");
} else {
Serial.println("The character is not printable or is a blank space.");
}
}
}
Explanation:
This program checks if a character is printable with visible content (not a
space) and prints the result.
Practical Exercise:
● Modify the code to check a series of characters for printable content.
● Add a feature to replace blank spaces with a visible marker like [SPACE] .
Hints:
Use isGraph() to ensure a character is printable and has content, avoiding
spaces or invisible characters where only visible text should appear.
Parameters:
● thisChar: The character to check. Data type: char.
Example Code:
Explanation:
This code checks whether myChar is a lowercase letter and prints the result.
Real-Life Application:Checking if a Character is Lowercase
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No additional components needed—just connect the Arduino to your
computer using the USB cable and use the Serial Monitor.
Code:
Explanation:
This program checks if a character entered by the user is lowercase and prints
the result.
Practical Exercise:
● Modify the code to check multiple characters to see if they are all
lowercase.
● Add a function to convert uppercase letters to lowercase if they aren't.
Hints:
Use isLowerCase() to ensure a character is lowercase, especially when you're
working with text where the distinction between uppercase and lowercase
matters. This can help with text formatting or validation.
isPrintable(thisChar
)
Parameters:
● thisChar: The character to check. Data type: char.
Example Code:
Explanation:
This code checks if myChar is printable and displays a message based on the
result.
Real-Life Application: Checking for Printable Characters
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No extra components needed—just connect the Arduino to your computer
using the USB cable and use the Serial Monitor.
Code:
isSpace(thisChar)
Parameters:
● thisChar: The character to check. Data type: char.
Example Code:
Explanation:
This code checks if myChar is a white-space character like a space or tab and
prints a message accordingly.
Real-Life Application: Detecting White-Space Characters
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No extra components needed—just connect the Arduino to your computer
using the USB cable and use the Serial Monitor.
Code:
Explanation:
This program checks if the entered character is a white-space character and
prints the result.
Practical Exercise:
● Modify the code to check multiple characters and detect all white-space
characters in a string.
● Add a feature that replaces white-space characters with visible markers,
like [SPACE] or [TAB] .
Hints:
Use isSpace() to identify white-space characters in text, which helps when
formatting text or ensuring input follows a specific layout.
isUpperCase(thisChar)
Parameters:
● thisChar: The character to check. Data type: char.
Example Code:
Explanation:
This program checks if the user-entered character is uppercase and displays
the result.
Practical Exercise:
● Modify the code to check multiple characters and see if each one is
uppercase.
● Add functionality to convert lowercase letters to uppercase if needed.
Hints:
Use isUpperCase() to ensure characters are in uppercase, which is useful
when you need consistent formatting or input validation in your text-based
programs.
Chapter-8 Arduino Variables and Data
Types
Overview:
In Arduino, variables and data types are the building blocks of any program,
enabling the storage and manipulation of information. Variables hold data that
can be used and changed throughout the program, while data types define the
kind of data a variable can store, such as integers, floating-point numbers, or
characters. Understanding how to choose the right data type is crucial for
optimizing memory usage and ensuring efficient operation, especially on
memory-constrained microcontrollers like Arduino.
● Variables:
Variables are containers for storing data values that can be modified as the
program runs. They must be declared with a name and a data type, and their
values can be updated as needed.
● Data Types:
Data types in Arduino determine the kind of values that can be stored in
variables. These can range from basic types like integers and characters to
more complex types like arrays or strings. Choosing the correct data type
helps optimize memory usage and processing speed, which is particularly
important in Arduino's limited memory environment.
Common data types include:
● int: Stores whole numbers between -32,768 and 32,767. Commonly used
for counting or pin numbers.
● float: Stores decimal numbers with 6-7 digits of precision. Useful for sensor
data or values requiring decimal points.
● char: Stores a single character or small numbers. Typically used for
handling text or character input.
● bool: Stores true or false values. Ideal for tracking binary states like
on/off.
● long: Stores larger whole numbers than int , from -2,147,483,648 to
2,147,483,647.
● unsigned int: Stores only positive whole numbers, ranging from 0 to
65,535, maximizing memory for larger values.
● String: Stores text strings. Useful for handling messages, text-based data,
or communication protocols.
By understanding and utilizing variables and data types effectively, you can
optimize your Arduino programs for performance and efficiency, managing
memory wisely and writing cleaner, more reliable code.
Parameters:
● Data Type: Defines the type of data stored in the array (int, float, char,
etc.).
● Array Name: The name you give to your array.
● Size: The number of elements the array can hold.
● Index: The position of an element in the array, starting from 0.
Example Code:
int myArray[5] = {2, 4, -8, 3, 7}; // Array with 5 elements
void setup() {
Serial.begin(9600);
for (int i = 0; i < 5; i++) {
Serial.println(myArray[i]); // Print each element of the array
}
}
void loop() {
// Nothing happens here
}
Explanation:
● An array myArray[] is declared with 5 integers.
● A for loop is used to access and print each element of the array to the
serial monitor.
Code:
int ledPins[] = {2, 3, 4, 5, 6}; // Array to store the LED pin numbers
void setup() {
for (int i = 0; i < 5; i++) {
pinMode(ledPins[i], OUTPUT); // Set each pin as an output
}
}
void loop() {
for (int i = 0; i < 5; i++) {
digitalWrite(ledPins[i], HIGH); // Turn each LED on
delay(500);
digitalWrite(ledPins[i], LOW); // Turn each LED off
}
}
Explanation:
● The ledPins[] array holds the pin numbers for the LEDs.
● The for loop cycles through the array, turning each LED on and off one
by one.
Practical Exercise:
1. Create an array to store sensor readings and print them to the serial
monitor.
2. Modify the code to control more LEDs by extending the array and
adding more pins to your circuit.
Hints:
● Arrays start with index 0, so myArray[0] accesses the first element.
● Be careful not to access an index that is out of bounds (e.g., accessing
myArray[6] when the array has only 5 elements).
Hints:
● Debouncing: The small delay after pressing the button ensures you don’t
get multiple button presses by mistake.
● Toggling: The expression running = !running; flips the value from true to
false , or from false to true .
Where:
● var is the name of your variable.
● val is the number you want to store (must be between 0 and 255).
Parameters:
● var: This is the name you give to the byte variable.
● val: This is the number you store in it, from 0 to 255.
Explanation:
● brightness is a byte variable holding a number between 0 and 255. It
controls how bright the LED is.
● analogWrite uses the number from the byte to adjust how much power
goes to the LED on pin 9. If the number is closer to 0, the LED will be dim.
If it’s closer to 255, the LED will be brighter.
Circuit Connection:
● Connect the anodes (long legs) of the LEDs to pins 9, 10, and 11 on the
Arduino.
● Connect the cathodes (short legs) to ground using a 220Ω resistor for
each LED.
Code:
This code will control the brightness of 3 LEDs using byte variables for each
byte led1Brightness = 128; // Medium brightness for LED 1
byte led2Brightness = 64; // Dim brightness for LED 2
byte led3Brightness = 255; // Full brightness for LED 3
void setup() {
pinMode(9, OUTPUT); // Set pin 9 for LED 1
pinMode(10, OUTPUT); // Set pin 10 for LED 2
pinMode(11, OUTPUT); // Set pin 11 for LED 3
}
void loop() {
analogWrite(9, led1Brightness); // Control brightness of LED 1
analogWrite(10, led2Brightness); // Control brightness of LED 2
analogWrite(11, led3Brightness); // Control brightness of LED 3
delay(1000); // Wait for 1 second
}
Explanation:
● led1Brightness, led2Brightness, and led3Brightness are byte variables
that control the brightness of each LED. By using different numbers for
each LED (like 128, 64, and 255), we control how bright each one is.
● The analogWrite function adjusts the brightness of each LED based on
the byte value.
Practical Exercise:
1. Try changing the brightness values (the numbers in the byte variables)
to see how each LED’s brightness changes.
2. Experiment by fading the LEDs by gradually increasing and
decreasing the brightness values inside the loop.
Hints:
● A byte can only store numbers between 0 and 255. If you try to use
numbers outside this range, they won’t work properly.
● When controlling LED brightness, using a byte ensures the values are
always within the correct range for the analogWrite function.
Where:
● var: The name of the variable.
● val: The decimal value assigned to the variable.
Parameters:
● var: The name of your double variable.
● val: The decimal number you assign to the variable.
Example Code:
Hints:
● On most Arduino boards like the UNO, double and float are the same in
terms of precision.
● If you're using Serial.print to display the value, use Serial.print(variable,
2) to limit the output to 2 decimal places.
Where:
● var: The name of the variable.
● val: The decimal value assigned to the variable.
Parameters:
● var: The name of your float variable.
● val: The decimal number you assign to the variable.
Example Code:
In this example:
● z stores a floating-point number by converting x into a float. This allows
the division to give an accurate result with a decimal, instead of being
rounded down to a whole number like y (which only holds integers).
Real-Life Application: Temperature Sensor Reading
Component List:
● Arduino Uno
● Temperature sensor (e.g., LM35 or DHT11)
● Breadboard
● Jumper wires
Circuit Connection:
● Connect the temperature sensor to analog pin A0.
● Provide 5V and GND connections to the sensor.
Code:
Explanation:
This code reads the voltage from a temperature sensor and converts it to a
Celsius value. The float variable temperature holds the value so you can
display it with decimal accuracy. The result is printed to the serial monitor,
showing the temperature with two decimal places for precision.
Practical Exercise:
1. Use a float to measure and display the distance from an ultrasonic
sensor.
2. Try storing values from a light sensor or moisture sensor in a float,
and print the results to the serial monitor.
Hints:
● Remember, floats have limited precision (6-7 digits). If you need more
precision, Arduino does not provide extra accuracy even with a double.
● When working with float math, ensure you include decimal points in your
calculations (e.g., 2.0 instead of 2 ) to avoid integer math results.
6 The int in Arduino
An int is the most common type of variable used for storing whole numbers
(integers) in Arduino. On most Arduino boards, like the Arduino UNO, an int
uses 2 bytes (16 bits) of memory and can store values between -32,768 and
32,767. On newer boards, like the Arduino Due or SAMD-based boards, an
int uses 4 bytes (32 bits), allowing it to store much larger values, from
-2,147,483,648 to 2,147,483,647.
Where to Use:
You use an int whenever you need to store or count whole numbers, like:
● Counting loops or actions.
● Pin numbers for controlling LEDs, motors, or sensors.
● Storing sensor readings that return whole numbers.
Why It’s Useful:
The int type is simple and efficient, as it stores whole numbers without
needing the extra memory required by other types like float (which stores
decimal values). It's also faster for calculations because it doesn’t need to
handle decimals.
However, be aware that if an int exceeds its maximum or minimum value, it
can cause an overflow, meaning it will roll over from its maximum to its
minimum value (or vice versa), causing unpredictable results. If you don’t
want negative values, you can use an unsigned int to avoid this.
Syntax:
int var =
val;
Where:
● var is the name of your variable.
● val is the value assigned to the variable.
Parameters:
● var: This is the name you give to your int variable.
● val: This is the whole number you want to store.
Example Code:
Here’s a simple example of an int used to count upwards:
Explanation:
In this code:
● countUp is an int that starts at 0 and increases by 1 every second.
● The value of countUp is printed to the serial monitor each time the loop
runs, showing the number increasing every second.
Real-Life Application: Counting Button Presses
Component List:
● Arduino Uno
● Pushbutton
● Resistor (10kΩ)
● Breadboard
● Jumper wires
Circuit Connection:
● Connect one leg of the pushbutton to pin 2.
● Connect the other leg to GND.
● Add a 10kΩ resistor between pin 2 and 5V for a pull-up.
Code:
Here’s an example that uses an int to count how many times a button is
pressed:
Explanation:
In this example:
● buttonCount is an int that increases every time the button is pressed.
● The digitalRead function checks if the button is pressed, and if it is, the
counter increases by 1 and the current count is displayed in the serial
monitor.
Practical Exercise:
1. Modify the code to reset the counter after 10 presses.
2. Use an unsigned int to count without negative values and see how it
behaves if the value exceeds its maximum.
Hints:
● If you’re storing values that will never go negative, you can use unsigned
int to avoid problems with negative numbers and extend the maximum
value range.
● Be careful of overflows when your int exceeds its limits (like going over
32,767 on Arduino UNO), which can cause unexpected behavior.
Where:
● var is the name of your variable.
● val is the value you want to store, which can range from -2,147,483,648 to
2,147,483,647.
Parameters:
● var: The name you assign to the variable.
● val: The number you want to store in the variable.
Example Code:
Here’s an example of how to use a long to store a large value:
Explanation:
In this example:
● speedOfLight_km_s is a long variable storing the speed of light (300,000
km/s). The L after the number ensures it's treated as a long. This is
important because some large numbers need to be forced into long format
when dealing with constants.
Real-Life Application: Counting Milliseconds with long
Component List:
● Arduino Uno
● Pushbutton
● Breadboard
● Jumper wires
Circuit Connection:
● Connect a pushbutton between pin 2 and ground.
● Use a 10kΩ resistor between pin 2 and 5V to pull the pin up when the
button is not pressed.
Code:
This example uses a long to track how long the button has been pressed.
Explanation:
● pressStartTime and pressDuration are long variables because millis()
returns a very large number of milliseconds. An int would not be able to
store such large values.
● The program records the time the button is pressed and how long it stays
pressed, printing the duration in milliseconds.
Practical Exercise:
1. Modify the code to use a long to count the number of milliseconds
since the Arduino started using the millis() function.
2. Use a long to store and track large distances (e.g., in kilometers) in an
imaginary vehicle simulation program.
Hints:
● Always use the L suffix when assigning large constant values to a long,
like 300000L, to avoid overflow issues.
● Be careful with very large values and math operations involving long, as
overflowing the maximum value can cause unpredictable results.
8 The short in Arduino
A short is a type of variable in Arduino that stores whole numbers. It is a 16-
bit (2-byte) data type, meaning it can store numbers in the range of -32,768 to
32,767. This makes it identical to an int on most Arduino boards, like the
UNO, because both use the same amount of memory (2 bytes). However, a
short can be used when you want to clearly indicate that you're only dealing
with smaller whole numbers.
Where to Use:
You can use a short when you need to store small whole numbers that fit
within the range of -32,768 to 32,767. Some examples include:
● Pin numbers.
● Loop counters.
● Any situation where you're working with small integers and want to save
memory.
Why It’s Useful:
The short data type is useful because it uses less memory than a long or other
larger data types. While it is essentially the same as an int on many Arduino
boards, it makes your code more readable and signals that you're only working
with small numbers. If you don't need large values, using a short is more
memory-efficient.
Syntax:
short var =
val;
Where:
● var: is the name of the variable.
● val: is the value assigned to the variable (must be between -32,768 and
32,767).
Parameters:
● var: The name of the short variable.
● val: The number you want to store.
Example Code:
Here’s an example using a short to store a pin number:
short ledPin = 13; // Define a short variable to hold the pin number for
an LED
void setup() {
pinMode(ledPin, OUTPUT); // Set the LED pin as output
}
void loop() {
digitalWrite(ledPin, HIGH); // Turn the LED on
delay(1000); // Wait for 1 second
digitalWrite(ledPin, LOW); // Turn the LED off
delay(1000); // Wait for 1 second
}
Explanation:
In this example:
● ledPin is a short variable that holds the value 13, which is the pin number
where the LED is connected.
● The code turns the LED on and off with a 1-second delay, repeatedly using
the short variable to reference the pin.
Real-Life Application: Controlling Multiple LEDs Using short
Component List:
● Arduino Uno
● 3 LEDs
● 3 Resistors (220Ω)
● Breadboard
● Jumper wires
Circuit Connection:
● Connect each LED to pins 9, 10, and 11 on the Arduino.
● Connect the anode (long leg) of each LED to the pins and the cathode
(short leg) to ground through a 220Ω resistor.
Code:
This code uses short to store the pin numbers for controlling 3 LEDs:
short led1Pin = 9;
short led2Pin = 10;
short led3Pin = 11;
void setup() {
pinMode(led1Pin, OUTPUT); // Set the pin modes for each LED
pinMode(led2Pin, OUTPUT);
pinMode(led3Pin, OUTPUT);
}
void loop() {
digitalWrite(led1Pin, HIGH); // Turn on LED 1
delay(500);
digitalWrite(led1Pin, LOW); // Turn off LED 1
Explanation:
In this example:
● led1Pin, led2Pin, and led3Pin are short variables that hold the pin
numbers for the three LEDs.
● The code turns each LED on and off with a delay between each, cycling
through all three LEDs.
Practical Exercise:
1. Modify the code to control more LEDs by adding more short variables
and corresponding pins.
2. Experiment with using short for storing and controlling other
components like buttons or sensors.
Hints:
● Remember that short can only store numbers between -32,768 and 32,767,
so use it only for small whole numbers.
● Using a short instead of a larger data type can save memory in situations
where you're working with many variables.
Explanation:
● myStrings[] is an array of pointers to strings. This allows you to store and
access multiple strings.
● The code prints each string in the array one after another with a 0.5-second
delay.
Real-Life Application: Displaying Messages on an LCD
Component List:
● Arduino Uno
● 16x2 LCD display
● 10kΩ potentiometer (for contrast adjustment)
● Breadboard
● Jumper wires
Circuit Connection:
● Connect the LCD to the Arduino following standard 16x2 LCD wiring.
● Use the potentiometer to adjust the LCD contrast.
Code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // Initialize the LCD with the Arduino
pins
char *messages[] = {"Hello, World!", "Welcome to Arduino", "Enjoy
Coding"};
void setup() {
lcd.begin(16, 2); // Set up the LCD's number of columns and rows
}
void loop() {
for (int i = 0; i < 3; i++) { // Loop through the messages
lcd.clear(); // Clear the display
lcd.print(messages[i]); // Display each message
delay(2000); // Wait for 2 seconds before showing the next message
}
}
Explanation:
In this code:
● The LiquidCrystal library is used to control a 16x2 LCD display.
● messages[] is an array of strings, each holding a different message to be
displayed on the LCD. The program loops through each message,
displaying it on the screen for 2 seconds.
Practical Exercise:
1. Modify the code to add more messages to the messages[] array and
display them on the LCD.
2. Experiment with changing the delay times between messages to create
different effects.
Hints:
● Always remember that strings in char arrays must end with a null
character( \0 ) to work properly.
For multi-line strings, you can wrap long text across lines using:
● String objects offer more flexibility (like easily combining strings), but
they use more memory than char arrays.
Explanation:
This code uses unsigned char to store a brightness level for the LED. The
value can range from 0 (completely off) to 255 (fully on). The Arduino
changes the brightness of the LED based on this value.
Practical Exercise:
Try changing the value of brightness in the code and observe how the LED's
brightness changes. You can also try adding a sensor to adjust the brightness
automatically.
Hints:
● Always remember that unsigned char can only store values between 0 and
255.
● Use it when you want to save memory and work with small values like
brightness, sensor readings, or communication between devices.
In this example, ledPin is an unsigned int variable storing the value 13.
Explanation
Here, ledPin is set to 13, which is a valid positive number within the
unsigned int range. It would be used to control a pin on the Arduino board,
like turning an LED on or off.
Explanation
This code uses an unsigned int variable buttonPresses to count how many
times a button is pressed. Each time the button is pressed, the counter goes up
by 1 and the value is shown in the serial monitor.
Practical Exercise:
1. Modify the Code to count something else, like sensor readings or how
many times a light turns on and off.
2. Add a Reset: Try adding another button that resets the counter back to
zero when pressed.
Hints:
● Remember that unsigned int can only store positive numbers (between 0
and 65,535 on most boards).
● Be careful with math operations: If an unsigned int "rolls over" past its
limit, it wraps back around to 0, which can cause unexpected behavior.
Explanation
In this example, time is an unsigned long variable that stores the number of
milliseconds since the Arduino started running, provided by the millis()
function. Every second, the time is printed on the serial monitor.
Explanation
This code tracks the time that has passed since the Arduino started running the
program. It uses the millis() function, which returns the time in milliseconds
as an unsigned long. The time is printed every second on the serial monitor.
Practical Exercise:
1. Modify the code to perform different actions after a certain amount of
time has passed (e.g., blink an LED after 5 seconds).
2. Experiment by changing the delay value to print the time more or less
frequently.
Hints:
● unsigned long is perfect for counting large numbers or time, as it avoids
the issue of negative numbers.
● Keep in mind that millis() will "roll over" back to zero after approximately
50 days (when it exceeds the maximum value).
Explanation
Here, pi is defined as a constant with the value 3.14. You can use it in
calculations, like multiplying it by 2, but you cannot change the value of pi
later in the program.
Explanation
In this code, ledPin is defined as a constant, representing the pin number 13.
Using const ensures that the pin number won’t accidentally change anywhere
else in the program.
Practical Exercise:
● Try using the const keyword for other pin numbers, like for buttons or
other components.
● Add more constants for things like delays (e.g., const int delayTime =
1000; ) to make your program easier to manage.
Hints:
● Use const whenever you have values that should not change, like pin
numbers or fixed numbers in calculations.
● const is preferred over #define because it follows the rules of variable
scoping, making it more reliable.
Chapter-9 Understanding Data Type
Conversion in Arduino
Overview:
This chapter delves into the byte() , char() , float() , and int() functions in
Arduino, which are used to convert values from one data type to another.
These functions are essential for ensuring that the values processed in your
Arduino projects are within the expected ranges and formats. Each function
serves a unique purpose, whether it's handling small numbers, ASCII
characters, decimal numbers, or whole numbers. Understanding these
conversion functions allows you to optimize memory usage, manage different
data types, and prevent overflow issues in your programs.
● byte(): Converts a value into a byte type, suitable for values between 0
and 255. Useful when working with small numbers like sensor data or
LED brightness levels.
● char(): Converts a value into a char , representing either an ASCII
character or a byte-sized number. This is commonly used when dealing
with text or communication protocols.
● float(): Converts a value into a float , allowing you to work with decimal
numbers for precise calculations like sensor readings or measurements.
● int(): Converts a value into an int , a data type that holds whole numbers.
Useful when you need to work with numbers that do not require decimal
precision.
By mastering these functions, you'll be able to manage data types more
efficiently in Arduino, ensuring that your projects are robust, optimized, and
free of common errors associated with data conversion and overflow.
isAlpha(thisChar)
Parameters:
● thisChar : The character to be checked (data type: char ).
Example Code:
Explanation:
In this code, the isAlpha(myChar) function checks if myChar is a letter. If it
is, the message "The character is a letter" is printed; otherwise, the message
"The character is not a letter" is displayed.
Real-Life Application:
Imagine you're building a form where the user can only input letters for their
name. You can use isAlpha() to make sure no numbers or special characters
are entered, making the input validation process simpler.
Practical Example with Arduino: Checking for Letters Only
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Code:
Explanation:
This code checks if the character inputChar is a letter. If it's a letter, the
message "The character is a valid letter" is printed; otherwise, it shows
"Invalid input, not a letter."
Practical Exercise:
● Modify the code to allow user input through the serial monitor and check
if each entered character is a letter.
● Extend the program to keep a count of valid letter entries and non-letter
entries.
Hints:
● Use isAlpha() to handle only alphabetic characters and filter out other
inputs.
● Combine it with other string functions for more advanced text handling.
isAlphaNumeric(thisChar)
Parameters:
● thisChar : The character to be checked (data type: char ).
Example Code:
Explanation:
In this example, the isAlphaNumeric(myChar) function checks if myChar is
either a letter or a number. If it is, the message "The character is
alphanumeric" is printed; otherwise, the message "The character is not
alphanumeric" appears.
Real-Life Application:
When building login systems, you might want to restrict user input to only
letters and numbers for a username or password. The isAlphaNumeric()
function ensures that no special characters are entered, making the input safer
and more consistent.
Practical Example with Arduino: Validating Alphanumeric Input
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Code:
Explanation:
This code checks if the character inputChar is either a letter or a number. If it
is alphanumeric, it prints "The character is alphanumeric"; otherwise, it prints
"The character is not alphanumeric."
Practical Exercise:
● Modify the code to allow input from the serial monitor and check if each
character entered is alphanumeric.
● Add a counter to keep track of how many alphanumeric and non-
alphanumeric characters are entered.
Hints:
● Use isAlphaNumeric() to ensure only letters and numbers are processed.
● Combine it with other functions to handle more complex inputs like
passwords or form fields.
isAscii(thisChar
)
Parameters:
● thisChar : The character you want to check (data type: char ).
Example Code:
Explanation:
This example checks if the character myChar is part of the ASCII set. If the
character is ASCII, it prints "The character is Ascii"; otherwise, it prints "The
character is not Ascii."
Explanation:
● This program checks if the character entered through the Serial Monitor is
an ASCII character. It prints whether the character is ASCII or not.
● The Serial.read() function is used to capture user input from the Serial
Monitor.
Practical Exercise:
1. Modify the code to check multiple characters in a string input,
confirming if all characters are ASCII.
2. Create a counter that tracks how many ASCII and non-ASCII
characters are entered and display the results in the Serial Monitor.
Hints:
● ASCII characters include common letters, numbers, and symbols that you
see on your keyboard.
● Use this function when you need to work with characters that must be
universally supported across different systems.
isControl(thisChar)
Parameters:
● thisChar : The character you want to check (data type: char ).
Example Code:
Practical Exercise:
1. Modify the code to accept multiple characters and check if any are
control characters.
2. Add functionality to replace control characters with a visible marker
like [CTRL] .
Hints:
● Control characters like newline ( \n ) or tab ( \t ) don't show up visibly but
change how text is handled. Use this function to find and handle them in
your code.
isDigit(thisChar
)
Parameters:
● thisChar: The character you want to check. Data type: char .
Example Code:
Explanation:
This code checks whether myChar is a digit. If it is, it prints "The character is
a number." If not, it prints "The character is not a number."
Real-Life Application: Checking if User Input is a Number
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No additional components needed—just connect the Arduino to your
computer using the USB cable and use the Serial Monitor.
Code:
Explanation:
This program reads a character from the user, checks if it’s a number, and
displays the result.
Practical Exercise:
● Modify the code to check multiple characters in a row and see if they are
all numbers.
● Add a feature that stores only digits and ignores non-numeric characters.
Hints:
Use isDigit() to ensure you’re working with numbers before using them in
your program, helping to prevent errors.
isGraph(thisChar)
Parameters:
● thisChar: The character to check. Data type: char.
Example Code:
Explanation:
This code checks if myChar is a printable character with visible content and
prints the result.
Real-Life Application: Detecting Printable Characters with Content
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No extra components needed—just connect the Arduino to your computer
using the USB cable and use the Serial Monitor.
Code:
Explanation:
This program checks if a character is printable with visible content (not a
space) and prints the result.
Practical Exercise:
● Modify the code to check a series of characters for printable content.
● Add a feature to replace blank spaces with a visible marker like
[SPACE] .
Hints:
Use isGraph() to ensure a character is printable and has content, avoiding
spaces or invisible characters where only visible text should appear.
isLowerCase(thisChar)
Parameters:
● thisChar: The character to check. Data type: char.
Example Code:
Explanation:
This code checks whether myChar is a lowercase letter and prints the result.
Real-Life Application:Checking if a Character is Lowercase
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No additional components needed—just connect the Arduino to your
computer using the USB cable and use the Serial Monitor.
Code:
Explanation:
This program checks if a character entered by the user is lowercase and prints
the result.
Practical Exercise:
● Modify the code to check multiple characters to see if they are all
lowercase.
● Add a function to convert uppercase letters to lowercase if they aren't.
Hints:
Use isLowerCase() to ensure a character is lowercase, especially when you're
working with text where the distinction between uppercase and lowercase
matters. This can help with text formatting or validation.
isPrintable(thisChar
)
Parameters:
● thisChar: The character to check. Data type: char.
Example Code:
if (isPrintable(myChar)) { // Checks if myChar is printable
Serial.println("The character is printable");
} else {
Serial.println("The character is not printable");
}
Explanation:
This code checks if myChar is printable and displays a message based on the
result.
Real-Life Application: Checking for Printable Characters
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No extra components needed—just connect the Arduino to your computer
using the USB cable and use the Serial Monitor.
Code:
isSpace(thisChar)
Parameters:
● thisChar: The character to check. Data type: char.
Example Code:
Explanation:
This code checks if myChar is a white-space character like a space or tab and
prints a message accordingly.
Real-Life Application: Detecting White-Space Characters
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No extra components needed—just connect the Arduino to your computer
using the USB cable and use the Serial Monitor.
Code:
char inputChar; // Character input from the Serial Monitor
void setup() {
Serial.begin(9600); // Start serial communication
Serial.println("Enter a character to check if it's white-space:");
}
void loop() {
if (Serial.available() > 0) {
inputChar = Serial.read(); // Read the character from the Serial Monitor
if (isSpace(inputChar)) {
Serial.println("The character is white-space.");
} else {
Serial.println("The character is not white-space.");
}
}
}
Explanation:
This program checks if the entered character is a white-space character and
prints the result.
Practical Exercise:
● Modify the code to check multiple characters and detect all white-space
characters in a string.
● Add a feature that replaces white-space characters with visible markers,
like [SPACE] or [TAB] .
Hints:
Use isSpace() to identify white-space characters in text, which helps when
formatting text or ensuring input follows a specific layout.
isUpperCase(thisChar)
Parameters:
● thisChar: The character to check. Data type: char.
Example Code:
if (isUpperCase(myChar)) { // Checks if myChar is an uppercase letter
Serial.println("The character is upper case");
} else {
Serial.println("The character is not upper case");
}
Explanation:
This code checks if myChar is an uppercase letter and prints the result.
Real-Life Application: Detecting Uppercase Letters
Component List:
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection:
No extra components needed—just connect the Arduino to your computer
using the USB cable and use the Serial Monitor.
Code:
Explanation:
This program checks if the user-entered character is uppercase and displays
the result.
Practical Exercise:
● Modify the code to check multiple characters and see if each one is
uppercase.
● Add functionality to convert lowercase letters to uppercase if needed.
Hints:
Use isUpperCase() to ensure characters are in uppercase, which is useful
when you need consistent formatting or input validation in your text-based
programs.
Chapter-10 Logical and Comparison
Operators in Arduino
Overview:
In this chapter, you’ll learn how to use essential logical and comparison
operators in Arduino to control the flow of your programs. These operators
help you compare values, make decisions, and execute different parts of the
code based on conditions. Logical operators ( && , || , ! ) and comparison
operators ( == , > , >= , < , <= , != ) allow you to evaluate multiple
conditions and decide whether an action should be performed.
1. == (Equal To) Operator:
○ Compares two values to check if they are the same. If the values match, the
result is true ; otherwise, it's false .
○ Useful for checking if a variable equals a specific value or comparing
sensor readings.
○ Checks if the value on the left is greater than the value on the right. Returns
true if the left value is larger, otherwise false .
○ Commonly used to compare sensor values or control thresholds.
○ Evaluates whether the left value is greater than or equal to the right value.
Returns true if either condition is met.
○ Ideal for ensuring a value meets or exceeds a required minimum.
○ Checks if the value on the left is smaller than the value on the right.
Returns true if the left value is smaller.
○ Useful for setting upper limits on sensor values or data.
○ Determines if the left value is less than or equal to the right value. Returns
true if the condition is met.
○ Common in scenarios where values should not exceed a limit.
○ Checks if two values are not the same. Returns true if the values are
different.
○ Ideal for ensuring values do not match a specific value or setting.
○ Returns true if both conditions are true . If either condition is false , the
result is false .
○ Useful when you need multiple conditions to be true before executing an
action.
○ Inverts the value of a condition. It turns true into false and vice versa.
○ Ideal for simplifying checks when you want to confirm something is not
happening.
○ Returns true if either condition is true . If both conditions are false , the
result is false .
○ Useful for checking if one of several conditions is met.
By mastering these operators, you'll be able to create more dynamic and
responsive programs, allowing you to control various actions based on sensor
data, user input, or other real-time conditions.
Why is It Useful?
The == operator is essential because it allows programs to make decisions
based on whether two values are equal. It is commonly used in conditions like
if statements to control what the program does next.
Syntax:
Example Code:
Here’s an example of using the == operator to compare two variables:
int x = 5;
int y = 5;
if (x == y) {
// This code runs because x is equal to y
Serial.println("x is equal to y");
} else {
// This code runs if x is not equal to y
Serial.println("x is not equal to y");
}
In this case:
● The code checks if x is equal to y .
● Since both variables are 5, the comparison is true, and "x is equal to y" is
printed.
Real-Life Example:
Imagine you’re looking at two keys:
● You want to check if both keys are exactly the same.
● If they match, you can open the door. If they don’t match, you can’t.
In programming, the == operator checks if two values match in the same way.
If they do, it proceeds with the action.
Explanation:
● The program checks if the sensor value is equal to the threshold (100).
● If the values are the same, it prints "Sensor value is equal to threshold."
● If they are not equal, it prints "Sensor value is not equal to threshold."
Hints:
● Always use the == operator to compare values (don’t confuse it with =
which is used for assignment).
● Try changing the values of x and y or the threshold to see how the
program behaves.
Why is It Useful?
The > operator is essential because it allows you to control program flow
based on whether one value is larger than another. This can be used to make
decisions in your code, like whether to trigger an action or continue a process.
Syntax:
Example Code:
Here’s an example of using the > operator to compare two values:
In this case:
● The code checks if temperature (30) is greater than threshold (25).
● Since it is, the comparison is true, and "Temperature is above the threshold"
is printed.
Real-Life Example:
Imagine you’re at a weighing scale:
● You compare your weight to a maximum limit.
● If your weight is greater than the limit, you stop loading more items.
In programming, the > operator works similarly—it compares two values and
returns true if the first is larger.
Explanation:
● The program compares the sensor value with the threshold (50).
● If the sensor value is greater than the threshold, it prints "Sensor value is
greater than threshold."
● If not, it prints "Sensor value is less than or equal to threshold."
Hints:
● Always make sure that the data types of the values being compared are the
same to avoid unexpected results.
● Use the > operator to control actions based on which value is larger.
In this case:
● The code checks if score (75) is greater than or equal to passingScore
(70).
● Since it is, the comparison is true, and "You passed!" is printed.
Real-Life Example: Imagine you’re taking an exam:
● If you score 70 or higher, you pass.
● The >= operator checks whether your score is greater than or equal to
70, so both 70 and any higher score would pass the exam.
Explanation:
● The program compares the sensor value with the threshold (50).
● If the sensor value is greater than or equal to the threshold, it prints
"Sensor value is greater than or equal to threshold."
● If the sensor value is less than the threshold, it prints "Sensor value is less
than threshold."
Hints:
● Always ensure that the variables being compared are of the same data type
to avoid unexpected results.
● Use the >= operator when you need to check for both equality and a
larger value.
Parameters:
● x: The variable or value on the left side of the comparison. Data types
include int , float , double , byte , short , long .
● y: The value or variable on the right side of the comparison. Data types
include int , float , double , byte , short , long .
Example Code:
Here’s an example of using the < operator to check if a value is below a
threshold:
In this case:
● The code checks if temperature (20) is less than threshold (25).
● Since it is, the comparison is true, and "Temperature is below the
threshold" is printed.
Real-Life Example:
Imagine you’re comparing the speed of two cars:
● If car A is slower than car B, you let car B win the race.
● The < operator checks if one value is smaller than another, just like
checking if one car is slower than the other.
Circuit Connection:
● Connect the sensor to pin A0.
Code:
Explanation:
● The program compares the sensor value with the threshold (50).
● If the sensor value is less than the threshold, it prints "Sensor value is less
than threshold."
● If the sensor value is at or above the threshold, it prints "Sensor value is at
or above threshold."
Hints:
● Always compare values of the same data type to avoid unexpected results.
● Use the < operator to handle situations where you need to check if a value
is smaller than another.
Why is It Useful?
The <= operator allows you to perform actions when a value is either smaller
than or equal to another value. This is useful when you need to check for both
cases, like meeting a minimum requirement or staying within a safe range.
Syntax:
Parameters:
x: The variable or value on the left side of the comparison. Data types
include int , float , double , byte , short , long .
y: The value or variable on the right side of the comparison. Data
types include int , float , double , byte , short , long .
Example Code:
Here’s an example of using the <= operator to check if a score is less than or
equal to the maximum allowed:
int score = 60;
int maxScore = 100;
if (score <= maxScore) {
// This code runs because score is less than or equal to maxScore
Serial.println("Score is within the allowed range.");
} else {
// This code runs if score is greater than maxScore
Serial.println("Score exceeds the allowed range.");
}
In this case:
● The code checks if score (60) is less than or equal to maxScore (100).
● Since it is, the comparison is true, and "Score is within the allowed range"
is printed.
Real-Life Example:
Imagine you’re comparing height to see if someone is short enough to ride a
certain attraction at an amusement park:
● The ride allows people who are up to 150 cm tall.
● The <= operator checks if the person’s height is less than or equal to 150
cm.
Explanation:
The program compares the sensor value with the threshold (100).
If the sensor value is less than or equal to the threshold, it prints
"Sensor value is less than or equal to threshold."
If the sensor value is greater than the threshold, it prints "Sensor value
is above threshold."
Hints:
Use the <= operator when you need to check for both cases: values
that are equal to or smaller than the comparison.
Always compare values of the same data type to avoid unexpected
results.
Parameters:
● x: The variable or value on the left side of the comparison. Data types
include int , float , double , byte , short , long .
● y: The value or variable on the right side of the comparison. Data types
include int , float , double , byte , short , long .
Example Code:
Here’s an example of using the != operator to check if two numbers are not
the same:
int value1 = 5;
int value2 = 10;
if (value1 != value2) {
// This code runs because value1 is not equal to value2
Serial.println("Values are not equal.");
} else {
// This code runs if value1 is equal to value2
Serial.println("Values are equal.");
}
In this case:
The code checks if value1 (5) is not equal to value2 (10).
Since the values are different, the comparison is true, and "Values are
not equal" is printed.
Real-Life Example:
Imagine you’re entering a password:
If the password you enter is not equal to the stored password, the
system will not grant access.
The != operator checks if two values are different, just like checking
if two passwords don’t match.
Checking if a Sensor Value is Not Equal to a Target Value
Component List:
1 Sensor (e.g., temperature or light sensor)
Jumper wires
Arduino Board
Circuit Connection:
Connect the sensor to pin A0.
Code:
int targetValue = 100; // Set a target value
int sensorValue;
void setup() {
Serial.begin(9600); // Start the serial monitor
}
void loop() {
sensorValue = analogRead(A0); // Read the sensor value
if (sensorValue != targetValue) { // Check if sensor value is not equal to the target
Serial.println("Sensor value is not equal to the target.");
} else {
Serial.println("Sensor value matches the target.");
}
delay(1000); // Wait 1 second before checking again
}
Explanation:
● The program compares the sensor value with the target value (100).
● If the sensor value is not equal to the target, it prints "Sensor value is not
equal to the target."
● If the sensor value matches the target, it prints "Sensor value matches the
target."
Hints:
● Use != when you need to trigger actions when two values are different.
● Always compare values of the same data type to avoid unexpected results.
Parameters:
condition1: The first condition (a comparison or boolean value).
condition2: The second condition (a comparison or boolean value).
Example Code:
Here’s an example where two switches need to be in the HIGH position for the
action to occur:
In this case:
The code checks if both digital pins 2 and 3 are reading HIGH.
If both conditions are true, "Both switches are ON" is printed.
Real-Life Example:
Imagine you have a security system:
The alarm will sound only if both the door and the window are open.
The && operator checks if both conditions are met—only then will it
trigger the alarm.
Explanation:
● The program checks if both sensor values are above their respective
thresholds.
● If both conditions are true, it prints "Both sensors are above their
thresholds."
● If either condition is false, it prints "One or both sensors are below their
thresholds."
Hints:
● Use the && operator to check if multiple conditions are met at the same
time.
● Be sure to understand the difference between the logical AND ( && ) and
bitwise AND ( & ), as they work differently.
Why is It Useful?
The ! operator simplifies your code when you want to check the opposite of a
condition. Instead of writing extra code to check if something is false, you can
use ! to quickly reverse the logic.
Syntax:
Parameters:
condition: A boolean value or expression to be inverted.
Example Code:
Here’s an example where the program checks if a button is not pressed:
In this case:
● The ! operator inverts the value of buttonState .
● If the button is not pressed, "Button is not pressed" is printed.
Real-Life Example:
Imagine a light switch:
● If the switch is not flipped, the lights are off.
● The ! operator checks the opposite of a condition—in this case, it checks
if the switch is not in the "on" position.
Explanation:
The program checks if the sensor value is not within the range of 200
to 800 using ! .
If the value is outside the range, it prints "Sensor value is outside the
safe range."
If the value is within the range, it prints "Sensor value is within the
safe range."
Hints:
Use ! to invert conditions and make it easy to check the opposite of a
value.
Be careful not to confuse the logical NOT ( ! ) with the bitwise NOT
( ~ ), as they have different uses.
Parameters:
● condition1: The first condition (a comparison or boolean value).
● condition2: The second condition (a comparison or boolean value).
Example Code:
Here’s an example where the program checks if either x or y is greater than
zero:
int x = -5;
int y = 10;
if (x > 0 || y > 0) {
// This code runs if either x or y is greater than zero
Serial.println("Either x or y is greater than zero.");
} else {
// This code runs if both x and y are less than or equal to zero
Serial.println("Both x and y are less than or equal to zero.");
}
In this case:
The code checks if either x or y is greater than zero.
Since y is greater than zero, the comparison returns true, and "Either
x or y is greater than zero" is printed.
Real-Life Example:
Imagine you’re checking two doors for security:
If either door is open, an alarm will sound.
The || operator checks if one or both conditions are true, just like
monitoring multiple doors for any security breach.
Circuit Connection:
Connect one sensor to pin A0 and the other to pin A1.
Code:
int threshold = 100; // Set a threshold value
int sensor1Value, sensor2Value;
void setup() {
Serial.begin(9600); // Start the serial monitor
}
void loop() {
sensor1Value = analogRead(A0); // Read the first sensor value
sensor2Value = analogRead(A1); // Read the second sensor value
if (sensor1Value > threshold || sensor2Value > threshold) { // Check if either
sensor value is above the threshold
Serial.println("One or both sensors are above the threshold.");
} else {
Serial.println("Both sensors are below or equal to the threshold.");
}
delay(1000); // Wait 1 second before checking again
}
Explanation:
● The program checks if either of the sensor values is above the threshold
(100).
● If at least one sensor value exceeds the threshold, it prints "One or both
sensors are above the threshold."
● If neither sensor value exceeds the threshold, it prints "Both sensors are
below or equal to the threshold."
Hints:
● Use || when you want to check if at least one of the conditions is true.
● Be careful not to confuse logical OR ( || ) with bitwise OR ( | ), as they
serve different purposes.
Chapter-11 Bitwise Operators in
Arduino
Overview:
This chapter introduces the fundamental bitwise operators used in
Arduino, which allow you to manipulate individual bits within a number.
These operators are particularly useful in low-level programming, such
as handling hardware registers, working with binary data, and optimizing
performance in tasks like shifting, masking, and encoding.
1. << (Bitwise Left Shift) Operator:
○ Shifts bits to the right, with the leftmost bits filled based on whether
the variable is signed or unsigned. It's used to divide numbers
efficiently by powers of 2.
○ Important in dividing numbers or shifting bits to manipulate binary
data.
○ Inverts all bits of a number, turning 0s into 1s and vice versa. This is
useful for creating complementary values or working with binary data
streams.
5. | (Bitwise OR) Operator:
Parameters:
● variable: The variable whose bits will be shifted. Allowed data
types include byte , int , and long .
● number_of_bits: The number of positions to shift the bits to the
left. Allowed data type is int , and the value must be less than or
equal to 32.
Example Code:
Here’s an example of using the << operator:
int a = 5; // binary: 0000000000000101
int b = a << 3; // shifts the bits of a three positions to the left
Serial.println(b); // This will print 40 (binary: 0000000000101000)
In this case:
● The binary representation of 5 is 0000000000000101 .
● Shifting it left by 3 bits gives 0000000000101000 , which is 40 in
decimal.
Real-Life Example:
Imagine moving boxes on a conveyor belt:
● Every time you shift a box to the left by one space, a new empty
space (0) appears on the right. This is similar to how the left shift
operator moves bits to the left, filling the right with zeros.
Explanation:
● The program shifts the number 1 to the left by different amounts
(from 0 to 4 bits).
● Each shift multiplies the number by powers of 2 (e.g., 1 << 1
gives 2, 1 << 2 gives 4, etc.).
Hints:
● Be cautious about shifting bits out of existence: if a bit is shifted
past the leftmost bit, it is lost permanently.
● The left shift can be thought of as multiplying by powers of 2.
For example, x << 3 is equivalent to x * (2^3) or x * 8 .
variable >> number_of_bits; // Shifts the bits of the variable to the right
by the specified number_of_bits
Parameters:
● variable: The variable whose bits will be shifted. Allowed data types
include any integer type (byte, short, int, long, unsigned short, etc.).
● number_of_bits: A positive integer smaller than the bit-width of the
variable.
Example Code:
Here’s an example of using the >> operator:
In this case:
● The binary representation of 40 is 0000000000101000 .
● Shifting it right by 3 bits gives 0000000000000101 , which is 5 in
decimal.
Real-Life Example:
Imagine you are moving boxes on a conveyor belt:
● Each time you move a box to the right, a new empty space (0)
appears on the left. This is similar to how the right shift operator
moves bits to the right, filling the left with 0s or sign bits.
Explanation:
● The program shifts the number 32 to the right by different amounts
(from 0 to 4 bits).
● Each shift divides the number by powers of 2 (e.g., 32 >> 1 gives 16,
32 >> 2 gives 8, etc.).
Hints:
● Be cautious about shifting bits off the right end: once a bit is shifted
past the rightmost position, it is lost permanently.
● For signed integers, the right shift fills with the sign bit. If you want
to avoid sign extension, use an unsigned type for the variable or
explicitly cast it.
Parameters:
● operand1: The first integer value to compare.
● operand2: The second integer value to compare.
Example Code:
Here’s an example of using the & operator:
In this case:
● The binary representation of a is 0000000001011100 .
● The binary representation of b is 0000000001100101 .
● The result of a & b is 0000000001000100 , which is 68 in
decimal.
Real-Life Example:
Imagine you are filtering items based on multiple criteria:
● If both conditions (bits) are met (both are 1), the filter passes. If
either condition is not met (either is 0), the filter rejects it.
Explanation:
● The program uses the & operator to mask the input value, keeping
only the last 4 bits.
● The mask 0b00001111 ensures that only the rightmost 4 bits of the
input value are retained.
Hints:
● Use & for bit masking to select specific bits from an integer value.
● The bitwise AND is often used to clear or check specific bits by
applying a mask where 1s select the bits you want to keep and 0s
clear the other bits.
4 The ~ (Bitwise NOT) Operator
The ~ (bitwise NOT) operator is a unary operator that inverts all the
bits of a number. It flips each bit: 0 becomes 1, and 1 becomes 0. The
operation is performed on the entire bit structure of the operand.
Where to Use the ~ Operator:
Use the ~ operator when you need to:
● Invert all the bits of a number, often for tasks like creating masks or
working with complementary values.
● Perform tasks that require bit-level manipulation, such as handling
data streams or controlling hardware at the binary level.
Why is It Useful?
The ~ operator is useful when you need to quickly invert every bit of a
number. It is commonly used in low-level programming and bitwise
operations where precise control over the bits is necessary.
Syntax:
Parameters:
● operand: The integer value whose bits will be inverted. Allowed data
types include int , byte , long , etc.
Example Code:
Here’s an example of using the ~ operator:
In this case:
● The binary representation of 103 is 0000000001100111 .
● The bitwise NOT of 103 is 1111111110011000 , which is -104 in
decimal. This result occurs because the highest bit represents the
sign in two's complement.
Real-Life Example:
Imagine you have on/off switches:
● If you flip all the switches (change all 1s to 0s and vice versa),
that's similar to what the ~ operator does: it inverts all the bits.
void setup() {
Serial.begin(9600); // Start the serial monitor
int invertedValue = ~value; // Invert the bits of the value
Serial.print("Inverted value: ");
Serial.println(invertedValue, BIN); // Print the inverted value in binary
}
void loop() {
// No need for code in the loop
}
Explanation:
● The program uses the ~ operator to invert all the bits of the
variable value .
● The inverted value is printed to the serial monitor.
Hints:
● The result of ~ on a signed integer can appear negative because the
highest bit in a signed integer represents the sign (positive or
negative).
● Remember that unsigned integers behave differently: they don't have
a sign bit, so the result may differ from what you'd expect with signed
integers.
5 The Bitwise OR ( | ) Operator
The bitwise OR operator ( | ) is used in programming to compare two
numbers at the bit level. It looks at each bit of two numbers, and if at
least one of the bits is 1 , the result will be 1 in that position. If both
bits are 0 , the result will be 0 . This operation is helpful for
manipulating and setting specific bits in a binary number.
Where to Use the Bitwise OR Operator
The bitwise OR operator is often used in scenarios where:
● You want to set specific bits to 1 without affecting others.
● You're working with flags or control registers in hardware,
embedded systems, or low-level programming.
● You need to combine multiple binary conditions into a single value.
Why is the Bitwise OR Operator Useful?
The OR operator is useful when you need to modify certain bits while
leaving others unchanged. For instance, it can be used to create or
modify bit masks, which allow you to control individual bits of a value.
It's particularly handy in binary manipulation tasks where you want to
turn on specific bits without altering the rest of the number.
Syntax
Parameters
● operand1 and operand2: These are the two integers that are being
compared at the bit level. They can be any integer types, such as
int or long .
Example
Here’s an example of the bitwise OR operator in action:
Explanation:
● a is 0000000001011100 in binary (92 in decimal).
● b is 0000000001100101 in binary (101 in decimal).
● The result of a | b is 0000000001111101 , which equals 125 in
decimal.
Real-Life Application
Imagine a set of light switches controlling different devices. If any one
of the switches is ON (represented by a 1 ), the device remains ON.
This is similar to how the bitwise OR works. If either bit in the input
values is 1 , the output for that position will be 1 .
Practical Example with Arduino Setting Multiple Pin Directions on
Arduino
Component List
● Arduino Uno or Nano
● USB cable
● Computer with Arduino IDE
Circuit Connection
There’s no need for physical connections for this code example as it
focuses on setting the pin modes in the microcontroller.
Code
void setup() {
// Set pins 2 to 7 as OUTPUT (leave pins 0 and 1 untouched)
DDRD = DDRD | 0b11111100; // Sets direction bits for pins 2 to 7
// Print the value of DDRD to the serial monitor
Serial.begin(9600);
Serial.print("DDRD value: ");
Serial.println(DDRD, BIN); // Output DDRD in binary
}
void loop() {
// No need for code in the loop
}
Explanation:
● DDRD is the register that controls whether the pins on port D of the
Arduino are set as input or output. By applying the bitwise OR
operator, we set pins 2 to 7 as output pins without affecting pins 0
and 1.
● The OR operation ensures that specific pins are set to 1 (output)
while keeping other pins untouched.
Practical Exercise
● Modify the code to set pins 2 to 5 as outputs while leaving the others
unchanged.
● Experiment with different bit masks to see how the pin directions
change.
Hints
● The OR operator is ideal when you need to combine multiple flags
or conditions into a single result.
● Keep in mind that the OR operator only sets bits to 1—it does not
clear or reset any bits. To clear bits, you would use the AND
operator with a mask.
Chapter-12 Basic Arithmetic and
Compound Operators in Arduino
Overview:
This chapter covers fundamental arithmetic operations and compound
operators that are widely used in Arduino programming. You’ll learn how to
perform basic calculations such as addition, subtraction, multiplication, and
division, along with more advanced operations like modulus (remainder),
incrementing, and compound operators (e.g., += , -= , *= , etc.). These
operators help simplify repetitive tasks, manage sensor data, control variables
in loops, and handle more complex data manipulation. Understanding and
applying these operators effectively will enhance your ability to create
efficient, functional Arduino projects.
Parameters:
● sum: The variable that stores the result of the addition. It can be of data
types like int , float , double , byte , short , or long .
● operand1: The first number or variable to be added. It can be of data
types like int , float , double , byte , short , or long .
● operand2: The second number or variable to be added. It can be of data
types like int , float , double , byte , short , or long .
Example Code:
Here’s an example where two numbers are added together:
int a = 5;
int b = 10;
int c = 0;
c = a + b; // The variable 'c' now holds the value 15
Serial.println(c); // This will print 15
In this case:
● The variable a (5) is added to b (10).
● The result is stored in c , and the final value of c is 15.
Real-Life Example:
Imagine you’re at a store:
● You buy two items, one costing $5 and the other costing $10.
● The total cost is $15—this is exactly how the addition operator works: it
adds the two amounts together.
Explanation:
● The program reads values from two sensors.
● It then adds the two sensor values together using the + operator and
stores the result in totalValue .
● The total value is printed to the serial monitor.
Hints:
● Be cautious of overflow when adding very large numbers (e.g., adding
values that exceed the storage capacity of the data type).
● If you are adding floating-point numbers (like float or double ), ensure
the result is stored in a compatible variable type to avoid losing decimal
points.
Parameters:
● result: The variable that stores the result of the division. It can be of
data types like int , float , double , byte , short , or long .
● numerator: The number you want to divide. It can be of data types like
int , float , double , byte , short , or long .
● denominator: The number by which you are dividing. It must be a non-
zero value and can be of the same data types as the numerator.
Example Code:
Here’s an example of dividing two integers:
int a = 50;
int b = 10;
int result = 0;
result = a / b; // The variable 'result' gets the value 5
Serial.println(result); // This will print 5
In this case:
● The variable a (50) is divided by b (10).
● The result is stored in result , which is 5.
Real-Life Example:
Imagine you have 50 candies and you want to share them equally among 10
friends:
● You divide the total number of candies (50) by the number of friends (10).
● Each friend gets 5 candies—this is how division works: splitting a total
into equal parts.
Explanation:
● The program reads values from two sensors.
● It divides the first sensor value by the second sensor value and stores the
result in the variable result .
● It also checks to make sure the second sensor value (the denominator) is
not zero, as division by zero is not allowed.
Hints:
● When using division with floating-point numbers ( float or double ), be
sure to store the result in a compatible data type.
● Always check that the denominator is not zero to avoid division errors.
Parameters:
● product: The variable that stores the result of the multiplication. It can be
of data types like int , float , double , byte , short , or long .
● operand1: The first number or variable to be multiplied. It can be of data
types like int , float , double , byte , short , or long .
● operand2: The second number or variable to be multiplied. It can be of
data types like int , float , double , byte , short , or long .
Example Code:
Here’s an example where two numbers are multiplied together:
int a = 5;
int b = 10;
int product = 0;
product = a * b; // The variable 'product' now holds the value 50
Serial.println(product); // This will print 50
In this case:
● The variable a (5) is multiplied by b (10).
● The result is stored in product , which is 50.
Real-Life Example:
Imagine you’re buying apples:
● You buy 5 apples, and each apple costs $10.
● The total cost is $50—this is how the multiplication operator works:
multiplying the quantity by the price.
Explanation:
● The program reads values from two sensors.
● It multiplies the two sensor values together using the * operator and
stores the result in product .
● The result is printed to the serial monitor.
Hints:
● Be cautious of overflow when multiplying large numbers, as the result
may exceed the storage capacity of the variable.
● If using floating-point numbers (like float or double ), ensure the result
is stored in a compatible data type to avoid losing decimal points.
Parameters:
● remainder: The variable that stores the remainder of the division. It can
be of data types like int .
● dividend: The number you are dividing. It can be of data types like int .
● divisor: The number by which you are dividing. It must be non-zero
and can also be of data types like int .
Example Code:
Here’s an example of how the remainder operator works:
int x = 0;
x = 7 % 5; // x now contains 2 (7 divided by 5 gives a remainder of 2)
x = 9 % 5; // x now contains 4 (9 divided by 5 gives a remainder of 4)
x = 5 % 5; // x now contains 0 (5 divided by 5 gives no remainder)
x = 4 % 5; // x now contains 4 (4 divided by 5 gives a remainder of 4) of 4)
In this case:
● The remainder operator calculates the remainder when 7 is divided by
5 , which is 2.
Real-Life Example:
Imagine you’re distributing candies to kids:
● You have 7 candies, and there are 5 kids.
● After giving each kid one candy, you have 2 candies left—this is how
the remainder operator works, it tells you what is left after dividing.
Explanation:
● The sensor value is stored in an array with 10 slots.
● The counter i is updated using the remainder operator ( i = (i + 1) % 10 ),
ensuring it stays within the range of 0–9, cycling through the array.
Hints:
● The remainder operator only works with integers, not floating-point
numbers ( float or double ).
● Be careful when using negative numbers with the remainder operator, as
the result will also be negative (or zero).
Parameters:
● difference: The variable that stores the result of the subtraction. It can
be of data types like int , float , double , byte , short , or long .
● operand1: The first number or variable from which the second number
will be subtracted. It can be of data types like int , float , double ,
byte , short , or long .
● operand2: The second number or variable that is subtracted from the
first. It can be of data types like int , float , double , byte , short , or
long .
Example Code:
Here’s an example of subtracting two integers:
int a = 5;
int b = 10;
int result = 0;
result = a - b; // The variable 'result' gets the value of -5
Serial.println(result); // This will print -5
In this case:
● The variable a (5) is subtracted from b (10).
● The result is stored in result , which is -5.
Real-Life Example:
Imagine you have $10, and you spend $5:
● The amount left is $5—this is how the subtraction operator works:
subtracting the amount spent from the total amount.
Explanation:
● The program reads values from two sensors.
● It subtracts the second sensor value from the first using the - operator
and stores the result in difference .
● The result is printed to the serial monitor.
Hints:
● Be cautious of overflow when subtracting large values that may exceed
the storage capacity of the variable.
● If using floating-point numbers( float or double ), ensure the result is
stored in a compatible data type to avoid losing decimal points.
Compound Operators:
7 The += (Compound Addition) Operator
The += (compound addition) operator is a shorthand way to add a value
(constant or variable) to an existing variable. It simplifies the expression x = x
+ y by allowing you to write x += y .
Where to Use the += Operator:
Use the += operator when you want to increment a variable by a certain
amount. For example:
● Updating a total by adding new values to it.
● Accumulate sensor readings to calculate a sum.
Why is It Useful?
The += operator makes code shorter and easier to read by eliminating the
need to repeat the variable name on both sides of the expression.
Syntax:
Parameters:
● x: The variable to which the value will be added. It can be of data types
like int , float , double , byte , short , or long .
● y: The value (or variable) to be added to x . It can be of data types like
int , float , double , byte , short , or long .
Example Code:
Here’s an example of using the += operator:
int x = 2;
x += 4; // x now contains 6 (2 + 4)
Serial.println(x); // This will print 6
In this case:
● The variable x starts with a value of 2 .
● After x += 4 , the value of x becomes 6 (2 + 4).
Real-Life Example:
Imagine you’re keeping track of money saved:
● You start with $2 and later add $4 to your savings.
● Now you have $6—this is how the += operator works: it adds the new
amount to the existing total.
Explanation:
● The program reads the sensor value and adds it to the totalValue using the
+= operator.
● This continuously accumulates the sensor readings over time, and the total
is printed to the serial monitor.
Hints:
● Use += to simplify your code when adding values to a variable multiple
times.
● Be cautious of overflow if the value becomes too large for the data type to
handle.
Parameters:
● x: The variable whose bits are being modified. Allowed data types include
char , int , and long .
● y: A constant or variable used as the bitwise mask. Allowed data types
include char , int , and long .
Example Code:
Here’s an example of how the &= operator works to clear certain bits:
In this case:
● The variable myByte starts with the binary value 10101010 .
● The &= operation clears the two rightmost bits, resulting in
10101000 .
Real-Life Example:
Imagine you have an 8-light LED strip:
● You want to turn off the last two lights without affecting the other lights.
● The &= operator works similarly, clearing the last two bits (lights)
while keeping the others unchanged.
Explanation:
● The variable myByte starts with the binary value 11110011 .
● The &= operator is used to clear the last four bits (set them to 0),
resulting in 11110000 .
Hints:
● The &= operator is commonly used with binary masks to target specific
bits.
● Use 0b to represent binary numbers for clarity when manipulating bits.
● Be careful when using the &= operator, as it can reset important bits if
the mask isn’t applied correctly.
Parameters:
● x: The variable whose bits are being modified. Allowed data types
include char , int , and long .
● y: A constant or variable used as the bitwise mask. Allowed data types
include char , int , and long .
Example Code:
Here’s an example of how the |= operator works to set specific bits:
In this case:
● The variable myByte starts with the binary value 10101010 .
● The |= operation sets the two rightmost bits to 1, resulting in
10101011 .
Real-Life Example:
Imagine you have a row of switches where each switch controls a light:
● The |= operator allows you to turn on certain lights (set specific switches
to 1) without affecting the others.
Explanation:
● The variable myByte starts with the binary value 11110000 .
● The |= operator is used to set the last four bits to 1, resulting in
11111111 .
Hints:
● The |= operator is often used with binary masks to target specific bits.
● Use 0b to represent binary numbers for clarity when manipulating bits.
● Be careful when using the |= operator, as it will set bits to 1, potentially
overwriting important data in those bits.
In this case:
● The variable myByte starts with the binary value 10101010 .
● The ^= operation toggles the two rightmost bits, resulting in 10101001 .
Real-Life Example:
Imagine you have a light switch:
● Each time you press the switch, it toggles the light between on and off.
The ^= operator works similarly, flipping the state of specific bits.
Parameters:
● x: The variable that will be divided. It can be of data types like int ,
float , double , byte , short , or long .
● y: A non-zero variable or constant by which x will be divided. It can
be of data types like int , float , double , byte , short , or long .
Example Code:
Here’s an example of using the /= operator:
int x = 4;
x /= 2; // x now contains 2 (4 / 2)
Serial.println(x); // This will print 2
In this case:
● The variable x starts with a value of 4 .
● After x /= 2 , the value of x becomes 2.
Real-Life Example:
Imagine you have 4 apples, and you want to split them between 2 people:
● Each person gets 2 apples—this is how the /= operator works, by
dividing the total evenly.
Explanation:
● The program reads the sensor value and divides it by 2 using the /=
operator.
● The divided value is stored in result and printed to the serial monitor.
Hints:
● Use the /= operator to simplify your code when you need to divide
values multiple times.
● Always make sure the divisor ( y ) is not zero to avoid division errors.
Parameters:
● x: The variable that will be multiplied. It can be of data types like int ,
float , double , byte , short , or long .
● y: The value or variable to multiply by x . It can be of data types like int ,
float , double , byte , short , or long .
Example Code:
Here’s an example of using the *= operator:
int x = 2;
x *= 3; // x now contains 6 (2 * 3)
Serial.println(x); // This will print 6
In this case:
● The variable x starts with a value of 2 .
● After x *= 3 , the value of x becomes 6.
Real-Life Example:
Imagine you are doubling a recipe:
● If a recipe calls for 2 cups of flour, and you double it, you now need 4
cups of flour. The *= operator works the same way, by multiplying the
value.
Explanation:
● The program reads the sensor value and multiplies it by 2 using the *=
operator.
● The result is stored in result and printed to the serial monitor.
Hints:
● Use *= to simplify your code when you need to multiply values multiple
times.
● Be mindful of overflow, especially when multiplying large numbers in
limited data types like int .
Parameters:
● x: The variable that will be divided. It can be of the data type int .
● divisor: The non-zero variable or constant by which x will be divided.
It can also be of the int data type.
Example Code:
Here’s an example of using the %= operator:
int x = 7;
x %= 5; // x now contains 2 (7 % 5)
Serial.println(x); // This will print 2
In this case:
● The variable x starts with a value of 7 .
● After x %= 5 , the value of x becomes 2 (since 7 divided by 5 leaves a
remainder of 2).
Real-Life Example:
Imagine you are distributing items to a group of people:
● You have 7 candies and want to divide them among 5 people.
● After each person gets one candy, 2 candies are left—this is how the
remainder operator works.
Explanation:
● The program reads a sensor value and stores it in an array of size 5.
● The index i is updated using the %= operator, ensuring it cycles between
0 and 4, so the sensor readings are always stored within the bounds of the
array.
Hints:
● The %= operator is useful for keeping values within a specific range, like
array indices or circular buffers.
● Ensure that the divisor is not zero to avoid division errors.
Parameters:
● x: The variable that will be reduced. It can be of data types like int ,
float , double , byte , short , or long .
● y: The value (constant or variable) that will be subtracted from x . It can
be of data types like int , float , double , byte , short , or long .
Example Code:
Here’s an example of using the -= operator:
int x = 20;
x -= 2; // x now contains 18 (20 - 2)
Serial.println(x); // This will print 18
In this case:
● The variable x starts with a value of 20 .
● After x -= 2 , the value of x becomes 18.
Real-Life Example:
Imagine you have 20 apples and you eat 2:
● You are left with 18 apples. The -= operator works similarly, subtracting
the amount consumed from the total.
Explanation:
● The program reads a sensor value and subtracts it from a starting value of
100 using the -= operator.
● The updated result is printed to the serial monitor.
Hints:
● Use the -= operator to simplify your code when you need to subtract
values multiple times from a variable.
● Ensure the result does not underflow when dealing with small values,
especially in limited data types like byte or int .
Parameters:
● x: The variable to be decremented. Allowed data types include int and
long (possibly unsigned).
Returns:
● Post-decrement( x-- ): Returns the original value of x .
● Pre-decrement( --x ): Returns the new value of x after decrementing.
Example Code:
Here’s an example of using both pre-decrement and post-decrement:
int x = 2;
int y;
y = --x; // Pre-decrement: x becomes 1, y gets 1
Serial.println(y); // Prints 1
y = x--; // Post-decrement: y gets 1 (the old value of x), then x becomes 0
Serial.println(y); // Prints 1
Serial.println(x); // Prints 0
In this case:
● The pre-decrement --x first decrements x to 1, and then assigns this new
value to y .
● The post-decrement x-- assigns the original value of x (1) to y and then
decrements x to 0.
Real-Life Example:
Imagine you're counting down from a value:
● You start at 10, then subtract 1 each time until you reach 0. The --
operator automates this process by reducing the value with each step.
Explanation:
● The program counts down from 10 to 0 using the -- operator.
● Once the countdown reaches 0, it resets back to 10 and continues.
Hints:
● Use -- in loops or countdowns where you need to reduce a value by 1
with each iteration.
● Be mindful of underflow, especially when using unsigned types, where
a decrement could wrap the value back to its maximum.
Parameters:
● x: The variable to be incremented. Allowed data types include int , long
(possibly unsigned).
Returns:
● Post-increment( x++ ): Returns the original value of x .
● Pre-increment( ++x ): Returns the new value of x after incrementing.
Example Code:
Here’s an example of using both pre-increment and post-increment:
int x = 2;
int y;
y = ++x; // Pre-increment: x becomes 3, y gets 3
Serial.println(y); // Prints 3
y = x++; // Post-increment: y gets 3 (the old value of x), then x becomes 4
Serial.println(y); // Prints 3
Serial.println(x); // Prints 4
In this case:
● The pre-increment ++x first increments x to 3, and then assigns this
new value to y .
● The post-increment x++ assigns the original value of x (3) to y and
then increments x to 4.
Real-Life Example:
Imagine you're counting steps while walking:
● Each time you take a step, you increase your step count by 1. The ++
operator automates this by adding 1 to your count with each iteration.
Incrementing a Counter
Component List:
● 1 Arduino Board
Code:
Explanation:
● The program starts a counter at 0 and increments it by 1 each time using
the ++ operator.
● The updated counter value is printed to the serial monitor every second.
Hints:
● Use ++ in loops or counters where you need to increase a value by 1
with each iteration.
● Be mindful of overflow, especially when using unsigned types, where the
value could wrap back to 0 after reaching the maximum value.
Chapter-13 Control Structures in
Arduino Programming
Overview:
This chapter focuses on control structures, which are the building blocks
for decision-making, loops, and flow control in Arduino programming.
Understanding these will allow you to create dynamic and interactive
projects that respond to different conditions, such as sensor inputs or user
actions.
1. if Statement: Executes code based on a condition. If the
condition is true, it runs the code; otherwise, it skips it.
2. if...else Statement: Adds more flexibility by providing alternative
actions when a condition is false.
3. for Loop: Repeats a block of code a specific number of times.
Useful for iterating through data or controlling repeated actions.
4. while Loop: Repeats a block of code as long as a condition
remains true. It’s useful for tasks where the number of repetitions
is not fixed.
5. do...while Loop: Similar to the while loop, but guarantees the
code runs at least once before checking the condition.
6. switch...case Statement: Simplifies decision-making when a
single variable needs to be compared against several possible
values.
7. break Statement: Exits a loop or switch statement early, stopping
the current process.
8. continue Statement: Skips the current iteration of a loop and
proceeds to the next one.
9. return Statement: Exits a function and optionally sends a value
back to the caller.
10. goto Statement: Jumps to a labeled point in the code, useful for
breaking out of nested loops (though generally discouraged).
Where to Use the if Statement: You use the if statement when you
want your program to only do something if a certain condition is met.
For example:
● If a sensor detects motion, turn on a light.
● If a password is correct, allow access to an account.
● If the temperature is below a set point, turn on the heater.
The if statement helps you control what actions should happen based
on different situations.
if (condition) {
// action to do if the condition is true
}
Example Code:
Here’s an example using an if statement to control an LED light based
on a sensor reading:
In this example:
● The if statement checks if the sensorValue is greater than 50.
● If the sensorValue is greater than 50, the LED will turn on.
● If the sensorValue is 50 or lower, the LED will stay off.
Real-Life Application:
A real-life example of an if statement would be a smart thermostat. The
thermostat checks the current temperature of a room. If the temperature
is below 20°C, it will turn on the heater. Otherwise, it does nothing. This
allows the thermostat to react to the environment and keep the room at a
comfortable temperature.
Practical Exercise:
To help you get hands-on with the if statement, try this simple project:
Control an LED with a button press.
Component List:
● 1 LED
● 1 Button
● 1 Resistor (220Ω)
● Jumper wires
● Arduino Board
Circuit Connection:
● Connect one leg of the LED to pin 13 on the Arduino.
● Connect the other leg to a resistor and then to GND (ground).
● Connect one side of the button to pin 7 and the other side to GND.
Code Example:
int buttonPin = 7; // Pin connected to the button
int LEDpin = 13; // Pin connected to the LED
void setup() {
pinMode(buttonPin, INPUT); // Set the button pin as input
pinMode(LEDpin, OUTPUT); // Set the LED pin as output
}
void loop() {
int buttonState = digitalRead(buttonPin); // Read the button state
if (buttonState == HIGH) { // If the button is pressed
digitalWrite(LEDpin, HIGH); // Turn on the LED
} else {
digitalWrite(LEDpin, LOW); // Otherwise, turn off the LED
}
}
In this project:
● The LED turns on only when the button is pressed.
● The if statement checks the state of the button and reacts
accordingly.
Hints:
● Try changing the condition in the if statement to experiment with
different behaviors.
● Add more actions or conditions to create more complex interactions
in your program.
Where to Use the if...else Statement: Use the if...else statement when
you want to handle different actions for different conditions. For
example:
● If a temperature is very high, shut down the system.
● If the temperature is a little high, show a warning.
● If the temperature is normal, continue working.
It’s helpful when you have more than one condition to check and want
different actions based on each condition.
Syntax:
if (condition1) {
// Do something if condition1 is true
}
else if (condition2) {
// Do something else if condition2 is true
}
else {
// Do something if none of the above conditions are true
}
Example Code:
Here’s a simple example using an if...else statement to control a
temperature sensor system:
Real-Life Application:
Imagine you’re driving a car:
● If you see a red light, you stop the car.
● If you see a yellow light, you slow down.
● If you see a green light, you keep driving.
This is exactly how the if...else statement works in programming. It
checks different conditions and acts based on what it finds.
Practical Exercise:
Let’s try a simple project: Control an LED based on a temperature
sensor reading.
Component List:
● 1 LED
● 1 Temperature Sensor
● Jumper wires
● Resistor (220Ω)
● Arduino Board
Circuit Connection:
● Connect the temperature sensor to A0 on the Arduino.
● Connect the LED to pin 13 through the resistor, and connect the other
side to GND.
Code Example:
int tempSensor = A0; // Pin for the temperature sensor
int LEDpin = 13; // Pin for the LED
int temperature = 0; // Variable to store temperature
void setup() {
pinMode(LEDpin, OUTPUT); // Set the LED pin as output
Serial.begin(9600); // Start the serial monitor
}
void loop() {
temperature = analogRead(tempSensor); // Read temperature sensor data
if (temperature >= 70) {
digitalWrite(LEDpin, HIGH); // Turn on the LED if temp is high
Serial.println("Danger! System shutdown.");
}
else if (temperature >= 60) {
digitalWrite(LEDpin, HIGH); /60-70
delay(500);
digitalWrite(LEDpin, LOW);
delay(500);
Serial.println("Warning! Check the system.");
}
else {
digitalWrite(LEDpin, LOW); safe
Serial.println("System is safe.");
}
delay(1000); // Wait for 1 second before the next check
}
In this code:
● The LED turns on solid if the temperature is too high (>= 70).
● The LED flashes if the temperature is a little high (60-69).
● The LED stays off if the temperature is safe (< 60).
Hints:
● Try adding more conditions with else if to make your program
handle more situations.
● Play around with different temperature values to see how the
system reacts.
Why is the for Loop Useful? The for loop saves time and makes your
code shorter and easier to manage. Instead of writing the same action
multiple times, the for loop does it for you. This is especially helpful
when working with sensors, LEDs, or even large data sets.
Syntax:
Example Code:
Here’s an example of using a for loop to brighten an LED gradually:
Explanation:
● Initialization: int i = 0; sets the variable i to start at 0.
● Condition: The loop runs while i <= 255 (as long as i is less than
or equal to 255).
● Increment: Each time the loop runs, i increases by 1 ( i++ ).
In this code, the brightness of the LED gradually increases from 0 (off)
to 255 (full brightness).
Real-Life Application:
Think of the for loop like counting stairs:
● Initialization: Start on step 1.
● Condition: Keep climbing as long as you haven't reached the top.
● Increment: Move up one step each time.
In programming, the for loop counts and repeats tasks, just like climbing
stairs, until the condition is no longer true.
Practical Exercise:
Let’s make an LED fade up and down using a for loop.
Component List:
● 1 LED
● 1 Resistor (220Ω)
● Jumper wires
● Arduino Board
Circuit Connection:
● Connect the LED to pin 10 through the resistor and then to GND.
Code Example:
Explanation:
● The first for loop makes the LED fade up from 0 (off) to 255 (full
brightness).
● The second for loop makes the LED fade down from 255 back to 0.
Hints:
● Try changing the delay to see how the speed of the fade changes.
● Experiment with different ranges for i to control how bright the LED
gets.
Why is the while Loop Useful? The while loop allows your program
to keep doing something continuously until something changes. This is
great for tasks like monitoring sensors or waiting for user input, where
you don't know in advance how many times the loop needs to run.
Syntax:
while (condition) {
// Code to repeat
}
● Condition: This is the test that the program checks before each loop. If
it's true, the loop runs. If it's false, the loop stops.
Example Code:
Here’s an example where a variable increases until it reaches 200:
int var = 0;
while (var < 200) {
// Do something repetitive 200 times
var++; // Increase var by 1 each time
}
Explanation:
● The while loop keeps running as long as var is less than 200.
● The code inside the loop increases var by 1 each time, so eventually,
it reaches 200, and the loop stops.
Real-Life Example:
Imagine you’re filling a glass of water:
● You keep filling the glass while it’s not full.
● Once the glass is full, you stop.
In programming, the while loop works the same way. It keeps running a
task while the condition is true and stops when the condition becomes
false.
Practical Exercise:
Let’s try a project where an LED blinks repeatedly until a button is
pressed.
Component List:
● 1 LED
● 1 Button
● 1 Resistor (220Ω)
● Jumper wires
● Arduino Board
Circuit Connection:
● Connect the LED to pin 13 through the resistor and then to GND.
● Connect one side of the button to pin 7 and the other side to GND.
Code Example:
Explanation:
● The LED will keep blinking on and off while the button is not
pressed.
● As soon as the button is pressed, the while loop stops, and the
blinking stops.
Hints:
● Try using a sensor instead of a button to see how the loop behaves
based on external conditions.
● Be careful not to create an infinite loop (a loop that never ends).
Always make sure the condition can change!
Where to Use the do...while Loop: The do...while loop is useful when
you want to guarantee that a block of code runs at least one time, no
matter what. For example:
● Read sensor data at least once, even if the initial condition is false.
● Ask a user for input until they give the correct answer.
Why is the do...while Loop Useful? The do...while loop ensures that
the code block inside the loop runs at least once, regardless of whether
the condition is true or false. This can be helpful when you need to
perform a task before checking a condition, like initializing hardware or
reading a sensor.
Syntax:
do {
// Code to run
} while (condition);
● Condition: This is the test that the program checks after the code has
run. If it’s true, the loop repeats. If it’s false, the loop stops.
Example Code:
Here’s an example of a do...while loop that checks sensors and repeats
100 times:
int x = 0;
int i = 0;
do {
delay(50); // Wait for sensors to stabilize
x = readSensors(); // Check the sensors
i++; // Increase i by 1
} while (i < 100); // Repeat 100 times
Explanation:
● The code inside the loop will run once before checking the
condition.
● The loop will then repeat while i is less than 100.
Real-Life Example:
Imagine you're baking cookies:
● You have to taste the first cookie to check if it's good (do it once).
● Then, based on how the cookie tastes, you decide whether to keep
making more or stop.
In programming, the do...while loop always runs once before checking
if it should continue.
Practical Exercise:
Let’s try a project where an LED blinks at least once, and then keeps
blinking until a button is pressed.
Component List:
● 1 LED
● 1 Button
● 1 Resistor (220Ω)
● Jumper wires
● Arduino Board
Circuit Connection:
● Connect the LED to pin 13 through the resistor and then to GND.
● Connect one side of the button to pin 7 and the other side to GND.
Code Example:
Explanation:
● The LED will blink at least once, and keep blinking until the
button is pressed.
● Once the button is pressed, the do...while loop ends, and the LED
stops blinking.
Hints:
● Try changing the condition to see how it affects when the loop
stops.
● Use sensors or other inputs to control the do...while loop in
different ways.
Syntax:
switch (var) {
case label1:
// Do something if var equals label1
break;
case label2:
// Do something if var equals label2
break;
default:
// Do something if none of the cases match
break;
}
Example Code:
Here’s a simple example of how to use switch...case to control an action
based on the value of a variable:
int mode = 2;
switch (mode) {
case 1:
// If mode equals 1
Serial.println("Mode 1: Start the system");
break;
case 2:
// If mode equals 2
Serial.println("Mode 2: Stop the system");
break;
default:
// If mode doesn't match 1 or 2
Serial.println("Unknown mode");
break;
}
In this example:
● If mode is 1, the program starts the system.
● If mode is 2, the program stops the system.
● If mode doesn’t match 1 or 2, it prints "Unknown mode."
Real-Life Example:
Imagine you’re using a remote control:
● If you press button 1, the TV turns on.
● If you press button 2, the TV turns off.
● If you press any other button, nothing happens.
The switch...case statement works the same way—depending on the
value (button pressed), it runs a specific action.
Practical Exercise:
Let’s build a project where you control an LED based on a number input
using the switch...case statement.
Component List:
● 1 LED
● 1 Resistor (220Ω)
● Jumper wires
● Arduino Board
Circuit Connection:
● Connect the LED to pin 13 through the resistor and then to GND.
Code Example:
Explanation:
● The switch checks the mode value.
● If mode is 1, the LED turns on.
● If mode is 2, the LED turns off.
● If mode is neither 1 nor 2, it prints "Unknown mode."
Hints:
● Try adding more cases to control other devices or actions.
● Use a sensor to change the mode automatically.
Why is It Useful?
The break statement is useful because it lets you control when to stop a
loop or switch case. This makes your program more efficient because it
doesn't waste time checking conditions that are no longer necessary.
Syntax:
break
;
In a loop:
In a switch statement:
switch (var) {
case 1:
// Do something
break;
case 2:
// Do something else
break;
default:
// Default action
break;
}
Example Code: In this code, the loop stops as soon as the sensor value
exceeds the threshold:
Explanation:
● The loop runs, increasing the brightness of an LED using
analogWrite() .
● If the sensor value goes over 40, the break statement is triggered,
and the loop stops immediately.
● This is useful if you want to react quickly to a condition without
waiting for the loop to finish.
Real-Life Example:
Imagine you’re looking for a book in a library:
● You check each shelf until you find the book.
● Once you find it, you stop searching—there’s no need to check the
rest of the shelves.
This is how break works in programming. It stops the loop once the task
is done.
Practical Exercise
Exiting a Loop Early with break
Component List:
● 1 LED
● 1 Resistor (220Ω)
● Jumper wires
● Arduino Board
● Sensor (for reading values)
Circuit Connection:
● Connect the LED to pin 10 with the resistor.
● Connect the sensor to A0.
Code:
int threshold = 40; // Set a threshold for the sensor
int sensorPin = A0; // Sensor connected to pin A0
int PWMpin = 10; // LED connected to pin 10
void setup() {
pinMode(PWMpin, OUTPUT); // Set LED pin as output
Serial.begin(9600); // Start serial monitor
}
void loop() {
for (int i = 0; i <= 255; i++) {
int sensorValue = analogRead(sensorPin); // Read sensor value
analogWrite(PWMpin, i); // Adjust LED brightness
if (sensorValue > threshold) {
Serial.println("Threshold reached, stopping.");
break; // Stop the loop if sensor value exceeds the threshold
}
delay(50); // Wait before next loop
}
}
Explanation:
● The loop increases the LED brightness.
● If the sensor reading goes above the threshold (40 in this case), the
loop stops immediately, and the LED stays at its current brightness.
Hints:
● Use break carefully in loops to avoid unnecessary checks and save
time.
● In switch statements, always add break to prevent the program from
accidentally running into the next case.
Why is It Useful?
The continue statement is useful because it allows you to skip certain
conditions without stopping the entire loop. This makes your code more
efficient when you only want to avoid specific cases but still keep
looping.
Syntax:
Example Code:
Here’s an example where we skip certain values (between 41 and 119)
when writing to a PWM pin:
Explanation:
● The loop normally increases the PWM value from 0 to 255.
● When the value of x is between 41 and 119, the continue statement
skips the analogWrite() and moves directly to the next loop iteration.
● Values outside this range still get processed as usual.
Real-Life Example:
Imagine you're going down a list of things to buy:
● If you already have an item on the list, you skip it and move on to the
next one.
● You don’t stop shopping, you just ignore certain items while
continuing to buy the rest.
In programming, the continue statement works the same way: it skips
certain conditions and moves on with the loop.
Practical Exercise
Skipping LED Brightness Levels
Component List:
● 1 LED
● 1 Resistor (220Ω)
● Jumper wires
● Arduino Board
Circuit Connection:
● Connect the LED to pin 10 through the resistor and then to GND.
Code:
int PWMpin = 10; // Pin connected to the LED
void setup() {
pinMode(PWMpin, OUTPUT); // Set the LED pin as output
}
void loop() {
for (int brightness = 0; brightness <= 255; brightness++) {
if (brightness > 40 && brightness < 120) { // Skip values from 41 to 119
continue;
}
analogWrite(PWMpin, brightness); // Set LED brightness
delay(50); // Wait 50ms before the next step
}
}
Explanation:
● The LED will gradually brighten and dim.
● The brightness values between 41 and 119 are skipped due to the
continue statement, so the LED will jump from brightness 40 to 120
without showing the skipped levels.
Hints:
● Use continue carefully to skip unnecessary steps but still allow
the loop to run.
● Combine continue with conditional checks to control which
iterations are skipped.
Why is It Useful?
The return statement is essential because it allows functions to send data
back to other parts of the program. This helps make your code modular
and reusable. Without return , functions would not be able to
communicate results, making it harder to manage complex programs.
Syntax:
Example Code:
Here’s a function that checks if a sensor value is above a certain threshold
and returns a result:
int checkSensor() {
if (analogRead(A0) > 400) {
return 1; // If the sensor value is greater than 400, return 1
} else {
return 0; // Otherwise, return 0
}
}
In this example:
● The function reads a sensor value.
● If the value is above 400, the function returns 1, meaning "yes, it's
above the threshold."
● If it’s not, the function returns 0.
Real-Life Example:
Imagine you’re baking cookies:
● You put a cookie in your mouth and check if it’s sweet.
● If it’s sweet, you return the answer, "Yes, it’s sweet."
● If it’s not, you return, "No, it’s not sweet."
In programming, return works the same way—it checks a condition and
then sends back a result to the main part of the program.
Practical Exercise
Checking Sensor and Returning Results
Component List:
● 1 Sensor (e.g., light or temperature sensor)
● Jumper wires
● Arduino Board
Circuit Connection:
● Connect the sensor to pin A0.
Code:
int checkSensor() {
int sensorValue = analogRead(A0); // Read sensor value
if (sensorValue > 400) { // Check if value is greater than 400
return 1; // Return 1 if true
} else {
return 0; // Return 0 if false
}
}
void setup() {
Serial.begin(9600); // Start serial monitor
}
void loop() {
int result = checkSensor(); // Call the function and store the return value
if (result == 1) {
Serial.println("Sensor is above threshold!"); // Print if sensor is above 400
} else {
Serial.println("Sensor is below threshold."); // Print if sensor is below 400
}
delay(1000); // Wait for 1 second before checking again
}
Explanation:
● The checkSensor() function reads the sensor value and returns either
1 or 0, depending on whether the value is above or below the
threshold.
● The result is then printed in the loop() .
Hints:
● Use return when you want to send data from a function back to the
main part of your code.
● You can return any type of data, like integers, strings, or even objects.
Why is It Useful?
goto can help simplify your code in very specific cases. For example, if
you're deep inside several for loops and you want to exit all of them at
once, goto allows you to jump out quickly without using multiple break
statements.
However, overusing goto can make the program confusing and difficult
to debug, so it’s best to avoid it unless absolutely necessary.
Syntax:
Example Code:
Here’s an example where the program jumps out of deeply nested loops if
a condition is met:
Explanation:
● The program is running through nested loops.
● If the sensor value read by analogRead(0) is higher than 250, the
program jumps to the bailout label and exits all loops.
● After jumping, it prints "Exited the loops early!"
Real-Life Example:
Imagine you're filling out a form with many questions:
● If you encounter a major problem (like realizing you're filling out the
wrong form), you immediately skip to the end of the form without
finishing the rest.
● In programming, goto works similarly—it skips sections of code and
jumps to the end or another part when needed.
Practical Exercise
Using goto to Exit Nested Loops
Component List:
● 1 Sensor (e.g., temperature or light sensor)
● Jumper wires
● Arduino Board
Circuit Connection:
● Connect the sensor to pin A0.
Code:
int sensorPin = A0; // Pin connected to the sensor
void setup() {
Serial.begin(9600); // Start serial monitor
}
void loop() {
for (int i = 0; i < 255; i++) {
for (int j = 255; j > 0; j--) {
if (analogRead(sensorPin) > 300) { // If sensor value is above 300
goto endLoop; // Jump to the end of the loop
}
// Other code here (e.g., controlling LEDs)
}
}
endLoop:
Serial.println("Exited loops due to sensor value.");
delay(1000); // Wait 1 second before the next loop
}
Explanation:
● The loops are running and checking sensor values.
● When the sensor reading goes above 300, the program jumps to the
endLoop label and exits both loops.
● The goto helps us get out of nested loops quickly.
Hints:
● Avoid overusing goto , as it can make your program harder to read.
● Use goto only when necessary, such as when breaking out of deeply
nested loops.