学物联网,来万物简单IoT物联网!!
当遇到物联网、嵌入式、硬件等技术的时候,大家在脑海中就会构画出一些列复杂的技术框架内容,各种复杂的编译环境、下载环境搭建,市场上五花八门硬件设备、硬件开发板,而且学习的知识全网遍地都是,质量参差不齐,知识点非常散,让开发者无从下手,望而却步,然后就放弃了。
万物简单物联网教育团队长期致力于智能硬件的设计和研发,也一直关注物联网教育的这些问题,为了更好的解决它,团队搭建了一套一站式专业的物联网教学平台,便利于开发者和创客们学习和创作,团队成员均有15年以上的智能硬件设计和开发的经验,对物联网有独特的见解。
万物简单物联网教育开发板ETT-B1,选择当前市面热度高出货量大的ESP32作为核心板,即为大众所认知,也可消除客户后续大批量生产需要保证货源的后顾之忧;开发语言选择了MicroPython,是Python3语言的精简实现,可以非常灵活的运行在资源受限的MCU之上。选择MicroPython作为开发语言有一下几个原因:
万物简单物联网教育开发板ETT-B1选用了ESP32为核心板,同时支持3.7V的锂电池供电,Micro USB支持代码的下载和锂电池的充电能力,内置丰富的硬件资源:按键、led指示灯、无源蜂鸣器、OLED显示、MPU6050六轴陀螺仪、AHT10温湿度以及13个可扩展编程的IO接口等。
电气特性:
按键名称 | 编程引脚号 | 描述 | 其他 |
---|---|---|---|
IO0 | 0 | 可编程按键,开发者可以直接使用 | ESP32启动的时候由IO0和IO2选择系统启动的模式 |
EN | - | 复位按键,不可编程,按下系统会复位重启 | - |
下载启动模式要确保IO0和IO2都为电平,IO0高电平为SPI启动模式。
EN是ESP32内部3.3V稳压器的启用引脚,它被拉高。当接地时就会禁用3.3V的稳压器,所以当EN引脚出现低高上升沿电平就会重新启动系统。
ETT-B1开发板支持自动下载系统程序的能力。
指示灯名称 | 编程引脚号 | 描述 | 其他 |
---|---|---|---|
绿灯 | 14 | 高电平点亮,低电平熄灭 | |
蓝灯 | 13 | 高电平点亮,低电平熄灭 |
开发板支持2个可编程led指示灯绿灯和蓝灯。
编程引脚号 | 描述 | 其他 |
---|---|---|
27 | 低电平蜂鸣器导通,PWM控制 | 无源蜂鸣器需要PWM驱动 |
无源的蜂鸣器需要PWM控制,所以通过控制PWM的占空比,就可以发出不同的声音,这是无源蜂鸣器和有源的区别所在,有源只需要高低电平即可触发蜂鸣器的响声,但是发声频率只有一种。
引脚名称 | 编程引脚号 | 描述 | 其他 |
---|---|---|---|
SDA | 25 | I2C的数据信号线 | 通信地址 0x3c |
SCL | 26 | I2C的时钟信号线 |
使用I2C与OLED通信,显示驱动芯片为SSD1306,通信地址是0x68
引脚名称 | 编程引脚号 | 描述 | 其他 |
---|---|---|---|
SDA | 25 | I2C的数据信号线 | 通信地址 0x68 |
SCL | 26 | I2C的时钟信号线 |
使用I2C与MPU6050六轴陀螺仪通信,通信地址是0x68
引脚名称 | 编程引脚号 | 描述 | 其他 |
---|---|---|---|
SDA | 25 | I2C的数据信号线 | 通信地址 0x38 |
SCL | 26 | I2C的时钟信号线 |
使用I2C与AHT20温湿度传感器通信,通信地址是0x38
序号 | 引脚名称 | 编程引脚号 | 描述 | 其他 |
---|---|---|---|---|
1 | 5V | - | 提供5V电源 | |
2 | IO33 | 33 | ADC1-CH5\PWM | 输入输出 |
3 | IO32 | 32 | ADC1-CH4\PWM | 输入输出 |
4 | IO34 | 34 | ADC1-CH6 | 仅作输入引脚 |
5 | IO2 | 2 | ADC2-CH2\PWM | 输入输出 |
6 | IO4 | 4 | ADC2-CH0\PWM | 输入输出 |
7 | GND | - | 供地连接 | |
8 | IO16 | 16 | UART2_RXD\PWM | 输入输出 |
9 | IO17 | 17 | UART2_TXD\PWM | 输入输出 |
10 | IO18 | 18 | SPI3_CLK\PWM | 输入输出 |
11 | IO19 | 19 | SPI3_MISO\PWM | 输入输出 |
12 | IO21 | 21 | I2C_SDA\PWM | 输入输出 |
13 | IO22 | 22 | I2C_SCL\PWM | 输入输出 |
14 | IO23 | 23 | SPI3_MOSI\PWM | 输入输出 |
15 | GND | - | 供地连接 | |
16 | 3V3 | - | 提供3V3电源 |
可扩展编程IO除34引脚外,其他都可以用作GPIO输入输出以及PWM控制输出;
ESP32默认的I2C引脚为21/22,其他输入输出引脚也可以用作SCL或SDA,但是不推荐随意使用。
IO0按键编程示例代码
from machine import Pin
import utime
#按键初始化函数
def keyInit():
keyObj=Pin(0,Pin.IN,Pin.PULL_UP) #构建KEY对象
keyObj.irq(keyCB,Pin.IRQ_FALLING) #定义中断,下降沿触发
#按键中断回调函数
def keyCB(obj):
utime.sleep_ms(10) #消除抖动
if obj.value()==0: #确认按键被按下
print("key press down")
if __name__ == '__main__':
keyInit()
while True:
utime.sleep(1)
运行结果:
#当IO0按键时,出现一次key press down
key press down
key press down
key press down
led引脚说明
指示灯名称 | 编程引脚号 | 描述 | 其他 |
---|---|---|---|
绿灯 | 14 | 高电平点亮,低电平熄灭 | |
蓝灯 | 13 | 高电平点亮,低电平熄灭 |
led指示灯编程示例代码
from machine import Pin
import utime
ledblueObj = None
ledgreenObj = None
#led指示灯初始化函数
def ledInit():
global ledblueObj,ledgreenObj
ledblueObj=Pin(13,Pin.OUT) #构建led对象,GPIO13,输出
ledgreenObj=Pin(14,Pin.OUT) #构建led对象,GPIO14,输出
ledblueObj.value(1) #蓝灯点亮
ledgreenObj.value(1) #绿灯点亮
utime.sleep_ms(300)
ledblueObj.value(0) #蓝灯熄灭
ledgreenObj.value(0) #绿灯熄灭
if __name__ == '__main__':
ledInit()
while True:
ledblueObj.value(1)
utime.sleep(0.5)
ledblueObj.value(0)
ledgreenObj.value(1)
utime.sleep(0.5)
ledgreenObj.value(0)
运行结果:
led指示灯蓝绿交替闪烁
编程引脚号 | 描述 | 其他 |
---|---|---|
27 | 蜂鸣器低电平导通,PWM控制 | 无源蜂鸣器需要PWM驱动 |
无源蜂鸣器是靠PWM脉冲波形驱动发声。
无源蜂鸣器编程示例代码
from machine import Pin,PWM
import utime
pwmObj = None
#pwm初始化函数
def pwmInit():
global pwmObj
pwmObj=PWM(Pin(27),Pin(27).OUT) #构建led对象,GPIO27,输出
print(pwmObj)
#设置PWM频率
pwmObj.freq(100) #range 1Hz-40MHz
print(pwmObj)
utime.sleep(0.2)
#设置PWM占空比
pwmObj.duty(100) #range 0-1023 (default 512, 50%)
utime.sleep(0.2)
print(pwmObj)
if __name__ == '__main__':
pwmInit()
pwmObj.deinit() #关闭pwm,再使用pwm,必须重新初始化
while True:
utime.sleep(0.5)
运行结果:
PWM(27, freq=3, duty=512)
PWM(27, freq=100, duty=512)
PWM(27, freq=100, duty=100)
引脚名称 | 编程引脚号 | 描述 | 其他 |
---|---|---|---|
SDA | 25 | I2C的数据信号线 | 通信地址 0x3c |
SCL | 26 | I2C的时钟信号线 |
OLED编程示例代码
from machine import Pin,SoftI2C
import utime
from ssd1306 import SSD1306_I2C
i2cObj = None
oledObj = None
#OLED初始化函数
def OLEDInit():
global i2cObj,oledObj
i2cObj = SoftI2C(sda=Pin(25), scl=Pin(26)) # 创建i2c对象
oledObj = SSD1306_I2C(128, 64, i2cObj, i2cAddr=0x3c) # 创建ssd1306对象
oledObj.fill(0) #清屏背景黑色
oledObj.text(str('----------------------'),3,5)
oledObj.text('welcome ETT-B1', 3, 22)
oledObj.text('ettPython', 30, 38)
oledObj.text(str('----------------------'),3,55)
oledObj.show() # 屏幕显示
if __name__ == '__main__':
OLEDInit()
while True:
utime.sleep(0.5)
运行结果:
#oled 屏上显示
----------------------
welcome ETT-B1
ettPython
----------------------
引脚名称 | 编程引脚号 | 描述 | 其他 |
---|---|---|---|
SDA | 25 | I2C的数据信号线 | 通信地址 0x68 |
SCL | 26 | I2C的时钟信号线 |
六轴陀螺仪编程示例代码
from machine import Pin,SoftI2C
import utime
from mpu6050 import MPU6050
i2cObj = None
mpu6050Obj = None
#mpu6050初始化函数
def mpu6050Init():
global i2cObj,mpu6050Obj
i2cObj = SoftI2C(sda=Pin(25), scl=Pin(26)) # 创建i2c对象
mpu6050Obj = MPU6050(i2cObj, i2cAddr=0x68) # 创建mpu6050对象
def getData():
temp = mpu6050Obj.getTemperature() #获取mpu6050芯片温度
acc = mpu6050Obj.getAcceleration() #获取mpu6050加速度值
gy = mpu6050Obj.getGyroscope() #获取mpu6050陀螺仪值
return temp,acc,gy
if __name__ == '__main__':
mpu6050Init()
while True:
utime.sleep(1)
print(getData())
运行结果:
22.88 (1138, 132, 15470) (-36, -43, -35)
22.88 (1164, 140, 15466) (-37, -44, -35)
22.88 (1152, 132, 15496) (-37, -42, -38)
22.9 (1190, 146, 15514) (-38, -43, -37)
22.89 (1176, 96, 15408) (-37, -44, -37)
22.9 (1230, 86, 15484) (-38, -44, -35)
22.89 (1164, 126, 15520) (-37, -44, -35)
22.91 (1222, 212, 15496) (-37, -42, -37)
22.91 (1188, 194, 15448) (-37, -43, -38)
引脚名称 | 编程引脚号 | 描述 | 其他 |
---|---|---|---|
SDA | 25 | I2C的数据信号线 | 通信地址 0x38 |
SCL | 26 | I2C的时钟信号线 |
AHT10温湿度传感器编程示例代码
from machine import Pin,SoftI2C
import utime
from aht10 import AHT10
i2cObj = None
aht10Obj = None
#AHT10初始化函数
def aht10Init():
global i2cObj,aht10Obj
i2cObj = SoftI2C(sda=Pin(25), scl=Pin(26)) # 创建i2c对象
aht10Obj = AHT10(i2cObj, i2cAddr=0x38) # 创建AHT10对象
def getData():
temp = aht10Obj.temperature()
humidity = aht10Obj.humidity()
return temp,humidity
if __name__ == '__main__':
aht10Init()
while True:
utime.sleep(1)
print(getData())
运行结果:
(21.66348, 62.28437)
(21.66615, 62.2571)
(21.63677, 62.27026)
(21.63696, 62.19616)
(21.60816, 62.10594)
(21.62685, 62.11996)
(21.60797, 62.15734)
import time,network
def WIFI_Connect(ssid,pwd):
wlan = network.WLAN(network.STA_IF) #STA模式
wlan.active(True) #激活接口
start_time=time.time() #记录时间做超时判断
if not wlan.isconnected():
print('connecting to network...')
wlan.connect(ssid, pwd) #输入WIFI账号密码
while not wlan.isconnected():
#超时判断,15秒没连接成功判定为超时
if time.time()-start_time > 15 :
print('WIFI Connected Timeout!')
break
if wlan.isconnected():
global oled
#串口打印信息
print('network information:', wlan.ifconfig())
return True
else:
return False
def connent_server(ssid,pwd):
global client
if WIFI_Connect(ssid,pwd):
print('Wifi connect success!')
connent_server('路由器SSID','路由器密码')
from ible import GATT_BLE
import time
bt = None
bleStatus = 0
def connected_event():
global bleStatus
print('ble conn')
bleStatus = 1
def disconnected_event():
bleStatus = 0
print('ble dis event ')
bt.ettAdvertiser()
def ble_event_cb(event, data):
send_data = []
if event == 1:
'''Central disconnected'''
connected_event()
elif event == 2:
'''Central disconnected'''
disconnected_event()
elif event == 3:
'''New message received'''
print('data recv ')
buffer = bt.ettBleRecv()
if buffer[0] == 0xaa and buffer[1] == 0x55 :
print("data is ok")
if buffer[2] == 0x00:
print('start auth')
send_data = [0xaa,0x55,0x00,0x00,0x00]
bt.ettBleSend(bytes(send_data))
elif buffer[2] == 0x01:
print('auth resp')
send_data = [0xaa,0x55,0x01,0x00,0x00]
bt.ettBleSend(bytes(send_data))
elif buffer[2] == 0x10:
print('data proc')
if buffer[3] == 0x00:
print('LED off')
ledblueObj.value(0)
send_data = [0xaa,0x55,0x10,0x00,0x00]
bt.ettBleSend(bytes(send_data))
elif buffer[3] == 0x01:
print('LED on')
ledblueObj.value(1)
send_data = [0xaa,0x55,0x10,0x01,0x00]
bt.ettBleSend(bytes(send_data))
else:
print("data is error")
def ble_init():
global bt
print('init ble')
bt = GATT_BLE("ETT-Python",ble_event_cb)
print('init ble finish')
if __name__ == '__main__':
ble_init()
while True:
time.sleep(1)
import time,network,ujson
from ssd1306 import SSD1306_I2C
from machine import Pin,SoftI2C,Timer
from umqtt import simple
i2cObj = None
oledObj = None
clientObj = None
#OLED初始化函数
def OLEDInit():
global i2cObj,oledObj
i2cObj = SoftI2C(sda=Pin(25), scl=Pin(26)) # 创建i2c对象
oledObj = SSD1306_I2C(128, 64, i2cObj, i2cAddr=0x3c) # 创建ssd1306对象
oledObj.fill(0) #清屏背景黑色
oledObj.text(str('----------------------'),3,5)
oledObj.text('welcome ETT-B1', 3, 22)
oledObj.text('ettPython', 30, 38)
oledObj.text(str('----------------------'),3,55)
oledObj.show() # 屏幕显示
def WifiConnect(ssid,pwd):
wlan = network.WLAN(network.STA_IF) #STA模式
wlan.active(True) #激活接口
start_time=time.time() #记录时间做超时判断
if not wlan.isconnected():
print('connecting to network...')
wlan.connect(ssid, pwd) #输入WIFI账号密码
while not wlan.isconnected():
#超时判断,15秒没连接成功判定为超时
if time.time()-start_time > 15 :
print('WIFI Connected Timeout!')
break
if wlan.isconnected():
#串口打印信息
print('network information:', wlan.ifconfig())
#OLED数据显示(如果没接OLED,请将下面代码屏蔽)
oledObj.fill(0) #清屏背景黑色
oledObj.text('IP/Subnet/GW:',0,0)
oledObj.text(wlan.ifconfig()[0], 0, 20)
oledObj.text(wlan.ifconfig()[1],0,38)
oledObj.text(wlan.ifconfig()[2],0,56)
oledObj.show()
return True
else:
return False
def MQTTCallback(topic,msg):
parse = ujson.loads(msg)
print(parse["onoff"])
if parse["onoff"] == 1:
print('LED ON')
elif parse["onoff"] == 0:
print('LED OFF')
def MQTTRev(tim):
clientObj.check_msg()
def connentServer(ssid,pwd):
global clientObj
if WifiConnect(ssid,pwd):
SERVER = 'MQTT服务器地址'
PORT = MQTT端口
CLIENT_ID = '' # 客户端ID
TOPIC = '' # TOPIC名称
USER = '' # 用户名
PASSWORD = '=' # 密码
clientObj = simple.MQTTClient(CLIENT_ID, SERVER, PORT,USER,PASSWORD) #建立客户端对象
clientObj.set_callback(MQTTCallback) #配置回调函数
clientObj.connect()
clientObj.subscribe(TOPIC) #订阅主题
tim = Timer(-1)
tim.init(period=300, mode=Timer.PERIODIC,callback=MQTTRev)
if __name__ == '__main__':
OLEDInit()
connentServer('路由器SSID','路由器密码')
while True:
time.sleep(1)
ETT-B1开发板整体验证代码
import utime
import urandom
from machine import Pin,SoftI2C,PWM
from ssd1306 import SSD1306_I2C
from mpu6050 import MPU6050
from aht10 import AHT10
ledblueObj = None
ledgreenObj = None
pwmObj = None
i2cObj = None
oledObj = None
mpu6050Obj = None
aht10Obj = None
#按键初始化函数
def keyInit():
keyObj=Pin(0,Pin.IN,Pin.PULL_UP) #构建KEY对象
keyObj.irq(keyCB,Pin.IRQ_FALLING) #定义中断,下降沿触发
#按键中断回调函数
def keyCB(obj):
utime.sleep_ms(10) #消除抖动
if obj.value()==0: #确认按键被按下
print("key press down")
#led指示灯初始化函数
def ledInit():
global ledblueObj,ledgreenObj
ledblueObj=Pin(13,Pin.OUT) #构建led对象,GPIO13,输出
ledgreenObj=Pin(14,Pin.OUT) #构建led对象,GPIO14,输出
ledblueObj.value(0) #蓝灯熄灭
ledgreenObj.value(0) #绿灯熄灭
#pwm初始化函数
def pwmInit():
global pwmObj
pwmObj=PWM(Pin(27),Pin(27).OUT) #构建led对象,GPIO27,输出
#设置PWM占空比
pwmObj.duty(0) #range 0-1023 (default 512, 50%)
utime.sleep(0.2)
#OLED初始化函数
def OLEDInit():
global i2cObj,oledObj
i2cObj = SoftI2C(sda=Pin(25), scl=Pin(26)) # 创建i2c对象
oledObj = SSD1306_I2C(128, 64, i2cObj, i2cAddr=0x3c) # 创建ssd1306对象
oledObj.fill(0) #清屏背景黑色
oledObj.text(str('----------------------'),3,5)
oledObj.text('welcome ETT-B1', 3, 22)
oledObj.text('ettPython', 30, 38)
oledObj.text(str('----------------------'),3,55)
oledObj.show() # 屏幕显示
#mpu6050初始化函数
def mpu6050Init():
global i2cObj,mpu6050Obj
mpu6050Obj = MPU6050(i2cObj, i2cAddr=0x68) # 创建mpu6050对象
def testMpu6050():
global oledObj
temp = mpu6050Obj.getTemperature() #获取mpu6050芯片温度
acc = mpu6050Obj.getAcceleration() #获取mpu6050加速度值
gy = mpu6050Obj.getGyroscope() #获取mpu6050陀螺仪值
oledObj.fill(0) #清屏背景黑色
oledObj.text('mpu6050 test', 8, 5)
oledObj.text('ax:'+'{:.1f}'.format(acc[0]),8,20)
oledObj.text('ay:'+'{:.1f}'.format(acc[1]),8,38)
oledObj.text('az:'+'{:.1f}'.format(acc[2]),8,56)
oledObj.show()
#AHT10初始化函数
def aht10Init():
global i2cObj,aht10Obj
aht10Obj = AHT10(i2cObj, i2cAddr=0x38) # 创建AHT10对象
def testAht10():
temp = aht10Obj.temperature()
humidity = aht10Obj.humidity()
oledObj.fill(0) #清屏背景黑色
oledObj.text('ath10 test', 5, 5)
oledObj.text('T&H:'+'{:.1f}'.format(temp)+' '+'{:.1f}'.format(humidity), 5, 20)
oledObj.show()
return temp,humidity
if __name__ == '__main__':
keyInit()
ledInit()
pwmInit()
OLEDInit()
mpu6050Init()
aht10Init()
while True:
val = (int)(urandom.random())
print(val)
ledblueObj.value(1)
utime.sleep(0.5)
ledblueObj.value(0)
ledgreenObj.value(1)
utime.sleep(0.5)
ledgreenObj.value(0)
pwmObj.freq(1000+val)
pwmObj.duty(200+val)
utime.sleep(0.5)
pwmObj.freq(2000+val)
pwmObj.duty(800+val)
utime.sleep(0.5)
pwmObj.duty(0)
utime.sleep(0.5)
testMpu6050()
utime.sleep(1)
testAht10()
utime.sleep(1)
链接