Skip to main content

embassy_rp_gl5528/
lib.rs

1// Copyright (C) 2026 Jorge Andre Castro
2// GPL-2.0-or-later
3//! # embassy-rp-gl5528
4//!
5//! Driver async `no_std` minimaliste pour la photorésistance **GL5528** (LDR)
6//! sur microcontrôleur RP2040 et RP235x, basé sur le framework [Embassy](https://embassy.dev).
7//!
8//! ## Description du composant
9//!
10//! La GL5528 est une photorésistance (LDR — *Light Dependent Resistor*) dont la
11//! résistance varie entre ~1 kΩ (forte lumière) et ~10 MΩ (obscurité totale).
12//! Elle est typiquement utilisée dans un diviseur de tension avec une résistance
13//! fixe (10 kΩ recommandée) pour convertir la variation de résistance en tension
14//! lisible par un ADC.
15//!
16//! ## Schéma de câblage
17//!
18//! ```text
19//! 3.3V
20//!  │
21//! [GL5528]
22//!  │
23//!  ├──── GP26 (ADC0)
24//!  │
25//! [R 10kΩ]
26//!  │
27//! GND
28//! ```
29//!
30//! La tension sur la broche ADC augmente avec la luminosité (la GL5528 devient
31//! moins résistante, le point milieu monte vers 3,3 V).
32//!
33//! ## Exemple d'utilisation
34//!
35//! ```rust,no_run
36//! #![no_std]
37//! #![no_main]
38//!
39//! use embassy_executor::Spawner;
40//! use embassy_rp::adc::{Adc, Channel, Config as AdcConfig};
41//! use embassy_rp::bind_interrupts;
42//! use embassy_rp::peripherals::ADC;
43//! use embassy_rp::adc::InterruptHandler;
44//! use embassy_rp_gl5528::Gl5528;
45//!
46//! bind_interrupts!(struct Irqs {
47//!     ADC_IRQ_FIFO => InterruptHandler;
48//! });
49//!
50//! #[embassy_executor::main]
51//! async fn main(_spawner: Spawner) {
52//!     let p = embassy_rp::init(Default::default());
53//!
54//!     let adc = Adc::new(p.ADC, Irqs, AdcConfig::default());
55//!     let channel = Channel::new_pin(p.PIN_26, embassy_rp::gpio::Pull::None);
56//!
57//!     let mut sensor = Gl5528::new(adc, channel);
58//!
59//!     loop {
60//!         let raw = sensor.read_raw().await;
61//!         // Valeur entre 0 (obscurité) et 4095 (pleine lumière sur 12 bits)
62//!         let _ = raw;
63//!     }
64//! }
65//! ```
66//!
67//! ## Calcul de luminosité
68//!
69//! La valeur brute ADC peut être convertie en tension (ex: 12 bits sur RP2040, 14 bits sur RP235x) ::
70//!
71//! ```text
72//! V = raw × 3.3 / MAX (4095 ou 16383)
73//! ```
74//!
75//! La résistance de la LDR s'en déduit (diviseur de tension, R_pull = 10 kΩ) :
76//!
77//! ```text
78//! R_ldr = R_pull × V / (3.3 - V)
79//! ```
80//!
81//! ## Caractéristiques
82//!
83//! | Paramètre              | Valeur                                |
84//! |------------------------|-------------------------------------- |
85//! | Tension d'alimentation | 3,3 V (RP2040 / RP235x)               |
86//! | Résolution ADC         | 12 bits (0–4095) et 14 bits sur RP235x|
87//! | Résistance lumière     | ~1 kΩ @ 10 lux                        |
88//! | Résistance obscurité   | ~1 MΩ minimum                         |
89//! | Résistance de tirage   | 10 kΩ recommandée                     |
90//!
91//! ## `no_std`
92//!
93//! Cette crate ne dépend pas de la bibliothèque standard et est conçue pour
94//! tourner sur des microcontrôleurs bare-metal avec le runtime Embassy.
95
96#![no_std]
97#![forbid(unsafe_code)]
98
99use embassy_rp::adc::{Adc, Async, Channel};
100
101/// Driver pour la photorésistance GL5528 via l'ADC du RP2040.
102///
103/// Ce driver encapsule un canal ADC Embassy et fournit une lecture asynchrone
104/// de la valeur brute du capteur.
105///
106/// # Exemple
107///
108/// ```rust,no_run
109/// # use embassy_rp::adc::{Adc, Channel};
110/// # use embassy_rp_gl5528::Gl5528;
111/// // Création du driver (adc et channel obtenus depuis les périphériques Embassy)
112/// // let mut sensor = Gl5528::new(adc, channel);
113/// // let raw: u16 = sensor.read_raw().await;
114/// ```
115pub struct Gl5528<'d> {
116    adc: Adc<'d, Async>,
117    channel: Channel<'d>,
118}
119
120impl<'d> Gl5528<'d> {
121    /// Crée une nouvelle instance du driver GL5528.
122    ///
123    /// # Arguments
124    ///
125    /// * `adc` — Périphérique ADC Embassy en mode asynchrone.
126    /// * `channel` — Canal ADC connecté à la broche de lecture de la GL5528.
127    ///
128    /// # Exemple
129    ///
130    /// ```rust,no_run
131    /// # use embassy_rp::adc::{Adc, Channel, Config as AdcConfig};
132    /// # use embassy_rp_gl5528::Gl5528;
133    /// // let adc = Adc::new(p.ADC, Irqs, AdcConfig::default());
134    /// // let channel = Channel::new_pin(p.PIN_26, embassy_rp::gpio::Pull::None);
135    /// // let sensor = Gl5528::new(adc, channel);
136    /// ```
137    #[inline]
138    pub fn new(adc: Adc<'d, Async>, channel: Channel<'d>) -> Self {
139        Self { adc, channel }
140    }
141
142    /// Lit la valeur brute du convertisseur ADC.
143    ///
144    /// Retourne la valeur brute lue (ex: `0..=4095` sur RP2040 ou `0..=16383` sur RP235x).
145    /// Une valeur élevée correspond à une forte luminosité.
146    ///
147    /// En cas d'erreur ADC, la valeur `0` est retournée.
148    ///
149    /// # Retour
150    ///
151    ///* u16 — Valeur ADC brute (le maximum dépend de la puce : 4095 ou 16383).
152    ///
153    /// # Exemple
154    ///
155    /// ```rust,no_run
156    /// # use embassy_rp_gl5528::Gl5528;
157    /// # async fn example(mut sensor: Gl5528<'_>) {
158    /// let raw: u16 = sensor.read_raw().await;
159    ///
160    /// // Conversion en tension (V)
161    /// let voltage = raw as f32 * 3.3 / 4095.0; // Utiliser 16383.0 sur RP235x
162    ///
163    /// // Conversion en résistance LDR (kΩ), avec R_pull = 10 kΩ
164    /// if voltage < 3.3 {
165    ///     // Si LDR est au 3.3V et R_pull (10k) au GND :
166    ///     let r_ldr = 10.0 * (3.3 - voltage) / voltage;
167    ///     let _ = r_ldr;
168    /// }
169    /// # }
170    /// ```
171
172    #[inline]
173    pub async fn read_raw(&mut self) -> u16 {
174        self.adc.read(&mut self.channel).await.unwrap_or(0)
175    }
176}