天天看點

樹莓派與霍爾傳感器的那些事兒一、簡介二、硬體準備三、軟體準備四、資料準備

文章目錄

  • 一、簡介
  • 二、硬體準備
    • 1、元器件清單
    • 2、接線說明
  • 三、軟體準備
    • 1、打開I2C通信
    • 2、樹莓派采集不發送至PC
    • 3、将采集到的資料發送至PC,并存入資料庫
  • 四、資料準備

一、簡介

  本文是對霍爾傳感器使用的一次記錄,内容上将會介紹如何通過霍爾傳感器檢測到磁場實作雙色燈,以及如何通過socket将其采集到的資料存入PC端的資料庫。

樹莓派與霍爾傳感器的那些事兒一、簡介二、硬體準備三、軟體準備四、資料準備

二、硬體準備

1、元器件清單

名稱 數量
Raspberry Pi 4B 1
GPIO擴充闆套件 1
PCF8591模數轉換器 1
霍爾傳感器 1
雙色Led 1
面包闆 1

2、接線說明

樹莓派與霍爾傳感器的那些事兒一、簡介二、硬體準備三、軟體準備四、資料準備
GPIO擴充闆 PCF8591
SDA SDA
SCL SCL
5V VCC
GND GND
GPIO擴充闆 PCF8591 霍爾傳感器
* AIN0 A0
G17 * D0
5V VCC VCC
GND GND GND
GPIO擴充闆 雙色Led
G18 R
G27 G
GND GND

三、軟體準備

  因為pcf8591是通過I2C與樹莓派進行通信的,是以我們第一步首先就是打開I2C。

1、打開I2C通信

樹莓派與霍爾傳感器的那些事兒一、簡介二、硬體準備三、軟體準備四、資料準備

2、樹莓派采集不發送至PC

  該代碼實作的是當霍爾傳感器檢測到磁場時,亮紅燈;沒有檢測到磁場時,亮綠燈。模拟信号輸出表示檢測到磁場時,列印檢測到磁場的資訊“Detected magnetic materials”。同時數字信号輸出表示檢測到磁場時,列印“Detected Magnet”。

  • PCF8591.py:
#!/usr/bin/env python
#------------------------------------------------------
#
#		您可以使用下面語句将此腳本導入另一個腳本:
#	        “import PCF8591 as ADC”                
#	
#	ADC.Setup(Address)  # 查詢PCF8591的位址:“sudo i2cdetect -y 1”
# i2cdetect  is  a  userspace  program to scan an I2C bus for devices.
# It outputs a table with the list of detected devices on the specified bus.
#	ADC.read(channal)	# Channal範圍從0到3 
#	ADC.write(Value)	# Value範圍從0到255
#
#------------------------------------------------------
#SMBus (System Management Bus,系統管理總線) 
import smbus   #在程式中導入“smbus”子產品
import time

# for RPI version 1, use "bus = smbus.SMBus(1)"
# 0 代表 /dev/i2c-0, 1 代表 /dev/i2c-1 ,具體看使用的樹莓派那個I2C來決定
bus = smbus.SMBus(1)         #建立一個smbus執行個體

#在樹莓派上查詢PCF8591的位址:“sudo i2cdetect -y 1”
def setup(Addr):
	global address
	address = Addr

def read(chn): #channel
	if chn == 0:
		bus.write_byte(address,0x40)   #發送一個控制位元組到裝置
	if chn == 1:
		bus.write_byte(address,0x41)
	if chn == 2:
		bus.write_byte(address,0x42)
	if chn == 3:
		bus.write_byte(address,0x43)
	bus.read_byte(address)         # 從裝置讀取單個位元組,而不指定裝置寄存器。
	return bus.read_byte(address)  #傳回某通道輸入的模拟值A/D轉換後的數字值

def write(val):
	temp = val  # 将字元串值移動到temp
	temp = int(temp) # 将字元串改為整數類型
	# print temp to see on terminal else comment out
	bus.write_byte_data(address, 0x40, temp) 
    #寫入位元組資料,将數字值轉化成模拟值從AOUT輸出

if __name__ == "__main__":
	setup(0x48) 
 #在樹莓派終端上使用指令“sudo i2cdetect -y 1”,查詢出PCF8591的位址為0x48
	while True:
		print '電位計   AIN0 = ', read(0)   #電位計模拟信号轉化的數字值
		print '光敏電阻 AIN1 = ', read(1)   #光敏電阻模拟信号轉化的數字
        print '熱敏電阻 AIN2 = ', read(2)   #熱敏電阻模拟信号轉化的數字值
		tmp = read(0)
		tmp = tmp*(255-125)/255+125 
# 125以下LED不會亮,是以将“0-255”轉換為“125-255”,調節亮度時燈不會熄滅
		write(tmp)
		time.sleep(2)


           
  • Hall.py
#/usr/bin/env python
import RPi.GPIO as GPIO
import PCF8591 as ADC
import time

HallPin = 11
Gpin   = 13
Rpin   = 12

def setup():
	ADC.setup(0x48)
	GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical location
	GPIO.setup(Gpin, GPIO.OUT)     # Set Green Led Pin mode to output
	GPIO.setup(Rpin, GPIO.OUT)     # Set Red Led Pin mode to output
	GPIO.setup(HallPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)    # Set BtnPin's mode is input, and pull up to high level(3.3V)
	GPIO.add_event_detect(HallPin, GPIO.BOTH, callback=detect, bouncetime=200)
#    檢測到磁場時,數字輸出低電平,即GPIO.input(HallPin)==0 
#沒有檢測到磁場時,數字輸出高電平,即GPIO.input(HallPin)==1

def Led(x):
	if x == 0:    #檢測到磁場時,亮紅燈
		GPIO.output(Rpin, 1)
		GPIO.output(Gpin, 0)
	if x == 1:    #沒有檢測到磁場時,亮綠燈
		GPIO.output(Rpin, 0)
		GPIO.output(Gpin, 1)

def Print1(x):
	if x == 0:    #檢測到磁場時,數字輸出低電平,x==0
		print '    ***********************************'
		print '    *   Detected magnetic materials   *'
		print '    ***********************************'

def detect(chn):  
	Led(GPIO.input(HallPin))
	Print1(GPIO.input(HallPin))


def Print2(x):
	if x == 1:
		print ''
		print '*************'
		print '* No Magnet *'
		print '*************'
		print ''
	if x == 0:
		print ''
		print '*************'
		print '* Detected Magnet *'
		print '*************'
		print ''


def loop():
	status = 0
	while True:
		res = ADC.read(0)      #模拟輸出信号A/D轉換後的數字信号值
		print 'Current intensity of magnetic field : ', res
		if res  < 10:  #這裡的數字輸出ADC.read(0)隻有兩個值,0或255
			tmp = 0    #ADC.read(0)為255時沒有檢測到磁場
		               #ADC.read(0)為 0 時檢測到磁場,但有少量誤差的其它值,比如1或254等值偶爾出現
		if res > 200:  
			tmp = 1
		if tmp != status:
			Print2(tmp)
			status = tmp
		time.sleep(0.5)

def destroy():
	GPIO.output(Gpin, GPIO.LOW)       # Green led off
	GPIO.output(Rpin, GPIO.LOW)       # Red led off
	GPIO.cleanup()                     # Release resource

if __name__ == '__main__':
	setup()
	try:
		loop()
	except KeyboardInterrupt:  # When 'Ctrl+C' is pressed, the child program destroy() will be  executed.
		destroy()

           
樹莓派與霍爾傳感器的那些事兒一、簡介二、硬體準備三、軟體準備四、資料準備

3、将采集到的資料發送至PC,并存入資料庫

  PCF8591.py代碼不變,在Hall.py添加socket通信。

  • Hall.py
#/usr/bin/env python
import RPi.GPIO as GPIO
import PCF8591 as ADC
import socket
import time

HallPin = 11
Gpin   = 13
Rpin   = 12

print("用戶端開啟")
#套接字接口
mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

def setup():
	ADC.setup(0x48)
	GPIO.setmode(GPIO.BOARD)       # Numbers GPIOs by physical location
	GPIO.setup(Gpin, GPIO.OUT)     # Set Green Led Pin mode to output
	GPIO.setup(Rpin, GPIO.OUT)     # Set Red Led Pin mode to output
	GPIO.setup(HallPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)    # Set BtnPin's mode is input, and pull up to high level(3.3V)
	GPIO.add_event_detect(HallPin, GPIO.BOTH, callback=detect, bouncetime=200)
#    檢測到磁場時,數字輸出低電平,即GPIO.input(HallPin)==0 
#沒有檢測到磁場時,數字輸出高電平,即GPIO.input(HallPin)==1

def Led(x):
	if x == 0:    #檢測到磁場時,亮紅燈
		GPIO.output(Rpin, 1)
		GPIO.output(Gpin, 0)
	if x == 1:    #沒有檢測到磁場時,亮綠燈
		GPIO.output(Rpin, 0)
		GPIO.output(Gpin, 1)

def Print1(x):
	if x == 0:    #檢測到磁場時,數字輸出低電平,x==0
		print ('    ***********************************')
		print ('    *   Detected magnetic materials   *')
		print ('    ***********************************')

def detect(chn):  
	Led(GPIO.input(HallPin))
	Print1(GPIO.input(HallPin))


def Print2(x):
	if x == 1:
		print ('')
		print ('*************')
		print ('* No Magnet *')
		print ('*************')
		print ('')
	if x == 0:
		print ('')
		print ('*************')
		print ('* Detected Magnet *')
		print ('*************')
		print ('')

def connect():
	#設定ip和端口
	host = 'XXX.XXX.XXX.XXX' ## ip位址
	port = 2222
	try:
		mySocket.connect((host, port)) ##連接配接到伺服器
		print("連接配接到伺服器")
	except :                           ##連接配接不成功,運作最初的ip
		print ('連接配接不成功')

def loop():
	status = 0
	while True:
		res = ADC.read(0)      #模拟輸出信号A/D轉換後的數字信号值
		print ('Current intensity of magnetic field : ', res)
		if res  < 10:  #這裡的數字輸出ADC.read(0)隻有兩個值,0或255
			tmp = 0    #ADC.read(0)為255時沒有檢測到磁場
		               #ADC.read(0)為 0 時檢測到磁場,但有少量誤差的其它值,比如1或254等值偶爾出現
		if res > 200:  
			tmp = 1
		if tmp != status:
			Print2(tmp)
			status = tmp
		#編碼發送
		msg = str(res)
		mySocket.send(msg.encode("utf-8"))
		print("發送完成")
		time.sleep(10)
		if msg == "over":
			mySocket.close()
			print("通信結束\n")
			exit() 

def destroy():
	GPIO.output(Gpin, GPIO.LOW)       # Green led off
	GPIO.output(Rpin, GPIO.LOW)       # Red led off
	GPIO.cleanup()                     # Release resource
	print("程式結束\n")

if __name__ == '__main__':
	setup()
	connect()
	try:
		loop()
	except KeyboardInterrupt:  # When 'Ctrl+C' is pressed, the child program destroy() will be  executed.
		destroy()

           
  • PC.py
import pymysql  # 導入 pymysql
import socket
import time

print("服務端開啟")
# 套接字接口
mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 設定IP和端口
host = 'xxx.xxx.xxx.xxx'
port = 2222
# bind綁定該端口
mySocket.bind((host, port))
mySocket.listen(10)

# 打開資料庫連接配接
db = pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    passwd='123456',
    db='xxdb',
    charset='utf8'
)
print("資料庫開啟")
# 使用 cursor() 方法建立一個遊标對象 cursor
cursor = db.cursor()
sqltime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))

while True:
    # 接收用戶端連接配接
    print("等待連接配接....")
    client, address = mySocket.accept()
    print("新連接配接")
    print("IP is %s" % address[0])
    print("port is %d\n" % address[1])
    while True:
        # 讀取消息
        msg = client.recv(1024)
        # 把接收到的資料進行解碼
        print(msg.decode("utf-8"))
        print("讀取完成")

        # SQL 插入語句
        # sql = "INSERT INTO MAGNETISM(MTIME , MFLAG) VALUES ('%s','%s')" % (sqltime, msg.decode("utf-8"))
        sql = "INSERT INTO MAGNETISM(MFLAG) VALUES ('%s')" % (msg.decode("utf-8"))

        try:
            # 執行sql語句
            cursor.execute(sql)
            # 送出到資料庫執行
            db.commit()
        except:
            # 如果發生錯誤則復原
            db.rollback()

        time.sleep(10)

        if msg == "over":
            client.close()
            mySocket.close()
            # 關閉資料庫連接配接
            db.close()
            print("程式結束\n")
            exit()

           
樹莓派與霍爾傳感器的那些事兒一、簡介二、硬體準備三、軟體準備四、資料準備

四、資料準備

  為了快速記錄,是以就沒有詳細介紹各個傳感器的使用說明,想要進一步了解學習的朋友可以自行百度搜尋,或者檢視下方的相關文章:

  • 樹莓派與PCF8591模數轉換器的那些事兒
  • 樹莓派與雙色Led子產品的那些事兒
  • 樹莓派使用Socket發送資料至PC并存入資料庫
  • STC12C2052與LCD1602液晶顯示屏的那些事兒(2)

繼續閱讀