Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
TinyML Cookbook
TinyML Cookbook

TinyML Cookbook: Combine artificial intelligence and ultra-low-power embedded devices to make the world smarter

eBook
$9.99 $39.99
Paperback
$49.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Table of content icon View table of contents Preview book icon Preview Book

TinyML Cookbook

Chapter 2: Prototyping with Microcontrollers

Deploying machine learning (ML) applications on microcontrollers is cool because what we develop doesn't just live within our computer's brain. Instead, it can animate many things around us. Therefore, before diving into the ML world, let's take a glance at how to build basic applications on microcontrollers from a software and hardware perspective.

In this chapter, we will deal with code-debugging and present how to transmit data to the Arduino serial monitor. Next, we will discover how to program GPIO peripherals with the Arm Mbed API and use the solderless breadboard to connect external components such as LEDs and push-buttons. At the end of the chapter, we will see how to power the Arduino Nano and Raspberry Pi Pico with batteries.

The aim of this chapter is to cover the relevant microcontroller programming basics for the following topics in this book.

In this chapter, we're going to cover the following recipes:

  • Code debugging 101
  • Implementing an LED status indicator on the breadboard
  • Controlling an external LED with the GPIO
  • Turning an LED on and off with a ush-button
  • Using interrupts to read the push-button state
  • Powering microcontrollers with batteries

Technical requirements

To complete all the practical recipes of this chapter, we will need the following:

  • An Arduino Nano 33 BLE Sense board
  • A Raspberry Pi Pico board
  • A micro-USB cable
  • 1 x half-size solderless breadboard (30 rows and 10 columns)
  • 1 x red LED
  • 1 x 220 Ω resistor
  • 1 x 3 AA battery holder (Raspberry Pi Pico only)
  • 1 x 4 AA battery holder (Arduino Nano only)
  • 4 x AA batteries
  • 1 x push-button
  • 5 x jumper wires
  • Laptop/PC with either Ubuntu 18.04+ or Windows 10 on x86-64

