700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 树莓派-Raspberry Pi Pico RP2040 使用大全(硬件接口功能 传感器模块等)

树莓派-Raspberry Pi Pico RP2040 使用大全(硬件接口功能 传感器模块等)

时间:2020-02-23 08:19:30

相关推荐

树莓派-Raspberry Pi Pico RP2040 使用大全(硬件接口功能 传感器模块等)

树莓派-RP2040

主板实物图主板引脚图Thonny开发IDE工具查看帮助信息GPIO 输出GPIO 输入GPIO 中断ADC(模数转换)PWM(脉宽调制)WDT看门狗RTC实时时钟I2C总线接口UART串口通信Timer定时器_thread多线程File文件操作超声波测距模块舵机控制WS2812 RGB灯SSD1306 OLED屏AHT10温湿度传感器BH1750光照度传感器BMP280 气压强传感器HMC5883L地磁传感器MCP4725数模转换GNSS导航模块无线串口模块旋转编码器

主板实物图

/

主板引脚图

Thonny开发IDE工具

配置解释器:Raspberry Pi Pico

工具=》选项=》解释器(选择Raspberry Pi Pico)

查看帮助信息

help(‘modules’) :查看可以通过import导入的模名

help(模块名):查看指定模块下的类、函数、常量:

help(模块名.类):查看指定模块类包含的函数和常量

GPIO 输出

GPIO输出模式:machine.Pin.OUT

GPIO输入模式:machine.Pin.IN

import machineimport utimeled = machine.Pin(25, machine.Pin.OUT)print('gpio output demo...')while True:led.value(0)utime.sleep(1)led.value(1)utime.sleep(0.5)# 其它GPIO相关操作接口#led.low()#led.high()#led.toggle()#led.on()#led.off()#led.value(0)#led.value(1)#state=led.value()#print(state)

GPIO 输入

上拉:machine.Pin.PULL_UP

下拉:machine.Pin.PULL_DOWN

import machineimport utimekey = machine.Pin(23, machine.Pin.IN, machine.Pin.PULL_UP)led = machine.Pin(25, machine.Pin.OUT)print('gpio input demo...')while True:if key.value() == 1:led.value(1)else:led.value(0)utime.sleep_ms(100)

GPIO 中断

irq(trigger, handler), trigger中断触发方式,handler中断处理函数

下降沿:trigger=machine.Pin.IRQ_FALLING

上升沿:trigger=machine.Pin.IRQ_RISING

import machineimport utimekey = machine.Pin(23, machine.Pin.IN, machine.Pin.PULL_DOWN)led = machine.Pin(25, machine.Pin.OUT)print('gpio irq demo...')def irq_handler(pin):print(pin)led.toggle()key.irq(trigger=machine.Pin.IRQ_FALLING, handler=irq_handler)while True:utime.sleep(1)print("main loop...")

ADC(模数转换)

外部ADC模拟电压表

import machineimport utimeimport mathadc0 = machine.ADC(26)adc1 = machine.ADC(27)adc2 = machine.ADC(28)adcvalue0 = 0adcvalue1 = 0adcvalue2 = 0factor = 3.3/(65536)while True:adcvalue0 = adc0.read_u16()*factoradcvalue1 = adc1.read_u16()*factoradcvalue2 = adc2.read_u16()*factorprint(adcvalue0, adcvalue1, adcvalue2)utime.sleep_ms(500)

内部ADC测量温度

import machineimport utimesensor_temp = machine.ADC(4)#sensor_temp = machine.ADC(machine.ADC.CORE_TEMP)conversion_factor = 3.3/(65535)while True:reading = sensor_temp.read_u16()*conversion_factortemperature = 27 - (reading - 0.706)/0.001721print(temperature,"C")utime.sleep(1)

PWM(脉宽调制)

PWM相关接口:

pwm0 = machine.PWM(machine.Pin(0))

pwm0.freq() # 返回当前PWM设置频率

pwm0.freq(2000) # 设置PWM频率

pwm0.duty_u16(15000) # 设置占空比(0~65535)

pwm0.duty_ns(10) # 设置占空比时间ns

import machineimport utimeimport urandomled_r = machine.PWM(machine.Pin(4))led_g = machine.PWM(machine.Pin(3))led_b = machine.PWM(machine.Pin(2))led_r.freq(1000)led_g.freq(1000)led_b.freq(1000)print(led_r.freq())print(led_g.freq())print(led_b.freq())while True:led_r.duty_u16(urandom.randrange(1, 65535, 10))led_g.duty_u16(urandom.randrange(1, 65535, 20))led_b.duty_u16(urandom.randrange(1, 65535, 30)) utime.sleep_ms(100)

WDT看门狗

import machineimport utime# enable the WDT with a timeout of 5s (1s is the minimum)wdt = machine.WDT(timeout=5000)print("WDT Demo...")while True:wdt.feed()utime.sleep(3)

RTC实时时钟

rtc = machine.RTC()

rtc.datetime()返回一个元组数据:

(年,月,日,星期,时,分,秒,0)

(, 10, 14, 4, 14, 41, 57, 0)

import machineimport utimertc = machine.RTC()# 设置RTC日期时间等参数# rtc.datetime((, 1, 21, 2, 10, 32, 36, 0))while True:print(rtc.datetime())utime.sleep(1)

I2C总线接口

import machineimport utimesda = machine.Pin(16)scl = machine.Pin(17)i2c = machine.I2C(0, sda=sda, scl=scl, freq=200000)print(i2c.scan())i2c.writeto(35, '0x01') # power oni2c.writeto(35, '0x10') # H-resolution modei2c.writeto(35, '0x20')utime.sleep(0.2)while True:i2c.writeto(35, '\x01')val = i2c.readfrom(35, 2, True)print(val)utime.sleep(1)

UART串口通信

串口通信相关接口:

rxbuf=bytes()

rxData=bytes()

txData=bytes()

tx = machine.Pin(16)

rx = machine.Pin(17)

uart = machine.UART(0, baudrate=9600, bits=8, parity=None, stop=1, tx=tx, rx=rx)

uart.any() # True:有可以读取的数据,False:没有可读取的数据

rxData += uart.read(1) # 读取一个字节数据

rxData = uart.readline() # 读取一行数据

uart.readinto(rxbuf, 10) # 读取10个字节数据到rxbuf

uart.sendbreak() # 中断串口数据发送

txData = b’hello world!’

uart.write(txData) # 串口写入数据

uart.txdone() # 串口数据 True:发送完成, False:还有数据未发送成功

uart.flush() # 串口刷新数据

uart.deinit() # 串口反初始化

uart.CTS

uart.RTS

uart.INV_RX

uart.INV_TX

from machine import Pin,UARTimport utimeuart0 = UART(0, baudrate=9600, bits=8, parity=None, stop=1, tx=Pin(16), rx=Pin(17), )#uart0.deinit()txData = b'hello world\n\r'rxData = bytes()uart0.write(txData)#buf=bytes()#uart0.readinto(buf, 10)#uart0.sendbreak()print(type(txData))print(type(rxData))while True:while uart0.any() > 0:#rxData += uart0.read(1)rxData = uart0.readline()print(rxData.decode('utf-8'))if not uart0.txdone():uart0.flush()uart0.write(rxData)utime.sleep(0.2)

Timer定时器

初始化并启动定时器:

Timer.init(*, mode=Timer.PERIODIC, period=- 1, callback=None)

mode: 定时器模式(Timer.ONE_SHOT , Timer.PERIODIC)

period:定时器周期

callback:定时器回调函数Timer.deinit()

启动一个定时器:

from machine import Pin, Timerled = Pin(25, Pin.OUT)tim = Timer()def tick(timer):global ledled.toggle()tim.init(freq=2.5, mode=Timer.PERIODIC, callback=tick)

启动多个定时器:

import utimefrom machine import Timerdef tim_callback1(timer):"""Timer Callback Function."""print("Timer 1...")passdef tim_callback2(timer):print("Timer 2...")passtim1 = Timer()tim1.init(mode=Timer.PERIODIC, period=1000, callback=tim_callback1)#tim.init(mode=Timer.ONE_SHOT, period=100, callback=tim_callback)tim2 = Timer()tim2.init(mode=Timer.PERIODIC, period=2000, callback=tim_callback2)print("timer demo ...")#tim1.deinit()#tim2.deinit()while True:utime.sleep(1)

_thread多线程

RP2040 CPU是双核默认代码运行在core0通过

_thread.start_new_thread启动的线程代码运行在core1上,注:start_new_thread只能调用一次,多次调用会提示core 1已使用;

