#!/usr/bin/python3
from fcntl import ioctl
import os
import time

# return two bytes from data as an unsigned 16-bit value
def get_uint16(dat, index):  
	return (dat[index] << 8) + dat[index + 1]

# return two bytes from data as a signed 16-bit value
def get_int16(dat, index):  
	val = (dat[index] << 8) + dat[index + 1]
	if val > 32767:
		val = val - 65536
	return val

# refine bmp180 raw sample, ref. bmp180 datasheet
def refine_UT_UP(UT, UP, OVERSAMPLE = 3):
	# Refine temperature
	X1 = ((UT - AC6) * AC5) >> 15
	X2 = (MC << 11) / (X1 + MD)
	B5 = X1 + X2
	temperature = int(B5 + 8) >> 4

	# Refine pressure
	UP = UP >> (8 - OVERSAMPLE)
	B6  = B5 - 4000
	B62 = int(B6 * B6) >> 12
	X1  = (B2 * B62) >> 11
	X2  = int(AC2 * B6) >> 11
	X3  = X1 + X2
	B3  = (((AC1 * 4 + X3) << OVERSAMPLE) + 2) >> 2

	X1 = int(AC3 * B6) >> 13
	X2 = (B1 * B62) >> 16
	X3 = ((X1 + X2) + 2) >> 2
	B4 = (AC4 * (X3 + 32768)) >> 15
	B7 = (UP - B3) * (50000 >> OVERSAMPLE)

	P = (B7 * 2) / B4

	X1 = (int(P) >> 8) * (int(P) >> 8)
	X1 = (X1 * 3038) >> 16
	X2 = int(-7357 * P) >> 16
	pressure = int(P + ((X1 + X2 + 3791) >> 4))

	# Return temperature in degree C; pressure in mbar
	return(temperature/10.0, pressure/100.0)


# ======== gpio ===========
# gpio0 --> touch sensor power
# gpio1 <-- touch sensor output
os.system('echo in  > /sys/class/gpio/gpio1/direction')
os.system('echo out > /sys/class/gpio/gpio0/direction')
# Set gpio0 high, touch sensor power on, LED on
os.system('echo 1  > /sys/class/gpio/gpio0/value')
gpio1 = open("/sys/class/gpio/gpio1/value", "r")


#===== bmp180 i2c open and read calibration data ====
bmp180_i2c = open("/dev/i2c-1",  "r+b", buffering=0)
# bmp180 i2c slave address 0x77
I2C_SLAVE_ADDR = 0x77  
# ioctl function number: force set i2c slave address
I2C_SLAVE_FORCE = 0x0706  
rt = ioctl(bmp180_i2c, I2C_SLAVE_FORCE, I2C_SLAVE_ADDR) 

#read 22 bytes starting from register 0xAA
rt = bmp180_i2c.write(bytes([0xaa]))  
dat = bmp180_i2c.read(22)
# Convert calibration byte data to word values
AC1 = get_int16(dat, 0)
AC2 = get_int16(dat, 2)
AC3 = get_int16(dat, 4)
AC4 = get_uint16(dat, 6)
AC5 = get_uint16(dat, 8)
AC6 = get_uint16(dat, 10)
B1  = get_int16(dat, 12)
B2  = get_int16(dat, 14)
MB  = get_int16(dat, 16)
MC  = get_int16(dat, 18)
MD  = get_int16(dat, 20)

touch_state = 0

#===== Main Loop ======
while True:
	#======  touch sensor action
	gpio1.seek(0)  	# rewind for read
	if gpio1.read() == '1\n':
		touch = 1
	else:
		touch = 0
		
	if touch == 1 and touch_state == 0:
		# say Good on LED display
		os.system('echo \"Good\" > /tmp/led') 
	elif touch == 0 and touch_state == 1:
		# default LED display
		os.system('echo \"&&\" > /tmp/led')	 

	touch_state = touch

	#====== BMP180 i2c 
	# write 0x2E to reg. 0xF4, start sampling UT
	rt = bmp180_i2c.write(bytes([0xf4, 0x2e])) 
	time.sleep(.0045)
	# read 2 bytes starting from reg. 0xF6
	rt = bmp180_i2c.write(bytes([0xf6])) 			
	dat = bmp180_i2c.read(2)
	UT = get_uint16(dat, 0) 
	
	# write 0x34+(OVERSAMPLE<<6) to reg. 0xF4, start sampling UP
	rt = bmp180_i2c.write(bytes([0xf4, 0x34 + (3<<6)])) 
	time.sleep(.0225)
	# read 3 bytes starting from reg. 0xF6
	rt = bmp180_i2c.write(bytes([0xf6])) 			
	dat = bmp180_i2c.read(3)
	UP = (dat[0]<<16) + get_uint16(dat, 1)

	temperature, pressure =  refine_UT_UP(UT, UP)
	
	# The pressure change per meter of sensor altitude should be approximately 0.12 mbar

	print("touch =", touch_state, "   Temp =", temperature, "C   Pressure =", pressure, "mbar")

	time.sleep(0.2)
	
	
	
	
				
			

這是一個 Python3 程式,用於讀取和處理 BMP180 溫度和氣壓感測器的數據,以及監控觸摸感測器的狀態。以下是該程式碼的解釋:

  1. 導入所需的庫:fcntl, os, time

  2. 定義兩個函數 get_uint16() get_int16(),它們將從二進制數據中提取無符號和有符號 16 位值。

  3. 定義函數 refine_UT_UP(),該函數根據 BMP180 數據表對原始樣本進行修正,並返回溫度(攝氏度)和壓力(mbar)值。

  4. 初始化 GPIO 並設置觸摸感測器的電源和輸出。

  5. 開啟 BMP180 I2C 連接,並讀取校準數據。

  6. 初始化觸摸感測器狀態。

  7. 進入主循環,進行以下操作: a. 讀取觸摸感測器的狀態,並根據狀態改變 LED 顯示。 b. 讀取 BMP180 的溫度(UT)和壓力(UP)數據。 c. 使用 refine_UT_UP() 函數獲得精確的溫度和壓力值。 d. 打印觸摸感測器狀態、溫度和壓力值。 e. 暫停 0.2 秒後繼續循環。

該程式運行時將不斷監控觸摸感測器的狀態,並顯示 BMP180 溫度和氣壓感測器的數據。

執行程式:

$ sudo testMPIO10.py

用手指按觸 “Touch here” 區域,螢幕顯示會由 touch = 0 變成 touch =1 。

請注意,示範程式顯示的溫度和氣壓值未經校正。如何校正請參考:

BMP180 Digital Pressure Sensor Data Sheet

停止程式執行按 Ctrl+c。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *