DFrobot盖革计数器官方提供的代码是基于Arduino的,程序的架构是采用外部中断进行计数,然后主循环中每3s执行一次刷新数据,取3次数据进行计算CPM值,然后将CPM转换成uSv/h或nSv/h并在OLED液晶上显示出来。
尝试将代码用MicroPython改写,并优化计数,采用每3s存储一次数据,缓存20次共1分钟数据来计算CPM。未达到1分钟时用以缓存的时间来计算CPM,缓存时间越长,数据变化越稳定。
OLED及盖革计数器接线与前面Arduino代码一致。
''' 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 import time from machine import SoftI2C from ssd1306 import SSD1306_I2C #I2C的oled选该方法 #创建软件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) #Geiger计数器外部中断函数 def Geiger_In_irq(Geiger_In): global numPulse numPulse = numPulse + 1 #程序入口 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() #执行显示 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 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) str1 = "{:.0f}".format(cpm) #CPM转字符串 str2 = "{:.3f}".format(cpm/151)#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() #执行显示