你可以学到或了解到:
- 最基础的气体监测项目 开发过程;
- Arduino IDE上使用ESP8266 D1 mini 的TTL连接使用Modbus方法;
- ESP8266 D1 mini不为人知的大坑。
背景介绍
由于某宝氧气检测器小一千,因此自己拼一个氧气检测器会更实惠些,并且可以根据使用条件来调整。
需求如下:
OLED小屏幕显示氧气传感器发送的数据并显示,使用电化学氧气传感器获取基础模拟或数字信号。
Methord
实验设备
- 松柏氧气传感器(S40XV氧气传感器) 使用Modbus TTL直连,不需要RS232或RS485电平转换电路,通讯距离2m
- ESP8266 D1 mini
- 0.94寸OLED12864(驱动芯片 SSD1315) (我也不明白 为什么成本比SSD1306便宜一半 性能差不多,价格却没变化)
连接方式
然后在立创EDA上画板子,白嫖PCB进行项目测试。
程序
代码部分
#include <Arduino.h>
#include <U8g2lib.h>
#include <ModbusMaster.h>
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
ModbusMaster node;
void setup() {
u8g2.begin();
Serial.begin(9600);
node.begin(255, Serial);
}
void loop() {
u8g2.firstPage();
do{
get_O2Conc();
runtime_show();
}while(u8g2.nextPage());
delay(1000);
}
void get_O2Conc(){
uint8_t temp_result;
uint16_t temp_num0;
float temp_value = 99.9;
temp_result = node.readHoldingRegisters(0x6001, 1);
delay(1000);
if (temp_result == node.ku8MBSuccess)
{
temp_num0 = node.getResponseBuffer(0);
temp_value = temp_num0/10;
int16_t x1 = 0;
int16_t y1 = 10; // 调整第一行的Y坐标位置
u8g2.setFont(u8g2_font_7x14B_mr); // 小字体 u8g2_font_t0_11b_mf
u8g2.drawStr(x1, y1, "O2 Conc.(v%)");
u8g2.setFont(u8g2_font_ncenB24_tr); // 大字体
int16_t x2 = (128 - u8g2.getStrWidth("XX.X")) / 2;
int16_t x3 = (128 + u8g2.getStrWidth("XX.X")) / 2;
int16_t y2 = 45; // 调整第二行的Y坐标位置
char oxygenString[5];
snprintf(oxygenString, sizeof(oxygenString), "%.1f", temp_value);
Serial.println(oxygenString);
u8g2.drawStr(x2, y2, oxygenString);
u8g2.setFont(u8g2_font_fub14_tr); // 小字体
u8g2.drawStr(x3, y2, "%");
}else{
u8g2.setFont(u8g2_font_7x14B_mr);
u8g2.drawStr(0,10,"null");
}
}
void runtime_show(){
unsigned long time = millis() / 1000;
unsigned int sec = time % 60;
unsigned int minute = (time / 60) % 60;
unsigned int hour = (time / 3600) % 24;
unsigned long day = time / 86400;
char timeString[20];
snprintf(timeString, sizeof(timeString), "Run %2ud %02u:%02u:%02u", day, hour, minute, sec);
u8g2.setFont(u8g2_font_7x14B_mr); // 小字体
u8g2.drawStr(0, 63, timeString);
}
备注:由于ESP8266 D1 mini串口只有一个,被氧气传感器占用,无法在arduino IDE的串口程序中显示,因此直接使用OLED调试。
Modbus部分介绍
本部分使用arduino 中的Modbus Master库处理TTL发送过来的数据。访问寄存器部分说明如下:
对应的Modbus只读的代码如下:
temp_result = node.readHoldingRegisters(0x6001, 1);
temp_num0 = node.getResponseBuffer(0);
temp_value = temp_num0/10; // 小数点有一位,因此需要除以10
snprintf(oxygenString, sizeof(oxygenString), "%.1f", temp_value); // OLED显示数据
结果与总结
运行结果正确,符合项目的基本需要,因此本mini项目完成
不足之处及总结:
- 第一版 直接使用ESP8266 D1 mini 上的USB插口供电,5V 引脚作为氧气传感器5V供电电源,然而数据读取总是错误。后检查发现,ESP8266 D1 mini 5V输出电压实际为4.6V,导致5V电化学传感器反应不完全,因此输出电压不准确。因此需要使用独立的USB供电接口。
- **ESP8266 D1 mini 无法使用软串口,因此多个UART设备会导致自动自动下载失灵,**需要单独拔插开发板后录入程序。因此推荐使用ESP8266常规开发板(非mini),然后连接合适IO口作为软串口输入串口,TXRX作为监视和程序写入串口,软串口作为数据读取串口,不会互相干扰(因此ESP8266 ESP32开发板更合适)。由于本部分并不会频繁写入程序,并且需要体积小巧,因此仍然使用ESP8266 D1 mini作为开发板。(当然ESP01s也是个不错的选择,但是本着能不焊接就不焊接,能不用其他元器件就不用元器件的原则,ESP D1 mini方案胜出,采用插母方案随时准备回收开发板)。
- ESP 8266 D1 mini 无法连接到WIFI WPA2 Enterprise. (因此校园网无法登陆,ESP32支持该功能),因此本设备无法连接到学校企业WLAN网络,只能本地跑。
文章参考:
arduino ESP8266 Modbus 通信
注释: 如果只用03读取,可以参考本案例进行,使用更佳。
松柏氧气传感器 0-30%(体积比)