Nota
Ciao, benvenuto nella comunità SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts su Facebook! Approfondisci Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.
Perché unirsi?
Supporto esperto: Risolvi problemi post-vendita e sfide tecniche con l’aiuto della nostra comunità e del nostro team.
Impara e condividi: Scambia suggerimenti e tutorial per migliorare le tue competenze.
Anteprime esclusive: Ottieni accesso anticipato agli annunci di nuovi prodotti e anteprime.
Sconti speciali: Goditi sconti esclusivi sui nostri prodotti più recenti.
Promozioni e giveaway festivi: Partecipa a giveaway e promozioni durante le festività.
👉 Pronto a esplorare e creare con noi? Clicca [Qui] e unisciti oggi stesso!
3.1.5 Indicatore di Batteria (MCP3008)
Nota
A seconda della versione del kit, verifica se possiedi ADC0834 o MCP3008 e procedi con la sezione corrispondente.
Introduzione
In questo progetto, realizzeremo un dispositivo indicatore di batteria che può mostrare visivamente il livello della batteria sul LED Bargraph.
Avvertimento
Non utilizzare componenti della batteria che superino i 3,3 V per evitare sovraccarichi che potrebbero danneggiare il chip o il Raspberry Pi.
Componenti necessari
Per questo progetto, abbiamo bisogno dei seguenti componenti.
Schema elettrico
T-Board Name |
fisico |
wiringPi |
BCM |
SPICE0 |
Pin 24 |
10 |
8 |
SPIMOSI |
Pin 19 |
12 |
10 |
SPIMISO |
Pin 21 |
13 |
9 |
SPISCLK |
Pin 23 |
14 |
11 |
GPIO25 |
Pin 22 |
6 |
25 |
GPIO12 |
Pin 32 |
26 |
12 |
GPIO16 |
Pin 36 |
27 |
16 |
GPIO20 |
Pin 38 |
28 |
20 |
GPIO21 |
Pin 40 |
29 |
21 |
GPIO5 |
Pin 29 |
21 |
5 |
GPIO6 |
Pin 31 |
22 |
6 |
GPIO13 |
Pin 33 |
23 |
13 |
GPIO19 |
Pin 35 |
24 |
19 |
GPIO26 |
Pin 37 |
25 |
26 |
Procedure sperimentali
Passo 1: Montare il circuito.
Per utenti linguaggio C
Passo 2: Accedere alla cartella del codice.
cd ~/davinci-kit-for-raspberry-pi/c/3.1.5-2/
Passo 3: Compilare il codice.
gcc 3.1.5_BatteryIndicator.c -lwiringPi
Passo 4: Eseguire il file eseguibile.
sudo ./a.out
Dopo l’esecuzione del programma, collega separatamente un filo dal 3° pin di MCP3008 e un filo dal GND ai due poli della batteria. Potrai vedere il LED corrispondente sul LED Bargraph accendersi per mostrare il livello della batteria (intervallo di misurazione: 0-5V).
Nota
Se non funziona dopo l’esecuzione, o compare l’errore: «wiringPi.h: No such file or directory», fare riferimento a Installare e Verificare WiringPi.
Codice
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdio.h>
#define SPI_CHANNEL 0
#define SPI_SPEED 1000000 // 1MHz
#define VREF 3.3
int pins[10] = {6, 26, 27, 28, 29, 21, 22, 23, 24, 25};
int read_ADC(int channel)
{
if (channel < 0 || channel > 7) return -1;
unsigned char buffer[3];
buffer[0] = 1; // Start bit
buffer[1] = (8 + channel) << 4; // Single-ended mode
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int value = ((buffer[1] & 3) << 8) | buffer[2];
return value;
}
void LedBarGraph(int value) {
for (int i = 0; i < 10; i++) {
if (i < value)
digitalWrite(pins[i], HIGH);
else
digitalWrite(pins[i],LOW);
}
}
int main(void)
{
if (wiringPiSetup() == -1) {
printf("setup wiringPi failed!\n");
return 1;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("SPI setup failed!\n");
return 1;
}
for (int i = 0; i < 10; i++) {
pinMode(pins[i], OUTPUT);
digitalWrite(pins[i], HIGH);
}
while (1) {
int analogVal = read_ADC(0); // MCP3008 CH0
if (analogVal < 0) continue;
float voltage = analogVal * VREF / 1023.0;
int level = analogVal * 10 / 1024;
if (level > 10) level = 10;
LedBarGraph(level);
printf("ADC Value: %d\tVoltage: %.2f V\tLevel: %d\n", analogVal, voltage, level);
delay(200);
}
return 0;
}
Spiegazione del codice
int read_ADC(int channel)
{
if (channel < 0 || channel > 7) return -1;
unsigned char buffer[3];
buffer[0] = 1; // Start bit
buffer[1] = (8 + channel) << 4; // Modalità single-ended, CH0~CH7
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int value = ((buffer[1] & 3) << 8) | buffer[2]; // Combina il risultato a 10 bit
return value;
}
Questa funzione legge valori analogici dal chip MCP3008 tramite SPI.
Il parametro channel seleziona uno degli 8 ingressi analogici (CH0–CH7).
L’MCP3008 restituisce un valore digitale a 10 bit compreso tra 0 e 1023, che rappresenta la tensione analogica.
void LedBarGraph(int value) {
for (int i = 0; i < 10; i++) {
if (i < value)
digitalWrite(pins[i], HIGH); // Accende il LED (cablaggio attivo HIGH)
else
digitalWrite(pins[i], LOW); // Spegne il LED
}
}
Questa funzione controlla una barra LED a 10 segmenti. Ogni LED rappresenta 1/10 dell’intervallo di tensione. I LED vengono accesi in ordine fino al livello specificato.
Nota: Questa versione presuppone che gli anodi dei LED siano collegati ai GPIO e i catodi a GND (attivo HIGH).
int main(void)
{
if (wiringPiSetup() == -1) {
printf("setup wiringPi failed!\n");
return 1;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("SPI setup failed!\n");
return 1;
}
for (int i = 0; i < 10; i++) {
pinMode(pins[i], OUTPUT);
digitalWrite(pins[i], HIGH); // Inizializza tutti i LED su ON
}
while (1) {
int analogVal = read_ADC(0); // Legge la tensione su CH0
if (analogVal < 0) continue;
float voltage = analogVal * VREF / 1023.0;
int level = analogVal * 10 / 1024; // Mappa a livelli 0–10
if (level > 10) level = 10;
LedBarGraph(level); // Mostra il livello sui LED
printf("ADC Value: %d\tVoltage: %.2f V\tLevel: %d\n", analogVal, voltage, level);
delay(200); // Frequenza di aggiornamento: 5 Hz
}
return 0;
}
Logica principale del programma:
Inizializza wiringPi e la comunicazione SPI.
Imposta i pin GPIO come uscite per controllare la barra LED a 10 segmenti.
Legge continuamente la tensione analogica tramite MCP3008 (CH0).
Converte la lettura in tensione usando
VREF = 3.3V.Scala la tensione su un livello da 0 a 10 e accende i LED corrispondenti.
Mostra il valore ADC grezzo, la tensione (in volt) e il livello LED sulla console seriale.
Questo progetto funge da indicatore visivo del livello di batteria o da voltmetro analogico.
Per utenti linguaggio Python
Passo 2: Configurare l’interfaccia SPI e installare la libreria spidev (vedere Configurazione SPI per le istruzioni dettagliate). Se hai già completato questi passaggi, puoi saltarli.
Passo 3: Accedere alla cartella del codice.
cd ~/davinci-kit-for-raspberry-pi/python
Passo 4: Eseguire il file.
sudo python3 3.1.5-2_BatteryIndicator.py
Dopo l’esecuzione del programma, collega separatamente un filo dal 3° pin di ADC0834 e un filo dal GND ai due poli della batteria. Potrai vedere il LED corrispondente sul LED Bargraph accendersi per mostrare il livello della batteria (intervallo di misurazione: 0-5V).
Avvertimento
Se appare l’errore RuntimeError: Cannot determine SOC peripheral base address, fare riferimento a Se gpiozero non funziona.
Codice
Nota
Puoi Modificare/Reimpostare/Copiare/Eseguire/Interrompere il codice qui sotto. Ma prima, devi andare nel percorso del codice sorgente come davinci-kit-for-raspberry-pi/python. Dopo aver modificato il codice, puoi eseguirlo direttamente per vedere l’effetto.
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
# GPIO pins connected to 10 LEDs, ordered from left to right
led_pins = [25, 12, 16, 20, 21, 5, 6, 13, 19, 26] # BCM numbering
# GPIO setup
GPIO.setmode(GPIO.BCM)
for pin in led_pins:
GPIO.setup(pin, GPIO.OUT)
GPIO.output(pin, GPIO.LOW)
# Initialize SPI
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CE0
spi.max_speed_hz = 1000000 # 1 MHz
# Read value from MCP3008 channel
def read_adc(channel):
if channel < 0 or channel > 7:
return -1
r = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((r[1] & 0x03) << 8) | r[2]
return value
# Light up LED bar graph according to value
def led_bar_graph(level):
for i, pin in enumerate(led_pins):
if i < level:
GPIO.output(pin, GPIO.HIGH)
else:
GPIO.output(pin, GPIO.LOW)
# Main loop
try:
while True:
analog_val = read_adc(0) # Read from MCP3008 channel 0
level = int(analog_val * 10 / 1023)
led_bar_graph(level)
print(f"ADC: {analog_val}, Level: {level}")
time.sleep(0.2)
except KeyboardInterrupt:
pass
finally:
for pin in led_pins:
GPIO.output(pin, GPIO.LOW)
GPIO.cleanup()
spi.close()
Spiegazione del codice
Questo programma legge la tensione analogica da un MCP3008 ADC e mostra il risultato su un LED Bargraph a 10 LED utilizzando un Raspberry Pi (layout pin BCM).
Importazione moduli
RPi.GPIOcontrolla i pin GPIO del Raspberry Pi.spidevcomunica con MCP3008 tramite SPI.timefornisce funzionalità di ritardo/pausa.
#!/usr/bin/env python3 import RPi.GPIO as GPIO import spidev import time
Configurazione GPIO per i LED
Viene definita una lista di 10 pin GPIO per il controllo dei LED. Questi pin sono configurati come uscita e inizializzati a LOW (spenti).
# GPIO pins connected to 10 LEDs, ordered from left to right led_pins = [25, 12, 16, 20, 21, 5, 6, 13, 19, 26] # BCM numbering GPIO.setmode(GPIO.BCM) for pin in led_pins: GPIO.setup(pin, GPIO.OUT) GPIO.output(pin, GPIO.LOW)
Inizializzazione SPI
Inizializza il bus SPI 0 e il chip enable 0 (CE0) per comunicare con MCP3008. La velocità di comunicazione è impostata a 1 MHz.
spi = spidev.SpiDev() spi.open(0, 0) # Bus 0, CE0 spi.max_speed_hz = 1000000 # 1 MHz
Funzione di lettura ADC
Legge un valore analogico da un canale specificato di MCP3008 (0–7). La funzione invia un comando SPI di 3 byte e decodifica il risultato a 10 bit.
def read_adc(channel): if channel < 0 or channel > 7: return -1 r = spi.xfer2([1, (8 + channel) << 4, 0]) value = ((r[1] & 0x03) << 8) | r[2] return value
Funzione LED Bar Graph
Accende i LED in base al livello analogico. Se il livello è 7, i primi 7 LED saranno accesi e i restanti spenti.
def led_bar_graph(level): for i, pin in enumerate(led_pins): if i < level: GPIO.output(pin, GPIO.HIGH) else: GPIO.output(pin, GPIO.LOW)
Ciclo principale
Legge continuamente l’ingresso analogico dal canale 0, scala il risultato a un valore da 0 a 10 e aggiorna il display LED di conseguenza. Stampa i valori ADC e di livello per il monitoraggio.
try: while True: analog_val = read_adc(0) level = int(analog_val * 10 / 1023) led_bar_graph(level) print(f"ADC: {analog_val}, Level: {level}") time.sleep(0.2)
Pulizia all’uscita
Quando si preme
Ctrl+C, il programma spegne tutti i LED, ripristina lo stato dei GPIO e chiude l’interfaccia SPI.except KeyboardInterrupt: pass finally: for pin in led_pins: GPIO.output(pin, GPIO.LOW) GPIO.cleanup() spi.close()