import time, _threaddef th1_task(n, delay):while True:print("thread 1 running...",n)time.sleep(delay)pass_thread.start_new_thread(th1_task,(10, 1))print("thread demo...")while True:print("main loop...")time.sleep(10)

使用线程互斥锁:

import utimeimport _thread# 线程互斥锁lock = _thread.allocate_lock()# 内核1 运行任务def core1_task():"""Core1 task"""while True:#lock.acquire()print("core1 task")utime.sleep(0.5)#lock.release()pass_thread.start_new_thread(core1_task, ())while True:#lock.acquire()print("core0 task")utime.sleep(0.5)#lock.release()

File文件操作

file = open("test.txt", "w")file.write("Hello, File!")file.write(str('13245')+"\n")file.flush()file.close()file = open("test.txt")print(file.read())file.close()

超声波测距模块

import machineimport utimetrig = machine.Pin(16, machine.Pin.OUT)echo = machine.Pin(17, machine.Pin.IN)def get_distance(trig, echo):# 10us hightrig.low()utime.sleep_us(2)trig.high()utime.sleep_us(10)trig.low()while (echo.value() == 0):start = utime.ticks_us()while echo.value() == 1:end = utime.ticks_us()d = (end - start) * 0.034 / 2return dtrig.low()while True:distance = get_distance(trig, echo)print("距离:{:.2f} cm".format(distance))utime.sleep(0.1)

舵机控制

棕色:GND(电源负极)

红色:VCC(电源正极)

橙色:PWM(控制信号)

控制时序0~180角度

控制时序-90 ~ 0 ~ 90角度

from machine import Pin, PWMimport utimepwm0 = PWM(Pin(0))pwm0.freq(50)updown = True# 舵机控制信号周期T=20ms, f=1/T = 1/20ms = 50Hz# 脉冲宽度:0.5ms ---> 0度 PWM_DUTY=65535*(0.5ms/20ms)=1638# 脉冲宽度:1.5ms ---> 90度 PWM_DUTY=65535*(1.5ms/20ms)=4915# 脉冲宽度:2.5ms ---> 180度 PWM_DUTY=65535*(2.5ms/20ms)=8192vmin, vmax = (65535*(0.5/20)), (65535*(2.5/20))def get_angle(angle): duty = int(vmin + (((vmax-vmin)/180) *angle) )return dutyangle = 0pwm0.duty_u16(get_angle(angle))utime.sleep(2)while True:angle = 0pwm0.duty_u16(get_angle(angle))utime.sleep(1)angle = 45pwm0.duty_u16(get_angle(angle))utime.sleep(1)angle = 90pwm0.duty_u16(get_angle(angle))utime.sleep(1)angle = 135pwm0.duty_u16(get_angle(angle))utime.sleep(1)angle = 180pwm0.duty_u16(get_angle(angle))utime.sleep(1)

WS2812 RGB灯

将该文件通过Thonny保存到Raspberry PI Pico 的:“/lib/ws2812b.py”目录下

文件已保存到Raspberry Pi Pico内,然后就可以在代码使用import ws2812b

ws2812b(num, sm, pin)

num代表ws2812的数量

sm是内核,目前需要设置为0

pin是使用的引脚set_pixel(n, r, g, b)

n是第几个ws2812

r, b, b是红绿蓝颜色show(),刷新显示fill((r, g, b)),填充所有ws2812set_pixel_line(n1,n2,r,g,b),设置从n1到n2颜色set_pixel_line_gradient(n1,n2,r1,g1,b1,r2,g2,b2),设置从n1到n2渐变色

ws2812b.py

import array, timefrom machine import Pinimport rp2@rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24)def ws2812():T1 = 2T2 = 5T3 = 3wrap_target()label("bitloop")out(x, 1).side(0) [T3 - 1]jmp(not_x, "do_zero") .side(1) [T1 - 1]jmp("bitloop").side(1) [T2 - 1]label("do_zero")nop() .side(0) [T2 - 1]wrap()#delay here is the reset time. You need a pause to reset the LED strip back to the initial LED#however, if you have quite a bit of processing to do before the next time you update the strip#you could put in delay=0 (or a lower delay)class ws2812b:def __init__(self, num_leds, state_machine, pin, delay=0.001):self.pixels = array.array("I", [0 for _ in range(num_leds)])self.sm = rp2.StateMachine(state_machine, ws2812, freq=8000000, sideset_base=Pin(pin))self.sm.active(1)self.num_leds = num_ledsself.delay = delayself.brightnessvalue = 255# Set the overal value to adjust brightness when updating ledsdef brightness(self, brightness = None):if brightness == None:return self.brightnessvalueelse:if (brightness < 1):brightness = 1if (brightness > 255):brightness = 255self.brightnessvalue = brightness# Create a gradient with two RGB colors between "pixel1" and "pixel2" (inclusive)def set_pixel_line_gradient(self, pixel1, pixel2, left_red, left_green, left_blue, right_red, right_green, right_blue):if pixel2 - pixel1 == 0: returnright_pixel = max(pixel1, pixel2)left_pixel = min(pixel1, pixel2)for i in range(right_pixel - left_pixel + 1):fraction = i / (right_pixel - left_pixel)red = round((right_red - left_red) * fraction + left_red)green = round((right_green - left_green) * fraction + left_green)blue = round((right_blue - left_blue) * fraction + left_blue)self.set_pixel(left_pixel + i, red, green, blue)# Set an array of pixels starting from "pixel1" to "pixel2" to the desired color.def set_pixel_line(self, pixel1, pixel2, red, green, blue):for i in range(pixel1, pixel2+1):self.set_pixel(i, red, green, blue)def set_pixel(self, pixel_num, red, green, blue):# Adjust color values with brightnesslevelblue = round(blue * (self.brightness() / 255))red = round(red * (self.brightness() / 255))green = round(green * (self.brightness() / 255))self.pixels[pixel_num] = blue | red << 8 | green << 16# rotate x pixels to the leftdef rotate_left(self, num_of_pixels):if num_of_pixels == None:num_of_pixels = 1self.pixels = self.pixels[num_of_pixels:] + self.pixels[:num_of_pixels]# rotate x pixels to the rightdef rotate_right(self, num_of_pixels):if num_of_pixels == None:num_of_pixels = 1num_of_pixels = -1 * num_of_pixelsself.pixels = self.pixels[num_of_pixels:] + self.pixels[:num_of_pixels]def show(self):for i in range(self.num_leds):self.sm.put(self.pixels[i],8)time.sleep(self.delay)def fill(self, red, green, blue):for i in range(self.num_leds):self.set_pixel(i, red, green, blue)time.sleep(self.delay)

Demo演示代码

from machine import Pinimport utimeimport ws2812bprint(str(ws2812b))led = ws2812b.ws2812b(9, 0, 6)# 参数1:LED灯个数, 参数2:固定填0,参数3:Pin端口号led.fill(255, 0, 0)led.set_pixel(0, 255, 0, 0) # 设置第一个像素,为红色#led.set_pixel_line(1, 3, 255, 255, 0)led.set_pixel_line_gradient(0, 8, 255, 0, 0, 0, 255, 0)# 设置渐变led.show()while True:#led.rotate_left(1)led.rotate_right(1)led.show()utime.sleep(1)

SSD1306 OLED屏

ssd1306.py保存到pico的/lib目录

