'''Simulare in Wokwi l’acquisizione di un segnale analogico generato da un
fotoresistore e visualizzarne l’andamento in tempo reale su un display OLED
•Fornire in uscita i valori in uscita tramite UART usando la funzione print()
2. Processare il segnale acquisito con un filtro a media mobile di lunghezza L:
y(n)=1/L(x(n)+x(n-1)+x(n-2)+...+x(n-L+1))
• Suggerimento: Utilizzare i seguenti metodi:
.append(v) per aggiungere un valore v ad una lista
.pop(i) per rimuovere l’ i-esimo valore da una lista'''
from machine import Pin, I2C, ADC
from time import sleep_us, ticks_us
import ssd1306
i2c=I2C(0)
display=ssd1306.SSD1306_I2C(128, 64, i2c)
#Il fotoresistore ha due pin, uno di digital output (DO) e l'altro di analog output (AO)
#l'ingresso all'ADC deve essere un segnale analogico, quindi usiamo il pin AO
ldr=ADC(25) #ldr sta per Light Dependent Resistor
ldr.atten(ADC.ATTN_11DB)
fc=128 #f campinamento
y_prec_i=10
y_prec_u=40
x=0
lista=[] #creazione di una lista vuota
lista_i=[] #lista per accumulare i valori dell'ingresso
L=5 #lunghezza del filtro, cioè numero di campioni
while True:
start=ticks_us() #tempo in microsecondi
ingresso=ldr.read() #lettura della tensione
lista.append(ingresso)
if len(lista)>L: #numero di campioni sufficiente
lista.pop(0) #eleminiamo dalla lista il primo campione
#Il segnale in uscita dal filtro con lunghezza L è dato
#dalla media sugli ultimi L campioni, quindi:
uscita=round(sum(lista)/len(lista))
#PLOT REAL TIME SUL DISPLAY DI ENTRAMBI I SEGNALI
#dobbiamo decidere a quale altezza rappresentarli, mettiamo
#l'ingresso sopra a distanza di 10 pixel dall'alto del display,
#l'uscita sotto a distanza di 40 pixel dall'alto del display
#(posizione verticale di partenza)
pixel_i=ingresso*25
pixel_u=uscita*25
y_i=round(10+pixel_i/4095)
y_u=round(40+pixel_u/4095)
#4095--> risoluzione dell'ADC, normalizziamo i valori perché
#provengono direttamente dall'ADC
#Visto che il display.show() provoca dei ritardi, per plottare
#i segnali sul display è meglio farlo dopo aver accumulato tot valori
lista_i.append(y_i)
display.line(x, y_prec_i, x+1, y_i, 1)
display.line(x, y_prec_u, x+1, y_u, 1)
#Aggiornamento dei valori di x e y per muoversi sul display
y_prec_i=y_i
y_prec_u=y_u
x=x+1
if len(lista_i)%10==0: #controllo sull'accumulo dei valori
display.show() #il display viene aggiornato
#ogni volta che sono stati accumulati 10 nuovi valori nella lista
#così però si può finire fuori dal display, quindi controlliamo che
if x==128: #ritorniamo all'inizio del display
x=0
count=1
display.fill(0)
# Stampa dei valori su UART
print(ingresso)
end=ticks_us()
t=end-start #ritardo
sleep_us(round(1e6/fc) - (end-start) -120)