removed old utils virtualenv

This commit is contained in:
Kristjan Komlosi
2019-11-12 19:56:22 +01:00
parent 8e7435ff8f
commit 665cf6050b
66 changed files with 1260 additions and 0 deletions

BIN
..gitignore.swp Normal file

Binary file not shown.

129
.gitignore vendored Normal file
View File

@@ -0,0 +1,129 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/

2
.pylintrc Normal file
View File

@@ -0,0 +1,2 @@
[MASTER]
disable = c0103

14
LICENSE.txt Normal file
View File

@@ -0,0 +1,14 @@
Copyright (c) 2018, 2019, Kristjan Komloši, Jakob Kosec, Juš Dolžan,
TeraHz development team
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

23
README.md Normal file
View File

@@ -0,0 +1,23 @@
# TeraHz
[![Documentation Status](https://readthedocs.org/projects/terahz/badge/?version=latest)](https://terahz.readthedocs.io/en/latest/?badge=latest)
TeraHz is a low-cost spectrometer based on a Raspberry Pi 3 or 3 B+ and three sensors:
+ [__AS7265x__](https://www.tindie.com/products/onehorse/compact-as7265x-spectrometer/)
is a 18 channel spectrometer chipset that provides the device with spectral data
+ [__VEML6075__](https://www.sparkfun.com/products/15089) is an
UVA/UVB sensor
+ [__APDS-9301__](https://www.sparkfun.com/products/14350) is a calibrated illuminance (lux) meter that provides the device with reliable readings
## Why?
Because people and institutions could use an affordable and accurate light-analysing device that is also portable, easy to use and simple to assemble. TeraHz was started as an answer to our high school not being able to afford a commercially available solution. One TeraHz spectrometer costs around 150$ in parts, which makes it a competitive alternative to other solutions on the market today.
## Development team
Copyright 2018, 2019
- Kristjan "cls-02" Komloši (electronics, sensor drivers, backend)
- Jakob "D3m1j4ck" Kosec (frontend)
I would also like to thank Juš "ANormalPerson" Dolžan, who decided to leave the
team, but helped me a lot with backend development.

17
backend/app.py Normal file
View File

@@ -0,0 +1,17 @@
# app.py - main backend program
'''Main TeraHz backend program'''
# All code in this file is licensed under the ISC license, provided in LICENSE.txt
from flask import Flask
import flask
import sensors
app = Flask(__name__)
@app.route('/data')
def sendData():
'''Responder function for /data route'''
s = sensors.Spectrometer(path='/dev/serial0', baudrate=115200, tout=1)
u = sensors.UVSensor()
l = sensors.LxMeter()
response = flask.jsonify([s.getData(), l.getData(), u.getABI()])
response.headers.add('Access-Control-Allow-Origin', '*')
return response

4
backend/run.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
# run.sh - run the backend server
cd `dirname $0`
sudo gunicorn app:app -b 0.0.0.0:5000 &

BIN
backend/sample.db Normal file

Binary file not shown.

257
backend/sensors.py Normal file
View File

@@ -0,0 +1,257 @@
# sensors.py - a module for interfacing to the sensors
'''Module for interfacing with TeraHz sensors'''
# Copyright 2019 Kristjan Komloši
# All code in this file is licensed under the ISC license, provided in LICENSE.txt
import serial as ser
import pandas as pd
import smbus2
class Spectrometer:
'''Class representing the AS7265X specrometer'''
def initializeSensor(self):
'''confirm the sensor is responding and proceed\
with spectrometer initialization'''
try:
rstring = 'undefined' # just need it set to a value
self.setParameters({'gain': 0})
self.serialObject.write(b'AT\n')
rstring = self.serialObject.readline().decode()
if rstring == 'undefined':
raise Exception # sensor didn't respond
if rstring == 'OK':
pass # handshake passed
if rstring == 'ERROR':
raise Exception # sensor is in error state
except:
raise Exception(
'An exception ocurred when performing spectrometer handshake')
def setParameters(self, parameters):
'''applies the parameters like LED light and gain to the spectrometer'''
try:
if 'it_time' in parameters:
it_time = int(parameters['it_time'])
if it_time <= 0:
it_time = 1
self.serialObject.write(
'ATINTTIME={}\n'.format(str(it_time)).encode())
self.serialObject.readline()
if 'gain' in parameters:
gain = int(parameters['gain'])
if gain < 0 or gain > 3:
gain = 1
self.serialObject.write('ATGAIN={}\n'.format(gain).encode())
self.serialObject.readline()
if 'led' in parameters:
led = bool(parameters['led'])
if led:
led = 1
else:
led = 0
self.serialObject.write('ATLED3={}\n'.format(led).encode())
self.serialObject.readline()
except:
raise Exception(
'An exception occured during spectrometer initialization')
def getData(self):
'''Returns spectral data in a pandas DataFrame.'''
try:
self.serialObject.write(b'ATCDATA\n')
rawresp = self.serialObject.readline().decode()
except:
raise Exception(
'An exception occurred when polling for spectrometer data')
else:
responseorder = [i for i in 'RSTUVWGHIJKLABCDEF']
realorder = [i for i in 'ABCDEFGHRISJTUVWKL']
response = pd.Series(
[float(i) / 35.0 for i in rawresp[:-3].split(',')], index=responseorder)
return pd.DataFrame(response, index=realorder, columns=['uW/cm^2']).to_dict()['uW/cm^2']
def __init__(self, path='/dev/ttyUSB0', baudrate=115200, tout=1):
self.path = path
self.baudrate = baudrate
self.timeout = 1
try:
self.serialObject = ser.Serial(path, baudrate, timeout=tout)
except:
raise Exception(
'An exception occured when opening the serial port at {}'.format(path))
else:
self.initializeSensor()
class LxMeter:
'''Class representing the APDS-9301 digital photometer.'''
def __init__(self, busNumber=1, addr=0x39):
self.addr = addr
try:
# initialize the SMBus interface
self.bus = smbus2.SMBus(busNumber)
except:
raise Exception(
'An exception occured opening the SMBus {}'.format(self.bus))
try:
self.bus.write_byte_data(
self.addr, 0xa0, 0x03) # enable the sensor
self.setGain(16)
except:
raise Exception('An exception occured when enabling lux meter')
def setGain(self, gain):
'''Set the sensor gain. Either 1 or 16.'''
if gain == 1:
try:
temp = self.bus.read_byte_data(self.addr, 0xa1)
self.bus.write_byte_data(self.addr, 0xa1, 0xef & temp)
except:
raise Exception(
'An exception occured when setting lux meter gain')
if gain == 16:
try:
temp = self.bus.read_byte_data(self.addr, 0xa1)
self.bus.write_byte_data(self.addr, 0xa1, 0x10 | temp)
except:
raise Exception(
'An exception occured when setting lux meter gain')
else:
raise Exception('Invalid gain')
def getGain(self):
'''Get the gain from the sensor.'''
try:
if self.bus.read_byte_data(self.addr, 0xa1) & 0x10 == 0x10:
return 16
if self.bus.read_byte_data(self.addr, 0xa1) & 0x10 == 0x00:
return 1
raise Exception('An error occured when getting lux meter gain')
# Under normal conditions, this raise is unreachable.
except:
raise Exception('An error occured when getting lux meter gain')
def setIntTime(self, time):
'''Set the lux sensor integration time. 0 to including 2'''
if time < 0 or time > 2:
raise Exception('Invalid integration time')
try:
temp = self.bus.read_byte_data(self.addr, 0xa1)
self.bus.write_byte_data(self.addr, 0xa1, (temp & 0xfc) | time)
except:
raise Exception(
'An exception occured setting lux integration time')
def getIntTime(self):
'''Get the lux sensor integration time.'''
try:
return self.bus.read_byte_data(self.addr, 0xa1) & 0x03
except:
raise Exception(
'An exception occured getting lux integration time')
def getData(self):
'''return the calculated lux value'''
try:
chA = self.bus.read_word_data(self.addr, 0xac)
chB = self.bus.read_word_data(self.addr, 0xae)
except:
raise Exception('An exception occured fetching lux channels')
# scary computations ahead! refer to the apds-9301 datasheet!
if chB / chA <= 0.5 and chB / chA > 0:
lux = 0.0304 * chA - 0.062 * chA * (chB / chA)**1.4
elif chB / chA <= 0.61 and chB / chA > 0.5:
lux = 0.0224 * chA - 0.031 * chB
elif chB / chA <= 0.8 and chB / chA > 0.61:
lux = 0.0128 * chA - 0.0153 * chB
elif chB / chA <= 1.3 and chB / chA > 0.8:
lux = 0.00146 * chA - 0.00112 * chB
else:
lux = 0
return lux
class UVSensor:
'''Class representing VEML6075 UVA/B meter'''
def __init__(self, bus=1, addr=0x10):
self.addr = addr
try:
self.bus = smbus2.SMBus(bus)
except:
raise Exception(
'An exception occured opening SMBus {}'.format(bus))
try:
# enable the sensor and set the integration time
self.bus.write_byte_data(self.addr, 0x00, 0b00010000)
except:
raise Exception(
'An exception occured when initalizing the UV Sensor')
def getABI(self):
'''Calculates the UVA and UVB irradiances,
along with UV index. Returns [a,b,i]'''
try:
# read the raw UVA, UVB and compensation values from the sensor
aRaw = self.bus.read_word_data(self.addr, 0x07)
bRaw = self.bus.read_word_data(self.addr, 0x09)
c1 = self.bus.read_word_data(self.addr, 0x0a)
c2 = self.bus.read_word_data(self.addr, 0x0b)
except:
raise Exception('An exception occured when fetching raw UV data')
# scary computations ahead! refer to Vishay app note 84339 and Sparkfun
# VEML6075 documentation.
# compensate for visible and IR noise
aCorr = aRaw - 2.22 * c1 - 1.33 * c2
bCorr = bRaw - 2.95 * c1 - 1.74 * c2
# convert values into irradiances
a = aCorr * 1.06
b = bCorr * 0.48
# zero out negative results (readings with no uv)
if a < 0:
a = 0
if b < 0:
b = 0
# last, calculate the UV index
i = (a + b) / 2
return [a, b, i]
def getA(self):
'''Returns UVA value. A getABI() wrapper.'''
return self.getABI()[0]
def getB(self):
'''Returns UVB value. A getABI() wrapper.'''
return self.getABI()[1]
def getI(self):
'''Returns UV index. A getABI() wrapper.'''
return self.getABI()[2]
def on(self):
'''Turns the UV sensor on after shutdown.'''
try:
# write the default value for power on
# no configurable params = no bitmask
self.bus.write_byte_data(self.addr, 0x00, 0x10)
except:
raise Exception(
'An exception occured when turning the UV sensor on')
def off(self):
'''Shuts the UV sensor down.'''
try:
# write the default value + the shutdown bit
# no configurable params = no bitmask
self.bus.write_byte_data(self.addr, 0x00, 0x11)
except:
raise Exception(
'An exception occured when shutting the UV sensor down')

37
backend/storage.py Normal file
View File

@@ -0,0 +1,37 @@
# 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

0
backend/terahz.conf Normal file
View File

7
backend/terahz.fcgi Normal file
View File

@@ -0,0 +1,7 @@
#!/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()

9
docs/build.md Normal file
View File

@@ -0,0 +1,9 @@
# TeraHz build guide
In its early development phase, TeraHz was hard and time-consuming to compile and install.
This is not case now, as the more optimized DietPi Linux distribution allows
better performance and simpler configuration than formerly used Raspbian.
## Downloading the preconfigured image
DietPi needs some initial configuration to support TeraHz. To shorten the process,
Preconfigured SD card images are available for download under the release tab in
the Github repository

26
docs/dependencies.md Normal file
View File

@@ -0,0 +1,26 @@
# Development-stable dependencies
The current development version of TeraHz has been verified to work with:
- Raspbian Stretch (9)
- Python 3.6.8 (built from source code and altinstall'd)
- Module versions (direct `pip3.6 list` output):
```
Package Version
--------------- ---------
Click 7.0
Flask 1.0.3
itsdangerous 1.1.0
Jinja2 2.10.1
MarkupSafe 1.1.1
numpy 1.16.4
pandas 0.24.2
pip 18.1
pyserial 3.4
python-dateutil 2.8.0
pytz 2019.1
setuptools 40.6.2
six 1.12.0
smbus 1.1.post2
Werkzeug 0.15.4
```

95
docs/dev-guide.md Normal file
View File

@@ -0,0 +1,95 @@
# TeraHz developer's guide
This document explains how TeraHz works. It's a good starting point for developers
and an interesting read for the curious.
# Hardware
TeraHz was developed on and for the Raspberry Pi 3 Model B+. Compatibility with
other Raspberries can probably be achieved by tweaking the device paths in the
`app.py` file, but isn't confirmed at this point. Theoretically, 3 Model B and
Zero W should work out of the box, but models without Wi-Fi will need an
external Wi-Fi adapter if Wi-Fi functionality is desired. The practicality of
compiling Python on the first generation of Raspberry Pis is also very
questionable.
Sensors required for operation are:
+ AS7265x
+ VEML6075
+ APDS-9301
They provide the spectrometry data, UV data and illuminance data, respectively.
They all support I2C, AS7265x supports UART in addition.
The sensors leech power from the GPIO connector, thus eliminating the need for a
separate power supply. The necessary power for the whole system is delivered through
the Raspberry's USB port. This also allows for considerable versatility, as it
enables the resulting device to be either wall-powered or battery-powered.
In a portable configuration, I used a one-cell power bank, which allowed for
about 45 minutes of continuous operation.
## AS7265x chipset
_[Datasheet][1ds] [Buy breakout board][1]_
This chipset supports either I2C or UART. Because transferring large amounts of
data over I2C is rather cumbersome, TeraHz uses AS7265x in UART mode.
This chipset consists of three rather small surface-mounted chips and requires
an EEPROM. To lower the complexity of assembly for the end-user, I recommend
using a breakout board.
The serial UART connection operates at 115200 baud, which seems to be the
standard for most recent embedded peripherals. As with most serial hardware,
the TxD and RxD lines must be crossed over when connecting to the processor.
Communication with the sensor is simple and clear through AT commands. There's
a lot of them, all documented inside the datasheet, but the most important one
is `ATGETCDATA`, which returns the calibrated spectral data from the sensors.
The data is returned in the form of a comma-separated list of floating point
values, ending with a newline. The order is alphabetical, which is __different
from wavelength order__. See the datasheet for more information.
## VEML6075
_[Datasheet][2ds] [Buy breakout board][2]_
This chip communicates through I2C and provides TeraHz with UVA and UVB
irradiance readings. It's not an ideal chip for this task, as it's been marked
End-of-Life by Vishay and it'll have to be replaced with a better one in future
hardware versions of TeraHz.
The chip resides at the I2C address `0x10`. There's not a lot of communication
required: at initialization, the integration time has to be set and after that,
the sensor is ready to go.
16-bit UV values lie in two two-byte registers, `0x07` for UVA and `0x09` for
UVB. For correct result conversion, there are also two correction registers,
UVCOMP_1 and 2, located at `0x0A` and `0x0B`, respectively.
To convert these four values into irradiances, they must be multiplied by
certain constants, somewhat loosely defined in the sensor datasheet. Keep in
mind that the way of computing the "irradiance" is very much experimentally
derived, and even Vishay's tech support doesn't know how exactly to calculate
the irradiance.
## APDS-9301
_[Datasheet][3ds] [Buy breakout board][3]_
This chip measures illuminance in luxes and like the VEML6075, connects through
I2C. Unlike the VEML6075, this chip is very good at its job, providing accurate
and fast results without undefined mathematics or required calibration.
At power-on, it needs to be enabled and the sensor gain set to the high setting,
as the formula for Lux calculation is only defined for that setting. This
initialization is handled by the sensors module.
The lux reading is derived from two channels, descriptively called CH0 and CH1,
residing in respective 16-bit registers at addresses `0xAC` and `0xAE`. After a
successful read of both data registers, the lux value can be derived using the
formula in the sensor's datasheet.
[1]: https://www.tindie.com/products/onehorse/compact-as7265x-spectrometer/
[2]: https://www.sparkfun.com/products/15089
[3]: https://www.sparkfun.com/products/14350
[1ds]: sensor-docs/AS7265x.pdf
[2ds]: sensor-docs/veml6075.pdf
[3ds]: sensor-docs/APDS-9301.pdf

55
docs/electrical.md Normal file
View File

@@ -0,0 +1,55 @@
# TeraHz Electrical Guide
This section briefly explains the neccessary electrical connections between the
Raspberry Pi and the sensors you'll need to make to ensure correct and safe
operation.
As mentioned before, TeraHz requires 3 sensors to operate. The simpler UVA/UVB
sensor and the ambient light analyzer connect to the Raspberry's SMBus (I2C)
bus, while the spectrometer connects via high-speed UART.
![pinout](imgs/raspi-pinout.png)
## PCBs vs breakout boards & jumpers
The Raspberry Pi GPIO port includes enough power pins to require only jumper
cables to connect the sensors to the Raspberry Pi. However, this is not a great
idea. During development, jumper cables have repeatedly been proven to be an
unreliable nuisance, and their absolute lack of rigidity helped me fry one of my
development Raspberry Pis. For this reason, I wholeheartedly recommend using a
simple PCB to route the connections from the Pi to the sensors. At this time,
there is no official TeraHz PCB, but it shall be announced and included in the
project when basic testing will be done.
GPIO can be routed to the PCB with a standard old IDE disk cable, and terminated
with another 40-pin connector at the PCB. Sensor breakouts should be mounted
<<<<<<< HEAD
through standard 0.1" connectors, male on the sensor breakout and female on the
PCB. A shitty add-on header and a shitty add-on header v1.69bis can't hurt, either.
=======
through standard 0.1" connectors, male on the sensor brakout and female on the
PCB. A shitty addon header and a shitty addon header v1.69bis can't hurt, either.
>>>>>>> fd1f07d40dace3e003e49377d4771de53f8bdeb8
## SMBus sensors
SMBus is a well-defined version of the well-known I2C bus, widely used
in computer motherboards for low-band bandwidth communication with various ICs,
especially sensors and power-supply related devices. This bus is broken out on
the Raspberry Pi GPIO port as the "I2C1" bus (see picture).
Pins are familiarly marked as SDA and SCL, the same as with classic I2C. They
connect to the SDA and SCL pins on the VEML6075 and APDS-9301 sensor.
## UART sensor
<<<<<<< HEAD
Spectral sensor attaches through the UART port on the Raspberry pi (see picture).
=======
Spectrometry sensor attaches through the UART port on the Raspberry pi (see picture).
>>>>>>> fd1f07d40dace3e003e49377d4771de53f8bdeb8
The Tx and Rx lines must cross over, connecting the sensor's Tx line to the
computer's Rx line and vice versa.
## Power supply
As the sensors require only a small amount of power, they can be powered directly from the Raspberry Pi itself, leeching power from the 3.3V lines.
## Ground
There's not a lot to say here, connect sensor GND to Pi's GND.

BIN
docs/imgs/logo-sq.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/imgs/raspi-pinout.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

3
docs/index.md Normal file
View File

@@ -0,0 +1,3 @@
<img alt="TeraHz logo" src="imgs/logo-sq.png" width="200px">
# TeraHz documentation - index
This is the starting point of TeraHz documentation.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
etcs/dnsmasq.conf Normal file
View File

@@ -0,0 +1,3 @@
interface=wlan0
dhcp-range=192.168.1.10,192.168.1.100,255.255.255.0,24h
address=/terahz.site/192.168.1.1

6
etcs/hostapd/edit_ssid.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
# edit_ssid.sh - edits hostapd.conf and sets a MAC address-based SSID
cd `dirname $0`
ssid=`ip link | awk '/wlan0/ {getline; print $2}' | awk -v FS=':' '{printf("TeraHz_%s%s%s\n", $4, $5, $6)}'`
sed "/ssid=.*/s/ssid=.*/ssid=$ssid/" hostapd.conf > newconf
mv newconf hostapd.conf

View File

@@ -0,0 +1,9 @@
interface=wlan0
hw_mode=g
channel=8
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
ssid=TeraHz
wpa_passphrase=terahertz

18
etcs/install.sh Executable file
View File

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

3
etcs/interfaces-terahz Normal file
View File

@@ -0,0 +1,3 @@
iface wlan0 inet static
address 192.168.1.1
netmask 255.255.255.0

View File

@@ -0,0 +1,27 @@
server.modules = (
"mod_access",
"mod_alias",
"mod_compress",
"mod_redirect"
)
server.document-root = "/var/www/html"
server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
server.errorlog = "/var/log/lighttpd/error.log"
server.pid-file = "/var/run/lighttpd.pid"
server.username = "www-data"
server.groupname = "www-data"
server.port = 80
index-file.names = ( "index.php", "index.html", "index.lighttpd.html" )
url.access-deny = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
compress.cache-dir = "/var/cache/lighttpd/compress/"
compress.filetype = ( "application/javascript", "text/css", "text/html", "text/plain" )
# default listening port for IPv6 falls back to the IPv4 port
include_shell "/usr/share/lighttpd/use-ipv6.pl " + server.port
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"

16
etcs/rc.local Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/etc/hostapd/edit_ssid.sh &
/usr/local/lib/terahz/run.sh &
sleep 3
service hostapd restart # restart hostapd to prevent a weird startup race condition

46
frontend/frontend.js Normal file
View File

@@ -0,0 +1,46 @@
// All code in this file is licensed under the ISC license, provided in LICENSE.txt
$('#update').click(function () {
updateData();
});
// jQuery event binder
function updateData () {
const url = 'http://' + window.location.hostname + ':5000/data';
$.ajax({ // spawn an AJAX request
url: url,
success: function (data, status) {
console.log(data);
graphSpectralData(data[0], 0);
fillTableData(data);
},
timeout: 2500 // this should be a pretty sane timeout
});
}
function graphSpectralData (obj, dom) {
// graph spectral data in obj into dom
var graphPoints = [];
var graphXTicks = [];
Object.keys(obj).forEach((element, index) => {
graphPoints.push([index, obj[element]]); // build array of points
graphXTicks.push([index, element]); // build array of axis labels
});
// console.log(graphPoints);
const options = {
grid: {color: 'white'},
xaxis: {ticks: graphXTicks}
};
$.plot('#graph', [graphPoints], options);
// flot expects an array of arrays (lines) of 2-element arrays (points)
}
function fillTableData (obj) {
// fill the obj data into HTML tables
Object.keys(obj[0])
.forEach((element) => { $('#' + element).text(obj[0][element]); });
$('#lx').text(obj[1]);
$('#uva').text(obj[2][0]);
$('#uvb').text(obj[2][1]);
$('#uvi').text(obj[2][2]);
}

162
frontend/index.html Normal file
View File

@@ -0,0 +1,162 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<link rel="stylesheet" href="lib/bootstrap.min.css">
<link rel="stylesheet" href="stylesheet.css">
<title>TeraHz</title>
</head>
<body>
<div class="container text-center">
<h1><img src="lib/logo-sq.png" height="64px">TeraHz</h1>
</div>
<div class="container">
<button id="update" class="btn btn-primary m-1 float-right">Get data</button>
<p id="debug">
</p>
<h3>Spectrogram</h3>
<div id="graph" style="height:480px;width:720px"></div>
<h3>Spectral readings</h3>
<table class="table table-dark table-sm" id="specter">
<thead class="thead-dark">
<tr>
<th>Band</th>
<th>Wavelength [nm]</th>
<th>Irradiance [μW/cm²]</th>
</tr>
</thead>
<tr>
<td>A</td>
<td>410 nm</td>
<td id="A">---</td>
</tr>
<tr>
<td>B</td>
<td>435 nm</td>
<td id="B">---</td>
</tr>
<tr>
<td>C</td>
<td>460 nm</td>
<td id="C">---</td>
</tr>
<tr>
<td>D</td>
<td>485 nm</td>
<td id="D">---</td>
</tr>
<tr>
<td>E</td>
<td>510 nm</td>
<td id="E">---</td>
</tr>
<tr>
<td>F</td>
<td>535 nm</td>
<td id="F">---</td>
</tr>
<tr>
<td>G</td>
<td>560 nm</td>
<td id="G">---</td>
</tr>
<tr>
<td>H</td>
<td>585 nm</td>
<td id="H">---</td>
</tr>
<tr>
<td>R</td>
<td>610 nm</td>
<td id="R">---</td>
</tr>
<tr>
<td>I</td>
<td>645 nm</td>
<td id="I">---</td>
</tr>
<tr>
<td>S</td>
<td>680 nm</td>
<td id="S">---</td>
</tr>
<tr>
<td>J</td>
<td>705 nm</td>
<td id="J">---</td>
</tr>
<tr>
<td>T</td>
<td>730 nm</td>
<td id="T">---</td>
</tr>
<tr>
<td>U</td>
<td>760 nm</td>
<td id="U">---</td>
</tr>
<tr class="table-secondary">
<td>V</td>
<td>810 nm</td>
<td id="V">---</td>
</tr>
<tr class="table-secondary">
<td>W</td>
<td>860 nm</td>
<td id="W">---</td>
</tr>
<tr class="table-secondary">
<td>K</td>
<td>900 nm</td>
<td id="K">---</td>
</tr>
<tr class="table-secondary">
<td>L</td>
<td>940 nm</td>
<td id="L">---</td>
</tr>
</table>
<br>
<h3>Lux and UV readings</h3>
<table class="table-dark table" id="luxuv">
<thead class="thead-dark">
<tr>
<th>Parameter</th>
<th>Value</th>
</tr>
</thead>
<tr>
<td>Illuminance [lx]</td>
<td id="lx">---</td>
</tr>
<tr>
<td>UVA irradiance [μW/cm²]</td>
<td id="uva">---</td>
</tr>
<tr>
<td>UVB irradiance [μW/cm²]</td>
<td id="uvb">---</td>
</tr>
<tr>
<td>UVA/UVB average [μW/cm²]</td>
<td id="uvi">---</td>
</tr>
</table>
</div>
<script src="lib/bootstrap.bundle.min.js"></script>
<script src="lib/jquery-3.4.1.min.js"></script>
<script src="lib/flot/jquery.flot.js"></script>
<script src="frontend.js"></script>
<script src="lib/flot/jquery.canvaswrapper.js"></script>
<script src="lib/flot/jquery.colorhelpers.js"></script>
<script src="lib/flot/jquery.flot.js"></script>
<script src="lib/flot/jquery.flot.saturated.js"></script>
<script src="lib/flot/jquery.flot.browser.js"></script>
<script src="lib/flot/jquery.flot.drawSeries.js"></script>
<script src="lib/flot/jquery.flot.uiConstants.js"></script>
</body>
</html>

69
frontend/stylesheet.css Normal file
View File

@@ -0,0 +1,69 @@
body {
background: rgb(2,0,36);
background: linear-gradient(138deg, rgba(2,0,36,1) 0%, rgba(5,5,209,1) 51%, rgba(0,212,255,1) 100%);
color: white;
}
#A {
background-color: #7e00db;
color: white;
}
#B {
background-color: #2300ff;
color: white;
}
#C {
background-color: #007bff;
color: white;
}
#D {
background-color: #00eaff;
}
#E {
background-color: #00ff00;
}
#F {
background-color: #70ff00;
}
#G {
background-color: #c3ff00;
}
#H {
background-color: #ffef00;
}
#R {
background-color: #ff9b00;
}
#I, #S {
background-color: #ff0000;
}
#J {
background-color: #f60000;
}
#T {
background-color: #c80000;
color: white;
}
#U {
background-color: #8d0000;
color: white;
}
.table-secondary {
color: black;
}
.flot-tick-label {
fill: white;
}