# MicroPython SSD1306 OLED driver, I2C and SPI interfacesfrom micropython import constimport framebuf# register definitionsSET_CONTRAST = const(0x81)SET_ENTIRE_ON = const(0xA4)SET_NORM_INV = const(0xA6)SET_DISP = const(0xAE)SET_MEM_ADDR = const(0x20)SET_COL_ADDR = const(0x21)SET_PAGE_ADDR = const(0x22)SET_DISP_START_LINE = const(0x40)SET_SEG_REMAP = const(0xA0)SET_MUX_RATIO = const(0xA8)SET_COM_OUT_DIR = const(0xC0)SET_DISP_OFFSET = const(0xD3)SET_COM_PIN_CFG = const(0xDA)SET_DISP_CLK_DIV = const(0xD5)SET_PRECHARGE = const(0xD9)SET_VCOM_DESEL = const(0xDB)SET_CHARGE_PUMP = const(0x8D)# Subclassing FrameBuffer provides support for graphics primitives# /en/latest/pyboard/library/framebuf.htmlclass SSD1306(framebuf.FrameBuffer):def __init__(self, width, height, external_vcc):self.width = widthself.height = heightself.external_vcc = external_vccself.pages = self.height // 8self.buffer = bytearray(self.pages * self.width)super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)self.init_display()def init_display(self):for cmd in (SET_DISP | 0x00, # off# address settingSET_MEM_ADDR,0x00, # horizontal# resolution and layoutSET_DISP_START_LINE | 0x00,SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0SET_MUX_RATIO,self.height - 1,SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0SET_DISP_OFFSET,0x00,SET_COM_PIN_CFG,0x02 if self.width > 2 * self.height else 0x12,# timing and driving schemeSET_DISP_CLK_DIV,0x80,SET_PRECHARGE,0x22 if self.external_vcc else 0xF1,SET_VCOM_DESEL,0x30, # 0.83*Vcc# displaySET_CONTRAST,0xFF, # maximumSET_ENTIRE_ON, # output follows RAM contentsSET_NORM_INV, # not inverted# charge pumpSET_CHARGE_PUMP,0x10 if self.external_vcc else 0x14,SET_DISP | 0x01,): # onself.write_cmd(cmd)self.fill(0)self.show()def poweroff(self):self.write_cmd(SET_DISP | 0x00)def poweron(self):self.write_cmd(SET_DISP | 0x01)def contrast(self, contrast):self.write_cmd(SET_CONTRAST)self.write_cmd(contrast)def invert(self, invert):self.write_cmd(SET_NORM_INV | (invert & 1))def show(self):x0 = 0x1 = self.width - 1if self.width == 64:# displays with width of 64 pixels are shifted by 32x0 += 32x1 += 32self.write_cmd(SET_COL_ADDR)self.write_cmd(x0)self.write_cmd(x1)self.write_cmd(SET_PAGE_ADDR)self.write_cmd(0)self.write_cmd(self.pages - 1)self.write_data(self.buffer)class SSD1306_I2C(SSD1306):def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False):self.i2c = i2cself.addr = addrself.temp = bytearray(2)self.write_list = [b"\x40", None] # Co=0, D/C#=1super().__init__(width, height, external_vcc)def write_cmd(self, cmd):self.temp[0] = 0x80 # Co=1, D/C#=0self.temp[1] = cmdself.i2c.writeto(self.addr, self.temp)def write_data(self, buf):self.write_list[1] = bufself.i2c.writevto(self.addr, self.write_list)class SSD1306_SPI(SSD1306):def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):self.rate = 10 * 1024 * 1024dc.init(dc.OUT, value=0)res.init(res.OUT, value=0)cs.init(cs.OUT, value=1)self.spi = spiself.dc = dcself.res = resself.cs = csimport timeself.res(1)time.sleep_ms(1)self.res(0)time.sleep_ms(10)self.res(1)super().__init__(width, height, external_vcc)def write_cmd(self, cmd):self.spi.init(baudrate=self.rate, polarity=0, phase=0)self.cs(1)self.dc(0)self.cs(0)self.spi.write(bytearray([cmd]))self.cs(1)def write_data(self, buf):self.spi.init(baudrate=self.rate, polarity=0, phase=0)self.cs(1)self.dc(1)self.cs(0)self.spi.write(buf)self.cs(1)

from machine import Pin,I2Cfrom ssd1306 import SSD1306_I2Cimport framebufimport utimeimport arrayi2c = I2C(0, scl=Pin(9), sda=Pin(8))print("I2C Address:", hex(i2c.scan()[0]).upper())WIDTH = 128HEIGHT = 64oled = SSD1306_I2C(WIDTH, HEIGHT, i2c)# Raspberry Pi logo as 32x32 bytearraybuffer = bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|?\x00\x01\x86@\x80\x01\x01\x80\x80\x01\x11\x88\x80\x01\x05\xa0\x80\x00\x83\xc1\x00\x00C\xe3\x00\x00~\xfc\x00\x00L'\x00\x00\x9c\x11\x00\x00\xbf\xfd\x00\x00\xe1\x87\x00\x01\xc1\x83\x80\x02A\x82@\x02A\x82@\x02\xc1\xc2@\x02\xf6>\xc0\x01\xfc=\x80\x01\x18\x18\x80\x01\x88\x10\x80\x00\x8c!\x00\x00\x87\xf1\x00\x00\x7f\xf6\x00\x008\x1c\x00\x00\x0c \x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")# Load the raspberry pi logo into the framebuffer (the image is 32x32)fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB)oled.fill(0)oled.blit(fb, (128-32)//2, (64-32)//2)oled.text('RaspberryPi Pico', 0, 48)oled.show()utime.sleep(1)#oled.invert(True)# 反色#oled.invert(False) # 正常#oled.poweroff()#oled.poweron()oled.contrast(250) # 0x0~0xFFoled.fill(0)oled.text("Hello", 15, 30)oled.text("RP2040", 15, 40)oled.hline(0,0,60, 1)oled.hline(0,20,60, 1) # 水平线, X,Y, W, 颜色oled.vline(0,0,20, 1)oled.vline(60,0,20, 1) # 垂直线, X,Y, W, 颜色oled.rect(80, 0, 40, 10, 1, True) # X,Y, 宽度,高度,颜色,True:实心矩形,False:空心矩形oled.ellipse(40, 20, 30, 10, 1, True, 0b0010) # 中心X,中心Y,宽度,高度,颜色,实心/空心 象限Q4|Q3|Q2|Q1oled.pixel(64, 32, 1) # 画一个像素,X,Y, 颜色coords = array.array('h', [0,0, 15,12, 2,8, 16,26]) # 路径坐标, [x0,y0, x1,y1,...xn,yn]oled.poly(60, 20, coords, 1, False) #多边形 x, y, 路径,颜色,实心/空心oled.show()while True:#oled.scroll(0,1)oled.show()utime.sleep_ms(200)

AHT10温湿度传感器

aht10.py另存到pico的/lib/aht10.py

import timefrom math import log# AHT10 Library for MicroPython on ESP32# Author: Sean Yong# Date: 23rd December, # Version 1.0#CONSTANTSAHT10_ADDRESS = 0x38 # 0111000 (7bit address)AHT10_READ_DELAY_MS = 75 # Time it takes for AHT to collect dataAHT_TEMPERATURE_CONST = 200AHT_TEMPERATURE_OFFSET = 50KILOBYTE_CONST = 1048576CMD_INITIALIZE = bytearray([0xE1, 0x08, 0x00])CMD_MEASURE = bytearray([0xAC, 0x33, 0x00])FARENHEIT_MULTIPLIER = 9/5FARENHEIT_OFFSET = 32class AHT10:def __init__(self, i2c, mode=0, address=AHT10_ADDRESS):if i2c is None:raise ValueError('I2C object required.')if mode is not (0 and 1):raise ValueError('Mode must be either 0 for Celsius or 1 Farenheit')self.i2c = i2cself.address = addressself.i2c.writeto(address, CMD_INITIALIZE)self.readings_raw = bytearray(8)self.results_parsed = [0, 0]self.mode = mode # 0 for Celsius, 1 for Farenheitdef read_raw(self):self.i2c.writeto(self.address, CMD_MEASURE)time.sleep_ms(AHT10_READ_DELAY_MS)self.readings_raw = self.i2c.readfrom(AHT10_ADDRESS, 6)self.results_parsed[0] = self.readings_raw[1] << 12 | self.readings_raw[2] << 4 | self.readings_raw[3] >> 4self.results_parsed[1] = (self.readings_raw[3] & 0x0F) << 16 | self.readings_raw[4] << 8 | self.readings_raw[5]def humidity(self):self.read_raw()return (self.results_parsed[0] / KILOBYTE_CONST) * 100 def temperature(self):self.read_raw()if self.mode is 0:return (self.results_parsed[1] / KILOBYTE_CONST) * AHT_TEMPERATURE_CONST - AHT_TEMPERATURE_OFFSETelse:return ((self.results_parsed[1] / KILOBYTE_CONST) * AHT_TEMPERATURE_CONST - AHT_TEMPERATURE_OFFSET) * FARENHEIT_MULTIPLIER + FARENHEIT_OFFSETdef set_mode(self, mode):if mode is not (0 or 1):raise ValueError('Mode must be either 0 for Celsius or 1 Farenheit')self.mode = modedef print(self):print("Temperature: " + str(self.temperature()) + ("C","F")[self.mode] + ", Humidity: " + str(self.humidity()))def dew_point(self):h = self.humidity()t = self.temperature()prev_mode = self.modeself.mode = 0h = (log(h, 10) - 2) / 0.4343 + (17.62 * t) / (243.12 + t)return 243.12 * h / (17.62 - h)

