• No results found

3.2 De digitala sensorerna

3.2.4 Läsning av Digilent PmodMIC3

Mikrofonens Vcc ansluts till raspberryns 3V3 samt GND till GND. Resterande anslutningspinnar MISO, SCL och SS tillhör enhetens SPI-gränssnitt och ansluts

3.2. DE DIGITALA SENSORERNA 29 därav till raspberryns GPIO 9, 11 och 7 vilket gör den till SPI-slav 1. Kopplingar- na illustreras i figur 3.3

Figur 3.4:Kopplingsschema för mikrofonen Digilent PmodMIC3

Eftersom kommunikationen med denna enhet är envägs behövs det bara att göra en läsning ifrån enheten om 2 bytes för att överföra mätdatan. I övrigt är kommunikationen snarlik den för a/d-omvandlaren. Proceduren har förenklats med funktionenread_mic() vars definition syns i kodstycket nedan.

import pigpio pi = pigpio.pi()

# Open bus on slave 1, 48KHz, SPI-unit 0 mic = pi.spi_open(1,48000,0)

def read_mic():

# Read 2 bytes from databus (count,buf) = pi.spi_read(mic,2)

# Data returns as offset of half maximum value with MSByte first and LSByte last

sample = 2048.0 -((buf[0]<< 8) + buf[1])

return sample

Då mätdatan anländer uppdelad i form av 2 bytes som representerar en offset ifrån dess mittenvärde konverteras värdet genom att högerskiftabuf[0] 8 steg, ad-

dera medbuf[1] och sist subtrahera resultatet ifrån hälften av maxvärdet för 12

bitar 4096.

Ett enda ljudsample säger dock inte så mycket då lufttryck fluktuerar väldigt mycket. Istället tas en serie samples och ett medelvärde skapas utifrån deras ab- solutbelopp. Denna metod ger ett värde som motsvarar en ungefärlig enhetslös ljudnivå, men möjligheten finns att vidareutveckla denna funktion till att fånga in riktigt ljud för vidare analysering.

3.2.5

Bildtagning

Kameran Raspberry Pi Camera Module V2.1 kopplas in på raspberryns dedike- rade anslutningsport och bilder tas sedan genom att kalla på scriptet camera.sh vars innehåll ser ut som nedan.

DATE=$(date +"%Y-%m-%d_%H-%M-%S")

sudo raspistill --timeout 1 --mode 0 --nopreview -awb auto --exposure auto -o /home/pi/citisense/logs/$DATE.jpg

I scriptet kollas först datumet som OS’et rapporterar och sparar detta i en variabel på formatet år-månad-dag_timme-minut-sekund. Sedan tas bilden genom att kal- la påraspistill med inparametrar för automatisk vitbalans, exponering och upp-

lösning, 1 sekunds tidsutlösning, inget förhandsvisningsfönster och sparplats/ho- me/pi/citisense/logs/ med ett filnamn som motsvarar dagens datum och tid.

3.3

Anemometerkonstruktion

En vindsnurra modellerades i 6 olika delar i programmet 3DS Max 2019 student. Den exporterades sedan till en utskrivbar .STL-fil som sedan användes för att skriva ut med Linköpings Universitets 3D-skrivare.

Modellen skruvades sedan ihop och limmades fast på DC-motorns motorpinne. Motorns positiva pol kopplas sedan till kanal 1 på a/d-omvandlaren, och den negativa polen till systemets ground.

För att utsignalen ifrån motorn ska få en jämnare och mätbar signal lades en parallell kapacitans på 1µF till. Ytterligare en 1kΩ resistor lades till i serie mellan DC-motorn och a/d-omvandlaren för att skydda mot överspänningar.

3.4

Trådlös nätverkspunkt

För att raspberryn ska agera som värd för en trådlös nätverkspunkt används två tjänster, dnsmasq och hostapd.

Tjänsterna installeras först på enheten, detta görs med kommandot $ sudo apt-get install dnsmasq hostapd

vilket använder raspberryns pakethanterare för att självmant installera de två paketen.

Vidare modifieras inställningsfilerna för tjänsterna.

Till att börja med blockeras OS’et ifrån att använda internetmodulerna. Detta görs genom att i filen/etc/dhcpcd.conf lägga till följande rad i slutet:

denyinterfaces eth0 denyinterfaces wlan0

Efter det modifieras filen/etc/dnsmasq.conf till att enbart innehålla raderna

interface=wlan0

3.4. TRÅDLÖS NÄTVERKSPUNKT 31 vilket gör att klienter som ansluter till nätverket tilldelas ip-adresser i omfång- et 192.168.0.(2-22) under 24 timmar, vilket motsvarar 20 anslutna enheter som maximum.

Sedan skapas en inställningsfil för hostapd. Dess innehåll lyder interface=wlan0 # the interface used by the AP

driver = nl80211 # Use this driver hw_mode=g # 2.4GHz-band

channel=7 # Channel 7 of the 2.4GHz spectrum ieee80211n=1 # 802.11n support

ssid=Citisense # the name of the AP auth_algs=1 # 1=wpa, 2=wep, 3=both wpa=0 # No password

ignore_broadcast_ssid = 0 # Make wifi discoverable

och valdes för att stödja fler enheter till kostnad av prestanda då datan som ska överföras är relativt liten. Filen sparas i/etc/hostapd/hostapd.conf och för att tjäns-

ten ska hitta konfigurationsfilen läggs sökvägen till i filen/etc/default/hostapd ef-

ter raden#DAMON_CONF så dess rad istället ser ut som DAEMON_CONF="/etc/hostapd/hostapd.conf".

Sista inställningarna som görs är i filen /etc/network/interfaces där följande

stycke adderas i slutet av filen: allow-hotplug wlan0 iface wlan inet static address 192.168.0.1 netmask 255.255.255.0 network 192.168.0.0 broadcast 192.168.0.255

Detta ser till att en statisk ip-adress för raspberryn kopplad till det trådlösa nät- verket sätts och tillåter att servicen hostapd tillåts åtkomst till wifi-modulen.

Efter det startas systemet om och det trådlösa nätverket Citisense finns att

ansluta till. För att när som helst stänga av eller på det trådlösa nätverket används metodiken i kodstycket nedan.

# Turn off ap

sudo service hostapd stop sleep(1)

# Turn off wifi entirely sudo ifdown wlan0

# Turn on wifi sudo ifup wlan0 # Turn on ap

sudo service hostapd start # Let module boot for 4s sleep(4)

# Restart ap-service twice sudo service hostapd restart sleep(2)

sudo service hostapd restart

Denna funktionalitet används tillsammans med Bluetooth för att spara energi. Att överföra mätdatan testas sedan med en minimal flask-applikation vars källkod återfinns i appendix A.11. När denna körs kan en enhet ansluten till det trådlösa nätverket skriva adressen 192.168.0.1 i i adressfältet i en vanlig webblä- sare och all mätdata dyker upp formaterat.

3.5

Blåtandsöverföring

Bluetooth har i projektet flera användningar. Att överföra loggdatan på ett smi- digare och energieffektivare vis, men den kan också användas för att starta och stänga av den mer energikonsumerande trådlösa-nätverkspunkten. Först görs ett antal konfigurationer på modulen. Dessa konfigurationer måste göras varje gång raspberryn startar så de läggs in i startscriptetapplauncher.sh som sådan:

# Name

sudo hciconfig hci0 name ’Citisense’ # No verification

sudo hciconfig hci0 noauth # Add Serial Profile sudo sdptool add SP # Make discoverable

sudo hciconfig hci0 piscan

Konfigurationerna ger enheten Bluetoothnamnet Citisense, gör den upptäckbar

och parbar utan verifikation på raspberryn, samt lägger till en profil för seriell överföring.

För att den seriella profilen ska kunna användas måste även Bluetooth-service- n startas i kompatibilitetsläge. Detta görs genom att addera flaggan -C efter raden

ExecStart=/usr/lib/bluetooth/bluetoothd i servicens konfigurationsfil som återfinns

i/etc/systemd/system/dbus-org.bluez.service. Filen borde således innehålla raden

ExecStart=/usr/lib/bluetooth/bluetoothd -C

för att Bluetooth-servicen ska köras i kompitabilitetsläge och tillåta en seriell da- taöverföringsprofil.

För att sedan överföra information seriellt via Bluetooth initieras först en Blue- toothSocket att utföra kommunikationsoperationer på. Denna sätts sedan till att lystna efter och acceptera en anslutning ifrån en annan enhet. Detta görs med följande kodstycke:

3.6. DATALOGGNING 33

# Import the BT library

from bluetooth import *

# Create a socket using the RFCOMM protocoll for transfers pisocket = BluetoothSocket( RFCOMM )

# Associate socket with a dataport pisocket.bind(("", PORT_ANY)) # Listen for 1 client

pisocket.listen(1)

# Await, and accept 1 client connection client_socket,adr = pisocket.accept()

Efter etablerad anslutning inväntas en instruktion ifrån den anslutna enheten och tas emot som en enda byte. Vad som kan göras är att stänga av/på den trådlö- sa nätverkspunkten, överföra sensordatan eller överföra en bild. Det förstnämnda kallar på de ovan beskrivna funktionerna att stänga av det trådlösa nätverket ige- nom pythonssubprocess.call()-funktionalitet. Men om en fil eller bild önskats så

överförs denna med funktionensend_file(s,dir) som tar inparametrarna s = objekt

av klientens anslutningssocket och dir = sökväg för filen som ska överföras. Dess definition lyder såsom kodstycket nedan

def send_file(s,dir):

# Open file from dir in read-only, binary mode

file = open(dir,’rb’)

# Send dir for reciever to know filename s.send(dir)

s.send(’\n’) packet = 1

while(packet):

# Read 1kB from file and send, repeat until empty packet = file.read(1024)

try:

s.send(packet)

except BluetoothError:

# If client disconnects leave loop packet = None

file.close()

och löser problemet med Bluetoothbibliotekets funktionsend() samt OS-bibliotek-

etsopen() och read() genom att skicka filen i paket om 1024 bytes till bluetoothk-

lienten.

Programmet körs hela tiden i bakgrunden på raspberryn och återfinns i sin helhet i appendix A.2. En enhet som ansluter kan skicka en byte med ASCII-motsvarande bokstaven ’S’ för att motta all mätdata. Datan anländer i form av en .csv-fil.

3.6

Dataloggning

För att logga all mätdata ifrån de olika komponenterna används python-scriptet

nom att importera de olika underprogrammen för hämtning av mätdata såsom

read_adc_raw() och read_gas() som bearbetats i ovan kapitel. Dessa kan då använ-

das för att initiera alla enheter samt periodvis hämta, spara eller säkerhetskopie- ra all mätdata till USB-minnet. Detta görs i funktionernainitiate(), append_log()

samtupdate_sensors(Bool log, Bool backup) vars definitioner bearbetas i komman-

de underkapitel.

3.6.1

Funktionen initiate()

För att systemet ska hålla koll på vilka sensorer som är anslutna försöker i denna funktion programmet att kommunicera med dem en efter en. De som svarar på ett korrekt sätt sätts då till status närvarande.

De olika komponenterna svarar dock på olika sätt när de inte är anslutna, där- av har en funktioninit() skapats för varje digital sensorkomponent.

Vid kommunikation med en onärvarande CCS811, AT30TSE752A eller Ardu- ino så kastar biblioteket pigpio ett felmeddelande som kan fångas. Sker detta vid initiationen så sätter programmet enheterna som onärvarande.

Om däremot en SPI-enhet (mikrofonen eller ADC:n) inte är närvarande så kastas inget felmeddelande, utan funktionerna returnerar istället mätvärdet 0 konstant vilket gör det svårare att veta om enheterna är närvarande eller inte. Men eftersom ingen av enheterna någonsin borde ge ett mätvärde som alltid är noll om de faktiskt är närvarande och inkopplade så kan programmet istället an- ta att de inte är det.

För att undvika fel antagande vid de fåtal fall när ett mätvärde faktiskt är 0 så tas en multitud av mätvärden som alla jämförs mot 0 och om enheten inte avvi- ker en endaste gång så är det högst otroligt att enheten är närvarande och därav sätter programmet den som icke sådan.

En annan metod för detta är att låta användaren manuellt sätta enhet för en- het som närvarande eller icke vilket görs genom att sätta dess booleanska närva- rovariabel som True istället för False i början av logger.py-skriptet.

Related documents