added my Recipes
@@ -0,0 +1,71 @@
|
||||
How to deploy demonstration:
|
||||
----------------------------
|
||||
Materials:
|
||||
* Nucleo extension board with mems, here IKS01A2
|
||||
* connection between extension board and stm32mp15 board.
|
||||
|
||||
Pre-requisite:
|
||||
--------------
|
||||
1. Kernel:
|
||||
You need to configure the kernel to support the Nucleo extension
|
||||
board with the devitree configuration and the kernel configuration.
|
||||
|
||||
1.1 DeviceTree:
|
||||
* Enable the sensor on I2C
|
||||
For Discovery board (stm32mp157c-dk2), the sensors are linked on ic25.
|
||||
Add the following line on your devicetree associateds to the board
|
||||
|
||||
&i2c5 {
|
||||
pinctrl-names = "default", "sleep";
|
||||
pinctrl-0 = <&i2c5_pins_a>;
|
||||
pinctrl-1 = <&i2c5_pins_sleep_a>;
|
||||
i2c-scl-rising-time-ns = <124>;
|
||||
i2c-scl-falling-time-ns = <3>;
|
||||
/delete-property/dmas;
|
||||
/delete-property/dma-names;
|
||||
|
||||
status = "okay";
|
||||
|
||||
hts221@5f {
|
||||
compatible = "st,hts221";
|
||||
reg = <0x5f>;
|
||||
};
|
||||
lsm6dsl@6b {
|
||||
compatible = "st,lsm6dsl";
|
||||
reg = <0x6b>;
|
||||
};
|
||||
};
|
||||
|
||||
NOTE: the i2c depend of the pin-muxing of the board and could be different of
|
||||
i2c5.
|
||||
|
||||
1.2 Kernel configuration:
|
||||
Add the following config on your kernel configuraturation
|
||||
(best way are via a new fragment)
|
||||
CONFIG_IIO_BUFFER=y
|
||||
CONFIG_IIO_KFIFO_BUF=y
|
||||
CONFIG_IIO_TRIGGERED_BUFFER=y
|
||||
CONFIG_HTS221=y
|
||||
CONFIG_IIO_ST_PRESS=y
|
||||
CONFIG_IIO_ST_LSM6DSX=y
|
||||
CONFIG_IIO_ST_LSM6DSX_I2C=y
|
||||
|
||||
2. Software
|
||||
You need to have some framework available on the board for executing the
|
||||
python script:
|
||||
|
||||
List of packages already present on st-example-image-weston:
|
||||
weston
|
||||
gtk+3
|
||||
python3 and several python3 addons
|
||||
|
||||
Execution of script on board:
|
||||
-----------------------------
|
||||
Files:
|
||||
/usr/local/demo/
|
||||
/usr/local/demo/sensors_temperature.py
|
||||
|
||||
Put the files on board and launch the python script:
|
||||
BOARD > /usr/local/demo/sensors_temperature.py
|
||||
|
||||
To quit the application, just click on ST logo.
|
||||
@@ -0,0 +1,7 @@
|
||||
CONFIG_IIO_BUFFER=y
|
||||
CONFIG_IIO_KFIFO_BUF=y
|
||||
CONFIG_IIO_TRIGGERED_BUFFER=y
|
||||
CONFIG_HTS221=y
|
||||
CONFIG_IIO_ST_PRESS=y
|
||||
CONFIG_IIO_ST_LSM6DSX=y
|
||||
CONFIG_IIO_ST_LSM6DSX_I2C=y
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 61 KiB |
269
meta-st/meta-st-openstlinux/recipes-samples/demo/sensors-iks01a2/sensor.py
Executable file
@@ -0,0 +1,269 @@
|
||||
#!/usr/bin/python3
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import GLib
|
||||
from gi.repository import GdkPixbuf
|
||||
import cairo
|
||||
|
||||
import random
|
||||
import math
|
||||
import os
|
||||
from time import sleep, time
|
||||
|
||||
# time between each sensor mesearuement (1s)
|
||||
TIME_UPATE = 2000
|
||||
|
||||
|
||||
class Sensors():
|
||||
def __init__(self):
|
||||
''' '''
|
||||
self.sensor_dictionnary = {}
|
||||
|
||||
def found_iio_device_with_name(self, data, name):
|
||||
prefix = "/sys/bus/iio/devices/"
|
||||
of_name = 'OF_NAME=' + name
|
||||
try:
|
||||
for filefolder in os.listdir(prefix):
|
||||
with open(prefix + '/' + filefolder + '/uevent') as f:
|
||||
for line in f:
|
||||
if line.split('\n')[0] == of_name:
|
||||
''' return directory which contains "data" '''
|
||||
if os.path.exists(prefix + '/' + filefolder + '/' + data):
|
||||
return (prefix + '/' + filefolder + '/')
|
||||
except OSError:
|
||||
pass
|
||||
except Exception as exc:
|
||||
pass
|
||||
return None
|
||||
|
||||
def found_all_sensor_path(self):
|
||||
self.sensor_dictionnary['temperature'] = self.found_iio_device_with_name("in_temp_raw", "hts221")
|
||||
self.sensor_dictionnary['humidity'] = self.found_iio_device_with_name("in_humidityrelative_raw", "hts221")
|
||||
self.sensor_dictionnary['accelerometer'] = self.found_iio_device_with_name("in_accel_x_raw", "lsm6dsl")
|
||||
self.sensor_dictionnary['gyroscope'] = self.found_iio_device_with_name("in_anglvel_x_raw", "lsm6dsl")
|
||||
|
||||
print("[DEBUG] temperature -> ", self.sensor_dictionnary['temperature'], "<")
|
||||
print("[DEBUG] humidity -> ", self.sensor_dictionnary['humidity'], "<")
|
||||
print("[DEBUG] accelerometer -> ", self.sensor_dictionnary['accelerometer'], "<")
|
||||
print("[DEBUG] gyroscope -> ", self.sensor_dictionnary['gyroscope'], "<")
|
||||
|
||||
def temperature_read(self):
|
||||
prefix_path = self.sensor_dictionnary['temperature']
|
||||
try:
|
||||
with open(prefix_path + "in_temp_" + 'raw', 'r') as f:
|
||||
raw = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_temp_" + 'raw', exc)
|
||||
raw = 0.0
|
||||
try:
|
||||
with open(prefix_path + "in_temp_" + 'scale', 'r') as f:
|
||||
scale = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_temp_" + 'scale', exc)
|
||||
scale = 0.0
|
||||
try:
|
||||
with open(prefix_path + "in_temp_" + 'offset', 'r') as f:
|
||||
offset = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_temp_" + 'offset', exc)
|
||||
offset = 0.0
|
||||
return (offset + raw) * scale
|
||||
|
||||
def humidity_read(self):
|
||||
prefix_path = self.sensor_dictionnary['humidity']
|
||||
try:
|
||||
with open(prefix_path + "in_humidityrelative_" + 'raw', 'r') as f:
|
||||
raw = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'raw', exc)
|
||||
raw = 0.0
|
||||
try:
|
||||
with open(prefix_path + "in_humidityrelative_" + 'scale', 'r') as f:
|
||||
scale = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'scale', exc)
|
||||
scale = 0.0
|
||||
try:
|
||||
with open(prefix_path + "in_humidityrelative_" + 'offset', 'r') as f:
|
||||
offset = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_humidityrelative_" + 'offset', exc)
|
||||
offset = 0.0
|
||||
return (offset + raw) * scale
|
||||
|
||||
def accelerometer_read(self):
|
||||
prefix_path = self.sensor_dictionnary['accelerometer']
|
||||
try:
|
||||
with open(prefix_path + "in_accel_" + 'scale', 'r') as f:
|
||||
rscale = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_accel_" + 'scale', exc)
|
||||
rscale = 0.0
|
||||
|
||||
try:
|
||||
with open(prefix_path + "in_accel_" + 'x_raw', 'r') as f:
|
||||
xraw = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_accel_" + 'x_raw', exc)
|
||||
xraw = 0.0
|
||||
accel_x = int(xraw * rscale * 256.0 / 9.81)
|
||||
|
||||
try:
|
||||
with open(prefix_path + "in_accel_" + 'y_raw', 'r') as f:
|
||||
yraw = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_accel_" + 'y_raw', exc)
|
||||
yraw = 0.0
|
||||
accel_y = int(yraw * rscale * 256.0 / 9.81)
|
||||
|
||||
try:
|
||||
with open(prefix_path + "in_accel_" + 'z_raw', 'r') as f:
|
||||
zraw = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_accel_" + 'z_raw', exc)
|
||||
zraw = 0.0
|
||||
accel_z = int(zraw * rscale * 256.0 / 9.81)
|
||||
|
||||
return [ accel_x, accel_y, accel_z]
|
||||
|
||||
def gyroscope_read(self):
|
||||
prefix_path = self.sensor_dictionnary['gyroscope']
|
||||
try:
|
||||
with open(prefix_path + "in_anglvel_" + 'scale', 'r') as f:
|
||||
rscale = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'scale', exc)
|
||||
rscale = 0.0
|
||||
|
||||
try:
|
||||
with open(prefix_path + "in_anglvel_" + 'x_raw', 'r') as f:
|
||||
xraw = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'x_raw', exc)
|
||||
xraw = 0.0
|
||||
gyro_x = int(xraw * rscale * 256.0 / 9.81)
|
||||
|
||||
try:
|
||||
with open(prefix_path + "in_anglvel_" + 'y_raw', 'r') as f:
|
||||
yraw = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'y_raw', exc)
|
||||
yraw = 0.0
|
||||
gyro_y = int(yraw * rscale * 256.0 / 9.81)
|
||||
|
||||
try:
|
||||
with open(prefix_path + "in_anglvel_" + 'z_raw', 'r') as f:
|
||||
zraw = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % prefix_path + "in_anglvel_" + 'z_raw', exc)
|
||||
zraw = 0.0
|
||||
gyro_z = int(zraw * rscale * 256.0 / 9.81)
|
||||
|
||||
return [ gyro_x, gyro_y, gyro_z]
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------
|
||||
class MainUIWindow(Gtk.Window):
|
||||
def __init__(self):
|
||||
Gtk.Window.__init__(self, title="Sensor usage")
|
||||
#self.set_decorated(False)
|
||||
self.maximize()
|
||||
self.screen_width = self.get_screen().get_width()
|
||||
self.screen_height = self.get_screen().get_height()
|
||||
|
||||
self.set_default_size(self.screen_width, self.screen_height)
|
||||
print("[DEBUG] screen size: %dx%d" % (self.screen_width, self.screen_height))
|
||||
self.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.connect('destroy', Gtk.main_quit)
|
||||
|
||||
# search sensor interface
|
||||
self.sensors = Sensors()
|
||||
self.sensors.found_all_sensor_path()
|
||||
|
||||
sensor_box = Gtk.VBox(homogeneous=False, spacing=0)
|
||||
|
||||
# temperature
|
||||
temp_label = Gtk.Label()
|
||||
temp_label.set_markup("<span font_desc='LiberationSans 25'>Temperature</span>")
|
||||
self.temp_value_label = Gtk.Label()
|
||||
self.temp_value_label.set_markup("<span font_desc='LiberationSans 25'>--.-- °C</span>")
|
||||
temp_box = Gtk.HBox(homogeneous=False, spacing=0)
|
||||
temp_box.add(temp_label)
|
||||
temp_box.add(self.temp_value_label)
|
||||
sensor_box.add(temp_box)
|
||||
|
||||
# humidity
|
||||
humidity_label = Gtk.Label()
|
||||
humidity_label.set_markup("<span font_desc='LiberationSans 25'>Humidity</span>")
|
||||
self.humidity_value_label = Gtk.Label()
|
||||
self.humidity_value_label.set_markup("<span font_desc='LiberationSans 25'>--.-- %c</span>" % '%')
|
||||
humidity_box = Gtk.HBox(homogeneous=False, spacing=0)
|
||||
humidity_box.add(humidity_label)
|
||||
humidity_box.add(self.humidity_value_label)
|
||||
sensor_box.add(humidity_box)
|
||||
|
||||
# Accel
|
||||
accel_label = Gtk.Label()
|
||||
accel_label.set_markup("<span font_desc='LiberationSans 25'>Accelerometer</span>")
|
||||
self.accel_value_label = Gtk.Label()
|
||||
self.accel_value_label.set_markup("<span font_desc='LiberationSans 25'> [ --.--, --.--, --.--]</span>")
|
||||
accel_box = Gtk.HBox(homogeneous=False, spacing=0)
|
||||
accel_box.add(accel_label)
|
||||
accel_box.add(self.accel_value_label)
|
||||
sensor_box.add(accel_box)
|
||||
|
||||
# Gyroscope
|
||||
gyro_label = Gtk.Label()
|
||||
gyro_label.set_markup("<span font_desc='LiberationSans 25'>Gyroscope</span>")
|
||||
self.gyro_value_label = Gtk.Label()
|
||||
self.gyro_value_label.set_markup("<span font_desc='LiberationSans 25'> [ --.--, --.--, --.--]</span>")
|
||||
gyro_box = Gtk.HBox(homogeneous=False, spacing=0)
|
||||
gyro_box.add(gyro_label)
|
||||
gyro_box.add(self.gyro_value_label)
|
||||
sensor_box.add(gyro_box)
|
||||
|
||||
self.add(sensor_box)
|
||||
|
||||
# Add a timer callback to update
|
||||
# this takes 2 args: (how often to update in millisec, the method to run)
|
||||
GLib.timeout_add(TIME_UPATE, self.update_ui)
|
||||
|
||||
|
||||
def destroy(self, widget, data=None):
|
||||
Gtk.main_quit()
|
||||
|
||||
|
||||
def update_ui(self):
|
||||
# temperature
|
||||
temp = self.sensors.temperature_read()
|
||||
self.temp_value_label.set_markup("<span font_desc='LiberationSans 25'>%.02f °C</span>" % temp)
|
||||
# humidity
|
||||
hum = self.sensors.humidity_read()
|
||||
self.humidity_value_label.set_markup("<span font_desc='LiberationSans 25'>%.02f %c</span>" % (hum, '%'))
|
||||
# accel
|
||||
accel = self.sensors.accelerometer_read()
|
||||
self.accel_value_label.set_markup("<span font_desc='LiberationSans 25'>[ %.02f, %.02f, %.02f]</span>" % (accel[0], accel[1], accel[2]))
|
||||
# gyro
|
||||
gyro = self.sensors.gyroscope_read()
|
||||
self.gyro_value_label.set_markup("<span font_desc='LiberationSans 25'>[ %.02f, %.02f, %.02f]</span>" % (gyro[0], gyro[1], gyro[2]))
|
||||
|
||||
# As this is a timeout function, return True so that it
|
||||
# continues to get called
|
||||
return True
|
||||
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------
|
||||
# Main
|
||||
if __name__ == "__main__":
|
||||
# add signal to catch CRTL+C
|
||||
import signal
|
||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
win = MainUIWindow()
|
||||
win.connect("delete-event", Gtk.main_quit)
|
||||
win.show_all()
|
||||
|
||||
Gtk.main()
|
||||
91
meta-st/meta-st-openstlinux/recipes-samples/demo/sensors-iks01a2/sensor.sh
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/bin/sh
|
||||
|
||||
for d in `ls -d1 /sys/bus/iio/devices/*device*`;
|
||||
do
|
||||
# for hts221: Temperature + Humidity
|
||||
if grep -q hts221 $d/name ;
|
||||
then
|
||||
echo "============================="
|
||||
echo "=== HTS221 ==="
|
||||
echo "=== (temperature) ==="
|
||||
echo "============================="
|
||||
raw=`cat $d/in_temp_raw`
|
||||
offset=`cat $d/in_temp_offset`
|
||||
scale=`cat $d/in_temp_scale`
|
||||
|
||||
printf "Value read: raw %0f\n" $raw
|
||||
printf "Value read: offset %0f\n" $offset
|
||||
printf "Value read: scale %0f\n" $scale
|
||||
|
||||
temperature=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`
|
||||
|
||||
echo "Temperature $temperature"
|
||||
printf "Temperature %.02f\n" $temperature
|
||||
|
||||
echo "============================="
|
||||
echo "=== HTS221 ==="
|
||||
echo "=== (humidity) ==="
|
||||
echo "============================="
|
||||
raw=`cat $d/in_humidityrelative_raw`
|
||||
offset=`cat $d/in_humidityrelative_offset`
|
||||
scale=`cat $d/in_humidityrelative_scale`
|
||||
|
||||
printf "Value read: raw %0f\n" $raw
|
||||
printf "Value read: offset %0f\n" $offset
|
||||
printf "Value read: scale %0f\n" $scale
|
||||
|
||||
humidity=`echo "scale=2;$raw*$scale + $offset*$scale" | bc`
|
||||
|
||||
echo "Humidity $humidity"
|
||||
printf "Humidity %.02f\n" $humidity
|
||||
fi
|
||||
|
||||
# for lsm6dsl: accelerometer
|
||||
if grep -q lsm6dsl_accel $d/name ;
|
||||
then
|
||||
echo "============================="
|
||||
echo "=== LSM6DSL ==="
|
||||
echo "=== (accelerometer) ==="
|
||||
echo "============================="
|
||||
rscale=`cat $d/in_accel_scale`
|
||||
|
||||
xraw=`cat $d/in_accel_x_raw`
|
||||
yraw=`cat $d/in_accel_y_raw`
|
||||
zraw=`cat $d/in_accel_z_raw`
|
||||
|
||||
printf "Value read: X (raw/scale) %d / %.06f \n" $xraw $rscale
|
||||
printf "Value read: Y (raw/scale) %d / %.06f \n" $yraw $rscale
|
||||
printf "Value read: Z (raw/scale) %d / %.06f \n" $zraw $rscale
|
||||
|
||||
factor=`echo "scale=2;256.0 / 9.81" | bc`
|
||||
xval=`echo "scale=2;$xraw*$rscale*$factor" | bc`
|
||||
yval=`echo "scale=2;$yraw*$rscale*$factor" | bc`
|
||||
zval=`echo "scale=2;$zraw*$rscale*$factor" | bc`
|
||||
|
||||
printf "Accelerometer value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
|
||||
fi
|
||||
|
||||
# for lsm6dsl: gyroscope
|
||||
if grep -q lsm6dsl_gyro $d/name ;
|
||||
then
|
||||
echo "============================="
|
||||
echo "=== LSM6DSL ==="
|
||||
echo "=== (gyroscope) ==="
|
||||
echo "============================="
|
||||
rscale=`cat $d/in_anglvel_scale`
|
||||
xraw=`cat $d/in_anglvel_x_raw`
|
||||
yraw=`cat $d/in_anglvel_y_raw`
|
||||
zraw=`cat $d/in_anglvel_z_raw`
|
||||
|
||||
printf "Value read: X (raw/scale) %d / %.06f \n" $xraw $rscale
|
||||
printf "Value read: Y (raw/scale) %d / %.06f \n" $yraw $rscale
|
||||
printf "Value read: Z (raw/scale) %d / %.06f \n" $zraw $rscale
|
||||
|
||||
factor=`echo "scale=2;256.0 / 9.81" | bc`
|
||||
xval=`echo "scale=2;$xraw*$rscale*$factor" | bc`
|
||||
yval=`echo "scale=2;$yraw*$rscale*$factor" | bc`
|
||||
zval=`echo "scale=2;$zraw*$rscale*$factor" | bc`
|
||||
|
||||
printf "Gyroscope value: [ %.02f, %.02f, %.02f ]\n" $xval $yval $zval
|
||||
fi
|
||||
done
|
||||
@@ -0,0 +1,767 @@
|
||||
#!/usr/bin/python3
|
||||
# to debug this script:
|
||||
# python3 -m pdb ./sensors_temperature.py
|
||||
#
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gdk
|
||||
from gi.repository import GLib
|
||||
from gi.repository import GdkPixbuf
|
||||
import cairo
|
||||
|
||||
import random
|
||||
import math
|
||||
import os
|
||||
import socket
|
||||
from collections import deque
|
||||
from time import sleep, time
|
||||
|
||||
#
|
||||
# For simulating the presence of sensor, please use
|
||||
# the variable SIMULATE_SENSORS = 1
|
||||
# If SIMULATE_SENSORS = 1 then
|
||||
# the picture/icon must be present on pictures directory
|
||||
#
|
||||
SIMULATE_SENSORS = 0
|
||||
|
||||
ICON_PICTURES_PATH = "/usr/local/demo/pictures"
|
||||
|
||||
WITH_PRESSURE = 0
|
||||
WITH_GYRO = 1
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------
|
||||
# CONSTANT VALUES
|
||||
#
|
||||
SIMULATE_SCREEN_SIZE_WIDTH = 480
|
||||
SIMULATE_SCREEN_SIZE_HEIGHT = 800
|
||||
DEFAULT_SCREEN_WIDTH = 400
|
||||
DEFAULT_SCREEN_HEIGHT = 600
|
||||
|
||||
# time between each sensor mesearuement (1s)
|
||||
TIME_UPATE = 2000
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------
|
||||
# SPLASH SCREEN class
|
||||
# the splash screen display a logo and the different step of boot
|
||||
#
|
||||
class SplashScreen():
|
||||
def __init__(self, picture_filename, timeout):
|
||||
#DONT connect 'destroy' event here!
|
||||
self.window = Gtk.Window()
|
||||
self.window.set_title('Sensor IKS01A2')
|
||||
self.window.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.window.set_decorated(False)
|
||||
if SIMULATE_SENSORS > 0:
|
||||
screen_width = SIMULATE_SCREEN_SIZE_WIDTH
|
||||
screen_height = SIMULATE_SCREEN_SIZE_HEIGHT
|
||||
else:
|
||||
self.window.fullscreen()
|
||||
#self.maximize()
|
||||
screen_width = self.window.get_screen().get_width()
|
||||
screen_height = self.window.get_screen().get_height()
|
||||
|
||||
self.window.set_default_size(screen_width, screen_height)
|
||||
self.window.set_border_width(1)
|
||||
|
||||
# Add Vbox with image and label
|
||||
main_vbox = Gtk.VBox(False, 1)
|
||||
self.window.add(main_vbox)
|
||||
# load picture
|
||||
print("[DEBUG] Splash screen with picture: %s" % picture_filename)
|
||||
if os.path.exists(picture_filename):
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
|
||||
filename=picture_filename,
|
||||
width=400, # TODO: change size
|
||||
height=600, # TODO: change size
|
||||
preserve_aspect_ratio=True)
|
||||
image = Gtk.Image.new_from_pixbuf(pixbuf)
|
||||
main_vbox.pack_start(image, True, True, 0)
|
||||
|
||||
#self.lbl = Gtk.Label("Init: splash screen")
|
||||
#self.lbl.set_alignment(0, 0.5)
|
||||
#main_vbox.pack_start(self.lbl, True, True, 0)
|
||||
|
||||
self.window.set_auto_startup_notification(False)
|
||||
self.window.show_all()
|
||||
self.window.set_auto_startup_notification(True)
|
||||
|
||||
# Ensure the splash is completely drawn before moving on
|
||||
GLib.timeout_add(1000, self.loop)
|
||||
self.loops = 0
|
||||
self.loops_timeout = timeout
|
||||
self.loops_break = 0
|
||||
|
||||
def update_text(self, text):
|
||||
self.lbl.set_text(text)
|
||||
|
||||
def loop_stop(self):
|
||||
self.loops_break = 1
|
||||
|
||||
def loop(self):
|
||||
global var
|
||||
var = time ()
|
||||
print ("[DEBUG] ", var)
|
||||
self.loops += 1
|
||||
if self.loops_break or self.loops == self.loops_timeout:
|
||||
Gtk.main_quit()
|
||||
self.window.destroy()
|
||||
return False
|
||||
return True
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------
|
||||
def _load_image_on_button(parent, filename, label_text, scale_w, scale_h):
|
||||
# Create box for xpm and label
|
||||
box1 = Gtk.HBox(homogeneous=False, spacing=0)
|
||||
box1.set_border_width(2)
|
||||
# Now on to the image stuff
|
||||
#image = Gtk.Image()
|
||||
#image.set_from_file(filename)
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
|
||||
filename=filename,
|
||||
width=scale_w,
|
||||
height=scale_h,
|
||||
preserve_aspect_ratio=True)
|
||||
image = Gtk.Image.new_from_pixbuf(pixbuf)
|
||||
|
||||
# Create a label for the button
|
||||
label = Gtk.Label(label_text)
|
||||
|
||||
# Pack the pixmap and label into the box
|
||||
box1.pack_start(image, True, False, 3)
|
||||
#box1.pack_start(label, False, False, 3)
|
||||
|
||||
image.show()
|
||||
label.show()
|
||||
return box1
|
||||
# -------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------
|
||||
def _load_image(parent, filename_without_prefix):
|
||||
img = Gtk.Image()
|
||||
img.set_from_file("%s/%s" % (ICON_PICTURES_PATH, filename_without_prefix))
|
||||
return img
|
||||
|
||||
# scale_width and scale_height are sht siez disired after scale,
|
||||
# It can be -1 for no scale on one value
|
||||
def _load_image_constrained(parent, filename_without_prefix, scale_width, scale_height):
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
|
||||
filename="%s/%s" % (ICON_PICTURES_PATH, filename_without_prefix),
|
||||
width=scale_width,
|
||||
height=scale_height,
|
||||
preserve_aspect_ratio=True)
|
||||
image = Gtk.Image.new_from_pixbuf(pixbuf)
|
||||
return image
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------
|
||||
class Sensors():
|
||||
key_temperature = 'temp'
|
||||
key_humidity = 'humidity'
|
||||
key_pressure = 'pressure'
|
||||
|
||||
key_accelerometer = 'accel'
|
||||
key_gyroscope = 'gyro'
|
||||
key_magnetometer = 'magneto'
|
||||
|
||||
driver_name_temperature = 'driver_temp'
|
||||
driver_name_humidity = 'driver_humidity'
|
||||
driver_name_pressure = 'driver_pressure'
|
||||
driver_name_accelerometer = 'driver_accel'
|
||||
driver_name_gyroscope = 'driver_gyro'
|
||||
driver_name_magnetometer = 'driver_magneto'
|
||||
|
||||
|
||||
prefix_temp = "in_temp_"
|
||||
prefix_humidity = "in_humidityrelative_"
|
||||
prefix_pressure = "in_pressure_"
|
||||
|
||||
prefix_accel = "in_accel_"
|
||||
prefix_gyro = "in_anglvel_"
|
||||
prefix_magneto = "in_magn_" # TODO: verify
|
||||
|
||||
def __init__(self):
|
||||
''' '''
|
||||
self.sensor_dictionnary = {}
|
||||
|
||||
def init_pressure_sampling_frequency(self):
|
||||
if not self.sensor_dictionnary[self.key_pressure] is None and len(self.sensor_dictionnary[self.key_pressure]) > 5:
|
||||
with open(self.sensor_dictionnary[self.key_pressure] + 'sampling_frequency', 'w') as f:
|
||||
f.write('10')
|
||||
|
||||
def found_iio_device(self, data):
|
||||
prefix = "/sys/bus/iio/devices/"
|
||||
try:
|
||||
for filefolder in os.listdir(prefix):
|
||||
if os.path.exists(prefix + '/' + filefolder + '/' + data):
|
||||
''' return directory which contains "data" '''
|
||||
return (prefix + '/' + filefolder + '/')
|
||||
except OSError:
|
||||
pass
|
||||
return None
|
||||
|
||||
def found_iio_device_with_name(self, data, name):
|
||||
prefix = "/sys/bus/iio/devices/"
|
||||
of_name = 'OF_NAME=' + name
|
||||
try:
|
||||
for filefolder in os.listdir(prefix):
|
||||
with open(prefix + '/' + filefolder + '/uevent') as f:
|
||||
for line in f:
|
||||
if line.split('\n')[0] == of_name:
|
||||
''' return directory which contains "data" '''
|
||||
if os.path.exists(prefix + '/' + filefolder + '/' + data):
|
||||
return (prefix + '/' + filefolder + '/')
|
||||
except OSError:
|
||||
pass
|
||||
except Exception as exc:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def driver_name_iio_device(self, key):
|
||||
if SIMULATE_SENSORS > 0:
|
||||
val_name = "-Simulated-"
|
||||
else:
|
||||
if self.sensor_dictionnary[key] == None:
|
||||
val_name = "-Not present / Simulated-"
|
||||
else:
|
||||
try:
|
||||
with open(self.sensor_dictionnary[key] + "name", 'r') as f:
|
||||
val_name = f.read()
|
||||
except Exception as exc:
|
||||
val_name = "-Not present-"
|
||||
return val_name
|
||||
|
||||
def found_all_sensor_path(self):
|
||||
self.sensor_dictionnary[self.key_temperature] = self.found_iio_device_with_name("in_temp_raw", "hts221")
|
||||
self.sensor_dictionnary[self.key_humidity] = self.found_iio_device("in_humidityrelative_raw")
|
||||
self.sensor_dictionnary[self.key_pressure] = self.found_iio_device("in_pressure_raw")
|
||||
|
||||
self.sensor_dictionnary[self.key_accelerometer] = self.found_iio_device("in_accel_x_raw")
|
||||
if WITH_GYRO:
|
||||
self.sensor_dictionnary[self.key_gyroscope] = self.found_iio_device("in_anglvel_x_raw")
|
||||
else:
|
||||
self.sensor_dictionnary[self.key_gyroscope] = ""
|
||||
|
||||
self.sensor_dictionnary[self.key_magnetometer] = "" #TODO
|
||||
|
||||
self.sensor_dictionnary[self.driver_name_temperature] = self.driver_name_iio_device(self.key_temperature)
|
||||
self.sensor_dictionnary[self.driver_name_humidity] = self.driver_name_iio_device(self.key_humidity)
|
||||
self.sensor_dictionnary[self.driver_name_pressure] = self.driver_name_iio_device(self.key_pressure)
|
||||
|
||||
self.sensor_dictionnary[self.driver_name_accelerometer] = self.driver_name_iio_device(self.key_accelerometer)
|
||||
self.sensor_dictionnary[self.driver_name_gyroscope] = self.driver_name_iio_device(self.key_gyroscope)
|
||||
self.sensor_dictionnary[self.driver_name_magnetometer] = self.driver_name_iio_device(self.key_magnetometer)
|
||||
|
||||
self.init_pressure_sampling_frequency()
|
||||
print("[DEBUG] " , self.key_temperature, " -> ", self.sensor_dictionnary[self.key_temperature], "<")
|
||||
print("[DEBUG] " , self.key_humidity, " -> ", self.sensor_dictionnary[self.key_humidity], "<")
|
||||
print("[DEBUG] " , self.key_pressure, " -> ", self.sensor_dictionnary[self.key_pressure], "<")
|
||||
print("[DEBUG] " , self.key_accelerometer, " -> ", self.sensor_dictionnary[self.key_accelerometer], "<")
|
||||
print("[DEBUG] " , self.key_gyroscope, " -> ", self.sensor_dictionnary[self.key_gyroscope], "<")
|
||||
print("[DEBUG] " , self.key_magnetometer, " -> ", self.sensor_dictionnary[self.key_magnetometer], "<")
|
||||
|
||||
|
||||
def read_sensor_basic(self, key, prefix):
|
||||
if SIMULATE_SENSORS > 0:
|
||||
if self.key_temperature == key:
|
||||
return random.uniform(0.0, 50.0)
|
||||
elif self.key_humidity == key:
|
||||
return random.uniform(0.0, 100.0)
|
||||
else:
|
||||
return random.uniform(800.0, 1200.0)
|
||||
else:
|
||||
if self.sensor_dictionnary[key] is None or len(self.sensor_dictionnary[key]) < 5:
|
||||
return 0.0
|
||||
try:
|
||||
with open(self.sensor_dictionnary[key] + prefix + 'raw', 'r') as f:
|
||||
raw = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % self.sensor_dictionnary[key] + prefix + 'raw', exc)
|
||||
raw = 0.0
|
||||
try:
|
||||
with open(self.sensor_dictionnary[key] + prefix + 'scale', 'r') as f:
|
||||
scale = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % self.sensor_dictionnary[key] + prefix + 'scale', exc)
|
||||
scale = 0.0
|
||||
if self.key_pressure != key:
|
||||
try:
|
||||
with open(self.sensor_dictionnary[key] + prefix + 'offset', 'r') as f:
|
||||
offset = float(f.read())
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % self.sensor_dictionnary[key] + prefix + 'offset', exc)
|
||||
offset = 0.0
|
||||
else:
|
||||
offset = 0.0
|
||||
scale = scale * 10
|
||||
|
||||
temp = (offset + raw) * scale
|
||||
#print("[DEBUG] [%s] %f" % (key, temp))
|
||||
return temp
|
||||
def read_sensor_move(self, key, prefix):
|
||||
if SIMULATE_SENSORS > 0:
|
||||
in_x = random.randint(-180, 180)
|
||||
in_y = random.randint(-180, 180)
|
||||
in_z = random.randint(-180, 180)
|
||||
return [in_x, in_y, in_z]
|
||||
else:
|
||||
if self.sensor_dictionnary[key] is None or len(self.sensor_dictionnary[key]) < 5:
|
||||
return [0, 0, 0]
|
||||
try:
|
||||
with open(self.sensor_dictionnary[key] + prefix + 'x_raw', 'r') as f:
|
||||
scale = float(f.read())
|
||||
with open(self.sensor_dictionnary[key] + prefix + 'x_scale', 'r') as f:
|
||||
raw = float(f.read())
|
||||
in_x = int(raw * scale * 256.0 / 9.81)
|
||||
with open(self.sensor_dictionnary[key] + prefix + 'y_raw', 'r') as f:
|
||||
scale = float(f.read())
|
||||
with open(self.sensor_dictionnary[key] + prefix + 'y_scale', 'r') as f:
|
||||
raw = float(f.read())
|
||||
in_y = int(raw * scale * 256.0 / 9.81)
|
||||
with open(self.sensor_dictionnary[key] + prefix + 'z_raw', 'r') as f:
|
||||
scale = float(f.read())
|
||||
with open(self.sensor_dictionnary[key] + prefix + 'z_scale', 'r') as f:
|
||||
raw = float(f.read())
|
||||
in_z = int(raw * scale * 256.0 / 9.81)
|
||||
except Exception as exc:
|
||||
print("[ERROR] read %s " % self.sensor_dictionnary[key] + prefix + '[x_ , y_ , z_ ]', exc)
|
||||
return [0, 0, 0]
|
||||
return [in_x, in_y, in_z]
|
||||
|
||||
def read_temperature(self):
|
||||
return self.read_sensor_basic(self.key_temperature, self.prefix_temp)
|
||||
def read_humidity(self):
|
||||
return self.read_sensor_basic(self.key_humidity, self.prefix_humidity)
|
||||
def read_pressure(self):
|
||||
return self.read_sensor_basic(self.key_pressure, self.prefix_pressure)
|
||||
|
||||
def read_accelerometer(self):
|
||||
return self.read_sensor_move(self.key_accelerometer, self.prefix_accel)
|
||||
def read_gyroscope(self):
|
||||
return self.read_sensor_move(self.key_gyroscope, self.prefix_gyro)
|
||||
def read_magnetometer(self):
|
||||
return self.read_sensor_move(self.key_magnetometer, self.prefix_magneto)
|
||||
|
||||
def get_driver_name_temperature(self):
|
||||
return self.sensor_dictionnary[self.driver_name_temperature]
|
||||
def get_driver_name_humidity(self):
|
||||
return self.sensor_dictionnary[self.driver_name_humidity]
|
||||
def get_driver_name_pressure(self):
|
||||
return self.sensor_dictionnary[self.driver_name_pressure]
|
||||
def get_driver_name_accelerometer(self):
|
||||
return self.sensor_dictionnary[self.driver_name_accelerometer]
|
||||
def get_driver_name_gyroscope(self):
|
||||
return self.sensor_dictionnary[self.driver_name_gyroscope]
|
||||
def get_driver_name_magnetometer(self):
|
||||
return self.sensor_dictionnary[self.driver_name_magnetometer]
|
||||
|
||||
def calculate_imu(self, accel):
|
||||
x = accel[0]
|
||||
y = accel[1]
|
||||
z = accel[2]
|
||||
if x == 0 and y == 0 and z == 0:
|
||||
return [0, 0, 0]
|
||||
pitch = round(math.atan(x / math.sqrt(y * y + z * z)) * (180.0 / math.pi))
|
||||
roll = round(math.atan(y / math.sqrt(x * x + z * z)) * (180.0 / math.pi))
|
||||
yaw = round(math.atan(z / math.sqrt(x * x + z * z)) * (180.0 / math.pi))
|
||||
|
||||
return [pitch, roll, yaw]
|
||||
def get_imu_orientation(self, pitch, roll):
|
||||
if abs(pitch) > 35:
|
||||
''' (rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;'''
|
||||
if pitch > 0:
|
||||
return "left-up"
|
||||
else:
|
||||
return "right-up"
|
||||
else:
|
||||
if abs(roll) > 35:
|
||||
'''ret = (rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;'''
|
||||
if roll > 0:
|
||||
return "bottom-up"
|
||||
else:
|
||||
return "normal"
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------
|
||||
class MainUIWindow(Gtk.Window):
|
||||
def __init__(self):
|
||||
Gtk.Window.__init__(self, title="Sensor usage")
|
||||
self.set_decorated(False)
|
||||
if SIMULATE_SENSORS > 0:
|
||||
self.screen_width = SIMULATE_SCREEN_SIZE_WIDTH
|
||||
self.screen_height = SIMULATE_SCREEN_SIZE_HEIGHT
|
||||
else:
|
||||
self.fullscreen()
|
||||
#self.maximize()
|
||||
self.screen_width = self.get_screen().get_width()
|
||||
self.screen_height = self.get_screen().get_height()
|
||||
|
||||
self.set_default_size(self.screen_width, self.screen_height)
|
||||
print("[DEBUG] screen size: %dx%d" % (self.screen_width, self.screen_height))
|
||||
self.set_position(Gtk.WindowPosition.CENTER)
|
||||
self.connect('destroy', Gtk.main_quit)
|
||||
|
||||
# search sensor interface
|
||||
self.sensors = Sensors()
|
||||
self.sensors.found_all_sensor_path()
|
||||
|
||||
# variable for sensor
|
||||
self._axis_ranges = {} # {axis_num: [min_seen, max_seen]}
|
||||
self._axis_values = {} # {axis_num: deque([val0, ..., valN])}
|
||||
# create nodebook
|
||||
self.notebook = Gtk.Notebook()
|
||||
self.add(self.notebook)
|
||||
|
||||
# page for basic information
|
||||
# current temperature / Humidity / Pressure
|
||||
self.create_notebook_page_basic_sensor()
|
||||
|
||||
# page for accel / gyro / magentic
|
||||
self.create_notebook_page_basic_accel()
|
||||
|
||||
# page for IMU
|
||||
self.create_notebook_page_imu()
|
||||
|
||||
# page sensor information
|
||||
self.create_notebook_page_sensor_information()
|
||||
|
||||
# page for quitting application
|
||||
self.create_notebook_page_exit()
|
||||
|
||||
# Add a timer callback to update
|
||||
# this takes 2 args: (how often to update in millisec, the method to run)
|
||||
self.timer = GObject.timeout_add(TIME_UPATE, self.update_ui, None)
|
||||
self.timer_enable = True
|
||||
|
||||
self.show_all()
|
||||
|
||||
def _set_basic_temperature(self, val):
|
||||
self.temperature_basic_label.set_markup("<span font_desc='LiberationSans 25'>%.02f °C</span>" % val)
|
||||
#self.temperature_basic_label.set_text("%.02f °C" % val)
|
||||
def _set_basic_humidity(self, val):
|
||||
self.humidity_basic_label.set_markup("<span font_desc='LiberationSans 25'>%.02f %c</span>" % (val, '%'))
|
||||
#self.humidity_basic_label.set_text("%.02f %c" % (val, '%'))
|
||||
def _set_basic_pressure(self, val):
|
||||
self.pressure_basic_label.set_markup("<span font_desc='LiberationSans 25'>%.02f hP</span>" % val)
|
||||
#self.pressure_basic_label.set_text("%.02f hP" % val)
|
||||
def _set_basic_accelerometer(self, x, y, z):
|
||||
self.liststore[self.accel_store][1] = '%d' % x
|
||||
self.liststore[self.accel_store][2] = '%d' % y
|
||||
self.liststore[self.accel_store][3] = '%d' % z
|
||||
def _set_basic_gyroscope(self, x, y, z):
|
||||
self.liststore[self.gyro_store][1] = '%d' % x
|
||||
self.liststore[self.gyro_store][2] = '%d' % y
|
||||
self.liststore[self.gyro_store][3] = '%d' % z
|
||||
def _set_basic_magnetometer(self, x, y, z):
|
||||
self.liststore[self.magneto_store][1] = '%d' % x
|
||||
self.liststore[self.magneto_store][2] = '%d' % y
|
||||
self.liststore[self.magneto_store][3] = '%d' % z
|
||||
def _set_imu_roll(self, val):
|
||||
self.imu_liststore[self.roll_store][1] = '%d' % val
|
||||
def _set_imu_pitch(self, val):
|
||||
self.imu_liststore[self.pitch_store][1] = '%d' % val
|
||||
def _set_imu_yaw(self, val):
|
||||
self.imu_liststore[self.yaw_store][1] = '%d' % val
|
||||
def _update_orientation(self, val):
|
||||
self.orientation_label.set_markup("<span font_desc='LiberationSans 25'>Orientation: %s</span>" % val)
|
||||
|
||||
def create_notebook_page_basic_sensor(self):
|
||||
'''
|
||||
create notebook page for displaying basic current
|
||||
sensor information: temperature, humidity, pressure
|
||||
'''
|
||||
page_basic = Gtk.HBox(homogeneous=False, spacing=0)
|
||||
page_basic.set_border_width(10)
|
||||
|
||||
# temperature
|
||||
temp_box = Gtk.VBox(homogeneous=False, spacing=0)
|
||||
temp_image = _load_image_constrained(self, "RS1069_climate_change_light_blue.png", -1, 100)
|
||||
self.temperature_basic_label = Gtk.Label('--.-- °C')
|
||||
temp_image.show()
|
||||
self.temperature_basic_label.show()
|
||||
temp_box.pack_start(temp_image, True, False, 1)
|
||||
temp_box.add(self.temperature_basic_label)
|
||||
# humidity
|
||||
humidity_box = Gtk.VBox(homogeneous=False, spacing=0)
|
||||
humidity_image = _load_image_constrained(self, "RS1902_humidity_light_blue.png", -1, 100)
|
||||
self.humidity_basic_label = Gtk.Label('--.-- °C')
|
||||
humidity_image.show()
|
||||
self.humidity_basic_label.show()
|
||||
humidity_box.pack_start(humidity_image, True, False, 1)
|
||||
humidity_box.add(self.humidity_basic_label)
|
||||
# Pressure
|
||||
if WITH_PRESSURE:
|
||||
pressure_box = Gtk.VBox(homogeneous=False, spacing=0)
|
||||
pressure_image = _load_image_constrained(self, "RS6355_FORCE_PRESSURE_light_blue.png", -1, 100)
|
||||
self.pressure_basic_label = Gtk.Label('--.-- °C')
|
||||
pressure_image.show()
|
||||
self.pressure_basic_label.show()
|
||||
pressure_box.pack_start(pressure_image, True, False, 1)
|
||||
pressure_box.add(self.pressure_basic_label)
|
||||
|
||||
page_basic.add(temp_box)
|
||||
page_basic.add(humidity_box)
|
||||
if WITH_PRESSURE:
|
||||
page_basic.add(pressure_box)
|
||||
notebook_title = Gtk.Label()
|
||||
notebook_title.set_markup("<span font_desc='LiberationSans 25'>Sensors</span>")
|
||||
self.notebook.append_page(page_basic, notebook_title)
|
||||
|
||||
def create_notebook_page_basic_accel(self):
|
||||
'''
|
||||
create notebook page for displaying movement
|
||||
sensor information: accellerometer, gyroscope, magentometer
|
||||
'''
|
||||
page_basic_movement = Gtk.Box()
|
||||
page_basic_movement.set_border_width(10)
|
||||
|
||||
self.liststore = Gtk.ListStore(str, str, str, str)
|
||||
self.accel_store = self.liststore.append([ "Accelerometer", "0.0", "0.0", "0.0" ])
|
||||
if WITH_GYRO:
|
||||
self.gyro_store = self.liststore.append([ "Gyroscope", "0.0", "0.0", "0.0" ])
|
||||
#if WITH_MAGNETO:
|
||||
# self.magneto_store = self.liststore.append([ "Magnetometer", "0.0", "0.0", "0.0" ])
|
||||
treeview = Gtk.TreeView(model=self.liststore)
|
||||
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
column_text = Gtk.TreeViewColumn("Sensor", renderer_text, text=0)
|
||||
treeview.append_column(column_text)
|
||||
|
||||
renderer_x = Gtk.CellRendererText()
|
||||
column_x = Gtk.TreeViewColumn("X", renderer_x, text=1)
|
||||
treeview.append_column(column_x)
|
||||
|
||||
renderer_y = Gtk.CellRendererText()
|
||||
column_y = Gtk.TreeViewColumn("Y", renderer_y, text=2)
|
||||
treeview.append_column(column_y)
|
||||
|
||||
renderer_z = Gtk.CellRendererText()
|
||||
column_z = Gtk.TreeViewColumn("Z", renderer_z, text=3)
|
||||
treeview.append_column(column_z)
|
||||
|
||||
page_basic_movement.add(treeview)
|
||||
notebook_title = Gtk.Label()
|
||||
notebook_title.set_markup("<span font_desc='LiberationSans 25'>Move</span>")
|
||||
self.notebook.append_page(page_basic_movement, notebook_title)
|
||||
|
||||
|
||||
def create_notebook_page_imu(self):
|
||||
'''
|
||||
display the IMU: Inertial Measurement Unit
|
||||
Roll(X-axis), Pitch(Y-axis) and Yaw(Z-axis).
|
||||
'''
|
||||
page_imu_all = Gtk.VBox(homogeneous=False, spacing=0)
|
||||
imu_frame = Gtk.Frame(label="IMU")
|
||||
orientation_frame = Gtk.Frame(label="Orientation")
|
||||
|
||||
page_imu = Gtk.VBox(homogeneous=False, spacing=0)
|
||||
|
||||
#page_imu_all.add(page_imu)
|
||||
page_imu_all.add(imu_frame)
|
||||
page_imu_all.add(orientation_frame)
|
||||
|
||||
page_imu.set_border_width(10)
|
||||
# explanation
|
||||
imu_label = Gtk.Label()
|
||||
imu_label.set_markup("<span font_desc='LiberationSans 25'>Inertial Measurement Unit</span>")
|
||||
|
||||
page_imu.add(imu_label)
|
||||
|
||||
imu_h_box = Gtk.HBox(homogeneous=False, spacing=0)
|
||||
# picture which describe IMU
|
||||
picture_filename = "%s/RS10670_Aereo-lpr.jpg" % ICON_PICTURES_PATH
|
||||
image_imu = _load_image(self, "RS10670_Aereo-lpr.jpg")
|
||||
|
||||
imu_h_box.pack_start(image_imu, True, True, 10)
|
||||
# add tree view with roll, picth, yaw
|
||||
self.imu_liststore = Gtk.ListStore(str, str)
|
||||
self.roll_store = self.imu_liststore.append([ "Roll (X-axis)", "0.0"])
|
||||
self.pitch_store = self.imu_liststore.append([ "Pitch (Y-axis)", "0.0"])
|
||||
self.yaw_store = self.imu_liststore.append([ "Yaw (Z-axis)", "0.0"])
|
||||
imu_treeview = Gtk.TreeView(model=self.imu_liststore)
|
||||
imu_h_box.add(imu_treeview)
|
||||
page_imu.add(imu_h_box)
|
||||
imu_frame.add(page_imu)
|
||||
|
||||
self.orientation_label = Gtk.Label()
|
||||
self.orientation_label.set_markup("<span font_desc='LiberationSans 25'>Orientation: --none--</span>")
|
||||
orientation_frame.add(self.orientation_label)
|
||||
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
#renderer_text.set_property("size", 18)
|
||||
column_imu_text = Gtk.TreeViewColumn('Type', renderer_text, text=0)
|
||||
imu_treeview.append_column(column_imu_text)
|
||||
renderer_val = Gtk.CellRendererText()
|
||||
column_val = Gtk.TreeViewColumn("Value", renderer_val, text=1)
|
||||
imu_treeview.append_column(column_val)
|
||||
|
||||
notebook_title = Gtk.Label()
|
||||
notebook_title.set_markup("<span font_desc='LiberationSans 25'>IMU</span>")
|
||||
self.notebook.append_page(page_imu_all, notebook_title)
|
||||
|
||||
def _create_frame_with_image_and_label(self, title, img_file_name, label_text):
|
||||
frame = Gtk.Frame(label=title)
|
||||
box = Gtk.VBox(homogeneous=False, spacing=0)
|
||||
img = _load_image(self, img_file_name)
|
||||
img = _load_image_constrained(self, img_file_name, -1, 100)
|
||||
label = Gtk.Label()
|
||||
label.set_markup("<span font_desc='LiberationSans 18'>%s</span>" % label_text)
|
||||
box.add(img)
|
||||
box.add(label)
|
||||
frame.add(box)
|
||||
return frame
|
||||
|
||||
def create_notebook_page_sensor_information(self):
|
||||
''' Display all the sensor used for this demo '''
|
||||
page_sensor_info = Gtk.Grid()
|
||||
|
||||
frame_temp = self._create_frame_with_image_and_label(
|
||||
"%25s" % "Temperature",
|
||||
"RS1069_climate_change_light_blue.png",
|
||||
self.sensors.get_driver_name_temperature()
|
||||
)
|
||||
frame_humidity = self._create_frame_with_image_and_label(
|
||||
"%25s" % "Humidity",
|
||||
"RS1902_humidity_light_blue.png",
|
||||
self.sensors.get_driver_name_humidity()
|
||||
)
|
||||
if WITH_PRESSURE:
|
||||
frame_pressure = self._create_frame_with_image_and_label(
|
||||
"%25s" % "Pressure",
|
||||
"RS6355_FORCE_PRESSURE_light_blue.png",
|
||||
self.sensors.get_driver_name_pressure()
|
||||
)
|
||||
frame_accel = self._create_frame_with_image_and_label(
|
||||
"%25s" % "Accelerometer",
|
||||
"RS1761_MEMS_accelerometer_light_blue.png",
|
||||
self.sensors.get_driver_name_accelerometer()
|
||||
)
|
||||
if WITH_GYRO:
|
||||
frame_gyro = self._create_frame_with_image_and_label(
|
||||
"%25s" % "Gyroscope",
|
||||
"RS1760_MEMS_gyroscope_light_blue.png",
|
||||
self.sensors.get_driver_name_gyroscope()
|
||||
)
|
||||
#if WITH_MAGNETO:
|
||||
# frame_magneto = self._create_frame_with_image_and_label(
|
||||
# "%25s" % "Magnetometer",
|
||||
# "RS1762_MEMS_compass_light_blue.png",
|
||||
# self.sensors.get_driver_name_magnetometer()
|
||||
# )
|
||||
|
||||
page_sensor_info.set_column_spacing(2)
|
||||
page_sensor_info.set_row_spacing(2)
|
||||
|
||||
page_sensor_info.attach(frame_temp, 1, 1, 3, 1)
|
||||
page_sensor_info.attach_next_to(frame_humidity, frame_temp,
|
||||
Gtk.PositionType.RIGHT, 1, 1)
|
||||
if WITH_PRESSURE:
|
||||
page_sensor_info.attach_next_to(frame_pressure, frame_humidity,
|
||||
Gtk.PositionType.RIGHT, 1, 1)
|
||||
page_sensor_info.attach_next_to(frame_accel, frame_temp,
|
||||
Gtk.PositionType.BOTTOM, 1, 1)
|
||||
if WITH_GYRO:
|
||||
page_sensor_info.attach_next_to(frame_gyro, frame_accel,
|
||||
Gtk.PositionType.RIGHT, 1, 1)
|
||||
#if WITH_MAGNETO:
|
||||
# page_sensor_info.attach_next_to(frame_magneto, frame_gyro,
|
||||
# Gtk.PositionType.RIGHT, 1, 1)
|
||||
|
||||
#self.notebook.append_page(page_sensor_info,
|
||||
# Gtk.Image.new_from_icon_name(
|
||||
# "dialog-information",
|
||||
# Gtk.IconSize.MENU
|
||||
# ))
|
||||
notebook_title = Gtk.Label()
|
||||
notebook_title.set_markup("<span font_desc='LiberationSans 25'>Infos</span>")
|
||||
self.notebook.append_page(page_sensor_info, notebook_title)
|
||||
|
||||
def create_notebook_page_exit(self):
|
||||
''' notebook page for quitting application '''
|
||||
page = Gtk.VBox(homogeneous=False, spacing=0)
|
||||
page.set_border_width(10)
|
||||
''' button '''
|
||||
lastbutton = Gtk.Button()
|
||||
lastbutton.connect("clicked", self.destroy)
|
||||
image_to_add = _load_image_on_button(self, "%s/RS70_ST_Logo_Qi.png" % ICON_PICTURES_PATH, "Quit", -1, 200)
|
||||
lastbutton.add(image_to_add)
|
||||
lastbutton.show()
|
||||
|
||||
page.pack_start(lastbutton, True, True, 0)
|
||||
exit_label = Gtk.Label()
|
||||
exit_label.set_markup("<span font_desc='LiberationSans 25'>To exit, click on logo.</span>")
|
||||
page.pack_start(exit_label, False, False, 0)
|
||||
|
||||
notebook_title = Gtk.Label()
|
||||
notebook_title.set_markup("<span font_desc='LiberationSans 25'>EXIT</span>")
|
||||
|
||||
self.notebook.append_page(page, notebook_title)
|
||||
def destroy(self, widget, data=None):
|
||||
Gtk.main_quit()
|
||||
|
||||
def rearm_timer(self):
|
||||
if self.timer_enable:
|
||||
self.timer = GObject.timeout_add(TIME_UPATE, self.update_ui, None)
|
||||
|
||||
def update_ui(self, user_data):
|
||||
if False == self.timer_enable:
|
||||
return False;
|
||||
|
||||
# temperature
|
||||
temp = self.sensors.read_temperature()
|
||||
self._set_basic_temperature(temp)
|
||||
# humidity
|
||||
hum = self.sensors.read_humidity()
|
||||
self._set_basic_humidity(hum)
|
||||
# pressure
|
||||
if WITH_PRESSURE:
|
||||
press = self.sensors.read_pressure()
|
||||
self._set_basic_pressure(press)
|
||||
|
||||
# accel
|
||||
accel = self.sensors.read_accelerometer()
|
||||
self._set_basic_accelerometer(accel[0], accel[1], accel[2])
|
||||
# gyro
|
||||
if WITH_GYRO:
|
||||
gyro = self.sensors.read_gyroscope()
|
||||
self._set_basic_gyroscope(gyro[0], gyro[1], gyro[2])
|
||||
# magneto
|
||||
#if WITH_MAGNETO:
|
||||
# magneto = self.sensors.read_magnetometer()
|
||||
# self._set_basic_magnetometer(magneto[0], magneto[1], magneto[2])
|
||||
|
||||
# imu
|
||||
pitch, roll, yaw = self.sensors.calculate_imu(accel)
|
||||
self._set_imu_pitch(pitch)
|
||||
self._set_imu_roll(roll)
|
||||
self._set_imu_yaw(yaw)
|
||||
self._update_orientation(self.sensors.get_imu_orientation(pitch, roll))
|
||||
|
||||
#print("[DEBUG] visibility: ", self.get_property("visible"))
|
||||
|
||||
# As this is a timeout function, return True so that it
|
||||
# continues to get called
|
||||
return True
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# -------------------------------------------------------------------
|
||||
# Main
|
||||
if __name__ == "__main__":
|
||||
# add signal to catch CRTL+C
|
||||
import signal
|
||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
try:
|
||||
#splScr = SplashScreen("%s/RS70_ST_Logo_Qi.png" % ICON_PICTURES_PATH, 5)
|
||||
#Gtk.main()
|
||||
|
||||
win = MainUIWindow()
|
||||
win.connect("delete-event", Gtk.main_quit)
|
||||
win.show_all()
|
||||
except Exception as exc:
|
||||
print("Main Exception: ", exc )
|
||||
|
||||
Gtk.main()
|
||||
@@ -0,0 +1,505 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import gi
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gdk
|
||||
import cairo
|
||||
|
||||
import random
|
||||
import math
|
||||
from collections import deque
|
||||
import os
|
||||
|
||||
#for testing on PC without sensors, put REAL to 0
|
||||
MAKE_REAL_MESUREMENT = 1
|
||||
|
||||
NUM_SAMPLES = 112
|
||||
HMARGIN = 20
|
||||
VMARGIN = 10
|
||||
CHARTHEIGHT = 40
|
||||
|
||||
GRAPH_V_PADDING = 4
|
||||
GRAPH_H_PADDING = 4
|
||||
|
||||
#TIME_UPATE = 5000
|
||||
TIME_UPATE = 1000
|
||||
|
||||
|
||||
# example of orientation
|
||||
# https://github.com/hadess/iio-sensor-proxy/blob/master/src/test-orientation-gtk.c
|
||||
ORIENTATION_UNDEFINED = 0
|
||||
ORIENTATION_NORMAL = 1
|
||||
ORIENTATION_BOTTOM_UP = 2
|
||||
ORIENTATION_LEFT_UP = 3
|
||||
ORIENTATION_RIGHT_UP = 4
|
||||
|
||||
def _load_image_on_button(parent, filename, label_text):
|
||||
# Create box for xpm and label
|
||||
box1 = Gtk.HBox(False, 0)
|
||||
box1.set_border_width(2)
|
||||
# Now on to the image stuff
|
||||
image = Gtk.Image()
|
||||
image.set_from_file(filename)
|
||||
|
||||
# Create a label for the button
|
||||
label = Gtk.Label(label_text)
|
||||
|
||||
# Pack the pixmap and label into the box
|
||||
box1.pack_start(image, True, False, 3)
|
||||
#box1.pack_start(label, False, False, 3)
|
||||
|
||||
image.show()
|
||||
label.show()
|
||||
return box1
|
||||
|
||||
class SensorWindow(Gtk.Window):
|
||||
def __init__(self):
|
||||
Gtk.Window.__init__(self, title="Temperature/Humidity")
|
||||
if MAKE_REAL_MESUREMENT > 0:
|
||||
self.fullscreen()
|
||||
#self.maximize()
|
||||
screen_width = self.get_screen().get_width()
|
||||
screen_height = 600
|
||||
else:
|
||||
screen_width = 400
|
||||
screen_height = 600
|
||||
|
||||
self.temperature_prefix_path = self.found_iio_device("in_temp_raw")
|
||||
self.humidity_prefix_path = self.found_iio_device("in_humidityrelative_raw")
|
||||
self.accelerometer_prefix_path = self.found_iio_device("in_accel_x_raw")
|
||||
|
||||
#screen_height = self.get_screen().get_height()
|
||||
|
||||
self.set_default_size(screen_width, screen_height)
|
||||
|
||||
# current, Max, Min
|
||||
self.temperature_max = 0.0
|
||||
self.temperature_min = 35.0
|
||||
self.humidity_max = 0.0
|
||||
self.humidity_min = 35.0
|
||||
|
||||
'''
|
||||
0: "undefined"
|
||||
1: "normal"
|
||||
2: "bottom-up",
|
||||
3: "left-up",
|
||||
4: "right-up",
|
||||
'''
|
||||
self.previous_orientation = ORIENTATION_UNDEFINED
|
||||
|
||||
''' TreeView '''
|
||||
self.liststore = Gtk.ListStore(str, str, str, str)
|
||||
self.temperature_store = self.liststore.append([ "Temperature", "0.0", "0.0", "0.0" ])
|
||||
self.humidity_store = self.liststore.append([ "Humidity", "0.0", "0.0", "0.0" ])
|
||||
self.accel_store = self.liststore.append([ "Accelerometer", "0.0", "0.0", "0.0" ])
|
||||
|
||||
self.treeview = Gtk.TreeView(model=self.liststore)
|
||||
|
||||
renderer_text = Gtk.CellRendererText()
|
||||
column_text = Gtk.TreeViewColumn("Sensor", renderer_text, text=0)
|
||||
self.treeview.append_column(column_text)
|
||||
|
||||
renderer_current = Gtk.CellRendererText()
|
||||
column_cur = Gtk.TreeViewColumn("Current", renderer_current, text=1)
|
||||
self.treeview.append_column(column_cur)
|
||||
|
||||
renderer_max = Gtk.CellRendererText()
|
||||
column_max = Gtk.TreeViewColumn("Max", renderer_max, text=2)
|
||||
self.treeview.append_column(column_max)
|
||||
|
||||
renderer_min = Gtk.CellRendererText()
|
||||
column_min = Gtk.TreeViewColumn("Min", renderer_min, text=3)
|
||||
self.treeview.append_column(column_min)
|
||||
|
||||
# Add a timer callback to update
|
||||
# this takes 2 args: (how often to update in millisec, the method to run)
|
||||
self.timer = GObject.timeout_add(TIME_UPATE, self.update_ui, None)
|
||||
|
||||
''' DrawView '''
|
||||
self.drawarea = Gtk.DrawingArea()
|
||||
|
||||
self.drawing_area_width = screen_width
|
||||
self.drawing_area_height = screen_height/2
|
||||
|
||||
self.drawarea.set_size_request(self.drawing_area_width, self.drawing_area_height)
|
||||
self.drawarea.connect("draw", self._draw_event)
|
||||
self._axis_ranges = {} # {axis_num: [min_seen, max_seen]}
|
||||
self._axis_values = {} # {axis_num: deque([val0, ..., valN])}
|
||||
|
||||
''' spinner '''
|
||||
# add scale
|
||||
grid_scale_hor = Gtk.Grid()
|
||||
grid_scale_hor.set_column_spacing(10)
|
||||
grid_scale_hor.set_column_homogeneous(True)
|
||||
|
||||
self.x_adj = Gtk.Adjustment(0, -256, 256, 2, 2, 0)
|
||||
self.x_scale = Gtk.Scale(orientation=Gtk.Orientation.VERTICAL)
|
||||
self.x_scale.set_orientation(Gtk.Orientation.VERTICAL)
|
||||
self.x_scale.set_adjustment(self.x_adj)
|
||||
self.x_scale.set_digits(0)
|
||||
self.x_scale.set_draw_value(True)
|
||||
self.x_scale.set_vexpand(True)
|
||||
grid_scale_hor.attach(self.x_scale, 0, 0, 1, 1)
|
||||
|
||||
self.y_adj = Gtk.Adjustment(0, -256, 256, 2, 2, 0)
|
||||
self.y_scale = Gtk.Scale()
|
||||
self.y_scale.set_orientation(Gtk.Orientation.VERTICAL)
|
||||
self.y_scale.set_adjustment(self.y_adj)
|
||||
self.y_scale.set_digits(0)
|
||||
self.y_scale.set_draw_value(True)
|
||||
self.y_scale.set_vexpand(True)
|
||||
grid_scale_hor.attach_next_to(self.y_scale, self.x_scale, Gtk.PositionType.RIGHT, 1, 1)
|
||||
|
||||
self.z_adj = Gtk.Adjustment(0.0, -256.0, 256.0, 2.0, 2.0, 0.0)
|
||||
self.z_scale = Gtk.Scale()
|
||||
self.z_scale.set_orientation(Gtk.Orientation.VERTICAL)
|
||||
self.z_scale.set_adjustment(self.z_adj)
|
||||
self.z_scale.set_digits(0)
|
||||
self.z_scale.set_draw_value(True)
|
||||
self.z_scale.set_vexpand(True)
|
||||
grid_scale_hor.attach_next_to(self.z_scale, self.y_scale, Gtk.PositionType.RIGHT, 1, 1)
|
||||
|
||||
self.orientation = Gtk.Label("Orientation")
|
||||
#grid_scale_hor.attach_next_to(self.orientation, self.z_scale, Gtk.PositionType.RIGHT, 1, 1)
|
||||
grid_scale_hor.attach(self.orientation, 0, 1, 2, 1)
|
||||
|
||||
''' button '''
|
||||
lastbutton = Gtk.Button()
|
||||
lastbutton.connect("clicked", self.destroy)
|
||||
if MAKE_REAL_MESUREMENT > 0:
|
||||
image_to_add = _load_image_on_button(self, "/home/root/stlogo.png", "Quit")
|
||||
else:
|
||||
image_to_add = _load_image_on_button(self, "./stlogo.png", "Quit")
|
||||
lastbutton.add(image_to_add)
|
||||
lastbutton.show()
|
||||
|
||||
"""
|
||||
UI:
|
||||
---------------------------------------------------
|
||||
| | |
|
||||
| DrawingArea with two graph | Treeview |
|
||||
| | |
|
||||
---------------------------------------------------
|
||||
| | |
|
||||
| Spinner for accelerometer | Button with |
|
||||
| | ST image |
|
||||
---------------------------------------------------
|
||||
"""
|
||||
box_outer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6)
|
||||
self.add(box_outer)
|
||||
|
||||
# to activate draw area
|
||||
boxdraw_vert = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
|
||||
boxdraw_vert.pack_start(self.drawarea, False, True, 0)
|
||||
boxdraw_vert.pack_start(grid_scale_hor, True, True, 0)
|
||||
|
||||
box_outer.pack_start(boxdraw_vert, False, True, 0)
|
||||
|
||||
box_vert = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
|
||||
|
||||
self.tree_frame = Gtk.Frame(label="Temperature & Humidity")
|
||||
box_vert.pack_start(self.tree_frame, True, True, 0)
|
||||
self.tree_frame.add(self.treeview)
|
||||
|
||||
box_vert.pack_start(lastbutton, True, True, 0)
|
||||
|
||||
box_outer.pack_start(box_vert, True, True, 0)
|
||||
|
||||
def destroy(self, widget, data=None):
|
||||
Gtk.main_quit()
|
||||
|
||||
def found_iio_device(self, data):
|
||||
prefix = "/sys/bus/iio/devices/"
|
||||
try:
|
||||
for filefolder in os.listdir(prefix):
|
||||
if os.path.exists(prefix + '/' + filefolder + '/' + data):
|
||||
''' return directory which contains "data" '''
|
||||
return (prefix + '/' + filefolder + '/')
|
||||
except OSError:
|
||||
pass
|
||||
return None
|
||||
|
||||
def _draw_cb(self, drawingarea, ctx):
|
||||
width = self.drawing_area_width
|
||||
height = self.drawing_area_height
|
||||
|
||||
axis_ids = set(self._axis_ranges.keys())
|
||||
axis_ids.intersection_update(set(self._axis_values.keys()))
|
||||
for i in sorted(axis_ids):
|
||||
if i == 1:
|
||||
# temperature value
|
||||
|
||||
#draw rectangle
|
||||
ctx.set_source_rgb(0.8, 0.8, 0.8)
|
||||
ctx.rectangle(0, 0, width, height/2)
|
||||
ctx.fill()
|
||||
|
||||
#draw axes
|
||||
ctx.set_source_rgb(0, 1, 1)
|
||||
ctx.move_to(30 + 0.5, height/4)
|
||||
ctx.line_to(width - 0.5, height/4)
|
||||
ctx.stroke()
|
||||
|
||||
# value (text)
|
||||
ctx.select_font_face("sans-serif")
|
||||
ctx.set_font_size(20.0)
|
||||
ctx.set_source_rgb(0, 0, 0)
|
||||
ctx.move_to(0, 20)
|
||||
ctx.show_text("T (°C)")
|
||||
ctx.set_font_size(10.0)
|
||||
ctx.move_to(0, height/4 + 4)
|
||||
ctx.show_text("20 °C")
|
||||
# temperateure between 0 and 40
|
||||
values = self._axis_values[i]
|
||||
ctx.set_source_rgb(0, 0, 0)
|
||||
for x, v in enumerate(values):
|
||||
val = 30 + x*GRAPH_H_PADDING
|
||||
ctx.move_to(val, height/2)
|
||||
ctx.line_to(val, (40.0 - v) * height/80)
|
||||
ctx.stroke()
|
||||
|
||||
if i == 2:
|
||||
# Humidity values
|
||||
|
||||
offset = 10
|
||||
#draw rectangle
|
||||
ctx.set_source_rgb(0.8, 0.8, 0.8)
|
||||
ctx.rectangle(0, height/2 + offset, width, height/2)
|
||||
ctx.fill()
|
||||
|
||||
#draw axes
|
||||
ctx.set_source_rgb(0, 1, 1)
|
||||
ctx.move_to(25 + 0.5, height/2 + offset + height/4)
|
||||
ctx.line_to(width - 0.5, height/2 + offset + height/4)
|
||||
ctx.stroke()
|
||||
|
||||
# value (text)
|
||||
ctx.select_font_face("sans-serif")
|
||||
ctx.set_font_size(20.0)
|
||||
ctx.set_source_rgb(0, 0, 0)
|
||||
ctx.move_to(0, height/2 + offset + 20)
|
||||
ctx.show_text("H (%)")
|
||||
ctx.set_font_size(10.0)
|
||||
ctx.set_source_rgb(0, 0, 0)
|
||||
ctx.move_to(0, height/2 + offset + height/4 + 4)
|
||||
ctx.show_text("50 %")
|
||||
|
||||
values = self._axis_values[i]
|
||||
ctx.set_source_rgb(0, 0, 0)
|
||||
for x, v in enumerate(values):
|
||||
val = 25 + x*GRAPH_H_PADDING
|
||||
ctx.move_to(val, height/2 + offset + height/2)
|
||||
ctx.line_to(val, height/2 + offset + (100.0 - v) * height/200)
|
||||
ctx.stroke()
|
||||
return False
|
||||
|
||||
def _orientation_calc(self, x, y, z):
|
||||
rotation = round( math.atan(x / math.sqrt(y * y + z * z)) * 180.0 * math.pi)
|
||||
if abs(rotation) > 35:
|
||||
''' (rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;'''
|
||||
if self.previous_orientation == ORIENTATION_LEFT_UP or self.previous_orientation == ORIENTATION_NORMAL:
|
||||
if abs(rotation) < 5:
|
||||
self.update_movement(self.previous_orientation)
|
||||
else:
|
||||
if rotation > 0:
|
||||
self.update_movement(ORIENTATION_LEFT_UP)
|
||||
else:
|
||||
self.update_movement(ORIENTATION_RIGHT_UP)
|
||||
else:
|
||||
rotation = round( math.atan(y / math.sqrt(x * x + z * z)) * 180.0 * math.pi)
|
||||
if abs(rotation) > 35:
|
||||
'''ret = (rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;'''
|
||||
if self.previous_orientation == ORIENTATION_BOTTOM_UP or self.previous_orientation == ORIENTATION_NORMAL:
|
||||
if abs(rotation) < 5:
|
||||
self.update_movement(self.previous_orientation)
|
||||
else:
|
||||
if rotation > 0:
|
||||
self.update_movement(ORIENTATION_BOTTOM_UP)
|
||||
else:
|
||||
self.update_movement(ORIENTATION_NORMAL)
|
||||
|
||||
def orientation_calc(self, x, y, z):
|
||||
rotation = round( math.atan(x / math.sqrt(y * y + z * z)) * 180.0 * math.pi)
|
||||
|
||||
if abs(rotation) > 35:
|
||||
''' (rotation > 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP;'''
|
||||
if rotation > 0:
|
||||
self.update_movement(ORIENTATION_LEFT_UP)
|
||||
else:
|
||||
self.update_movement(ORIENTATION_RIGHT_UP)
|
||||
else:
|
||||
rotation = round( math.atan(y / math.sqrt(x * x + z * z)) * 180.0 * math.pi)
|
||||
if abs(rotation) > 35:
|
||||
'''ret = (rotation > 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL;'''
|
||||
if rotation > 0:
|
||||
self.update_movement(ORIENTATION_BOTTOM_UP)
|
||||
else:
|
||||
self.update_movement(ORIENTATION_NORMAL)
|
||||
|
||||
def udate_temperature(self, cur_val):
|
||||
self.liststore[self.temperature_store][1] = '%.2f' % cur_val
|
||||
if cur_val > self.temperature_max:
|
||||
self.temperature_max = cur_val
|
||||
if cur_val < self.temperature_min:
|
||||
self.temperature_min = cur_val
|
||||
self.liststore[self.temperature_store][2] = '%.2f' % self.temperature_max
|
||||
self.liststore[self.temperature_store][3] = '%.2f' % self.temperature_min
|
||||
|
||||
''' for drawing '''
|
||||
values = self._axis_values.get(1, None)
|
||||
if values is None:
|
||||
values = deque(maxlen=NUM_SAMPLES)
|
||||
self._axis_values[1] = values
|
||||
if len(list(values)) > (NUM_SAMPLES - 1):
|
||||
values. popleft()
|
||||
values.append(cur_val)
|
||||
self._axis_ranges[1] = (0.0, 60.0)
|
||||
|
||||
#print("TEMPERATURE: cur_val = %0.2f Max: %0.2f" % (cur_val, self.temperature_max))
|
||||
#print(self.liststore[self.temperature_store][0:])
|
||||
|
||||
def udate_humidity(self, cur_val):
|
||||
self.liststore[self.humidity_store][1] = '%.2f' % cur_val
|
||||
if cur_val > self.humidity_max:
|
||||
self.humidity_max = cur_val
|
||||
if cur_val < self.humidity_min:
|
||||
self.humidity_min = cur_val
|
||||
self.liststore[self.humidity_store][2] = '%.2f' % self.humidity_max
|
||||
self.liststore[self.humidity_store][3] = '%.2f' % self.humidity_min
|
||||
|
||||
''' for drawing '''
|
||||
values = self._axis_values.get(2, None)
|
||||
if values is None:
|
||||
values = deque(maxlen=NUM_SAMPLES)
|
||||
self._axis_values[2] = values
|
||||
values.append(cur_val)
|
||||
self._axis_ranges[2] = (0.0, 60.0)
|
||||
|
||||
def update_accel(self, x, y, z):
|
||||
self.liststore[self.accel_store][1] = '%d' % x
|
||||
self.liststore[self.accel_store][2] = '%d' % y
|
||||
self.liststore[self.accel_store][3] = '%d' % z
|
||||
self.x_adj.set_value(x)
|
||||
self.y_adj.set_value(y)
|
||||
self.z_adj.set_value(z)
|
||||
|
||||
def update_movement(self, m):
|
||||
self.previous_orientation = m
|
||||
if m == ORIENTATION_UNDEFINED:
|
||||
self.orientation.set_text("undefined")
|
||||
elif m == ORIENTATION_NORMAL:
|
||||
self.orientation.set_text("normal")
|
||||
elif m == ORIENTATION_BOTTOM_UP:
|
||||
self.orientation.set_text("bottom-up")
|
||||
elif m == ORIENTATION_LEFT_UP:
|
||||
self.orientation.set_text("left-up")
|
||||
elif m == ORIENTATION_RIGHT_UP:
|
||||
self.orientation.set_text("right-up")
|
||||
else:
|
||||
self.orientation.set_text("undefined")
|
||||
|
||||
def read_temperature(self):
|
||||
offset = 0.0
|
||||
raw = 0.0
|
||||
scale = 0.0
|
||||
temp = 0.0
|
||||
if MAKE_REAL_MESUREMENT > 0:
|
||||
if self.temperature_prefix_path:
|
||||
with open(self.temperature_prefix_path + 'in_temp_offset', 'r') as f:
|
||||
offset = float(f.read())
|
||||
with open(self.temperature_prefix_path + 'in_temp_raw', 'r') as f:
|
||||
raw = float(f.read())
|
||||
with open(self.temperature_prefix_path + 'in_temp_scale', 'r') as f:
|
||||
scale = float(f.read())
|
||||
temp = (offset + raw) * scale
|
||||
self.udate_temperature(temp)
|
||||
else:
|
||||
# randomly generated
|
||||
self.udate_temperature(random.uniform(18.0, 35.0))
|
||||
else:
|
||||
# randomly generated
|
||||
self.udate_temperature(random.uniform(18.0, 35.0))
|
||||
|
||||
def read_humidity(self):
|
||||
offset = 0.0
|
||||
raw = 0.0
|
||||
scale = 0.0
|
||||
temp = 0.0
|
||||
if MAKE_REAL_MESUREMENT > 0:
|
||||
if self.humidity_prefix_path:
|
||||
with open(self.humidity_prefix_path + 'in_humidityrelative_offset', 'r') as f:
|
||||
offset = float(f.read())
|
||||
with open(self.humidity_prefix_path + 'in_humidityrelative_raw', 'r') as f:
|
||||
raw = float(f.read())
|
||||
with open(self.humidity_prefix_path + 'in_humidityrelative_scale', 'r') as f:
|
||||
scale = float(f.read())
|
||||
temp = (offset + raw) * scale
|
||||
self.udate_humidity(temp)
|
||||
else:
|
||||
# randomly generated
|
||||
self.udate_humidity(random.uniform(18.0, 35.0))
|
||||
else:
|
||||
# randomly generated
|
||||
self.udate_humidity(random.uniform(18.0, 35.0))
|
||||
|
||||
def read_accel(self):
|
||||
raw = 0.0
|
||||
scale = 0.0
|
||||
in_x = 0.0
|
||||
in_y = 0.0
|
||||
in_z = 0.0
|
||||
if MAKE_REAL_MESUREMENT > 0:
|
||||
if self.accelerometer_prefix_path:
|
||||
with open(self.accelerometer_prefix_path + 'in_accel_x_raw', 'r') as f:
|
||||
scale = float(f.read())
|
||||
with open(self.accelerometer_prefix_path + 'in_accel_x_scale', 'r') as f:
|
||||
raw = float(f.read())
|
||||
in_x = int(raw * scale * 256.0 / 9.81)
|
||||
with open(self.accelerometer_prefix_path + 'in_accel_y_raw', 'r') as f:
|
||||
scale = float(f.read())
|
||||
with open(self.accelerometer_prefix_path + 'in_accel_y_scale', 'r') as f:
|
||||
raw = float(f.read())
|
||||
in_y = int(raw * scale * 256.0 / 9.81)
|
||||
with open(self.accelerometer_prefix_path + 'in_accel_z_raw', 'r') as f:
|
||||
scale = float(f.read())
|
||||
with open(self.accelerometer_prefix_path + 'in_accel_z_scale', 'r') as f:
|
||||
raw = float(f.read())
|
||||
in_z = int(raw * scale * 256.0 / 9.81)
|
||||
self.update_accel(in_x, in_y, in_z)
|
||||
else:
|
||||
in_x = random.randint(-256, 256)
|
||||
in_y = random.randint(-256, 256)
|
||||
in_z = random.randint(-256, 256)
|
||||
self.update_accel(in_x, in_y, in_z)
|
||||
else:
|
||||
in_x = random.randint(-256, 256)
|
||||
in_y = random.randint(-256, 256)
|
||||
in_z = random.randint(-256, 256)
|
||||
self.update_accel(in_x, in_y, in_z)
|
||||
|
||||
self.orientation_calc(in_x, in_y, in_z)
|
||||
|
||||
def _draw_event(self, drawingarea, user_data):
|
||||
win = self.drawarea.get_window()
|
||||
ctx = win.cairo_create()
|
||||
self._draw_cb(win, ctx)
|
||||
|
||||
def update_ui(self, user_data):
|
||||
self.read_temperature()
|
||||
self.read_humidity()
|
||||
self.read_accel()
|
||||
|
||||
win = self.drawarea.get_window()
|
||||
ctx = win.cairo_create()
|
||||
self._draw_cb(win, ctx)
|
||||
|
||||
# As this is a timeout function, return True so that it
|
||||
# continues to get called
|
||||
return True
|
||||
|
||||
win = SensorWindow()
|
||||
win.connect("delete-event", Gtk.main_quit)
|
||||
win.show_all()
|
||||
Gtk.main()
|
||||