前一篇通过MicroPython实现DFRobot盖革模块与wifi连接,本篇通过MicroPython实现DFRobot盖革模块与蓝牙连接。使用ESP32自带的蓝牙模块,与手机蓝牙通讯,读取盖革计数器的值。
源代码如下
''' DFrobot 盖革计数器实验 接线说明:DFrobot Geiger模块-->ESP32 IO (D)-->(14) (+)-->(5V) (-)-->(GND) OLED(IIC)液晶模块-->ESP32 IO GND-->(GND) VCC-->(5V) SCL-->(18) SDA-->(23) ''' #导入Pin模块 from machine import Pin from machine import Timer import time from machine import SoftI2C from ssd1306 import SSD1306_I2C #I2C的oled选该方法 from time import sleep_ms import bluetooth BLE_MSG = "" #创建软件I2C对象 i2c = SoftI2C(sda=Pin(23), scl=Pin(18)) #创建OLED对象,OLED分辨率、I2C接口 oled = SSD1306_I2C(128, 64, i2c) #Geiger in Geiger_In=Pin(14,Pin.IN,Pin.PULL_UP) class ESP32_BLE(): def __init__(self, name): self.led = Pin(15, Pin.OUT) self.timer1 = Timer(0) self.name = name self.ble = bluetooth.BLE() self.ble.active(True) self.ble.config(gap_name=name) self.disconnected() self.ble.irq(self.ble_irq) self.register() self.ble.gatts_write(self.rx, bytes(100)) #修改一次最大接收字节数100 self.advertiser() def connected(self): self.led.value(1) self.timer1.deinit() def disconnected(self): self.timer1.init(period=100, mode=Timer.PERIODIC, callback=lambda t: self.led.value(not self.led.value())) def ble_irq(self, event, data): global BLE_MSG if event == 1: #_IRQ_CENTRAL_CONNECT 手机链接了此设备 self.connected() elif event == 2: #_IRQ_CENTRAL_DISCONNECT 手机断开此设备 self.advertiser() self.disconnected() elif event == 3: #_IRQ_GATTS_WRITE 手机发送了数据 buffer = self.ble.gatts_read(self.rx) BLE_MSG = buffer.decode('UTF-8').strip() def register(self): service_uuid = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E' reader_uuid = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E' sender_uuid = '6E400003-B5A3-F393-E0A9-E50E24DCCA9E' services = ( ( bluetooth.UUID(service_uuid), ( (bluetooth.UUID(sender_uuid), bluetooth.FLAG_NOTIFY), (bluetooth.UUID(reader_uuid), bluetooth.FLAG_WRITE), ) ), ) ((self.tx, self.rx,), ) = self.ble.gatts_register_services(services) def send(self, data): self.ble.gatts_notify(0, self.tx, data + '\n') def advertiser(self): name = bytes(self.name, 'UTF-8') adv_data = bytearray('\x02\x01\x02', 'UTF-8') + bytearray((len(name) + 1, 0x09)) + name self.ble.gap_advertise(100, adv_data) print(adv_data) print("\r\n") #Geiger计数器外部中断函数 def Geiger_In_irq(Geiger_In): global numPulse numPulse = numPulse + 1 ble.send(str3) #程序入口 if __name__=="__main__": global numPulse BUFFER_SIZE = 20 rows, cols = 2, BUFFER_SIZE mem_data = [[0 for _ in range(cols)] for _ in range(rows)] numPulse = 0 pos = 0 oled.fill(0) #清空屏幕 oled.text("Geiger Counter",0,0,1) #显示字符串 oled.show() #执行显示 ble = ESP32_BLE("Geiger_Counter") Geiger_In.irq(Geiger_In_irq,Pin.IRQ_FALLING) #配置外部中断,下降沿触发 while True: time.sleep_ms(3000) mem_data[0][pos] = time.ticks_ms() mem_data[1][pos] = numPulse numPulse = 0 cpm=0 pos_old = pos pos = (pos+1)%BUFFER_SIZE numAll = 0 uSvh = 0 time_now = mem_data[0][pos_old] for i in range(0, BUFFER_SIZE - 1): if mem_data[0][pos_old] != 0: numAll = numAll + mem_data[1][pos_old] time_old = mem_data[0][pos_old] if pos_old == 0: pos_old = BUFFER_SIZE - 1 else: pos_old = pos_old - 1 if time_now-time_old > 0: cpm = numAll*1000*60/(time_now-time_old) uSvh = cpm/151 str1 = "{:.0f}".format(cpm) #CPM转字符串 str2 = "{:.3f}".format(uSvh) #uSv/h转字符串 oled.fill(0) #清空屏幕 oled.text("Geiger Counter",0,0,1) #显示字符串 oled.text("CPM",80,10,2) #显示CPM单位 oled.text("uSv/h",80,20,2) #显示uSv/h单位 oled.text(str1,0,10,2) #显示CPM数据 oled.text(str2,0,20,2) #显示uSv/h数据 oled.show() #执行显示 str3 = str1+' CPM ' + str2+' uSv/h' print(str3)
手机上下载BLE调试助手APP,
程序下载运行后,打开BLE调试助手APP后,连接到Geiger_Counter蓝牙,
选择Unknown Service,点击接受数据,手机蓝牙收到盖革计数器的测量值。