The source code and additional material are available in the Chapter02 folder on the GitHub repository (https://github.com/PacktPublishing/TinyML-Cookbook/tree/main/Chapter02).

Code debugging 101

Code debugging is a fundamental process of software development to uncover errors in code.

This recipe will show how to perform print debugging on an Arduino Nano and Raspberry Pi Pico by transmitting the following strings to the serial terminal:

  • Initialization completed: Once we have completed the initialization of the serial port
  • Executed: After every 2 seconds

The following Arduino sketch contains the code referred to in this recipe:

  • 01_printf.ino:

https://github.com/PacktPublishing/TinyML-Cookbook/blob/main/Chapter02/ArduinoSketches/01_printf.ino

Getting ready

All programs are prone to bugs, and print debugging is a basic process that prints statements on the output terminal to give insight into the program execution, as shown in the following example:

int func (int func_type, int a) {
  int ret_val = 0;
  switch(func_type){
    case 0:
      printf("FUNC0\n");
      ret_val = func0(a)
      break;
    default:
      printf("FUNC1\n");
      ret_val = func1(a);
  }
  return ret_val;
}

To get ready with this first recipe, we only need to know how the microcontroller can send messages on the serial terminal.

The Arduino programming language offers a similar function to printf(), the Serial.print() function.

This function can send characters, numbers, or even binary data from the microcontroller board to our computer through the serial port, commonly called UART or USART. You can refer to https://www.arduino.cc/reference/en/language/functions/communication/serial/print/ for the complete list of input arguments.

How to do it...

Note

The code reported in this recipe is valid for both the Arduino Nano and Raspberry Pi Pico. The Arduino IDE, in fact, will compile the code accordingly with the selected platform in the device drop-down menu.

Open the Arduino IDE and create a new empty project by clicking on Sketchbook from the leftmost menu (EDITOR) and then click on NEW SKETCH, as shown in the following figure:

Figure 2.1 – Click on the NEW SKETCH button to create a new project

Figure 2.1 – Click on the NEW SKETCH button to create a new project

As we saw in Chapter 1, Getting Started with TinyML, all sketches require a file containing the setup() and loop() functions.

The following steps will show what to write in these functions to implement our print debugging recipe:

  1. Initialize the UART baud rate in the setup() function and wait until the peripheral is open:
    void setup() {
      Serial.begin(9600);
      while (!Serial);

In contrast to the standard C library printf function, the Serial.print() function requires initialization before transmitting data. Therefore, we initialize the peripheral with the Arduino Serial.begin() function, which only requires the baud rate as an input argument. The baud rate is the data transmission rate in bits per second, and it is set to 9600 bps.

However, we can't use the peripheral immediately after the initialization because we should wait until it is ready to transmit. So, we use while(!Serial) to wait until the serial communication is open.

  1. Print Initialization completed after Serial.begin() in the setup() function:
      Serial.print("Initialization completed\n");
    }

We transmit the string Initialization completed with Serial.print("Initialization completed\n") to report the completion of the initialization.

  1. Print Executed every 2 seconds in the loop() function:
    void loop() {
      delay(2000);
      Serial.print("Executed\n");
    }      

Since the loop() function is called iteratively, we use the Arduino's delay() function to pause the program execution for 2 seconds. delay() accepts the amount of time in milliseconds (1 s = 1000 ms) as an input argument.

Now, make sure the device is plugged into your computer through the micro-USB cable.

If the device is recognized, we can open the serial monitor by clicking on Monitor from the Editor menu. From there, we will see any data transmitted by the microcontroller through the UART peripheral. However, before any communication starts, ensure the serial monitor uses the same baud rate as the microcontroller peripheral (9600), as shown in the following figure:

Figure 2.2 – The serial monitor must use the same baud rate as the UART's peripheral

Figure 2.2 – The serial monitor must use the same baud rate as the UART's peripheral

With the serial monitor open, we can click on the arrow near the device drop-down menu to compile and upload the program to the target platform. Once the sketch has been uploaded, the serial monitor will receive the Initialization completed and Executed messages, as shown in the following screenshot:

Figure 2.3 – Expected output on the serial monitor

Figure 2.3 – Expected output on the serial monitor

As we can see from the serial monitor output, Initialization completed is printed once because the setup() function is just called when starting the program.

There's more

Print debugging is a simple debugging approach, but it has significant disadvantages with the increase of software complexity, such as the following:

  • Needing to re-compile and flash the board every time we add or move Serial.print().
  • Serial.print() costs in terms of program memory footprint.
  • We could make mistakes reporting the information (for example, using print to report an unsigned int variable that is actually signed).

We will not cover more advanced debugging in this book, but we recommend looking at serial wire debug (SWD) debuggers (https://developer.arm.com/architectures/cpu-architecture/debug-visibility-and-trace/coresight-architecture/serial-wire-debug) to make this process less painful. SWD is an Arm debug protocol for almost all Arm Cortex processors that you can use to flash the microcontroller, step through the code, add breakpoints, and so on with only two wires.

Implementing an LED status indicator on the breadboard

We have the chance to interact with the world around us with microcontrollers. For example, we can get data from sensors or perform physical actions, such as turning on and off an LED or moving an actuator.

In this recipe, we will learn how to connect external components with the microcontroller by building the following electronic circuit on the breadboard:

Figure 2.4 – LED power status indicator circuit

Figure 2.4 – LED power status indicator circuit

The preceding circuit uses a red LED to indicate whether the microcontroller is plugged into the power.

Getting ready

When connecting external components to the microcontroller, we mean physically joining two or more metal connectors together. Although we could solder these connectors, it is not usual for prototyping because it is not quick and straightforward.

Therefore, this Getting ready section aims to present a solderless alternative to connect our components effortlessly.

Making contacts directly with the microcontroller's pins can be extremely hard for the tiny space between each pin. For example, considering the RP2040 microcontroller, the pin space is roughly 0.5 mm since the chip size is 7x7 mm. Therefore, it would be practically impossible to connect any of our components safely since most terminals have a wire diameter of ~1 mm.

For this reason, our platforms provide alternative points of contact with wider spacing on the board. These contact points on the Arduino Nano and Raspberry Pi Pico are the two rows of pre-drilled holes located at the platform's edge.

The simplest way to know the correspondence between these contacts and the microcontroller pins is to refer to the datasheet of the microcontroller boards. Hardware vendors usually provide the pinout diagram to note the pins' arrangement and functionality.

For example, the following list reports the links to the Arduino Nano and Raspberry Pi Pico pinout diagrams:

  • Arduino Nano:

https://content.arduino.cc/assets/Pinout-NANOsense_latest.pdf

  • Rasberry Pi Pico:

https://datasheets.raspberrypi.org/pico/Pico-R3-A4-Pinout.pdf

On top of these pre-drilled holes, which often come with a 2.54 mm spacing, we can solder a header to insert and connect the electronic components easily.

The header can be either a male (pin header) or a female connector (socket header), as shown in the following figure:

Figure 2.5 – Male header versus female header

Figure 2.5 – Male header versus female header (image from https://en.wikipedia.org/wiki/Pin_header)

Important Note

We recommend buying devices with pre-soldered male headers if you are not familiar with soldering or just want a ready-to-go solution.

As we have seen, the boards provide a way to connect the external components with the microcontroller. However, how can we attach other electrical elements to build a complete electronic circuit?

Prototyping on a breadboard

The breadboard is a solderless prototyping platform to build circuits by pushing the device's pins in a rectangular grid of metal holes:

Figure 2.6 – Solderless breadboard

Figure 2.6 – Solderless breadboard

As shown in the previous figure, breadboards provide two connecting areas for our components:

  • Bus rails are usually located on both sides of the breadboard and consist of two columns of holes identified with the symbols + and as shown in the following diagram:
Figure 2.7 – Bus rails labeled with + and - on both sides of the breadboard

Figure 2.7 – Bus rails labeled with + and - on both sides of the breadboard

All the holes of the same column are internally connected. Therefore, we will have the same voltage through all its columns when applying a voltage to whatever hole.

Since bus rails are beneficial for having reference voltages for our circuits, we should never apply different voltages on the same bus column.

  • Terminal strips are located in the central area of the breadboard and join only the holes of the same row so that the following occurs:
    • Holes on the same row have the same voltage.
    • Holes on the same column might have a different voltage.

However, since we typically have a notch running parallel in the middle of the breadboard, we have two different terminal strips per row, as shown in the following figure:

Figure 2.8 – Terminal strips are located in the central area of the breadboard

Figure 2.8 – Terminal strips are located in the central area of the breadboard

We can place several devices on the breadboard and connect them through jumper wires.

Note

The size of a breadboard is defined by the number of rows and columns in the terminal area. In our case, we will always refer to a half-sized breadboard with 30 rows and 10 columns.

How to do it...

Before building any circuits, unplug the micro-USB cable from the microcontroller board to remove the possibility of unintentionally damaging any components.

Once we have disconnected the board from the power, follow the following steps to build the circuit to turn the LED on when the platform is plugged into the power:

  1. Put the microcontroller board on the breadboard:
Figure 2.9 – Vertically mount the microcontroller board between the left and right terminal strips

Figure 2.9 – Vertically mount the microcontroller board between the left and right terminal strips

Since we have a notch running parallel, it is safe to put the platforms in this way because the left and right pin headers touch two different terminal strips.

  1. Use two jumper wires to connect the 3.3 V and GND pins of the microcontroller board with the + and - bus rails:
Figure 2.10 – Use the jumper wires to connect the 3.3 V and GND to the + and - bus rails

Figure 2.10 – Use the jumper wires to connect the 3.3 V and GND to the + and - bus rails

It is important to note that all holes of the bus rails will have 3.3 V and GND, respectively, only when the microcontroller is connected to the power.

  1. Insert the LED pins on two terminal strips:
Figure 2.11 – Insert the LED on the breadboard

Figure 2.11 – Insert the LED on the breadboard

In the preceding figure, we insert the longer LED terminal in (H, 24) and the shorter one in (H, 25). Do not invert the longer and shorter terminals because then the LED won't turn on.

  1. Place the 220 Ω resistor in series with the LED:
Figure 2.12 – Place the resistor in series with the LED

Figure 2.12 – Place the resistor in series with the LED

The color bands of the resistor can be determined through the Digikey web tool (https://www.digikey.com/en/resources/conversion-calculators/conversion-calculator-resistor-color-code). For example, a 220Ω resistor with five or six bands is encoded with the following colors:

  • First band: red (2)
  • Second band: red (2)
  • Third band: black (0)
  • Fourth band: black (1)

As reported in the circuit presented at the beginning of this recipe, one terminal of the resistor should touch the shorter LED pin. In our case, we insert one terminal in (H, 25). The remaining terminal of the resistor goes in whichever unused terminal strip. In our case, we insert this terminal in (H, 28).

  1. Close the circuit by connecting the + bus rail (3.3 V) to the longer LED pin and the - bus rail (GND) to the resistor terminal:
Figure 2.13 – Close the circuit by connecting 3.3 V and GND

Figure 2.13 – Close the circuit by connecting 3.3 V and GND

The previous figure shows how to connect the two remaining jumper wires used to close the circuit. One jumper wire connects the + bus rail with the longer LED terminal (H, 24) while the other one connects the - bus rail with the resistor (H, 28).

Now, the LED should emit light whenever you plug the microcontroller into the power with the micro-USB cable.

Controlling an external LED with the GPIO

Nowadays, LEDs are everywhere, particularly in our houses, because they use less energy than older lights for the same luminous intensity. However, the LEDs considered for our experiments are not light bulbs but through-hole LEDs for rapid prototyping on the breadboard.

In this recipe, we will discover how to build a basic circuit with an external LED and program the GPIO peripheral to control its light.

The following Arduino sketch contains the code referred to in this recipe:

  • 03_gpio_out.ino:

https://github.com/PacktPublishing/TinyML-Cookbook/blob/main/Chapter02/ArduinoSketches/03_gpio_out.ino

Getting ready

To implement this recipe, we need to know how the LED works and how to program the microcontroller GPIO peripheral in output mode.

LED stands for Light-Emitting Diode and is a semiconductor component that emits light when the current flows through it.

A through-hole LED is made of the following:

  • A head of transparent material from where the light comes. The head can be of different diameters, but typically comes in 3mm, 5mm, and 10mm sizes.
  • Two legs (leads) of different lengths to identify the positive (anode) from the negative (cathode) terminal. The anode is the longer lead.

The following diagram shows the basic structure of a through-hole LED and its symbolic representation in an electronic circuit.

Figure 2.14 – LED with symbolic representation

Figure 2.14 – LED with symbolic representation

As mentioned, the LED emits light when the current flows through it. However, in contrast to the resistors, the current flows only in one direction, specifically from the anode to the cathode. This current is commonly called forward current (If).

The brightness of the LED is proportional to If, so the higher it is, the brighter it will appear.

The LED has a maximum operating current that we must not exceed to avoid breaking it instantly. For standard through-hole 5 mm LEDs, the maximum current is typically 20 mA, so values between 4 mA and 15 mA should be enough to see the LED emitting the light.

To allow the current to flow, we need to apply a specific voltage to the terminals' LED, called forward voltage (Vf). We define the Vf as:

We report the typical Vf range for some LED colors in the following table:

Figure 2.15 – Typical LED forward voltage

Figure 2.15 – Typical LED forward voltage

From the preceding table, we can observe the following about the forward voltage range:

  • It depends on the color.
  • It is narrow and less than the typical 3.3 V required to power a microcontroller in most cases.

From these observations, three questions come into mind:

  • First, how can we apply the forward voltage on the LED terminals since we typically only have 3.3 V from the microcontroller?
  • What happens if we apply a voltage lower than the minimum Vf?
  • What happens if we apply a voltage higher than the maximum Vf?

The answers rely on the following physical relationship between the voltage and current of the LED:

Figure 2.16 – Voltage-current (VI) characteristic of LED

Figure 2.16 – Voltage-current (VI) characteristic of LED

From the previous chart where the x and y axes report the voltage and current, we can deduce the following:

  • If we applied a voltage much lower than Vf to the LED, the LED would not turn on because the current would be low.
  • If we applied a voltage much higher than Vf on the LED, the LED would be damaged because the current would exceed the 20 mA limit.

Therefore, fixing the voltage at the required operating Vf is crucial to ensure that the device works and is not damaged.

The solution is simple and only requires a resistor in series with the LED, as shown in the following figure:

Figure 2.17 – The resistor in series with the LED limits the current

Figure 2.17 – The resistor in series with the LED limits the current

At this point, it should be clear why we included the resistor in the circuit of the previous recipe. Since the LED has a fixed voltage drop when it emits the light (Vf), the resistor limits the current at the value we want, such as 4 mA–15 mA. Therefore, having the LED current in the acceptable range means that the Vf does not fall out of the expected operating range.

We can calculate the resistor's value using the following formula:

Where:

  • Vf is the forward voltage.
  • If is the forward current.
  • R is the resistance.

The forward voltage/current and LED brightness information is generally available in the LED datasheet.

Now, let's see how we can control the status of this device with the GPIO peripheral.

Introducing the GPIO peripheral

General-purpose input/output (GPIO) is the most common and versatile peripheral on microcontrollers.

As the name suggests, GPIO does not have a fixed functionality. Instead, its primary function is to provide (output) or read (input) digital signals (1 or 0) through the external pins, commonly called either GPIO, IO, or GP.

A microcontroller can integrate several GPIO peripherals, where each one can control a dedicated pin of the integrated chip.

GPIO has similar behavior to std::cout and std::cin of the C++ iostream library but with the difference that it writes and reads fixed voltages rather than characters.

The commonly applied voltages for the logical 1 and 0 levels are as follows:

Figure 2.18 – Relation between logical levels and voltages

Figure 2.18 – Relation between logical levels and voltages

The LED blinking is a typical example of configuring the GPIO peripheral in output mode to supply either 3.3 V (1) or 0 V (0) programmatically.

There are two ways to connect the LED with the GPIO pin, and the direction of the current makes them different. The first way is current sourcing, where the current flows out of the microcontroller board. To do so, we need to do the following:

  • Connect the LED anode to the GPIO pin.
  • Connect the LED cathode to the resistor in the series.
  • Connect the remaining resistor terminal to GND.

The following circuit shows how to drive an LED with a current sourcing circuit:

Figure 2.19 – Current sourcing. The current goes out of the microcontroller board

Figure 2.19 – Current sourcing. The current goes out of the microcontroller board

From the preceding circuit, we can observe that the GPIO pin should supply the logical level 1 to turn on the LED.

The second and opposite way is current sinking, where the current flows into the microcontroller board. In this case, we need to do the following:

  • Connect the LED cathode to the GPIO pin.
  • Connect the LED anode to the resistor in series.
  • Connect the remaining resistor terminal to 3.3 V.

As we can observe from the following circuit, the GPIO pin should supply the logical level 0 to turn on the LED:

Figure 2.20 – Current sinking. The current goes into the microcontroller board

Figure 2.20 – Current sinking. The current goes into the microcontroller board

Whatever solution we adopt, it is essential to keep in mind that the pin has limits on the maximum current, which can be different depending on its direction. For example, the Arduino Nano has a maximum output current of 15 mA and a maximum input current of 5 mA. So, when designing the circuit to drive the LED, we should always consider these limitations for correctly operating and not damaging the device.

How to do it...

Disconnect the microcontroller boards from the power and keep the LED and resistor on the breadboard as in the previous recipe. However, unplug all the jumper wires except the one connected to the - bus rail (GND). The following diagram shows what you should have on the breadboard:

Figure 2.21 – We keep the microcontroller board, LED, and resistor from the Implementing an LED status indicator on the breadboard recipe

Figure 2.21 – We keep the microcontroller board, LED, and resistor from the Implementing an LED status indicator on the breadboard recipe

Since the LED cathode is connected to the terminal resistor, the LED will be driven by a current sourcing circuit.

The following steps will show how to control the LED light through the GPIO peripheral:

  1. Choose the GPIO pin to drive the LED. The following table reports our choice:
Figure 2.22 – GPIO pin selected for driving the LED

Figure 2.22 – GPIO pin selected for driving the LED

  1. Connect the LED anode to the GPIO pin with a jumper wire:
Figure 2.23 – Connect the LED anode to the GPIO pin

Figure 2.23 – Connect the LED anode to the GPIO pin

On the Arduino Nano, we use a jumper wire to connect (J, 6) with (J, 24). On the Raspberry Pi Pico, we use a jumper wire to connect (J, 12) with (J, 24).

  1. Connect the terminal resistor to GND:
Figure 2.24 – Connect the resistor to GND

Figure 2.24 – Connect the resistor to GND

On both the Arduino Nano and Raspberry Pi Pico, we connect (J, 28) with the - bus rail.

The 220Ω resistor imposes an LED current of ~5 mA, which is below the maximum 20 mA LED current and below the maximum output GPIO current, as reported in the following table:

Figure 2.25 – Max GPIO current (sourcing) on the Arduino Nano and Raspberry Pi Pico

Figure 2.25 – Max GPIO current (sourcing) on the Arduino Nano and Raspberry Pi Pico

Once the circuit is ready, we can focus on the GPIO programming.

  1. Open the Arduino IDE and create a new sketch. Declare and initialize a global mbed::DigitalOut object with the pin name used for driving the LED.

For the Arduino Nano, we have the following:

mbed::DigitalOut led(p23); 

And this for the Raspberry Pi Pico:

mbed::DigitalOut led(p22); 

Mbed, or rather Mbed OS (https://os.mbed.com/), is a real-time operating system (RTOS) specifically for Arm Cortex-M processors, which offers functionalities typical of a canonical OS and drivers to control microcontroller peripherals. All programs on the Arduino Nano 33 BLE Sense board and Raspberry Pi Pico are built on top of this tiny operating system. In this recipe, we use the mbed::DigitalOutput object (https://os.mbed.com/docs/mbed-os/v6.15/apis/digitalout.html) from Mbed OS to interface with the GPIO peripheral in output mode. The peripheral initialization requires the GPIO pin (PinName) connected to the LED. PinName always starts with the letter p, followed by the pin number.

On the Arduino Nano, the pin number is obtained from the y number reported in the pin label P<x>.<y>. Therefore, PinName is p23.

On the Raspberry Pi Pico, the pin number is obtained from the y number reported in the label GPy. Therefore, PinName is p22.

  1. Set led to 1 for turning on the LED in the loop() function:
    void loop() {
      led = 1;
    }

Compile the sketch and upload the program to the microcontroller.

Turning an LED on and off with a push-button

In contrast to a PC where the keyboard, mouse, or even a touchscreen facilitates human interactions with the software applications, a physical button represents the easiest way for a user to interact with a microcontroller.

This recipe will teach us how to program the GPIO to read the status of a push-button (pushed or released) to control the LED light.

The following Arduino sketch contains the code referred to in this recipe:

  • 04_gpio_in_out.ino:

https://github.com/PacktPublishing/TinyML-Cookbook/blob/main/Chapter02/ArduinoSketches/04_gpio_in_out.ino

Getting ready

To get ready for this recipe, we need to know how this device works and program the GPIO peripheral in input mode.

The push-button is a type of button used with microcontrollers, and it has boolean behavior since its state can either be pushed (true) or released (false).

From an electronics point of view, a push-button is a device that makes (a.k.a. short) or breaks (a.k.a. open) the connection between two wires. When we press the button, we connect the wires through a mechanical system, allowing the current to flow. However, it is not like a standard light switch that keeps the wires connected when released. When we don't apply pressure to the button, the wires disconnect, and the current stops flowing.

Although this device has four metal legs, it is a two-terminal device because the contacts on the opposite side (1, 4 and 2, 3) are connected, as shown in the following figure:

Figure 2.26 – Push-button representation

Figure 2.26 – Push-button representation

When building a circuit with this component, the legs on the same side (1,2 or 4,3 in the preceding figure) are responsible for connecting two points. These two points will have the same voltage when the push-button is pressed.

The state of a push-button can be read with the GPIO peripheral in input mode. When configuring the GPIO in input mode, the peripheral reads the applied voltage on the pin to infer the logical level. From this value, we can guess whether the button is pressed. 

In the following diagram, the voltage on the GPIO pin is GND when we press the button. However, what is the voltage when the button is released?

Figure 2.27 – What is the voltage on the GPIO pin when we release the push-button?

Figure 2.27 – What is the voltage on the GPIO pin when we release the push-button?

Although the pin could only assume two logical levels, this could not be true in some input mode circumstances. A third logical level called floating (or high impedance) could occur if we do not take circuit precautions. When the floating state occurs, the pin's logical level is undefined because the voltage fluctuates between 3.3 V and GND. Since the voltage is not constant, we cannot know whether the push-button is pressed. To prevent this problem, we must include a resistor in our circuit to always have a well-defined logical level under all conditions.

Depending on what logical level we want in the pushed state, the resistor can be as follows:

  • Pull-up: The resistor connects the GPIO pin to the 3.3 V. Thus, the GPIO pin reads LOW in the pushed state and HIGH in the released state.
  • Pull-down: The resistor connects the GPIO pin to GND in contrast to the pull-up configuration. Thus, the GPIO pin reads the logical level HIGH in the pushed state and LOW in the released state.

The following diagram shows the difference between the pull-up and pull-down configurations:

Figure 2.28 – Pull-up versus pull-down configurations

Figure 2.28 – Pull-up versus pull-down configurations

Typically, a 10 K resistor should be okay for both cases. However, most microcontrollers offer an internal and programmable pull-up resistor so the external one is often not needed.

How to do it...

Keep all the components on the breadboard. The following steps will show what to change in the previous sketch to control the LED status with the push-button:

  1. Choose the GPIO pin for reading the push-button state. The following table reports our choice.
Figure 2.29 – GPIO pin used to read the push-button state

Figure 2.29 – GPIO pin used to read the push-button state

  1. Mount the push-button between the breadboard's left and right terminal strips:
Figure 2.30 – The push-button is mounted between the terminal strips 21 and 23

Figure 2.30 – The push-button is mounted between the terminal strips 21 and 23

As we can observe from the preceding diagram, we use terminal strips not employed by other devices.

  1. Connect the push-button to the GPIO pin and GND:
Figure 2.31 – The push-button is only connected to the GPIO pin and GND

Figure 2.31 – The push-button is only connected to the GPIO pin and GND

The floating state will not occur because we use the microcontroller pull-up resistor.

  1. Open the sketch developed in the previous recipe. Declare and initialize a global mbed::DigitalIn object with the pin name used for the push-button.

For the Arduino Nano:

mbed::DigitalIn button(p30);

And this for the Raspberry Pi Pico:

mbed::DigitalIn button(p10);

mbed::DigitalIn (https://os.mbed.com/docs/mbed-os/v6.15/apis/digitalin.html) is used to interface with the GPIO peripheral in input mode. The initialization only requires the GPIO pin (PinName) connected to the push-button.

  1. Set the button mode to PullUp in the setup() function:
    void setup() {
      button.mode(PullUp);
    }

The preceding code enables the microcontroller's internal pull-up resistor.

  1. Turn on the LED when the push-button is LOW (0) in the loop() function:
    void loop() {
      led = !button;
    }

We just need to set the led object to the opposite value returned by button to light up the LED when the push-button is pressed.

Compile the sketch and upload the program to the microcontroller.

Tip

When the push-button is pressed, the switch could generate spurious logical-level transitions due to the mechanical nature of the component. This issue is called button bouncing because the switch response bounces between HIGH and LOW for a short time. You may consider adopting a switch debouncing algorithm (for example, https://os.mbed.com/teams/TVZ-Mechatronics-Team/wiki/Timers-interrupts-and-tasks) to prevent the generation of multiple transitions.

Using interrupts to read the push-button state

The previous recipe explained how to read digital signals with the GPIO peripheral. However, the proposed solution is inefficient because the CPU wastes cycles waiting for the button to be pressed while it could do something else in the meantime. Furthermore, this could be a scenario where we would keep the CPU in low-power mode when there is nothing else to do.

This recipe will teach us how to read the push-button state efficiently by using the interrupts on the Arduino Nano.

The following Arduino sketch contains the code referred to in this recipe:

  • 05_gpio_interrupt.ino:

https://github.com/PacktPublishing/TinyML-Cookbook/blob/main/Chapter02/ArduinoSketches/05_gpio_interrupt.ino

Getting ready

Let's prepare this recipe by learning what an interrupt is and what Mbed OS API we can use to read the push-button efficiently.

An interrupt is a signal that temporarily pauses the main program to respond to an event with a dedicated function, called an interrupt handler or interrupt service routine (ISR). Once the ISR ends the execution, the processor resumes the main program from the point it was left at, as shown in the following diagram:

Figure 2.32 – Interrupt pauses the main program temporarily

Figure 2.32 – Interrupt pauses the main program temporarily

The interrupt is a powerful mechanism to save energy because the CPU could enter the sleep state and wait for an event before starting the computation.

A microcontroller has several interrupt sources, and for each one, we can program a dedicated ISR.

Although the ISR is a function, there are limitations to its implementation:

  • It does not have input arguments.
  • It does not return a value. Therefore, we need to use global values to report status changes.
  • It must be short to not steal too much time from the main program. We want to remind you that the ISR is not a thread since the processor can only resume the computation when the ISR finishes.

For GPIO peripherals in input mode, we can use the mbed::InterruptIn (https://os.mbed.com/docs/mbed-os/v6.15/apis/interruptin.html) object to trigger an event whenever the logical level on the pin changes:

Figure 2.33 – Rising interrupt versus falling interrupt

Figure 2.33 – Rising interrupt versus falling interrupt

As we can observe from the preceding diagram, mbed::InterruptIn can trigger interrupts when the logical level on the pin goes from LOW to HIGH (rising interrupts) or HIGH to LOW (falling interrupt).

How to do it...

Open the sketch built in the previous recipe and follow these steps to turn on and off the LED with the GPIO interrupt:

  1. Define and initialize the mbed::InterruptIn object with the PinName of the GPIO pin connected to the push-button.

For the Arduino Nano:

mbed::InterruptIn button(p30);

For the Raspberry Pi Pico:

mbed::InterruptIn button(p10);

The mbed::DigitalIn object is not required anymore since mbed::InterruptIn also controls the interface with the GPIO peripheral in input mode.

  1. Write an ISR for handling the interrupt request on the rising edge (LOW to HIGH) of the input signal:
    void rise_ISR() {
      led = 0;
    }

The LED is turned off when the preceding ISR is called (led = 0).

Next, write an ISR for handling the interrupt request on the falling edge (HIGH to LOW) of the input signal:

void fall_ISR() {
  led = 1;
}

The LED switches on when the preceding ISR is called (led = 1).

  1. Initialize button in the setup() function:
    void setup() {
      button.mode(PullUp);
      button.rise(&rise_ISR);
      button.fall(&fall_ISR);
    }

We configure the mbed::InterruptIn object by doing the following:

  • Enabling the internal pull-up resistor (button.mode(PullUp))
  • Attaching the ISR function to call when the rising interrupt occurs (button.rise(&rise_ISR))
  • Attaching the ISR function to call when the falling interrupt occurs (button.fall(&fall_ISR))
  1. Replace the code in the loop() function with delay(4000):
    void loop() {
      delay(4000);
    }

In theory, we could leave the loop() function empty. However, we recommend calling delay() when nothing has to be done because it can put the system in low-power mode.

Compile the sketch and upload the program to the microcontroller.

Powering microcontrollers with batteries

For many TinyML applications, batteries could be the only power source for our microcontrollers.

In this final recipe, we will learn how to power microcontrollers with AA batteries.

The following Colab notebook contains the code referred to in this recipe:

  • 06_estimate_battery_life.ipynb:

https://github.com/PacktPublishing/TinyML-Cookbook/blob/main/Chapter02/ColabNotebooks/06_estimate_battery_life.ipynb

Getting started

Microcontrollers don't have a built-in battery, so we need to supply an external one to make the device work when it is not connected through the micro-USB cable.

To get ready for this recipe, we need to know what types of batteries we need and how we can use them correctly to supply power.

Batteries are sources of electric power and have a limited energy capacity. The energy capacity (or battery capacity) quantifies the energy stored and is measured in milli-ampere-hour (mAh). Therefore, a higher mAh implies a longer battery life.

The following table reports some commercial batteries that find applicability with microcontrollers:

Figure 2.34 – Suitable commercial batteries for microcontrollers

Figure 2.34 – Suitable commercial batteries for microcontrollers

The battery selection depends on the required microcontroller voltage and other factors such as energy capacity, form factor, and operating temperature.

As we can observe from the preceding table, the AA battery provides a higher capacity, but it supplies 1.5 V, typically insufficient for microcontrollers.

Therefore, how can we power microcontrollers with AA batteries?

In the following subsections, we will show standard techniques to either increase the supplied voltage or the energy capacity.

Increasing the output voltage by connecting batteries in series

When connecting batteries in series, the positive terminal of one battery is connected to the negative terminal of the other one, as shown in the following figure:

Figure 2.35 – Batteries in series

Figure 2.35 – Batteries in series

Important Note

This approach will not extend the battery capacity but just the supplied voltage.

The new supplied voltage () is as follows:

Where N is the number of connected batteries in series.

For example, since one AA battery supplies 1.5 V for 2400 mAh, we could connect two AA batteries in series to produce 3.0 V for the same energy capacity.

However, if the battery capacity is not enough for our application, how can we increase it?

Increasing the energy capacity by connecting batteries in parallel

When connecting batteries in parallel, the positive terminals of the batteries are tied together with one wire. The same applies to the negative terminals, which are joined together as shown in the following figure:

Figure 2.36 – Batteries in parallel

Figure 2.36 – Batteries in parallel

Important Note

This approach will not increase the output voltage but just the battery capacity.

The new battery capacity () is as follows:

Where N is the number of connected batteries in parallel.

For example, since one AA battery has a battery capacity of 2400 mAh, we could connect two AA batteries in parallel to increase the battery capacity by two times.

Now that we know how to connect multiple batteries together to get the desired output voltage and energy capacity, let's see how we can use them to power the microcontrollers.

Connecting batteries to the microcontroller board

Microcontrollers have dedicated pins for supplying power through external energy sources, such as batteries. These pins have voltage limits, commonly reported in the datasheet.

On the Arduino Nano, the external power source is supplied through the Vin pin. The Vin input voltage can range from 5 V–21 V.

On the Raspberry Pi Pico, the external power source is supplied through the VSYS pin. The VSYS input voltage can range from 1.8 V – 5.5 V.

On both platforms, the onboard voltage regulator will convert the supplied voltage to 3.3 V.

How to do it...

Disconnect the Arduino Nano and Raspberry Pi Pico from the micro-USB and keep all the components on the breadboard.

The battery holder considered for this recipe connects the AA batteries in series. We recommend not inserting the batteries in the battery holder yet. The batteries should only be inserted when the electric circuit is completed.

The following steps will show how to power the Arduino Nano and Raspberry Pi Pico with batteries:

  1. Connect the positive (red) and negative (black) wires of the battery holder to the + and bus rails respectively:
Figure 2.37 – Connect the battery holder to the bus rails

Figure 2.37 – Connect the battery holder to the bus rails

  1. The Arduino Nano and Raspberry Pi Pico have different voltage limits for the external power source. Therefore, we cannot use the same number of AA batteries on both platforms. In fact, three AA batteries are enough for the Raspberry Pi Pico but not for the Arduino Nano. In contrast, four AA batteries are enough for the Arduino Nano but beyond the voltage limit on the Raspberry Pi Pico. For this reason, we use a 4 x AA battery holder for the Arduino Nano to supply 6 V and a 3 x AA battery holder for the Raspberry Pi Pico to supply 4.5 V.
  2. Connect the external power source to the microcontroller board, as shown in the following diagram:
Figure 2.38 – Connect the bus rails to the microcontroller power pin and GND

Figure 2.38 – Connect the bus rails to the microcontroller power pin and GND

As you can observe from the preceding figure, VIN (Arduino Nano) and VSYS (Raspberry Pi Pico) are connected to the positive battery holder terminal through the + bus rail.

  1. Insert the batteries in the battery holder:
    • 4 x AA batteries for the Arduino Nano
    • 3 x AA batteries for the Raspberry Pi Pico

The LED application should now work again.

However, one thing we might be curious about is how can we evaluate the lifetime of a battery-powered application?

There's more

Once we have chosen the battery for the microcontroller, we can estimate its lifetime with the following formula:

Where:

Figure 2.39 – Physical quantities of the battery lifetime estimate formula

Figure 2.39 – Physical quantities of the battery lifetime estimate formula

The following Python code calculates the battery life in hours and days:

battery_cap_mah = 2400
i_load_ma = 1.5
 
battery_life_hours = battery_cap_mah / i_load_ma
battery_life_days = battery_life_hours / 24
 
print("Battery life:", battery_life_hours,"hours,", battery_life_days, "days")

The preceding code estimates the battery life for the case when the battery capacity (battery_cap_mah) is 2400 mAh, and the load current (i_load_ma) is 1.5 mA.

The expected output is as follows:

Figure 2.40 – Expected output from the battery life estimator

Figure 2.40 – Expected output from the battery life estimator

Although the formula above is an estimation and valid under ideal conditions, it is enough to understand how long the system could last. A better model could include other factors such as battery self-discharge and temperature.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Train and deploy ML models on Arduino Nano 33 BLE Sense and Raspberry Pi Pico
  • Work with different ML frameworks such as TensorFlow Lite for Microcontrollers and Edge Impulse
  • Explore cutting-edge technologies such as microTVM and Arm Ethos-U55 microNPU

Description

This book explores TinyML, a fast-growing field at the unique intersection of machine learning and embedded systems to make AI ubiquitous with extremely low-powered devices such as microcontrollers. The TinyML Cookbook starts with a practical introduction to this multidisciplinary field to get you up to speed with some of the fundamentals for deploying intelligent applications on Arduino Nano 33 BLE Sense and Raspberry Pi Pico. As you progress, you’ll tackle various problems that you may encounter while prototyping microcontrollers, such as controlling the LED state with GPIO and a push-button, supplying power to microcontrollers with batteries, and more. Next, you’ll cover recipes relating to temperature, humidity, and the three “V” sensors (Voice, Vision, and Vibration) to gain the necessary skills to implement end-to-end smart applications in different scenarios. Later, you’ll learn best practices for building tiny models for memory-constrained microcontrollers. Finally, you’ll explore two of the most recent technologies, microTVM and microNPU that will help you step up your TinyML game. By the end of this book, you’ll be well-versed with best practices and machine learning frameworks to develop ML apps easily on microcontrollers and have a clear understanding of the key aspects to consider during the development phase.

Who is this book for?

This book is for machine learning developers/engineers interested in developing machine learning applications on microcontrollers through practical examples quickly. Basic familiarity with C/C++, the Python programming language, and the command-line interface (CLI) is required. However, no prior knowledge of microcontrollers is necessary.

What you will learn

  • Understand the relevant microcontroller programming fundamentals
  • Work with real-world sensors such as the microphone, camera, and accelerometer
  • Run on-device machine learning with TensorFlow Lite for Microcontrollers
  • Implement an app that responds to human voice with Edge Impulse
  • Leverage transfer learning to classify indoor rooms with Arduino Nano 33 BLE Sense
  • Create a gesture-recognition app with Raspberry Pi Pico
  • Design a CIFAR-10 model for memory-constrained microcontrollers
  • Run an image classifier on a virtual Arm Ethos-U55 microNPU with microTVM
Estimated delivery fee Deliver to United States

Economy delivery 10 - 13 business days

Free $6.95

Premium delivery 6 - 9 business days

$21.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Apr 01, 2022
Length: 344 pages
Edition : 1st
Language : English
ISBN-13 : 9781801814973
Category :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
OR
Modal Close icon
Payment Processing...
tick Completed

Shipping Address

Billing Address

Shipping Methods
Estimated delivery fee Deliver to United States

Economy delivery 10 - 13 business days

Free $6.95

Premium delivery 6 - 9 business days

$21.95
(Includes tracking information)

Product Details

Publication date : Apr 01, 2022
Length: 344 pages
Edition : 1st
Language : English
ISBN-13 : 9781801814973
Category :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 156.97
Machine Learning with PyTorch and Scikit-Learn
$54.99
Raspberry Pi Pico DIY Workshop
$51.99
TinyML Cookbook
$49.99
Total $ 156.97 Stars icon
Banner background image

Table of Contents

9 Chapters
Chapter 1: Getting Started with TinyML Chevron down icon Chevron up icon
Chapter 2: Prototyping with Microcontrollers Chevron down icon Chevron up icon
Chapter 3: Building a Weather Station with TensorFlow Lite for Microcontrollers Chevron down icon Chevron up icon
Chapter 4: Voice Controlling LEDs with Edge Impulse Chevron down icon Chevron up icon
Chapter 5: Indoor Scene Classification with TensorFlow Lite for Microcontrollers and the Arduino Nano Chevron down icon Chevron up icon
Chapter 6: Building a Gesture-Based Interface for YouTube Playback Chevron down icon Chevron up icon
Chapter 7: Running a Tiny CIFAR-10 Model on a Virtual Platform with the Zephyr OS Chevron down icon Chevron up icon
Chapter 8: Toward the Next TinyML Generation with microNPU Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Top Reviews
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.9
(11 Ratings)
5 star 90.9%
4 star 9.1%
3 star 0%
2 star 0%
1 star 0%
Filter icon Filter
Top Reviews

Filter reviews by




Client Amazon Apr 14, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
We have been tinkering and testing ideas in the when it comes to "Physical Computing" for a long time. We have also been looking for a book we can use as a reference standard. It has been a long time coming. We have finally found the perfect book. TinyML Cookbook: Combine artificial intelligence.... is the best I have seen thus far on the market. This book is pedagogically sound. It's designed in such a way that even upper elementary level learners are able to follow the recipes and conduct the hands-on inquiry-based activities. We have conducted many of the activities using both the Arduino Nona 33 and the Raspberry Pi Pico. This is an excellent book which can be used to introduce learners to embedded/edge/cloud computing, microcontroller/edgeware, TinyML, Machine Learning-ML, Deep Learning-DL, Artificial Intelligence-AI, Internet of Things-IoT. Every STEM educator/tinkerer on Earth needs to have a copy of this book. We are safely guarding our copy close to our chest in the Alchemist Club StudiosDr. RonelusSTEM Learning ScientistNew York City Board of Education
Amazon Verified review Amazon
Jack Raifer Apr 27, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
When I got this book, I thought it would be like a tiny reference guide for ML applications, lo and behold, I got happily enticed into the world of IoT devices and how to get around their processing limitations to implement Machine Learning in them. A happy surprise and now one of my favorite books.
Amazon Verified review Amazon
tina Jul 20, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Background: I've been involved with TinyML for over 6 years through working at Qeexo, and was at the inaugural TinyML Meetup at Qualcomm in the Silicon Valley. I also read Pete and Daniel's "TinyML: Machine Learning with TensorFlow Lite".That said, I found the TinyML Cookbook... well, very "cookbook"-like. Besides a pretty general (but good) intro of TinyML not unlike my own TinyML pitch, it comes with very detailed, step-by-step instructions and pre-prepared code on GitHub, so it's super easy to get started, even if you're not a coder or embedded engineer. (I am neither, but I do have a CS degree from a long time ago.)This Cookbook is very well-structured, and broken down into individual projects and categories. One can select the tools and hardware one is interested in, and start there, without having to go through the entire book, similar to how you can pick out one dish to cook from a cookbook. Full disclosure: I didn't do every single project, just selected a couple that I already have the hardware for (Arduino Nano 33 BLE Sense, Raspberry Pi Pico).Chapter 8 on the Arm microNPU is actually the most interesting to me as the latest and greatest tech in TinyML, however:"Arm Ethos-U55 is the first microNPU designed by Arm to extend the ML capabilitiesof Cortex-M-based microcontrollers. Unfortunately, there is no hardware availabilitywith this new processor at the time of writing. However, Arm offers a free Fixed VirtualPlatform (FVP) based on the Arm Corstone-300 system to quickly experiment with MLmodels on this processor without the need for physical devices."So, I was not able to test with actual hardware.Overall, it was quite fun to try some new things out. One thing I wish it had is more room for experimenting or expanding upon the current project - pointers on how to change the current code to achieve different results, or other applications and real-life use cases of these "demo" projects. (However, I understand that's not really in the scope of a "cookbook" - one usually doesn't just experiment with random ingredients to see how a dish turns out differently.)Fun read!Anyway,
Amazon Verified review Amazon
Venkat Rangan May 02, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
The book takes you from developing a super simple Arduino based neural network on a tiny CortexM processor, through the data collection and associated flow to running a neural network on an Ethos NPU accelerator on Qemu. The scope of this book took my breath away!Every chapter is in cookbook style so it encourages learning by doing rather than a formulaic approach (I prefer to learn by doing). There are a wide variety of examples including weather prediction, keyword spotting, vision and using TensorFlow and Edge Impulse. All code is on Github, python based for the most part and easy to dig into and learn from as there is detailed explanation of each step. I think this book significantly reduces the barriers for tinyML by demonstration.Am looking forward to going through the book again, far more slowly and experimentally with HW in tow.This cookbook has some good recipes!
Amazon Verified review Amazon
Guangping zhang May 06, 2022
Full star icon Full star icon Full star icon Full star icon Full star icon 5
TinyML is a kind of machine learning (ML), it makes AI work with extremely low-powereddevices, such as microcontrollers.This book introduces applications of multidisciplinary fields, such as Arduino Nano 33 BLE Sense and Raspberry Pi Pico.Also the book discusses microcontrollers, such as controlling the LED state with GPIO and a push-button and supplying power to microcontrollers with batteries. After that, the book covers recipes relating to temperature, humidity, and the three V (voice, vision, and vibration) sensors to gain the necessary skills to implement end-to-end smart applications in different scenarios.Then the author introduces how to build tiny models for memory-constrained microcontrollers.Finally, the book discusses two of the most recent technologies, microTVM and microNPU, which will help you step up your TinyML game.The book covers the most interesting fields of TinyML, I suggest you read it and have a good start.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela