9 Commits

Author SHA1 Message Date
Kristjan Komloši
1dc9fecff6 Update README 2021-04-08 22:30:22 +02:00
Kristjan Komlosi
57d10a5ae5 test sign 2021-03-09 22:47:20 +01:00
Kristjan Komlosi
2cc0fd977b Comment out old debug buttons 2021-02-17 23:40:04 +01:00
Kristjan Komlosi
3d3254c4a7 formatting 2020-07-13 13:01:34 +02:00
Kristjan Komlosi
cfe6e3c286 remove old-unused files 2020-07-13 12:13:31 +02:00
Kristjan Komlosi
7a3877b34b remove unused FastCGI configuration file 2020-07-13 11:55:21 +02:00
Kristjan Komlosi
f20dd30292 remove unused config file 2020-07-13 11:54:35 +02:00
Kristjan Komlosi
ef5c87d8d2 removed janky and unused storage module 2020-07-13 11:54:20 +02:00
Kristjan Komlosi
4878df9ca8 Shortened error messages 2020-07-13 11:52:22 +02:00
14 changed files with 33 additions and 153 deletions

Binary file not shown.

View File

@@ -1,6 +1,6 @@
[![Documentation Status](https://readthedocs.org/projects/terahz/badge/?version=latest)](https://terahz.readthedocs.io/en/latest/?badge=latest) [![Documentation Status](https://readthedocs.org/projects/terahz/badge/?version=latest)](https://terahz.readthedocs.io/en/latest/?badge=latest)
# <img alt="TeraHz logo" src="docs/imgs/logo-sq.png" width="200px"> TeraHz # <img alt="TeraHz logo" src="docs/imgs/logo-sq.png" width="200px"> TeraHz
*This project is currently at a standstill because SparkFUN stopped making one of the board this project needs. TeraHz will return in a better form some day!*
*Za slovensko različico se odpravite na <http://git.sckr-lab.tk/kristjank/TeraHz>* *Za slovensko različico se odpravite na <http://git.sckr-lab.tk/kristjank/TeraHz>*
TeraHz is a low-cost portable spectrometer based on Raspberry Pi and a few TeraHz is a low-cost portable spectrometer based on Raspberry Pi and a few

View File

@@ -8,7 +8,7 @@ app = Flask(__name__)
@app.route('/data') @app.route('/data')
def sendData(): def sendData():
'''Responder function for /data route''' '''Responder function for /data route'''
s = sensors.Spectrometer(path='/dev/serial0', baudrate=115200, tout=1) s = sensors.Spectrometer(path='/dev/serial0')
u = sensors.UVSensor() u = sensors.UVSensor()
l = sensors.LxMeter() l = sensors.LxMeter()
response = jsonify([s.getData(), l.getData(), u.getABI()]) response = jsonify([s.getData(), l.getData(), u.getABI()])

Binary file not shown.

View File

@@ -6,8 +6,13 @@ import serial as ser
import pandas as pd import pandas as pd
import smbus2 import smbus2
class Spectrometer: class Spectrometer:
'''Class representing the AS7265X specrometer''' '''Class representing the AS7265X specrometer'''
def initializeSensor(self): def initializeSensor(self):
'''confirm the sensor is responding and proceed\ '''confirm the sensor is responding and proceed\
with spectrometer initialization''' with spectrometer initialization'''
@@ -23,8 +28,7 @@ class Spectrometer:
if rstring == 'ERROR': if rstring == 'ERROR':
raise Exception # sensor is in error state raise Exception # sensor is in error state
except: except:
raise Exception( raise Exception('No AT command response')
'An exception ocurred when performing spectrometer handshake')
def setParameters(self, parameters): def setParameters(self, parameters):
'''applies the parameters like LED light and gain to the spectrometer''' '''applies the parameters like LED light and gain to the spectrometer'''
@@ -53,8 +57,7 @@ class Spectrometer:
self.serialObject.write('ATLED3={}\n'.format(led).encode()) self.serialObject.write('ATLED3={}\n'.format(led).encode())
self.serialObject.readline() self.serialObject.readline()
except: except:
raise Exception( raise Exception('Error setting spectrometer parameters')
'An exception occured during spectrometer initialization')
def getData(self): def getData(self):
'''Returns spectral data in a pandas DataFrame.''' '''Returns spectral data in a pandas DataFrame.'''
@@ -62,8 +65,7 @@ class Spectrometer:
self.serialObject.write(b'ATCDATA\n') self.serialObject.write(b'ATCDATA\n')
rawresp = self.serialObject.readline().decode() rawresp = self.serialObject.readline().decode()
except: except:
raise Exception( raise Exception('Error polling spectrometer data')
'An exception occurred when polling for spectrometer data')
else: else:
responseorder = list('RSTUVWGHIJKLABCDEF') responseorder = list('RSTUVWGHIJKLABCDEF')
realorder = list('ABCDEFGHRISJTUVWKL') realorder = list('ABCDEFGHRISJTUVWKL')
@@ -78,14 +80,14 @@ class Spectrometer:
try: try:
self.serialObject = ser.Serial(path, baudrate, timeout=tout) self.serialObject = ser.Serial(path, baudrate, timeout=tout)
except: except:
raise Exception( raise Exception('Error opening serial port: {}'.format(path))
'An exception occured when opening the serial port at {}'.format(path))
else: else:
self.initializeSensor() self.initializeSensor()
class LxMeter: class LxMeter:
'''Class representing the APDS-9301 digital photometer.''' '''Class representing the APDS-9301 digital photometer.'''
def __init__(self, busNumber=1, addr=0x39): def __init__(self, busNumber=1, addr=0x39):
self.addr = addr self.addr = addr
try: try:
@@ -93,14 +95,14 @@ class LxMeter:
self.bus = smbus2.SMBus(busNumber) self.bus = smbus2.SMBus(busNumber)
except: except:
raise Exception( raise Exception(
'An exception occured opening the SMBus {}'.format(self.bus)) 'Error opening SMBus {}'.format(self.bus))
try: try:
self.bus.write_byte_data( self.bus.write_byte_data(
self.addr, 0xa0, 0x03) # enable the sensor self.addr, 0xa0, 0x03) # enable the sensor
self.setGain(16) self.setGain(16)
except: except:
raise Exception('An exception occured when enabling lux meter') raise Exception('Error enabling lux meter')
def setGain(self, gain): def setGain(self, gain):
'''Set the sensor gain. Either 1 or 16.''' '''Set the sensor gain. Either 1 or 16.'''
@@ -109,15 +111,13 @@ class LxMeter:
temp = self.bus.read_byte_data(self.addr, 0xa1) temp = self.bus.read_byte_data(self.addr, 0xa1)
self.bus.write_byte_data(self.addr, 0xa1, 0xef & temp) self.bus.write_byte_data(self.addr, 0xa1, 0xef & temp)
except: except:
raise Exception( raise Exception('Error setting lux meter gain')
'An exception occured when setting lux meter gain')
if gain == 16: if gain == 16:
try: try:
temp = self.bus.read_byte_data(self.addr, 0xa1) temp = self.bus.read_byte_data(self.addr, 0xa1)
self.bus.write_byte_data(self.addr, 0xa1, 0x10 | temp) self.bus.write_byte_data(self.addr, 0xa1, 0x10 | temp)
except: except:
raise Exception( raise Exception('Error setting lux meter gain')
'An exception occured when setting lux meter gain')
else: else:
raise Exception('Invalid gain') raise Exception('Invalid gain')
@@ -176,6 +176,7 @@ class LxMeter:
class UVSensor: class UVSensor:
'''Class representing VEML6075 UVA/B meter''' '''Class representing VEML6075 UVA/B meter'''
def __init__(self, bus=1, addr=0x10): def __init__(self, bus=1, addr=0x10):
self.addr = addr self.addr = addr
try: try:
@@ -189,13 +190,14 @@ class UVSensor:
self.bus.write_byte_data(self.addr, 0x00, 0b00010000) self.bus.write_byte_data(self.addr, 0x00, 0b00010000)
# trigger a measurement to prevent bus errors at first read # trigger a measurement to prevent bus errors at first read
self.bus.write_byte_data(self.addr, 0x00, 0b00010010) # UV_AF=1 self.bus.write_byte_data(self.addr, 0x00, 0b00010010) # UV_AF=1
self.bus.write_byte_data(self.addr, 0x00, 0b00010110) # UV_TRIG=1 self.bus.write_byte_data(self.addr, 0x00, 0b00010110) # UV_TRIG=1
self.bus.write_byte_data(self.addr, 0x00, 0b00010000) # normal mode self.bus.write_byte_data(
self.addr, 0x00, 0b00010000) # normal mode
except: except:
raise Exception( raise Exception(
'An exception occured when initalizing the UV Sensor') 'Error initalizing the UV Sensor')
def getABI(self): def getABI(self):
'''Calculates the UVA and UVB irradiances, '''Calculates the UVA and UVB irradiances,
@@ -208,14 +210,14 @@ class UVSensor:
c1 = self.bus.read_word_data(self.addr, 0x0a) c1 = self.bus.read_word_data(self.addr, 0x0a)
c2 = self.bus.read_word_data(self.addr, 0x0b) c2 = self.bus.read_word_data(self.addr, 0x0b)
except: except:
raise Exception('An exception occured when fetching raw UV data') raise Exception('Error fetching raw UV data')
# Refer to Vishay app note 84339 and Sparkfun VEML6075 documentation. # Refer to Vishay app note 84339 and Sparkfun VEML6075 documentation.
# The computed values may be negative if UV is vastly weaker than # The computed values may be negative if UV is vastly weaker than
# visible and IR light. This is not a bug! # visible and IR light. This is not a bug!
a = (aRaw - 2.22 * c1 - 1.33 * c2) * 1.06 a = (aRaw - 2.22 * c1 - 1.33 * c2) * 1.06
b = (bRaw - 2.95 * c1 - 1.74 * c2) * 0.48 b = (bRaw - 2.95 * c1 - 1.74 * c2) * 0.48
i = (a + b) / 2 # calculate UV index i = (a + b) / 2 # calculate UV index
return [a, b, i] return [a, b, i]
def on(self): def on(self):
@@ -226,7 +228,7 @@ class UVSensor:
self.bus.write_byte_data(self.addr, 0x00, 0x10) self.bus.write_byte_data(self.addr, 0x00, 0x10)
except: except:
raise Exception( raise Exception(
'An exception occured when turning the UV sensor on') 'Error turning the UV sensor on')
def off(self): def off(self):
'''Shuts the UV sensor down.''' '''Shuts the UV sensor down.'''
@@ -236,4 +238,4 @@ class UVSensor:
self.bus.write_byte_data(self.addr, 0x00, 0x11) self.bus.write_byte_data(self.addr, 0x00, 0x11)
except: except:
raise Exception( raise Exception(
'An exception occured when shutting the UV sensor down') 'Error shutting the UV sensor down')

View File

@@ -1,37 +0,0 @@
# storage.py - storage backend for TeraHz
'''TeraHz storage backend'''
# Copyright Kristjan Komloši 2019
# All code in this file is licensed under the ISC license,
# provided in LICENSE.txt
import sqlite3
class jsonStorage:
'''Class for simple sqlite3 database of JSON entries'''
def __init__(self, dbFile):
'''Storage object constructor. Argument is filename'''
self.db = sqlite3.connect(dbFile)
def listJSONs(self):
'''Returns a list of all existing entries.'''
c = self.db.cursor()
c.execute('SELECT * FROM storage')
result = c.fetchall()
c.close()
return result
def storeJSON(self, jsonString, comment):
'''Stores a JSON entry along with a timestamp and a comment.'''
c = self.db.cursor()
c.execute(('INSERT INTO storage VALUES (datetime'
'(\'now\', \'localtime\'), ?, ?)'), (comment, jsonString))
c.close()
self.db.commit()
def retrieveJSON(self, timestamp):
'''Retrieves a JSON entry. Takes a timestamp string'''
c = self.db.cursor()
c.execute('SELECT * FROM storage WHERE timestamp = ?', (timestamp,))
result = c.fetchall()
c.close()
return result

View File

@@ -1,7 +0,0 @@
#!/usr/bin/python3
# Minimal flup configuration for Flask
from flup.server.fcgi import WSGIServer
from app import app
if __name__ == '__main__':
WSGIServer(app, bindAddress='/var/www/api/terahz.sock').run()

View File

@@ -1,4 +1,4 @@
# install.sh - install TeraHz onto a Raspbian or DietPi installation # install.sh - install TeraHz onto a Raspbian Lite instance
cd `dirname $0` cd `dirname $0`
apt -y update apt -y update
@@ -6,15 +6,16 @@ apt -y full-upgrade
apt install -y python3 python3-pip lighttpd dnsmasq hostapd libatlas-base-dev apt install -y python3 python3-pip lighttpd dnsmasq hostapd libatlas-base-dev
pip3 install numpy pandas flask smbus2 pyserial gunicorn pip3 install numpy pandas flask smbus2 pyserial gunicorn
cp -R hostapd/ /etc cp -R hostapd/* /etc/hostapd/
chmod +rx /etc/hostapd/edit_ssid.sh chmod +rx /etc/hostapd/edit_ssid.sh
cp dnsmasq.conf /etc cp dnsmasq.conf /etc/
cp rc.local /etc cp rc.local /etc/
chmod +rx /etc/rc.local chmod +rx /etc/rc.local
cp interfaces-terahz /etc/network/interfaces.d/ cp interfaces-terahz /etc/network/interfaces.d/
cp -R ../frontend/* /var/www/html/ cp -R ../frontend/* /var/www/html/
mkdir -p /usr/local/lib/terahz mkdir -p /usr/local/lib/terahz
cp -R ../backend/* /usr/local/lib/terahz cp -R ../backend/* /usr/local/lib/terahz

View File

@@ -26,8 +26,8 @@
<div class="container"> <div class="container">
<button id="update" onclick="updateData()" class="btn btn-primary">Get data</button> <button id="update" onclick="updateData()" class="btn btn-primary">Get data</button>
<button id="download" class="btn btn-primary">Download</button> <!-- <button id="download" class="btn btn-primary">Download</button>
<button id="debug" class="btn btn-danger">DEBUG</button> <button id="debug" class="btn btn-danger">DEBUG</button> -->
</div> </div>
<div class="container"> <div class="container">

View File

@@ -1,45 +0,0 @@
# getcdata.py - fetch the calibrated data from the AS7265x module
# All code in this file is licensed under the ISC license, provided in LICENSE.txt
import serial as ser
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import time
#global variables
uartpath = '/dev/ttyUSB0'
uartbaud = 115200
uarttout = 5
wl = [410, 435, 460, 485, 510, 535, 560, 585, 610, 645, 680, 705, 730, 760, 810, 860, 900, 940]
responseorder = [i for i in 'RSTUVWGHIJKLABCDEF'] # works, do NOT touch!
realorder = [i for i in 'ABCDEFGHRISJTUVWKL']
print('getcdata')
print('This utility is part of the TeraHz project')
wavelens = pd.Series(realorder)
plt.ion()
win = plt.figure()
spectrum=win.add_subplot(111)
with ser.Serial(uartpath, uartbaud, timeout=uarttout) as sensor:
while True:
sensor.write(b'ATCDATA\n')
rawresp = sensor.readline().decode()
# parses, calculates and saves the data
response = pd.Series([float(i)/35.0 for i in rawresp[:-3].split(',')], index=responseorder)
data = pd.DataFrame(response, index=realorder, columns = ['uW/cm^2']) # puts data into a DataFrame
data.insert(0, 'wavelenght', wl) #inserts a legend
print(data)
spectrum.cla()
spectrum.plot(data['wavelenght'], data['uW/cm^2'])
spectrum.set_xlabel('Valovna dolžina')
spectrum.set_ylabel('uW/cm2')
win.canvas.draw()
time.sleep(0.1)

View File

@@ -1,12 +0,0 @@
import smbus2
bus = smbus2.SMBus(1)
result = bus.read_byte_data(0x39, 0x8a)
print('LUX Meter ID = {}'.format(result))
result = bus.read_word_data(0x10, 0x0c)
print('UV sensor ID = {}'.format(result))
result = bus.read_word_data(0x39, 0xec)
print('LUX chan 0 = {}'.format(result))

View File

@@ -1,22 +0,0 @@
from serial import Serial
import tkinter as tk
import pandas as pd
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
uartpath = '/dev/ttyUSB0'
uartbaud = 115200
uarttout = 5
wl = [410, 435, 460, 485, 510, 535, 560, 585, 610, 645, 680, 705, 730, 760, 810, 860, 900, 940]
responseorder = [i for i in 'RSTUVWGHIJKLABCDEF'] # works, do NOT touch!
realorder = [i for i in 'ABCDEFGHRISJTUVWKL']
root = tk.Tk()
root.wm_title('TeraHz Demo')
fig = Figure(figsize=(5, 4), dpi=100)
plot = fig.add_subplot(111)
canvas = FigureCanvasTkAgg(fig, master=root)