-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e54efb7
commit 3d334b8
Showing
19 changed files
with
357 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,89 @@ | ||
# ADC (Analog to Digital Converter) | ||
|
||
# TODO: Explanation | ||
An Analog-to-Digital Converter (ADC) is a device used to convert analog signals (continuous signals like sound, light, or temperature) into digital signals (discrete values, typically represented as 1s and 0s). This conversion is necessary for digital systems like microcontrollers (e.g., Raspberry Pi, Arduino) to interact with the real world. For example, sensors that measure temperature or sound produce analog signals, which need to be converted into digital format for processing by digital devices. | ||
|
||
## ADC Resolution | ||
The resolution of an ADC refers to how precisely the ADC can measure an analog signal. It is expressed in bits, and the higher the resolution, the more precise the measurements. | ||
|
||
- 8-bit ADC produces digital values between 0 and 255. | ||
- 10-bit ADC produces digital values between 0 and 1023. | ||
- 12-bit ADC produces digital values between 0 and 4095. | ||
|
||
The resolution of the ADC can be expressed as the following formula: | ||
\\[ | ||
\text{Resolution} = \frac{\text{Vref}}{2^{\text{bits}} - 1} | ||
\\] | ||
|
||
## Pico | ||
Based on the [Pico datasheet](https://datasheets.raspberrypi.com/pico/pico-2-datasheet.pdf), Raspberry Pi Pico has 12-bit 500ksps Analogue to Digital Converter (ADC). So, it provides values ranging from 0 to 4095 (4096 possible values) | ||
|
||
\\[ | ||
\text{Resolution} = \frac{3.3V}{2^{12} - 1} = \frac{3.3V}{4095} \approx 0.000805 \text{V} \approx 0.8 \text{mV} | ||
\\] | ||
|
||
## Pins | ||
The Raspberry Pi Pico has **four accessible ADC channels** on the following GPIOs: | ||
|
||
| **GPIO Pin** | **ADC Channel** | **Function** | | ||
|--------------|-----------------|--------------------------------------------------| | ||
| GPIO26 | ADC0 | Can be used to read voltage from peripherals. | | ||
| GPIO27 | ADC1 | Can be used to read voltage from peripherals. | | ||
| GPIO28 | ADC2 | Can be used to read voltage from peripherals. | | ||
| GPIO29 | ADC3 | Measures the VSYS supply voltage on the board. | | ||
|
||
In pico, ADC operates with a reference voltage set by the supply voltage, which can be measured on pin 35 (ADC_VREF). | ||
|
||
## ADC Value and LDR Resistance in a Voltage Divider | ||
In a voltage divider with an LDR and a fixed resistor, the output voltage \\( V_{\text{out}} \\) is given by: | ||
|
||
\\[ | ||
V_{\text{out}} = V_{\text{in}} \times \frac{R_{\text{LDR}}}{R_{\text{LDR}} + R_{\text{fixed}}} | ||
\\] | ||
|
||
It is same formula as explained in the previous chapter, just replaced the \\({R_2}\\) with \\({R_{\text{LDR}}}\\) and \\({R_1}\\) with \\({R_{\text{fixed}}}\\) | ||
|
||
- **Bright light** (low LDR resistance): \\( V_{\text{out}} \\) decreases, resulting in a lower ADC value. | ||
- **Dim light** (high LDR resistance): \\( V_{\text{out}} \\) increases, leading to a higher ADC value. | ||
|
||
## Example ADC value calculation: | ||
|
||
**Bright light**: | ||
|
||
Let's say the Resistence value of LDR is \\(1k\Omega\\) in the bright light. | ||
|
||
\\[ | ||
V_{\text{out}} = 3.3V \times \frac{1k\Omega}{1k\Omega + 10k\Omega} \approx 0.3V | ||
\\] | ||
|
||
The ADC value is calculated as: | ||
\\[ | ||
\text{ADC value} = \left( \frac{V_{\text{out}}}{V_{\text{ref}}} \right) \times (2^{12} - 1) \approx \left( \frac{0.3}{3.3} \right) \times 4095 \approx 372 | ||
\\] | ||
|
||
**Darkness**: | ||
|
||
Let's say the Resistence value of LDR is \\(140k\Omega \\) in very low light. | ||
|
||
\\[ | ||
V_{\text{out}} = 3.3V \times \frac{140k\Omega}{140k\Omega + 10k\Omega} \approx 3.08V | ||
\\] | ||
|
||
The ADC value is calculated as: | ||
\\[ | ||
\text{ADC value} = \left( \frac{V_{\text{out}}}{V_{\text{ref}}} \right) \times (2^{12} - 1) \approx \left( \frac{3.08}{3.3} \right) \times 4095 = 3822 | ||
\\] | ||
|
||
### **Converting ADC value back to voltage**: | ||
|
||
Now, if we want to convert the ADC value back to the input voltage, we can multiply the ADC value by the resolution (0.8mV). | ||
|
||
For example, let's take an ADC value of 3822: | ||
|
||
\\[ | ||
\text{Input Voltage} = 3822 \times 0.8mV = 3057.6mV \approx 3.06V | ||
\\] | ||
|
||
|
||
## Reference | ||
- [What is Analog to Digital Converter & Its Working](https://www.elprocus.com/analog-to-digital-converter/) | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,12 @@ | ||
## LDR (Light Dependent Resistor) | ||
|
||
# TODO: Explanation | ||
In this section, we will use an LDR (Light Dependent Resistor) with the Raspberry Pi Pico 2. An LDR changes its resistance based on the amount of light falling on it. The brighter the light, the lower the resistance, and the dimmer the light, the higher the resistance. This makes it ideal for applications like light sensing, automatic lighting, or monitoring ambient light levels. | ||
|
||
<img style="display: block; margin: auto;" alt="pico2" src="./images/ldr.png"/> | ||
|
||
|
||
## Components Needed: | ||
- LDR (Light Dependent Resistor) | ||
- Resistor (typically 10kΩ); needed to create voltage divider | ||
- Jumper wires (as usual) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
# Action | ||
|
||
We'll use the Embassy HAL for this exercise. | ||
|
||
## Project from template | ||
|
||
To set up the project, run: | ||
```sh | ||
cargo generate --git https://github.com/ImplFerris/pico2-template.git | ||
``` | ||
When prompted, give your project a name, like "dracula-ldr" and select `embassy` as the HAL. | ||
|
||
Then, navigate into the project folder: | ||
```sh | ||
cd PROJECT_NAME | ||
# For example, if you named your project "dracula-ldr": | ||
# cd dracula-ldr | ||
``` | ||
|
||
## Interrupt Handler | ||
Let's set up interrupt handling for the ADC. | ||
|
||
```rust | ||
use embassy_rp::adc::InterruptHandler; | ||
|
||
bind_interrupts!(struct Irqs { | ||
ADC_IRQ_FIFO => InterruptHandler; | ||
}); | ||
``` | ||
In simple terms, when the ADC completes a conversion and the result is ready, it triggers an interrupt. This tells the pico that the new data is available, so it can process the ADC value. The interrupt ensures that the pico doesn't need to constantly check the ADC, allowing it to respond only when new data is ready. | ||
|
||
Read more about RP2350 interreupts in the [datasheet (82th page).](https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf) | ||
|
||
|
||
## Initialize the Embassy HAL | ||
```rust | ||
let p = embassy_rp::init(Default::default()); | ||
``` | ||
|
||
## Initialize the ADC | ||
```rust | ||
let mut adc = Adc::new(p.ADC, Irqs, Config::default()); | ||
``` | ||
|
||
## Configuring the ADC Pin and LED | ||
We set up the ADC input pin (PIN_26) for reading an analog signal. | ||
Then we set up an output pin (PIN_15) to control an LED. The LED starts in the low state (Level::Low), meaning it will be off initially. | ||
|
||
```rust | ||
let mut p26 = Channel::new_pin(p.PIN_26, Pull::None); | ||
let mut led = Output::new(p.PIN_15, Level::Low); | ||
``` | ||
|
||
## Main loop | ||
The logic is straightforward: read the ADC value, and if it's greater than 3800, turn on the LED; otherwise, turn it off. | ||
|
||
```rust | ||
loop { | ||
let level = adc.read(&mut p26).await.unwrap(); | ||
if level > 3800 { | ||
led.set_high(); | ||
} else { | ||
led.set_low(); | ||
} | ||
Timer::after_secs(1).await; | ||
} | ||
``` | ||
|
||
## The full code | ||
```rust | ||
#![no_std] | ||
#![no_main] | ||
|
||
use embassy_executor::Spawner; | ||
use embassy_rp::adc::{Adc, Channel, Config, InterruptHandler}; | ||
use embassy_rp::bind_interrupts; | ||
use embassy_rp::block::ImageDef; | ||
use embassy_rp::gpio::{Level, Output, Pull}; | ||
use embassy_time::Timer; | ||
use {defmt_rtt as _, panic_probe as _}; | ||
|
||
#[link_section = ".start_block"] | ||
#[used] | ||
pub static IMAGE_DEF: ImageDef = ImageDef::secure_exe(); | ||
|
||
bind_interrupts!(struct Irqs { | ||
ADC_IRQ_FIFO => InterruptHandler; | ||
}); | ||
|
||
#[embassy_executor::main] | ||
async fn main(_spawner: Spawner) { | ||
let p = embassy_rp::init(Default::default()); | ||
let mut adc = Adc::new(p.ADC, Irqs, Config::default()); | ||
|
||
let mut p26 = Channel::new_pin(p.PIN_26, Pull::None); | ||
let mut led = Output::new(p.PIN_15, Level::Low); | ||
|
||
loop { | ||
let level = adc.read(&mut p26).await.unwrap(); | ||
if level > 3800 { | ||
led.set_high(); | ||
} else { | ||
led.set_low(); | ||
} | ||
Timer::after_secs(1).await; | ||
} | ||
} | ||
``` | ||
|
||
|
||
## Clone the existing project | ||
You can clone (or refer) project I created and navigate to the `dracula-ldr` folder. | ||
|
||
```sh | ||
git clone https://github.com/ImplFerris/pico2-projects | ||
cd pico2-projects/dracula-ldr/ | ||
``` |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
## Setup | ||
|
||
## Hardware Requirements | ||
|
||
- **LED** – Any standard LED (choose your preferred color). | ||
- **LDR (Light Dependent Resistor)** – Used to detect light intensity. | ||
- **Resistors** | ||
- **300Ω** – For the LED to limit current and prevent damage. (You might have to choose based on your LED) | ||
- **10kΩ** – For the LDR, forming a voltage divider in the circuit. (You might have to choose based on your LDR) | ||
- **Jumper Wires** – For connecting components on a breadboard or microcontroller. | ||
|
||
|
||
## Circuit to connect LED, LDR with Pico | ||
|
||
<img style="display: block; margin: auto;" alt="pico2" src="./images/ldr-pico-led-circuit.jpg"/> | ||
|
||
### LDR (Light Dependent Resistor) Setup: | ||
1. **One side of the LDR** is connected to **AGND** (Analog Ground). | ||
2. The **other side of the LDR** is connected to **GPIO26 (ADC0)**, which is the analog input pin of the pico2 | ||
3. A **resistor** is placed between the LDR and **ADC_VREF** (the reference voltage for the analog-to-digital converter). | ||
- From the datasheet: "ADC_VREF is the ADC power supply (and reference) voltage, and is generated on Pico 2 by filtering the 3.3V supply. This pin can be used with an external reference if better ADC performance is required" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
## LDR | ||
|
||
We have already given an introduction to what an LDR is. Let me repeat it again: an LDR changes its resistance based on the amount of light falling on it. The brighter the light, the lower the resistance, and the dimmer the light, the higher the resistance. | ||
|
||
**Dracula**: Imagine the LDR like Dracula. In bright light, its power (resistance) decreases. In the dark, it becomes stronger (higher resistance). | ||
|
||
## Circuit | ||
|
||
I have created a voltage divider circuit with an LDR(the resistor symbol shows the light, in the form of arrows shining on it) in Falstad . You can import the circuit file I created, [`voltage-divider-ldr.circuitjs.txt`](./voltage-divider-ldr.circuitjs.txt), import into the [Falstad site](https://www.falstad.com/circuit/e-voltdivide.html) and play around. | ||
|
||
You can adjust the brightness value and observe how the resistance of R2 (which is the LDR) changes. Also, you can watch how the \\( V_{out} \\) voltage changes as you increase or decrease the brightness. | ||
|
||
|
||
### Example output for full brightness | ||
The resistance of the LDR is low when exposed to full brightness, causing the output voltage(\\( V_{out} \\)) to be significantly lower. | ||
|
||
<img style="display: block; margin: auto;" alt="pico2" src="./images/voltage-divider-ldr1.png"/> | ||
|
||
|
||
### Example output for low light | ||
With less light, the resistance of the LDR increases, and the output voltage increase. | ||
|
||
<img style="display: block; margin: auto;" alt="pico2" src="./images/voltage-divider-ldr2.png"/> | ||
|
||
### Example output for full darkness | ||
In darkness, the LDR's resistance is high, resulting in a higher output voltage (\\( V_{out} \\)). | ||
|
||
<img style="display: block; margin: auto;" alt="pico2" src="./images/voltage-divider-ldr3.png"/> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
$ 1 0.000005 10.20027730826997 63 10 62 5e-11 | ||
v 240 400 240 80 0 0 40 3.3 0 0 0.5 | ||
w 240 80 368 80 0 | ||
r 368 80 368 240 0 10000 | ||
w 240 400 368 400 0 | ||
O 368 240 432 240 1 0 | ||
x 378 144 393 147 4 12 R1 | ||
x 377 305 392 308 4 12 R2 | ||
x 199 219 227 222 4 14 3.3V | ||
x 209 201 223 204 4 10 Vin | ||
x 424 227 444 230 4 10 Vout | ||
374 368 240 368 400 0 0.0001 Light\sBrightness |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
$ 1 0.000005 10.20027730826997 63 10 62 5e-11 | ||
v 240 400 240 80 0 0 40 3.3 0 0 0.5 | ||
w 240 80 368 80 0 | ||
r 368 80 368 240 0 10000 | ||
w 240 400 368 400 0 | ||
O 368 240 432 240 1 0 | ||
x 378 144 393 147 4 12 R1 | ||
x 377 305 392 308 4 12 R2 | ||
r 368 400 368 240 0 10000 | ||
x 199 219 227 222 4 14 3.3V | ||
x 209 201 223 204 4 10 Vin | ||
x 424 227 444 230 4 10 Vout |
Oops, something went wrong.