Funpack第八期-Arduino nano 33 ble sense环境监测站
任务二:环境监测站利用NANO-33 BLE的传感器, 搭建一个小型环境监测站用于监测户外环境。
标签
测试
2t _2t
更新2021-05-19
1212

一、任务目的

利用NANO-33 BLE的传感器, 搭建一个小型环境监测站用于监测户外环境。待监测的参数包括:

  • 周边环境温度(精度:±1°C, ±0.1°F)
  • 周边环境湿度(精度:±1%)
  • 大气压强(精度:±1kPa, ±0.1psi)
  • 日照强度(用于判断白天/夜晚)
  • 周边平均噪声(精度:±1dB)

二、功能介绍及实现思路:

  1. 支持:Arduino IDE工具开发,安装下面的库:

FhN5g4rSSOW2IVjT7_Uud_5m1YgK

  2. 实现的功能:

Arduino nano 33 ble sense 的BLE连接手机的蓝牙,板卡通过蓝牙发送温度、湿度、压强、颜色光照强度、环境噪声及判断黑天白天的数据,在NRF Connect APP上显示

  3. 代码:

  3.1 BLE初始化:

  Service是服务,Characteristic是特征值,蓝牙里面有多个Service,一个Service里面又包括多个Characteristic。Service和Characteristic的通用16位UUID需要自己在bluetooth官网上下载并查找,找不到就自己定义128位的UUID,然后设置特征值的UUID和properties,这里我用到了BLEread(APP上只读)和BLEnotify(数据修改就会通知)两个功能,详情可参考ArduinoBLE library

BLEService Station_Service("181A"); // BLE LED Service

// BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("181A", BLERead | BLEWrite);
BLEShortCharacteristic Temperature_BLE("2A6E", BLERead| BLENotify); // short (sint16)
BLEShortCharacteristic Fahrenheit("2A20", BLERead| BLENotify);

BLEShortCharacteristic Humidity("2A6F", BLERead| BLENotify); 

BLELongCharacteristic Pressure_BLE("2A6D", BLERead| BLENotify); //pressure
BLEStringCharacteristic Pressure_PSI("A4E649F4-4BE5-11E5-885D-FEFF819CDC9F", BLERead| BLENotify,64); //pressure

BLEStringCharacteristic ColorandLightIntensity("1648A1AE-5A8D-4544-B3CF-6C497D73E772", BLERead| BLENotify, 64);  // String, r,g,b
BLEStringCharacteristic DayorNight("1648A1AE-5A8D-4544-B3CF-6C497D73E773", BLERead| BLENotify,64); // int for ambient light

BLEStringCharacteristic microphone_BLE("590d65c7-3a0a-4023-a05a-6aaf2f22441c", BLERead| BLENotify,64);

const int ledPin = LED_BUILTIN; // pin to use for the LED

void setup() {
  Serial.begin(9600);
  while (!Serial);
  // set LED pin to output mode
  pinMode(ledPin, OUTPUT);
  // begin initialization
  if (!BLE.begin()) {
    Serial.println("starting BLE failed!");

    while (1);
  }
 if (!BARO.begin()) {
     Serial.println("Failed to initialize pressure sensor!");
     while (1);
   }
 if (!APDS.begin()) { // Initialize Colour, Proximity and Gesture sensor 
    Serial.println("Failed to initialize Colour, Proximity and Gesture Sensor!");
    while (1);
  }
if (!HTS.begin()) { // Initialize Temperature and Humidity sensor 
    Serial.println("Failed to initialize Temperature and Humidity Sensor!");
    while (1);
  }
PDM.onReceive(onPDMdata);

if (!PDM.begin(1, 16000)) {
    Serial.println("Failed to start PDM!");
    while (1);
  }
  BLE.setDeviceName("Environmental Sensing");
  BLE.setLocalName("Weather Station");

  BLE.setAdvertisedService(Station_Service);

  Station_Service.addCharacteristic(switchCharacteristic);
  Station_Service.addCharacteristic(Temperature_BLE);
  Station_Service.addCharacteristic(Fahrenheit);
  Station_Service.addCharacteristic(Pressure_BLE);
  Station_Service.addCharacteristic(Pressure_PSI);
  Station_Service.addCharacteristic(Humidity);
  Station_Service.addCharacteristic(ColorandLightIntensity);
  Station_Service.addCharacteristic(DayorNight);
  Station_Service.addCharacteristic(microphone_BLE);
  // add service
  BLE.addService(Station_Service);
  // set the initial value for the characeristic:
  switchCharacteristic.writeValue(0);
  BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);
  // start advertising
  BLE.advertise();
  Serial.println("Weather Station");
}

   3.2 读取温湿度:

  温湿度有通用的16位UUID,只需要写入数据的值,NRF Connect自动显示带上单位的数据

