|
1 | 1 | ---
|
2 |
| -featured: micropython-101 |
3 |
| -title: '2. Micropython - Analog I/O' |
4 |
| -description: 'Learn the basics for Analog I/O ports on MicroPython.' |
5 |
| -author: 'Pedro Lima' |
6 |
| -hero_image: "./hero-banner.png" |
| 2 | + |
| 3 | +featured: micropython-101 |
| 4 | +title: '2. Micropython Basics - Analog I/O' |
| 5 | +description: 'Learn the fundamentals of analog I/O with MicroPython for smooth signal interactions.' |
| 6 | +author: 'Pedro Lima' |
| 7 | +hero_image: "./hero-banner.png" |
| 8 | + |
7 | 9 | ---
|
8 | 10 |
|
| 11 | +Analog inputs and outputs are essential for handling a range of values rather than simple on/off states, allowing for more nuanced control over devices and inputs in your projects. In this chapter, we’ll cover how to work with analog I/O using MicroPython, focusing on how to: |
| 12 | + |
| 13 | +- Read analog values, such as a light sensor or potentiometer. |
| 14 | +- Generate analog outputs, like controlling LED brightness or motor speed. |
| 15 | + |
| 16 | +Analog signals differ from digital signals in that they represent a continuous range of values. This flexibility enables more refined interactions with the physical world, making analog I/O indispensable for many types of sensors and actuators. |
| 17 | + |
| 18 | +## Analog Inputs |
| 19 | + |
| 20 | +To read analog values as microcontrollers work on a binary system, we typically use the `ADC` (Analog-to-Digital Converter) class. Analog inputs measure voltage levels that range continuously between two values, often 0V (LOW) and the board's operating voltage, like 3.3V or 5V. |
| 21 | +Analog signals allow you to interact with the world more fluidly by capturing gradual changes rather than absolute states. This flexibility is ideal for applications like environmental sensing, variable speed control, and responsive lighting. |
| 22 | +Analog sensors output a range of voltages to reflect changes in physical conditions. By converting these values into digital numbers, your Arduino board can interpret real-world signals, such as light intensity or temperature. |
| 23 | + |
| 24 | +## PWM - Pulse Width Modulation |
| 25 | + |
| 26 | +In microcontrollers, **Pulse Width Modulation (PWM)** is essential for creating the appearance of analog output. True analog signals involve a continuous voltage range, but since microcontrollers primarily handle digital signals (on or off), PWM bridges the gap by rapidly switching the signal between HIGH and LOW. By adjusting the time the signal remains in the HIGH state (known as the "duty cycle"), PWM simulates varying voltage levels. |
| 27 | + |
| 28 | +PWM is especially useful in applications where true analog output is not possible but smooth transitions are necessary. Common scenarios include: |
| 29 | + |
| 30 | +- **LED Dimming**: PWM allows for adjusting brightness levels by controlling how long the LED is ON versus OFF within a given time frame. |
| 31 | +- **Motor Control**: By modifying the duty cycle, PWM can control the speed of motors for robotics or other mechanical devices, as the motor responds to the average power supplied over time. |
| 32 | +- **Audio Signals**: Some sound applications also use PWM to generate varying sound frequencies or control speaker volume. |
| 33 | + |
| 34 | +The main advantage of PWM is that it allows you to control analog-like behavior using digital pins, adding versatility to your projects while keeping power consumption efficient. |
| 35 | + |
| 36 | +TODO: ILLUSTRATE THIS PWM MAGIC |
| 37 | + |
| 38 | +### Code Example: Reading a Light Sensor |
| 39 | + |
| 40 | +**Components Needed:** |
| 41 | + |
| 42 | +- Arduino board compatible with MicroPython |
| 43 | +- Analog light sensor (e.g., photoresistor) |
| 44 | +- Jumper wires |
| 45 | + |
| 46 | +**Circuit Diagram:** |
| 47 | + |
| 48 | +1. Connect one leg of the photoresistor to the analog input pin (e.g., `A0`) and the other leg to `GND`. |
| 49 | +2. Optionally, add a pull-up resistor to the sensor if needed. |
| 50 | + |
| 51 | +**MicroPython Code:** |
| 52 | + |
| 53 | +```python |
| 54 | +from machine import ADC |
| 55 | +import time |
| 56 | + |
| 57 | +# Initialize ADC for the analog pin |
| 58 | +light_sensor = ADC(0) # Replace '0' with the correct ADC channel for your board |
| 59 | + |
| 60 | +while True: |
| 61 | + light_level = light_sensor.read_u16() # Reads a 16-bit value (0-65535) |
| 62 | + print("Light level:", light_level) |
| 63 | + time.sleep(1) |
| 64 | +``` |
| 65 | + |
| 66 | +**Explanation:** |
| 67 | + |
| 68 | +- **ADC Initialization**: We initialize the `ADC` class, passing the analog channel as an argument. |
| 69 | +- **Reading Values**: `read_u16()` reads a 16-bit integer (0-65535), where `0` represents 0V and `65535` represents the board's maximum operating voltage. |
| 70 | +- **Loop**: The sensor reading is printed every second, showing how the value changes based on light intensity. |
| 71 | + |
| 72 | +## Analog Outputs |
| 73 | + |
| 74 | +Unlike analog input, analog output on microcontrollers doesn’t provide a truly continuous range of voltages. Instead, we use **Pulse Width Modulation** (PWM) to simulate varying voltage levels. PWM rapidly switches a digital output between HIGH and LOW at a specified duty cycle, creating the illusion of analog output by controlling the amount of time the signal stays HIGH. |
| 75 | + |
| 76 | +### Code Example: Dimming an LED with PWM |
| 77 | + |
| 78 | +PWM is commonly used for tasks such as dimming LEDs or controlling motor speeds. |
| 79 | + |
| 80 | +**Components Needed:** |
| 81 | + |
| 82 | +- Arduino board compatible with MicroPython |
| 83 | +- LED |
| 84 | +- Current-limiting resistor (e.g., 220Ω) |
| 85 | +- Jumper wires |
| 86 | + |
| 87 | +**Circuit Diagram:** |
| 88 | + |
| 89 | +1. Connect the anode (+) of the LED to the PWM-capable output pin (e.g., `D5`). |
| 90 | +2. Connect the cathode (-) through a resistor to `GND`. |
| 91 | + |
| 92 | +**MicroPython Code:** |
| 93 | + |
| 94 | +```python |
| 95 | +from machine import Pin, PWM |
| 96 | +import time |
| 97 | + |
| 98 | +# Initialize PWM for the LED pin |
| 99 | +led_pwm = PWM(Pin(5)) # Replace '5' with the correct pin for your board |
| 100 | +led_pwm.freq(1000) # Set frequency to 1 kHz |
| 101 | + |
| 102 | +# Gradually change the LED brightness |
| 103 | +while True: |
| 104 | + for duty in range(0, 65536, 1024): # 0 to 65535 for 16-bit PWM |
| 105 | + led_pwm.duty_u16(duty) |
| 106 | + time.sleep(0.01) |
| 107 | + for duty in range(65535, -1, -1024): |
| 108 | + led_pwm.duty_u16(duty) |
| 109 | + time.sleep(0.01) |
| 110 | +``` |
| 111 | + |
| 112 | +**Explanation:** |
| 113 | + |
| 114 | +- **PWM Initialization**: We create a `PWM` object and set the frequency to 1 kHz, which works well for LEDs. |
| 115 | +- **Duty Cycle**: `duty_u16()` takes a value between 0 and 65535. The higher the value, the longer the signal stays HIGH, making the LED brighter. |
| 116 | +- **Loop**: The brightness gradually increases and decreases by adjusting the duty cycle in small steps, causing the LED to fade in and out. |
| 117 | + |
| 118 | + |
0 commit comments