from machine import Pin,I2Cimport utimeimport aht10i2c = I2C(0, sda=Pin(8), scl=Pin(9),freq=400000)devlist = i2c.scan()print("Address List:",devlist)for dev in devlist:print(hex(dev))aht10 = aht10.AHT10(i2c, mode=0, address=0x38)while True:humi = aht10.humidity()# 湿度temp = aht10.temperature() # 温度dewp = aht10.dew_point() # 露点aht10.print()utime.sleep(1)

OLED显示AHT10读取值

from machine import Pin,I2Cfrom ssd1306 import SSD1306_I2C,SSD1306_SPIimport framebufimport arrayimport utimeimport aht10i2c = I2C(0, sda=Pin(8), scl=Pin(9),freq=400000)devlist = i2c.scan()print("Address List:",devlist)for dev in devlist:print(hex(dev))# Raspberry Pi logo as 32x32 bytearraybuffer = bytearray(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|?\x00\x01\x86@\x80\x01\x01\x80\x80\x01\x11\x88\x80\x01\x05\xa0\x80\x00\x83\xc1\x00\x00C\xe3\x00\x00~\xfc\x00\x00L'\x00\x00\x9c\x11\x00\x00\xbf\xfd\x00\x00\xe1\x87\x00\x01\xc1\x83\x80\x02A\x82@\x02A\x82@\x02\xc1\xc2@\x02\xf6>\xc0\x01\xfc=\x80\x01\x18\x18\x80\x01\x88\x10\x80\x00\x8c!\x00\x00\x87\xf1\x00\x00\x7f\xf6\x00\x008\x1c\x00\x00\x0c \x00\x00\x03\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")# Load the raspberry pi logo into the framebuffer (the image is 32x32)fb = framebuf.FrameBuffer(buffer, 32, 32, framebuf.MONO_HLSB)WIDTH = 128HEIGHT = 64oled = SSD1306_I2C(WIDTH,HEIGHT,i2c)oled.fill(0)# oled.blit(fb, (128-32)//2, (64-32)//2)oled.text('RaspberryPi Pico', 0, 0)oled.hline(0,12, 128, 1)oled.blit(fb, (128-32), 15)oled.show()aht10 = aht10.AHT10(i2c, mode=0, address=0x38)utime.sleep(1)while True:humi = aht10.humidity()temp = aht10.temperature()dewp = aht10.dew_point()#aht10.print()utime.sleep(0.2)#oled.fill(0)oled.rect(0,15,128-32,45, 0, True)oled.text("Temp:{:.2f}C".format(temp), 0, 15)oled.text("Humi:{:.2f}%".format(humi), 0, 25)oled.text("Dewp:{:.2f}C".format(dewp), 0, 35)oled.show()utime.sleep(1)

BH1750光照度传感器

bh1750.py

import utime# BH1750 Library for MicroPython on RP2040# Author: Song YuLong# Date: -10-25# Version 1.0#CONSTANTSBH1750_ADDRESS = const (0x23) # 00100011 I2C Slave AddressBH1750_READ_DELAY_MS = 180 # measurement time ms.BH1750_POWERDOWN = bytearray([0x00])# Power DownBH1750_POWERON = bytearray([0x01])# Power OnBH1750_RESET= bytearray([0x07])# Reset Data Register Value.# Countinue :# One Time : it is automatically set to power down mode after measurement.BH1750_CONTINUE_H_MODE = bytearray([0x10]) # Countinue H-Resolution Mode 1lx 120msBH1750_CONTINUE_H_MODE2 = bytearray([0x11]) # Countinue H-Resolution Mode 0.5lx 120msBH1750_CONTINUE_L_MODE = bytearray([0x13])# Countinue L-Resolution Mode 4lx 16msBH1750_ONE_TIME_H_MODE = bytearray([0x20]) # One Time H-Resolution Mode 1lx 120msBH1750_ONE_TIME_H_MODE2 = bytearray([0x21]) # One Time H-Resolution Mode 0.5lx 120msBH1750_ONE_TIME_L_MODE = bytearray([0x23]) # One Time L-Resolution Mode 4lx 16msclass BH1750:def __init__(self, i2c, mode=0, address=BH1750_ADDRESS):if i2c is None:raise ValueError('I2C object required.')if mode == 0:self.mode = BH1750_CONTINUE_H_MODEelif mode == 1:self.mode = BH1750_CONTINUE_H_MODE2elif mode == 2:self.mode = BH1750_CONTINUE_L_MODEelif mode == 3:self.mode = BH1750_ONE_TIME_H_MODEelif mode == 4:self.mode = BH1750_ONE_TIME_H_MODE2elif mode == 5:self.mode = BH1750_ONE_TIME_L_MODEif self.mode == BH1750_CONTINUE_H_MODE2 or self.mode == BH1750_ONE_TIME_H_MODE2:self.resolurtion = 0.5elif self.mode == BH1750_CONTINUE_H_MODE or self.mode == BH1750_ONE_TIME_H_MODE:self.resolurtion = 1elif self.mode == BH1750_CONTINUE_L_MODE or self.mode == BH1750_ONE_TIME_L_MODE:self.resolurtion = 4else:raise ValueError('Mode must be 0 ~ 5')self.i2c = i2cself.address = addressself.i2c.writeto(address, BH1750_POWERDOWN)self.i2c.writeto(address, BH1750_POWERON)self.i2c.writeto(address, self.mode)self.rawdata = bytearray(8)self.value = 0.0def read_raw(self):self.i2c.writeto(self.address, self.mode)utime.sleep_ms(BH1750_READ_DELAY_MS) # max 160msself.rawdata = self.i2c.readfrom(self.address, 2) def illuminance(self):# illumination =(reg[15:0] * resolurtion) / 1.2 (unit:lx)self.read_raw()self.value = ((self.rawdata[0]<<8 | self.rawdata[1]) * self.resolurtion)/1.2return self.valuedef output(self):print("illuminance -->{:.2f}".format(self.value), "LX")def set_mode(self, mode):if mode == 0:self.mode = BH1750_CONTINUE_H_MODEelif mode == 1:self.mode = BH1750_CONTINUE_H_MODE2elif mode == 2:self.mode = BH1750_CONTINUE_L_MODEelif mode == 3:self.mode = BH1750_ONE_TIME_H_MODEelif mode == 4:self.mode = BH1750_ONE_TIME_H_MODE2elif mode == 5:self.mode = BH1750_ONE_TIME_L_MODEif self.mode == BH1750_CONTINUE_H_MODE2 or self.mode == BH1750_ONE_TIME_H_MODE2:self.resolurtion = 0.5elif self.mode == BH1750_CONTINUE_H_MODE or self.mode == BH1750_ONE_TIME_H_MODE:self.resolurtion = 1elif self.mode == BH1750_CONTINUE_L_MODE or self.mode == BH1750_ONE_TIME_L_MODE:self.resolurtion = 4else:raise ValueError('Mode must be 0 ~ 5')

bh1750_demo.py

from machine import Pin,I2Cimport utimeimport bh1750i2c = I2C(0, sda=Pin(8), scl=Pin(9), freq=200000)devlist = i2c.scan()print(devlist)for dev in devlist:print(hex(dev))bh1750 = bh1750.BH1750(i2c, mode=1, address=0x23)print("BH1750 Demo...")value = 0.0while True:value = bh1750.illuminance()print("illuminance:{:.2f} lx".format(value))#bh1750.output()utime.sleep(0.1)

BMP280 气压强传感器

bmp280.py

from micropython import constfrom ustruct import unpack as unp# Author David Stenwall Wahlund (david at dafnet.se)# Power ModesBMP280_POWER_SLEEP = const(0)BMP280_POWER_FORCED = const(1)BMP280_POWER_NORMAL = const(3)BMP280_SPI3W_ON = const(1)BMP280_SPI3W_OFF = const(0)BMP280_TEMP_OS_SKIP = const(0)BMP280_TEMP_OS_1 = const(1)BMP280_TEMP_OS_2 = const(2)BMP280_TEMP_OS_4 = const(3)BMP280_TEMP_OS_8 = const(4)BMP280_TEMP_OS_16 = const(5)BMP280_PRES_OS_SKIP = const(0)BMP280_PRES_OS_1 = const(1)BMP280_PRES_OS_2 = const(2)BMP280_PRES_OS_4 = const(3)BMP280_PRES_OS_8 = const(4)BMP280_PRES_OS_16 = const(5)# Standby settings in msBMP280_STANDBY_0_5 = const(0)BMP280_STANDBY_62_5 = const(1)BMP280_STANDBY_125 = const(2)BMP280_STANDBY_250 = const(3)BMP280_STANDBY_500 = const(4)BMP280_STANDBY_1000 = const(5)BMP280_STANDBY_2000 = const(6)BMP280_STANDBY_4000 = const(7)# IIR Filter settingBMP280_IIR_FILTER_OFF = const(0)BMP280_IIR_FILTER_2 = const(1)BMP280_IIR_FILTER_4 = const(2)BMP280_IIR_FILTER_8 = const(3)BMP280_IIR_FILTER_16 = const(4)# Oversampling settingBMP280_OS_ULTRALOW = const(0)BMP280_OS_LOW = const(1)BMP280_OS_STANDARD = const(2)BMP280_OS_HIGH = const(3)BMP280_OS_ULTRAHIGH = const(4)# Oversampling matrix# (PRESS_OS, TEMP_OS, sample time in ms)_BMP280_OS_MATRIX = [[BMP280_PRES_OS_1, BMP280_TEMP_OS_1, 7],[BMP280_PRES_OS_2, BMP280_TEMP_OS_1, 9],[BMP280_PRES_OS_4, BMP280_TEMP_OS_1, 14],[BMP280_PRES_OS_8, BMP280_TEMP_OS_1, 23],[BMP280_PRES_OS_16, BMP280_TEMP_OS_2, 44]]# Use casesBMP280_CASE_HANDHELD_LOW = const(0)BMP280_CASE_HANDHELD_DYN = const(1)BMP280_CASE_WEATHER = const(2)BMP280_CASE_FLOOR = const(3)BMP280_CASE_DROP = const(4)BMP280_CASE_INDOOR = const(5)_BMP280_CASE_MATRIX = [[BMP280_POWER_NORMAL, BMP280_OS_ULTRAHIGH, BMP280_IIR_FILTER_4, BMP280_STANDBY_62_5],[BMP280_POWER_NORMAL, BMP280_OS_STANDARD, BMP280_IIR_FILTER_16, BMP280_STANDBY_0_5],[BMP280_POWER_FORCED, BMP280_OS_ULTRALOW, BMP280_IIR_FILTER_OFF, BMP280_STANDBY_0_5],[BMP280_POWER_NORMAL, BMP280_OS_STANDARD, BMP280_IIR_FILTER_4, BMP280_STANDBY_125],[BMP280_POWER_NORMAL, BMP280_OS_LOW, BMP280_IIR_FILTER_OFF, BMP280_STANDBY_0_5],[BMP280_POWER_NORMAL, BMP280_OS_ULTRAHIGH, BMP280_IIR_FILTER_16, BMP280_STANDBY_0_5]]_BMP280_REGISTER_ID = const(0xD0)_BMP280_REGISTER_RESET = const(0xE0)_BMP280_REGISTER_STATUS = const(0xF3)_BMP280_REGISTER_CONTROL = const(0xF4)_BMP280_REGISTER_CONFIG = const(0xF5) # IIR filter config_BMP280_REGISTER_DATA = const(0xF7)class BMP280:def __init__(self, i2c_bus, addr=0x76, use_case=BMP280_CASE_HANDHELD_DYN):self._bmp_i2c = i2c_busself._i2c_addr = addr# read calibration data# < little-endian# H unsigned short# h signed shortself._T1 = unp('<H', self._read(0x88, 2))[0]self._T2 = unp('<h', self._read(0x8A, 2))[0]self._T3 = unp('<h', self._read(0x8C, 2))[0]self._P1 = unp('<H', self._read(0x8E, 2))[0]self._P2 = unp('<h', self._read(0x90, 2))[0]self._P3 = unp('<h', self._read(0x92, 2))[0]self._P4 = unp('<h', self._read(0x94, 2))[0]self._P5 = unp('<h', self._read(0x96, 2))[0]self._P6 = unp('<h', self._read(0x98, 2))[0]self._P7 = unp('<h', self._read(0x9A, 2))[0]self._P8 = unp('<h', self._read(0x9C, 2))[0]self._P9 = unp('<h', self._read(0x9E, 2))[0]# output rawself._t_raw = 0self._t_fine = 0self._t = 0self._p_raw = 0self._p = 0self._h = 0self.read_wait_ms = 0 # interval between forced measure and readoutself._new_read_ms = 200 # interval betweenself._last_read_ts = 0if use_case is not None:self.use_case(use_case)def _read(self, addr, size=1):return self._bmp_i2c.readfrom_mem(self._i2c_addr, addr, size)def _write(self, addr, b_arr):if not type(b_arr) is bytearray:b_arr = bytearray([b_arr])return self._bmp_i2c.writeto_mem(self._i2c_addr, addr, b_arr)def _gauge(self):# TODO limit new reads# read all data at once (as by spec)d = self._read(_BMP280_REGISTER_DATA, 6)self._p_raw = (d[0] << 12) + (d[1] << 4) + (d[2] >> 4)self._t_raw = (d[3] << 12) + (d[4] << 4) + (d[5] >> 4)self._t_fine = 0self._t = 0self._p = 0self._h = 0def reset(self):self._write(_BMP280_REGISTER_RESET, 0xB6)def load_test_calibration(self):self._T1 = 27504self._T2 = 26435self._T3 = -1000self._P1 = 36477self._P2 = -10685self._P3 = 3024self._P4 = 2855self._P5 = 140self._P6 = -7self._P7 = 15500self._P8 = -14600self._P9 = 6000def load_test_data(self):self._t_raw = 519888self._p_raw = 415148def print_calibration(self):print("T1: {} {}".format(self._T1, type(self._T1)))print("T2: {} {}".format(self._T2, type(self._T2)))print("T3: {} {}".format(self._T3, type(self._T3)))print("P1: {} {}".format(self._P1, type(self._P1)))print("P2: {} {}".format(self._P2, type(self._P2)))print("P3: {} {}".format(self._P3, type(self._P3)))print("P4: {} {}".format(self._P4, type(self._P4)))print("P5: {} {}".format(self._P5, type(self._P5)))print("P6: {} {}".format(self._P6, type(self._P6)))print("P7: {} {}".format(self._P7, type(self._P7)))print("P8: {} {}".format(self._P8, type(self._P8)))print("P9: {} {}".format(self._P9, type(self._P9)))def _calc_t_fine(self):# From datasheet page 22self._gauge()if self._t_fine == 0:var1 = (((self._t_raw >> 3) - (self._T1 << 1)) * self._T2) >> 11var2 = (((((self._t_raw >> 4) - self._T1)* ((self._t_raw >> 4)- self._T1)) >> 12)* self._T3) >> 14self._t_fine = var1 + var2@propertydef temperature(self):self._calc_t_fine()if self._t == 0:self._t = ((self._t_fine * 5 + 128) >> 8) / 100.return self._t@propertydef pressure(self):# From datasheet page 22self._calc_t_fine()if self._p == 0:var1 = self._t_fine - 128000var2 = var1 * var1 * self._P6var2 = var2 + ((var1 * self._P5) << 17)var2 = var2 + (self._P4 << 35)var1 = ((var1 * var1 * self._P3) >> 8) + ((var1 * self._P2) << 12)var1 = (((1 << 47) + var1) * self._P1) >> 33if var1 == 0:return 0p = 1048576 - self._p_rawp = int((((p << 31) - var2) * 3125) / var1)var1 = (self._P9 * (p >> 13) * (p >> 13)) >> 25var2 = (self._P8 * p) >> 19p = ((p + var1 + var2) >> 8) + (self._P7 << 4)self._p = p / 256.0return self._p@propertydef altitude_p_t(self):'''Calculate altitude from current temperature and pressure.h = ( (((P0/P)^(1/5.257))-1) * (T + 237.15) ) / 0.0065h:altitude (m)P0:101.325(kPa)P:current pressure in kPaT:current temperature in Celsius'''self._h = ( (((101.325/(self._p/1000))**(1/5.257))-1) * (self._t + 273.15) ) / 0.0065return self._h@propertydef altitude_p(self):self._h = 44330 * (1 - (((self._p/1000)/101.325)**(1/5.255)))return self._hdef _write_bits(self, address, value, length, shift=0):d = self._read(address)[0]m = int('1' * length, 2) << shiftd &= ~md |= m & value << shiftself._write(address, d)def _read_bits(self, address, length, shift=0):d = self._read(address)[0]return d >> shift & int('1' * length, 2)@propertydef standby(self):return self._read_bits(_BMP280_REGISTER_CONFIG, 3, 5)@standby.setterdef standby(self, v):assert 0 <= v <= 7self._write_bits(_BMP280_REGISTER_CONFIG, v, 3, 5)@propertydef iir(self):return self._read_bits(_BMP280_REGISTER_CONFIG, 3, 2)@iir.setterdef iir(self, v):assert 0 <= v <= 4self._write_bits(_BMP280_REGISTER_CONFIG, v, 3, 2)@propertydef spi3w(self):return self._read_bits(_BMP280_REGISTER_CONFIG, 1)@spi3w.setterdef spi3w(self, v):assert v in (0, 1)self._write_bits(_BMP280_REGISTER_CONFIG, v, 1)@propertydef temp_os(self):return self._read_bits(_BMP280_REGISTER_CONTROL, 3, 5)@temp_os.setterdef temp_os(self, v):assert 0 <= v <= 5self._write_bits(_BMP280_REGISTER_CONTROL, v, 3, 5)@propertydef press_os(self):return self._read_bits(_BMP280_REGISTER_CONTROL, 3, 2)@press_os.setterdef press_os(self, v):assert 0 <= v <= 5self._write_bits(_BMP280_REGISTER_CONTROL, v, 3, 2)@propertydef power_mode(self):return self._read_bits(_BMP280_REGISTER_CONTROL, 2)@power_mode.setterdef power_mode(self, v):assert 0 <= v <= 3self._write_bits(_BMP280_REGISTER_CONTROL, v, 2)@propertydef is_measuring(self):return bool(self._read_bits(_BMP280_REGISTER_STATUS, 1, 3))@propertydef is_updating(self):return bool(self._read_bits(_BMP280_REGISTER_STATUS, 1))@propertydef chip_id(self):return self._read(_BMP280_REGISTER_ID, 2)@propertydef in_normal_mode(self):return self.power_mode == BMP280_POWER_NORMALdef force_measure(self):self.power_mode = BMP280_POWER_FORCEDdef normal_measure(self):self.power_mode = BMP280_POWER_NORMALdef sleep(self):self.power_mode = BMP280_POWER_SLEEPdef use_case(self, uc):assert 0 <= uc <= 5pm, oss, iir, sb = _BMP280_CASE_MATRIX[uc]p_os, t_os, self.read_wait_ms = _BMP280_OS_MATRIX[oss]self._write(_BMP280_REGISTER_CONFIG, (iir << 2) + (sb << 5))self._write(_BMP280_REGISTER_CONTROL, pm + (p_os << 2) + (t_os << 5))def oversample(self, oss):assert 0 <= oss <= 4p_os, t_os, self.read_wait_ms = _BMP280_OS_MATRIX[oss]self._write_bits(_BMP280_REGISTER_CONTROL, p_os + (t_os << 3), 2)

