Kurs i koding - Hadeland VGS
Innhold
Pythonskole.no/koder
Noen utvalgte koder finnes i kodebiblioteket til Pythonskole.no. Se gjerne om du finner du vil utfordre deg selv på eller teste i dag,
Annengradslikning
PASCO
Her kommet et lite utvalg av koder som bruker PASCO sine (hvite) trådløse sensorer til å logge data, rett inn i din Python-kode. Dette gir stor frihet i å bearbeide og analysere dataene du måler, med teknikker og metoder som du og elevene kan skrive selv. Detaljert dokumentasjon på PASCO sitt Python bibliotek finnes på PyPi.org: https://pypi.org/project/pasco/.
Siden disse kodene er avhengig av å bruke PC’ens blåtann-grensesnitt, er det ikke mulig å kjøre disse fra nettleseren. Kodene er kun gjengitt her så du kan laste ned/kopiere koden til din egen maskin, og kjøre de derfra. Alle kodene er testet og kjørt i Thonny. Husk før du starter at du også må installere følgende bibliotek:
- matplotlib
- numpy
- pasco
Du kan også installere disse bibliotekene med ‘pip’ om du har tilgang til et terminalvindu i ditt Python utviklermiljø (f.eks. Anaconda, Spyder, etc).
pip install numpy matplotlib pasco
OBS Første stabile versjon av PASCO-biblioteket er ikke annonsert helt enda, men den kommer nok i løpet av 2022. Koden er dog testet og funger med få eller sjelden feil.
pasco-read.py
# pasco-read.py
# Skrevet av Vegard Rekaa 27.1.2022
# kontakt@pythonskole.no
from pasco.pasco_ble_device import PASCOBLEDevice
device = PASCOBLEDevice()
device_id = '900-209'
data = 'Illuminance'
device.connect_by_id(device_id) #Endre ID til din sensor
enhet = device.get_measurement_unit(data)
for i in range(0,100):
verdi = device.read_data(data)
print(str(verdi)+enhet)
device.disconnect()
pasco-liveplotting.py
#LIVE PLOTTING WITH PASCO PYTHON MODULE
#CONTACT: kontakt@pythonskole.no
#Version 26.1.2022
##############################################################
#Edit this section:
##############################################################
device_id = '469-773' # Change to you sensor
data = 'Accelerationx' # What do you want to measure?
measure_time = 15.0 #Say how many seconds you want to measure
ymin = 0.0 #What max/min y-values do you expect
ymax = 31.0
max_iterations = 200 #At how many iterations do you wish to abort?
#################################################################
################ EDIT THIS AT YOUR OWN RISK ####################
#################################################################
#Import libraries
#Documentation pasco: https://pypi.org/project/pasco/
import sys
import csv
import numpy as np
from time import time
import matplotlib.pyplot as plt
from matplotlib import animation
from pasco.pasco_ble_device import PASCOBLEDevice
live_animation = True
#Create a code element, through which we can handle the instrument
device = PASCOBLEDevice()
if len(device.scan())==0:
print("No sensors found!")
sys.exit(0)
device.connect_by_id(device_id)
if not device.is_connected():
print("Connection failed")
exit(0)
#Prevent the device to disconnect after 5 minutes
device.keepalive()
#Setup data storage and plotting parameters
fps = 10.0
t_start = time()
xdata = []
ydata = []
#Set up figure, axis and plot element
fig = plt.figure()
ax = plt.axes()
line, = ax.plot([], [])
plt.title(data)
plt.ylabel(data)
plt.xlabel('Tid (s)')
ax.set_xlim([0,measure_time])
ax.set_ylim([ymin,ymax])
# initialization function: plot the background
def init():
line.set_data([],[])
return line,
# animation function. This is called sequentially
def animate(i):
verdi = device.read_data(data)
tid = time()-t_start
fps = i/tid
xdata.append(tid)
ydata.append(verdi)
line.set_data(xdata,ydata)
print("Frame:{0:3d} Tid:{1:6.2f}s fps={2:4.1f}".\
format(i,tid,i/tid),end='\r')
return line,
def animate_save(i):
tid = xdata[i]
line.set_data(xdata[0:i],ydata[0:i])
print("Frame:{0:3d}".format(i),end='\r')
return line,
# call the animator.
if live_animation:
print("")
print("Animating plot")
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=max_iterations, interval=1, blit=True, repeat=False)
plt.show()
else:
print("")
print("Reading and saving data (NO ANIMATION)")
for i in range(max_iterations):
verdi = device.read_data(data)
tid = time()-t_start
fps = i/tid
xdata.append(tid)
ydata.append(verdi)
print("Frame:{0:3d} Tid:{1:6.2f}s fps={2:4.1f}".\
format(i,tid,i/tid),end='\r')
#### SAVE TO VIDEO FILES (mp4 and gif) AND DATA FILE (csv)
Nframes = len(xdata)
fps_save = fps
giffile = data+'.gif'
mp4file = data+'.mp4'
csvfile = data+'.csv'
video = animation.FuncAnimation(fig, animate_save, init_func=init,
frames=Nframes, save_count=Nframes,
interval=1, blit=True, repeat=False)
print("")
print("Saving video to "+giffile)
writergif = animation.PillowWriter(fps=fps_save)
video.save(giffile, writer=writergif)
#print("")
#print("Saving video to "+mp4file)
#writervideo = animation.FFMpegWriter(fps=fps_save)
#video.save(mp4file,writer=writervideo)
device.disconnect()
#Sometimes, the first data value is None. Replace it
print("")
print("Saving data to "+csvfile)
with open(csvfile, 'w', encoding="UTF8", newline='') as f:
writer = csv.writer(f)
writer.writerow(["Tid",data])
writer.writerows(np.array([xdata,ydata]).T.tolist())
print("Done!")
pasco-read.py
# pasco-read.py
# Skrevet av Vegard Rekaa 27.1.2022
# kontakt@pythonskole.no
from pasco.pasco_ble_device import PASCOBLEDevice
device = PASCOBLEDevice()
device_id = '900-209'
data = 'Illuminance'
device.connect_by_id(device_id) #Endre ID til din sensor
enhet = device.get_measurement_unit(data)
for i in range(0,100):
verdi = device.read_data(data)
print(str(verdi)+enhet)
device.disconnect()
pasco-devices.py
# pasco-device.py
# Looks for Pasco devices and prints their available
# sensors and measurments. Then disconnects.
# Written by Vegard Rekaa 2021, kontakt@pythonskole.no
# Updated January 2022
#
# Documentation on pasco libraries: https://pypi.org/project/pasco/
from sys import exit
from pasco.pasco_ble_device import PASCOBLEDevice
# Create a code element, through which we can handle the instrument
device = PASCOBLEDevice()
# List all devices
device_list = device.scan()
if len(device_list) == 0:
#Leace program if no devices are found
print("No device found")
exit(0)
# Print the list of devices
for i, dev in enumerate(device_list):
print("["+str(i+1)+"] "+str(dev))
# Get user input which device you want.
# If there is only one, select that device automatically
select = input('Select a device: ') if len(device_list) > 1 else 0
select_device = device_list[int(select)-1]
#Print the name and ID of the selected device, and connect
print("Connecting to:"+str(select_device))
device.connect(select_device)
#Leave code if connection failed
if not device.is_connected():
print("Connection failed")
exit(0)
#Print list of sensors on connected device
print("Sensor list:", device.get_sensor_list())
#Print list of measurments available from the connected device
print("Measurement list:", device.get_measurement_list())
for data in device.get_measurement_list():
print(" - ",data)
#Clean disconnect.
device.disconnect()
pasco-temperature-live.py
#CODE: pasco-temperature-live.py
#Version: 26.1.2022
#Author: Vegard Rekaa, Pythonskole.no
#kontakt@pythonskole.no
import sys
from time import time
from numpy import polyfit
from pasco.pasco_ble_device import PASCOBLEDevice
from matplotlib import animation
import matplotlib.pyplot as plt
device_id = '508-699' #Change ID to your sensor
data_type = 'Temperature'
#set up the experiment
xmin = 0
xmax = 120.0
ymin = 10.0
ymax = 50.0
interval = 2000 #ms between each measurment
#Keep these as they are
tid = 0.0
tid_start = time()
max_iterations = int((xmax-xmin)/(interval/1000))
xdata = []
y1data = []
y2data = []
def curvefit():
#Second order polynomial curve fit
if len(xdata) < 3:
a,b,c = 0.0,0.0,0.0
else:
a,b,c = polyfit(xdata,y1data,2)
return [a*x*x + b*x + c for x in xdata]
#Fourth order polynomial curve fit
#if len(xdata) < 5:
# a,b,c,d,e = 0.0,0.0,0.0,0.0,0.0
#else:
# a,b,c,d,e = polyfit(xdata,y1data,4)
#return [a*x**4 + b*x**3 + c*x**2 + d*x + e for x in xdata]
############################################
### EVERYTHING BELOW HERE IS VOODO MAGIC ###
### READ AT YOUR OWN RISK ###
### (you might learn something new) ###
############################################
# Documentation: https://pypi.org/project/pasco/
#Connect to the PASCO device.
device = PASCOBLEDevice()
if len(device.scan())==0:
print("Can not find any sensors")
sys.exit(0)
device.connect_by_id(device_id):
#Set up figure, axis and plot element
fig = plt.figure()
ax = plt.axes()
ax.set_xlim([xmin,xmax])
ax.set_ylim([ymin,ymax])
plt.xlabel("Tid (s)")
plt.ylabel("Temperatur (C)")
labels = ['Data','Curve fit']
colors = ["blue","red"]
linestyles = ['dotted','solid']
markers = ['.','']
#Set up initial line elements
lines = []
for index in range(2):
lobj = ax.plot([],[],linewidth=1,label=labels[index],color=colors[index],
linestyle=linestyles[index],marker=markers[index])[0]
lines.append(lobj)
# initialization function: plot the background
def init():
for line in lines:
line.set_data([],[])
plt.legend()
return lines
# animation function. This is called sequentially
def animate(i):
tid = time()-tid_start
print("Frame:{0:3d} Tid:{1:6.2f}s fps={2:4.1f}".\
format(i,tid,i/tid),end='\r')
xdata.append(tid)
y1data.append(device.read_data(data_type))
y2data = curvefit()
lines[0].set_data(xdata,y1data)
lines[1].set_data(xdata,y2data)
return lines
# call the animator (this is voodo magic)
print("Max iterations:",max_iterations)
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=max_iterations, interval=interval, repeat=False)
plt.show()
device.disconnect()
pasco-temperature-newton-live.py
#CODE: pasco-temperature-newton.py
#Version: 20.10.2021
#Author: Vegard Rekaa, Pythonskole.no
#kontakt@pythonskole.no
# Documentation: https://pypi.org/project/pasco/
from pasco.pasco_ble_device import PASCOBLEDevice
#from pasco.code_node_device import CodeNodeDevice
#from pasco.character_library import Icons
import matplotlib.pyplot as plt
import numpy as np
import time
selected_device = None
device = PASCOBLEDevice()
available_devices = device.scan()
n = len(available_devices)
print("Found ",n," devices")
for dev in available_devices:
if 'Temperature' in str(dev):
selected_device = dev
if selected_device == None:
print("No device found")
exit(0)
device.connect(selected_device)
if not device.is_connected():
print("Connection FAILED: "+selected_device)
exit(0)
device.keepalive()
#Prepare measurments
tid_start = time.time()
tid = 0
tid_previous = tid
temp = float(device.read_data('Temperature'))
temp_start = temp
temp_sim = temp
temp_room = 25.0
k = 0.02
#Create storage arrays
tid_array = np.array([])
temp_array = np.array([])
temp_sim_array = np.array([])
print("Starting experiment")
print("Time(s) Temp(data) Temp(sim)")
print("{0:8.2f} {1:8.2f} {2:8.2f}".format(tid,temp,temp_sim))
while(tid < 1*60.0):
#Measure temperature
temp = float(device.read_data('Temperature'))
tid = time.time()-tid_start
#Simulate temperature
dt = tid-tid_previous
#print(k,temp_sim,temp_room,dt)
temp_sim = temp_sim - k*(temp_sim-temp_room)*dt
# Save values in arrays
tid_array = np.append(tid_array,[tid])
temp_array = np.append(temp_array,[temp])
temp_sim_array = np.append(temp_sim_array,[temp_sim])
#Output / Prepare next iteration
print("{0:8.2f} {1:8.2f} {2:8.2f}".format(tid,temp,temp_sim))
tid_previous = tid
time.sleep(1)
device.disconnect()
print("Experiment finished")
plt.plot(tid_array,temp_array,'bo-')
plt.plot(tid_array,temp_sim_array,'ro-')
plt.legend(["Data","Sim"])
plt.ylabel("Temp (C)")
plt.xlabel("Tid (s)")
plt.show()