PROJECTES 2023
NOTA: Hauràs de refer la indentació en el codi Python al copiar i pegar codi
ARDUINO+LDR+PYTHON
Per connectar Arduino a Mu editor i fer que llegeixi un LDR amb Python, segueix aquests passos:
- Connecta Arduino al teu ordinador amb un cable USB.
- Descarrega i instal·la el programari Arduino IDE al teu ordinador des de la seva pàgina oficial.
- Obre el programari Arduino IDE i selecciona la placa Arduino que estàs utilitzant i el port sèrie adequat.
- A continuació, carrega el codi següent al teu Arduino:
int ldrPin = A0;
int ldrValue = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
ldrValue = analogRead(ldrPin);
Serial.println(ldrValue);
delay(100);
}
Aquest codi llegeix el valor del LDR connectat al pin A0 de l’Arduino i el transmet a través del port sèrie amb una velocitat de 9600 bps.
- Obre el mu editor i crea un nou fitxer de Python.
- Escriu el codi següent per llegir el valor del LDR des de l’Arduino:
import serial
ser = serial.Serial('nom_del_port', 9600)
while True:
ldrValue = ser.readline().decode('utf-8').rstrip()
print(ldrValue)
Nota: Hauràs de canviar ‘nom_del_port’ pel nom del port sèrie que està utilitzant l’Arduino al teu ordinador. Pots trobar aquesta informació a l’Arduino IDE en la pestanya “Eines > Port sèrie”.
- Guarda el teu fitxer de Python i executa’l.
- Hauries de veure els valors del LDR que es llegeixen des de l’Arduino a la pantalla de la consola del mu editor.
VALORS I GRÀFICS
Per veure els valors i els gràfics tant en Arduino com amb Mu Editor, pots seguir aquests passos:
- Descarrega i instal·la el programari Arduino IDE al teu ordinador des de la seva pàgina oficial.
- Connecta el LDR al pin analògic A0 de l’Arduino.
- Obre el programari Arduino IDE i selecciona la placa Arduino que estàs utilitzant i el port sèrie adequat.
- Carrega el codi següent al teu Arduino:
int ldrPin = A0;
int ldrValue = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
ldrValue = analogRead(ldrPin);
Serial.println(ldrValue);
delay(100);
}
Aquest codi llegeix el valor del LDR connectat al pin A0 de l’Arduino i el transmet a través del port sèrie amb una velocitat de 9600 bps.
- Obre el Mu editor i crea un nou fitxer de Python.
- Escriu el codi següent per llegir el valor del LDR des de l’Arduino i visualitzar-lo en un gràfic:
import serial
import matplotlib.pyplot as plt
ser = serial.Serial('nom_del_port', 9600)
data = []
plt.ion() # Activa el mode interactiu de Matplotlib
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_ylim(0, 1023) # Estableix els límits dels eixos
while True:
ldrValue = ser.readline().decode('utf-8').rstrip()
data.append(int(ldrValue))
# Actualitza el gràfic
ax.clear()
ax.plot(data)
plt.draw()
plt.pause(0.0001)
Nota: Hauràs de canviar ‘nom_del_port’ pel nom del port sèrie que està utilitzant l’Arduino al teu ordinador. Pots trobar aquesta informació a l’Arduino IDE en la pestanya “Eines > Port sèrie”.
- Guarda el teu fitxer de Python i executa’l.
- Hauries de veure els valors del LDR que es llegeixen des de l’Arduino a la pantalla de la consola del Mu editor i en un gràfic que es va actualitzant en temps real.
INTERFICIE GRÀFICA
Per crear una interfície gràfica amb Tkinter per al teu codi anterior, pots seguir aquests passos:
- Importa el mòdul Tkinter i altres mòduls necessaris al teu fitxer de Python:
import serial
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
- Crea una finestra principal de Tkinter i establix el seu títol i mida:
root = tk.Tk()
root.title("LDR Reading")
root.geometry("800x600")
- Crea un subfinestra Tkinter per mostrar el gràfic de Matplotlib i establix les seves dimensions:
graph_frame = tk.Frame(root, width=600, height=400)
graph_frame.pack(side=tk.TOP, padx=10, pady=10)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_ylim(0, 1023) # Estableix els límits dels eixos
canvas = FigureCanvasTkAgg(fig, master=graph_frame)
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
- Crea un subfinestra Tkinter per mostrar els valors del LDR i establix les seves dimensions:
data_frame = tk.Frame(root, width=600, height=200)
data_frame.pack(side=tk.TOP, padx=10, pady=10)
value_label = tk.Label(data_frame, text="LDR Value:")
value_label.pack(side=tk.LEFT, padx=10, pady=10)
value_var = tk.StringVar()
value_var.set("N/A")
value_text = tk.Label(data_frame, textvariable=value_var)
value_text.pack(side=tk.LEFT, padx=10, pady=10)
- Defineix la funció principal que llegeix els valors del LDR i actualitza el gràfic i el valor de la finestra Tkinter:
def read_ldr():
ser = serial.Serial('nom_del_port', 9600)
data = []
while True:
ldrValue = ser.readline().decode('utf-8').rstrip()
data.append(int(ldrValue))
# Actualitza el gràfic
ax.clear()
ax.plot(data)
canvas.draw()
# Actualitza el valor de la finestra Tkinter
value_var.set(ldrValue)
root.update_idletasks()
- Crea un botó Tkinter per començar a llegir els valors del LDR:
start_button = tk.Button(root, text="Start Reading", command=read_ldr)
start_button.pack(side=tk.TOP, padx=10, pady=10)
- Executa la finestra principal de Tkinter:
root.mainloop()
Nota: Hauràs de canviar ‘nom_del_port’ pel nom del port sèrie que està utilitzant l’Arduino al teu ordinador. Pots trobar aquesta informació a l’Arduino IDE en la pestanya “Eines > Port sèrie”.
Això és tot! Has creat una interfície gràfica amb Tkinter per al teu codi anterior. Quan executis el teu fitxer de Python, hauries de veure el gràfic de Matplotlib actualitzant-se en temps real i el valor del LDR s’actualitza en una finestra Tkinter.
THEREMIN + MÚSICA EN PC
Per fer que el programa toqui una nota musical diferent depenent de la llum rebuda al LDR, pots seguir aquests passos:
- Defineix una llista de notes musicals, una per a cada possible valor del LDR. Per exemple:
notes = ['C4', 'D4', 'E4', 'F4', 'G4', 'A4', 'B4', 'C5']
- Defineix una funció per convertir el valor del LDR a un índex de la llista de notes. Pots fer-ho utilitzant la funció
round
per arrodonir el valor del LDR a l’enter més proper i la funciómin
per assegurar-te que l’índex no sigui més gran que la longitud de la llista de notes. Per exemple:
def ldr_to_index(ldr_value):
index = round(ldr_value / 128)
return min(index, len(notes) - 1)
- Defineix una funció per tocar una nota musical. Pots fer-ho utilitzant la llibreria
pyautogui
, que simula la pressió de tecles en el teclat de l’ordinador. Pots definir una funció que rebi un índex i simuli la pressió de la tecla corresponent a la nota musical en aquest índex. Per exemple:
import pyautogui
def play_note(index):
note = notes[index]
pyautogui.press(note.lower())
- Modifica la funció
read_ldr
per tocar la nota musical corresponent a cada valor del LDR. Pots cridar la funcióplay_note
amb l’índex calculat a partir del valor del LDR. Per exemple:
def read_ldr():
ser = serial.Serial('nom_del_port', 9600)
data = []
while True:
ldr_value = int(ser.readline().decode('utf-8').rstrip())
data.append(ldr_value)
# Actualitza el gràfic
ax.clear()
ax.plot(data)
canvas.draw()
# Actualitza el valor de la finestra Tkinter
value_var.set(ldr_value)
root.update_idletasks()
# Toca una nota musical
index = ldr_to_index(ldr_value)
play_note(index)
Això és tot! Ara el programa tocarà una nota musical diferent depenent de la llum rebuda al LDR. L’única cosa que has de fer és assegurar-te que la llista de notes notes
estigui sincronitzada amb les notes musicals disponibles en el teu sistema.
Comunicació entre Arduino, Mu editor i Arduino IDE
Per assegurar una comunicació correcta entre Arduino, Mu Editor i Arduino IDE, pots seguir aquests passos:
- Verifica que el teu Arduino estigui connectat correctament al teu ordinador i que la placa estigui seleccionada en el programa que vols utilitzar. Això és important perquè el port sèrie que s’utilitza per connectar-se a l’Arduino pot canviar de vegades en funció del programa que s’utilitza.
- Quan utilitzis Mu Editor, selecciona el port sèrie correcte. Pots fer-ho fent clic a l’icona de configuració a la barra d’eines i seleccionant la pestanya “Serial”. Aquí hauries de veure una llista de ports sèrie disponibles. Si no estàs segur de quin port sèrie s’utilitza, pots provar diferents ports fins que trobis el correcte.
- Verifica que la velocitat de transmissió de dades (baud rate) sigui la mateixa en tots els programes que utilitzis per connectar-te a l’Arduino. La velocitat de transmissió predeterminada per als Arduino és de 9600 bits per segon, però això pot variar segons la configuració de la teva placa.
- Si utilitzes Arduino IDE, verifica que la finestra del monitor sèrie estigui tancada quan utilitzis altres programes per connectar-te a l’Arduino. La finestra del monitor sèrie pot interferir amb altres programes que intenten connectar-se a l’Arduino.
- Si tens problemes per connectar-te a l’Arduino des de Mu Editor o Arduino IDE, pots provar a reiniciar el teu Arduino o el teu ordinador. Això pot ajudar a restablir la connexió.
- Si tot això no funciona, pots intentar actualitzar els controladors del teu Arduino o utilitzar un cable USB diferent per connectar-te a l’ordinador. També pots provar de canviar de port USB al teu ordinador per connectar-te a l’Arduino.
Seguint aquests passos, hauries de ser capaç de connectar-te a l’Arduino sense problemes des de Mu Editor i Arduino IDE.
GENERACIÓ DE NOTES MUSICALS
El codi anterior que genera notes musicals depenent de la llum rebuda pel LDR és una combinació de Python i Arduino.
En resum, el codi fa el següent:
- Estableix la connexió entre l’Arduino i el programa Python a través del port sèrie.
- Configura l’Arduino per llegir els valors del sensor de llum LDR i envia aquests valors al programa Python.
- Utilitza els valors del sensor de llum per determinar la freqüència de les notes musicals a reproduir.
- Envia les notes musicals a reproduir a l’Arduino a través del port sèrie.
- L’Arduino utilitza un altaveu connectat a la sortida digital per reproduir les notes musicals.
El codi utilitza la llibreria “pyserial” per establir la connexió sèrie entre Python i Arduino. També utilitza la llibreria “tkinter” per crear una interfície gràfica d’usuari (GUI).
A continuació, explicaré els detalls del codi, línia per línia:
import serial
import tkinter as tk
import time
Aquestes línies importen les llibreries necessàries per establir la connexió sèrie amb l’Arduino i crear una interfície gràfica d’usuari.
# Configuració del port sèrie
arduino_port = 'COM3'
baud_rate = 9600
ser = serial.Serial(arduino_port, baud_rate, timeout=1)
time.sleep(2)
Aquestes línies configuren el port sèrie per connectar-se a l’Arduino. L’arduino_port s’ha de configurar per ser el mateix port sèrie al qual està connectat l’Arduino al teu ordinador. El baud_rate s’ha de configurar per ser la mateixa velocitat de transmissió de dades que s’utilitza en l’Arduino (per defecte, 9600 bits per segon). La línia “time.sleep(2)” fa una petita pausa de 2 segons per assegurar-se que la connexió s’estableix correctament.
# Funció per calcular la freqüència de les notes musicals
def get_frequency(light_value):
min_light_value = 200
max_light_value = 800
min_frequency = 440
max_frequency = 1760
if light_value < min_light_value:
light_value = min_light_value
if light_value > max_light_value:
light_value = max_light_value
frequency = ((light_value - min_light_value) / (max_light_value - min_light_value)) * (max_frequency - min_frequency) + min_frequency
return int(frequency)
Aquesta funció rep un valor de llum i utilitza aquest valor per calcular la freqüència de la nota musical a generar. La freqüència de la nota es calcula a partir d’una escala predefinida que s’estableix en les variables min_light_value, max_light_value, min_frequency i max_frequency.
# Funció per enviar la freqüència de la nota musical a l'Arduino
def send_frequency(frequency):
ser.write(str(frequency).encode())
Així doncs, la funció “send_frequency” rep la freqüència de la nota musical calculada per la funció “get_frequency” i envia aquesta freqüència a l’Arduino a través del port sèrie. La freqüència s’ha de convertir a una cadena de caràcters (str) perquè es pugui enviar a través del port sèrie. La funció “encode” converteix la cadena de caràcters en bytes perquè es pugui transmetre a través del port sèrie.
# Funció per llegir les dades del sensor de llum LDR
def read_lightsensor():
ser.write(b'r')
arduinoData = ser.readline().decode().strip()
if arduinoData:
try:
light_value = int(arduinoData)
return light_value
except ValueError:
return None
else:
return None
Aquesta funció envia la comanda “r” a l’Arduino per sol·licitar les dades del sensor de llum LDR. L’Arduino ha de ser programat per llegir les dades del sensor de llum quan rep aquesta comanda. Les dades del sensor de llum s’envien des de l’Arduino al programa Python a través del port sèrie. El programa Python llegeix les dades enviades pel port sèrie i les converteix en un enter (int) que representa el valor de llum mesurat pel sensor de llum. Si hi ha algun error de comunicació, la funció retorna None.
# Funció per actualitzar la interfície gràfica
def update_gui():
light_value = read_lightsensor()
if light_value is not None:
frequency = get_frequency(light_value)
send_frequency(frequency)
canvas.itemconfig(note, text="Note: " + str(frequency) + " Hz")
canvas.itemconfig(value, text="Value: " + str(light_value))
root.after(100, update_gui)
Aquesta funció actualitza la interfície gràfica amb les dades del sensor de llum. Primer, crida a la funció “read_lightsensor” per llegir el valor del sensor de llum. Si el valor és vàlid (no és None), la funció crida a la funció “get_frequency” per calcular la freqüència de la nota musical. A continuació, crida a la funció “send_frequency” per enviar la freqüència de la nota musical a l’Arduino. Finalment, actualitza la interfície gràfica amb les dades del sensor de llum i la freqüència de la nota musical calculada.
# Configuració de la interfície gràfica
root = tk.Tk()
root.title("Arduino Light Sensor Music")
root.geometry("400x200")
canvas = tk.Canvas(root, width=400, height=200)
canvas.pack()
note = canvas.create_text(200, 50, text="Note: ", font=("Arial", 20))
value = canvas.create_text(200, 100, text="Value: ", font=("Arial", 20))
Aquestes línies configuren la interfície gràfica de l’aplicació utilitzant la llibreria “tkinter”. Es crea una finestra (root) amb el títol “Arduino Light
# Configuració de la interfície gràfica root = tk.Tk() root.title(“Arduino Light Sensor Music”) root.geometry(“400×200”) canvas = tk.Canvas(root, width=400, height=200) canvas.pack() note = canvas.create_text(200, 50, text=”Note: “, font=(“Arial”, 20)) value = canvas.create_text(200, 100, text=”Value: “, font=(“Arial”, 20)) Continua explicació..
Sensor Music” i les dimensions de 400×200 píxels. Es crea un “canvas” (lienzo) per dibuixar la interfície gràfica dins de la finestra i es defineixen dos textos “Note” i “Value” amb fonts de 20 punts. Els textos es situen a les coordenades (200,50) i (200,100), respectivament.
# Funció per actualitzar la interfície gràfica
def update_gui():
light_value = read_lightsensor()
if light_value is not None:
frequency = get_frequency(light_value)
send_frequency(frequency)
canvas.itemconfig(note, text="Note: " + str(frequency) + " Hz")
canvas.itemconfig(value, text="Value: " + str(light_value))
root.after(100, update_gui)
Aquesta és la funció que s’executa en bucle per actualitzar la interfície gràfica. Primer, es crida la funció “read_lightsensor” per llegir el valor del sensor de llum. Si el valor és vàlid (no és None), la funció crida la funció “get_frequency” per calcular la freqüència de la nota musical corresponent. A continuació, s’envia la freqüència a l’Arduino utilitzant la funció “send_frequency”. Finalment, es modifiquen els valors de text dels elements “note” i “value” del “canvas” amb les dades llegides.
# Configuració de la connexió sèrie amb l'Arduino
ser = serial.Serial('COM3', 9600, timeout=1)
# Inicialització de la interfície gràfica
update_gui()
root.mainloop()
# Tancament de la connexió sèrie amb l'Arduino
ser.close()
En aquesta secció s’inicialitza la connexió sèrie amb l’Arduino a través del port COM3 amb una velocitat de transmissió de 9600 bauds i un temps d’espera de 1 segon. A continuació, s’inicia la funció “update_gui” per actualitzar la interfície gràfica en bucle. Això fa que la funció “update_gui” s’executi cada 100ms. Finalment, s’executa el bucle principal de la interfície gràfica amb el mètode “mainloop” i, quan es tanca la finestra, es tanca també la connexió sèrie amb l’Arduino amb el mètode “close”.
Aquest programa utilitza una interfície gràfica per mostrar el valor llegit pel sensor de llum i per enviar la freqüència corresponent a l’Arduino, que genera una nota musical en funció del valor rebuig. També s’ha explicat com assegurar la comunicació entre l’Arduino, Mu Editor i Arduino IDE. Aquest programa pot ser una bona base per a altres projectes que utilitzin Arduino, sensors i interfícies gràfiques.