From 2ed62b84ded57f81eacd11af4277940de50a0f02 Mon Sep 17 00:00:00 2001 From: Jean-manuel Gagnon Date: Thu, 29 Dec 2016 09:51:44 -0500 Subject: [PATCH 1/4] Clean up and add some database input some clean up and addition of (# coding: utf8) i hope this will help. I change folder name to add rpi_ i add -air pressure to database (bmp085) -Orientation sensor calibration status and cuz acceleration (bno055) - more button setting like debuncing possibility some bug correction. --- src/config/database.csv | 5 + src/config/main.cfg | 33 +++-- src/plugins/mcp3008/__init__.py | 120 ----------------- .../Adafruit_BMP/BMP085.py | 1 + .../Adafruit_BMP/__init__.py | 0 .../{bmp085 => rpi_bmp085}/__init__.py | 54 ++++---- .../Adafruit_BNO055/BNO055.py | 1 + .../Adafruit_BNO055/__init__.py | 0 .../{virtualwire => rpi_bno055}/__init__.py | 122 +++++++++--------- .../{button => rpi_button}/__init__.py | 19 ++- .../Adafruit_MCP3008/MCP3008.py | 1 + .../Adafruit_MCP3008/__init__.py | 0 src/plugins/rpi_mcp3008/__init__.py | 121 +++++++++++++++++ .../__init__.py | 9 +- .../{bno055 => rpi_virtualwire}/__init__.py | 109 ++++++++-------- .../virtualwire/__init__.py | 0 .../virtualwire/virtualwire.py | 1 + 17 files changed, 321 insertions(+), 275 deletions(-) delete mode 100755 src/plugins/mcp3008/__init__.py rename src/plugins/{bmp085 => rpi_bmp085}/Adafruit_BMP/BMP085.py (99%) rename src/plugins/{bmp085 => rpi_bmp085}/Adafruit_BMP/__init__.py (100%) rename src/plugins/{bmp085 => rpi_bmp085}/__init__.py (67%) rename src/plugins/{bno055 => rpi_bno055}/Adafruit_BNO055/BNO055.py (99%) rename src/plugins/{bno055 => rpi_bno055}/Adafruit_BNO055/__init__.py (100%) rename src/plugins/{virtualwire => rpi_bno055}/__init__.py (54%) rename src/plugins/{button => rpi_button}/__init__.py (86%) rename src/plugins/{mcp3008 => rpi_mcp3008}/Adafruit_MCP3008/MCP3008.py (99%) rename src/plugins/{mcp3008 => rpi_mcp3008}/Adafruit_MCP3008/__init__.py (100%) create mode 100755 src/plugins/rpi_mcp3008/__init__.py rename src/plugins/{rotary_encoder => rpi_rotary_encoder}/__init__.py (93%) rename src/plugins/{bno055 => rpi_virtualwire}/__init__.py (59%) rename src/plugins/{virtualwire => rpi_virtualwire}/virtualwire/__init__.py (100%) rename src/plugins/{virtualwire => rpi_virtualwire}/virtualwire/virtualwire.py (99%) diff --git a/src/config/database.csv b/src/config/database.csv index 88c805f..97ae14f 100644 --- a/src/config/database.csv +++ b/src/config/database.csv @@ -18,6 +18,7 @@ ALT:Indicated Altitude:float:-1000:60000:ft:0.0:2000: TALT:True Altitude:float:-1000:60000:ft:0.0:2000: DALT:Density Altitude:float:-1000:60000:ft:0.0:2000: BARO:Altimeter Setting:float:0:35:inHg:29.92:2000: +AIRPRESS:Air Pressure:float:0:200000:Pa:101325:2000: VS:Vertical Speed:float:-10000:10000:ft/min:0.0:2000:Min,Max,lowWarn,highWarn,lowAlarm,highAlarm HEAD:Current Aircraft Magnetic Heading:float:0:360:deg:0.0:2000: TRACK:Current Aircraft Bearing:float:0:360:deg:0.0:2000: @@ -29,6 +30,10 @@ CAT:Cabine Air Temperature:float:-100:100:degC:0.0:2000:Min,Max,lowWarn,highWarn OATW:Outside Air Temperature Warning:int:0:5:warninglevel:0:0:2000 ROLL:Roll Angle:float:-180:180:deg:0.0:200: PITCH:Pitch Angle:float:-180:180:deg:0.0:200: +ORISYSW:Orientation System Warning:int:0:5:warninglevel:0:0:2000 +GYROW:Gyroscope sensor Warning:int:0:5:warninglevel:0:0:2000 +ACCELW:Acceleration sensor Warning:int:0:5:warninglevel:0:0:2000 +MAGW:Magnetic sensor Warning:int:0:5:warninglevel:0:0:2000 PITCHSET:Pitch angle setting:float:-180:180:deg:0.0:200: YAW:Yaw Angle:float:-180:180:deg:0.0:200: AOA:Angle of attack:float:-180:180:deg:0.0:200:Min,Max,0g,Warn,Stall diff --git a/src/config/main.cfg b/src/config/main.cfg index e2be953..3334777 100755 --- a/src/config/main.cfg +++ b/src/config/main.cfg @@ -41,35 +41,37 @@ module = plugins.test [conn_bno055] load = yes -module = plugins.bno055 +module = plugins.rpi_bno055 [conn_bmp085] load = yes -module = plugins.bmp085 +module = plugins.rpi_bmp085 +tkey = CAT +pkey = AIRPRESS [conn_virtualwire] load = yes -module = plugins.virtualwire +module = plugins.rpi_virtualwire rxpin = 23 bps = 2000 [conn_rotary_encoder] load = yes -module = plugins.rotary_encoder +module = plugins.rpi_rotary_encoder btn = True -btnkey = PITCHSET -btnstcounter = 0 -btnincr = .5 +btnkey = BARO +btnstcounter = 29.92 +btnincr = 0.01 btnpin = 4 pina = 26 pinb = 19 -stcount = 29.92 -rkey = BARO -incr = 0.01 +stcount = 0 +rkey = PITCHSET +incr = 1 [conn_mcp3008] load = yes -module = plugins.mcp3008 +module = plugins.rpi_mcp3008 vkey1 = VOLT vkey2 = ANLG2 vkey3 = ANLG3 @@ -83,6 +85,15 @@ miso = 23 mosi = 24 cs = 25 +# if you want several button copie this configuration with different setting like this [conn_button2] +[conn_button1] +load = no +module = plugins.rpi_button +btnkey = BTN1 +btnpin = 4 +rdelay = 0 # 0 for debouncing or time in seconde to determine the repeat delay + + # Logging configuration - See Python logging.config module documenation [loggers] keys=root diff --git a/src/plugins/mcp3008/__init__.py b/src/plugins/mcp3008/__init__.py deleted file mode 100755 index 56f1bba..0000000 --- a/src/plugins/mcp3008/__init__.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2014 Phil Birkelbach -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -# USA.import plugin - -# This file serves as a starting point for a plugin. This is a Thread based -# plugin where the main Plugin class creates a thread and starts the thread -# when the plugin's run() function is called. - -import plugin -import threading -import time -import Adafruit_GPIO.SPI as SPI -import Adafruit_MCP3008 -from collections import OrderedDict - -class MainThread(threading.Thread): - def __init__(self, parent): - """The calling object should pass itself as the parent. - This gives the thread all the plugin goodies that the - parent has.""" - super(MainThread, self).__init__() - self.getout = False # indicator for when to stop - self.parent = parent # parent plugin object - self.log = parent.log # simplifies logging - self.count = 0 - SPI_PORT = 0 - SPI_DEVICE = 0 - self.CLK = int(parent.config['clk']) if ('clk' in parent.config) and parent.config['clk'] else 18 - self.MISO = int(parent.config['miso']) if ('miso' in parent.config) and parent.config['miso'] else 23 - self.MOSI = int(parent.config['mosi']) if ('mosi' in parent.config) and parent.config['mosi'] else 24 - self.CS = int(parent.config['cs']) if ('cs' in parent.config) and parent.config['cs'] else 25 - self.VKEY1 = parent.config['vkey1'] if ('vkey1' in parent.config) and parent.config['vkey1'] else "ANLG1" - self.VKEY2 = parent.config['vkey2'] if ('vkey2' in parent.config) and parent.config['vkey2'] else "ANLG2" - self.VKEY3 = parent.config['vkey3'] if ('vkey3' in parent.config) and parent.config['vkey3'] else "ANLG3" - self.VKEY4 = parent.config['vkey4'] if ('vkey4' in parent.config) and parent.config['vkey4'] else "ANLG4" - self.VKEY5 = parent.config['vkey5'] if ('vkey5' in parent.config) and parent.config['vkey5'] else "ANLG5" - self.VKEY6 = parent.config['vkey6'] if ('vkey6' in parent.config) and parent.config['vkey6'] else "ANLG6" - self.VKEY7 = parent.config['vkey7'] if ('vkey7' in parent.config) and parent.config['vkey7'] else "ANLG7" - self.VKEY8 = parent.config['vkey8'] if ('vkey8' in parent.config) and parent.config['vkey8'] else "ANLG8" - - #self.mcp = Adafruit_MCP3008.MCP3008(clk=self.CLK, cs=self.CS, miso=self.MISO, mosi=self.MOSI) - self.mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE)) - - def run(self): - while True: - if self.getout: - break - time.sleep(1) - self.count += 1 - value1 = self.mcp.read_adc(0) - value2 = self.mcp.read_adc(1) - value3 = self.mcp.read_adc(2) - value4 = self.mcp.read_adc(3) - value5 = self.mcp.read_adc(4) - value6 = self.mcp.read_adc(5) - value7 = self.mcp.read_adc(6) - value8 = self.mcp.read_adc(7) - self.parent.db_write(self.VKEY1, value1) - self.parent.db_write(self.VKEY2, value2) - self.parent.db_write(self.VKEY3, value3) - self.parent.db_write(self.VKEY4, value4) - self.parent.db_write(self.VKEY5, value5) - self.parent.db_write(self.VKEY6, value6) - self.parent.db_write(self.VKEY7, value7) - self.parent.db_write(self.VKEY8, value8) - self.running = False - - def stop(self): - self.getout = True - - -class Plugin(plugin.PluginBase): - """ All plugins for FIX Gateway should implement at least the class - named 'Plugin.' They should be derived from the base class in - the plugin module. - - The run and stop methods of the plugin should be overridden but the - base module functions should be called first.""" - def __init__(self, name, config): - super(Plugin, self).__init__(name, config) - self.thread = MainThread(self) - - def run(self): - """ The run method should return immediately. The main routine will - block when calling this function. If the plugin is simply a collection - of callback functions, those can be setup here and no thread will be - necessary""" - super(Plugin, self).run() - self.thread.start() - - def stop(self): - """ The stop method should not return until the plugin has completely - stopped. This generally means a .join() on a thread. It should - also undo any callbacks that were set up in the run() method""" - self.thread.stop() - if self.thread.is_alive(): - self.thread.join(1.0) - if self.thread.is_alive(): - raise plugin.PluginFail - super(Plugin, self).stop() - - def get_status(self): - """ The get_status method should return a dict or OrderedDict that - is basically a key/value pair of statistics""" - return OrderedDict({"Count":self.thread.count}) diff --git a/src/plugins/bmp085/Adafruit_BMP/BMP085.py b/src/plugins/rpi_bmp085/Adafruit_BMP/BMP085.py similarity index 99% rename from src/plugins/bmp085/Adafruit_BMP/BMP085.py rename to src/plugins/rpi_bmp085/Adafruit_BMP/BMP085.py index 356c256..1f243a5 100644 --- a/src/plugins/bmp085/Adafruit_BMP/BMP085.py +++ b/src/plugins/rpi_bmp085/Adafruit_BMP/BMP085.py @@ -1,3 +1,4 @@ +# coding: utf8 # Copyright (c) 2014 Adafruit Industries # Author: Tony DiCola # diff --git a/src/plugins/bmp085/Adafruit_BMP/__init__.py b/src/plugins/rpi_bmp085/Adafruit_BMP/__init__.py similarity index 100% rename from src/plugins/bmp085/Adafruit_BMP/__init__.py rename to src/plugins/rpi_bmp085/Adafruit_BMP/__init__.py diff --git a/src/plugins/bmp085/__init__.py b/src/plugins/rpi_bmp085/__init__.py similarity index 67% rename from src/plugins/bmp085/__init__.py rename to src/plugins/rpi_bmp085/__init__.py index 1c15c76..01f688d 100755 --- a/src/plugins/bmp085/__init__.py +++ b/src/plugins/rpi_bmp085/__init__.py @@ -1,3 +1,4 @@ +# coding: utf8 #!/usr/bin/env python # Copyright (c) 2017 Jean-Manuel Gagnon @@ -31,33 +32,40 @@ class MainThread(threading.Thread): def __init__(self, parent): - """The calling object should pass itself as the parent. - This gives the thread all the plugin goodies that the + """The calling object should pass itself as the parent. + This gives the thread all the plugin goodies that the parent has.""" - super(MainThread, self).__init__() + super(MainThread, self).__init__() self.getout = False # indicator for when to stop - self.parent = parent # parent plugin object - self.log = parent.log # simplifies logging - self.count = 0 - self.alt = 0 - self.smooted = 0.85 - self.sensor = BMP085.BMP085() + self.parent = parent # parent plugin object + self.log = parent.log # simplifies logging + self.count = 0 + self.tkey = parent.config['tkey'] if ('tkey' in parent.config) and parent.config['tkey'] else "CAT" + self.pkey = parent.config['pkey'] if ('pkey' in parent.config) and parent.config['pkey'] else "AIRPRESS" + self.alt = 0 + self.sleep_time = .03 # 3 x .03 give +/-10Hz refresh rate + self.smooted = 0.8 # smooth altitude 0 to 1 , 1 is very smooth. + self.sensor = BMP085.BMP085(mode=BMP085.BMP085_ULTRAHIGHRES) def run(self): - while True: - if self.getout: - break - time.sleep(.1) - self.count += 1 - stdbaro = 29.92 - currentbaro = self.parent.db_read("BARO") - init_alt = (float(self.sensor.read_altitude())*3.28083989502) - self.alt = float((self.alt*self.smooted)+(1.0-self.smooted)*(init_alt)) - altitude = ((float(currentbaro[0]) - stdbaro)*1000) + self.alt - cat = float(self.sensor.read_temperature()) - self.parent.db_write("ALT", round(altitude)) - self.parent.db_write("CAT", cat) - self.running = False + while True: + if self.getout: + break + time.sleep(sleep_time) + self.count += 1 + stdbaro = 29.92 + currentbaro = self.parent.db_read("BARO") + init_alt = round((float(self.sensor.read_altitude())*3.28083989502)) + self.alt = float((self.alt*self.smooted)+(1.0-self.smooted)*(init_alt)) + altitude = ((float(currentbaro[0]) - stdbaro)*1000) + self.alt + self.parent.db_write("ALT", altitude) + time.sleep(sleep_time) + cat = float(self.sensor.read_temperature()) + self.parent.db_write(self.tkey, cat) + time.sleep(sleep_time) + airpress = int(self.sensor.read_pressure()) + self.parent.db_write(self.pkey, airpress) + self.running = False def stop(self): self.getout = True diff --git a/src/plugins/bno055/Adafruit_BNO055/BNO055.py b/src/plugins/rpi_bno055/Adafruit_BNO055/BNO055.py similarity index 99% rename from src/plugins/bno055/Adafruit_BNO055/BNO055.py rename to src/plugins/rpi_bno055/Adafruit_BNO055/BNO055.py index 2d1ac82..c51d7a8 100644 --- a/src/plugins/bno055/Adafruit_BNO055/BNO055.py +++ b/src/plugins/rpi_bno055/Adafruit_BNO055/BNO055.py @@ -1,3 +1,4 @@ +# coding: utf8 # Adafruit BNO055 Absolute Orientation Sensor Library # Copyright (c) 2015 Adafruit Industries # Author: Tony DiCola diff --git a/src/plugins/bno055/Adafruit_BNO055/__init__.py b/src/plugins/rpi_bno055/Adafruit_BNO055/__init__.py similarity index 100% rename from src/plugins/bno055/Adafruit_BNO055/__init__.py rename to src/plugins/rpi_bno055/Adafruit_BNO055/__init__.py diff --git a/src/plugins/virtualwire/__init__.py b/src/plugins/rpi_bno055/__init__.py similarity index 54% rename from src/plugins/virtualwire/__init__.py rename to src/plugins/rpi_bno055/__init__.py index 244464c..4ef781f 100755 --- a/src/plugins/virtualwire/__init__.py +++ b/src/plugins/rpi_bno055/__init__.py @@ -1,3 +1,4 @@ +# coding: utf8 #!/usr/bin/env python # Copyright (c) 2017 Jean-Manuel Gagnon @@ -26,70 +27,75 @@ import plugin import threading import time -import pigpio -from virtualwire import virtualwire +from Adafruit_BNO055 import BNO055 from collections import OrderedDict class MainThread(threading.Thread): - def __init__(self, parent): - """The calling object should pass itself as the parent. - This gives the thread all the plugin goodies that the - parent has.""" - super(MainThread, self).__init__() - self.getout = False # indicator for when to stop - self.parent = parent # parent plugin object - self.log = parent.log # simplifies logging - self.count = 0 - self.ias = 0 - self.oat = 0 - self.ias_W_S = 0 - self.oat_W_S = 0 - self.smooted = 0.8 - pigpio.exceptions = False - self.rxpin = int(parent.config['rxpin']) if ('rxpin' in parent.config) and parent.config['rxpin'] else 23 - self.bps = int(parent.config['bps']) if ('bps' in parent.config) and parent.config['rxpin'] else 2000 - self.pi = pigpio.pi() # Connect to local Pi - self.rx = virtualwire.rx(self.pi, self.rxpin, self.bps) # Specify Pi, rx GPIO. + def __init__(self, parent): + """The calling object should pass itself as the parent. + This gives the thread all the plugin goodies that the + parent has.""" + super(MainThread, self).__init__() + self.getout = False # indicator for when to stop + self.parent = parent # parent plugin object + self.log = parent.log # simplifies logging + self.count = 0 + self.sleep_time = 0.005 # 3 x .005 give +/-60Hz refresh rate + self.bno = BNO055.BNO055(serial_port='/dev/ttyAMA0', rst=18) + if not self.bno.begin(): + self.parent.db_write("ORISYSW",0) # TODO put 0 to orientation system status but a fail flag are need here. + raise RuntimeError('Failed to initialize BNO055! Is the sensor connected?') - def run(self): - while True: - if self.getout: - break - time.sleep(.25) - self.count += 1 - try: - while self.rx.ready(): - try: - msg = str("".join(chr (c) for c in self.rx.get())) - except: - msg = [400, -50] - print msg - pass - msg = msg.split(',') - - if float(msg[0]) < 400 : - init_ias = float(msg[0]) - self.ias = float((self.ias*self.smooted)+(1.0-self.smooted)*(init_ias)) - self.ias_W_S = 3 - if float(msg[1]) > -50 : - self.oat = float(msg[1]) - self.oat_W_S = 3 - else: - self.ias_W_S = 2 - self.oat_W_S = 2 - except: - self.ias_W_S = 2 - self.oat_W_S = 2 - pass - self.parent.db_write("IAS", int(self.ias)) - self.parent.db_write("OAT", self.oat) - self.parent.db_write("IASW", self.ias_W_S) - self.parent.db_write("OATW", self.oat_W_S) - self.running = False + def run(self): + while True: + if self.getout: + break + time.sleep(sleep_time) + self.count += 1 + heading, roll, pitch = self.bno.read_euler() + if pitch >= 90: + pdiff = pitch - 90 + pitch = 90 - pdiff + if roll > 0: + roll = -(roll - 180) + else: + roll = -(roll + 180) + else: + mpdiff = pitch + 90 + pitch = -(90 + mpdiff) + if roll > 0: + roll = -(roll - 180) + else: + roll = -(roll + 180) + if heading >= 180: + heading = heading - 180 + else: + heading = heading + 180 + try: + pitchset = self.parent.db_read("PITCHSET") + pitch = pitch + int(pitchset[0]) + except: + pass + self.parent.db_write("HEAD", heading) + self.parent.db_write("ROLL", roll) + self.parent.db_write("PITCH", pitch) + time.sleep(sleep_time) + x,y,z = self.bno.read_accelerometer() + x = -x/60 + y = -y/60 + z = -z/60 + self.parent.db_write("ALAT", x) + self.parent.db_write("ANORM", y) + self.parent.db_write("ALONG", z) + time.sleep(.sleep_time) + sys, gyro, accel, mag = self.bno.get_calibration_status() # 0 to 3 calibration status, 3 is full calibrated + self.parent.db_write("ORISYSW", sys) + self.parent.db_write("GYROW", gyro) + self.parent.db_write("ACCELW", accel) + self.parent.db_write("MAGW", mag) + self.running = False def stop(self): - self.rx.cancel() - self.pi.stop() self.getout = True diff --git a/src/plugins/button/__init__.py b/src/plugins/rpi_button/__init__.py similarity index 86% rename from src/plugins/button/__init__.py rename to src/plugins/rpi_button/__init__.py index 291f182..8bf39bb 100755 --- a/src/plugins/button/__init__.py +++ b/src/plugins/rpi_button/__init__.py @@ -1,6 +1,7 @@ +# coding: utf8 #!/usr/bin/env python -# Copyright (c) 2014 Phil Birkelbach +# Copyright (c) 2017 Jean-Manuel Gagnon # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -36,23 +37,29 @@ def __init__(self, parent): self.getout = False # indicator for when to stop self.parent = parent # parent plugin object self.log = parent.log # simplifies logging - self.key = parent.config['bkey'] if ('bkey' in parent.config) and parent.config['bkey'] else "BTN1" + self.btnkey = parent.config['btnkey'] if ('btnkey' in parent.config) and parent.config['btnkey'] else "BTN1" self.btnpin = int(parent.config['btnpin']) if ('btnpin' in parent.config) and parent.config['btnpin'] else 4 + self.rdelay = parent.config['rdelay'] if ('rdelay' in parent.config) and parent.config['rdelay'] else "0" GPIO.setmode(GPIO.BCM) GPIO.setup(self.btnpin,GPIO.IN, pull_up_down=GPIO.PUD_UP) self.count = 0 - + self.prev_input = 0 +# TODO !Not tested! def run(self): while True: if self.getout: break - time.sleep(0.001) + time.sleep(0.05) self.count += 1 - if (GPIO.input(self.btnpin)): + input = GPIO.input(self.btnpin) + if ((not prev_input) and input): self.parent.db_write(self.btnkey, "True") else: self.parent.db_write(self.btnkey, "False") - + self.prev_input = input + if self.rdelay != 0: + self.prev_input = 0 + time.sleep(self.rdelay) self.running = False def stop(self): diff --git a/src/plugins/mcp3008/Adafruit_MCP3008/MCP3008.py b/src/plugins/rpi_mcp3008/Adafruit_MCP3008/MCP3008.py similarity index 99% rename from src/plugins/mcp3008/Adafruit_MCP3008/MCP3008.py rename to src/plugins/rpi_mcp3008/Adafruit_MCP3008/MCP3008.py index 027cec7..76b55ed 100644 --- a/src/plugins/mcp3008/Adafruit_MCP3008/MCP3008.py +++ b/src/plugins/rpi_mcp3008/Adafruit_MCP3008/MCP3008.py @@ -1,3 +1,4 @@ +# coding: utf8 # Copyright (c) 2016 Adafruit Industries # Author: Tony DiCola # diff --git a/src/plugins/mcp3008/Adafruit_MCP3008/__init__.py b/src/plugins/rpi_mcp3008/Adafruit_MCP3008/__init__.py similarity index 100% rename from src/plugins/mcp3008/Adafruit_MCP3008/__init__.py rename to src/plugins/rpi_mcp3008/Adafruit_MCP3008/__init__.py diff --git a/src/plugins/rpi_mcp3008/__init__.py b/src/plugins/rpi_mcp3008/__init__.py new file mode 100755 index 0000000..9bc3057 --- /dev/null +++ b/src/plugins/rpi_mcp3008/__init__.py @@ -0,0 +1,121 @@ +# coding: utf8 +#!/usr/bin/env python + +# Copyright (c) 2017 Jean-Manuel Gagnon +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA.import plugin + +# This file serves as a starting point for a plugin. This is a Thread based +# plugin where the main Plugin class creates a thread and starts the thread +# when the plugin's run() function is called. + +import plugin +import threading +import time +import Adafruit_GPIO.SPI as SPI +import Adafruit_MCP3008 +from collections import OrderedDict + +class MainThread(threading.Thread): + def __init__(self, parent): + """The calling object should pass itself as the parent. + This gives the thread all the plugin goodies that the + parent has.""" + super(MainThread, self).__init__() + self.getout = False # indicator for when to stop + self.parent = parent # parent plugin object + self.log = parent.log # simplifies logging + self.count = 0 + SPI_PORT = 0 + SPI_DEVICE = 0 + self.CLK = int(parent.config['clk']) if ('clk' in parent.config) and parent.config['clk'] else 18 + self.MISO = int(parent.config['miso']) if ('miso' in parent.config) and parent.config['miso'] else 23 + self.MOSI = int(parent.config['mosi']) if ('mosi' in parent.config) and parent.config['mosi'] else 24 + self.CS = int(parent.config['cs']) if ('cs' in parent.config) and parent.config['cs'] else 25 + self.VKEY1 = parent.config['vkey1'] if ('vkey1' in parent.config) and parent.config['vkey1'] else "ANLG1" + self.VKEY2 = parent.config['vkey2'] if ('vkey2' in parent.config) and parent.config['vkey2'] else "ANLG2" + self.VKEY3 = parent.config['vkey3'] if ('vkey3' in parent.config) and parent.config['vkey3'] else "ANLG3" + self.VKEY4 = parent.config['vkey4'] if ('vkey4' in parent.config) and parent.config['vkey4'] else "ANLG4" + self.VKEY5 = parent.config['vkey5'] if ('vkey5' in parent.config) and parent.config['vkey5'] else "ANLG5" + self.VKEY6 = parent.config['vkey6'] if ('vkey6' in parent.config) and parent.config['vkey6'] else "ANLG6" + self.VKEY7 = parent.config['vkey7'] if ('vkey7' in parent.config) and parent.config['vkey7'] else "ANLG7" + self.VKEY8 = parent.config['vkey8'] if ('vkey8' in parent.config) and parent.config['vkey8'] else "ANLG8" + + #self.mcp = Adafruit_MCP3008.MCP3008(clk=self.CLK, cs=self.CS, miso=self.MISO, mosi=self.MOSI) + self.mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE)) + + def run(self): + while True: + if self.getout: + break + time.sleep(1) + self.count += 1 + value1 = self.mcp.read_adc(0) + value2 = self.mcp.read_adc(1) + value3 = self.mcp.read_adc(2) + value4 = self.mcp.read_adc(3) + value5 = self.mcp.read_adc(4) + value6 = self.mcp.read_adc(5) + value7 = self.mcp.read_adc(6) + value8 = self.mcp.read_adc(7) + self.parent.db_write(self.VKEY1, value1) + self.parent.db_write(self.VKEY2, value2) + self.parent.db_write(self.VKEY3, value3) + self.parent.db_write(self.VKEY4, value4) + self.parent.db_write(self.VKEY5, value5) + self.parent.db_write(self.VKEY6, value6) + self.parent.db_write(self.VKEY7, value7) + self.parent.db_write(self.VKEY8, value8) + self.running = False + + def stop(self): + self.getout = True + + +class Plugin(plugin.PluginBase): + """ All plugins for FIX Gateway should implement at least the class + named 'Plugin.' They should be derived from the base class in + the plugin module. + + The run and stop methods of the plugin should be overridden but the + base module functions should be called first.""" + def __init__(self, name, config): + super(Plugin, self).__init__(name, config) + self.thread = MainThread(self) + + def run(self): + """ The run method should return immediately. The main routine will + block when calling this function. If the plugin is simply a collection + of callback functions, those can be setup here and no thread will be + necessary""" + super(Plugin, self).run() + self.thread.start() + + def stop(self): + """ The stop method should not return until the plugin has completely + stopped. This generally means a .join() on a thread. It should + also undo any callbacks that were set up in the run() method""" + self.thread.stop() + if self.thread.is_alive(): + self.thread.join(1.0) + if self.thread.is_alive(): + raise plugin.PluginFail + super(Plugin, self).stop() + + def get_status(self): + """ The get_status method should return a dict or OrderedDict that + is basically a key/value pair of statistics""" + return OrderedDict({"Count":self.thread.count}) diff --git a/src/plugins/rotary_encoder/__init__.py b/src/plugins/rpi_rotary_encoder/__init__.py similarity index 93% rename from src/plugins/rotary_encoder/__init__.py rename to src/plugins/rpi_rotary_encoder/__init__.py index 854a872..c223dbe 100755 --- a/src/plugins/rotary_encoder/__init__.py +++ b/src/plugins/rpi_rotary_encoder/__init__.py @@ -1,6 +1,7 @@ +# coding: utf8 #!/usr/bin/env python -# Copyright (c) 2014 Phil Birkelbach +# Copyright (c) 2017 Jean-Manuel Gagnon # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,7 +27,7 @@ import time from RPi import GPIO from collections import OrderedDict - +# TODO create a menu driver between setting, like Garmin gns or gnc serie class MainThread(threading.Thread): def __init__(self, parent): """The calling object should pass itself as the parent. @@ -40,7 +41,7 @@ def __init__(self, parent): self.btn = parent.config['btn'] if ('btn' in parent.config) and parent.config['btn'] else "False" self.btnpin = int(parent.config['btnpin']) if ('btnpin' in parent.config) and parent.config['btnpin'] else 4 self.btnkey = parent.config['btnkey'] if ('btnkey' in parent.config) and parent.config['btnkey'] else "BTN1" - self.btnstcounter = int(parent.config['btnstcounter']) if ('btnstcounter' in parent.config) and parent.config['btnstcounter'] else 0 + self.btnstcounter = float(parent.config['btnstcounter']) if ('btnstcounter' in parent.config) and parent.config['btnstcounter'] else 0 self.btnincr = float(parent.config['btnincr']) if ('btnincr' in parent.config) and parent.config['btnincr'] else 1 self.counter = float(parent.config['stcount']) if ('stcount' in parent.config) and parent.config['stcount'] else 0 self.incr = float(parent.config['incr']) if ('incr' in parent.config) and parent.config['incr'] else 1 @@ -61,7 +62,7 @@ def run(self): self.count += 1 clkState = GPIO.input(self.clk) dtState = GPIO.input(self.dt) - if self.btn == "True" and (GPIO.input(self.btnpin)): + if self.btn == "True" and not (GPIO.input(self.btnpin)): if clkState != self.clkLastState: if dtState != clkState: self.btnstcounter += self.btnincr diff --git a/src/plugins/bno055/__init__.py b/src/plugins/rpi_virtualwire/__init__.py similarity index 59% rename from src/plugins/bno055/__init__.py rename to src/plugins/rpi_virtualwire/__init__.py index c161c8b..8ffc04b 100755 --- a/src/plugins/bno055/__init__.py +++ b/src/plugins/rpi_virtualwire/__init__.py @@ -1,3 +1,4 @@ +# coding: utf8 #!/usr/bin/env python # Copyright (c) 2017 Jean-Manuel Gagnon @@ -26,67 +27,69 @@ import plugin import threading import time -from Adafruit_BNO055 import BNO055 +import pigpio +from virtualwire import virtualwire from collections import OrderedDict class MainThread(threading.Thread): def __init__(self, parent): - """The calling object should pass itself as the parent. - This gives the thread all the plugin goodies that the - parent has.""" - super(MainThread, self).__init__() - self.getout = False # indicator for when to stop - self.parent = parent # parent plugin object - self.log = parent.log # simplifies logging - self.count = 0 - self.bno = BNO055.BNO055(serial_port='/dev/ttyAMA0', rst=18) - if not self.bno.begin(): - raise RuntimeError('Failed to initialize BNO055! Is the sensor connected?') + """The calling object should pass itself as the parent. + This gives the thread all the plugin goodies that the + parent has.""" + super(MainThread, self).__init__() + self.getout = False # indicator for when to stop + self.parent = parent # parent plugin object + self.log = parent.log # simplifies logging + self.count = 0 + self.ias = 0 + self.oat = 0 + self.ias_W_S = 0 + self.oat_W_S = 0 + self.smooted = 0.8 + pigpio.exceptions = False + self.rxpin = int(parent.config['rxpin']) if ('rxpin' in parent.config) and parent.config['rxpin'] else 23 + self.bps = int(parent.config['bps']) if ('bps' in parent.config) and parent.config['rxpin'] else 2000 + self.pi = pigpio.pi() # Connect to local Pi + self.rx = virtualwire.rx(self.pi, self.rxpin, self.bps) # Specify Pi, rx GPIO. def run(self): - while True: - if self.getout: - break - time.sleep(.1) - self.count += 1 - heading, roll, pitch = self.bno.read_euler() - if pitch >= 90: - pdiff = pitch - 90 - pitch = 90 - pdiff - if roll > 0: - roll = -(roll - 180) - else: - roll = -(roll + 180) - elif pitch <= -90: - mpdiff = pitch + 90 - pitch = -(90 + mpdiff) - if roll > 0: - roll = -(roll - 180) - else: - roll = -(roll + 180) - if heading >= 180: - heading = heading - 180 - else: - heading = heading + 180 - try: - pitchset = self.parent.db_read("PITCHSET") - pitch = pitch + int(pitchset[0]) - except: - pass - self.parent.db_write("HEAD", heading) - self.parent.db_write("ROLL", roll) - self.parent.db_write("PITCH", pitch) - #time.sleep(.1) - x,y,z = self.bno.read_accelerometer() - x = -x/60 - self.parent.db_write("ALAT", x) - #self.parent.db_write("SYS", sys) - #self.parent.db_write("GYRO", gyro) - #self.parent.db_write("MAG", mag) - #self.log.debug("Yep") # Do something more useful here - self.running = False + while True: + if self.getout: + break + time.sleep(.25) + self.count += 1 + try: + while self.rx.ready(): + try: + msg = str("".join(chr (c) for c in self.rx.get())) + except: + msg = [400, -50] + #print msg + pass + msg = msg.split(',') + if float(msg[0]) < 400 : + init_ias = float(msg[0]) + self.ias = float((self.ias*self.smooted)+(1.0-self.smooted)*(init_ias)) + self.ias_W_S = 3 + if float(msg[1]) > -50 : + self.oat = float(msg[1]) + self.oat_W_S = 3 + else: + self.ias_W_S = 2 + self.oat_W_S = 2 + except: + self.ias_W_S = 2 + self.oat_W_S = 2 + pass + self.parent.db_write("IAS", int(self.ias)) + self.parent.db_write("OAT", self.oat) + self.parent.db_write("IASW", self.ias_W_S) + self.parent.db_write("OATW", self.oat_W_S) + self.running = False def stop(self): + self.rx.cancel() + self.pi.stop() self.getout = True diff --git a/src/plugins/virtualwire/virtualwire/__init__.py b/src/plugins/rpi_virtualwire/virtualwire/__init__.py similarity index 100% rename from src/plugins/virtualwire/virtualwire/__init__.py rename to src/plugins/rpi_virtualwire/virtualwire/__init__.py diff --git a/src/plugins/virtualwire/virtualwire/virtualwire.py b/src/plugins/rpi_virtualwire/virtualwire/virtualwire.py similarity index 99% rename from src/plugins/virtualwire/virtualwire/virtualwire.py rename to src/plugins/rpi_virtualwire/virtualwire/virtualwire.py index 231942f..d7ac520 100755 --- a/src/plugins/virtualwire/virtualwire/virtualwire.py +++ b/src/plugins/rpi_virtualwire/virtualwire/virtualwire.py @@ -1,3 +1,4 @@ +# coding: utf8 #!/usr/bin/env python # vw.py From 38835bc36c527f92369b5ff165f6d05205fcb769 Mon Sep 17 00:00:00 2001 From: Jean-manuel Gagnon Date: Thu, 29 Dec 2016 13:45:31 -0500 Subject: [PATCH 2/4] Add doc I think a doc are need to people wanted to use this plugins --- src/plugins/rpi_bmp085/doc/info.rst | 33 ++++++++ src/plugins/rpi_bno055/doc/info.rst | 59 +++++++++++++ src/plugins/rpi_button/doc/info.rst | 16 ++++ src/plugins/rpi_mcp3008/__init__.py | 8 +- src/plugins/rpi_mcp3008/doc/info.rst | 40 +++++++++ .../doc/sensors_raspberry_pi_mcp3008pin.gif | Bin 0 -> 14152 bytes src/plugins/rpi_rotary_encoder/doc/info.rst | 24 ++++++ src/plugins/rpi_virtualwire/Arduino/IAS.ino | 79 ++++++++++++++++++ src/plugins/rpi_virtualwire/doc/info.rst | 31 +++++++ 9 files changed, 287 insertions(+), 3 deletions(-) create mode 100644 src/plugins/rpi_bmp085/doc/info.rst create mode 100644 src/plugins/rpi_bno055/doc/info.rst create mode 100644 src/plugins/rpi_button/doc/info.rst create mode 100644 src/plugins/rpi_mcp3008/doc/info.rst create mode 100644 src/plugins/rpi_mcp3008/doc/sensors_raspberry_pi_mcp3008pin.gif create mode 100644 src/plugins/rpi_rotary_encoder/doc/info.rst create mode 100644 src/plugins/rpi_virtualwire/Arduino/IAS.ino create mode 100644 src/plugins/rpi_virtualwire/doc/info.rst diff --git a/src/plugins/rpi_bmp085/doc/info.rst b/src/plugins/rpi_bmp085/doc/info.rst new file mode 100644 index 0000000..ec734e3 --- /dev/null +++ b/src/plugins/rpi_bmp085/doc/info.rst @@ -0,0 +1,33 @@ +========================= +rpi_bmp085 plugins +========================= + +This precision sensor from Bosch is the best low-cost sensing solution for measuring barometric pressure and temperature. Because pressure changes with altitude you can also use it as an altimeter! The sensor is soldered onto a PCB with a 3.3V regulator, I2C level shifter and pull-up resistors on the I2C pins. + +* Pressure sensing range: 300-1100 hPa (9000m to -500m above sea level) +* Up to 0.03hPa / 0.25m resolution +* -40 to +85°C operational range, +-2°C temperature accuracy + + + +Configuration +------------------- + +[conn_bmp085] +load = yes # yes or no +module = plugins.rpi_bmp085 +tkey = CAT # temperature KEY +pkey = AIRPRESS # Air pressure KEY + +# Altitude result send directly to ALT KEY in feet + +Installation +-------------------- + +https://learn.adafruit.com/using-the-bmp085-with-raspberry-pi/using-the-adafruit-bmp085-python-library?view=all + +* sudo apt-get update +* sudo apt-get install git build-essential python-dev python-smbus +* git clone https://github.com/adafruit/Adafruit_Python_BMP.git +* cd Adafruit_Python_BMP +* sudo python setup.py install diff --git a/src/plugins/rpi_bno055/doc/info.rst b/src/plugins/rpi_bno055/doc/info.rst new file mode 100644 index 0000000..70ab268 --- /dev/null +++ b/src/plugins/rpi_bno055/doc/info.rst @@ -0,0 +1,59 @@ +========================= +rpi_bno055 plugins +========================= + +If you've ever ordered and wire up a 9-DOF sensor, chances are you've also realized the challenge of turning the sensor data from an accelerometer, gyroscope and magnetometer into actual "3D space orientation"! Orientation is a hard problem to solve. The sensor fusion algorithms (the secret sauce that blends accelerometer, magnetometer and gyroscope data into stable three-axis orientation output) can be mind-numbingly difficult to get right and implement on low cost real time systems. + +Bosch is the first company to get this right by taking a MEMS accelerometer, magnetometer and gyroscope and putting them on a single die with a high speed ARM Cortex-M0 based processor to digest all the sensor data, abstract the sensor fusion and real time requirements away, and spit out data you can use in quaternions, Euler angles or vectors. + +Rather than spending weeks or months fiddling with algorithms of varying accuracy and complexity, you can have meaningful sensor data in minutes thanks to the BNO055 - a smart 9-DOF sensor that does the sensor fusion all on its own! + + +The BNO055 can output the following sensor data: + + +Absolute Orientation (Euler Vector, 100Hz) +*Three axis orientation data based on a 360° sphere + +Absolute Orientation (Quaterion, 100Hz) +*Four point quaternion output for more accurate data manipulation + +Angular Velocity Vector (100Hz) +*Three axis of 'rotation speed' in rad/s + +Acceleration Vector (100Hz) +*Three axis of acceleration (gravity + linear motion) in m/s^2 + +Magnetic Field Strength Vector (20Hz) +*Three axis of magnetic field sensing in micro Tesla (uT) + +Linear Acceleration Vector (100Hz) +*Three axis of linear acceleration data (acceleration minus gravity) in m/s^2 + +Gravity Vector (100Hz) +*Three axis of gravitational acceleration (minus any movement) in m/s^2 + +Temperature (1Hz) +*Ambient temperature in degrees celsius + +But this plugins automatique put absolute orientation and acceleration data to database at +/-60Hz + +Configuration +------------------- + +[conn_bno055] +load = yes +module = plugins.rpi_bno055 + +Independency installation +-------------------- + +https://learn.adafruit.com/bno055-absolute-orientation-sensor-with-raspberry-pi-and-beaglebone-black/hardware?view=all + +* Disable the kernel serial port +* sudo apt-get update +* sudo apt-get install -y build-essential python-dev python-smbus python-pip git +* cd ~ +* git clone https://github.com/adafruit/Adafruit_Python_BNO055.git +* cd Adafruit_Python_BNO055 +* sudo python setup.py install diff --git a/src/plugins/rpi_button/doc/info.rst b/src/plugins/rpi_button/doc/info.rst new file mode 100644 index 0000000..ad72e64 --- /dev/null +++ b/src/plugins/rpi_button/doc/info.rst @@ -0,0 +1,16 @@ +========================= +rpi_button plugins +========================= + +This plugins is a small python script to handle a momentary button. You can adjust the repeat delay or simply use the debouncing feature + + +Configuration +------------------- + +[conn_button1] +load = no +module = plugins.rpi_button +btnkey = BTN1 # KEY name in database +btnpin = 4 # GPIO pin on raspberry pi +rdelay = 0 # 0 for debouncing or time in seconde to determine the repeat delay \ No newline at end of file diff --git a/src/plugins/rpi_mcp3008/__init__.py b/src/plugins/rpi_mcp3008/__init__.py index 9bc3057..c65f9d9 100755 --- a/src/plugins/rpi_mcp3008/__init__.py +++ b/src/plugins/rpi_mcp3008/__init__.py @@ -53,9 +53,11 @@ def __init__(self, parent): self.VKEY6 = parent.config['vkey6'] if ('vkey6' in parent.config) and parent.config['vkey6'] else "ANLG6" self.VKEY7 = parent.config['vkey7'] if ('vkey7' in parent.config) and parent.config['vkey7'] else "ANLG7" self.VKEY8 = parent.config['vkey8'] if ('vkey8' in parent.config) and parent.config['vkey8'] else "ANLG8" - - #self.mcp = Adafruit_MCP3008.MCP3008(clk=self.CLK, cs=self.CS, miso=self.MISO, mosi=self.MOSI) - self.mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE)) + self.HARDW = parent.config['hardw'] if ('hardw' in parent.config) and parent.config['hardw'] else "False" + if HARDW == True: + self.mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE)) + else: + self.mcp = Adafruit_MCP3008.MCP3008(clk=self.CLK, cs=self.CS, miso=self.MISO, mosi=self.MOSI) def run(self): while True: diff --git a/src/plugins/rpi_mcp3008/doc/info.rst b/src/plugins/rpi_mcp3008/doc/info.rst new file mode 100644 index 0000000..b3bf741 --- /dev/null +++ b/src/plugins/rpi_mcp3008/doc/info.rst @@ -0,0 +1,40 @@ +========================= +rpi_mcp3008 plugins +========================= + +The MCP3008 is a low cost 8-channel 10-bit analog to digital converter. The precision of this ADC is similar to that of an Arduino Uno, and with 8 channels you can read quite a few analog signals from the Pi. This chip is a great option if you just need to read simple analog signals, like from a temperature or light sensor. + + +Configuration +------------------- + +[conn_mcp3008] +load = yes +module = plugins.rpi_mcp3008 +vkey1 = ANLG1 # mcp3008 pin 1 to KEY in database +vkey2 = ANLG2 +vkey3 = ANLG3 +vkey4 = ANLG4 +vkey5 = ANLG5 +vkey6 = ANLG6 +vkey7 = ANLG7 +vkey8 = ANLG8 +hardw = True # if you want to use hardware SPI or False for software SPI + +#Software SPI pin Not need if you use hardware SPI +clk = 18 # Software SPI clk pin +miso = 23 # Software SPI miso pin +mosi = 24 # Software SPI mosi pin +cs = 25 # Software SPI cs pin + +Installation +-------------------- + +https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters/mcp3008 + +sudo apt-get update +sudo apt-get install build-essential python-dev python-smbus git +cd ~ +git clone https://github.com/adafruit/Adafruit_Python_MCP3008.git +cd Adafruit_Python_MCP3008 +sudo python setup.py install diff --git a/src/plugins/rpi_mcp3008/doc/sensors_raspberry_pi_mcp3008pin.gif b/src/plugins/rpi_mcp3008/doc/sensors_raspberry_pi_mcp3008pin.gif new file mode 100644 index 0000000000000000000000000000000000000000..eccc62624eab91d6541e879a5da3827aa5bc4a92 GIT binary patch literal 14152 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 SvSAy#;TytX94b%{002ACP*W}d literal 0 HcmV?d00001 diff --git a/src/plugins/rpi_rotary_encoder/doc/info.rst b/src/plugins/rpi_rotary_encoder/doc/info.rst new file mode 100644 index 0000000..63b4113 --- /dev/null +++ b/src/plugins/rpi_rotary_encoder/doc/info.rst @@ -0,0 +1,24 @@ +========================= +rpi_rotary_encoder plugins +========================= + +This plugins is a small python script to handle a rotary encoder with or without push button. You can use push button to handle 2 setting. You can adjust start setting point and the increment for bolt KEY + +TODO : Create a menu navigator like Garmin GNC or GNS series. + +Configuration +------------------- + +[conn_rotary_encoder] +load = yes +module = plugins.rpi_rotary_encoder +btn = True # Enable push button +btnkey = BARO # when the push button is pressed this KEY change with the rotary encoder +btnstcounter = 29.92 # start setting point when the push button is pressed +btnincr = 0.01 # Each click increment +btnpin = 4 # GPIO pin +pina = 26 #encoder GPIO pin_a +pinb = 19 #encoder GPIO pin_b +stcount = 0 # Standard start point +rkey = PITCHSET # KEY change with the rotary encoder +incr = 1 # Each click increment diff --git a/src/plugins/rpi_virtualwire/Arduino/IAS.ino b/src/plugins/rpi_virtualwire/Arduino/IAS.ino new file mode 100644 index 0000000..e693053 --- /dev/null +++ b/src/plugins/rpi_virtualwire/Arduino/IAS.ino @@ -0,0 +1,79 @@ +/* + Takes an input on the arduino pro from analog input 3 + and outputs it using 433mhz tranceiver + */ +#include +#include +Thermistor temp(4); +#define A_INPUT A3 +#undef int +#undef abs +#undef double +#undef float +#undef round +float airspeed_kn; +float oat; +char ias_String[24]; +char oat_String[24]; +char msg[27]; +int initval; +const char *ias_Name = "ias="; +const char *oat_Name = "oat="; + +void setup () { + pinMode(13,OUTPUT); + pinMode(3,OUTPUT); + digitalWrite(3,HIGH); + analogReference (DEFAULT); // or EXTERNAL or INTERNAL + for (int i = 0; i < 8; i++) + analogRead (A_INPUT), delay (120); + initval = 0; + for (int i = 0; i < 8; i++) + initval += analogRead (A_INPUT), delay (120); + initval = (initval >> 3) + 1; + vw_set_ptt_inverted(true); + vw_set_tx_pin(2); + vw_setup(2000); // Bits per sec +} + +void loop () { +#define ABSOLUTE_0_KELVIN 273.16f +#define PRESSURE_SEA_LEVEL 101325.0f + int currval = 0; + for (int i = 0; i < 8; i++) + currval += analogRead (A_INPUT), delay (10); + currval >>= 3; + if (currval < initval) + currval = initval; + float pitotpressure = 5000.0f * ((currval - initval) / 1024.0f) + PRESSURE_SEA_LEVEL; // differential pressure in Pa, 1 V/kPa, max 3920 Pa + float ambientpressure = PRESSURE_SEA_LEVEL; + float temperature = 20.0f + ABSOLUTE_0_KELVIN; + float airspeed_ms = get_air_speed (pitotpressure, ambientpressure, temperature); // speed in m/s + airspeed_kn = airspeed_ms * 3600 / 1852.0; // convert to knots + oat = temp.getTemp(); + send_Data (); + } + + float get_air_speed (float frontpressure, float externalpressure, float temperature) +{ +#define UNIVERSAL_GAS_CONSTANT 8.3144621f +#define DRY_AIR_MOLAR_MASS 0.0289644f + + float density = (externalpressure * DRY_AIR_MOLAR_MASS) / (temperature * UNIVERSAL_GAS_CONSTANT); + return sqrt ((2 * (frontpressure - externalpressure)) / density); +} + +/* ********************** 433 mhz interface ********************** */ + +void send_Data() +{ + digitalWrite(13,HIGH); + dtostrf(airspeed_kn, 5, 1, ias_String); + dtostrf(oat, 4, 1,oat_String); + //Combining to one string + sprintf(msg, "%s, %s", ias_String, oat_String); + vw_send((uint8_t *)msg, strlen(msg)); + vw_wait_tx(); + digitalWrite(13,LOW); +} + diff --git a/src/plugins/rpi_virtualwire/doc/info.rst b/src/plugins/rpi_virtualwire/doc/info.rst new file mode 100644 index 0000000..006595b --- /dev/null +++ b/src/plugins/rpi_virtualwire/doc/info.rst @@ -0,0 +1,31 @@ +========================= +rpi_virtualwire plugins +========================= + +Class to send and receive radio messages compatible with the Virtual Wire library for Arduinos. This library is commonly used with 313MHz and 434MHz radio tranceivers. + +This plugins is a complex hardware and software configuration. See in Arduino folder to see the code. + +TODO : Create a to explain how to reproduce this little device + +Configuration +-------------------- + +[conn_virtualwire] +load = yes +module = plugins.rpi_virtualwire +rxpin = 23 # GPIO pin +bps = 2000 # Bits per second (bps). The bps defaults to 2000. + +Independency installation +-------------------- + +http://abyz.co.uk/rpi/pigpio/ + +rm pigpio.zip +sudo rm -rf PIGPIO +wget abyz.co.uk/rpi/pigpio/pigpio.zip +unzip pigpio.zip +cd PIGPIO +make -j4 +sudo make install \ No newline at end of file From e07b3fa654c417e16095c1b946fba9e233c52259 Mon Sep 17 00:00:00 2001 From: Jean-manuel Gagnon Date: Thu, 29 Dec 2016 13:54:02 -0500 Subject: [PATCH 3/4] doc corection --- src/plugins/rpi_bmp085/doc/info.rst | 12 ++--- src/plugins/rpi_bno055/doc/info.rst | 6 +-- src/plugins/rpi_button/doc/info.rst | 12 ++--- src/plugins/rpi_mcp3008/doc/info.rst | 51 +++++++++++---------- src/plugins/rpi_rotary_encoder/doc/info.rst | 28 +++++------ src/plugins/rpi_virtualwire/doc/info.rst | 28 +++++------ 6 files changed, 69 insertions(+), 68 deletions(-) diff --git a/src/plugins/rpi_bmp085/doc/info.rst b/src/plugins/rpi_bmp085/doc/info.rst index ec734e3..1280caf 100644 --- a/src/plugins/rpi_bmp085/doc/info.rst +++ b/src/plugins/rpi_bmp085/doc/info.rst @@ -13,13 +13,13 @@ This precision sensor from Bosch is the best low-cost sensing solution for measu Configuration ------------------- -[conn_bmp085] -load = yes # yes or no -module = plugins.rpi_bmp085 -tkey = CAT # temperature KEY -pkey = AIRPRESS # Air pressure KEY +* [conn_bmp085] +* load = yes # yes or no +* module = plugins.rpi_bmp085 +* tkey = CAT # temperature KEY +* pkey = AIRPRESS # Air pressure KEY -# Altitude result send directly to ALT KEY in feet +* # Altitude result send directly to ALT KEY in feet Installation -------------------- diff --git a/src/plugins/rpi_bno055/doc/info.rst b/src/plugins/rpi_bno055/doc/info.rst index 70ab268..3fc16f7 100644 --- a/src/plugins/rpi_bno055/doc/info.rst +++ b/src/plugins/rpi_bno055/doc/info.rst @@ -41,9 +41,9 @@ But this plugins automatique put absolute orientation and acceleration data to d Configuration ------------------- -[conn_bno055] -load = yes -module = plugins.rpi_bno055 +* [conn_bno055] +* load = yes +* module = plugins.rpi_bno055 Independency installation -------------------- diff --git a/src/plugins/rpi_button/doc/info.rst b/src/plugins/rpi_button/doc/info.rst index ad72e64..e654a5c 100644 --- a/src/plugins/rpi_button/doc/info.rst +++ b/src/plugins/rpi_button/doc/info.rst @@ -8,9 +8,9 @@ This plugins is a small python script to handle a momentary button. You can adju Configuration ------------------- -[conn_button1] -load = no -module = plugins.rpi_button -btnkey = BTN1 # KEY name in database -btnpin = 4 # GPIO pin on raspberry pi -rdelay = 0 # 0 for debouncing or time in seconde to determine the repeat delay \ No newline at end of file +* [conn_button1] +* load = no +* module = plugins.rpi_button +* btnkey = BTN1 # KEY name in database +* btnpin = 4 # GPIO pin on raspberry pi +* rdelay = 0 # 0 for debouncing or time in seconde to determine the repeat delay \ No newline at end of file diff --git a/src/plugins/rpi_mcp3008/doc/info.rst b/src/plugins/rpi_mcp3008/doc/info.rst index b3bf741..6276106 100644 --- a/src/plugins/rpi_mcp3008/doc/info.rst +++ b/src/plugins/rpi_mcp3008/doc/info.rst @@ -8,33 +8,34 @@ The MCP3008 is a low cost 8-channel 10-bit analog to digital converter. The pre Configuration ------------------- -[conn_mcp3008] -load = yes -module = plugins.rpi_mcp3008 -vkey1 = ANLG1 # mcp3008 pin 1 to KEY in database -vkey2 = ANLG2 -vkey3 = ANLG3 -vkey4 = ANLG4 -vkey5 = ANLG5 -vkey6 = ANLG6 -vkey7 = ANLG7 -vkey8 = ANLG8 -hardw = True # if you want to use hardware SPI or False for software SPI - -#Software SPI pin Not need if you use hardware SPI -clk = 18 # Software SPI clk pin -miso = 23 # Software SPI miso pin -mosi = 24 # Software SPI mosi pin -cs = 25 # Software SPI cs pin +* [conn_mcp3008] +* load = yes +* module = plugins.rpi_mcp3008 +* vkey1 = ANLG1 # mcp3008 pin 1 to KEY in database +* vkey2 = ANLG2 +* vkey3 = ANLG3 +* vkey4 = ANLG4 +* vkey5 = ANLG5 +* vkey6 = ANLG6 +* vkey7 = ANLG7 +* vkey8 = ANLG8 +* hardw = True # if you want to use hardware SPI or False for software SPI + +Software SPI pin Not need if you use hardware SPI +————————— +* clk = 18 # Software SPI clk pin +* miso = 23 # Software SPI miso pin +* mosi = 24 # Software SPI mosi pin +* cs = 25 # Software SPI cs pin Installation -------------------- -https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters/mcp3008 +* https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters/mcp3008 -sudo apt-get update -sudo apt-get install build-essential python-dev python-smbus git -cd ~ -git clone https://github.com/adafruit/Adafruit_Python_MCP3008.git -cd Adafruit_Python_MCP3008 -sudo python setup.py install +* sudo apt-get update +* sudo apt-get install build-essential python-dev python-smbus git +* cd ~ +* git clone https://github.com/adafruit/Adafruit_Python_MCP3008.git +* cd Adafruit_Python_MCP3008 +* sudo python setup.py install diff --git a/src/plugins/rpi_rotary_encoder/doc/info.rst b/src/plugins/rpi_rotary_encoder/doc/info.rst index 63b4113..cdb9bc5 100644 --- a/src/plugins/rpi_rotary_encoder/doc/info.rst +++ b/src/plugins/rpi_rotary_encoder/doc/info.rst @@ -4,21 +4,21 @@ rpi_rotary_encoder plugins This plugins is a small python script to handle a rotary encoder with or without push button. You can use push button to handle 2 setting. You can adjust start setting point and the increment for bolt KEY -TODO : Create a menu navigator like Garmin GNC or GNS series. +* TODO : Create a menu navigator like Garmin GNC or GNS series. Configuration ------------------- -[conn_rotary_encoder] -load = yes -module = plugins.rpi_rotary_encoder -btn = True # Enable push button -btnkey = BARO # when the push button is pressed this KEY change with the rotary encoder -btnstcounter = 29.92 # start setting point when the push button is pressed -btnincr = 0.01 # Each click increment -btnpin = 4 # GPIO pin -pina = 26 #encoder GPIO pin_a -pinb = 19 #encoder GPIO pin_b -stcount = 0 # Standard start point -rkey = PITCHSET # KEY change with the rotary encoder -incr = 1 # Each click increment +* [conn_rotary_encoder] +* load = yes +* module = plugins.rpi_rotary_encoder +* btn = True # Enable push button +* btnkey = BARO # when the push button is pressed this KEY change with the rotary encoder +* btnstcounter = 29.92 # start setting point when the push button is pressed +* btnincr = 0.01 # Each click increment +* btnpin = 4 # GPIO pin +* pina = 26 #encoder GPIO pin_a +* pinb = 19 #encoder GPIO pin_b +* stcount = 0 # Standard start point +* rkey = PITCHSET # KEY change with the rotary encoder +* incr = 1 # Each click increment diff --git a/src/plugins/rpi_virtualwire/doc/info.rst b/src/plugins/rpi_virtualwire/doc/info.rst index 006595b..5098603 100644 --- a/src/plugins/rpi_virtualwire/doc/info.rst +++ b/src/plugins/rpi_virtualwire/doc/info.rst @@ -6,26 +6,26 @@ Class to send and receive radio messages compatible with the Virtual Wire librar This plugins is a complex hardware and software configuration. See in Arduino folder to see the code. -TODO : Create a to explain how to reproduce this little device +* TODO : Create a to explain how to reproduce this little device Configuration -------------------- -[conn_virtualwire] -load = yes -module = plugins.rpi_virtualwire -rxpin = 23 # GPIO pin -bps = 2000 # Bits per second (bps). The bps defaults to 2000. +* [conn_virtualwire] +* load = yes +* module = plugins.rpi_virtualwire +* rxpin = 23 # GPIO pin +* bps = 2000 # Bits per second (bps). The bps defaults to 2000. Independency installation -------------------- -http://abyz.co.uk/rpi/pigpio/ +* http://abyz.co.uk/rpi/pigpio/ -rm pigpio.zip -sudo rm -rf PIGPIO -wget abyz.co.uk/rpi/pigpio/pigpio.zip -unzip pigpio.zip -cd PIGPIO -make -j4 -sudo make install \ No newline at end of file +* rm pigpio.zip +* sudo rm -rf PIGPIO +* wget abyz.co.uk/rpi/pigpio/pigpio.zip +* unzip pigpio.zip +* cd PIGPIO +* make -j4 +* sudo make install \ No newline at end of file From 6ad4d10caa3b142986b2dd12a734a4d817961d37 Mon Sep 17 00:00:00 2001 From: Jean-manuel Gagnon Date: Thu, 29 Dec 2016 13:58:05 -0500 Subject: [PATCH 4/4] doc correction --- src/plugins/rpi_mcp3008/doc/info.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/rpi_mcp3008/doc/info.rst b/src/plugins/rpi_mcp3008/doc/info.rst index 6276106..a217eb6 100644 --- a/src/plugins/rpi_mcp3008/doc/info.rst +++ b/src/plugins/rpi_mcp3008/doc/info.rst @@ -22,7 +22,7 @@ Configuration * hardw = True # if you want to use hardware SPI or False for software SPI Software SPI pin Not need if you use hardware SPI -————————— +-------------------- * clk = 18 # Software SPI clk pin * miso = 23 # Software SPI miso pin * mosi = 24 # Software SPI mosi pin