bmp280_demo.py

from machine import Pin, I2Cimport utimeimport bmp280import mathfrom ustruct import unpack as unpi2c = I2C(0, sda=Pin(8), scl=Pin(9), freq=200000)devlist = i2c.scan()print(devlist)for dev in devlist:print(hex(dev))print("BMP280 Demo...")bmp280 = bmp280.BMP280(i2c_bus=i2c, addr=0x76)bmp280.use_case(1)bmp280.oversample(1)bmp280.iir = 2bmp280.temp_os=2bmp280.press_os=2bmp280.print_calibration()print(bmp280.chip_id)while True:t = bmp280.temperaturep = bmp280.pressureh = bmp280.altitude_p_t# calculate altitude from pressure and temperatureh1 = bmp280.altitude_p # calculate altitude from pressureprint("P:{:.2f}(kPa)".format(p/1000),"T:{:.2f}(C)".format(t), "H:{:.2f}(m)".format(h), "H1:{:.2f}(m)".format(h1))#print(p, t, h, h1)utime.sleep(0.5)

运行效果:

HMC5883L地磁传感器

IC丝印L883为HMC8553L

IC丝印5883为QMC5883L

库模块/lib/hmc5883l.py

import mathimport machinefrom ustruct import packfrom array import arrayclass HMC5883L:__gain__ = {'0.88': (0 << 5, 0.73),'1.3': (1 << 5, 0.92),'1.9': (2 << 5, 1.22),'2.5': (3 << 5, 1.52),'4.0': (4 << 5, 2.27),'4.7': (5 << 5, 2.56),'5.6': (6 << 5, 3.03),'8.1': (7 << 5, 4.35)}def __init__(self, i2c, address=30, gauss='1.3', declination=(0, 0)):self.i2c = i2cself.address = address# Initialize sensor.#i2c.start()# Configuration register A:# 0bx11xxxxx -> 8 samples averaged per measurement# 0bxxx100xx -> 15 Hz, rate at which data is written to output registers# 0bxxxxxx00 -> Normal measurement modei2c.writeto_mem(self.address, 0x00, pack('B', 0b111000))# Configuration register B:reg_value, self.gain = self.__gain__[gauss]i2c.writeto_mem(self.address, 0x01, pack('B', reg_value))# Set mode register to continuous mode.i2c.writeto_mem(self.address, 0x02, pack('B', 0x00))#i2c.stop()# Convert declination (tuple of degrees and minutes) to radians.self.declination = (declination[0] + declination[1] / 60) * math.pi / 180# Reserve some memory for the raw xyz measurements.self.data = array('B', [0] * 6)def read(self):data = self.datagain = self.gainself.i2c.readfrom_mem_into(self.address, 0x03, data)x = (data[0] << 8) | data[1]z = (data[2] << 8) | data[3]y = (data[4] << 8) | data[5]x = x - (1 << 16) if x & (1 << 15) else xy = y - (1 << 16) if y & (1 << 15) else yz = z - (1 << 16) if z & (1 << 15) else zx = round(x * gain, 4)y = round(y * gain, 4)z = round(z * gain, 4)return x, y, zdef heading(self, x, y):heading_rad = math.atan2(y, x)heading_rad += self.declination# Correct reverse heading.if heading_rad < 0:heading_rad += 2 * math.pi# Compensate for wrapping.elif heading_rad > 2 * math.pi:heading_rad -= 2 * math.pi# Convert from radians to degrees.heading = heading_rad * 180 / math.pidegrees = math.floor(heading)minutes = round((heading - degrees) * 60)return degrees, minutesdef format_result(self, x, y, z):degrees, minutes = self.heading(x, y)return 'X: {:.4f}, Y: {:.4f}, Z: {:.4f}, Heading: {}° {}′ '.format(x, y, z, degrees, minutes)

hmc5883l_demo.py

from machine import Pin,I2Cimport utimefrom hmc5883l import HMC5883Lfrom ssd1306 import SSD1306_I2C,SSD1306_SPIi2c0 = I2C(0, sda=Pin(8), scl=Pin(9),freq=400000)devlist = i2c0.scan()print("I2C0 Address List:",devlist)for dev in devlist:print(hex(dev))mSensor = HMC5883L(i2c0, address=0x1e, gauss='1.3')while True:x, y, z = mSensor.read()print(mSensor.format_result(x, y, z))utime.sleep(0.1)

MCP4725数模转换

/lib/mcp4725.py

#Library for the MCP4725 I2C bus DAC from machine import I2C#The MCP4725 has support from 2 addressesBUS_ADDRESS = [0x60,0x62,0x63]#The device supports a few power down modes on startup and during operation POWER_DOWN_MODE = {'Off':0, '1k':1, '100k':2, '500k':3}class MCP4725:def __init__(self,i2c, address=BUS_ADDRESS[0]) :self.i2c=i2cself.address=addressself._writeBuffer=bytearray(2)def write(self,value):if value < 0:value=0value=value & 0xFFFself._writeBuffer[0]=(value>>8) & 0xFFself._writeBuffer[1]=value & 0xFFreturn self.i2c.writeto(self.address,self._writeBuffer)==2def read(self):buf=bytearray(5)if self.i2c.readfrom_into(self.address,buf) ==5:eeprom_write_busy=(buf[0] & 0x80)==0power_down=self._powerDownKey((buf[0] >> 1) & 0x03)value=((buf[1]<<8) | (buf[2])) >> 4eeprom_power_down=self._powerDownKey((buf[3]>>5) & 0x03)eeprom_value=((buf[3] & 0x0f)<<8) | buf[4] return (eeprom_write_busy,power_down,value,eeprom_power_down,eeprom_value)return Nonedef config(self,power_down='Off',value=0,eeprom=False):buf=bytearray()conf=0x40 | (POWER_DOWN_MODE[power_down] << 1)if eeprom:#store the powerdown and output value in eepromconf=conf | 0x60buf.append(conf)#check value rangeif value<0:value=0value=value & 0xFFFbuf.append(value >> 4)buf.append((value & 0x0F)<<4)return self.i2c.writeto(self.address,buf)==3def _powerDownKey(self,value):for key,item in POWER_DOWN_MODE.items():if item == value:return key

mcp4725_demo.py

from machine import Pin,I2Cimport mcp4725import utimeimport mathimport machinei2c0 = I2C(0, sda=Pin(8), scl=Pin(9), freq=400000)devlist = i2c0.scan()print(devlist)for dev in devlist:print(hex(dev))#create the MCP4725 driverdac=mcp4725.MCP4725(i2c0,mcp4725.BUS_ADDRESS[0])#configure the DAC to output ``Vdd/2`` on power-up or after a reset#dac.config('Off',2048, eeprom=True)#configure the DAC to go into power-down mode and set the output value to maximum output.dac.config('100k',4096)print(dac.read())x = 0value = 0updown = Truewhile True:#print(value)dac.write(value)# 正弦波value = 2048+int(math.sin(x)*2048)x += 0.01if x >= 360:x = 0.0# 方波'''if value == 0:value = 4095else:value = 0'''# 锯齿波 正'''if value < 4096:value += 1elif value == 4096:value=0'''# 锯齿波 反'''if value > 0:value -= 1elif value <= 0:value = 4095 '''# 三角波'''if updown :value+=1else:value-=1if value == 4096:updown = Falseelif value == 0:updown = True'''

正弦波

方波

锯齿波

三角波

GNSS导航模块

navigation.py

## songyulong# -11-03# GNSS 模块库# GNSS(Global Navigation Satellite System) 的全称是全球导航卫星系统# 保存配置参数命令 CAS00CMD_SAVE_CONFIG = const(b'$PCAS00*01\r\n') # save configuration information to flash# 串口通信波特率设置命令 CAS01CMD_SET_BAUDRATE_4800bps = const(b'$PCAS01,0*1C\r\n')CMD_SET_BAUDRATE_9600bps = const(b'$PCAS01,1*1D\r\n')CMD_SET_BAUDRATE_19200bps = const(b'$PCAS01,2*1E\r\n')CMD_SET_BAUDRATE_38400bps = const(b'$PCAS01,3*1F\r\n')CMD_SET_BAUDRATE_57600bps = const(b'$PCAS01,4*18\r\n')CMD_SET_BAUDRATE_115200bps= const(b'$PCAS01,5*19\r\n')# 设定定位更新率 CAS02CMD_SET_UPDATE_FREQ_1HZ = const(b'$PCAS02,1000*2E\r\n')CMD_SET_UPDATE_FREQ_2HZ = const(b'$PCAS02,500*1A\r\n')CMD_SET_UPDATE_FREQ_4HZ = const(b'$PCAS02,250*18\r\n')CMD_SET_UPDATE_FREQ_5HZ = const(b'$PCAS02,200*1D\r\n')CMD_SET_UPDATE_FREQ_10HZ= const(b'$PCAS02,100*1E\r\n')# 设置要求输出或停止输出的 NMEA 语句。CAS03# 配置工作系统 CAS04 GPS:美国,BDS:中国, GLONASS:俄罗斯CMD_SET_SYS_GPS = const(b'$PCAS04,1*18\r\n') CMD_SET_SYS_BDS = const(b'$PCAS04,2*1B\r\n') CMD_SET_SYS_GPS_BDS= const(b'$PCAS04,3*1A\r\n') CMD_SET_SYS_GLONASS= const(b'$PCAS04,4*1D\r\n')CMD_SET_SYS_GPS_GLONASS= const(b'$PCAS04,5*1C\r\n')CMD_SET_SYS_BDS_GLONASS= const(b'$PCAS04,6*1F\r\n')CMD_SET_SYS_GPS_BDS_GLONASS = const(b'$PCAS04,7*1E\r\n')# 接收机重启 CAS10CMD_RESTART_Hot= const(b'$PCAS10,0*1C\r\n') # 热启动 :不使用初始化信息,备份存储中的所有数据有效CMD_RESTART_Warm = const(b'$PCAS10,1*1D\r\n') # 温启动 :不使用初始化信息,清除星历CMD_RESTART_Cold = const(b'$PCAS10,2*1E\r\n') # 冷启动 :不使用初始化信息,清除备份存储中除配置外的所有数据。CMD_RESTART_Factory = const(b'$PCAS10,3*1F\r\n') # 出厂启动 :清除内存所有数据,并将接收机复位至出厂默认配置class NAVIGATION:def __init__(self, uart, mode=CMD_SET_SYS_GPS_BDS, update_freq=CMD_SET_UPDATE_FREQ_1HZ):self.uart = uartself.mode = modeself.update_freq = update_freqself.longitude = 0self.latitude = 0self.speed = 0self.course = 0self.year = 0self.month = 0self.day = 0self.hour = 0self.minute = 0self.second = 0self.rxbuf = bytes()self.send_command(self.mode)self.send_command(self.update_freq)def deinit(self):self.uart.deinit()def send_command(self, cmd):self.uart.write(cmd)def recv_loop(self):while self.uart.any() > 0:#self.rxbuf=self.uart.readline()#self.parse_message(self.rxbuf) c = self.uart.read(1)self.rxbuf += cif c == b'\n': # 一行报文结收结束self.parse_message(self.rxbuf)self.rxbuf = b''def parse_message(self,msg):try:root = msg.decode('utf-8')#print(root)if (root.startswith('$GNRMC') or root.startswith('$BDRMC') or root.startswith('$GPRMC')): # GNRMC = root.split(',')if GNRMC[2] == 'A': # 'A':有效, 'V':无效#print(GNRMC)self.hour = int(GNRMC[1][0:2])self.minute = int(GNRMC[1][2:4])self.second = int(GNRMC[1][4:6])#ms = int(GNRMC[1][7:10])self.day = int(GNRMC[9][0:2])self.month = int(GNRMC[9][2:4])self.year = int(GNRMC[9][4:6])if GNRMC[4] == 'N': # 北纬self.latitude = float(GNRMC[3]) elif GNRMC[4] == 'S': # 南纬self.latitude = -(float(GNRMC[3]))if GNRMC[6] == 'E': # 东经self.longitude = float(GNRMC[5])elif GNRMC[6] == 'W': # 西经self.longitude = -(float(GNRMC[5]))self.speed = float(GNRMC[7])self.course = float(GNRMC[8])#print(self.longitude, self.latitude, self.speed, self.course)else:self.latitude = 0self.longitude = 0elif (root.startswitch('$BDGSV')):print('BDGSV')except:passpass

from machine import Pin,I2C,UARTfrom ssd1306 import SSD1306_I2C,SSD1306_SPIimport framebufimport utimeimport navigationfrom navigation import *import _threadi2c0 = I2C(0, sda=Pin(8), scl=Pin(9),freq=400000)WIDTH = 128HEIGHT = 64oled = SSD1306_I2C(WIDTH,HEIGHT,i2c0)oled.fill(0)uart0 = UART(1, baudrate=9600, bits=8, parity=None, stop=1, tx=Pin(4), rx=Pin(5), )nav = navigation.NAVIGATION(uart0)nav.send_command(CMD_SET_SYS_BDS)nav.send_command(CMD_SET_UPDATE_FREQ_1HZ)# 导航模块结束数据任务def navigation_task(delay):while True:nav.recv_loop()utime.sleep_ms(delay)_thread.start_new_thread(navigation_task, (1,) )utime.sleep(1.5)while True:#nav.recv_loop()oled.fill(0)oled.text("Lat:{:.4f}".format(nav.latitude), 0, 0)oled.text("Lon:{:.4f}".format(nav.longitude), 0, 10)oled.text("Speed:{:.2f}".format(nav.speed), 0, 20)oled.text("Course:{:.2f}".format(nav.course), 0, 30)oled.text("{:02d}/{:02d}/{:02d}".format(nav.year, nav.month, nav.day), 0, 40)oled.text("{:02d}:{:02d}:{:02d}".format(nav.hour+8, nav.minute, nav.second), 0, 50)oled.show()#print("main loop....", nav.longitude, nav.latitude, nav.speed, nav.course)utime.sleep(1)

无线串口模块

简单数据透传Demo

