Arduino PDF
Arduino PDF
#arduino
Table of Contents
About 1
Remarks 2
What is Arduino? 2
Versions 2
Examples 2
Bare Minimum 2
Blink 3
Setup 5
Upload 7
Serial monitor 7
Syntax 9
Remarks 9
Examples 9
Examples 11
Installing on Windows 11
Installing on Fedora 11
Installing on Ubuntu 11
Installing on macOS 11
Parameters 12
Examples 12
Basic Note Outputs 12
Parameters 13
Remarks 14
Examples 14
Examples 15
cardInfo 15
SD card datalogger 17
Listfiles 20
SD card read/write 22
Syntax 24
Parameters 24
Remarks 24
Examples 24
Pushbutton reading 24
Syntax 26
Examples 26
Write to pin 26
Chapter 9: Functions 27
Remarks 27
Examples 27
Call a function 27
Examples 29
Arduino Uno R3 29
Syntax 32
Parameters 32
Remarks 32
Examples 32
Chapter 12: How to store variables in EEPROM and use them for permanent storage 34
Syntax 34
Parameters 34
Remarks 34
Examples 34
Introduction 36
Examples 36
Multiple slaves 36
Syntax 39
Parameters 39
Remarks 39
Examples 39
Introduction 41
Examples 41
Introduction 44
Syntax 44
Parameters 44
Examples 44
Basic Usage 44
Syntax 46
Remarks 46
Examples 46
While 46
For 47
Do ... While 47
Flow Control 48
Introduction 49
Examples 49
Examples 57
The basics 57
The build 58
The code 58
Syntax 60
Parameters 60
Remarks 60
Examples 60
Generate a random number 60
Setting a seed 61
Syntax 62
Parameters 62
Remarks 62
Examples 63
Arduino: 64
Python: 65
Introduction 66
Syntax 66
Examples 66
Remarks 67
Transactions 67
Examples 68
Basics: initialize the SPI and a chip select pin, and perform a 1-byte transfer 68
Syntax 70
Remarks 70
Implementation details 70
Examples 71
blocking blinky with delay() 71
Remarks 75
Setup 75
Connections 75
Debugging considerations 77
Software setup 79
Benefits 80
Examples 81
Examples 82
Create variable 82
Variable types 82
Credits 84
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: arduino
It is an unofficial and free arduino ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official arduino.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to info@zzzprojects.com
https://riptutorial.com/ 1
Chapter 1: Getting started with arduino
Remarks
What is Arduino?
Arduino is an open-source electronics platform based on easy-to-use hardware and software.
Versions
1.0.0 2016-05-08
Examples
Bare Minimum
Here's the 'bare minimum' Arduino sketch. This can be loaded into the Arduino IDE by choosing
File > Examples > 01. Basics > Bare Minimum.
void setup() {
// put your setup code here, to run once
}
void loop() {
// put your main code here, to run repeatedly
}
Code in the setup() function will be run once when the program starts. This is useful to set up I/O
pins, initialize variables, etc. Code in the loop() function will be run repeatedly until the Arduino is
switched off or a new program is uploaded. Effectively, the code above looks like this inside the
Arduino runtime library:
setup();
while(1) {
https://riptutorial.com/ 2
loop();
}
Unlike programs running on your computer, Arduino code can never quit. This is because the
microcontroller only has one program loaded into it. If this program quit there would be nothing to
tell the microcontroller what to do.
Blink
Here's a short example that demonstrates the setup() and loop() functions. This can be loaded
into the Arduino IDE by choosing File > Examples > 01. Basics > Blink. (Note: Most Arduino
boards have an LED already connected to pin 13, but you may need to add an external LED to
see the effects of this sketch.)
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin 13 as an output.
pinMode(13, OUTPUT);
}
1. Defines the setup() function. The setup() function gets called first on execution in every
Arduino program.
Without this, it might be set to an input, which would make the LED not work; however
once it is set as an output it will stay that way so this only needs to be done once when
the program starts.
2. Defines the loop() function. The loop() function is called repeatedly for as long as the
program is running.
Because loop() is run repeatedly for as long as the program is running, the LED will flash on and
off with a period of 2 seconds (1 second on, 1 second off). This example is based off of the
Arduino Uno and any other board that already has an LED connected to Pin 13. If the board that is
being used does not have an on-board LED connected to that pin, one can be attached externally.
https://riptutorial.com/ 3
More on timing (for example delays and measuring time): Time Management
https://riptutorial.com/ 4
https://riptutorial.com/ 5
functions. This is enough to upload to an Arduino board, but it will do nothing at all. The "Blink"
example sketch works as a simple test when first using an Arduino board. Go to File → Examples
→ 01.Basics → Blink. This will open a new window with the Blink sketch.
Select the COM port for your board. Most Aurduino-compatible boards will create a fake COM
port, which is used for serial communication (debugging) and for programming the board. COM 1
https://riptutorial.com/ 6
is usually already present, and your board will create a new one, e.g. COM 4. Select this from
Tools → Port → COM 4 (or other COM number).
Some boards have additional settings in the Tools menu, such as clock speed. These vary from
board to board, but usually an acceptable set of defaults is already selected.
Upload
You are now ready to upload Blink. Click the Upload button or select Sketch → Upload. The
sketch will compile, then upload to your Arduino board. If everything worked, the on-board LED will
start blinking on and off every second.
Serial monitor
In the Arduino IDE ypu hava a serial monitor. To open it use the button serial monitor at the right
side of the window.
Be sure that the code is uploaded before you open the monitor. The upload and monitor will not
run at the same time!
You can also use this code to setup an LED with a button switch with a pull up resistor, this could
preferably be with the next step after setting up the intial LED controller
void setup()
{
// initialize the LED pin as an output:
pinMode(13, OUTPUT); // You can set it just using its number
// initialize the pushbutton pin as an input:
pinMode(2, INPUT);
}
void loop()
{
// read the state of the pushbutton value:
buttonState = DigitalRead(2);
https://riptutorial.com/ 7
digitalWrite(13, LOW);
}
else
{
// turn LED off:
digitalWrite(13, HIGH);
}
}
https://riptutorial.com/ 8
Chapter 2: Analog Inputs
Syntax
• analogRead(pin) //Read from the given pin.
Remarks
Serial.println(val)
Examples
Print out an Analog Value
void setup() {
Serial.begin(9600); //Begin serializer to print out value
void loop() {
Analog pins can be used to read voltages which is useful for battery monitoring or interfacing with
analog devices. By default the AREF pin will be the same as the operating voltage of the arduino,
but can be set to other values externally. If the voltage to read is larger than the input voltage, a
potential devider will be needed to lower the analog voltage.
int ADCValue = 0;
https://riptutorial.com/ 9
float voltage = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
readADC();
Serial.print(voltage); Serial.println("V");
}
void readADC()
{
ADCValue = analogRead(analogPin);
float = ( ( (float)ADCValue/ADCRange ) * AREFValue ); //Convert the ADC value to a
float, devide by the ADC resolution and multiply by the AREF voltage
}
https://riptutorial.com/ 10
Chapter 3: Arduino IDE
Examples
Installing on Windows
1. Go to https://www.arduino.cc/en/Main/Software
2. Click the "Windows Installer" link
3. Follow the instructions
1. Go to https://www.arduino.cc/en/Main/Software
2. Click the "Windows ZIP file for non admin install" link
3. Extract the archive to a folder
4. Open the folder, and double click Arduino.exe
Installing on Fedora
Installing on Ubuntu
Installing on macOS
1. Go to https://www.arduino.cc/en/Main/Software
2. Click the Mac OS X link.
3. Unzip the .zipfile.
4. Move the Arduino application to Applications.
https://riptutorial.com/ 11
Chapter 4: Audio Output
Parameters
Parameter Details
Examples
Basic Note Outputs
#define NOTE_C4 262 //From pitches.h file defined in [Arduino Tone Tutorial][1]
int Key = 2;
int KeyVal = 0;
void setup()
{
pinMode(Key, INPUT); //Declare our key (button) as input
pinMode(speaker, OUTPUT);
}
void loop()
{
KeyVal = digitalRead(Key);
if (KeyVal == HIGH) {
tone(speaker, NOTE_C4); //Sends middle C tone out through analog speaker
} else {
noTone(speaker); //Ceases tone emitting from analog speaker
}
delay(100);
}
[1]: https://www.arduino.cc/en/Tutorial/toneMelody
https://riptutorial.com/ 12
Chapter 5: Bluetooth Communication
Parameters
method details
SoftwareSerial.h Documentation
Prints data to the transmit pin of the software serial port. Works
print(data)
the same as the Serial.print() function.
Prints data to the transmit pin of the software serial port, followed
println(data) by a carriage return and line feed. Works the same as the
Serial.println() function.
https://riptutorial.com/ 13
method details
listening).
Prints data to the transmit pin of the software serial port as raw
write(data)
bytes. Works the same as the Serial.write() function.
Remarks
Common Mistake : If you keep the rx and tx pins at default values (0 and 1), you cannot upload
new code until and unless you remove it, so it's almost always better to change the tx and rx pins
in the SoftwareSerial constructor.
Examples
Basic bluetooth hello world
#include <SoftwareSerial.h>
// its always better to change the default tx and rx as the may interfere with other process
in future.
void loop() {
// put code that you want it to run every time no matter what
if(blue.available()){
// put only that code which needsd to run when there is some data
// This means that the their is some data sent over the bluetooth
// You can do something with the data
int n;
// consider that the data received to be integer, read it by using blue.parseInt();
n = blue.parseInt();
https://riptutorial.com/ 14
Chapter 6: Data Storage
Examples
cardInfo
/*
SD card test
This example shows how use the utility libraries on which the'
SD library is based in order to get info about your SD card.
Very useful for testing a card when you're not sure whether its working or not.
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
** CS - depends on your SD card shield or module.
Pin 4 used here for consistency with other Arduino examples
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("\nInitializing SD card...");
https://riptutorial.com/ 15
Serial.println("* is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
return;
} else {
Serial.println("Wiring is correct and a card is present.");
}
Serial.println("\nFiles found on the card (name, date and size in bytes): ");
root.openRoot(volume);
void loop(void) {
https://riptutorial.com/ 16
SD card datalogger
/*
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card using the SD library.
The circuit:
* analog sensors on analog ins 0, 1, and 2
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
*/
#include <SPI.h>
#include <SD.h>
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
void loop()
{
// make a string for assembling the data to log:
String dataString = "";
https://riptutorial.com/ 17
}
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
/*
SD card file dump
This example shows how to read a file from the SD card using the
SD library and send it over the serial port.
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
*/
#include <SPI.h>
#include <SD.h>
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
https://riptutorial.com/ 18
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt");
void loop()
{
/*
SD card basic file example
*/
#include <SPI.h>
#include <SD.h>
File myFile;
void setup()
{
// Open serial communications and wait for port to open:
https://riptutorial.com/ 19
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
}
void loop()
{
// nothing happens after setup finishes.
}
Listfiles
/*
Listfiles
The circuit:
https://riptutorial.com/ 20
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
#include <SPI.h>
#include <SD.h>
File root;
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
root = SD.open("/");
printDirectory(root, 0);
Serial.println("done!");
}
void loop()
{
// nothing happens after setup finishes.
}
https://riptutorial.com/ 21
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs+1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
SD card read/write
/*
SD card read/write
This example shows how to read and write data to and from an SD card file
The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4
*/
#include <SPI.h>
#include <SD.h>
File myFile;
void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);
https://riptutorial.com/ 22
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
void loop()
{
// nothing happens after setup
}
https://riptutorial.com/ 23
Chapter 7: Digital Inputs
Syntax
• pinMode(pin, pinMode) // Sets the pin to the mode defined.
• digitalRead(pin); // Reads the value from a specified digital pin,
Parameters
Paramter Details
Remarks
If the input pin is not pulled LOW or HIGH, the value will float. That is, it won't be clearly a 1 or a 0,
but somewhere in between. For digital input, a pullup or pulldown resistor is a necessity.
Examples
Pushbutton reading
This is an basic example on how to wire up and make an LED turn on/off when the pushbutton is
pressed.
https://riptutorial.com/ 24
* pin 13, when pressing a pushbutton attached to pin 7. It illustrates the
* concept of Active-Low, which consists in connecting buttons using a
* 1K to 10K pull-up resistor.
*
* Created 1 December 2005
* copyleft 2005 DojoDave <http://www.0j0.org>
* http://arduino.berlios.de
*
*/
void setup() {
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inPin, INPUT); // declare pushbutton as input
}
void loop(){
val = digitalRead(inPin); // read input value
if (val == HIGH) { // check if the input is HIGH (button released)
digitalWrite(ledPin, LOW); // turn LED OFF
} else {
digitalWrite(ledPin, HIGH); // turn LED ON
}
}
https://riptutorial.com/ 25
Chapter 8: Digital Output
Syntax
• digitalWrite(pin, value)
Examples
Write to pin
void setup()
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}
void loop()
{
digitalWrite(ledPin, HIGH); // sets the LED on
delay(1000); // waits for a second
digitalWrite(ledPin, LOW); // sets the LED off
delay(1000); // waits for a second
}
Example at Arduino.cc.
https://riptutorial.com/ 26
Chapter 9: Functions
Remarks
Other than in ordinary C / C++ , the Arduino IDE allows to call a function before it is defined.
In .cpp files, you have to define the function, or at least declare the function prototype before you
can use it.
In an .ino file, the Arduino IDE creates such a prototype behind the scenes.
Examples
Create simple function
return a*a : return a value (same type as the return type defined at the beginning)
Call a function
If you have a function declared you can call it anywhere else in the code. Here is an example of
calling a function:
https://riptutorial.com/ 27
void setup(){
Serial.begin(9600);
}
void loop() {
int i = 2;
int squareNum(int a) {
return a*a;
}
https://riptutorial.com/ 28
Chapter 10: Hardware pins
Examples
Arduino Uno R3
Microcontrollers use pins to interact with the rest of the circuit. These pins will usually be one of
input / output pins, vin or ground. I/O pins can be simple digital I/O pins, or they can have some
special carachteristics like being able to vary the voltage of their output using pulse width
modulation. Here's a schematic of the Arduino R3 Uno and its pins.
https://riptutorial.com/ 29
(source)
PWM Pins
https://riptutorial.com/ 30
PWM allows you to control the voltage of the output by switching the output between high and low
very very quickly. The percentage of time the pin is high is called its 'duty cycle'.
Analog Inputs
Just like a PWM pin can put out a range of voltages, analog pins on the Arduino Uno R3 can
sense a range of oinput voltages. You might use this to read the position of a potentiometer or
another input with a smoothly variable input. Please note that analog pins can't do analogWrite
output - for this you need to use PWM pins.
The serial pins on the Arduino Uno R3 are also used by (for instance) the USB to Serial chip when
it communicates with a computer via the on board USB port. Serial: Tx on 0, Rx on 1
SPI and I2C are communication protocols the Arduino can use to talk to shields, sensors, outputs
etc...:
On-board LED
The Arduino Uno R3 has an LED with its own resistor attached to pin 13. This means that even if
you don't attach any LEDs to your board, if you set pin 13 to an output and set it high, you should
see an LED on the board come on. Use the 'Blink' example sketch to locate your onboard LED.
NOTE: Digital pin 13 is harder to use as a digital input than the other digital pins
because it has an LED and resistor attached to it that's soldered to the board on most
boards. If you enable its internal 20k pull-up resistor, it will hang at around 1.7V instead
of the expected 5V because the onboard LED and series resistor pull the voltage level
down, meaning it always returns LOW. If you must use pin 13 as a digital input, set its
pinMode() to INPUT and use an external pull down resistor.
https://riptutorial.com/ 31
Chapter 11: How Python integrates with
Arduino Uno
Syntax
• Serial.begin(baudrate) // Set baud rate (bits per second) for serial data transmission
• Serial.println(value) // Print data to serial port followed by Carriage Return \r and
Newline character \n
• serial.Serial((port=None, baudrate=9600, bytesize=EIGHTBITS, parity=PARITY_NONE,
stopbits=STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, write_timeout=None,
dsrdtr=False, inter_byte_timeout=None) // Initialize serial port with all parameters
• serial.readline() // Read serial data which contains Carriage Return \r and Newline
character \n
Parameters
Parameter Details
serial Python package contains classes and methods to access serial port
Remarks
I use an Arduino Uno with Arduino IDE 1.6.9 and Python 2.7.12 running in Windows 10.
Examples
First serial communication between Arduino and Python
In this very first example, a basic serial write operation is started from an Arduino device.
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("Hello World!");
delay(100);
}
In setup(), function Serial.begin(9600) sets up the baud rate for serial data communication. In this
example, a baud rate of 9600 is used. Other values can be read here: Arduino Serial.begin()
function
https://riptutorial.com/ 32
In loop(), the first message we would like to send is "Hello World!". This message is transmitted by
using Serial.println("Hello World!") as it will send this string to serial port in ASCII format. At the
end of the message, there are Carriage Return (CR, \r) and Newline character (\n). Also, a delay
of 100 milliseconds is used each time program prints to serial port.
Next, upload this Arduino sketch via COM port (remember this COM port number as it will be used
in Python program).
The Python program reading serial data sent from Arduino device is shown below:
import serial
import time
First, pyserial package should be imported. For more information about installing pyserial in
Windows environment, please check this instruction: Installing Python and pyserial. Then, we
initialize the serial port with COM port number and baud rate. The baud rate needs to be the same
as used in Arduino sketch.
Received message will be printed in while loop using readline() function. A delay of 100
milliseconds is also used here as same as in Arduino sketch. Please notice that pyserial
readline() function requires a timeout when opening a serial port (pyserial documentation:
PySerial ReadLine).
https://riptutorial.com/ 33
Chapter 12: How to store variables in
EEPROM and use them for permanent
storage
Syntax
• EEPROM.write(address, value); //(Store variables in EEPROM in a particular address)
• EEPROM.read(address); //(Retrieve values from EEPROM and read data stored in
EEPROM)
Parameters
Parameters of
Detail
EEPROM.write
Parameters of
Detail
EEPROM.Read
Remarks
The allowable addresses vary by hardware.
source
Examples
Store a variable in EEPROM and then retrieve it and print to screen
https://riptutorial.com/ 34
#include <EEPROM.h>
// Stores value in a particular address in EEPROM. There are almost 512 addresses present.
// ---------
// Retrieves value from a particular address in EEPROM
// Retrieve value from address 0 in EEPROM
int retrievedVal = EEPROM.read(0); // Retrieves value stored in 0 address in
// EEPROM
Read How to store variables in EEPROM and use them for permanent storage online:
https://riptutorial.com/arduino/topic/5987/how-to-store-variables-in-eeprom-and-use-them-for-
permanent-storage
https://riptutorial.com/ 35
Chapter 13: I2C Communication
Introduction
I2C is a communication protocol that can make two or more Arduino boards talk to each other.
The protocol uses two pins - SDA (data line) and SCL (clock line). Those pins are different from
one Arduino board type to another, so check the board specification. The I2C protocol set one
Arduino board as the master, and all the others as a slave. Each slave has a different address that
the programmer set hard-coded. Remark: Make sure all boards connected to the same VCC
source
Examples
Multiple slaves
The following example shows how the master can receive data from multiple slaves. In this
example the slave sends two short numbers. The first one is for temperature, and the second one
is for moisture. Please notice that the temperature is a float (24.3). In order to use only two bytes
and not four (float is four bytes), I multiple the temperature in 10, and save it as a short. So here is
the master code:
#include <Wire.h>
#define BUFFER_SIZE 4
#define MAX_NUMBER_OF_SLAVES 24
#define FIRST_SLAVE_ADDRESS 1
#define READ_CYCLE_DELAY 1000
byte buffer[BUFFER_SIZE];
void setup()
{
Serial.begin(9600);
Serial.println("MASTER READER");
Serial.println("*************");
void loop()
{
for (int slaveAddress = FIRST_SLAVE_ADDRESS;
slaveAddress <= MAX_NUMBER_OF_SLAVES;
slaveAddress++)
{
Wire.requestFrom(slaveAddress, BUFFER_SIZE); // request data from the slave
if(Wire.available() == BUFFER_SIZE)
{ // if the available data size is same as I'm expecting
// Reads the buffer the slave sent
for (int i = 0; i < BUFFER_SIZE; i++)
{
https://riptutorial.com/ 36
buffer[i] = Wire.read(); // gets the data
}
delay(READ_CYCLE_DELAY);
}
}
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
//=====================
// This is the hard-coded address. Change it from one device to another
#define SLAVE_ADDRESS 1
//=====================
// I2C Variables
#define BUFFER_SIZE 2
#define READ_CYCLE_DELAY 1000
short data[BUFFER_SIZE];
// Temprature Variables
OneWire oneWire(8);
DallasTemperature temperatureSensors(&oneWire);
float m_temperature;
// Moisture Variables
short m_moisture;
// General Variables
https://riptutorial.com/ 37
int m_timestamp;
void setup()
{
Serial.begin(9600);
Serial.println("SLAVE SENDER");
Serial.print("Node address: ");
Serial.println(SLAVE_ADDRESS);
Serial.print("Buffer size: ");
Serial.println(BUFFER_SIZE * sizeof(short));
Serial.println("***********************");
m_timestamp = millis();
Wire.begin(NODE_ADDRESS); // Activate I2C network
Wire.onRequest(requestEvent); // Set the request event handler
temperatureSensors.begin();
}
void loop()
{
if(millis() - m_timestamp < READ_CYCLE_DELAY) return;
void requestEvent()
{
data[0] = m_temperature * 10; // In order to use short, I multiple by 10
data[1] = m_moisture;
Wire.write((byte*)data, BUFFER_SIZE * sizeof(short));
}
https://riptutorial.com/ 38
Chapter 14: Interrupts
Syntax
• digitalPinToInterrupt(pin); // converts a pin id to an interrupt id, for use with attachInterrupt()
and detachInterrupt().
• detachInterrupt(digitalPinToInterrupt(pin));
• detachInterrupt(interrupt);
Parameters
Parameter Notes
Interrupt Service Routine. This is the method which will be executed when the
ISR
interrupt occurs.
What should cause the interrupt to trigger. One of LOW, CHANGE, RISING, or
mode
FALLING. Due boards also allow HIGH.
Remarks
Interrupt Service Routines (ISRs) should be as short as possible, since they pause main program
execution and can thus screw up time-dependent code. Generally this means in the ISR you set a
flag and exit, and in the main program loop you check the flag and do whatever that flag is
supposed to do.
You cannot use delay() or millis() in an ISR because those methods themselves rely on
interrupts.
Examples
Interrupt on Button Press
https://riptutorial.com/ 39
This example uses a push button (tact switch) attached to digital pin 2 and GND, using an internal
pull-up resistor so pin 2 is HIGH when the button is not pressed.
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(INTERRUPT_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), myISR, FALLING); // trigger when
button pressed, but not when released.
}
void loop() {
digitalWrite(LED_PIN, ledState);
}
void myISR() {
ledState = !ledState;
// note: LOW == false == 0, HIGH == true == 1, so inverting the boolean is the same as
switching between LOW and HIGH.
}
One gotcha with this simple example is that push buttons tend to bounce, meaning that when
pressing or releasing, the circuit opens and closes more than once before it settles into the final
closed or open state. This example doesn't take that into account. As a result, sometimes pressing
the button will toggle the LED multiple times, instead of the expected once.
https://riptutorial.com/ 40
Chapter 15: Libraries
Introduction
Here you will find documentation on:
Examples
Installing libraries with the Library Manager
Once you have opened the Library Manager you can use the menu in the top to filter
the results.
• Click on the library you want, select a version in the drop down menu, and click
install.
https://riptutorial.com/ 41
Now your library is installed. In order to use it, you need to include it in your sketch.
Once you have installed a library, you need to include it in your sketch in order to use it.
• Open the Sketch Menu > Include Library and click the Library you want to include.
https://riptutorial.com/ 42
• Now, the IDE has generated the required inclusion tags into your code.
Now the Library is included in your sketch, and you can use it in your code.
https://riptutorial.com/ 43
Chapter 16: Liquid Crystal Library
Introduction
Arduino's Liquid Crystal Library is a library for controlling LCD displays compatible the Hitachi
HD44780 driver, characterised by their 16 pin interface. The 16 pins might be connected via an
I2C interface. These displays contain a matrix of 5x7 pixel blocks used to display characters or
small monochromatic images. The displays are usually named according to how many rows and
columns they have, e.g. 16x2 or 1602 for 16 columns and 2 rows, and 20x4 or 2004 for 20
columns and 4 rows.
Syntax
• #include <LiquidCrystal.h> // Includes the library
• LiquidCrystal(rs, enable, d4, d5, d6, d7) //
• LiquidCrystal(rs, rw, enable, d4, d5, d6, d7)
• LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7)
• LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7)
Parameters
LiquidCrystal
Details
Parameter
rs the number of the Arduino pin that is connected to the RS pin on the LCD
the number of the Arduino pin that is connected to the RW pin on the
rw
LCD (optional)
the number of the Arduino pin that is connected to the enable pin on the
enable
LCD
the numbers of the Arduino pins that are connected to the corresponding
d0 - d7 data pins on the LCD. d0, d1, d2, and d3 are optional; if omitted, the LCD
will be controlled using only the four data lines (d4, d5, d6, d7).
Examples
Basic Usage
/*
Wiring:
LCD pin 1 (VSS) -> Arduino Ground
LCD pin 2 (VDD) -> Arduino 5V
https://riptutorial.com/ 44
LCD pin 3 (VO) -> Arduino Ground
LCD pin 4 (RS) -> Arduino digital pin 12
LCD pin 5 (RW) -> Arduino Ground
LCD pin 6 (E) -> Arduino digital pin 11
LCD pin 11 (D4) -> Arduino digital pin 5
LCD pin 12 (D5) -> Arduino digital pin 4
LCD pin 13 (D6) -> Arduino digital pin 3
LCD pin 14 (D7) -> Arduino digital pin 2
*/
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// start writing on the first row and first column.
lcd.setCursor(0, 0);
// Print a message to the LCD.
lcd.print("hello, world!");
}
void loop() {
// No need to do anything to keep the text on the display
}
https://riptutorial.com/ 45
Chapter 17: Loops
Syntax
• for (declaration, condition, iteration) { }
• while (condition) { }
• do { } while (condition)
Remarks
General Remark If you intend to create a loop to wait for something to happen, you're probably on
the wrong track here. Rather remember that all code after setup() is run from a method called
loop(). So if you need to wait for something, it's easiest to not do anything (or only other
independent stuff) and come back to check for the waiting condition next time.
do { } while(condition) will not evaluate the condition statement until after the first iteration. This
is important to keep in mind if the condition statement has side effects.
Examples
While
A while loop will evaluate its condition, and if true, it will execute the code inside and start over.
That is, as long as its condition evaluates to true, the while loop will execute over and over.
This loop will execute 100 times, each time adding 1 to the variable num:
int num = 0;
while (num < 100) {
// do something
num++;
}
while (true) {
// do something
}
https://riptutorial.com/ 46
The above loop is equivalent to a for loop:
for (;;) {
// do something
}
For
forloops are simplified syntax for a very common loop pattern, which could be accomplished in
more lines with a while loop.
The following is a common example of a for loop, which will execute 100 times and then stop.
int num = 0;
while (num < 100) {
// do something
num++;
}
for (;;) {
// do something
}
while (true) {
// do something
}
Do ... While
A do while loop is the same as a while loop, except that it is guaranteed to execute at least one
time.
int i = 0;
do {
i++;
} while (i < 100);
https://riptutorial.com/ 47
int i = 0;
do {
i++;
} while (i < 0);
If the above loop were merely a while loop, it would execute 0 times, because the condition would
evaluate to false before the first iteration. But since it is a do while loop, it executes once, then
checks its condition before executing again.
Flow Control
break; will exit the current loop, and will not execute any more lines within that loop.
continue; will not execute any more code within the current iteration of the loop, but will remain in
the loop.
The following loop will execute 101 times (i = 0, 1, ..., 100 ) instead of 1000, due to the break
statement:
The following loop will result in j's value being 50 instead of 100, because of the continue
statement:
int j=0;
for (int i = 0; i < 100; i++) {
if (i % 2 == 0) { // if `i` is even
continue;
}
j++;
}
// j has the value 50 now.
https://riptutorial.com/ 48
Chapter 18: MIDI Communication
Introduction
The intent of this topic to demonstrate some basic MIDI programs that show how to operate with
the protocol and progressively add useful features that more complex applications require.
Examples
MIDI THRU Example
The MIDI Thru is simple and easy to test. When working properly you will be able to install your
Arduino project between two MIDI devices, MIDI IN to MIDI OUT and you will be able to verify that
the two device operate together. If you have the ability to measure latency, you will see an
increase due to the serial buffer capture and re-transmit instructions.
boolean byteReady;
unsigned char midiByte;
void setup() {
// put your setup code here, to run once:
// Set MIDI baud rate:
Serial.begin(31250);
byteReady = false;
midiByte = 0;
}
// The little function that gets called each time loop is called.
// This is automated somwhere in the Arduino code.
void serialEvent() {
if (Serial.available()) {
// get the new byte:
midiByte = (unsigned char)Serial.read();
byteReady = true;
}
}
// This is a more complex MIDI THRU. This version uses a queue. Queues are important because
https://riptutorial.com/ 49
some
// MIDI messages can be interrupted for real time events. If you are generating your own
messages,
// you may need to stop your message to let a "real time" message through and then resume your
message.
void setup() {
// put your setup code here, to run once:
// Set MIDI baud rate:
Serial.begin(31250);
}
void loop() {
if (getQDepth>0) {
Serial.write(deQueue());
}
}
// The little function that gets called each time loop is called.
// This is automated somwhere in the Arduino code.
void serialEvent() {
https://riptutorial.com/ 50
if (Serial.available()) {
// get the new byte:
addQueue((unsigned char)Serial.read());;
}
}
void setup() {
// Set MIDI baud rate:
Serial.begin(31250);
clk_period_us = 60000000 / (24 * BPM);
lastClock = micros();
}
https://riptutorial.com/ 51
tailQ++;
tailQ = tailQ % QUEUE_DEPTH; // Keep this tailQ contained within a limit
// Now that we dequeed the byte, it must be sent.
return myByte;
}
void loop() {
captClock = micros();
if (getQDepth>0) {
Serial.write(deQueue());
}
}
// The little function that gets called each time loop is called.
// This is automated somwhere in the Arduino code.
void serialEvent() {
if (Serial.available()) {
// get the new byte:
addQueue((unsigned char)Serial.read());;
}
}
In general, MIDI protocol is broken down into "messages". There are 4 general classes of
messages:
• Channel Voice
• Channel Mode
• System Common
• System Real-Time Messages
Messages start with a byte value above 0x80. Any value below 0x7F is considered data.
Effectively meaning that 127 is the maximum value that can be encoded into a single MIDI data
byte. To encode larger values, two or more MIDI data bytes are required.
It should be pointed out that messages must be sent start to finish without interruption...
EXCEPT... System Real-Time messages, which are a single byte, which can be injected in the
middle of any message.
https://riptutorial.com/ 52
Channel Voice Messages
Status
Data Bytes Description
D7..D0
Status Data
Description
D7..D0 Bytes
https://riptutorial.com/ 53
Status Data
Description
D7..D0 Bytes
commands are:
All Sound Off. When All Sound Off is received all oscillators will
turn off, and their volume envelopes are set to zero as soon as
possible. c = 120, v = 0: All Sound Off
All Notes Off. When an All Notes Off is received, all oscillators will
turn off.
Status
Data Bytes Description
D7..D0
0iiiiiii [0iiiiiii 0iiiiiii] System Exclusive. This message type allows manufacturers
11110000 0ddddddd --- --- to create their own messages (such as bulk dumps, patch
0ddddddd parameters, and other non-spec data) and provides a
https://riptutorial.com/ 54
Status
Data Bytes Description
D7..D0
Status Data
Description
D7..D0 Bytes
https://riptutorial.com/ 55
Status Data
Description
D7..D0 Bytes
https://riptutorial.com/ 56
Chapter 19: PWM - Pulse Width Modulation
Examples
Control a DC motor through the Serial port using PWM
In this example we aim to accomplish one of the most common tasks: I have a small DC motor
laying around, how do I use my Arduino to control it? Easy, with PWM and serial communication,
using the function analogWrite() and the Serial library.
The basics
Pulse Width Modulation or PWM for short is a technique for mimicking analog signals using digital
output. How does this work? Using a pulse train whose relation D (duty cycle) between time at
high level (digital 1, usually 5V) and time at low level (digital 0, 0V) in each period can be modified
to produce an average voltage between these two levels:
By using Arduino's analogWrite(pin,value) function we can vary the value of the duty cycle of pin's
output. Note that the pin must be put into output mode and the value must be between 0 (0V) and
255 (5V). Any value in between will simulate a proportional intermediate analog output.
However, the purpose of analog signals is usually related to the control of mechanical systems
that require more voltage and current than the Arduino board alone is capable of. In this example,
we will learn how to amplify Arduino's PWM capabilities.
For this a MOSFET diode is used. In essence, this diode acts as a switch. It allows or interrupts
the electric flow between its source and drain terminals. But instead of a mechanical switch, it
features a third terminal called gate. A very small current (<1mA) will "open" this gate and allow
the current to flow. This is very convenient, because we can send Arduino's PWM output to this
gate, thereby creating another PWM pulse train with the same duty cycle through the MOSFET,
https://riptutorial.com/ 57
which allows voltages and currents that would destroy the Arduino.
The build
Put everything together! Power the rails of the breadboard and place the MOSFET diode in it.
Connect the motor between the positive rail and the MOSFET drain. Connect the protection diode
in the same way: between the MOSFET drain and the positive rail. Connect the source of the
MOSFET to the common ground rail. Finally, connect the PWM pin (we're using pin 10 in this
example) to the gate of the MOSFET and also to the common ground through the resistor (we
need very low current!).
Here's an example of how this build looks. If you prefer an scheme here's one.
The code
Now we can connect the Arduino to a computer, upload the code and control the motor, by
sending values through the serial communication. Recall that these values should be integers
https://riptutorial.com/ 58
between 0 and 255. The actual code of this example is very simple. An explanation is provided in
each line.
And that's it! Now you can use Arduino's PWM capabilities to control applications that require
analog signals even when the power requirements exceed the board's limits.
The TLC5940 is a handy item to have when you run out of PWM ports on the Arduino. It has 16
channels, each individually controllable with 12 bits of resolution (0-4095). An existing library is
available at http://playground.arduino.cc/Learning/TLC5940. It is useful for controlling multiple
servos or RGB LEDs. Just keep in mind, the LEDs must be common anode to work. Also, the
chips are daisy-chainable, allowing even more PWM ports.
Example:
void setup() {
// Initialize
Tlc.init();
Tlc.clear();
}
https://riptutorial.com/ 59
Chapter 20: Random Numbers
Syntax
• random(max) //Returns a (long) pseudo-random number between 0 (inclusive) and max
(exclusive)
• random(min, max) //Returns a (long) pseudo-random number between min (inclusive) and
max (exclusive)
Parameters
Parameter Details
seed The seed that will be used to shuffle the random() function.
Remarks
If randomSeed() is called with a fixed value (eg. randomSeed(5)), the sequence of random numbers
generated by the sketch will repeat each time it is run. In most cases, a random seed is preferred,
which can be obtained by reading an unconnected analog pin.
Examples
Generate a random number
void setup() {
Serial.begin(9600);
}
void loop() {
long randomNumber = random(500); // Generate a random number between 0 and 499
Serial.println(randomNumber);
randomNumber = random(100, 1000); // Generate a random number between 100 and 999
https://riptutorial.com/ 60
Serial.println(randomNumber);
delay(100);
}
Setting a seed
void setup() {
Serial.begin(9600);
void loop() {
long randomNumber = random(500); // Generate a random number between 0 and 499
Serial.println(randomNumber);
delay(100);
}
https://riptutorial.com/ 61
Chapter 21: Serial Communication
Syntax
• Serial.begin(speed) // Opens the serial port on the given baud rate
• Serial.begin(speed, config)
• Serial[1-3].begin(speed) // Arduino Mega only! When writing 1-3 it means you can choose
between the numbers 1 to 3 when choosing the serial port.
• Serial[1-3].begin(speed, config) // Arduino Mega only! When writing 1-3 it means you can
choose between the numbers 1 to 3 when choosing the serial port.
• Serial.peek() // Reads the next byte of input without removing it from the buffer
• Serial.available() // Gets the number of bytes in the buffer
• Serial.print(text) // Writes text to the serial port
• Serial.println(text) // Same as Serial.print() but with a trailing newline
Parameters
Parameter Details
Text The text to write to the serial port (any data type)
Parity Parity options for error detection: none (default), even, odd
Remarks
The Arduino Mega has four serial ports which there can be choosed from. They are accesed in the
following way
Serial.begin(9600);
Serial1.begin(38400);
Serial2.begin(19200);
Serial3.begin(4800);
The serial port on an Arduino can be set with additional parameters. The config parameter sets
data bits, parity, and stop bits. For example:
https://riptutorial.com/ 62
7 data bits, no parity and 1 stop bit would be - SERIAL_7N1
Examples
Simple read and write
This example listens for input coming in over the serial connection, then repeats it back out the
same connection.
byte incomingBytes;
void setup() {
Serial.begin(9600); // Opens serial port, sets data rate to 9600 bps.
}
void loop() {
// Send data only when you receive data.
if (Serial.available() > 0) {
// Read the incoming bytes.
incomingBytes = Serial.read();
String base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
void setup() {
void loop() {
if (Serial.available() > 0) { // Check if data has been sent from the user
char c = Serial.read(); // Gets one byte/Character from serial buffer
int result = base64.indexOf(c); // Base64 filtering
if (result>=0)
Serial.print(c); // Only print Base64 string
}
}
byte incoming;
String inBuffer;
void setup() {
Serial.begin(9600); // or whatever baud rate you would like
}
https://riptutorial.com/ 63
void loop(){
// setup as non-blocking code
if(Serial.available() > 0) {
incoming = Serial.read();
void handle_command() {
// expect something like 'pin 3 high'
String command = inBuffer.substring(0, inBuffer.indexOf(' '));
String parameters = inBuffer.substring(inBuffer.indexOf(' ') + 1);
if(command.equalsIgnoreCase('pin')){
// parse the rest of the information
int pin = parameters.substring("0, parameters.indexOf(' ')).toInt();
String state = parameters.substring(parameters.indexOf(' ') + 1);
if(state.equalsIgnoreCase('high')){
digitalWrite(pin, HIGH);
}else if(state.equalsIgnoreCase('low)){
digitalWrite(pin, LOW);
}else{
Serial.println("did not compute");
}
} // add code for more commands
}
If you have an Arduino connected to a computer or a Raspberry Pi, and want to send data from
the Arduino to the PC you can do the following:
Arduino:
void setup() {
// Opens serial port, sets data rate to 9600 bps:
Serial.begin(9600);
}
void loop() {
// Sends a line over serial:
https://riptutorial.com/ 64
Serial.println("Hello, Python!");
delay(1000);
}
Python:
import serial
https://riptutorial.com/ 65
Chapter 22: Servo
Introduction
A Servo is a an enclosed system containing a motor and some supporting circuitry. The shaft of a
servo can be rotated to a fixed angle within an arc using a control signal. If the control signal is
maintained, then the servo will maintain its angle. Servos can easily be controlled with the Arduino
Servo.h library.
Syntax
• #include <Servo.h> // Include the Servo library
• Servo.attach(pin) // Attach to the servo on pin. Returns a Servo object
• Servo.write(degrees) // Degrees to move to (0 - 180)
• Servo.read() // Gets the current rotation of the servo
Examples
Moving the servo back and forth
#include <Servo.h>
Servo srv;
void setup() {
srv.attach(9); // Attach to the servo on pin 9
To use a servo, you need to call attach() function first. It starts generating a PWM signal
controlling a servo on a specified pin. On boards other than Arduino Mega, use of Servo library
disables analogWrite() (PWM) functionality on pins 9 and 10, whether or not there is a Servo on
those pins.
void loop() {
Servo.write(90); // Move the servo to 90 degrees
delay(1000); // Wait for it to move to it's new position
Servo.write(0); // Move the servo to 0 degrees
delay(1000); // Wait for it to move to it's new position
}
Note that you are not guaranteed that the servo reached the desired position, nor you can check it
from the program.
https://riptutorial.com/ 66
Chapter 23: SPI Communication
Remarks
// use:
digitalWrite(CSPIN, 0); // select
... perform data transfer ...
digitalWrite(CSPIN, 1); // deselect
Deselecting a slave is just as important as selecting it, because a slave may drive the MISO line
while it is selected. There may be many slaves, but only one may drive MISO. If a slave is not
deselected properly, two or more slaves might be driving MISO, which may lead to shorts between
their outputs and might damage the devices.
Transactions
Transactions serve two purposes:
• tell the SPI when we want to start and end using it within a particular context
• configure the SPI for a specific chip
The clock line has different idle states in the different SPI modes. Changing the SPI mode while a
slave is selected might confuse the slave, so always set the SPI mode before selecting a slave.
The SPI mode can be set with an SPISettings object passed to SPI.beginTransaction:
https://riptutorial.com/ 67
If another part of the code tries to use the SPI between a pair of calls to beginTransaction() and
endTransaction(), an error may be raised - how that is done depends on the implementation.
Examples
Basics: initialize the SPI and a chip select pin, and perform a 1-byte transfer
#include <SPI.h>
#define CSPIN 1
void setup() {
pinMode(CSPIN, OUTPUT); // init chip select pin as an output
digitalWrite(CSPIN, 1); // most slaves interpret a high level on CS as "deasserted"
SPI.begin();
digitalWrite(CSPIN, 1);
SPI.endTransaction();
SPI.end();
}
void loop() {
// we don't need loop code in this example.
}
This example:
https://riptutorial.com/ 68
Read SPI Communication online: https://riptutorial.com/arduino/topic/4919/spi-communication
https://riptutorial.com/ 69
Chapter 24: Time Management
Syntax
• unsigned long millis()
• See the elapsedMillis header for constructors and operators of that class. In short:
Remarks
• Wasting CPU time: More complex sketches might need the CPU for something else while
waiting for an LED blinking period to end.
• unexpected delays: when delay() is called in subroutines that are not obviously called, for
example in libraries you include.
• missing events that happen during the delay and are not handled by an interrupt handler, for
example polled button presses: A button might be pressed for 100 ms, but this might be
shadowed by a delay(500).
Implementation details
millis() usually relies on a hardware timer that runs at a speed that's much higher than 1 kHz.
When millis() is called, the implementation returns some value, but you don't know how old that
actually is. It's possible that the "current" millisecond just started, or that it will end right after that
function call. That means that, when calculating the difference between two results from millis(),
you can be off by anything between almost zero and almost one millisecond. Use micros() if higher
precision is needed.
https://riptutorial.com/ 70
Looking into the source code of elapsedMillis reveals that it indeed uses millis() internally to
compare two points in time, so it suffers from this effect as well. Again, there's the alternative
elapsedMicros for higher precision, from the same library.
Examples
blocking blinky with delay()
One of the most straight forward way of making an LED blink is: turn it on, wait a bit, turn it off,
wait again, and repeat endlessly:
void setup()
{
pinMode(OUTPIN, OUTPUT); // sets the digital pin as output
}
void loop()
{
digitalWrite(OUTPIN, HIGH); // sets the pin on
delayMicroseconds(PERIOD); // pauses for 500 miliseconds
digitalWrite(OUTPIN, LOW); // sets the pin off
delayMicroseconds(PERIOD); // pauses for 500 milliseconds
However, waiting as done in the example above wastes CPU cycles, because it just sits there in a
loop waiting for a certain point in time to go past. That's what the non-blocking ways, using
millis() or elapsedMillis, do better - in the sense that they don't burn as much of the hardware's
capabilities.
The elapsedMillis library provides a class with the same name that keeps track of the time that
passed since it was created or set to a certain value:
#include <elapsedMillis.h>
elapsedMillis ledTime;
void setup()
{
// initialize the digital pin as an output.
pinMode(OUTPIN, OUTPUT);
https://riptutorial.com/ 71
}
void loop()
{
if (ledTime >= PERIOD)
{
ledState = !ledState;
digitalWrite(OUTPIN, ledState);
ledTime = 0;
}
// do other stuff here
}
You can see in the example that the ledTime object is assigned zero when the LED pin was
toggled. This might not be surprising at first glance, but it has an effect if more time-consuming
things are happening:
Consider a situation where the comparison between ledTime and PERIOD is done after 750
milliseconds. Then setting ledTime to zero means that all following toggle operations will be 250 ms
"late". If, in contrast, PERIOD was subtracted from ledTime, the LED would see one short period and
then continue blinking as if nothing happened.
// millis() returns an unsigned long so we'll use that to keep track of time
unsigned long lastTime = 0;
void setup() {
// set the digital pin as output:
pinMode(OUTPIN, OUTPUT);
}
void loop() {
unsigned long now = millis();
if (now - lastTime >= PERIOD) // this will be true every PERIOD milliseconds
{
lastTime = now;
if (ledState == LOW)
{
ledState = HIGH;
}
else
{
ledState = LOW;
}
digitalWrite(OUTPIN, ledState);
}
https://riptutorial.com/ 72
}
Using millis() in this way - to time operations in a non-blocking way - is something that is needed
quite frequently, so consider using the elapsedMillis library for this.
#include <elapsedMillis.h>
void setup() {
Serial.begin(115200);
elapsedMillis msTimer;
elapsedMicros usTimer;
Serial.print("delay(");Serial.print(dt);Serial.println(") took");
Serial.print(us);Serial.println(" us, or");
Serial.print(ms);Serial.println(" ms");
}
void loop() {
}
In this example, an elapsedMillis object and an elapsedMicros object are used to measure how
long something took, by creating them just before the expression we want to time is executed, and
getting their values afterwards. They will show slightly different results, but the millisecond result
won't be off by more than one millisecond.
If you have more than 1 task to execute repeatedly in different intervals, use this example as a
starting point:
unsigned long intervals[] = {250,2000}; //this defines the interval for each task in
milliseconds
unsigned long last[] = {0,0}; //this records the last executed time for each task
void setup() {
pinMode(LED_BUILTIN, OUTPUT); //set the built-it led pin as output
Serial.begin(115200); //initialize serial
}
void loop() {
unsigned long now = millis();
if(now-last[0]>=intervals[0]){ last[0]=now; firstTask(); }
if(now-last[1]>=intervals[1]){ last[1]=now; secondTask(); }
https://riptutorial.com/ 73
void firstTask(){
//let's toggle the built-in led
digitalWrite(LED_BUILTIN, digitalRead(LED_BUILTIN)?0:1);
}
void secondTask(){
//say hello
Serial.println("hello from secondTask()");
}
To add another task to execute every 15 seconds, extend the variables intervals and last:
Then add an if statement to execute the new task. In this example, I named it thirdTask.
void thirdTask(){
//your code here
}
https://riptutorial.com/ 74
Chapter 25: Using Arduino with Atmel Studio
7
Remarks
Setup
• Download and install Atmel Studio 7 from here.
• Purchase a debugger. You can get by with a ISP programmer, but if you want debugging
capabilities, which is one of the big advantages of using Atmel Studio, you will want a
debugger. I recommend the Atmel ICE, as it provides debugging capabilities for AVR based
arduinos (like the Uno, pro mini, etc) and the ARM based Arduinos, such as the Zero and
Due. If you are on a budget, you can get it without the plastic case and be careful not to
shock it.
Connections
• For the Uno, use the 6-pin ICSP cable. Plug one side into the Uno as shown. Plug the other
side into the debugger's AVR port.
https://riptutorial.com/ 75
For the Arduino Pro Mini, use the mini squid cable as shown, again connecting the other side the
debugger's AVR port.
https://riptutorial.com/ 76
Debugging considerations
For debugging with the Uno, you will need to cut the Reset-enable trace (you can always solder it
back for using with the Arduino IDE):
https://riptutorial.com/ 77
Using the Pro Mini, if you intend to connect the serial port to your computer using an FTDI board,
do not connect the DTR line, as it will interfere with Atmel's Serial Wire Debug (SWD) interface. I
simply connect power, ground, Tx and Rx as shown here below. Rx and Tx on Arduino go to Tx
and Rx, respectively on FTDI board. Some FTDI boards are labeled differently, so if the serial port
doesn't work, swap Rx and Tx.
https://riptutorial.com/ 78
You will have to provide power separately to the Arduino because the debugger will not power it.
This can be done on the Pro Mini through the FTDI board as shown above, or with a USB cable or
AC adaptor on the Uno.
Software setup
Plug the Atmel ICE into your computer, start Atmel Studio and you can now import an existing
Arduino project.
In Atmel Studio, go to File -> New -> Project and select "Create project from Arduino sketch". Fill
out options including board and device dropdown menus.
Go to Project -> yourProjectName Properties, click on Tool, select Atmel ICE under
debugger/programmer and debugWire under interface. Go to Debug -> Start debugging and
https://riptutorial.com/ 79
break. You should see a warning and be asked if you want to set the DWEN fuse. Choose OK,
unplug the Arduino from power and plug it in again. You can stop debugging by clicking the red
square button and start by clicking the green triangle button. To return the Arduino to a state that it
can be used in the Arduino IDE, while you're debugging, choose Debug -> disable debugWIRE
and close.
Note that any functions you add must include a function prototype as well (loop and setup don't
need them). You can see the ones Atmel Studio added at the top of the sketch if there were any
functions when you imported your project into Atmel Studio (see sample code for example).
C++11 support is enabled by default in Arduino 1.6.6 and above. This provides more C++
language features and enabling it may increase compatibility with the Arduinio system. To enable
C++11 in Atmel Studio 7, right click on your project file, select properties, click on ToolChain on
the left, Click on Miscellaneous under AVR/GNU C++ Compiler and put -std=c++11 in the Other
flags field.
Benefits
Programming Arduino with a moder IDE like Atmel Studio 7 gives you numerous advantages over
the Arduino IDE, including debugging, autocompletion, jump to definition and declaration,
forward/backward navigation, bookmarks and refactoring options to name a few.
You can configure key bindings by going to Tools -> Options -> Environment -> Keyboard. Some
that really speed up development are:
• Edit.CommentSelection, Edit.UncommentSelection
• View.NavigateForward, View.NavigateBackward
• Edit.MoveSelectedLinesUp, Edit.MoveSelectedLinesDown
• Edit.GoToDefinition
https://riptutorial.com/ 80
Examples
Atmel Studio 7 imported sketch example
This is an example of what a simple Arduino sketch looks like after being imported into Atmel
Studio. Atmel Studio added the auto generated sections at the top. The rest is identical to the
original Arduino code. If you expand the ArduinoCore project that was created and look in the src -
> core folder, you will find main.cpp, the entry point for the program. There you can see the call to
the the Arduino setup function and a never ending for loop that calls the Arduino loop function over
and over.
void setup() {
Serial.begin(9600);
}
void loop() {
printA();
}
void printA() {
Serial.println("A");
}
https://riptutorial.com/ 81
Chapter 26: Variables and Data Types
Examples
Create variable
To create a variable:
variableType variableName;
For example:
int a;
For example:
int a = 2;
If you have a variable declared before, you can assign some value to it:
For example:
Variable types
https://riptutorial.com/ 82
• float : 4-byte floating point number
• double : 4-byte (on ATMEGA based boards) or 8-byte (on Arduino Due) floating point number
Examples:
char a = 'A';
char a = 65;
byte b = B10010;
int c = 2;
unsigned int d = 3;
long e = 186000L;
float g = 1.117;
double h = 1.117;
https://riptutorial.com/ 83
Credits
S.
Chapters Contributors
No
Bluetooth
5 Girish, Martin Carney
Communication
How Python
11 integrates with Danny_ds, Peter Mortensen, Stark Nguyen
Arduino Uno
How to store
variables in
AZ Vcience, Chris Combs, Danny_ds, Jeremy, Peter Mortensen
12 EEPROM and use
, RamenChef
them for permanent
storage
https://riptutorial.com/ 84
18 MIDI Communication Rich Maes
https://riptutorial.com/ 85