void ReadTemperature() {
  float temperature = HTS.readTemperature();
  short t = convertFloatToShort(temperature);
  Temperature_BLE.writeValue(t);
  Serial.print("Temperature = "); Serial.print(temperature);Serial.println("°C");
}

void ReadFahrenheit() {
  float fahrenheit = HTS.readTemperature(FAHRENHEIT);
//  short t = convertFloatToShort(fahrenheit);
  Fahrenheit.writeValue(fahrenheit*10);
  Serial.print("Fahrenheit = "); Serial.print(fahrenheit);Serial.println("°F");
}


void ReadHumidity() {
  float humidity = HTS.readHumidity();
  short t = convertFloatToShort(humidity);
  Humidity.writeValue(t);
  Serial.print("Humidity = "); Serial.print(humidity);Serial.println("%");
}

   3.3 读取压强:

  单位为PSI的压强查不到16位UUID,自己定义128位的UUID,发送数据先要把数据和单位打印成字符串,通过发送字符串可以显示

void ReadPressure_KPA() {
  float pressure = BARO.readPressure();
  short p = convertFloatToShort(pressure);
  Pressure_BLE.writeValue(p*100);
  Serial.print("Pressure = "); Serial.print(pressure);Serial.println(" kPa");
}

 void ReadPressure_PSI() {
   float pressure_psi = BARO.readPressure(PSI);
   char psi[20];
   sprintf(psi,"%fpsi",pressure_psi);  
   Pressure_PSI.writeValue(String(psi));
   Serial.print("Pressure = "); Serial.print(pressure_psi);Serial.println(" psi");
 }

   3.4 读取颜色和光照强度并判断黑天白天:

调用类里面的函数,通过比较光照强度来判断黑天白天

void ReadColor() {
  int tries = 50;
  while(APDS.colorAvailable() == 0 && tries > 0) {
    tries--;
    delay(30);
  }
  int r, g, b, c;
  APDS.readColor(r, g, b, c); // read the color and clear light intensity
  char buf[32];
  char buff[10];
  sprintf(buf, "%d,%d,%d,%d", r, g, b,c);
  
  ColorandLightIntensity.writeValue(String(buf));
  Serial.print("Color and intensity= "); Serial.println(buf);
  
if(c>40){
  sprintf(buff,"Daylight");
  DayorNight.writeValue(String(buff));
  Serial.print("DayorNight= "); Serial.println(buff);
  }
  else{
  strcpy(buff,"/0");
  sprintf(buff,"   Night");
  DayorNight.writeValue(String(buff));
  Serial.print("DayorNight= "); Serial.println(buff);
    }
}

   3.4 读取环境噪声:

  对数据均值滤波,这个不知道该怎么转成分贝,参考了冷月烟的公式,对数字麦克风不会处理,等大家的项目发布以后,再学习学习

void onPDMdata() {
  // query the number of bytes available
  int bytesAvailable = PDM.available();

  // read into the sample buffer
  PDM.read(sampleBuffer, bytesAvailable);

  // 16-bit, 2 bytes per sample
  samplesRead = bytesAvailable / 2;
}
//均值滤波
int16_t averageFilter(int16_t in_data)
{
	int32_t sum = 0;
	for(int i=0; i<9; i++)
	{
		data[i]=data[i+1];
		sum = sum + data[i];
	}
	data[9] = in_data;
	sum = sum + data[9];
	
	return(sum/10);
}

三、心得体会:

  感觉Arduino真的上手快,生态强大,C++面向对象封装的库,用起来方便快捷,有许多函数不会调用可以参考Arduino的Reference,更重要的是有很多示例,基本上可以教会你使用绝大多数的函数,但也会有许多坑需要自己解决。

APP下载

附件下载
nrf-connect.apk
4.22_Nano_33_ble_sense.ino
团队介绍
团队成员
王德慧
长春大学 通信工程
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号