内容介绍
内容介绍
简介
基于Arduino NANO-33 BLE Sense开发板实现了一个微型环境监测站,可以检测周围温度、湿度、气压、光强和噪声,然后通过BLE功能将数据给手机,在手机微信小程序上接收数据并展示。
主要功能及代码片段
Arduino提供了丰富的例程和便捷的API,并对开发流程做了极大简化。只需要实现初始化和大循环两个函数。
void onPDMdata() {
int bytesAvailable = PDM.available();
if(bytesAvailable == MICROPHONE_BUFFER_SIZE_IN_BYTES)
{
PDM.read(microphoneBuffer, bytesAvailable);
microphoneBufferReadyFlag = true;
}
}
void setup() {
//Serial.begin(9600);
//while (!Serial);
if (!HTS.begin()) {
Serial.println("Failed to initialize humidity temperature sensor!");
while (1);
}
if (!BARO.begin()) {
Serial.println("Failed to initialize pressure sensor!");
while (1);
}
if (!APDS.begin()) {
Serial.println("Error initializing APDS9960 sensor.");
while (true);
}
PDM.onReceive(onPDMdata);
if (!PDM.begin(1, 16000)) {
Serial.println("Failed to start PDM!");
while (1);
}
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}
BLE.setLocalName("EnvironmentMonitor");
BLE.setAdvertisedService(envMonitorService);
envMonitorService.addCharacteristic(temperatureChar);
envMonitorService.addCharacteristic(humidityChar);
envMonitorService.addCharacteristic(pressureChar);
envMonitorService.addCharacteristic(lightIntensityChar);
envMonitorService.addCharacteristic(noiseChar);
BLE.addService(envMonitorService);
BLE.advertise();
Serial.println("Bluetooth device active, waiting for connections...");
}
初始化函数中,初始化所有需要的传感器,并开启蓝牙广播。
void updateValue()
{
float temperature = HTS.readTemperature();
if(temperatureChar.subscribed())
{
temperatureChar.writeValue(temperature);
}
float humidity = HTS.readHumidity();
if(humidityChar.subscribed())
{
humidityChar.writeValue(humidity);
}
float pressure = BARO.readPressure();
if(pressureChar.subscribed())
{
pressureChar.writeValue(pressure);
}
int r,g,b,a;
if (APDS.colorAvailable()) {
APDS.readColor(r, g, b ,a);
if(lightIntensityChar.subscribed())
{
lightIntensityChar.writeValue(a);
}
}
int16_t micMax = 0;
if(microphoneBufferReadyFlag)
{
uint16_t i;
for(i=0;i<MICROPHONE_BUFFER_SIZE_IN_WORDS;++i)
{
if(microphoneBuffer[i]>micMax)
{
micMax = microphoneBuffer[i];
}
}
if(noiseChar.subscribed())
{
noiseChar.writeValue(micMax);
}
microphoneBufferReadyFlag = false;
}
if(Serial)
{
Serial.println(temperature);
Serial.println(humidity);
Serial.println(pressure);
Serial.println(a);
Serial.println(micMax);
}
}
void loop() {
static long previousMillis = 0;
BLEDevice central = BLE.central();
if(central)
{
while (central.connected()) {
long currentMillis = millis();
if (currentMillis - previousMillis >= 200) {
previousMillis = currentMillis;
updateValue();
}
}
}
}
大循环中,当BLE连接建立后,每200ms读取更新传感器数据,并通过BLE发送通知。
微信小程序代码主要逻辑是,扫描广播设备,连接Environment Monitor,连接建立服务发现后,使能所有特征值的通知。当得到通知数据,将其处理并显示。
const app = getApp()
Page({
data: {
devices: [],
connected: false,
chs: [],
},
startScan() {
wx.onBluetoothDeviceFound((res) => {
res.devices.forEach(device => {
if (!device.name && !device.localName) {
return
}
const foundDevices = this.data.devices
const idx = inArray(foundDevices, 'deviceId', device.deviceId)
const data = {}
if (idx === -1) {
data[`devices[${foundDevices.length}]`] = device
} else {
data[`devices[${idx}]`] = device
}
this.setData(data)
})
})
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true,
success: (res) => {
console.log('startBluetoothDevicesDiscovery success', res)
},
})
},
createBLEConnection(e) {
console.log('createBLEConnection ', e)
const ds = e.currentTarget.dataset
const deviceId = ds.deviceId
const name = ds.name
wx.createBLEConnection({
deviceId,
success: (res) => {
console.log('devConnected ', res)
this.setData({
connected: true,
name,
deviceId,
})
this.getBLEDeviceServices(deviceId)
}
})
wx.stopBluetoothDevicesDiscovery()
},
closeBLEConnection() {
wx.closeBLEConnection({
deviceId: this.data.deviceId
})
this.setData({
connected: false,
chs: [],
canWrite: false,
})
},
getBLEDeviceServices(deviceId) {
wx.getBLEDeviceServices({
deviceId,
success: (res) => {
for (let i = 0; i < res.services.length; i++) {
if (res.services[i].isPrimary) {
this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
return
}
}
}
})
},
getBLEDeviceCharacteristics(deviceId, serviceId) {
wx.getBLEDeviceCharacteristics({
deviceId,
serviceId,
success: (res) => {
console.log('getBLEDeviceCharacteristics success', res.characteristics)
for (let i = 0; i < res.characteristics.length; i++) {
let item = res.characteristics[i]
if (item.properties.read) {
}
if (item.properties.write) {
}
if (item.properties.notify || item.properties.indicate) {
wx.notifyBLECharacteristicValueChange({
deviceId,
serviceId,
characteristicId: item.uuid,
state: true,
})
}
const data = {}
data[`chs[${i}]`] = {
uuid:item.uuid,
properties:'read:'+item.properties.read+',write:'+item.properties.write+',notify:'+item.properties.notify+',indicate:'+item.properties.indicate,
}
this.setData(data)
}
},
fail(res) {
console.error('getBLEDeviceCharacteristics', res)
}
})
wx.onBLECharacteristicValueChange((characteristic) => {
console.log('onBLECharacteristicValueChange ', characteristic)
switch(characteristic.characteristicId)
{
case "00008000-0000-1000-8000-00805F9B34FB":
this.setData({
temperature: "temperature:"+new DataView(characteristic.value).getFloat32(0,true),
})
break;
case "00008001-0000-1000-8000-00805F9B34FB":
this.setData({
humidity: "humidity:"+new DataView(characteristic.value).getFloat32(0,true),
})
break;
case "00008002-0000-1000-8000-00805F9B34FB":
this.setData({
pressure: "pressure:"+new DataView(characteristic.value).getFloat32(0,true),
})
break;
case "00008003-0000-1000-8000-00805F9B34FB":
let light = new DataView(characteristic.value).getInt32(0,true);
if(light > 100)
{
this.setData({
light: "ligth-Day:"+light,
})
}else
{
this.setData({
light: "ligth-Night:"+light,
})
}
break;
case "00008004-0000-1000-8000-00805F9B34FB":
let micMax = new DataView(characteristic.value).getInt32(0,true);
let k = 5;
this.setData({
noise: "noise:"+ 20*Math.log10(k*micMax),
})
break;
}
})
},
结果演示
先给板子上电,启动微信小程序,扫描到设备后建立连接,可以看到如下数据不停变化
白天
夜晚
体会
第一次使用Arduino,惊叹于其API的简单易用。以前不理解为什么Arduino用C++,C++本身过于复杂,使用C++开发不会增加Arduino使用难度么?现在使用后才发现,Arduino利用一些C++的特性,将API高度简化并使之易于理解,开发者使用C++开发中,不需要涉及C++复杂的一面。
针对这一款板子,Arduino也有支持不完善的地方。不过综合来看,Arduino真的是原型开发的利器。
附件下载
funpack8.7z
团队介绍
评论
0 / 100
查看更多