from machine import Pin,UARTimport utimeclass WIRELESS_UART:def __init__(self, uart, m0, m1, aux=-1, mode=0):self.uart = uartself.mode = modeself.m0 = Pin(m0, Pin.OUT)self.m1 = Pin(m1, Pin.OUT)if aux >= 0:self.aux = Pin(aux, Pin.IN)self.set_mode(mode)self.rxbuf = bytes()def set_mode(self, mode):self.mode = modeif self.mode == 0:self.m0.value(0)self.m1.value(0)elif self.mode == 1:self.m0.value(1)self.m1.value(0)elif self.mode == 2:self.m0.value(0)self.m1.value(1)elif self.mode == 3:self.m0.value(1)self.m1.value(1)else:print('Error mode must be in 0 ~ 3')def write(self, data):self.uart.write(data)def recv_loop(self):while self.uart.any() > 0:#self.rxbuf=self.uart.readline()#self.parse_message(self.rxbuf) c = self.uart.read(1)self.rxbuf += cif c == b'\n': # 一行报文结收结束print(self.rxbuf)self.uart.write(b'\n'+self.rxbuf)self.rxbuf = b'' uart0 = UART(0, baudrate=9600, bits=8, parity=None, stop=1, tx=Pin(16), rx=Pin(17) ) wuart = WIRELESS_UART(uart=uart0, m0=19, m1=18, aux=-1, mode=0) wuart.set_mode(0) # mode:0,1,2,3while True:#wuart.write(b'good')wuart.recv_loop()utime.sleep_ms(10)

支持参数配置Demo

from machine import Pin,UARTimport utimeimport structCMD_READ_CONFIG = bytes([0xC1,0xC1,0xC1]) # 读取模块配置参数,比如:C0 00 00 18 50 44。CMD_READ_INFO = bytes([0xC3,0xC3,0xC3]) # 读取模块版本信息,比如:C3 30 xx yy;30表示E30系列,CMD_RESET = bytes([0xC4,0xC4,0xC4]) # 复位模块# 串口校验模式UART_8N1 = 0x00<<6UART_8O1 = 0x01<<6UART_8E1 = 0x02<<6# 串口波特率BAUDRATE_1200 = 0x00<<3BAUDRATE_2400 = 0x01<<3BAUDRATE_4800 = 0x02<<3BAUDRATE_9600 = 0x03<<3BAUDRATE_19200 = 0x04<<3BAUDRATE_38400 = 0x05<<3BAUDRATE_57600 = 0x06<<3BAUDRATE_115200 = 0x07<<3# 无线空中速率AIRRATE_1KBPS = 0x00AIRRATE_2KBPS = 0x01AIRRATE_5KBPS = 0x02AIRRATE_8KBPS = 0x03AIRRATE_10KBPS = 0x04AIRRATE_15KBPS = 0x05AIRRATE_20KBPS = 0x06AIRRATE_25KBPS = 0x07# 定点发生使能TRS_MODE = 0x00<<7FIX_MODE = 0x01<<7# IO驱动IO_PPO = 0x01<<6 # Push-Pull Output 推挽输出IO_ODO = 0x00<<6 # Open Drain Output 开漏输出WAKEUP_250MS = 0x00<<3WAKEUP_500MS = 0x01<<3WAKEUP_750MS = 0x02<<3WAKEUP_1000MS = 0x03<<3WAKEUP_1250MS = 0x04<<3WAKEUP_1500MS = 0x05<<3WAKEUP_1750MS = 0x06<<3WAKEUP_2000MS = 0x07<<3# FEC开关FEC_ON = 0x01<<2FEC_OFF = 0x00<<2# 发射功率POWER_10dBm = 0x00POWER_9dBm = 0x01POWER_8dBm = 0x02POWER_7dBm = 0x03class WIRELESS_UART:def __init__(self, uart, m0, m1, aux=-1, mode=0):self.uart = uartself.mode = modeself.m0 = Pin(m0, Pin.OUT)self.m1 = Pin(m1, Pin.OUT)if aux >= 0:self.aux = Pin(aux, Pin.IN)self.HEAD = 0xC2 # 0xC0:设置参数到ROM, 0xC2:设置参数到RAMself.ADDH = 0x00 # 地址高字节 00H-FFHself.ADDL = 0x00 # 地址低字节 00H-FFHself.SPED = UART_8N1|BAUDRATE_9600|AIRRATE_1KBPS # 速率参数self.CHAN = 0xFF # 通信频率 信道self.OPTION = TRS_MODE|IO_PPO|WAKEUP_250MS|FEC_ON|POWER_10dBm #选项print(self.SPED, self.OPTION)self.set_mode(mode)self.rxbuf = bytes()self.recv = bytes()def send_configurate(self, save=False):mode = self.modeself.set_mode(3)utime.sleep_ms(100)if save==True:self.HEAD = 0xC0else:self.HEAD = 0xC2cmd = bytearray([self.HEAD, self.ADDH, self.ADDL, self.SPED, self.CHAN, self.OPTION])print(cmd)self.uart.write(cmd)utime.sleep_ms(200)self.set_mode(mode)def set_mode(self, mode):self.mode = mode# mode_0: 一般模式# mode_1: 唤醒模式# mode_2: 省电模式# mode_3: 休眠模式if self.mode == 0:self.m0.value(0)self.m1.value(0)elif self.mode == 1:self.m0.value(1)self.m1.value(0)elif self.mode == 2:self.m0.value(0)self.m1.value(1)elif self.mode == 3:self.m0.value(1)self.m1.value(1)else:print('Error mode must be in 0 ~ 3')def read_configurate(self):mode = self.modeself.set_mode(3)self.uart.write(CMD_READ_CONFIG)utime.sleep_ms(200)recv = bytes()while self.uart.any():recv += self.uart.read(1)self.set_mode(mode)print(len(recv))if len(recv)>=6:umode = (recv[3]&0xC0)>>6 # [7,6] 串口校验位模式ubsp = (recv[3]&0x38)>>3 # [5,4,3] TTL串口速率(bps)wbps = (recv[3]&0x07) # [2,1,0] 无线空中速率(bps)freq = 425+(int(recv[4]) * 0.1) # 通信频率 425M+CHAN*0.1M 00H-FFH,对应425~455MHzfcc = (recv[5]&0x04)>>2 #[2] FCC开关 0:关闭FCC, 1:打开FCCdBm = (recv[5]&0x03) #[1,0] 发射功率print('----------Configurate-------------')print('-- head {:#X}'.format(recv[0]))print('-- ADDH {:#X}'.format(recv[1]))print('-- ADDL {:#X}'.format(recv[2]))print('-- SPEED:{:x}'.format(umode))print('-- ubsp:{:x}'.format(ubsp))print('-- wbps:{:x}'.format(wbps))print('-- ch:{:x}'.format(recv[4]))print('-- freq:{:d}MHz'.format(freq))print('-- option:{:x}'.format(recv[5]))print('-- FCC:{:d}'.format(fcc))print('-- dBm:{:d}dBm'.format(dBm))else:print('error configuarte head')return recvdef write(self, data):self.uart.write(data)def recv_loop(self):while self.uart.any() > 0:#self.rxbuf=self.uart.readline()#self.parse_message(self.rxbuf) c = self.uart.read(1)self.rxbuf += c#print(c)if c == b'\n': # 一行报文结收结束print(self.rxbuf)self.uart.write(b'\n'+self.rxbuf)self.rxbuf = b'' uart0 = UART(0, baudrate=9600, bits=8, parity=None, stop=1, tx=Pin(16), rx=Pin(17) ) wuart = WIRELESS_UART(uart=uart0, m0=19, m1=18, aux=-1, mode=0) wuart.set_mode(0)wuart.send_configurate(False)utime.sleep(1)ret = wuart.read_configurate()for r in ret:print(r)utime.sleep(1)while True:#wuart.write(b'good')wuart.recv_loop()utime.sleep_ms(100)

旋转编码器

from machine import Pinimport utimekey = Pin(18, Pin.IN)rotary_clk = Pin(19, Pin.IN)rotary_dt = Pin(20, Pin.IN)def rotary_encoder_task(pin):# 当CLK下降沿时,DT是低电平:顺时针旋转,DT是高电平:逆时针旋转if rotary_dt.value() == 0:print('----right---')else:print('----left---')rotary_clk.irq(trigger=Pin.IRQ_FALLING, handler=rotary_encoder_task)# 当按键按下或抬起时会有抖动,这里增加个变量以便过滤掉干扰脉冲key_pressed = Falsedef key_task(pin):global key_pressedif key_pressed == False:if key.value()==0:key_pressed = Trueprint('key down')elif key_pressed == True:if key.value()==1:key_pressed = Falseprint('key up')key.irq(trigger=Pin.IRQ_FALLING|Pin.IRQ_RISING, handler=key_task)while True:utime.sleep(0.5)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。