最近在做一个小项目,k210的温湿度检测、大气压强检测、土壤湿度检测以及光敏传感器,在官方店买了很多传感器....然而经过多方确定K210没有ADC,只能做DS18B20(温度检测)和DHT11(温湿度检测)
也就是pybase右上角的两个传感器:
ADC是数模转换器,可以把模拟信号转换为数字信号,传感器工作的本质就是电压的变化,是一个连续的值,也就是模拟值,以光敏传感器为例:
光敏传感器就三个引脚,VCC和GND用来通电,还有一个S引脚就是通过内部的电路设计,里面有一个光敏电阻,当光照强度发生改变时,电阻变化,导致电压变化,读取S引脚的电压变化,再通过ADC数模转换器,转换成数值,从而反应光照强弱。
from machine import Pin,ADC
Light = ADC(Pin(32))
value=Light.read() #获取ADC数值
#判断光照强度,分3档显示。
if 0 < value <=1365:
print('Bright')
if 1365 < value <= 2730:
print('Normal')
if 2730 < value <= 4095:
print('Weak')
注意:以上代码是官网另一款产品WIFI-ESP32,k210芯片内部没有封装ADC模块,无法导入。
了解到此,我只能在淘宝上再入手一块WIFI-ESP32...
不知是不是电路的串并联原因,这块ESP32看上去有7个ADC?真的假的,过几天到了试一试,能不能把传感器都接上,同时工作。
在Github里找到了官方教程,讲如何用k210做温湿度检测的,原来DHT11内部可以自己实现AD转换,包括DS18B20。
传送门: MicroPython_Examples/pyAI-K210 at master · 01studio-lab/MicroPython_Examples (github.com)
哦对了,官方提供的是两个py文件,一个单独用来写dht11了,好像是把dht11.py保存到SD卡上,这样就是写入了一个库,身边没有SD卡,我就把两个代码合并了。
DHT11的代码:
import time
from fpioa_manager import fm
from Maix import GPIO
class DHT11Result:
# 'DHT11 sensor result returned by DHT11.read() method'
ERR_NO_ERROR = 0
ERR_MISSING_DATA = 1
ERR_CRC = 2
error_code = ERR_NO_ERROR
temperature = -1
humidity = -1
def __init__(self, error_code, temperature, humidity):
self.error_code = error_code
self.temperature = temperature
self.humidity = humidity
def is_valid(self):
return self.error_code == DHT11Result.ERR_NO_ERROR
class DHT11:
def __init__(self, gpio = None):
# '1DHT11 sensor reader class for MaixPy'
if gpio != None:
self._gpio = gpio
else:
raise Exception("please input a valid gpio")
def read(self):
self._gpio.mode(GPIO.OUT)
# send initial high
self.__send_and_sleep(1, 50)
# pull down to low
self.__send_and_sleep(0, 20)
# change to input using pull up
self._gpio.mode(GPIO.IN)
# collect data into an array
data = self.__collect_input()
# parse lengths of all data pull up periods
pull_up_lengths = self.__parse_data_pull_up_lengths(data)
# if bit count mismatch, return error (4 byte data + 1 byte checksum)
if len(pull_up_lengths) != 40:
return DHT11Result(DHT11Result.ERR_MISSING_DATA, 0, 0)
# calculate bits from lengths of the pull up periods
bits = self.__calculate_bits(pull_up_lengths)
# we have the bits, calculate bytes
the_bytes = self.__bits_to_bytes(bits)
# calculate checksum and check
checksum = self.__calculate_checksum(the_bytes)
if the_bytes[4] != checksum:
return DHT11Result(DHT11Result.ERR_CRC, 0, 0)
# ok, we have valid data
# The meaning of the return sensor values
# the_bytes[0]: humidity int
# the_bytes[1]: humidity decimal
# the_bytes[2]: temperature int
# the_bytes[3]: temperature decimal
temperature = the_bytes[2] + float(the_bytes[3]) / 10
humidity = the_bytes[0] + float(the_bytes[1]) / 10
return DHT11Result(DHT11Result.ERR_NO_ERROR, temperature, humidity)
def __send_and_sleep(self, output, sleep):
self._gpio.value(output)
time.sleep_ms(sleep)
def __collect_input(self):
# collect the data while unchanged found
unchanged_count = 0
# this is used to determine where is the end of the data
max_unchanged_count = 100
last = -1
data = []
while True:
current = self._gpio.value()
data.append(current)
if last != current:
unchanged_count = 0
last = current
else:
unchanged_count += 1
if unchanged_count > max_unchanged_count:
break
return data
def __parse_data_pull_up_lengths(self, data):
STATE_INIT_PULL_DOWN = 1
STATE_INIT_PULL_UP = 2
STATE_DATA_FIRST_PULL_DOWN = 3
STATE_DATA_PULL_UP = 4
STATE_DATA_PULL_DOWN = 5
state = STATE_INIT_PULL_DOWN
lengths = [] # will contain the lengths of data pull up periods
current_length = 0 # will contain the length of the previous period
for i in range(len(data)):
current = data[i]
current_length += 1
if state == STATE_INIT_PULL_DOWN:
if current == 0:
# ok, we got the initial pull down
state = STATE_INIT_PULL_UP
continue
else:
continue
if state == STATE_INIT_PULL_UP:
if current == 1:
# ok, we got the initial pull up
state = STATE_DATA_FIRST_PULL_DOWN
continue
else:
continue
if state == STATE_DATA_FIRST_PULL_DOWN:
if current == 0:
# we have the initial pull down, the next will be the data pull up
state = STATE_DATA_PULL_UP
continue
else:
continue
if state == STATE_DATA_PULL_UP:
if current == 1:
# data pulled up, the length of this pull up will determine whether it is 0 or 1
current_length = 0
state = STATE_DATA_PULL_DOWN
continue
else:
continue
if state == STATE_DATA_PULL_DOWN:
if current == 0:
# pulled down, we store the length of the previous pull up period
lengths.append(current_length)
state = STATE_DATA_PULL_UP
continue
else:
continue
return lengths
def __calculate_bits(self, pull_up_lengths):
# find shortest and longest period
shortest_pull_up = 1000
longest_pull_up = 0
for i in range(0, len(pull_up_lengths)):
length = pull_up_lengths[i]
if length < shortest_pull_up:
shortest_pull_up = length
if length > longest_pull_up:
longest_pull_up = length
# use the halfway to determine whether the period it is long or short
halfway = shortest_pull_up + (longest_pull_up - shortest_pull_up) / 2
bits = []
for i in range(0, len(pull_up_lengths)):
bit = False
if pull_up_lengths[i] > halfway:
bit = True
bits.append(bit)
return bits
def __bits_to_bytes(self, bits):
the_bytes = []
byte = 0
for i in range(0, len(bits)):
byte = byte << 1
if (bits[i]):
byte = byte | 1
else:
byte = byte | 0
if ((i + 1) % 8 == 0):
the_bytes.append(byte)
byte = 0
return the_bytes
def __calculate_checksum(self, the_bytes):
return the_bytes[0] + the_bytes[1] + the_bytes[2] + the_bytes[3] & 255
while True:
# initialize GPIOHS3 using io 11
fm.register(11, fm.fpioa.GPIOHS3, force=True)
gpio = GPIO(GPIO.GPIOHS3, GPIO.OUT)
# read data using gpio
instance = DHT11(gpio)
try:
while True:
result = instance.read()
if result.is_valid():
print("Temperature: %-3.1f C" % result.temperature)
print("Humidity: %-3.1f %%" % result.humidity)
time.sleep_ms(1000)
except Exception as e:
print(e)
总结:k210没有ADC,所以只能做这种内部有AD转换的传感器。