feat(pressure):Add python script for outputting pressure to stdout
authorSteven Baltakatei Sandoval <baltakatei@gmail.com>
Sat, 11 Jul 2020 08:42:46 +0000 (08:42 +0000)
committerSteven Baltakatei Sandoval <baltakatei@gmail.com>
Sat, 11 Jul 2020 08:42:46 +0000 (08:42 +0000)
doc/pressure/README.org [new file with mode: 0644]
exec/pressure/bmp388.py [new file with mode: 0644]

diff --git a/doc/pressure/README.org b/doc/pressure/README.org
new file mode 100644 (file)
index 0000000..3852ac4
--- /dev/null
@@ -0,0 +1,43 @@
+* Software
+** BMP388 Pressure sensor
+The following command will download a repository containing a python
+script that can pull pressure data from the BerryGPS-IMU v3.5's BMP388
+: git clone https://github.com/getelectronics/PIBits.git
+*** 2020-04-10 Note regarding getting data from BMP388 (task:8a5607fe)
+2020-04-10T03:03Z; baltakatei>
+
+- I ordered another two Raspberry Pi Zero W's and another BerryIMU-GPS.
+
+- I think I found the problem with the pressure sensor. According to a
+  2020-03-12 post by johnmark at
+  https://ozzmaker.com/forums/topic/temp-barometer/ , the BerryIMU-GPS
+  version 3.5 uses BMP388, not BMP280. johnmark posted a link to a
+  python script that works for the BMP388 pressure sensor at:
+  
+    https://github.com/getelectronics/PIBits/blob/master/python/bmp388.py
+
+- I have downloaded this PIBits git repository to jalrasaroa-02 and am
+  testing it now. It works.
+
+- I am checking to see how I can automatically update the clock on
+  jalrasaora-02 via a network time server. Reading instructions at
+  https://www.garron.me/en/go2linux/how-to-set-date-and-time-linux.html
+  .
+
+- I am installing the `ntp` package described here:
+
+    https://www.digitalocean.com/community/tutorials/how-to-set-up-time-synchronization-on-debian-10
+
+    $ sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get install ntp
+
+  - I confirmed that the ntp time synchronization service is running with:
+
+    sudo systemctl status ntp
+
+- I am creating a git repository to store executables and setup
+  instructions for Raspberry Pi Zero W's used for logging:
+
+  - Location (GPS WGS84)
+  - Air pressure (Pa)
+  - Temperature (°C)
+  - Direction (magnetic north heading)
diff --git a/exec/pressure/bmp388.py b/exec/pressure/bmp388.py
new file mode 100644 (file)
index 0000000..b396b59
--- /dev/null
@@ -0,0 +1,217 @@
+#!/usr/bin/python\r
+# -*- coding: utf-8 -*-\r
+import time\r
+import smbus\r
+import math\r
+\r
+# define BMP388 Device I2C address\r
+\r
+I2C_ADD_BMP388_AD0_LOW = 0x76\r
+I2C_ADD_BMP388_AD0_HIGH = 0x77\r
+I2C_ADD_BMP388 = I2C_ADD_BMP388_AD0_HIGH\r
+\r
+BMP388_REG_ADD_WIA = 0x00\r
+BMP388_REG_VAL_WIA = 0x50\r
+\r
+BMP388_REG_ADD_ERR = 0x02\r
+BMP388_REG_VAL_FATAL_ERR = 0x01\r
+BMP388_REG_VAL_CMD_ERR = 0x02\r
+BMP388_REG_VAL_CONF_ERR = 0x04\r
+\r
+BMP388_REG_ADD_STATUS = 0x03\r
+BMP388_REG_VAL_CMD_RDY = 0x10\r
+BMP388_REG_VAL_DRDY_PRESS = 0x20\r
+BMP388_REG_VAL_DRDY_TEMP = 0x40\r
+\r
+BMP388_REG_ADD_CMD = 0x7E\r
+BMP388_REG_VAL_EXTMODE_EN = 0x34\r
+BMP388_REG_VAL_FIFI_FLUSH = 0xB0\r
+BMP388_REG_VAL_SOFT_RESET = 0xB6\r
+\r
+BMP388_REG_ADD_PWR_CTRL = 0x1B\r
+BMP388_REG_VAL_PRESS_EN = 0x01\r
+BMP388_REG_VAL_TEMP_EN = 0x02\r
+BMP388_REG_VAL_NORMAL_MODE = 0x30\r
+\r
+BMP388_REG_ADD_PRESS_XLSB = 0x04\r
+BMP388_REG_ADD_PRESS_LSB = 0x05\r
+BMP388_REG_ADD_PRESS_MSB = 0x06\r
+BMP388_REG_ADD_TEMP_XLSB = 0x07\r
+BMP388_REG_ADD_TEMP_LSB = 0x08\r
+BMP388_REG_ADD_TEMP_MSB = 0x09\r
+\r
+BMP388_REG_ADD_T1_LSB = 0x31\r
+BMP388_REG_ADD_T1_MSB = 0x32\r
+BMP388_REG_ADD_T2_LSB = 0x33\r
+BMP388_REG_ADD_T2_MSB = 0x34\r
+BMP388_REG_ADD_T3 = 0x35\r
+BMP388_REG_ADD_P1_LSB = 0x36\r
+BMP388_REG_ADD_P1_MSB = 0x37\r
+BMP388_REG_ADD_P2_LSB = 0x38\r
+BMP388_REG_ADD_P2_MSB = 0x39\r
+BMP388_REG_ADD_P3 = 0x3A\r
+BMP388_REG_ADD_P4 = 0x3B\r
+BMP388_REG_ADD_P5_LSB = 0x3C\r
+BMP388_REG_ADD_P5_MSB = 0x3D\r
+BMP388_REG_ADD_P6_LSB = 0x3E\r
+BMP388_REG_ADD_P6_MSB = 0x3F\r
+BMP388_REG_ADD_P7 = 0x40\r
+BMP388_REG_ADD_P8 = 0x41\r
+BMP388_REG_ADD_P9_LSB = 0x42\r
+BMP388_REG_ADD_P9_MSB = 0x43\r
+BMP388_REG_ADD_P10 = 0x44\r
+BMP388_REG_ADD_P11 = 0x45\r
+\r
+\r
+class BMP388(object):\r
+\r
+    """docstring for BMP388"""\r
+\r
+    def __init__(self, address=I2C_ADD_BMP388):\r
+        self._address = address\r
+        self._bus = smbus.SMBus(0x01)\r
+\r
+        # Load calibration values.\r
+\r
+        if self._read_byte(BMP388_REG_ADD_WIA) == BMP388_REG_VAL_WIA:\r
+            print("Pressure sersor is BMP388!\r\n")\r
+            u8RegData = self._read_byte(BMP388_REG_ADD_STATUS)\r
+            if u8RegData & BMP388_REG_VAL_CMD_RDY:\r
+                self._write_byte(BMP388_REG_ADD_CMD,\r
+                                 BMP388_REG_VAL_SOFT_RESET)\r
+                time.sleep(0.01)\r
+        else:\r
+            print ("Pressure sersor NULL!\r\n")\r
+        self._write_byte(BMP388_REG_ADD_PWR_CTRL,\r
+                         BMP388_REG_VAL_PRESS_EN\r
+                         | BMP388_REG_VAL_TEMP_EN\r
+                         | BMP388_REG_VAL_NORMAL_MODE)\r
+        self._load_calibration()\r
+\r
+    def _read_byte(self, cmd):\r
+        return self._bus.read_byte_data(self._address, cmd)\r
+\r
+    def _read_s8(self, cmd):\r
+        result = self._read_byte(cmd)\r
+        if result > 128:\r
+            result -= 256\r
+        return result\r
+\r
+    def _read_u16(self, cmd):\r
+        LSB = self._bus.read_byte_data(self._address, cmd)\r
+        MSB = self._bus.read_byte_data(self._address, cmd + 0x01)\r
+        return (MSB << 0x08) + LSB\r
+\r
+    def _read_s16(self, cmd):\r
+        result = self._read_u16(cmd)\r
+        if result > 32767:\r
+            result -= 65536\r
+        return result\r
+\r
+    def _write_byte(self, cmd, val):\r
+        self._bus.write_byte_data(self._address, cmd, val)\r
+\r
+    def _load_calibration(self):\r
+        print ("_load_calibration\r\n")\r
+        self.T1 = self._read_u16(BMP388_REG_ADD_T1_LSB)\r
+        self.T2 = self._read_u16(BMP388_REG_ADD_T2_LSB)\r
+        self.T3 = self._read_s8(BMP388_REG_ADD_T3)\r
+        self.P1 = self._read_s16(BMP388_REG_ADD_P1_LSB)\r
+        self.P2 = self._read_s16(BMP388_REG_ADD_P2_LSB)\r
+        self.P3 = self._read_s8(BMP388_REG_ADD_P3)\r
+        self.P4 = self._read_s8(BMP388_REG_ADD_P4)\r
+        self.P5 = self._read_u16(BMP388_REG_ADD_P5_LSB)\r
+        self.P6 = self._read_u16(BMP388_REG_ADD_P6_LSB)\r
+        self.P7 = self._read_s8(BMP388_REG_ADD_P7)\r
+        self.P8 = self._read_s8(BMP388_REG_ADD_P8)\r
+        self.P9 = self._read_s16(BMP388_REG_ADD_P9_LSB)\r
+        self.P10 = self._read_s8(BMP388_REG_ADD_P10)\r
+        self.P11 = self._read_s8(BMP388_REG_ADD_P11)\r
+\r
+        # print(self.T1)\r
+        # print(self.T2)\r
+        # print(self.T3)\r
+        # print(self.P1)\r
+        # print(self.P2)\r
+        # print(self.P3)\r
+        # print(self.P4)\r
+        # print(self.P5)\r
+        # print(self.P6)\r
+        # print(self.P7)\r
+        # print(self.P8)\r
+        # print(self.P9)\r
+        # print(self.P10)\r
+        # print(self.P11)\r
+\r
+    def compensate_temperature(self, adc_T):\r
+        partial_data1 = adc_T - 256 * self.T1\r
+        partial_data2 = self.T2 * partial_data1\r
+        partial_data3 = partial_data1 * partial_data1\r
+        partial_data4 = partial_data3 * self.T3\r
+        partial_data5 = partial_data2 * 262144 + partial_data4\r
+        partial_data6 = partial_data5 / 4294967296\r
+        self.T_fine = partial_data6\r
+        comp_temp = partial_data6 * 25 / 16384\r
+        return comp_temp\r
+\r
+    def compensate_pressure(self, adc_P):\r
+        partial_data1 = self.T_fine * self.T_fine\r
+        partial_data2 = partial_data1 / 0x40\r
+        partial_data3 = partial_data2 * self.T_fine / 256\r
+        partial_data4 = self.P8 * partial_data3 / 0x20\r
+        partial_data5 = self.P7 * partial_data1 * 0x10\r
+        partial_data6 = self.P6 * self.T_fine * 4194304\r
+        offset = self.P5 * 140737488355328 + partial_data4 \\r
+            + partial_data5 + partial_data6\r
+\r
+        partial_data2 = self.P4 * partial_data3 / 0x20\r
+        partial_data4 = self.P3 * partial_data1 * 0x04\r
+        partial_data5 = (self.P2 - 16384) * self.T_fine * 2097152\r
+        sensitivity = (self.P1 - 16384) * 70368744177664 \\r
+            + partial_data2 + partial_data4 + partial_data5\r
+\r
+        partial_data1 = sensitivity / 16777216 * adc_P\r
+        partial_data2 = self.P10 * self.T_fine\r
+        partial_data3 = partial_data2 + 65536 * self.P9\r
+        partial_data4 = partial_data3 * adc_P / 8192\r
+        partial_data5 = partial_data4 * adc_P / 512\r
+        partial_data6 = adc_P * adc_P\r
+        partial_data2 = self.P11 * partial_data6 / 65536\r
+        partial_data3 = partial_data2 * adc_P / 128\r
+        partial_data4 = offset / 0x04 + partial_data1 + partial_data5 \\r
+            + partial_data3\r
+        comp_press = partial_data4 * 25 / 1099511627776\r
+        return comp_press\r
+\r
+    def get_temperature_and_pressure_and_altitude(self):\r
+        """Returns pressure in Pa as double. Output value of "6386.2"equals 96386.2 Pa = 963.862 hPa."""\r
+\r
+        xlsb = self._read_byte(BMP388_REG_ADD_TEMP_XLSB)\r
+        lsb = self._read_byte(BMP388_REG_ADD_TEMP_LSB)\r
+        msb = self._read_byte(BMP388_REG_ADD_TEMP_MSB)\r
+        adc_T = (msb << 0x10) + (lsb << 0x08) + xlsb\r
+        temperature = self.compensate_temperature(adc_T)\r
+        xlsb = self._read_byte(BMP388_REG_ADD_PRESS_XLSB)\r
+        lsb = self._read_byte(BMP388_REG_ADD_PRESS_LSB)\r
+        msb = self._read_byte(BMP388_REG_ADD_PRESS_MSB)\r
+\r
+        adc_P = (msb << 0x10) + (lsb << 0x08) + xlsb\r
+        pressure = self.compensate_pressure(adc_P)\r
+        altitude = 4433000 * (0x01 - pow(pressure / 100.0 / 101325.0,\r
+                              0.1903))\r
+\r
+        return (temperature, pressure, altitude)\r
+\r
+\r
+if __name__ == '__main__':\r
+\r
+       import time\r
+       \r
+       print("BMP388 Test Program ...\n")\r
+       \r
+       bmp388 = BMP388()\r
+                               \r
+       while True:\r
+               time.sleep(0.5)\r
+               temperature,pressure,altitude = bmp388.get_temperature_and_pressure_and_altitude()\r
+               print(' Temperature = %.1f Pressure = %.2f  Altitude =%.2f '%(temperature/100.0,pressure/100.0,altitude/100.0))\r