文章总结: 本文介绍基于ESP32-C6的智能鱼缸监测仪制作过程,集成高精度温度与气压传感器及圆形LCD屏,实现水温、气压及溶氧量实时显示。项目采用ESP-IDF与FreeRTOS开发,通过I2C与SPI接口通信,利用均值滤波与插值算法计算溶氧量,并展示了PCB设计与核心代码实现,为IoT爱好者提供技术参考。 综合评分: 83 文章分类: 解决方案,其他
IoT爱好者,新手养鱼必备!基于ESP32手搓智能鱼缸:水体温度、大气压强、溶氧量,动态加热、降温或加氧一应俱全
原创
.
IoT物联网技术
2026年1月6日 08:22 北京
文末联系小编,获取项目源码
趁着元旦大促,作为长期空军的钓鱼佬,小编终于入手了一套鱼缸、10条斑马鱼,成功转型新手养鱼人,日常生活的格调一下子就起来了。
同时,作为IoT物联网爱好者,小编利用三天假期,基于乐鑫ESP32手搓了一台温度-气压-水体溶氧量显示仪,可以实时掌握水体温度、大气压强、水体溶氧量,为养鱼提供参考,自动实现水体加热、降温或加氧。未来智能鱼缸项目还会实现自动换水、氛围灯和自动喂食等功能。
-
主控SEEED XIAO ESP32-C6:一款基于两个 32 位 RISC-V 处理器构建的高性能主控芯片。该芯片具有 512KB SRAM 和 4 MB Flash,为物联网控制场景提供了丰富的编程空间和强大的处理能力。
-
温度传感器 NST461-DQNR:一款高精度且低功耗的数字温度传感器,基于 CMOS 工艺晶体管 PN 结的温度效应,分辨率高达 0.0625°C。除了具有高精度的本地温度测量能力外,该传感器还支持通过外部晶体管进行远程温度测量。其远程测量功能主要通过外部低成本晶体管或二极管实现。
-
绝压传感器 NSPAD1N200DR04:一款经过精确校准的绝对压力传感器,采用汽车级专用集成电路(ASIC)对 MEMS 传感器元件进行校准和补偿,能够将 10千帕到40万帕 的压力信号转换为 SPI/I2C 输出信号。
-
圆形LCD 屏幕 GC9A01:提供高分辨率240×240 IPS显示效果,是需要圆形显示器应用的理想选择。该模块专为高要求的工作环境设计,具有卓越的性能、持久的耐用性,并且可以轻松集成到各种系统中。
温度-气压-水体溶氧量显示仪基于ESP32-C6作为主控,采用ESP-IDF+Freertos进行开发,保证多任务的实时执行通过I2C接口连接两个传感器,其中I2C需要使用外部电阻进行上拉保证信号读取稳定性,主控还进行传感器数据读取与滤波、溶氧量计算,然后通过SPI接口连接LCD屏幕,控制LCD进行显示。
PCB设计上,根据圆形LCD屏幕的尺寸,将PCB外框设置为圆形。将两个传感器放置在边缘,尤其是温度传感器。其中温度传感器附近不进行铺铜,减少因其他元件导热影响温度测量。
程序首先进行初始化,包括LCD、LVGL、I2C、NST461的初始化,并创建多个任务。
- NST461任务:周期读取本地和远端温度数据,由于跳变严重,对数据进行了均值滤波;随后通过LVGL显示数据,并通过消息队列发布数据;
- NSPAD1N任务:周期读取气压数据,并通过LVGL显示;同样通过消息队列发布数据;
- 溶氧量计算任务:通过消息队列等待温度和气压数据,通过插值计算得到溶氧量并显示;同时对于异常数据,进行警报。
NST461设置远端温度偏移值:由于远端温度使用三极管,不同的三极管具有不同的特性,需要根据实际情况设置偏移值。计算得到后,写入对应地址即可,如下:
esp_err_t nst461_set_offset_factor(){ // 根据测量结果,选取的三极管温差为+13.0℃,需要减去这么多 // 因为是减去,需要使用~进行取反 // 比例系统选取1不变 // -13.0 = -13 + (0)*0.0625 data_wr[0] = ~0x0D; data_wr[1] = ~0x00; i2c_bus_write_bytes(handler, NST461_OFFSET_H_ADDR, 1, data_wr); i2c_bus_write_bytes(handler, NST461_OFFSET_L_ADDR, 1, data_wr + 1);
return ESP_OK;}
NST461温度读取并滤波:读取到本地和远端数据后,进行滤波防止温度跳变严重。
esp_err_t nst461_get_senser_dat(float *lt, float *rt){ // 读取本地温度 uint8_t ltemp[2]; if (i2c_bus_read_bytes(handler, 0x00, 1, ltemp) != ESP_OK) return ESP_FAIL; if (i2c_bus_read_bytes(handler, 0x15, 1, ltemp + 1) != ESP_OK) return ESP_FAIL; float local_temp = (float)ltemp[0] + (float)(ltemp[1] >> 4) * 0.0625;
// 读取远程温度 uint8_t rtemp[2]; if (i2c_bus_read_bytes(handler, 0x01, 1, rtemp) != ESP_OK) return ESP_FAIL; if (i2c_bus_read_bytes(handler, 0x10, 1, rtemp + 1) != ESP_OK) return ESP_FAIL; float remote_temp = (float)rtemp[0] + (float)(rtemp[1] >> 4) * 0.0625;
// 应用移动平均滤波器 local_temp = moving_average_filter(local_temp, &local_temp_filter); remote_temp = moving_average_filter(remote_temp, &remote_temp_filter);
// 记录结果 ESP_LOGI(NST461_TAG, "Local Temp: %.2f C, Remote Temp: %.2f C", local_temp, remote_temp);
// 通过指针返回结果 *lt = local_temp; *rt = remote_temp;
return ESP_OK; // 成功时返回ESP_OK}
NSPAD1N读取气压数据:读取到原始数据后,需要通过计算得到准确的气压值。
/*——— 读取压力(kPa)———*/esp_err_t nspad1n_get_senser_dat(float *pressure){ if (pressure == NULL) { ESP_LOGE(NSPAD1N_TAG, "pressure out ptr is null"); return ESP_ERR_INVALID_ARG; } if (handler == NULL) { ESP_LOGE(NSPAD1N_TAG, "I2C handler not initialized"); return ESP_FAIL; }
/* 触发一次测量(如果芯片需要) */ data_wr[0] = 0x0A; // 具体启动命令以手册为准 esp_err_t err = i2c_bus_write_bytes(handler, NSPAD1N_REG_CMD, 1, data_wr); if (err != ESP_OK) { ESP_LOGE(NSPAD1N_TAG, "write CMD failed: %d", err); return err; }
/* 轮询等待就绪 */ uint8_t retries = NSPAD1N_POLL_RETRIES; while (retries--) { err = i2c_bus_read_bytes(handler, NSPAD1N_REG_CMD, 1, data_wr); if (err != ESP_OK) { ESP_LOGE(NSPAD1N_TAG, "read STATUS failed: %d", err); return err; } if ((data_wr[0] & NSPAD1N_STATUS_READY) == NSPAD1N_STATUS_READY) { break; } vTaskDelay(pdMS_TO_TICKS(NSPAD1N_POLL_DELAY_MS)); } if (retries == 0) { ESP_LOGE(NSPAD1N_TAG, "read timeout"); return ESP_ERR_TIMEOUT; }
/* 读取 24bit 原始压力数据 */ uint8_t raw[3]; err = i2c_bus_read_bytes(handler, NSPAD1N_REG_PRESS_MSB, 3, raw); if (err != ESP_OK) { ESP_LOGE(NSPAD1N_TAG, "read pressure failed: %d", err); return err; }
/* 组装为 24 位并做符号扩展到 int32 */ uint32_t u24 = ((uint32_t)raw[0] << 16) | ((uint32_t)raw[1] << 8) | (uint32_t)raw[2]; int32_t s24 = (u24 & 0x00800000U) ? (int32_t)(u24 | 0xFF000000U) : (int32_t)u24;
/* 标定换算(按手册/实测调整 A、B) */ const float A = 231.250021f; const float B = -8.125010f; const float FS = 8388607.0f; // 2^23 - 1 *pressure = A * ((float)s24 / FS) + B;
ESP_LOGI(NSPAD1N_TAG, "P: %.1f kPa", *pressure); return ESP_OK;}
溶氧量计算:等待温度和气压数据后,通过插值的方式计算得到理论的氧溶解度。
// 任务:计算溶氧量void oxygen_task(void *arg){ static char sdat[50]; // 标准大气压101.325 kPa下的氧溶解度,温度0-40°, const float Rou_O2[41] = { 14.62, 14.22, 13.83, 13.46, 13.11, 12.77, 12.45, 12.14, 11.84, 11.56, 11.29, 11.03, 10.78, 10.54, 10.31, 10.08, 9.87, 9.66, 9.47, 9.28, 9.09, 8.91, 8.73, 8.56, 8.42, 8.26, 8.11, 7.97, 7.83, 7.69, 7.56, 7.43, 7.30, 7.18, 7.07, 6.95, 6.84, 6.73, 6.63, 6.53, 6.43 }; // 饱和水蒸汽压力,温度0-40° const float p_w[41] = { 0.61, 0.66, 0.71, 0.76, 0.81, 0.87, 0.93, 1.00, 1.07, 1.15, 1.23, 1.31, 1.40, 1.49, 1.60, 1.71, 1.81, 1.93, 2.07, 2.20, 2.81, 2.99, 3.17, 3.36, 3.56, 3.77, 4.00, 4.24, 4.49, 4.76, 5.02, 5.32, 5.62, 5.94, 6.28, 6.62, 6.98, 2.81, 2.99, 3.17, 7.37 }; // 计算公式,不同温度和气压下的氧溶解度 // Rou = Rou_O2[t] * (p - p_w[t]) / (101.325 - p_w[t]) // 其中t是温度,p是当前压强 float t = 20; // 设置目标温度 float p = 101.325; // 设置当前压力 while(1) { xQueueReceive(pressure_queue, &p, portMAX_DELAY); xQueueReceive(temp_queue, &t, portMAX_DELAY);
// 确保温度在0到40度之间 if(t < 0) t = 0; if(t > 39) t = 39; // 获取温度下的低点和高点 int t_floor = (int)t; // 向下取整的温度值 int t_ceil = t_floor + 1; // 向上取整的温度值
// 进行线性插值计算氧溶解度 float Rou_O2_interp = Rou_O2[t_floor] + (t - t_floor) * (Rou_O2[t_ceil] - Rou_O2[t_floor]); // 进行线性插值计算水蒸气压力 float p_w_interp = p_w[t_floor] + (t - t_floor) * (p_w[t_ceil] - p_w[t_floor]); // 计算最终的氧溶解度(氧气浓度) float Rou = Rou_O2_interp * (p - p_w_interp) / (101.325 - p_w_interp); // 显示在屏幕上 snprintf(sdat, 50, "%.1f mg/L", Rou); lv_label_set_text(ui_Lo2, sdat); lv_slider_set_value(ui_So2, (int16_t)(Rou*10), LV_ANIM_ON); }}
3D打印的外壳组装实物效果
原文地址:
https://www.eetree.cn/project/detail/4691
如有IoT 源码采购和项目交付需求,请扫码联系小编,微信号: beacon0418
往期推荐
☞开箱即用!国产开源30+AI视觉算法IoT智能物联网云平台
☞国产开源Web 工业IoT组态软件,支持Modbus、OPC,支持拖拉拽
☞源码交付,7天完成国产信创部署智慧工地方案
☞4万元,国产信创私有化部署,破解县域无人机AI巡检平台落地难题
☞上班摸鱼, 智能AI 监控老板行踪
免责声明:本公众号所发布的内容来源于互联网,我们会尊重并维护原作者的权益。由于信息来源众多,若文章内容出现版权问题,或文中使用的图片、资料、下载链接等,如涉及侵权,请告知我们,我们将尽快处理。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:IoT物联网技术 .《IoT爱好者,新手养鱼必备!基于ESP32手搓智能鱼缸:水体温度、大气压强、溶氧量,动态加热、降温或加氧一应俱全》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。












评论