9
mkdocs.yml Normal file
View File

@@ -0,0 +1,9 @@
site_name: TeraHz Documentation
theme: readthedocs
nav:
- Start page: 'index.md'
- Advanced guides:
- Build guide: 'build.md'
- Developer's guide: 'dev-guide.md'
- Electrical connections: 'electrical.md'
- Latest dependencies: 'dependencies.md'

3
readthedocs.yml Normal file
View File

@@ -0,0 +1,3 @@
version: 2
mkdocs:
configuration: mkdocs.yml

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sensor_docs/demo.epgz Normal file

Binary file not shown.

BIN
sensor_docs/demo.odt Normal file

Binary file not shown.

131
sensor_docs/demo.svg Normal file
View File

@@ -0,0 +1,131 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:p="http://www.evolus.vn/Namespace/Pencil" xmlns:pencil="http://www.evolus.vn/Namespace/Pencil" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:rdfa="http://docs.oasis-open.org/opendocument/meta/rdfa#" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:em="http://exslt.org/math" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="1385" height="852" id="exportedSVG" version="1.1" pencil:version="1.2.2" sodipodi:docname="demo"><g inkscape:label="Untitled Page" inkscape:groupmode="layer" id="layer_untitled_page"><g><rect x="0" y="0" width="1385" height="852" fill="none"/><g p:type="Shape" p:def="Evolus.Sketchy.GUI:box" id="316ea25d69264185809ddf96933f1b9d" transform="matrix(1,0,0,1,479,239)"><p:metadata><p:property name="box">379,359</p:property><p:property name="textPadding">18.95,23.933333333333334</p:property><p:property name="fillColor">#FFFFFFFF</p:property><p:property name="strokeColor">#000000FF</p:property><p:property name="strokeStyle">1|</p:property><p:property name="textContent"/><p:property name="textFont">'Comic Sans MS'|normal|normal|12px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<path style="stroke-linejoin: round; fill: rgb(255, 255, 255); fill-opacity: 1; stroke: rgb(0, 0, 0); stroke-opacity: 1; stroke-width: 1;" p:name="line1" id="9f2cd04595654a2daa5c78cc57fc3ad1" transform="translate(0.5,0.5)" d="M 0 0 C 126 -1 253 -1 379 0 C 381 120 381 239 379 359 C 253 360 126 360 0 359 C -2 239 -2 120 0 0 z"/>
<text p:name="text" id="22d3cf61288a4e6f8aea91fd9f11d090" transform="translate(190,180)" style="font-family: &quot;Comic Sans MS&quot;; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;"/>
</g><g p:type="Shape" p:def="Evolus.Common:Bitmap" id="f2992ac1faff43ef857d97b6097a3377" transform="matrix(1,0,0,1,545,295)"><p:metadata><p:property name="box">248,248</p:property><p:property name="imageData">1600,1600,ref://c549d0e3af32443d81f8de3a764ef050.png</p:property><p:property name="withBlur">false</p:property><p:property name="fillColor">#FFFFFF00</p:property><p:property name="strokeColor">#000000FF</p:property><p:property name="strokeStyle">0|</p:property></p:metadata>
<defs>
<filter height="1.2558399" y="-0.12792" width="1.06396" x="-0.03198" p:name="imageShading" id="47f2743a5502445daeea6763b1824d99">
<feGaussianBlur stdDeviation="1.3325" in="SourceAlpha"/>
</filter>
<g p:name="container" id="c807f25ef7cd4046b815700f4e8dd837">
<rect style="fill: rgb(255, 255, 255); stroke: rgb(0, 0, 0); stroke-opacity: 1; stroke-width: 0; fill-opacity: 0;" p:name="bgRect" id="442171111cd644568d10f9aaa8367c03" transform="translate(0,0)" width="248" height="248"/>
<g p:name="imageContainer" id="149b425645654fd99d93a63c39be92cd" transform="scale(0.155,0.155)">
<image x="0" y="0" p:name="image" id="6f19a34b96bf4773969f6d58610f56bd" xlink:href="file:///tmp/tmp-27399CzGZUH8OkSfx/refs/c549d0e3af32443d81f8de3a764ef050.png?token=1549194154000" width="1600" height="1600"/>
</g>
</g>
</defs>
<use xlink:href="#c807f25ef7cd4046b815700f4e8dd837" transform="translate(1, 1)" p:filter="url(#47f2743a5502445daeea6763b1824d99)" style="opacity: 0.6; visibility: hidden; display: none;" p:name="bgCopy" id="f490b3b5a7e340a89dd6f4e992753bb7"/>
<use xlink:href="#c807f25ef7cd4046b815700f4e8dd837"/>
</g><g p:type="Shape" p:def="Evolus.Common:PlainTextV2" p:sc="Label" id="d874a4977f474fdeb875d7e6bf5944ed" transform="matrix(1,0,0,1,596,289)"><p:metadata><p:property name="disabled">false</p:property><p:property name="width">100,0</p:property><p:property name="fixedWidth">false</p:property><p:property name="label">Raspberry Pi 3 B+</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textFont">'Comic Sans MS'|normal|normal|18px|none</p:property><p:property name="textAlign">0,0</p:property></p:metadata>
<rect x="0" y="0" style="fill: none; stroke: none; visibility: hidden; display: none;" p:name="bgRect" id="de7b105d7eec4d18b5eb971d7883baaa" width="147.640625" height="25.09375"/>
<text xml:space="preserve" p:name="text" id="949a08b7fd4044b794cc5b69b6f83422" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Comic Sans MS&quot;; font-size: 18px; font-weight: normal; font-style: normal; text-decoration: none;"><tspan x="0" y="0">Raspberry Pi 3 B+</tspan></text>
</g><g p:type="Shape" p:def="Evolus.Sketchy.GUI:box" id="4e6d928174bb44b2b165b10e439c8069" transform="matrix(1,0,0,1,215,144)"><p:metadata><p:property name="box">200,150</p:property><p:property name="textPadding">10,10</p:property><p:property name="fillColor">#FFFFFFFF</p:property><p:property name="strokeColor">#000000FF</p:property><p:property name="strokeStyle">1|</p:property><p:property name="textContent">AS7265X
Spektrometerski senzor za IR in vidno svetlobo</p:property><p:property name="textFont">'Comic Sans MS'|normal|normal|12px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<path style="stroke-linejoin: round; fill: rgb(255, 255, 255); fill-opacity: 1; stroke: rgb(0, 0, 0); stroke-opacity: 1; stroke-width: 1;" p:name="line1" id="ba226d4a59e9445cb033b5f6cda2407c" transform="translate(0.5,0.5)" d="M 0 0 C 67 1 133 1 200 0 C 200 50 200 100 200 150 C 133 148 67 148 0 150 C -1 100 -1 50 0 0 z"/>
<text p:name="text" id="2f20051133e249f78ca5e893035376d7" transform="translate(10,64)" style="font-family: &quot;Comic Sans MS&quot;; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;"><tspan x="62.4609375" y="0">AS7265X</tspan><tspan x="5.109375" y="16">Spektrometerski senzor za IR</tspan><tspan x="43.7109375" y="32.390625">in vidno svetlobo</tspan></text>
</g><g p:type="Shape" p:def="Evolus.Sketchy.GUI:box" id="0788d286529c4856817fe87c11c8c576" transform="matrix(1,0,0,1,113,331)"><p:metadata><p:property name="box">200,150</p:property><p:property name="textPadding">10,10</p:property><p:property name="fillColor">#FFFFFFFF</p:property><p:property name="strokeColor">#000000FF</p:property><p:property name="strokeStyle">1|</p:property><p:property name="textContent">VEML6075
Senzor UV svetlobe</p:property><p:property name="textFont">'Comic Sans MS'|normal|normal|12px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<path style="stroke-linejoin: round; fill: rgb(255, 255, 255); fill-opacity: 1; stroke: rgb(0, 0, 0); stroke-opacity: 1; stroke-width: 1;" p:name="line1" id="fb336ddc2a0e4285ab16ca92def9a93f" transform="translate(0.5,0.5)" d="M 0 0 C 67 2 133 2 200 0 C 199 50 199 100 200 150 C 133 151 67 151 0 150 C -1 100 -1 50 0 0 z"/>
<text p:name="text" id="5a27b79034a142a182fbba178737c976" transform="translate(10,72)" style="font-family: &quot;Comic Sans MS&quot;; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;"><tspan x="59.109375" y="0">VEML6075</tspan><tspan x="34.640625" y="16">Senzor UV svetlobe</tspan></text>
</g><g p:type="Shape" p:def="Evolus.Sketchy.GUI:box" id="fdd2989c419f44e49052af8a9433398b" transform="matrix(1,0,0,1,112,499)"><p:metadata><p:property name="box">200,150</p:property><p:property name="textPadding">10,10</p:property><p:property name="fillColor">#FFFFFFFF</p:property><p:property name="strokeColor">#000000FF</p:property><p:property name="strokeStyle">1|</p:property><p:property name="textContent">APDS-9301
Merilec osvetljenosti
(lux-meter)</p:property><p:property name="textFont">'Comic Sans MS'|normal|normal|12px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<path style="stroke-linejoin: round; fill: rgb(255, 255, 255); fill-opacity: 1; stroke: rgb(0, 0, 0); stroke-opacity: 1; stroke-width: 1;" p:name="line1" id="fd47ea2f4fea4465b5145099e062a50f" transform="translate(0.5,0.5)" d="M 0 0 C 67 0 133 0 200 0 C 198 50 198 100 200 150 C 133 151 67 151 0 150 C 1 100 1 50 0 0 z"/>
<text p:name="text" id="3a1e6ef59bfe4e32a29f2d83e8a0eda4" transform="translate(10,64)" style="font-family: &quot;Comic Sans MS&quot;; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;"><tspan x="57.8125" y="0">APDS-9301</tspan><tspan x="30.8671875" y="16">Merilec osvetljenosti</tspan><tspan x="57.859375" y="32.484375">(lux-meter)</tspan></text>
</g><g p:type="Shape" p:def="Evolus.Sketchy.GUI:box" id="6a62643b2a9e40ad92de2807a3b4d499" transform="matrix(1,0,0,1,898,448)"><p:metadata><p:property name="box">200,150</p:property><p:property name="textPadding">10,10</p:property><p:property name="fillColor">#FFFFFFFF</p:property><p:property name="strokeColor">#000000FF</p:property><p:property name="strokeStyle">1|</p:property><p:property name="textContent">2600 mAh Powerbank
Napaja spektrometer</p:property><p:property name="textFont">'Comic Sans MS'|normal|normal|12px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<path style="stroke-linejoin: round; fill: rgb(255, 255, 255); fill-opacity: 1; stroke: rgb(0, 0, 0); stroke-opacity: 1; stroke-width: 1;" p:name="line1" id="0e72ea3ae7374eae96f6d39616ad398b" transform="translate(0.5,0.5)" d="M 0 0 C 67 -1 133 -1 200 0 C 200 50 200 100 200 150 C 133 150 67 150 0 150 C 0 100 0 50 0 0 z"/>
<text p:name="text" id="e73d9b50f41c4e3eb2efffdb7a5f58d9" transform="translate(10,72)" style="font-family: &quot;Comic Sans MS&quot;; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;"><tspan x="29.6875" y="0">2600 mAh Powerbank</tspan><tspan x="30.125" y="16">Napaja spektrometer</tspan></text>
</g><g p:type="Shape" p:def="Evolus.Common:arrow" id="bc03848225fa44a3a7c3339794d1aa4e" transform="matrix(1,0,0,1,479,127)"><p:metadata><p:property xmlns:ns9889235="http://www.evolus.vn/Namespace/Pencil" name="startPin" ns9889235:viay="92" ns9889235:viax="-54" ns9889235:connectedOutletId="middle-right" ns9889235:connectedShapeId="4e6d928174bb44b2b165b10e439c8069">-64,92</p:property><p:property xmlns:ns9889235="http://www.evolus.vn/Namespace/Pencil" name="endPin" ns9889235:viay="102" ns9889235:viax="189.5" ns9889235:connectedOutletId="top-center" ns9889235:connectedShapeId="316ea25d69264185809ddf96933f1b9d">189.5,112</p:property><p:property name="withStartArrow">true</p:property><p:property name="withEndArrow">true</p:property><p:property name="mode">curvy</p:property><p:property name="detached">false</p:property><p:property name="strokeColor">#1B3280FF</p:property><p:property name="strokeStyle">2|</p:property><p:property name="textContent"/><p:property name="textFont">"Liberation Sans",Arial,sans-serif|normal|normal|13px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<defs>
<path style="stroke-linejoin: round; fill: none;" p:name="path" id="590e362dc0a941558c8729fc4369cced" d="M -58 98 L -64 92 L -58 86 M -64 92 C -4 92 190 52 189.5 112 M 195 106 L 189.5 112 L 184 106"/>
</defs>
<use xlink:href="#590e362dc0a941558c8729fc4369cced" stroke-width="10" stroke-opacity="0" stroke="#FF0000"/>
<use xlink:href="#590e362dc0a941558c8729fc4369cced" p:name="outArrow1" id="9c47d44f84ff4e8c9c60f2427e5649e4" style="stroke: rgb(27, 50, 128); stroke-opacity: 1; stroke-width: 2;"/>
<text p:name="text" id="2027c38e59a7415ea356985839c3cb6a" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Liberation Sans&quot;, Arial, sans-serif; font-size: 13px; font-weight: normal; font-style: normal; text-decoration: none;">
<textPath xlink:href="#590e362dc0a941558c8729fc4369cced" startOffset="50%" text-anchor="middle" alignment-baseline="middle">
<tspan dy="-4.333333333333333" p:name="textSpan" id="7e3a712874e84610942b4fa041b7a43b" dx="0"/>
</textPath>
</text>
</g><g p:type="Shape" p:def="Evolus.Sketchy.GUI:box" id="3f86fad121f34239a0d9a0381b8e5293" transform="matrix(1,0,0,1,339,331)"><p:metadata><p:property name="box">76,316</p:property><p:property name="textPadding">3.8,21.066666666666663</p:property><p:property name="fillColor">#FFFFFFFF</p:property><p:property name="strokeColor">#000000FF</p:property><p:property name="strokeStyle">1|</p:property><p:property name="textContent">I2C
Vodilo</p:property><p:property name="textFont">'Comic Sans MS'|normal|normal|12px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<path style="stroke-linejoin: round; fill: rgb(255, 255, 255); fill-opacity: 1; stroke: rgb(0, 0, 0); stroke-opacity: 1; stroke-width: 1;" p:name="line1" id="38738b385aac4e4f882b7957ae3baf95" transform="translate(0.5,0.5)" d="M 0 0 C 25 -1 51 -1 76 0 C 76 105 76 211 76 316 C 51 315 25 315 0 316 C -1 211 -1 105 0 0 z"/>
<text p:name="text" id="d829667556ac42128e839eeb4432aec3" transform="translate(4,155)" style="font-family: &quot;Comic Sans MS&quot;; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none; fill: rgb(0, 0, 0); fill-opacity: 1;"><tspan x="23.645312500000003" y="0">I2C</tspan><tspan x="17.145312500000003" y="16">Vodilo</tspan></text>
</g><g p:type="Shape" p:def="Evolus.Common:arrow" id="e6e45b080a4640e2af58d063d5abe1ef" transform="matrix(1,0,0,1,562,696)"><p:metadata><p:property xmlns:ns9889235="http://www.evolus.vn/Namespace/Pencil" name="startPin" ns9889235:connectedShapeId="0788d286529c4856817fe87c11c8c576" ns9889235:connectedOutletId="middle-right" ns9889235:viax="-239" ns9889235:viay="-290">-249,-290</p:property><p:property xmlns:ns9889235="http://www.evolus.vn/Namespace/Pencil" name="endPin" ns9889235:connectedShapeId="3f86fad121f34239a0d9a0381b8e5293" ns9889235:connectedOutletId="middle-left" ns9889235:viax="-233" ns9889235:viay="-207">-223,-207</p:property><p:property name="withStartArrow">true</p:property><p:property name="withEndArrow">true</p:property><p:property name="mode">curvy</p:property><p:property name="detached">false</p:property><p:property name="strokeColor">#1B3280FF</p:property><p:property name="strokeStyle">2|</p:property><p:property name="textContent"/><p:property name="textFont">"Liberation Sans",Arial,sans-serif|normal|normal|13px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<defs>
<path style="stroke-linejoin: round; fill: none;" p:name="path" id="564ef2543bfd4d4f8bf59146b4632c7c" d="M -243 -284 L -249 -290 L -243 -296 M -249 -290 C -206 -290 -266 -207 -223 -207 M -229 -213 L -223 -207 L -229 -201"/>
</defs>
<use xlink:href="#564ef2543bfd4d4f8bf59146b4632c7c" stroke-width="10" stroke-opacity="0" stroke="#FF0000"/>
<use xlink:href="#564ef2543bfd4d4f8bf59146b4632c7c" p:name="outArrow1" id="9fd757e4b8d042a09378b6031cfe99e2" style="stroke: rgb(27, 50, 128); stroke-opacity: 1; stroke-width: 2;"/>
<text p:name="text" id="c73cdd327696416eab5fa6971dba53ef" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Liberation Sans&quot;, Arial, sans-serif; font-size: 13px; font-weight: normal; font-style: normal; text-decoration: none;">
<textPath xlink:href="#564ef2543bfd4d4f8bf59146b4632c7c" startOffset="50%" text-anchor="middle" alignment-baseline="middle">
<tspan dy="-4.333333333333333" p:name="textSpan" id="221213c9b3fc487facaa478640fecf0f" dx="0"/>
</textPath>
</text>
</g><g p:type="Shape" p:def="Evolus.Common:arrow" id="540bab7bb3f3442f8429144581700e47" transform="matrix(1,0,0,1,324,705)"><p:metadata><p:property xmlns:ns9889235="http://www.evolus.vn/Namespace/Pencil" name="startPin" ns9889235:viay="-131" ns9889235:viax="-2" ns9889235:connectedOutletId="middle-right" ns9889235:connectedShapeId="fdd2989c419f44e49052af8a9433398b">-12,-131</p:property><p:property xmlns:ns9889235="http://www.evolus.vn/Namespace/Pencil" name="endPin" ns9889235:connectedShapeId="3f86fad121f34239a0d9a0381b8e5293" ns9889235:connectedOutletId="middle-left" ns9889235:viax="5" ns9889235:viay="-216">15,-216</p:property><p:property name="withStartArrow">true</p:property><p:property name="withEndArrow">true</p:property><p:property name="mode">curvy</p:property><p:property name="detached">false</p:property><p:property name="strokeColor">#1B3280FF</p:property><p:property name="strokeStyle">2|</p:property><p:property name="textContent"/><p:property name="textFont">"Liberation Sans",Arial,sans-serif|normal|normal|13px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<defs>
<path style="stroke-linejoin: round; fill: none;" p:name="path" id="b08f88ad83b84d5fad883f5b2d7152d9" d="M -6 -125 L -12 -131 L -6 -137 M -12 -131 C 33 -131 -30 -216 15 -216 M 9 -222 L 15 -216 L 9 -210"/>
</defs>
<use xlink:href="#b08f88ad83b84d5fad883f5b2d7152d9" stroke-width="10" stroke-opacity="0" stroke="#FF0000"/>
<use xlink:href="#b08f88ad83b84d5fad883f5b2d7152d9" p:name="outArrow1" id="81869e15f13e41609130f9b556eef9d3" style="stroke: rgb(27, 50, 128); stroke-opacity: 1; stroke-width: 2;"/>
<text p:name="text" id="2fa0348639be49eda6fa12a65623e9b6" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Liberation Sans&quot;, Arial, sans-serif; font-size: 13px; font-weight: normal; font-style: normal; text-decoration: none;">
<textPath xlink:href="#b08f88ad83b84d5fad883f5b2d7152d9" startOffset="50%" text-anchor="middle" alignment-baseline="middle">
<tspan dy="-4.333333333333333" p:name="textSpan" id="c544ec23fdcd4df998935ca8bb683723" dx="0"/>
</textPath>
</text>
</g><g p:type="Shape" p:def="Evolus.Common:arrow" id="0bc4ad3e83614786a0f2348a47ec40f2" transform="matrix(1,0,0,1,463,627)"><p:metadata><p:property xmlns:ns9889235="http://www.evolus.vn/Namespace/Pencil" name="startPin" ns9889235:connectedShapeId="3f86fad121f34239a0d9a0381b8e5293" ns9889235:connectedOutletId="middle-right" ns9889235:viax="-38" ns9889235:viay="-138">-48,-138</p:property><p:property xmlns:ns9889235="http://www.evolus.vn/Namespace/Pencil" name="endPin" ns9889235:connectedShapeId="316ea25d69264185809ddf96933f1b9d" ns9889235:connectedOutletId="middle-left" ns9889235:viax="5.999999999999972" ns9889235:viay="-208.5">16,-208</p:property><p:property name="withStartArrow">true</p:property><p:property name="withEndArrow">true</p:property><p:property name="mode">curvy</p:property><p:property name="detached">false</p:property><p:property name="strokeColor">#1B3280FF</p:property><p:property name="strokeStyle">2|</p:property><p:property name="textContent"/><p:property name="textFont">"Liberation Sans",Arial,sans-serif|normal|normal|13px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<defs>
<path style="stroke-linejoin: round; fill: none;" p:name="path" id="6c567c02fe2642e19f2b63f417f770a9" d="M -42 -132 L -48 -138 L -42 -144 M -48 -138 C -1 -138 -31 -210 16 -208 M 11 -214 L 16 -208 L 10 -203"/>
</defs>
<use xlink:href="#6c567c02fe2642e19f2b63f417f770a9" stroke-width="10" stroke-opacity="0" stroke="#FF0000"/>
<use xlink:href="#6c567c02fe2642e19f2b63f417f770a9" p:name="outArrow1" id="cad90b7ac097400b8a9febcd1059b193" style="stroke: rgb(27, 50, 128); stroke-opacity: 1; stroke-width: 2;"/>
<text p:name="text" id="7256ea09df6f4b7ebf33202f1ced446d" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Liberation Sans&quot;, Arial, sans-serif; font-size: 13px; font-weight: normal; font-style: normal; text-decoration: none;">
<textPath xlink:href="#6c567c02fe2642e19f2b63f417f770a9" startOffset="50%" text-anchor="middle" alignment-baseline="middle">
<tspan dy="-4.333333333333333" p:name="textSpan" id="a3e251b119324498b6079771d87cf26b" dx="0"/>
</textPath>
</text>
</g><g p:type="Shape" p:def="Evolus.Common:RichTextBoxV2" id="f9704a7a815d4cdba445660a10c7ddc8" transform="matrix(1,0,0,1,479,601)"><p:metadata><p:property name="width">200,0</p:property><p:property name="fixedWidth">false</p:property><p:property name="textContent">&lt;span xmlns="http://www.w3.org/1999/xhtml" style="font-family: &amp;quot;Comic Sans MS&amp;quot;;"&gt;Računalnik na tiskanem vezju (SBC = single board computer)&lt;br xmlns="http://www.w3.org/1999/xhtml" /&gt;Opravlja prevzem in obdelavo podatkov s senzorja, in jih preda telefonu, ki upravlja spektrmeter&lt;/span&gt;</p:property><p:property name="textFont">"Liberation Sans",Arial,sans-serif|normal|normal|13px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="customStyle">
</p:property></p:metadata>
<foreignObject x="0" y="0" width="585" height="38" p:name="htmlObject" id="54de4aab4c144b8ead414b2e22841369" style="color: rgb(0, 0, 0); font-family: &quot;Liberation Sans&quot;, Arial, sans-serif; font-size: 13px; font-weight: normal; font-style: normal; text-decoration: none;">
<div xmlns="http://www.w3.org/1999/xhtml" p:name="textDiv" id="0cbc982da2c54d4aa9a65d4f6e9727c6" style="display: inline-block; white-space: nowrap; text-decoration: none;"><div><span style="font-family: &quot;Comic Sans MS&quot;;">Računalnik na tiskanem vezju (SBC = single board computer)<br />Opravlja prevzem in obdelavo podatkov s senzorja, in jih preda telefonu, ki upravlja spektrmeter</span></div></div>
</foreignObject>
</g><g p:type="Shape" p:def="Evolus.Common:arrow" id="c884a2093fdc477bb3a74e719a1c7c77" transform="matrix(1,0,0,1,951,527)"><p:metadata><p:property xmlns:ns9889235="http://www.evolus.vn/Namespace/Pencil" name="startPin" ns9889235:connectedShapeId="316ea25d69264185809ddf96933f1b9d" ns9889235:connectedOutletId="middle-right" ns9889235:viax="-83" ns9889235:viay="-108.5">-93,-108</p:property><p:property xmlns:ns9889235="http://www.evolus.vn/Namespace/Pencil" name="endPin" ns9889235:viay="-4" ns9889235:viax="-63.000000000000014" ns9889235:connectedOutletId="middle-left" ns9889235:connectedShapeId="6a62643b2a9e40ad92de2807a3b4d499">-53,-4</p:property><p:property name="withStartArrow">true</p:property><p:property name="withEndArrow">true</p:property><p:property name="mode">curvy</p:property><p:property name="detached">false</p:property><p:property name="strokeColor">#1B3280FF</p:property><p:property name="strokeStyle">2|</p:property><p:property name="textContent"/><p:property name="textFont">"Liberation Sans",Arial,sans-serif|normal|normal|13px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<defs>
<path style="stroke-linejoin: round; fill: none;" p:name="path" id="384134701047435fac995fc6eaee5932" d="M -87 -102 L -93 -108 L -87 -114 M -93 -108 C -37 -108 -109 -4 -53 -4 M -59 -10 L -53 -4 L -59 2"/>
</defs>
<use xlink:href="#384134701047435fac995fc6eaee5932" stroke-width="10" stroke-opacity="0" stroke="#FF0000"/>
<use xlink:href="#384134701047435fac995fc6eaee5932" p:name="outArrow1" id="14d921eb06d44f7d9acd062d2b01551a" style="stroke: rgb(27, 50, 128); stroke-opacity: 1; stroke-width: 2;"/>
<text p:name="text" id="5485420a3edb40669c089909c03dc1f8" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Liberation Sans&quot;, Arial, sans-serif; font-size: 13px; font-weight: normal; font-style: normal; text-decoration: none;">
<textPath xlink:href="#384134701047435fac995fc6eaee5932" startOffset="50%" text-anchor="middle" alignment-baseline="middle">
<tspan dy="-4.333333333333333" p:name="textSpan" id="428895865f0145dca4a5ff61843e80ef" dx="0"/>
</textPath>
</text>
</g><g p:type="Shape" p:def="Evolus.Common:Bitmap" id="b6ed13921fdd40f9a3eb0e1e3d0ecbe6" transform="matrix(1,0,0,1,1103,146)"><p:metadata><p:property name="box">195,276</p:property><p:property name="imageData">318,450,ref://7214557d80314d2ea0269f3a449d0000.png</p:property><p:property name="withBlur">false</p:property><p:property name="fillColor">#FFFFFF00</p:property><p:property name="strokeColor">#000000FF</p:property><p:property name="strokeStyle">0|</p:property></p:metadata>
<defs>
<filter height="1.2558399" y="-0.12792" width="1.06396" x="-0.03198" p:name="imageShading" id="45b9efdc21654623a49f9d3d92738b31">
<feGaussianBlur stdDeviation="1.3325" in="SourceAlpha"/>
</filter>
<g p:name="container" id="dc93c38161c8442faea0e63e5cbf5843">
<rect style="fill: rgb(255, 255, 255); stroke: rgb(0, 0, 0); stroke-opacity: 1; stroke-width: 0; fill-opacity: 0;" p:name="bgRect" id="62e29bf3081e4449ae9fc80c6c967b71" transform="translate(0,0)" width="195" height="276"/>
<g p:name="imageContainer" id="6f7191c994c644f183d02acf013570d0" transform="scale(0.6132075471698113,0.6133333333333333)">
<image x="0" y="0" p:name="image" id="a6b907023988404f8a2a4c4daeb1b81e" xlink:href="file:///tmp/tmp-27399CzGZUH8OkSfx/refs/7214557d80314d2ea0269f3a449d0000.png?token=1549194986000" width="318" height="450"/>
</g>
</g>
</defs>
<use xlink:href="#dc93c38161c8442faea0e63e5cbf5843" transform="translate(1, 1)" p:filter="url(#45b9efdc21654623a49f9d3d92738b31)" style="opacity: 0.6; visibility: hidden; display: none;" p:name="bgCopy" id="02792f50e6104ccc99ad1f691c8d3a5e"/>
<use xlink:href="#dc93c38161c8442faea0e63e5cbf5843"/>
</g><g p:type="Shape" p:def="Evolus.Common:arrow" id="7b94aab3e1cd494696d3b5cf838dfde6" transform="matrix(1,0,0,1,858,286)"><p:metadata><p:property name="startPin">0,0</p:property><p:property name="endPin">282,-4</p:property><p:property name="withStartArrow">true</p:property><p:property name="withEndArrow">true</p:property><p:property name="mode">curvy</p:property><p:property name="detached">false</p:property><p:property name="strokeColor">#1B3280FF</p:property><p:property name="strokeStyle">4|3,3</p:property><p:property name="textContent"/><p:property name="textFont">"Liberation Sans",Arial,sans-serif|normal|normal|13px|none</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textAlign">1,1</p:property></p:metadata>
<defs>
<path style="stroke-linejoin: round; fill: none;" p:name="path" id="b8c0a2b9697f46288c408540e8af57fa" d="M 11 11 L 0 0 L 11 -11 M 0 0 C 60 0 222 -3 282 -4 M 271 -15 L 282 -4 L 271 7"/>
</defs>
<use xlink:href="#b8c0a2b9697f46288c408540e8af57fa" stroke-width="10" stroke-opacity="0" stroke="#FF0000"/>
<use xlink:href="#b8c0a2b9697f46288c408540e8af57fa" p:name="outArrow1" id="97846f435e74416e996116a08ef664e4" style="stroke: rgb(27, 50, 128); stroke-opacity: 1; stroke-width: 4; stroke-dasharray: 3, 3;"/>
<text p:name="text" id="987b10b79cfa4658917b6bb36a6005fb" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Liberation Sans&quot;, Arial, sans-serif; font-size: 13px; font-weight: normal; font-style: normal; text-decoration: none;">
<textPath xlink:href="#b8c0a2b9697f46288c408540e8af57fa" startOffset="50%" text-anchor="middle" alignment-baseline="middle">
<tspan dy="-4.333333333333333" p:name="textSpan" id="667515745b224bb79dbd2e134284f6d2" dx="0"/>
</textPath>
</text>
</g><g p:type="Shape" p:def="Evolus.Common:PlainTextV2" p:sc="Label" id="bb91f7fb7faf445a834363edc2cb287a" transform="matrix(1,0,0,1,1034,157)"><p:metadata><p:property name="disabled">false</p:property><p:property name="width">100,0</p:property><p:property name="fixedWidth">false</p:property><p:property name="label">Mobilni telefon preko WiFi povezave upravlja spektrometer</p:property><p:property name="textColor">#000000FF</p:property><p:property name="textFont">'Comic Sans MS'|normal|normal|12px|none</p:property><p:property name="textAlign">0,0</p:property></p:metadata>
<rect x="0" y="0" style="fill: none; stroke: none; visibility: hidden; display: none;" p:name="bgRect" id="c2e343a9ad3246cdb047e5e01ee1fb42" width="332.390625" height="16.484375"/>
<text xml:space="preserve" p:name="text" id="357a8a3e3c4044bb8518698b7d607b60" style="fill: rgb(0, 0, 0); fill-opacity: 1; font-family: &quot;Comic Sans MS&quot;; font-size: 12px; font-weight: normal; font-style: normal; text-decoration: none;"><tspan x="0" y="0">Mobilni telefon preko WiFi povezave upravlja spektrometer</tspan></text>
</g></g></g></svg>

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

1
sensor_docs/sysprep.md Normal file
View File

@@ -0,0 +1 @@
# sysprep - How to prepare a Raspberry Pi 3 B+ to run TeraHz

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

45
utils/getcdata.py Normal file
View File

@@ -0,0 +1,45 @@
# 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)

12
utils/smbus-test.py Normal file
View File

@@ -0,0 +1,12 @@
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))

22
utils/tinter-demo.py Normal file
View File

@@ -0,0 +1,22 @@
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)