Hassan S. ESP32 MicroPython Programming. An Essential Guide.2024
Hassan S. ESP32 MicroPython Programming. An Essential Guide.2024
Each part contains chapters that build upon one another to create a complete
learning path from beginner to intermediate-level IoT developer.
What Was Left Out
To keep this book focused on essential skills, advanced topics such as deep
learning on microcontrollers, extensive error handling, and advanced
hardware debugging techniques were omitted. Additionally, while we touch
on many IoT concepts, topics like cloud integration and long-range
communication (LoRa) are left out, as they require more specialized
hardware and deeper knowledge.
Code Style (About the Code)
The code examples in this book are written in a clear, beginner-friendly
style, following standard MicroPython conventions. Code is formatted with
consistent indentation, meaningful variable names, and simple comments to
explain each step. You will find code snippets throughout the book to
demonstrate each concept, and complete projects are provided for you to
follow along.
MicroPython Platform Release Notes
This book is based on MicroPython Version 1.15 or later. As MicroPython
is an open-source project with frequent updates, you may find minor
differences between the book's examples and newer versions. It is
recommended to visit the official MicroPython documentation for any
updates that might affect your code.
Notes on the First Edition
This is the first edition of ESP32 MicroPython Programming: An
Essential Guide for Absolute Beginners & IoT Projects. As the field of
IoT and embedded systems is evolving rapidly, we encourage readers to
send feedback, corrections, and suggestions for future editions.
Conventions Used in This Book
The following conventions are used throughout the book:
● Code blocks: Represented in monospace font to differentiate from
regular text.
● Commands: Shown as you would type them into a terminal or
MicroPython REPL.
● Warnings and tips: Special notes are highlighted to help you
avoid common mistakes.
Using Code Examples
All the code examples provided in this book are free to use and modify in
your own projects. We encourage you to experiment with the code to
reinforce your understanding of MicroPython and ESP32 programming.
MechatronicsLAB Online Learning
For additional resources, tutorials, and online courses, visit
MechatronicsLAB at mechatronicslab.net. You can find supplementary
materials for this book, as well as additional projects and guides.
For inquiries, feel free to contact us at [email protected].
How to Contact Us
We welcome your feedback. You can reach us via:
● Email: [email protected]
● Website: mechatronicslab.net
Acknowledgments for the First Edition
I would like to extend my deepest thanks to the entire MechatronicsLAB
team, my family, and all those who helped make this book possible. Special
thanks to the developers of MicroPython and the open-source community
for providing the tools and inspiration to create this guide.
Copyright
© 2024 MechatronicsLAB. All rights reserved. No part of this publication
may be reproduced, stored, or transmitted in any form without the prior
written permission of the author and publisher, except for brief excerpts in
reviews or academic work.
Disclaimer
The author and publisher have made every effort to ensure that the
information in this book is accurate and reliable. However, they assume no
responsibility for errors or omissions or for damages resulting from the use
of the information contained herein. This book is provided “as is,” without
warranty of any kind.
Table of Contents
Part 1: Introduction to ESP32 and ESP8266 and MicroPython
Chapter-1 Introduction of ESP32 and ESP8266
Chapter-2 Introduction to MicroPython
Chapter-3 Preparing Your Tools
Part 2: Programming Fundamentals with MicroPython
Chapter 4. Variables and Data Types
Chapter 5. Math Functions
Chapter 6. Data Type Conversions
Chapter 7. Operators and Expressions
Chapter 8. Control Structures
Chapter 9. Timing and Delays
Chapter 10. Functions and Modules
Chapter 11. GPIO I/O operations
Chapter 12.Programming Fundamentals Project
Part 3 : Get started with IOT with Micropython
Chapter 13. Networking Wifi
Chapter-14 Building IoT Applications
Part 1: Introduction to ESP32 and ESP8266
and MicroPython
Chapter-1 Introduction of ESP32 and ESP8266
The ESP32 and ESP8266 are microcontrollers developed by Espressif
Systems, commonly used in Internet of Things (IoT) projects. These
microcontrollers are known for their built-in Wi-Fi capabilities, which
make them highly popular for connecting devices to the internet and
creating smart, connected systems. Both are affordable and widely used, but
they have different levels of power, features, and applications, making them
suitable for different use cases.
● ESP32: Designed to be a high-performance microcontroller with
dual-core processing, Wi-Fi, and Bluetooth capabilities, the ESP32
is ideal for more advanced IoT projects. It is suitable for
applications where more computing power, additional features, and
enhanced connectivity are needed.
● ESP8266: Known for its low cost and built-in Wi-Fi, the ESP8266
is ideal for simpler IoT projects, particularly for beginners or
budget-conscious makers. It’s capable of handling basic tasks and is
perfect for projects that do not require the higher performance or
additional connectivity options found in the ESP32.
Introduction to ESP32
The ESP32 is a powerful and versatile microcontroller unit (MCU) created
by Espressif Systems, specifically designed to enable connected, smart, and
interactive devices. The key highlights of the ESP32 are:
● Dual-Core Processor: The ESP32 features two Xtensa LX6
processors, each capable of running up to 240 MHz. This dual-core
setup makes it powerful enough for multitasking and managing
different operations simultaneously, which is beneficial in many
IoT scenarios.
● Connectivity: It supports Wi-Fi (802.11 b/g/n) and Bluetooth,
including Bluetooth Low Energy (BLE). This makes the ESP32
versatile, as it can connect to the internet or other devices via
Bluetooth.
● Power Management: The ESP32 is known for its various low-
power modes, which makes it ideal for battery-powered
applications. It can operate in deep sleep mode with very low
power consumption, which is an essential feature for IoT projects
that need to last long on a single battery charge.
● Peripherals and GPIO: The ESP32 comes with a wide range of
GPIO (General Purpose Input/Output) pins, which can be used
to connect sensors, LEDs, buttons, and other devices. It also has
built-in modules like analog-to-digital converters (ADC), touch
sensors, and a temperature sensor.
● Applications: It is well-suited for smart home automation,
wearables, wireless sensors, and other advanced IoT projects
that require a high level of connectivity and computation power.
Introduction to ESP8266
The ESP8266 is an earlier microcontroller model from Espressif Systems,
widely popular for its affordability and integrated Wi-Fi. Key
characteristics of the ESP8266 are:
● Single-Core Processor: The ESP8266 features a 32-bit Tensilica
L106 processor, running at speeds between 80 MHz and 160
MHz. While it’s not as powerful as the ESP32, it is sufficient for
less demanding IoT projects, especially those that don’t require
extensive data processing.
● Built-in Wi-Fi: The ESP8266 has a built-in Wi-Fi module,
making it perfect for connecting small devices to the internet
without needing an external Wi-Fi chip. It supports standard Wi-Fi
protocols for internet access.
● Cost-Effectiveness: The ESP8266 is known for being highly
affordable, which is why it became popular with hobbyists and
makers. It provides a low-cost way to add Wi-Fi capabilities to
electronics.
● GPIO and Connectivity: It has a limited number of GPIO pins
compared to the ESP32, which limits the number of sensors and
peripherals that can be connected simultaneously. Nevertheless, it
supports common communication protocols like SPI, I2C, and
UART, making it versatile enough for many smaller projects.
● Applications: The ESP8266 is ideal for simple projects such as
smart light switches, basic wireless sensors, and simple
automation devices where a low-cost solution is needed.
Comparison between ESP32 and ESP8266
To help understand the differences and choose between ESP32 and
ESP8266, let’s compare their features:
1. Processing Power:
2. Connectivity:
3. Power Consumption:
5. Price:
2. Interactive Development
4. Versatility of ESP32
1. Components Required
○ ESP32 board
○ Micro USB cable (to connect the ESP32 to your computer)
○ Computer with internet access
3. Installing esptool
1. Download Python
Global Variables
What are Global Variables?
Global variables are variables that are declared outside of all functions and
are accessible from any part of the program. Unlike local variables (which
are only accessible within the function they are declared in), global
variables can be used by any function in the program, making them useful
for sharing data across multiple functions.
Why is Important
Global variables are used when you need a variable to be accessible
throughout the entire program, across multiple functions. This is useful
when different parts of the code need to share or update the same data, such
as sensor values, counters, or configuration settings.
Syntax
global variableName
Local Variables
What are Local Variables?
Local variables are variables that are declared within a function or a block
of code and are only accessible inside that specific function or block. Once
the function finishes executing, the local variables are destroyed, and their
values are no longer accessible.
Why is Important
Local variables are used when you only need a variable to store data
temporarily within a specific function or block of code. They help avoid
conflicts with global variables and ensure that the variable is only used in
the context where it's needed.
Syntax Use
variableName = value
Syntax Explanation
variable_name represents the name you assign to store your integer value.
int(value) assigns an integer value to the variable.
Code Example
temperature = int(25)
counter = int(0)
Notes
● You can use int to initialize a variable with any whole number.
● When converting from another data type to int , make sure the
value is suitable for integer representation.
Warnings
● If you attempt to convert a non-numeric value to int , a
ValueError may be raised.
● int variables cannot hold decimal numbers; use float if you need
to work with fractional values.
2. Float Variable float
What is
A float variable is a type of data used in MicroPython to store numbers with
decimals, like 23.5 or 3.14. You use float when you need to work with
numbers that aren't whole, such as measurements or precise values.
Why is Important?
The float variable is important because it lets you do calculations with
numbers that have decimals. This is useful when working with things like
temperature, distances, or any situation where you need more precision than
a whole number.
Syntax
variable_name = float(value)
Syntax Explanation
● variable_name is the name you give to your variable to store the
number.
● float(value) means you are creating a decimal number, where value
is the number you want to store.
Code Example
temperature = float(23.5)
distance = float(15.75)
Notes
● float is used to store numbers with decimals, allowing you to do
more precise math.
● You can convert an integer to a float by using float(). For example,
float(5) will become 5.0.
Warnings
● Be careful when doing math with float values, because sometimes
the result might not be exact due to how computers handle decimal
numbers.
● Using float may take more memory than using whole numbers
(int), so it’s something to keep in mind when working on a
microcontroller with limited space.
3. Bool Variable bool
What is
A bool variable is a type of data used in MicroPython that can only have
one of two values: True or False. It is used when you need to represent
something as being either on/off, yes/no, or true/false.
Why is Important?
The bool variable is important because it helps control decision-making in
your program. For example, you can use it to determine if a condition is
met or not, like checking if a button is pressed or if a temperature is above a
certain level.
Syntax
variable_name = bool(value)
Syntax Explanation
● variable_name is the name you assign to the variable.
● bool(value) sets the variable to either True or False. You can also
directly use True or False without converting another value.
Code Example
is_light_on = bool(True)
is_temperature_high = bool(False)
Notes
● You can also assign True or False directly without using bool(),
like is_valid = True.
● bool is often used in conditional statements to control the flow of a
program, like in if statements.
Warnings
● When converting other values to bool, remember that 0, None, and
empty sequences (like an empty string "") are considered False,
while all other values are considered True.
● Be careful not to confuse bool with numerical values, as True is
equivalent to 1 and False is equivalent to 0 in mathematical
operations.
4. NoneType Variable None
What is
NoneType is a special data type in MicroPython that has only one possible
value: None. It is used to represent the absence of a value or a "nothing"
value. When a variable is assigned None, it means that it doesn't contain any
useful information yet.
Why is Important?
NoneType is important because it allows you to define a variable that does
not have a value yet. This can be useful when initializing variables before
you assign them real data or when you need to indicate that no meaningful
value exists.
Syntax
variable_name = None
Syntax Explanation
● variable_name is the name you assign to the variable.
● None is used to indicate that the variable currently has no value.
Code Example
temperature = None button_state = None
Notes
● You can use None to initialize a variable that will get a value later.
● Checking if a variable is None can be done using if variable_name
is None:.
Warnings
● Do not use None in mathematical operations, as it will cause errors
since it is not a number.
● When working with NoneType, be careful to handle it properly in
conditions to avoid unexpected behavior in your code.
variable_name = str(value)
or variable_name = "text value"
Syntax Explanation
● variable_name is the name you give to the variable to store the
text.
● str(value) converts a given value to a string.
● Alternatively, you can directly assign a string by using quotation
marks like "text value".
Code Example
name = str("John")
message = "Hello, World!"
Notes
● You can concatenate (join) two strings using the + operator, like
greeting = "Hello, " + "John".
● Strings can also be created by converting other data types, such as
str(123) to get the text representation "123".
Warnings
● Remember that numbers in a str format cannot be used in
mathematical calculations unless you convert them back to an int or
float.
● Be careful with quotation marks—always match the opening and
closing quotation marks to avoid syntax errors.
2. List Variable list
What is
A list is a data type in MicroPython that allows you to store multiple values
in a single variable. You can think of a list as a collection of items, such as
numbers or strings, all enclosed in square brackets [ ].
Why is Important?
The list is important because it helps you store and manage multiple related
values easily. For example, you could store the temperatures recorded at
different times, or keep a list of names of users. This makes it easy to
access, modify, or perform actions on the entire collection of items.
Syntax
variable_name = [value1, value2, value3, ...]
Syntax Explanation
● variable_name is the name you give to the list.
● The values inside the square brackets [ ] are the items in the list,
separated by commas. They can be of any data type, like int, float,
or str.
Code Example
temperatures = [23, 25, 21, 22]
names = ["Alice", "Bob", "Charlie"]
Notes
● You can access an item in the list using its index, like
temperatures[0], which would give you 23.
● Lists are flexible; you can add items using append(), like
temperatures.append(26).
Warnings
● Indexing starts at 0, not 1. For example, names[0] gives "Alice".
● If you try to access an index that doesn’t exist, you’ll get an
IndexError. Always check the list's length with len(list_name)
before accessing an index.
3. Tuple Variable tuple
What is
A tuple is a data type in MicroPython that allows you to store multiple
values, similar to a list. However, unlike a list, the values in a tuple cannot
be changed once they are set. A tuple is created by enclosing the values in
parentheses ( ).
Why is Important?
The tuple is important when you need to store a collection of items that
should not be modified. This ensures that your data remains consistent and
prevents accidental changes. For example, it is useful for storing fixed
configuration settings or constant values.
Syntax
variable_name = (value1, value2, value3, ...)
Syntax Explanation
● variable_name is the name you assign to the tuple.
● The values inside the parentheses ( ) are the items in the tuple,
separated by commas. These items can be of any data type, like int,
float, or str.
Code Example
coordinates = (10, 20)
colors = ("red", "green", "blue")
Notes
● You can access an item in a tuple using its index, just like with a
list, for example, coordinates[0] will give you 10.
● Tuples can be used to store multiple values that should remain
constant, which helps make your code safer and more predictable.
Warnings
● Tuples are immutable, which means you cannot change, add, or
remove items after the tuple is created.
● If you need to modify the values, consider using a list instead of a
tuple.
4. Bytes Variable bytes
What is
A bytes variable in MicroPython is a type of data used to represent
sequences of bytes, which are numbers ranging from 0 to 255. It is
commonly used when you need to work with binary data, such as reading
data from sensors or working with communication protocols.
Why is Important?
The bytes type is important for low-level operations where you need precise
control over the data, such as handling raw data from devices, working with
communication interfaces (like UART or I2C), or storing data in a memory-
efficient way.
Syntax
Notes
● You can create a bytes object directly by prefixing a string with b,
like b"Hello".
● The bytes type is immutable, which means you cannot change
individual elements once the bytes object is created.
Warnings
● The values in a bytes object must be between 0 and 255. Trying to
use a value outside this range will cause an error.
● Since bytes are immutable, if you need to modify the content,
consider using a bytearray, which is a mutable version of bytes.
Syntax Explanation
● variable_name is the name you give to the set.
● The values inside the curly braces { } are the items in the set,
separated by commas. The items can be of any data type, like int,
float, or str.
Code Example
unique_numbers = {1, 2, 3, 4, 5}
unique_names = {"Alice", "Bob", "Charlie"}
Notes
● Sets are unordered, so the items do not have a specific index, and
you cannot access elements using an index like with lists.
● You can add items to a set using the add() method, for example,
unique_numbers.add(6).
Warnings
● Sets cannot have duplicate values. If you add a duplicate, it will be
ignored.
● Sets are not ordered, so the order of items may change when you
add or remove elements, and you cannot rely on the order for
accessing items.
2. Dictionary Variable dict
What is
A dict (short for dictionary) is a data type in MicroPython that stores data in
key-value pairs. It works like a real-life dictionary, where each key has an
associated value, making it easy to organize and access related data.
Why is Important?
The dict is important because it allows you to store and retrieve data
efficiently using keys, which makes it easy to organize data that is related.
For example, you can use a dict to store information like device
configurations, sensor readings by their names, or any data that can be
labeled.
Syntax
Notes
● You can access a value using its key, for example, person["name"]
will give you "Alice".
● You can add a new key-value pair by assigning a value to a new
key, like person["height"] = 170.
Warnings
● Keys in a dict must be unique. If you use the same key again, it
will overwrite the existing value.
● Be careful when accessing keys that might not exist, as it will raise
a KeyError. You can use get() to avoid this, like
person.get("weight", "Not Available"), which will return "Not
Available" if the key does not exist.
math.sqrt(value)
Syntax Explanation
● math is the module that provides mathematical functions, so you
need to import it first.
● sqrt(value) takes a number as input and returns its square root.
value should be a non-negative number.
Code Example
Notes
● Before using sqrt(), you must import the math module using import
math.
● The result of sqrt() is a floating-point number, even if the input is a
perfect square.
Warnings
● The value passed to sqrt() must be non-negative. If you pass a
negative number, it will raise a ValueError.
● Ensure that the math module is properly imported; otherwise,
attempting to use sqrt() will result in a NameError.
1. Sine Function sin()
What is
The sin() function in MicroPython is used to calculate the sine of an angle,
which is a trigonometric function. It takes an angle in radians as input and
returns the sine value, which is useful for working with waves, rotations,
and periodic phenomena.
Why is Important?
The sin() function is important for various mathematical and engineering
calculations, especially when dealing with oscillations, waveforms, or
analyzing angles. It is commonly used in fields like physics, robotics, and
electronics to model behavior like sensor readings or motor movement.
Syntax
math.sin(angle_in_radians)
Syntax Explanation
● math is the module that provides mathematical functions, so you
need to import it first.
● sin(angle_in_radians) takes an angle in radians and returns the sine
value of that angle.
Code Example
Notes
● You must import the math module using import math to use the
sin() function.
● The angle provided to sin() should be in radians. To convert
degrees to radians, you can use math.radians(degrees).
Warnings
● Be careful with the unit of the angle. The sin() function requires
radians, not degrees.
● If you pass a very large value, you may experience precision issues
due to how floating-point numbers are handled.
3. Cosine Function cos()
What is
The cos() function in MicroPython is used to calculate the cosine of an
angle, which is a trigonometric function. It takes an angle in radians as
input and returns the cosine value, which is useful for working with
waveforms, angles, and periodic functions.
Why is Important?
The cos() function is important for calculations involving waveforms,
rotations, or periodic behavior. It is frequently used in applications like
robotics, signal processing, and physics to model or analyze scenarios
involving angles and their relationships.
Syntax
math.cos(angle_in_radians)
Syntax Explanation
● math is the module that provides mathematical functions, so you
need to import it first.
● cos(angle_in_radians) takes an angle in radians and returns the
cosine value of that angle.
Code Example
import math angle = math.pi / 3 cosine_value = math.cos(angle)
print(cosine_value) # Output: 0.5
Notes
● You must import the math module using import math to use the
cos() function.
● The angle given to cos() must be in radians. You can use
math.radians(degrees) to convert degrees to radians if needed.
Warnings
● The input for the cos() function must be in radians, not degrees, to
get the correct value.
● Using very large or very small values might result in precision
issues due to the limitations of floating-point arithmetic in
microcontrollers.
Common Mistakes and How to Avoid Them
1. Not Importing the math Module
Syntax
int(value)
Syntax Explanation
● value can be a number or a string that represents a number. The
int() function will convert this value to an integer.
Code Example
Notes
● If you use int() with a floating-point number, it will truncate the
decimal part and return only the whole number.
● You can use int() with strings that represent valid whole numbers.
Warnings
● If the string value passed to int() is not a valid representation of an
integer (e.g., "abc"), it will raise a ValueError.
● Using int() on a float will always round down, even if the decimal
is greater than 0.5. For example, int(4.9) will result in 4, not 5.
2. Floating-Point Conversion Function float()
What is
The float() function in MicroPython is used to convert a value to a floating-
point type, which is a number with a decimal point. It allows you to
represent real numbers for more precision compared to integers.
Why is Important?
The float() function is important when working with values that require
decimal precision, such as temperature measurements, distances, or
financial calculations. It allows you to convert integers or strings into
floating-point numbers for accurate mathematical operations.
Syntax
float(value)
Syntax Explanation
● value can be a number (integer) or a string representing a number.
The float() function will convert this value to a floating-point
number.
Code Example
number_str = "3.14" number = float(number_str)
print(number) # Output: 3.14
integer_value = 5 float_value = float(integer_value)
print(float_value) # Output: 5.0
Notes
● If you use float() with an integer, it will add a decimal point to
create a floating-point number.
● You can use float() with strings that represent valid numbers,
including those with decimals.
Warnings
● If the string value passed to float() is not a valid representation of a
number (e.g., "abc"), it will raise a ValueError.
● Be mindful of precision issues when using floating-point numbers,
as they can sometimes lead to rounding errors in calculations,
especially with very large or very small values.
3. String Conversion Function str()
What is
The str() function in MicroPython is used to convert a value to a string type.
It allows you to represent numbers, booleans, or other data as text, which is
useful for displaying or processing data in a readable format.
Why is Important?
The str() function is important when you need to convert data to text format
for output, user interaction, or storing information as strings. It is also
helpful when you need to concatenate numbers with other strings to create
meaningful messages.
Syntax
str(value)
Syntax Explanation
● value can be any data type, such as an integer, float, or boolean.
The str() function will convert this value to a string.
Code Example
number = 42 number_str = str(number)
print(number_str) # Output: "42"
boolean_value = True boolean_str = str(boolean_value)
print(boolean_str) # Output: "True"
Notes
● You can use str() to easily concatenate different data types by
converting them to strings first, such as "The value is " + str(10).
● Using str() helps make non-text data readable and is useful for
printing and logging information.
Warnings
● Be careful when converting complex data types, such as lists or
dictionaries, into strings, as it might not be easily readable without
formatting.
● When using str() on floating-point numbers, be aware of the
precision, as it may include many decimal places depending on the
value.
Common Mistakes and How to Avoid Them
Arithmetic Operators
Addition Operator (+)
What is
The addition operator + is used in MicroPython to add two values together.
It can be used with numbers to perform arithmetic addition, or with strings
to concatenate (join) them.
Why is Important?
The + operator is one of the basic arithmetic operations, and it is essential
for performing calculations, combining numerical data, and building
strings. It helps make mathematical operations easy and intuitive in your
code.
Syntax
value1 + value2
Syntax Explanation
● value1 and value2 can be numbers (integers or floats) that you
want to add, or strings that you want to concatenate.
Code Example
Notes
● The + operator can be used for both numbers and strings, but they
must be compatible (i.e., you cannot add a number and a string
directly).
● If you need to add a number to a string, convert the number to a
string first using str().
Warnings
● If you try to use + with incompatible types, such as an integer and
a string without converting, it will raise a TypeError.
● When working with floating-point numbers, be aware of potential
precision issues, especially when adding very large or very small
values.
Subtraction Operator (-)
What is
The subtraction operator - is used in MicroPython to subtract one value
from another. It is commonly used to perform arithmetic calculations
involving differences between numbers.
Why is Important?
The - operator is crucial for performing arithmetic operations like finding
the difference between two values. It is widely used in scenarios such as
adjusting values, performing calculations in loops, or solving mathematical
problems.
Syntax
value1 - value2
Syntax Explanation
● value1 and value2 are numbers (integers or floats) that you want to
subtract, with value2 being subtracted from value1.
Code Example
Notes
● The - operator is used only for numerical values (integers or floats).
● You can use - to subtract a smaller value from a larger value to get
a positive result, or vice versa to get a negative result.
Warnings
● If you use - with incompatible types (e.g., trying to subtract a
number from a string), it will raise a TypeError.
● Be mindful of precision issues when working with floating-point
numbers, as subtracting very large and very small values can lead
to inaccuracies due to how floating-point arithmetic works.
Multiplication Operator (*)
What is
The multiplication operator * is used in MicroPython to multiply two
values. It can be used with numbers to perform arithmetic multiplication,
and also with strings to repeat them multiple times.
Why is Important?
The * operator is essential for performing multiplication in mathematical
calculations, scaling values, or repeating strings. It helps simplify many
types of arithmetic and data manipulation tasks in your code.
Syntax
value1 * value2
Syntax Explanation
● value1 and value2 can be numbers (integers or floats) that you
want to multiply. You can also use value1 with a string to repeat it
multiple times, where value2 must be an integer.
Code Example
# Multiplying two numbers
result = 5 * 3
print(result) # Output: 15
# Repeating a string multiple times
repeat_text = "Hi! " * 3
print(repeat_text) # Output: "Hi! Hi! Hi! "
Notes
● The * operator can be used to repeat strings by multiplying them
with an integer. This is useful for creating repeated patterns or
messages.
● When using the * operator with two numbers, both numbers can be
either integers or floating-point values.
Warnings
● If you try to use the * operator with incompatible types (e.g.,
multiplying two strings), it will raise a TypeError.
● Be careful when multiplying very large numbers, as it can lead to
overflow errors or memory issues, especially when working with
limited resources like microcontrollers.
Division Operator (/)
What is
The division operator / is used in MicroPython to divide one value by
another. It returns the result as a floating-point number, even if both
operands are integers.
Why is Important?
The / operator is important for performing division operations in your code,
which are fundamental in many mathematical calculations and data
processing tasks. It allows you to calculate ratios, averages, and distribute
values.
Syntax
value1 / value2
Syntax Explanation
● value1 is the dividend (the number to be divided).
● value2 is the divisor (the number by which you divide). The result
will always be a floating-point number.
Code Example
# Dividing two numbers
result = 10 / 2
print(result) # Output: 5.0
# Using division with variables
a = 15
b=4
division_result = a / b
print(division_result) # Output: 3.75
Notes
● Division with / always returns a floating-point number, even if both
value1 and value2 are integers.
● For integer division (without a remainder), you can use the floor
division operator //.
Warnings
● Dividing by zero will raise a ZeroDivisionError. Always ensure
value2 is not zero before performing division.
● Be cautious with floating-point precision, as dividing very large or
very small numbers may lead to inaccuracies due to how floating-
point arithmetic is handled.
Floor Division Operator (//)
What is
The floor division operator // is used in MicroPython to divide one value by
another and return the largest integer less than or equal to the result. This
means it performs a division and then rounds down to the nearest whole
number.
Why is Important?
The // operator is important when you need to perform integer division
without worrying about the remainder or fractional part. It is particularly
useful in situations where only whole numbers are required, such as
indexing or dividing items into even parts.
Syntax
value1 // value2
Syntax Explanation
● value1 is the dividend (the number to be divided).
● value2 is the divisor (the number by which you divide). The result
will be an integer.
Code Example
# Floor dividing two numbers
result = 10 // 3
print(result) # Output: 3
# Using floor division with variables
a = 15
b=4
floor_division_result = a // b
print(floor_division_result) # Output: 3
Notes
● The // operator discards the remainder and returns only the integer
part of the division.
● If either operand is a float, the result will also be a float but without
the fractional part (e.g., 15.0 // 4 gives 3.0).
Warnings
● Dividing by zero will raise a ZeroDivisionError. Always check that
value2 is not zero before performing floor division.
● Be careful when using negative numbers, as the result will be
rounded down towards negative infinity, which may not always
match your expectations.
Modulus Operator (%)
What is
The modulus operator % is used in MicroPython to find the remainder
when one value is divided by another. It is useful for determining if a
number is evenly divisible by another number.
Why is Important?
The % operator is important for operations where you need to check if a
value is divisible (e.g., checking for even or odd numbers) or when working
with cyclic patterns like determining whether a number is within a range or
finding remainders.
Syntax
value1 % value2
Syntax Explanation
● value1 is the dividend (the number to be divided).
● value2 is the divisor (the number by which you divide). The result
is the remainder after the division.
Code Example
Notes
● The % operator is helpful for determining if a number is even or
odd. For example, number % 2 gives 0 for even numbers and 1 for
odd numbers.
● You can also use the modulus operator to work with cyclic
conditions, such as checking the rotation index within a given
range.
Warnings
● Dividing by zero will raise a ZeroDivisionError. Always ensure
value2 is not zero before using the modulus operator.
● The result of % will have the same sign as the divisor, so be careful
when working with negative numbers, as it can affect the
remainder.
Exponentiation Operator ()**
What is
The exponentiation operator ** is used in MicroPython to raise one number
to the power of another. It performs exponential calculations, where a base
number is multiplied by itself a specified number of times.
Why is Important?
The ** operator is important for performing mathematical calculations that
involve powers, such as squaring a number or finding higher powers. It is
especially useful in applications involving scientific calculations, physics,
and geometry.
Syntax
base ** exponent
Syntax Explanation
● base is the number you want to raise.
● exponent is the power to which you want to raise the base. The
result will be base raised to the power of exponent.
Code Example
Notes
● The ** operator can be used with both integers and floats, allowing
for fractional exponents (e.g., 9 ** 0.5 calculates the square root of
9).
● You can also use negative exponents to calculate the reciprocal of a
number raised to a positive power (e.g., 2 ** -3 results in 0.125).
Warnings
● Be cautious when using very large exponents, as the result can
quickly grow beyond the storage capacity of your microcontroller,
leading to an OverflowError.
● When using negative bases with fractional exponents, you may
encounter complex numbers, which MicroPython may not handle
directly without additional libraries or functions.
Comparison Operators
Equal To Operator (==)
What is
The == operator in MicroPython is used to compare two values to check if
they are equal. It returns True if the values are the same, and False
otherwise.
Why is Important?
The == operator is important for making decisions in your code. It is used
in conditional statements, such as if statements, to determine whether
certain actions should be taken based on whether two values are equal.
Syntax
value1 == value2
Syntax Explanation
● value1 and value2 are the values you want to compare. They can be
of any data type, such as numbers, strings, or booleans.
Code Example
# Comparing two numbers
result = (5 == 5)
print(result) # Output: True
# Using equal to in an if statement
temperature = 25
if temperature == 25:
print("Temperature is 25 degrees.") # Output: Temperature is 25 degrees.
Notes
● The == operator checks for value equality, not identity. This means
it checks if the values are the same, not whether they are stored in
the same memory location.
● The result of == is always a boolean (True or False), and it can be
used in any context that expects a boolean value.
Warnings
● Be careful not to confuse the == operator with the assignment
operator =, which is used to assign values to variables.
Not Equal To Operator (!=)
What is
The != operator in MicroPython is used to compare two values to check if
they are not equal. It returns True if the values are different, and False if
they are the same.
Why is Important?
The != operator is important for decision-making in your code. It is used in
conditional statements to determine whether certain actions should be taken
based on whether two values are not equal.
Syntax
value1 != value2
Syntax Explanation
● value1 and value2 are the values you want to compare. They can be
of any data type, such as numbers, strings, or booleans.
Code Example
# Comparing two numbers
result = (5 != 3)
print(result) # Output: True
# Using not equal to in an if statement
password = "abc123"
if password != "password":
print("Access Denied.") # Output: Access Denied.
Notes
● The != operator checks for value inequality, meaning it verifies if
the values are different.
● The result of != is always a boolean (True or False), which can be
used in if statements or loops to control the flow of your program.
Warnings
● Be careful when comparing different data types, as this can lead to
unexpected results. For example, 5 != "5" will return True because
one is an integer and the other is a string.
● Avoid confusing the != operator with the assignment operator =,
which is used to assign values to variables.
Greater Than Operator (>)
What is
The > operator in MicroPython is used to compare two values to check if
the first value is greater than the second. It returns True if the first value is
larger, and False otherwise.
Why is Important?
The > operator is important for decision-making and conditional logic in
your code. It is useful for comparing numerical values to determine if one is
larger than the other, which is helpful in sorting, filtering, or controlling the
flow of your program.
Syntax
Syntax Explanation
● value1 and value2 are the values you want to compare. Both can be
integers, floats, or any other comparable data type.
Code Example
# Comparing two numbers
result = 10 > 5
print(result) # Output: True
# Using greater than in an if statement
speed = 60
if speed > 50:
print("You are over the speed limit!") # Output: You are over the speed limit!
Notes
● The > operator can be used with both integers and floats.
● This operator is often used in if statements, loops, or to sort values
by comparing them.
Warnings
● Be careful when comparing different data types, such as strings and
numbers, as it can lead to errors or unexpected results.
● If you compare two values that are not directly comparable (like a
string and an integer), it will raise a TypeError. Always ensure the
data types are compatible before comparing them.
Less Than Operator (<)
What is
The < operator in MicroPython is used to compare two values to check if
the first value is less than the second. It returns True if the first value is
smaller, and False otherwise.
Why is Important?
The < operator is important for making comparisons and implementing
conditional logic in your code. It is useful for situations where you need to
verify if one value is smaller than another, such as setting limits, filtering
data, or controlling loops.
Syntax
Syntax Explanation
● value1 and value2 are the values you want to compare. Both can be
integers, floats, or any other comparable data type.
Code Example
Notes
● The < operator works with numbers (integers or floats) and helps
in determining the relationship between them.
● It is commonly used in if statements, loops, and conditional checks.
Warnings
● Be careful not to compare incompatible data types, such as trying
to compare a string with a number, as it can cause a TypeError.
● When comparing values, ensure the types are consistent to avoid
unexpected outcomes or errors.
Greater Than or Equal To Operator (>=)
What is
The >= operator in MicroPython is used to compare two values to check if
the first value is greater than or equal to the second. It returns True if the
first value is either greater than or equal to the second value, and False
otherwise.
Why is Important?
The >= operator is important for making comparisons and implementing
decision-making logic in your code. It is useful for scenarios where you
need to determine if a value has reached or exceeded a specific threshold,
which is common in control flow and condition checks.
Syntax
Syntax Explanation
● value1 and value2 are the values you want to compare. Both can be
integers, floats, or any other comparable data type.
Code Example
# Comparing two numbers
result = 5 >= 5
print(result) # Output: True
# Using greater than or equal to in an if statement
score = 75
if score >= 70:
print("You passed the exam!") # Output: You passed the exam!
Notes
● The >= operator checks both conditions—whether the first value is
greater than or equal to the second.
● It is commonly used in loops, conditionals, and comparisons
involving thresholds.
Warnings
● Be mindful of the data types being compared, as comparing
incompatible types (like a string and a number) will raise a
TypeError.
● Ensure that the values are of a comparable type to avoid
unexpected results or runtime errors.
Less Than or Equal To Operator (<=)
What is
The <= operator in MicroPython is used to compare two values to check if
the first value is less than or equal to the second. It returns True if the first
value is either less than or equal to the second value, and False otherwise.
Why is Important?
The <= operator is important for implementing conditions and decision-
making in your code. It is useful when you need to determine if a value is
below or has reached a certain limit, which is commonly used in loops and
conditional checks.
Syntax
Syntax Explanation
● value1 and value2 are the values you want to compare. Both can be
integers, floats, or any other comparable data type.
Code Example
# Comparing two numbers
result = 4 <= 5
print(result) # Output: True
# Using less than or equal to in an if statement
temperature = 22
if temperature <= 25:
print("Temperature is comfortable.") # Output: Temperature is comfortable.
Notes
● The <= operator checks both conditions—whether the first value is
less than or equal to the second.
● This operator is often used in loops, conditionals, and checks where
there is a limit or maximum threshold.
Warnings
● Avoid comparing incompatible data types, like a string with a
number, as this will raise a TypeError.
● Always ensure that the values being compared are of a compatible
type to avoid unexpected outcomes or errors during program
execution.
Logical Operators
Logical AND Operator (and)
What is
The and operator in MicroPython is a logical operator used to combine two
conditions. It returns True only if both conditions are True, and returns
False if either of the conditions is False.
Why is Important?
The and operator is important for making complex logical decisions in your
code. It allows you to check multiple conditions simultaneously, which is
useful for scenarios where more than one condition must be met before
proceeding with a specific action.
Syntax
condition1 and condition2
Syntax Explanation
● condition1 and condition2 are the two conditions being checked.
Both must be True for the result to be True; otherwise, the result
will be False.
Code Example
# Checking two conditions
temperature = 20
humidity = 50
if temperature > 15 and humidity < 60:
print("The weather is pleasant.") # Output: The weather is pleasant.
Notes
● The and operator is used to ensure that multiple criteria are met
before taking an action.
● It is commonly used in if statements, loops, or other decision-
making constructs to combine conditions.
Warnings
● If either condition is False, the entire expression will be False.
Make sure both conditions are defined and evaluated properly to
avoid unexpected outcomes.
● Be careful with data types; logical conditions should be boolean
expressions or values that can be evaluated as True or False.
Logical OR (or)
What is
The or operator in MicroPython is a logical operator used to combine two
conditions. It returns True if at least one of the conditions is True, and only
returns False if both conditions are False.
Why is Important
The or operator is crucial for decision-making when you need to verify if at
least one condition is met. It simplifies logic in scenarios where multiple
conditions can trigger an action, making it essential for controlling the flow
of your program.
Syntax
condition1 or condition2
Syntax Explanation
condition1 and condition2 are the two conditions being checked. The result
is True if either one of the conditions is True. It will only be False if both
conditions are False.
Code Example
Notes
● The or operator is useful when at least one condition should be
satisfied before executing a block of code.
● It can be used in if statements or loops to simplify decision-making
where multiple possibilities exist.
Warnings
● If both conditions are False, the entire expression will be False.
Ensure your conditions are well defined.
● Be cautious with data types; logical conditions should be boolean
expressions or values that can be evaluated as True or False.
Logical NOT (not)
What is
The not operator in MicroPython is a logical operator used to reverse the
truth value of a condition. If a condition is True, the not operator will make
it False, and vice versa.
Why is Important
The not operator is important for situations where you need to negate a
condition. It helps simplify logic in cases where you want to perform an
action when a condition is False rather than True.
Syntax
not condition
Syntax Explanation
not is placed before a condition, and it will return the opposite boolean
value of that condition. If the condition is True, not condition will return
False, and if it is False, not condition will return True.
Code Example
Notes
● The not operator is used when you want to reverse the outcome of
a condition.
● It is commonly used in if statements or loops where the opposite
condition is required.
Warnings
● Be careful with double negatives (using not too many times), as
they can make the logic harder to understand.
● Ensure that the condition is properly defined to avoid unexpected
results when using not.
Common Mistakes and How to Avoid Them
1. Using Incompatible Data Types with Operators
2. Dividing by Zero
Conditional Statements:
If Statement
What is
The if statement in MicroPython is a conditional statement used to execute
a block of code if a specified condition is True. If the condition is False, the
code block is skipped.
Why is Important
The if statement is essential for decision-making in your program. It allows
you to control the flow of the code by performing actions only when certain
conditions are met, making your program responsive and dynamic.
Syntax
if condition:
# code block
Syntax Explanation
if condition checks whether the condition is True or False. If it is True, the
indented code block will run. If the condition is False, the code block will
be skipped.
Code Example
Notes
● The if statement is used to control which parts of your code are
executed based on certain conditions.
● Indentation is crucial in MicroPython for defining the code block
that belongs to the if statement.
Warnings
● Be careful with indentation. Improper indentation can lead to
syntax errors or unexpected behavior.
● Ensure that the condition inside the if statement is properly defined
to avoid errors or incorrect logic.
Elif
What is
The elif statement in MicroPython is short for "else if." It allows you to
check multiple conditions in sequence after an if statement. If the if
condition is False, the elif condition is checked. This continues until a
condition is True or all conditions are evaluated.
Why is Important
The elif statement is important because it allows you to handle multiple
scenarios in your code efficiently. Instead of writing multiple if statements,
you can use elif to make your code cleaner and easier to manage, especially
when checking for several conditions.
Syntax
if condition1:
# code block
elif condition2:
# code block
else:
# code block
Syntax Explanation
● if condition1: The first condition is checked. If it's True, the code
block under it runs.
● elif condition2: If the if condition is False, this condition is
checked. If True, the code block under it runs.
● else: If none of the previous conditions are True, this final block is
executed.
Code Example
temperature = 20 if temperature > 30:
print("It's hot.")
elif temperature > 15:
print("It's warm.")
else:
print("It's cool.")
Notes
● The elif statement is optional, but useful when multiple conditions
need to be evaluated.
● You can include as many elif statements as needed between if and
else.
Warnings
● Ensure that only one condition is True at a time; if multiple
conditions are True, only the first one encountered will be executed.
Else
What is
The else statement in MicroPython is used as a fallback option in
conditional statements. It is executed when all preceding if or elif conditions
are False.
Why is Important
The else statement is important because it ensures that a block of code will
always run if none of the conditions in the if or elif statements are met. This
provides a way to handle cases that don't fit specific conditions.
Syntax
if condition:
# code block
else:
# code block
Syntax Explanation
● if condition: The first condition is checked. If it's True, the code
block under if is executed.
● else: If the if condition is False, the else block is executed, serving
as a default case.
Code Example
temperature = 10 if temperature > 20:
print("It's warm.")
else:
print("It's cold.")
Notes
● The else statement is optional but useful when you want to ensure
that some code runs, even if none of the if or elif conditions are
satisfied.
● The else block always comes at the end of an if-elif-else chain.
Warnings
● Ensure that the else block is properly indented to avoid syntax
errors.
● The else block will run only when all other conditions are False.
Make sure the logic fits your program's needs.
Looping
For
What is
The for loop in MicroPython is used to iterate over a sequence (like a list,
tuple, or range) and execute a block of code for each element in that
sequence.
Why is Important
The for loop is important because it allows you to repeat a block of code
multiple times without having to write it out for each iteration. This is
useful for tasks like processing data, running repetitive tasks, or automating
actions in your program.
Syntax
Syntax Explanation
● for variable: This part defines a variable that takes the value of
each item in the sequence one at a time.
● in sequence: This is the sequence you are iterating over, such as a
list, tuple, or range.
● The code block will be executed once for each item in the
sequence.
Code Example
for i in range(5):
print(i)
This will print the numbers 0 to 4.
Notes
● The for loop is commonly used to iterate over a list of items or run
a block of code a specific number of times.
● The range() function is often used to generate a sequence of
numbers.
Warnings
● Be careful with sequences that are too large, as looping over large
data sets might affect performance on limited-memory
microcontrollers.
While
What is
The while loop in MicroPython is a control flow statement that repeatedly
executes a block of code as long as a specified condition remains True.
Why is Important
The while loop is important because it allows you to run a block of code
multiple times based on a condition. It's useful for situations where you
don’t know in advance how many iterations are needed, but you want the
loop to continue until a specific condition is met.
Syntax
while condition:
# code block
Syntax Explanation
● while condition: The loop runs as long as the condition is True.
● The code block will execute repeatedly until the condition becomes
False.
Code Example
Syntax Explanation
The break statement can be placed inside a for or while loop. When the loop
encounters the break statement, it immediately stops, and the program
continues with the code following the loop.
Code Example
for i in range(10):
if i == 5:
break print(i)
Syntax Explanation
The continue statement is placed inside a for or while loop. When
encountered, it causes the loop to immediately proceed to the next iteration,
skipping any code below the continue statement for that iteration.
Code Example
for i in range(5):
if i == 3:
continue print(i)
Syntax Explanation
The pass statement can be placed inside any block of code, such as loops,
functions, or conditionals, where Python expects a statement but you don’t
want to perform any actions.
Code Example
for i in range(5):
pass
Return Statement
What is
The return statement in MicroPython is used in functions to send a value
back to the caller. Once the return statement is executed, the function
terminates, and the specified value is passed back.
Why is Important
The return statement is important because it allows functions to provide
results or output that can be used later in the program. It enables functions
to process data and return a specific value or result.
Syntax
return value
Syntax Explanation
The return statement is used inside a function. It can return a value (such as
an integer, string, list, etc.), or it can return nothing (by simply using return
without any value).
Code Example
Notes
● The return statement can return any type of data, including
numbers, strings, lists, or even other functions.
● A function can have multiple return statements, but only one will
be executed based on the function's logic.
Warnings
● Once the return statement is executed, the function ends, so no
code after return will run.
● Be cautious when using multiple return statements in a function, as
it can make the code harder to follow.
Exception Handling
What is
Exception handling in MicroPython refers to the process of managing errors
that occur during program execution, preventing the program from
crashing. It allows you to catch and handle unexpected situations, ensuring
the program can respond gracefully to errors.
Why is Important
Exception handling is important because it helps in writing robust and
error-tolerant code. By catching and managing errors, your program can
avoid unexpected crashes and continue running or provide meaningful error
messages to the user.
Syntax
try:
# code that might raise an exception
except ExceptionType:
# code to handle the exception
Syntax Explanation
● try: The code inside this block is executed, and it may raise an
exception.
● except: If an error (exception) occurs in the try block, the except
block runs to handle the error.
● ExceptionType is optional and specifies the type of error to catch
(e.g., ValueError, ZeroDivisionError). If omitted, it catches any
exception.
Code Example
try:
result = 10 / 0 except ZeroDivisionError:
print("Cannot divide by zero!")
This will catch the division error and print a message instead of crashing the
program.
Notes
● Exception handling is useful when dealing with unpredictable
situations, like user input or file handling.
● You can use multiple except blocks to handle different types of
exceptions.
Warnings
● Be careful not to catch generic exceptions without handling them
properly, as it may hide bugs or make debugging harder.
● Always aim to catch specific exceptions (e.g., ValueError,
FileNotFoundError) to handle different cases effectively.
3. Infinite Loops
Syntax
time.sleep(seconds)
Syntax Explanation
● time.sleep() is the function call.
● seconds is the number of seconds the program should wait before
continuing. This can be a floating-point number to create sub-second delays
(e.g., time.sleep(0.5) for half a second).
Code Example
import time print("Start")
time.sleep(2)
print("End")
This will print "Start," wait for 2 seconds, and then print "End."
Notes
● You can use time.sleep() to create pauses in your program for both whole
and fractional seconds.
● It’s often used in loops to control the pace of repeated actions like blinking
LEDs or polling sensors.
Warnings
● Be cautious when using long delays, as they can make your program
unresponsive for that duration.
● time.sleep() halts the entire program, so if you need other parts of the
program to continue running during a delay, consider other timing
techniques.
Non-blocking Delays Using Timers
What is
Non-blocking delays using timers in MicroPython allow you to create delays without
stopping the execution of your entire program. Timers run in the background while
the main program continues, making them useful for multitasking.
Why is Important
Non-blocking delays are important because they enable your program to handle
multiple tasks simultaneously. Unlike time.sleep(), which blocks the entire program,
timers let you perform other actions while waiting, which is crucial for real-time
applications like sensor data reading and controlling devices.
Syntax
Timer.init(period=milliseconds, mode=Timer.ONE_SHOT or Timer.PERIODIC, callback=function)
Syntax Explanation
● Timer.init() is used to set up the timer.
● period specifies the interval in milliseconds.
● mode defines how the timer operates: Timer.ONE_SHOT for a single delay
or Timer.PERIODIC for repeated intervals.
● callback is the function that will be executed once the timer finishes.
Code Example
from machine import Timer def blink_led(timer):
print("LED blink")
timer = Timer(0)
timer.init(period=1000, mode=Timer.PERIODIC, callback=blink_led)
This example will call the blink_led function every 1 second without blocking the
main program.
Notes
● Timers are ideal for non-blocking delays where you need periodic actions,
such as sensor polling or blinking LEDs, while still allowing the rest of the
program to run.
● You can stop a timer using timer.deinit() when it is no longer needed.
Warnings
● Be careful with overlapping timers; ensure that multiple timers do not
interfere with each other.
● Always properly handle the callback function to avoid unexpected behavior
when the timer triggers.
Common Mistakes and How to Avoid Them
1. Blocking the Entire Program with time.sleep()
Syntax Explanation
● def: Keyword used to define a function.
● function_name: The name you give to the function.
● parameters: Optional inputs (arguments) that you can pass to the function to
process.
● The indented code block inside the function is executed when the function is
called.
Code Example
def greet(name):
print("Hello, " + name)
greet("Alice")
greet("Bob")
Syntax Explanation
● param1, param2, ...: These are placeholders for the inputs that the function
accepts.
● return value: The function ends and sends back the specified result to the
caller.
Code Example
def add_numbers(a, b):
return a + b
result = add_numbers(3, 7)
print(result) # Output: 10*
Notes
● You can define multiple parameters in a function to make it work with
different inputs.
● The return statement allows you to send back results from the function to the
rest of the program.
Warnings
● If a function does not have a return statement, it returns None by default.
● Be cautious with the number and type of parameters passed to the function
to avoid errors.
Default Parameters and Keyword Arguments
What is
In MicroPython, functions can have default parameters, which provide a default value
if no argument is passed. Keyword arguments allow you to specify arguments by
name when calling a function, making the function calls more readable.
Why is Important
Default parameters are important because they make functions more flexible and
versatile by allowing some arguments to be optional. Keyword arguments improve
code readability and make it easier to understand the purpose of each argument when
calling a function.
Syntax
Understanding Scope
What is
Scope in MicroPython refers to the region of a program where a variable is
accessible. Return values are the results that a function sends back to the code that
called it using the return statement.
Why is Important
Understanding scope is important because it determines where variables can be used
within your program, preventing errors caused by referencing undefined variables.
Return values are crucial for getting output from functions, enabling you to use the
result elsewhere in your code.
Syntax
def function_name():
# code block
return value
Syntax Explanation
● Variables defined inside a function have local scope, meaning they can only
be used within that function.
● The return statement allows you to send a value back from a function to the
part of the program that called it.
Code Example
def calculate_sum(a, b):
result = a + b # result has local scope
return result
total = calculate_sum(5, 10)
print(total) # Output: 15
Notes
● Variables defined inside a function (local variables) are not accessible
outside the function.
● Return values allow you to pass data out of a function to be used in other
parts of your program.
Warnings
● Be careful with variable scope: if you need to access a value outside of a
function, you must return it using the return statement.
Syntax Explanation
● import module_name: This imports the entire module, allowing access to all
its functions and classes.
● from module_name import function_name: This imports only specific
functions or classes from a module.
Code Example
upip.install('module_name')
Syntax Explanation
● upip.install('module_name'): This is the command used to install external
modules using the MicroPython package installer. It fetches the module
from a repository and installs it onto your device.
Code Example
import upip upip.install('micropython-umqtt.robust') # Installs the MQTT library for handling IoT protocols
Notes
● You can use upip to install packages directly on your ESP32/ESP8266 if it's
connected to the internet.
● Alternatively, you can manually upload external modules to your device
using tools like ampy or Thonny.
Warnings
● Make sure your ESP32/ESP8266 is connected to the internet if you're using
upip for installation.
Syntax Explanation
● network.WLAN(): Creates a WLAN (Wi-Fi) interface.
● network.STA_IF: Sets the device to "station" mode, allowing it to connect to
an existing Wi-Fi network.
● active(True): Activates the Wi-Fi interface.
● connect('SSID', 'password'): Connects to the specified Wi-Fi network using
the provided SSID and password.
Code Example
This example connects the device to a Wi-Fi network and prints the IP address once
connected.
Notes
● The network module allows you to configure both station mode (STA_IF)
for connecting to Wi-Fi and access point mode (AP_IF) for creating a
hotspot.
● You can use sta_if.isconnected() to check whether the device is successfully
connected to the Wi-Fi network.
Warnings
● Ensure that the SSID and password are correct, or the device will not
connect to the network.
● Avoid using hardcoded credentials in your code for security reasons.
Consider using environment variables or secure methods to handle sensitive
information.
Notes
● The dht module works with both DHT11 and DHT22 sensors. DHT11 is less
accurate but cheaper, while DHT22 provides better accuracy and a wider
range.
● Be sure to use the correct sensor initialization (DHT11 or DHT22) based on
the model you're using.
Warnings
● DHT sensors are relatively slow and can only be read every 2 seconds (for
DHT11) or 0.5 seconds (for DHT22). Make sure you wait between
consecutive reads.
● Ensure that the sensor is wired correctly, with the right pin for data, power,
and ground to avoid errors in data readings.
Common Mistakes and How to Avoid Them
1. Not Defining the Function Before Calling It
from machine import Pin pin = Pin(pin_number, Pin.OUT) or pin = Pin(pin_number, Pin.IN)
Syntax Explanation
● Pin(pin_number, Pin.OUT): Sets the pin to output mode, used for controlling
devices like LEDs or motors.
● Pin(pin_number, Pin.IN): Sets the pin to input mode, used for reading
sensors or button states.
● pin.on(): Turns on the output (for output mode).
● pin.off(): Turns off the output (for output mode).
● pin.value(): Reads the pin value (for input mode).
Code Example
from machine import Pin
led = Pin(2, Pin.OUT) # Set GPIO2 as an output pin
led.on() # Turn on the LED
led.off() # Turn off the LED*
button = Pin(0, Pin.IN) # Set GPIO0 as an input pin
if button.value() == 0: # Check if the button is pressed
print("Button pressed")
Notes
● GPIO pins can be used to control digital devices or read digital inputs
(on/off states).
● Be sure to configure the pin correctly for input or output depending on the
task.
Warnings
● Always verify the correct GPIO pin numbers for your board as they can
differ between ESP32 and ESP8266.
● Be careful with voltage levels, as certain components may require specific
operating voltages. Overvoltage can damage your board or components.
Syntax Explanation
● Pin(pin_number, Pin.IN): Configures the pin as a digital input.
● Pin.PULL_UP or Pin.PULL_DOWN: Optional internal resistor settings to
prevent floating inputs.
● pin.value(): Reads the current state of the pin (1 for high, 0 for low).
Code Example
from machine import Pin button = Pin(0, Pin.IN, Pin.PULL_UP) # Setup GPIO0 as input with internal pull-up
resistor*
if button.value() == 0: # Check if button is pressed (active low)
print("Button pressed")*
else:
print("Button not pressed")
Notes
● Pull-up or pull-down resistors are crucial for stable digital input readings,
especially for buttons. These resistors prevent "floating" states when no
signal is connected.
● The Pin.PULL_UP and Pin.PULL_DOWN options set the internal resistors,
making external resistors unnecessary in many cases.
Warnings
● Ensure the input signal's voltage level is compatible with the
ESP32/ESP8266's 3.3V GPIO pins to avoid damage.
● Avoid using floating inputs without resistors, as they may produce unreliable
or fluctuating readings.
Analog Input: machine.ADC()
What is
The machine.ADC() function in MicroPython is used to read analog signals from
components like sensors. Unlike digital inputs, which can only read high (1) or low
(0) states, analog inputs read a range of values that represent continuous signals, such
as temperature or light levels.
Why is Important
Analog input is important because it allows your ESP32 or ESP8266 to interpret real-
world signals, like varying voltage levels from sensors. This is essential for projects
where you need to monitor environmental conditions, such as temperature, light, or
pressure.
Syntax
from machine import ADC, Pin adc = ADC(Pin(34)) # Set GPIO34 for analog input*
value = adc.read() # Read analog value*
print("Analog value:", value)
Notes
● The ESP32 can read analog values between 0 and 4095 (corresponding to
0V to 3.3V by default). On ESP8266, the range is typically 0 to 1023.
● You can scale the analog value to match the sensor's range or voltage
reference using simple math, e.g., voltage = (value / 4095) * 3.3.
Warnings
● Ensure that the input voltage to the analog pin does not exceed the operating
voltage (typically 3.3V for ESP32 and ESP8266). Higher voltages may
damage the board.
● The ADC input resolution may vary depending on the pin and board model,
so check your microcontroller’s specifications to ensure accurate readings.
Syntax Explanation
● Pin(pin_number, Pin.OUT): Sets the pin as an output pin.
● pin.value(value): Sets the pin’s output value. A value of 1 sets the
pin to high (on), and 0 sets it to low (off).
Code Example
from machine import Pin led = Pin(2, Pin.OUT) # Set GPIO2 as an output*
led.value(1) # Turn on the LED*
led.value(0) # Turn off the LED*
Notes
● The value(1) function sets the GPIO pin to high, and value(0) sets
it to low.
● You can use this method to control devices like LEDs, relays, or
any other digital output devices.
Warnings
● Be cautious of the voltage and current ratings when controlling
external components, especially high-power devices like motors or
relays.
● Ensure that external components are properly wired to prevent
damage to your microcontroller and components. Always use
appropriate transistors or relays for high-power devices.
PWM Output: machine.PWM()
What is
The machine.PWM() function in MicroPython is used to generate Pulse
Width Modulation (PWM) signals on a GPIO pin. PWM allows you to
control devices like LEDs, motors, and servos by adjusting the duty cycle
of the signal, which determines how long the pin stays high within a cycle.
Why is Important
PWM output is important because it provides fine control over devices. By
adjusting the duty cycle, you can control brightness, motor speed, or even
position in servos, allowing for more precise and dynamic interactions in
your project.
Syntax
Syntax Explanation
● PWM(Pin(pin_number), freq=frequency): Initializes a PWM signal
on a specific GPIO pin with the given frequency (in Hz).
● duty=duty_cycle: Sets the duty cycle of the PWM signal. The value
ranges from 0 (always off) to 1023 (always on) for ESP8266 and 0
to 65535 for ESP32.
Code Example
from machine import PWM, Pin pwm = PWM(Pin(2), freq=5000) # Set GPIO2 with 5kHz PWM
signal*
pwm.duty(512) # Set duty cycle to 50% (on for half the time)*
Notes
● The frequency determines how fast the signal oscillates. For
example, a 5kHz frequency will oscillate the signal 5000 times per
second.
● The duty cycle controls how long the signal stays high in each
cycle. For example, 50% duty means the signal is high for half of
the cycle.
GPIO Pull-Up and Pull-Down Resistors
What is
Pull-up and pull-down resistors are internal or external resistors used to
ensure that a GPIO pin has a defined state (either high or low) when it is not
actively driven by an external signal. A pull-up resistor pulls the pin to a
high state, while a pull-down resistor pulls it to a low state.
Why is Important
Pull-up and pull-down resistors are important because they prevent floating
states (undefined or noisy signals) on GPIO pins, which can lead to erratic
behavior. This is especially useful when working with buttons or switches
where the pin needs a reliable state when not pressed or toggled.
Syntax
from machine import Pin pin = Pin(pin_number, Pin.IN, Pin.PULL_UP) or pin = Pin(pin_number,
Pin.IN, Pin.PULL_DOWN)
Syntax Explanation
● Pin(pin_number, Pin.IN): Configures the pin as an input.
● Pin.PULL_UP: Enables the internal pull-up resistor, setting the pin
to a default high state.
● Pin.PULL_DOWN: Enables the internal pull-down resistor, setting
the pin to a default low state.
Code Example
from machine import Pin button = Pin(0, Pin.IN, Pin.PULL_UP) # Configure GPIO0 as input with a
pull-up resistor*
if button.value() == 0: # Check if the button is pressed (active low)
print("Button pressed")*
Notes
● Pull-up and pull-down resistors are useful for buttons or switches
where you want to ensure a stable signal when no input is present.
● Most GPIO pins on ESP32 and ESP8266 support internal pull-up
and pull-down resistors, so external resistors are often unnecessary.
Warnings
● Be cautious when using pull-down resistors, as not all GPIO pins
on the ESP32/ESP8266 support internal pull-down resistors. Check
the pinout for your specific board.
GPIO Interrupts
What is
GPIO interrupts allow your ESP32 or ESP8266 to react immediately to
changes on a GPIO pin (e.g., a button press) by executing a specific
function when the state of the pin changes. Interrupts can trigger on rising
edges (low to high), falling edges (high to low), or both.
Why is Important
GPIO interrupts are important because they enable real-time reactions to
hardware events without constantly checking the pin’s state. This makes
your code more efficient by only executing when an event occurs, rather
than using continuous polling, which can waste processing time.
Syntax
Circuit connection:
● Connect the LED’s positive leg (anode) to GPIO 2 (for example)
via a 220Ω resistor, and connect the negative leg (cathode) to GND.
● Connect one side of the button to GPIO 0, and the other side to
GND. If using an external pull-up resistor, connect a 10kΩ resistor
between GPIO 0 and 3.3V.
Micropython code
while True:
if button.value() == 0: # Button pressed (active low)
led.on() # Turn on the LED
else:
led.off() # Turn off the LED
time.sleep(0.1) # Debounce delay
Code Explanation
● led_pin = 2, button_pin = 0: These variables store the pin numbers
for the LED and button using the int data type, making it easy to
manage and modify pin numbers.
● Pin(led_pin, Pin.OUT): Configures the GPIO pin for the LED as
an output.
● Pin(button_pin, Pin.IN, Pin.PULL_UP): Configures the GPIO pin
for the button as an input with an internal pull-up resistor to avoid
floating values when the button is not pressed.
● if button.value() == 0: Checks if the button is pressed. The button
is active low, so when pressed, its value is 0.
● led.on() and led.off(): These control the LED by turning it on or off
based on the button's state.
● time.sleep(0.1): Introduces a short delay to debounce the button,
ensuring stable and reliable input readings.
Note:
● The GPIO pin numbers (e.g., 2 for the LED and 0 for the button)
can be changed depending on your board and setup.
● The pull-up resistor ensures that the button works reliably without
needing external hardware components, but you can also use an
external pull-up resistor if needed.
Circuit connection:
● Connect each LED’s positive leg (anode) to a separate GPIO pin
(e.g., GPIO 2, GPIO 4, and GPIO 5) through a 220Ω resistor.
Connect each LED’s negative leg (cathode) to GND.
● Connect one side of the button to GPIO 0, and the other side to
GND. If using an external pull-up resistor, connect a 10kΩ resistor
between GPIO 0 and 3.3V.
Micropython code
while True:
if button.value() == 0: # Button pressed (active low)
leds[led_index].on() # Turn on the current LED
time.sleep(0.5) # Keep the LED on for a short period
leds[led_index].off() # Turn off the current LED
led_index = (led_index + 1) % len(leds) # Move to the next LED
time.sleep(0.5) # Debounce delay
Code Explanation
● led_pins = [2, 4, 5]: A list that stores the GPIO pin numbers for the
three LEDs.
● Pin(pin, Pin.OUT) for pin in led_pins: Initializes each LED as an
output based on the list of GPIO pins.
● if button.value() == 0: Checks if the button is pressed.
● leds[led_index].on() and leds[led_index].off(): Turn on and off the
current LED in the sequence.
● led_index = (led_index + 1) % len(leds): Moves to the next LED in
the list, using the modulo operator to cycle back to the first LED
after the last one.
● time.sleep(0.5): Adds delays for debounce and to give visible
feedback of the LED toggling.
Note:
● You can increase the number of LEDs by adding more pin numbers
to the led_pins list.
● The button press toggles through each LED, and the LEDs blink
sequentially with each button press. You can adjust the time delay
and cycle behavior based on your project's needs.
Circuit connection:
● Connect the LED’s positive leg (anode) to GPIO 2 through a 220Ω
resistor, and connect the negative leg (cathode) to GND.
● Connect one side of the button to GPIO 0, and the other side to
GND. Use a 10kΩ pull-up resistor between GPIO 0 and 3.3V (if
not using an internal pull-up).
● Connect the temperature sensor's VCC to 3.3V, GND to GND, and
the analog output to an ADC pin (e.g., GPIO 34 on ESP32).
Micropython code
from machine import ADC, Pin
import time
def read_temperature():
raw_value = sensor.read()
voltage = (raw_value / 4095) * 3.3 # Convert raw value to voltage (ESP32 12-bit ADC)
temperature = voltage * 100 # For LM35 sensor: 10mV = 1°C
return temperature
while True:
if button.value() == 0: # Button pressed (active low)
temperature = read_temperature()
Code Explanation
● led_pin, button_pin, sensor_pin: Defines the GPIO pins for the
LED, button, and temperature sensor using the int data type.
● read_temperature(): Reads the raw ADC value from the
temperature sensor, converts it to voltage, and then converts it to
temperature in Celsius (for an LM35 sensor).
● if button.value() == 0: Checks if the button is pressed.
● if temperature > 30: Adjusts the LED blinking speed based on the
temperature. The LED blinks faster if the temperature is above
30°C.
● for _ in range(5): Blinks the LED 5 times at the specified speed
based on the temperature.
● time.sleep(0.1): Introduces a debounce delay to avoid multiple
readings when the button is pressed.
Note:
● You can adjust the temperature threshold and blinking speed based
on your project requirements.
● The temperature sensor calibration (e.g., for LM35 or TMP36) can
be adjusted by modifying the conversion formula in
read_temperature().
Requirement component:
● ESP32 or ESP8266
● Temperature sensor (e.g., LM35 or TMP36)
● Fan or DC motor (connected via relay or NPN transistor)
● Relay module or NPN transistor (for fan control)
● Diode (if using a transistor to prevent back EMF)
● Breadboard
● Jumper wires
Circuit diagram:
Circuit connection:
● Connect the temperature sensor’s VCC to 3.3V, GND to GND, and
the analog output to an ADC pin (e.g., GPIO 34 on ESP32).
● Connect the fan’s positive terminal to an external 5V/12V power
supply, and connect the negative terminal to the relay’s NO
(Normally Open) pin or the transistor's collector.
● Connect the relay/transistor control pin to a GPIO pin (e.g., GPIO
2).
● Optionally, connect a button to GPIO 0 for manual fan control.
Micropython code
from machine import ADC, Pin
import time
def read_temperature():
raw_value = sensor.read()
voltage = (raw_value / 4095) * 3.3 # Convert raw ADC value to voltage (12-bit ADC)
temperature = voltage * 100 # For LM35 sensor: 10mV = 1°C
return temperature
while True:
temperature = read_temperature()
print("Current Temperature:", temperature)
Circuit connection:
● Connect the LDR sensor between 3.3V and an ADC pin (e.g.,
GPIO 34 on ESP32), with a pull-down resistor (10kΩ) connected to
GND.
● Connect the LED’s positive leg (anode) to GPIO 2 through a 220Ω
resistor and the negative leg (cathode) to GND.
● Alternatively, for a relay, connect the relay’s input pin to GPIO 2,
the common pin to the light's power supply, and the normally open
pin to the light's positive terminal.
Micropython code
# Initialize pins
light = Pin(led_pin, Pin.OUT) # LED or relay output pin
sensor = ADC(Pin(sensor_pin)) # Initialize ADC for light sensor
# Main loop
while True:
light_level = read_light_level() # Get the light level
print("Ambient Light Level:", light_level)
Code Explanation
● led_pin, sensor_pin: Defines GPIO pins for the light and ambient
light sensor.
● threshold_light = 1000: Sets the light threshold, below which the
light will turn on.
● read_light_level(): Reads the raw ADC value from the light sensor
and converts it to a percentage to represent ambient light.
● if light_level < threshold_light: Checks if the ambient light is
below the threshold and controls the light accordingly.
● light.on() and light.off(): These commands control the light or relay
based on the sensor readings.
Note:
● Adjust the light threshold based on the sensor used and your
project’s requirements.
● If you are using a relay, ensure that it is rated for the light or
appliance being controlled.
● You can replace the LED with a larger light connected through the
relay for real-world applications like home lighting automation.
Circuit connection:
● Connect the LED’s positive leg (anode) to GPIO 2 through a 220Ω
resistor, and connect the negative leg (cathode) to GND.
● Connect the light sensor (LDR) between 3.3V and an ADC pin
(e.g., GPIO 34 for ESP32), with a pull-down resistor (10kΩ)
connected to GND.
Micropython code
from machine import Pin, PWM, ADC
import time
led_pin = 2 # GPIO for LED
sensor_pin = 34 # GPIO for light sensor (ADC)
led = PWM(Pin(led_pin), freq=1000) # Initialize PWM for LED with 1kHz frequency
sensor = ADC(Pin(sensor_pin)) # Initialize ADC for light sensor
def read_light_level():
raw_value = sensor.read()
light_level = (raw_value / 4095) * 100 # Convert ADC value to percentage
return light_level
def adjust_led_brightness():
light_level = read_light_level()
duty_cycle = int((100 - light_level) * 1023 / 100) # Convert light level to PWM duty cycle
led.duty(duty_cycle) # Adjust LED brightness based on light level
while True:
adjust_led_brightness()
time.sleep(0.1) # Small delay for smooth adjustments
Code Explanation
● led_pin, sensor_pin: Define the GPIO pins for the LED and light
sensor.
● PWM(Pin(led_pin), freq=1000): Initializes PWM on the LED pin
with a frequency of 1kHz.
● sensor = ADC(Pin(sensor_pin)): Initializes the ADC to read
analog values from the light sensor.
● read_light_level(): Reads the ADC value from the light sensor and
converts it to a percentage (0-100).
● adjust_led_brightness(): Dynamically adjusts the LED brightness
based on the ambient light level by converting the light level to a
PWM duty cycle.
● while True: Continuously adjusts the LED brightness in real-time
based on the light sensor readings.
Note:
● Adjust the pull-down resistor and threshold for the light sensor as
needed, depending on the specific LDR or light sensor used.
● You can easily modify this code to control other devices, like
motors, based on sensor input by adjusting the PWM signal
accordingly.
Project -2: Controlling a Servo Motor Based on
Light Sensor Input
Object:
This project demonstrates how to control the position of a servo motor
using PWM signals based on input from a light sensor. The servo will
adjust its angle based on the amount of ambient light detected.
Programming Fundamentals name
● Control Structures: The if-else and while loops are used to control
the servo’s position based on light sensor readings.
● Functions: Encapsulate sensor reading and PWM adjustments in
reusable blocks to dynamically control the servo motor.
● Variables: Used to store GPIO pin numbers, sensor readings, and
PWM duty cycles for adjusting the servo motor’s position.
Use Syntax
● PWM(Pin(pin_number), freq=frequency): Initializes a GPIO pin
for PWM output to control the servo.
● pwm.duty_u16(duty_cycle): Adjusts the PWM duty cycle to control
the servo’s angle (for ESP32).
● pwm.duty(duty_cycle): Used for adjusting duty cycle in ESP8266
(range is 0-1023).
● ADC(Pin(pin_number)): Reads analog data from the light sensor.
● if condition:: Used to adjust the servo motor's position based on the
light sensor input.
● while condition:: Continuously monitors sensor input and
dynamically adjusts the servo motor’s position.
Requirement component:
● ESP32 or ESP8266
● Servo motor (e.g., SG90)
● Light sensor (e.g., LDR or BH1750)
● Resistors (10kΩ for LDR)
● External power supply (5V for the servo motor)
● Breadboard
● Jumper wires
Circuit diagram:
Circuit connection:
● Connect the LDR sensor between 3.3V and an ADC pin (e.g.,
GPIO 34 for ESP32), with a pull-down resistor (10kΩ) connected
to GND.
● Connect the servo motor's signal wire to GPIO 2 (for PWM
control), the power wire to 5V, and the ground wire to GND on the
ESP32/ESP8266.
Micropython code
from machine import Pin, PWM, ADC
import time
servo_pin = 2 # GPIO for controlling the servo
sensor_pin = 34 # GPIO for light sensor (ADC)
servo = PWM(Pin(servo_pin), freq=50) # Initialize PWM for servo motor with 50Hz frequency
sensor = ADC(Pin(sensor_pin)) # Initialize ADC for light sensor
def read_light_level():
raw_value = sensor.read()
light_level = (raw_value / 4095) * 100 # Convert ADC value to percentage (0-100)
return light_level
def adjust_servo_angle():
light_level = read_light_level()
duty_cycle = int((light_level / 100) * 102) + 40 # Convert light level to PWM duty cycle (0-180
degrees for SG90 servo)
servo.duty(duty_cycle) # Adjust servo position based on light level
while True:
adjust_servo_angle()
time.sleep(0.1) # Small delay for smooth adjustments
Code Explanation
● servo_pin, sensor_pin: Defines GPIO pins for the servo motor and
light sensor.
● PWM(Pin(servo_pin), freq=50): Initializes PWM on the servo pin
with a frequency of 50Hz, which is standard for controlling servos.
● sensor = ADC(Pin(sensor_pin)): Initializes the ADC to read
analog values from the light sensor.
● read_light_level(): Reads the ADC value from the light sensor and
converts it into a percentage.
● adjust_servo_angle(): Adjusts the servo motor’s angle by
converting the light level into a PWM duty cycle that corresponds
to servo positions (between 0 and 180 degrees).
● while True: Continuously adjusts the servo motor’s position in real-
time based on the light sensor readings.
Note:
● The PWM duty cycle for controlling the servo motor is mapped
between 40 and 142 (approximately 0 to 180 degrees). Adjust the
duty cycle range as needed for your specific servo motor.
Code Explanation
● servo_pin, sensor_pin: Defines GPIO pins for the servo motor and
temperature sensor.
● PWM(Pin(servo_pin), freq=50): Initializes PWM on the servo pin
with a frequency of 50Hz, which is required for controlling servos.
● sensor = ADC(Pin(sensor_pin)): Initializes the ADC to read
analog values from the temperature sensor.
● read_temperature(): Converts the raw ADC value from the
temperature sensor into a temperature reading in Celsius.
● adjust_servo_angle(): Adjusts the servo motor’s angle by mapping
the temperature range (0-50°C) to a PWM duty cycle
corresponding to the servo’s position (0 to 180 degrees).
● while True: Continuously adjusts the servo motor’s position in real-
time based on the temperature sensor readings.
Note:
● Adjust the temperature range and duty cycle mapping as needed for
your application. The example above maps temperatures from 0°C
to 50°C to servo positions between 0 and 180 degrees.
● Make sure the servo motor is powered by a suitable external power
supply (typically 5V for an SG90 servo).
● This project can be modified to control other mechanical systems
that need to respond to temperature changes, such as automated
fans or blinds.
Communication Protocols
Project-1: Temperature and Humidity-Based Servo
Control
Object:
This project demonstrates how to control a servo motor based on
temperature and humidity readings from a DHT22 sensor using PWM. The
servo’s angle is dynamically adjusted based on the temperature or humidity,
depending on the application. This can be useful for smart climate control
systems, such as opening vents or windows based on environmental
conditions.
Programming Fundamentals name
● Control Structures: The if-else and while loops are used to control
the servo motor based on temperature and humidity readings from
the DHT22 sensor.
● Functions: Used to encapsulate sensor reading and PWM control of
the servo motor.
● Variables: Used to store GPIO pin numbers, sensor readings, and
PWM duty cycles for servo control.
● Communication Protocols: The DHT22 sensor communicates
using a single-wire protocol to transmit temperature and humidity
data.
Use Syntax
● PWM(Pin(pin_number), freq=frequency): Initializes a GPIO pin
for PWM output to control the servo.
● pwm.duty_u16(duty_cycle): Adjusts the PWM duty cycle to control
the servo’s angle (for ESP32).
● dht.DHT22(Pin(pin_number)): Initializes the DHT22 sensor to
read temperature and humidity.
● if condition:: Used to control the servo motor based on the sensor
input.
● while condition:: Continuously monitors sensor data and adjusts
the servo position accordingly.
Requirement component:
● ESP32 or ESP8266
● Servo motor (e.g., SG90)
● DHT22 sensor
Circuit diagram:
Circuit connection:
● Connect the DHT22 sensor’s VCC to 3.3V, GND to GND, and the
data pin to GPIO 4 on the ESP32/ESP8266 (with a 10kΩ pull-up
resistor between VCC and data pin).
● Connect the servo motor’s signal wire to GPIO 2, the power wire
to 5V, and the ground wire to GND.
Micropython code
from machine import Pin, PWM import dht import time
servo_pin = 2 # GPIO for controlling the servo
sensor_pin = 4 # GPIO for DHT22 sensor
servo = PWM(Pin(servo_pin), freq=50) # Initialize PWM for servo motor at 50Hz
dht_sensor = dht.DHT22(Pin(sensor_pin)) # Initialize DHT22 sensor
def read_temperature_humidity():
dht_sensor.measure()
temperature = dht_sensor.temperature()
humidity = dht_sensor.humidity()
return temperature, humidity
def adjust_servo_based_on_temp():
temperature, _ = read_temperature_humidity()
duty_cycle = int((temperature / 50) * 102) + 40 # Map temperature (0-50°C) to PWM duty cycle
servo.duty(duty_cycle) # Adjust servo position based on temperature
def adjust_servo_based_on_humidity():
_, humidity = read_temperature_humidity()
duty_cycle = int((humidity / 100) * 102) + 40 # Map humidity (0-100%) to PWM duty cycle
servo.duty(duty_cycle) # Adjust servo position based on humidity
while True:
adjust_servo_based_on_temp() # or use adjust_servo_based_on_humidity() for humidity control
time.sleep(2) # Delay between sensor readings
Code Explanation
● servo_pin, sensor_pin: Define GPIO pins for the servo motor and
the DHT22 sensor.
● PWM(Pin(servo_pin), freq=50): Initializes PWM on the servo pin
with a frequency of 50Hz, which is required for controlling servos.
● dht.DHT22(Pin(sensor_pin)): Initializes the DHT22 sensor to read
temperature and humidity.
● read_temperature_humidity(): Reads the temperature and humidity
data from the DHT22 sensor using the single-wire communication
protocol.
● adjust_servo_based_on_temp(): Adjusts the servo motor’s position
by mapping the temperature range (0-50°C) to a PWM duty cycle
for servo control.
● adjust_servo_based_on_humidity(): Adjusts the servo motor’s
position based on humidity, mapping the humidity range (0-100%)
to the servo's PWM duty cycle.
● while True: Continuously adjusts the servo motor’s position in real-
time based on temperature or humidity readings from the DHT22
sensor.
Note:
● You can choose whether to control the servo based on temperature
or humidity by calling either adjust_servo_based_on_temp() or
adjust_servo_based_on_humidity() in the loop.
● Ensure the DHT22 sensor is properly powered and connected with
a pull-up resistor on the data line for reliable communication.
● Adjust the temperature and humidity ranges as needed based on the
environmental conditions you want to monitor.
while echo.value() == 0:
signaloff = time.ticks_us()
while echo.value() == 1:
signalon = time.ticks_us()
Code Explanation
● DHT22 Sensor (dht.DHT22): Used to measure temperature and
humidity.
● LDR (ADC): Reads analog data from the light sensor and converts
it into a percentage (0-100%).
● Ultrasonic Sensor (measure_distance): Sends a pulse and measures
the echo to calculate distance in centimeters.
● OLED Display (ssd1306): Updates the screen with current sensor
readings (temperature, humidity, light level, and distance).
● while True: Continuously reads data from all sensors and updates
the OLED display every 2 seconds.
Note:
● Ensure the correct wiring for the I2C OLED display, with the
appropriate SDA and SCL pins on the ESP32/ESP8266.
● You can modify this code to include more sensors or actions, such
as sending data to a cloud platform (e.g., via MQTT or HTTP).
Part 3 : Get started with IOT with
Micropython
Chapter 13. Networking Wifi
In this chapter, you'll learn how to connect the ESP32 or ESP8266 to a Wi-
Fi network, manage connections, and monitor the network status using
MicroPython. We'll cover the basic setup using WiFi.begin(), how to
disconnect from a network, and how to display the connection status and IP
address. Understanding these concepts is crucial for developing IoT
applications where devices need to communicate over the internet or local
networks.
Syntax Table
Topic Syntax Simple Example
Connecting WiFi.begin(ssid, WiFi.begin("MyNetworkSSID",
to Wi-Fi password) "MyNetworkPassword")
Disconnectin WiFi.disconnect() WiFi.disconnect()
g from Wi-Fi
Get IP station.ifconfig()[0] print("Device IP:",
Address station.ifconfig()[0])
(Station
Mode)
Check if station.isconnected( if station.isconnected():
Connected ) print("Connected")
1. Basic Wi-Fi Setup
Connecting ESP32/ESP8266 to Wi-Fi using WiFi.begin()
What is
WiFi.begin(ssid, password) is a function used to connect an ESP32 or
ESP8266 microcontroller to a Wi-Fi network by providing the network's
SSID (name) and password. This function is part of the ESP WiFi library,
used in MicroPython or Arduino programming, and helps establish internet
connectivity for your project.
Why is Important?
Connecting to a Wi-Fi network is crucial for IoT (Internet of Things)
projects where the ESP32 or ESP8266 devices need to communicate over
the internet, collect data from sensors, send data to a server, or interact with
cloud services. The WiFi.begin() function is the starting point for enabling
such connectivity.
Syntax
WiFi.begin(ssid, password)
Syntax Explanation
Code Example
WiFi.begin("MyNetworkSSID", "MyNetworkPassword")
Notes
● The WiFi.begin() function initiates the connection process, but the
connection is not instantaneous. You may need to wait until the
connection is successful by repeatedly checking the connection
status.
● ESP32 and ESP8266 may need different Wi-Fi library imports
depending on the platform being used.
Warnings
● Ensure that the SSID and password are correct; otherwise, the
connection will fail.
Disconnecting ESP32/ESP8266 from Wi-Fi using WiFi.disconnect() in
Arduino and MicroPython
What is
WiFi.disconnect() is a function used to disconnect the ESP32 or ESP8266
microcontroller from the currently connected Wi-Fi network. It can be used
in both Arduino and MicroPython environments to stop the ongoing Wi-Fi
connection.
Why is Important?
Disconnecting from a Wi-Fi network can be important for power
management, security reasons, or when switching between different
networks. In certain IoT scenarios, it's also useful to disconnect after data
transmission to save power or minimize exposure to unwanted networks.
Syntax
WiFi.disconnect()
Syntax Explanation
This function does not take any arguments and, when called, it disconnects
the device from the current Wi-Fi network.
Code Example
WiFi.disconnect()
Notes
● After calling WiFi.disconnect() , the device will no longer be
connected to any Wi-Fi network, and any ongoing communication
requiring the internet will be interrupted.
● This is often used when you need to perform a task locally and do
not require Wi-Fi for an extended period.
Warnings
● Make sure that disconnecting from the network is safe in the
context of your application, especially if you rely on a continuous
connection for critical functions.
● If your device needs to reconnect later, you will need to call
WiFi.begin() again with the correct credentials.
WiFi.localIP()
Syntax Explanation
This function does not take any arguments. It returns the local IP address of
the ESP32/ESP8266 as a string.
Code Example
ip_address = WiFi.localIP()
print("Device IP Address:", ip_address)
Notes
● The IP address returned by WiFi.localIP() is only valid when the
ESP32 or ESP8266 is connected to a Wi-Fi network.
● You can use this IP address to connect to the ESP32 from other
devices on the same network, such as accessing a web server or
sending data.
Warnings
● If the device is not connected to a Wi-Fi network, calling
WiFi.localIP() may return an empty or invalid IP address.
● Make sure to check the connection status using WiFi.isconnected()
before attempting to use WiFi.localIP().
Getting the IP Address of ESP32 in Access Point Mode Using
WiFi.softAPIP() in MicroPython
What is
WiFi.softAPIP() is a function used to retrieve the IP address of the ESP32
or ESP8266 when it is in Access Point (AP) mode. In this mode, the ESP32
acts as a Wi-Fi network that other devices can connect to, rather than
connecting to an existing network.
Why is Important?
In Access Point mode, the ESP32 creates its own Wi-Fi network, allowing
other devices to connect directly to it. The IP address returned by
WiFi.softAPIP() is crucial for interacting with the ESP32 while it acts as an
AP, such as accessing web servers hosted on the device or facilitating
communication between the ESP32 and connected clients.
Syntax
WiFi.softAPIP()
Syntax Explanation
This function does not take any arguments. It returns the IP address of the
ESP32/ESP8266 in Access Point mode as a string.
Code Example
ap_ip_address = WiFi.softAPIP()
print("Access Point IP Address:", ap_ip_address)
Notes
● The default IP address for ESP32 in Access Point mode is often
192.168.4.1, but this can be changed through configuration.
● WiFi.softAPIP() is only relevant when the ESP32 is set up as an
AP. In Station mode, use WiFi.localIP() instead.
Warnings
● Ensure that the ESP32 is correctly configured in Access Point
mode before calling WiFi.softAPIP(); otherwise, the function may
not return a valid IP address.
● Devices connected to the ESP32 AP will have their own IP
addresses within the subnet managed by the ESP32.
Use Syntax
WiFi.begin(ssid, password)
WiFi.localIP()
print("Device IP Address:", WiFi.localIP())
Requirement component
● ESP32 or ESP8266 module
● USB cable for programming
● Computer with MicroPython IDE (like Thonny)
● Wi-Fi network credentials (SSID and password)
Circuit connection
● Connect the ESP32/ESP8266 to the computer using a USB cable.
● Ensure that the correct serial port is selected in the IDE for code
upload and serial monitoring.
Micropython code
import network import time
ssid = "YourNetworkSSID" password = "YourNetworkPassword"
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)
while not station.isconnected():
print("Connecting to Wi-Fi...")
time.sleep(1)
print("Connected successfully")
print("Device IP Address:", station.ifconfig()[0])
WiFi.mode(WIFI_STA)
Syntax Explanation
WIFI_STA: A predefined constant that represents Station mode. This tells
the ESP32 to act as a client and connect to an available Wi-Fi network.
Code Example
import network station = network.WLAN(network.STA_IF)
station.active(True)
station.mode(WIFI_STA)
Notes
● Station mode is one of the modes supported by the ESP32, with
others being Access Point (AP) mode and both Station and AP
mode simultaneously.
● In most IoT applications, the ESP32 is set to Station mode to
connect to a Wi-Fi router.
Warnings
● Make sure to activate the interface using station.active(True)
before setting the mode.
Setting ESP32 to Access Point Mode Using WiFi.mode(WIFI_AP)
What is
WiFi.mode(WIFI_AP) is a function used to set the ESP32 in "Access Point"
(AP) mode, which allows the device to create its own Wi-Fi network. In
this mode, other devices can connect to the ESP32 as if it were a Wi-Fi
hotspot.
Why is Important?
Setting the ESP32 to Access Point mode is important when you want to
create a local network that other devices can connect to directly. This is
useful for creating a local server, managing configurations, or creating an
isolated network for peer-to-peer communication without requiring an
existing router.
Syntax
WiFi.mode(WIFI_AP)
Syntax Explanation
WIFI_AP: A predefined constant that represents Access Point mode. This
sets the ESP32 to act as a Wi-Fi network that other devices can join.
Code Example
WiFi.mode(WIFI_AP_STA)
Syntax Explanation
WIFI_AP_STA: A predefined constant that enables both Station and Access
Point modes simultaneously. This allows the ESP32 to act as both a client
and a Wi-Fi hotspot.
Code Example
import network wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.mode(WIFI_AP_STA)
Notes
● Using both modes at the same time gives flexibility, as the ESP32
can connect to an existing Wi-Fi network while also allowing direct
connections from other devices.
● This mode is useful for IoT applications where the device needs to
send data to the cloud while allowing local control via a connected
smartphone or computer.
Warnings
● Operating in both modes simultaneously may use more power and
require more system resources, which can impact performance.
Use Syntax
network.WLAN(network.STA_IF)
network.WLAN(network.AP_IF)
WiFi.mode(WIFI_AP_STA)
machine.Pin(pin_number, mode)
print("message")
Requirement component
● ESP32 or ESP8266 module
● USB cable for programming
● Computer with MicroPython IDE (such as Thonny IDE)
● Wi-Fi network credentials (SSID and password)
● LED
● Resistor (220 ohms)
● Jumper wires
● Breadboard
Circuit diagram
● Connect an LED to the ESP32's GPIO pin (e.g., GPIO 2).
● Connect a 220-ohm resistor in series with the LED to limit the
current.
● Connect the anode of the LED to GPIO 2 (or any suitable pin).
● Connect the cathode of the LED to GND.
Circuit connection
● Connect the ESP32/ESP8266 to the computer using a USB cable.
● Connect the LED to GPIO 2 through a resistor, and connect the
other end to GND.
● Ensure that the MicroPython firmware is installed on the ESP32
and the correct serial port is selected in the IDE (e.g., Thonny).
Micropython code
import network import time import machine
# Set up the LED indicator on GPIO 2
led = machine.Pin(2, machine.Pin.OUT)
# Set up Station mode (STA) to connect to an existing Wi-Fi network
ssid = "YourNetworkSSID"
password = "YourNetworkPassword"
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect(ssid, password)
print("Connecting to Wi-Fi as a client...")
led.value(1) # Turn on LED to indicate connection in progress
while not station.isconnected():
time.sleep(1)
if station.isconnected():
print("Connected successfully to Wi-Fi")
print("Device IP Address:", station.ifconfig()[0])
led.value(0) # Turn off LED to indicate successful connection
else:
print("Failed to connect to Wi-Fi")
led.value(1) # Keep LED on to indicate failure
# Set up Access Point (AP) mode to create a hotspot
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid="ESP32_Hotspot", password="HotspotPassword")
print("Access Point created")
print("AP IP Address:", ap.ifconfig()[0])
Replace Wi-Fi Credentials:
● Replace "YourNetworkSSID" and "YourNetworkPassword" with
your actual Wi-Fi network's SSID and password.
● Set the desired name ("ESP32_Hotspot") and password for the
ESP32's Access Point (hotspot) mode.
Save and Run the Code:
● Save the file with a .py extension (e.g., wifi_ap_connect.py).
● Click "Run" in Thonny or your chosen IDE to upload and execute
the code on your ESP32.
Check Output:
In the Thonny console or terminal, you should see something like:
Connecting to Wi-Fi as a client...
Connected successfully to Wi-Fi
Device IP Address: 192.168.x.x
Access Point created
AP IP Address: 192.168.4.1
If the connection to Wi-Fi fails, the message will say:
Failed to connect to Wi-Fi
LED Indicator:
● The LED connected to GPIO 2 will turn on while the ESP32 is
attempting to connect to Wi-Fi.
● If the connection is successful, the LED will turn off.
● If the ESP32 fails to connect to Wi-Fi, the LED will stay on as an
indicator of failure.
Note
● The LED serves as a visual indicator of the connection status: it is
on while connecting and off when connected.
● The ESP32 can operate in both Station and Access Point modes
simultaneously, which is useful for maintaining a connection to an
external network while also providing a local hotspot.
● Make sure to secure both networks with passwords to avoid
unauthorized access.
● Double-check your GPIO pin connections and LED polarity to
ensure proper functionality.
4. Network Scanning
Scanning for Nearby Wi-Fi Networks Using WiFi.scanNetworks()
What is
WiFi.scanNetworks() is a function used to scan for nearby Wi-Fi networks.
It returns a list of available Wi-Fi networks, including information like the
SSID (network name), signal strength, and security type.
Why is Important?
Scanning for available Wi-Fi networks is crucial in applications where the
ESP32 needs to dynamically select a network, provide a user with available
options, or automatically connect to the strongest or preferred network. It is
especially useful for setting up Wi-Fi connections in new environments
where the available networks may not be known beforehand.
Syntax
WiFi.scanNetworks()
Syntax Explanation
This function does not take any arguments. It returns a list of tuples, where
each tuple represents a detected network, containing information like the
SSID, RSSI (signal strength), and security type.
Code Example
import network station = network.WLAN(network.STA_IF)
station.active(True)
networks = station.scan()
for network in networks:
print("SSID:", network[0], "| Signal Strength:", network[3])
Notes
● The WiFi.scanNetworks() function is typically used in Station
mode to find nearby networks.
● The results include details such as SSID (name), BSSID (MAC
address), channel, RSSI (signal strength), and encryption type.
Warnings
● Scanning for networks may consume a significant amount of
power, so use it sparingly in battery-powered applications.
Getting the SSID of the i-th Network Using WiFi.SSID(i)
What is
WiFi.SSID(i) is a function used to retrieve the SSID (name) of the i-th Wi-
Fi network found during a scan. It allows you to access specific network
information from a list of available networks.
Why is Important?
Getting the SSID of a scanned network is important for providing users
with a list of available Wi-Fi networks to connect to. It is essential in
applications where the ESP32 needs to present network options for
selection or automate the connection process to a known network.
Syntax
WiFi.SSID(i)
Syntax Explanation
i The index of the scanned network for which you want to retrieve the
SSID. The index i must be a valid integer representing a scanned network.
Code Example
import network station = network.WLAN(network.STA_IF)
station.active(True)
networks = station.scan()
for i in range(len(networks)):
print("Network", i, "SSID:", networks[i][0])
Notes
● The index i is zero-based, meaning the first network is accessed
using i = 0, the second network with i = 1, and so on.
● The SSID is the public name of a Wi-Fi network, which can help
identify the networks that the ESP32 can connect to.
Warnings
● Ensure that the index i is within the range of available networks, or
an error may occur.
● The scan results may change if the networks are unstable or if
scanning occurs repeatedly, so always check the number of
networks found before accessing an index.
Project: Wi-Fi Network Scanner: Scan for Available
Wi-Fi Networks and Display SSIDs and Signal
Strengths
Object
To program the ESP32 to scan for nearby Wi-Fi networks and display the
SSIDs and signal strengths on the serial monitor using MicroPython.
Programming Fundamentals name
Use Syntax
network.WLAN(network.STA_IF)
station.scan()
print("message")
Requirement component
● ESP32 or ESP8266 module
● USB cable for programming
● Computer with MicroPython IDE (such as Thonny IDE)
Circuit diagram
This project involves scanning for Wi-Fi networks, so no additional
hardware components are necessary. The ESP32/ESP8266 is connected to
the computer via USB for programming and monitoring.
Circuit connection
● Connect the ESP32/ESP8266 to the computer using a USB cable.
● Ensure that the MicroPython firmware is installed on the ESP32
and the correct serial port is selected in the IDE (e.g., Thonny).
Micropython code
import network import time
# Set up Station mode to scan for available networks
station = network.WLAN(network.STA_IF)
station.active(True)
print("Scanning for available Wi-Fi networks...")
networks = station.scan()
# Display the SSID and RSSI of each network found
for i, network in enumerate(networks):
ssid = network[0].decode('utf-8')
rssi = network[3]
print(f"Network {i + 1}: SSID: {ssid}, Signal Strength (RSSI): {rssi} dBm")
Replace Wi-Fi Credentials:
● No Wi-Fi credentials are needed in this script, as the code is
designed to scan and display available networks. Simply run the
code as is.
Check Output:
In the console, you should see the available Wi-Fi networks along with their
SSIDs and signal strengths (RSSI values), like this:
Scanning for available Wi-Fi networks...
Network 1: SSID: YourWiFi, Signal Strength (RSSI): -45 dBm
Network 2: SSID: AnotherWiFi, Signal Strength (RSSI): -70 dBm
Note
● The network[0] value represents the SSID, which is in bytes and
needs to be decoded to display it properly.
● The RSSI (signal strength) is typically a negative value, with
values closer to zero indicating a stronger signal.
5. Event Handling
Registering a Function to Handle Wi-Fi Events Using
WiFi.onEvent(WiFiEvent)
What is
WiFi.onEvent(WiFiEvent) is a function used to register a callback function
that handles Wi-Fi-related events, such as connection, disconnection, and IP
address changes. It allows you to react to specific Wi-Fi status changes
automatically.
Why is Important?
Handling Wi-Fi events is important to create robust applications where you
need to monitor the connection status dynamically and take actions based
on specific events. For example, reconnecting automatically if
disconnected, or logging messages when the ESP32 connects to or
disconnects from the network. It helps to enhance reliability and user
experience.
Syntax
WiFi.onEvent(WiFiEvent)
Syntax Explanation
WiFiEvent: A callback function that you define to handle specific Wi-Fi
events. This function will be called automatically when certain Wi-Fi events
occur.
Code Example
Notes
● You need to register the event handler before starting the Wi-Fi
connection process to ensure all events are captured.
● You can handle various events, such as
EVENT_STAMODE_CONNECTED,
EVENT_STAMODE_DISCONNECTED, and more, depending on
your requirements.
Warnings
● Make sure the callback function is defined properly and handles
different events gracefully to avoid unexpected behavior.
● Incorrect handling of Wi-Fi events may lead to infinite loops or
unrecoverable errors, especially if the connection repeatedly fails.
Use Syntax
network.WLAN(network.STA_IF)
WiFi.onEvent(WiFiEvent)
print("message")
Requirement component
● ESP32 or ESP8266 module
● USB cable for programming
● Computer with MicroPython IDE (such as Thonny IDE)
● Wi-Fi network credentials (SSID and password)
Circuit diagram
This project involves logging Wi-Fi events, so no additional hardware
components are necessary. The ESP32/ESP8266 should be connected to the
computer via USB for programming and monitoring.
Circuit connection
● Connect the ESP32/ESP8266 to the computer using a USB cable.
● Ensure that the MicroPython firmware is installed on the ESP32
and the correct serial port is selected in the IDE (e.g., Thonny).
Micropython code
import network import time
# Define a callback function to handle Wi-Fi events
def wifi_event_handler(event):
if event == network.EVENT_STAMODE_CONNECTED:
print("Wi-Fi connected successfully")
elif event == network.EVENT_STAMODE_DISCONNECTED:
print("Wi-Fi disconnected")
# Set up Station mode to connect to an existing Wi-Fi network
station = network.WLAN(network.STA_IF)
station.active(True)
# Register the Wi-Fi event handler
station.on_event(wifi_event_handler)
# Start the connection process
station.connect("YourNetworkSSID", "YourNetworkPassword")
# Wait for the connection to establish
while not station.isconnected():
print("Attempting to connect...")
time.sleep(1)
print("Connected to Wi-Fi with IP:", station.ifconfig()[0])
Code Example
import network
station = network.WLAN(network.STA_IF)
station.active(True)
station.config(ip="192.168.1.50", gateway="192.168.1.1", subnet="255.255.255.0")
station.connect("YourNetworkSSID", "YourNetworkPassword")
while not station.isconnected():
pass
print("Connected with Static IP:", station.ifconfig()[0])
Notes
● Ensure that the static IP address you assign is within the range of
the network and is not already in use by another device.
● Setting a static IP is useful for applications where the device needs
to be accessed frequently and predictably, such as a web server
hosted on the ESP32.
Warnings
● If the IP address is incorrectly configured (e.g., conflicts with
another device), the ESP32 may not be able to connect to the
network properly.
● Make sure the gateway and subnet mask values are correct to avoid
routing and connectivity issues within your network.
Setting a Custom Hostname Using WiFi.setHostname(name)
What is
WiFi.setHostname(name) is a function used to set a custom hostname for
the ESP32. The hostname is the network name of the device, making it
easier to identify when connected to a network.
Why is Important?
Setting a custom hostname is important because it allows you to easily
identify the ESP32 on your network. Instead of seeing a generic name or an
IP address, you can give the ESP32 a descriptive name, making it more
convenient for management and troubleshooting, especially in networks
with multiple devices.
Syntax
WiFi.setHostname(name)
Syntax Explanation
name: The desired hostname for the ESP32, provided as a string (e.g.,
"ESP32_Logger").
Code Example
import network
station = network.WLAN(network.STA_IF)
station.active(True)
station.config(dhcp_hostname="ESP32_Logger")
station.connect("YourNetworkSSID", "YourNetworkPassword")
while not station.isconnected():
pass
print("Connected with Hostname:", "ESP32_Logger")
Notes
● The hostname can make it easier to access the ESP32 from other
devices on the network, especially if you use the mDNS feature to
access it via hostname.local.
● Hostnames must be unique within a network to prevent conflicts.
Warnings
● If the hostname is not set properly or conflicts with another device,
it may lead to issues with network identification.
● The hostname setting may need to be configured before the ESP32
connects to the Wi-Fi network for it to take effect.
Adjusting Wi-Fi Transmission Power Using WiFi.setTxPower(power)
What is
WiFi.setTxPower(power) is a function used to adjust the Wi-Fi transmission
power of the ESP32. The transmission power can be increased or decreased
to control the range and power consumption of the Wi-Fi signal.
Why is Important?
Adjusting the transmission power is important in scenarios where you want
to optimize the power consumption of the ESP32. Reducing power can help
save battery life for battery-powered devices, while increasing power can
improve the range in situations where a stronger signal is needed.
Syntax
WiFi.setTxPower(power)
Syntax Explanation
power: The desired transmission power level, usually set in dBm (e.g., 20
dBm for maximum power or 8 dBm for reduced power).
Code Example
import network
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect("YourNetworkSSID", "YourNetworkPassword")
while not station.isconnected():
pass
station.config(txpower=14) # Set transmission power to 14 dBm
print("Wi-Fi connected with adjusted transmission power.")
Notes
● Adjusting the power level affects both range and power
consumption. High power increases range but also increases energy
use.
● It is recommended to find a balance between transmission power
and energy efficiency, depending on your use case.
Warnings
● Setting the transmission power too high may cause interference
with other devices, especially in a congested Wi-Fi environment.
Disabling Wi-Fi Sleep Mode Using WiFi.setSleep(false)
What is
WiFi.setSleep(false) is a function used to disable the Wi-Fi sleep mode on
the ESP32 or ESP8266. Disabling sleep mode ensures that the device
maintains a continuous and uninterrupted connection to the Wi-Fi network,
which can be useful for real-time applications.
Why is Important?
Disabling Wi-Fi sleep mode is important in applications where a stable,
always-on connection is required, such as streaming data, real-time
monitoring, or control applications. By keeping the connection active, you
prevent latency or disconnections that may occur due to the power-saving
features of sleep mode.
Syntax
WiFi.setSleep(false)
Syntax Explanation
false: Setting false will disable the Wi-Fi sleep mode, keeping the Wi-Fi
module continuously active.
Code Example
import network
station = network.WLAN(network.STA_IF)
station.active(True)
station.config(ps_mode=network.WIFI_PS_NONE) # Disable sleep mode for continuous connection
station.connect("YourNetworkSSID", "YourNetworkPassword")
while not station.isconnected():
pass
print("Connected to Wi-Fi with sleep mode disabled.")
Notes
● Disabling sleep mode can improve connection reliability for tasks
that require continuous data exchange.
● Sleep mode is typically enabled by default to save power, but it can
introduce latency or momentary disconnections, which may not be
suitable for some applications.
Warnings
● Disabling sleep mode will increase the power consumption of the
ESP32/ESP8266, which may be a concern in battery-powered
projects.
● Ensure that the power supply can handle the increased energy
demands when sleep mode is disabled, especially for long-running
applications.
Use Syntax
network.WLAN(network.STA_IF)
station.config(ip="192.168.1.50", gateway="192.168.1.1", subnet="255.255.255.0")
station.config(dhcp_hostname="ESP32_StaticDevice")
station.config(ps_mode=network.WIFI_PS_NONE)
print("message")
Requirement component
● ESP32 or ESP8266 module
● USB cable for programming
● Computer with MicroPython IDE (such as Thonny IDE)
● Wi-Fi network credentials (SSID and password)
Circuit diagram
This project involves configuring network settings and power management,
so no additional hardware components are necessary. The ESP32/ESP8266
should be connected to the computer via USB for programming and
monitoring.
Circuit connection
● Connect the ESP32/ESP8266 to the computer using a USB cable.
● Ensure that the MicroPython firmware is installed on the ESP32
and the correct serial port is selected in the IDE (e.g., Thonny).
Micropython code
server.begin()
server.handleClient()
Syntax Explanation
● server.begin(): This command starts the web server.
● server.handleClient(): This function is called in the main loop to
process any client requests. Without calling this repeatedly, the
server won't be able to respond to incoming HTTP requests.
Code Example
Requirement component
● ESP32 or ESP8266 module
● USB cable for programming
● Computer with MicroPython IDE (such as Thonny IDE)
● Wi-Fi network credentials (SSID and password)
Circuit diagram
This project involves setting up a basic web server, so no additional
hardware components are necessary. The ESP32/ESP8266 should be
connected to the computer via USB for programming and monitoring.
Circuit connection
● Connect the ESP32/ESP8266 to the computer using a USB cable.
● Ensure that the MicroPython firmware is installed on the ESP32
and the correct serial port is selected in the IDE (e.g., Thonny).
Micropython code
import network
import socket
import time
# Set up Station mode and connect to Wi-Fi
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect("YourNetworkSSID", "YourNetworkPassword")
# Wait for the connection to establish
while not station.isconnected():
print("Connecting to Wi-Fi...")
time.sleep(1)
print("Connected to Wi-Fi with IP:", station.ifconfig()[0])
<html>
<body>
<h1>Welcome to ESP32 Web Server!</h1>
</body>
</html>
"""
conn.send(response)
conn.close()
Note
● This basic web server setup is meant to introduce beginners to how
the ESP32 can be used to serve web pages over a network.
● The IP address printed ( Connected to Wi-Fi with IP: ) is the one
you can type into a web browser to access the ESP32's web server.
For example, if it says 192.168.1.50 , you can type
http://192.168.1.50 in your browser to see the response.
2. Request Handling Functions
Setting up Web Routes Using on() and Handling 404 Errors Using
onNotFound() on ESP32/ESP8266
What is
on() and onNotFound() are functions typically used in web server
frameworks to define how the server should respond to specific URLs
(routes) or handle requests when the requested page is not found (404
error).
● on(): This function is used to register a route (a specific URL path)
and define how the server should respond when a client visits that
path.
● onNotFound(): This function is used to handle requests for URLs
that do not exist on the server, usually returning a "404 Not Found"
error message or a custom error page.
Why is Important?
● on() is important because it allows the web server to handle
different routes or URLs, making it more interactive and functional.
For example, you can create routes like /status , /control , or /info
and send different responses based on the path.
● onNotFound() is crucial for handling incorrect or non-existent
URLs in a user-friendly way, such as showing a "404 Page Not
Found" error instead of crashing the server.
Syntax
server.on(path, method, callback)
server.onNotFound(callback)
Syntax Explanation
● server.on(path, method, callback): This registers a route at the URL
path (e.g., /status ), for a specific HTTP method (like GET or
POST ), and the callback function defines what the server will do
when that route is requested.
● server.onNotFound(callback): This sets the callback function that
will be executed whenever a request is made to a non-existent path,
typically displaying a "404 Not Found" page.
Code Example
import network import socket import time
# Set up Wi-Fi connection
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect("YourNetworkSSID", "YourNetworkPassword")
while not station.isconnected():
time.sleep(1)
print("Connected to Wi-Fi with IP:", station.ifconfig()[0])
# Set up the server
server = socket.socket()
server.bind(('', 80))
server.listen(5)
def handle_root():
*return """HTTP/1.1 200 OK
Content-Type: text/html
<html><body><h1>Welcome to ESP32 Web Server</h1></body></html>"""*
def handle_404():
*return """HTTP/1.1 404 Not Found
Content-Type: text/html
<html><body><h1>404 Page Not Found</h1></body></html>"""*
while True:
conn, addr = server.accept()
request = conn.recv(1024)
if "/ " in request:
response = handle_root()
else:
response = handle_404()
conn.send(response)
conn.close()
Notes
● In this example, the root URL ( / ) is handled by the handle_root()
function, which sends back a simple HTML page.
● If the requested path is not / , the server responds with the
handle_404() function, showing a custom "404 Not Found" page.
Warnings
● Make sure to define all necessary routes using on() or
onNotFound() so that the server can handle every possible request.
● Failure to handle unknown routes with onNotFound() could lead to
unpredictable behavior or errors when users request invalid URLs.
html = """<html>
<head><title>ESP32 LED Control</title></head>
<body><h1>LED Control</h1>
<p>LED is currently: <strong>""" + led_state + """</strong></p>
<form action="/led_on"><button type="submit">Turn ON</button></form>
<form action="/led_off"><button type="submit">Turn OFF</button></form>
</body></html>"""
return html
if "/led_on" in request:
led.value(1) # Turn LED ON
if "/led_off" in request:
led.value(0) # Turn LED OFF
response = web_page()
conn.send("HTTP/1.1 200 OK\n")
conn.send("Content-Type: text/html\n\n")
conn.sendall(response)
conn.close()
Note
● Make sure to replace "YourNetworkSSID" and
"YourNetworkPassword" with your actual Wi-Fi credentials.
● After the ESP32 connects to Wi-Fi, it will print an IP address. Use
that IP address in your browser to access the web page (e.g.,
http://192.168.1.50 ).
● You can control the LED by clicking the "Turn ON" or "Turn
OFF" buttons on the web page.
3. Response Functions
Sending HTTP Responses Using send(), sendHeader(), send_P() on
ESP32/ESP8266
What is
send(), sendHeader(), and send_P() are functions used in web server
programming to send HTTP responses to clients.
● send(): Sends the HTTP response to the client, including the status
code, content type, and the body of the response.
● sendHeader(): Sends a specific HTTP header to the client, such as
Content-Type , to provide additional information about the
response.
● send_P(): Typically used to send data stored in program memory
(e.g., HTML strings), useful for sending large or repeated content
more efficiently.
Why is Important?
● send() is important because it is used to send the complete response
to a client, including the HTML content of a web page.
● sendHeader() is crucial to set specific response headers, like
content type ( text/html ) or caching instructions, allowing better
control over how the response is handled by the browser.
● send_P() is used to optimize memory usage by sending content
directly from program memory, helping save RAM on memory-
limited devices like the ESP32/ESP8266.
Syntax
send(status_code, content, content_type)
sendHeader(header_name, header_value)
send_P(content, content_type)
Syntax Explanation
● send(status_code, content, content_type): This sends a complete
HTTP response with a specific status code (e.g., 200 for OK), the
response body (e.g., HTML code), and the content type (e.g.,
text/html ).
● sendHeader(header_name, header_value): Sends a specific HTTP
header, where header_name is the name of the header (e.g.,
Content-Type ) and header_value is its value (e.g., text/html ).
● send_P(content, content_type): Sends the response content directly
from program memory, which is useful for large or constant HTML
content that should not be stored in RAM.
Code Example
import network
import socket
import machine
import time
Circuit connection
● VCC → 3.3V on ESP32
● GND → GND on ESP32
● Data/Output → GPIO 34 (ADC pin) on ESP32
● Connect ESP32 to your computer using a USB cable.
Micropython code
import network
import socket
import machine
import time
# Set up the temperature sensor pin (assuming it's an analog sensor like LM35)
sensor = machine.ADC(machine.Pin(34)) # Use GPIO 34 (analog input)
sensor.atten(machine.ADC.ATTN_11DB) # Set attenuation to read the full voltage range (0-3.3V)
Note
● Replace "YourNetworkSSID" and "YourNetworkPassword" with
your Wi-Fi credentials to connect successfully.
● The printed IP address after connection will be used to access the
temperature monitoring page in a web browser, e.g.,
http://192.168.1.50 .
● The conversion of the ADC value depends on the sensor you use.
The example provided is for an LM35 sensor, which outputs a
voltage that directly corresponds to temperature (in degrees
Celsius). Adjust the conversion if using a different sensor.
4. Request Data Retrieval Functions
Understanding arg() , uri() , method() , and hasArg() Functions in
MicroPython for ESP32/ESP8266
What is
arg() , uri() , method() , and hasArg() are functions used to manage and
interact with HTTP requests when working with ESP32 or ESP8266 using
MicroPython. They are used to handle incoming request parameters,
retrieve specific request information, and determine which HTTP methods
are in use.
Why is Important?
These functions are essential for controlling HTTP communication when
using ESP32/ESP8266 as a web server or client. They help in parsing
requests and creating interactive IoT applications, making your ESP8266 or
ESP32-based devices smarter and more functional.
Syntax
arg(argument_name)
uri()
method()
hasArg(argument_name)
Syntax Explanation
● arg(argument_name): Retrieves the value of the specified argument
in the HTTP request.
● uri(): Returns the URI (Uniform Resource Identifier) of the
incoming HTTP request.
● method(): Indicates the type of HTTP method used in the request
(e.g., GET or POST).
● hasArg(argument_name): Checks if a specific argument is present
in the HTTP request and returns a boolean value ( True or False ).
Code Example
if server.hasArg('temperature'):
temperature_value = server.arg('temperature')
print('Temperature: ', temperature_value)
Notes
● These functions are commonly used when you want to build a web
interface that allows users to interact with your ESP32/ESP8266
device, for example, to submit data via forms.
● Ensure that your ESP device is properly connected to the local
network to use these features effectively.
Warnings
● The functions should be used within an appropriate HTTP server
framework for ESP32/ESP8266 in MicroPython, otherwise, they
won't work properly.
● Improper parsing of arguments may lead to potential security
vulnerabilities like injection attacks if inputs are not sanitized
properly.
Project Title: Wi-Fi Network Configurator for
ESP32 and ESP8266
Objective
To create a simple and easy-to-use Wi-Fi Network Configurator using
MicroPython for ESP32 and ESP8266, allowing users to connect the device
to a specified Wi-Fi network through a web interface.
Programming Fundamentals
● import: Used to include necessary libraries, such as network and
socket, that provide network control capabilities.
● class: Defines the structure of the project by grouping related
functions and data together for reusability and organization.
● def: Defines functions that carry out specific tasks, like connecting
to Wi-Fi or handling HTTP requests.
● while: Implements a loop for repeatedly checking connection status
or continuously running the server.
● try/except: Helps in handling errors like incorrect Wi-Fi credentials
or connection failures, providing a stable user experience.
Use Syntax
import network
import socket
station = network.WLAN(network.STA_IF)
station.connect('SSID', 'password')
if station.isconnected():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Requirement Component
Circuit Diagram
● Not necessary for this project, as it primarily involves configuring
Wi-Fi settings on the board.
● If needed, you can connect an LED to GPIO for visual indication
of Wi-Fi status.
Circuit Connection
MicroPython Code
import network
import socket
import time
arg(argument_name)
hasArg(argument_name)
Syntax Explanation
● arg(argument_name): Retrieves the value of a specified argument
in the incoming HTTP request, where argument_name is the name
of the parameter you want to extract.
● hasArg(argument_name): Checks if a specific argument is present
in the HTTP request, returning True if found, otherwise False.
Code Example
if server.hasArg('led'):
led_state = server.arg('led')
print('LED state: ', led_state)
Notes
● arg() and hasArg() are usually used together to safely extract
arguments from an incoming request after verifying that the
parameter exists.
● They are generally used when setting up a basic web server on
ESP32/ESP8266, allowing the user to pass commands via URL
parameters.
Warnings
● Always validate input received through arg() to prevent potential
security vulnerabilities such as code injection or unexpected input
behavior.
● Ensure your ESP device has an active network connection to
receive requests and make use of these functions effectively.
Circuit Diagram
Circuit Connection
MicroPython Code
import machine
import network
import socket