项目简介
本项目基于FireBeetle ESP32-E开发板,通过模拟TDS传感器和浊度传感器采集被测溶液的对应数据,并通过WIFI将采集到的数据上传至阿里云的物联网平台,从而实现对水质的实时动态监测。
硬件介绍
FireBeetle ESP32-E是一款基于ESP-WROOM-32E双核芯片的主控板,它专为IoT设计。它支持WIFI和蓝牙双模通信并具有体积小巧、超低功耗、板载充电电路、接口易用等特性。可灵活的用于家庭物联网改装、工业物联网改装、可穿戴设备等等。通过和阿里云等物联网平台的连接,你可轻松制作出你独有的特色物联网智能家居系统。FireBeetle ESP32-E深度支ArduinoIDE编程,并且即将支持Scratch图形化编程及MicroPython编程。 DFROBOT提供了详细的在线教程和应用案例,以及上千种免焊接的Gravity接口传感器与执行器,可轻松上手制作,大幅度降低你的学习时间。
浊度传感器
浊度传感器是利用光学原理,通过液体溶液中的透光率和散射率来综合判断浊度情况。传感器内部是一个红外线对管,当光线穿过一定量的水时,光线的透过量取决于该水的污浊程度,水越污浊,透过的光就越少。光接收端把透过的光强度转换为对应的电流大小,透过的光多,电流大,反之透过的光少,电流小,再通过电阻将流过的电流转换为电压信号。
模拟TDS传感器
TDS(Total Dissolved Solids),中文名总溶解固体,又称溶解性固体总量,表明1升水中溶有多少毫克溶解性固体。一般来说,TDS值越高,表示水中含有的溶解物越多,水就越不洁净。因此,TDS值的大小,可作为反映水的洁净程度的依据之一。3.3~5.5V的宽电压供电,0~2.3V的模拟信号输出,使得这款产品兼容5V、3.3V控制系统,能非常方便的接到现成的控制系统中使用。测量用的激励源采用交流信号,可有效防止探头极化,延长探头寿命的同时,也增加了输出信号的稳定性。TDS探头为防水探头,可长期浸入水中测量。
软件简介
由于FireBeetle ESP32-E深度支持ArduinoIDE编程,并且DFROBOT提供了完善的参考例程,本次活动我选择的软件平台为Arduino+阿里云物联网平台。由于提供了完整的参考例程,仅需要对参考例程进行简单的修改便可以完成任务1中的要求。
阿里云物联网平台
阿里云->产品->物联网->物联网平台->进入控制台
选择公共实例->创建产品
输入产品名称->自定义品类->确认(其余默认即可)
设备->添加设备->选择刚创建的产品->命名设备->确认
设备->选择刚创建的设备->DeviceSecret查看->一键复制->妥善保存(代码中需填入)
产品->选择刚创建的产品->功能定义->编辑草稿
添加自定义功能->属性->功能名称->标识符(代码中需填入)->数据类型等按照自己需求填写->确认
发布上线->确认->再选择右上角的发布
产品->Topic类列表->物理型通信Topic->保存属性上报-发布和属性设置-订阅(代码中需填入)
至此阿里云平台操作基本完成,将上述步骤中需要填入代码中的信息填写到代码中的对应位置即可。
Arduino工程
参考DFRobot的官方例程SmartDHT11,对其进行了简单修改。
阿里云相关
将在阿里云操作步骤中记录下的信息填入对应的位置
/*配置WIFI名和密码*/
const char * WIFI_SSID = "WIFI_SSID";
const char * WIFI_PASSWORD = "WIFI_PASSWORD";
/*配置设备证书信息*/
String ProductKey = "you Product Key";
String ClientId = "12345";/*自定义ID*/
String DeviceName = "you Device Name";
String DeviceSecret = "you Device Secret";
/*配置域名和端口号*/
String ALIYUN_SERVER = "iot-as-mqtt.cn-shanghai.aliyuncs.com";
uint16_t PORT = 1883;
/*需要操作的产品标识符*/
String Identifier = "you Identifier";
/*需要上报和订阅的两个TOPIC*/
const char * subTopic = "you sub Topic";//****set
const char * pubTopic = "you pub Topic";//******post
连接云平台
void connectWiFi(){
Serial.print("Connecting to ");
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID,WIFI_PASSWORD);
while(WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP Adderss: ");
Serial.println(WiFi.localIP());
}
void callback(char * topic, byte * payload, unsigned int len){
Serial.print("Recevice [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < len; i++){
Serial.print((char)payload[i]);
}
Serial.println();
}
void ConnectAliyun(){
while(!client.connected()){
Serial.print("Attempting MQTT connection...");
/*根据自动计算的用户名和密码连接到Alinyun的设备,不需要更改*/
if(client.connect(myAliyun.client_id,myAliyun.username,myAliyun.password)){
Serial.println("connected");
client.subscribe(subTopic);
}else{
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
浊度传感器
void turbidity()
{
static unsigned long turbiditySampleTimepoint = millis();
if (millis() - turbiditySampleTimepoint > 1000U)
{
turbiditySampleTimepoint = millis();
sensorValue = analogRead(TurbiditySensorPin);// read the input on analog TurbiditySensorPin:
Serial.println(sensorValue); // print out the value you read:
}
}
模拟TDS
void analogTDS()
{
static unsigned long analogSampleTimepoint = millis();
if (millis() - analogSampleTimepoint > 40U) //every 40 milliseconds,read the analog value from the ADC
{
analogSampleTimepoint = millis();
analogBuffer[analogBufferIndex] = analogRead(TdsSensorPin); //read the analog value and store into the buffer
analogBufferIndex++;
if (analogBufferIndex == SCOUNT)
analogBufferIndex = 0;
}
static unsigned long printTimepoint = millis();
if (millis() - printTimepoint > 800U)
{
printTimepoint = millis();
for (copyIndex = 0; copyIndex < SCOUNT; copyIndex++)
analogBufferTemp[copyIndex] = analogBuffer[copyIndex];
averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF / 4096.0; // read the analog value more stable by the median filtering algorithm, and convert to voltage value
float compensationCoefficient = 1.0 + 0.02 * (temperature - 25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
float compensationVolatge = averageVoltage / compensationCoefficient; //temperature compensation
tdsValue = (133.42 * compensationVolatge * compensationVolatge * compensationVolatge - 255.86 * compensationVolatge * compensationVolatge + 857.39 * compensationVolatge) * 0.5; //convert voltage value to tds value
//Serial.print("voltage:");
//Serial.print(averageVoltage,2);
//Serial.print("V ");
Serial.print("TDS Value:");
Serial.print(tdsValue, 0);
Serial.println("ppm");
}
}
初始化函数
void setup()
{
Serial.begin(115200);
pinMode(TdsSensorPin, INPUT);
pinMode(TurbiditySensorPin, INPUT);
/*连接WIFI*/
connectWiFi();
/*初始化Alinyun的配置,可自动计算用户名和密码*/
myAliyun.init(ALIYUN_SERVER,ProductKey,ClientId,DeviceName,DeviceSecret);
client.setServer(myAliyun.mqtt_server,PORT);
/*设置回调函数,当收到订阅信息时会执行回调函数*/
client.setCallback(callback);
/*连接到Aliyun*/
ConnectAliyun();
}
void loop()
{
if(!client.connected()){
ConnectAliyun();
}
static unsigned long Timepoint = millis();
if (millis() - Timepoint > 1000U)
{
Timepoint = millis();
client.publish(pubTopic,("{\"id\":"+ClientId+",\"params\":{\""+TDSIdentifier+"\":"+tdsValue+",\""+TurbidityIdentifier+"\":"+sensorValue+"},\"method\":\"thing.event.property.post\"}").c_str());
}
analogTDS();
turbidity();
client.loop();
}
功能展示
实物展示
云平台数据
通过参加本次活动,我学会了通过ArduinoIDE对ESP32进行简单开发,并且学会了物联网云平台的基本使用,感谢硬禾学堂和得捷电子提供这么好的活动,也感谢所有交流群中的朋友们。