主要记录项目开发过程遇到的bug,项目进度、以及各个功能模块的实现

物联网鱼缸毕设

  • 需求
  • 一、主要硬件模块
    • 1、原理图:
      • (1)、温度传感器(18b20)
      • (2)、继电器
      • (3)、NODE MCU 、8266模块及自动下载电路、串口通信
      • 部分驱动代码:
      • 效果
      • 与网页交换数据
      • 网页端请求数据
    • 2、主要外围设备连接
      • 供电
  • 二、网页端
    • 1.WIFI配网
      • 写入网页文件地址
      • WIFI 配置部分后台代码
      • 扫描WIFI 并处理成json
      • WIFI配置处理部分
      • WIFI 配置部分网页端
      • 存储WIFI SSID、PassWord到EEPROM中
    • 2.网页数据显示、控制
    • 3、网页端数据请求
  • 项目进度

需求

关键字:物联网、网页与硬件交互、传感器数据上传、配网

智能鱼缸实现Wifi联网、网页后台控制、传感器数据上传、基本的鱼缸DIY搭建


提示:以下是本篇文章正文内容,下面案例可供参考

一、主要硬件模块

1、原理图:

(1)、温度传感器(18b20)

(2)、继电器

原理图

(3)、NODE MCU 、8266模块及自动下载电路、串口通信

8266模块

自动下载电路

使用usb接口供电兼串口下载/串口通信

板载外围的电路:

其它版本的NodeMCU板子 PCB图、和本次使用100%兼容

部分驱动代码:

#include <Arduino.h>
//单总线18b20驱动库
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 13//8266连接GPIO13即D7,Arduino连接port 2
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);void setup(void)
{Serial.begin(9600);Serial.println("Dallas Temperature IC Control Library Demo");// Start up the librarysensors.begin();
}
void loop(void)
{ // call sensors.requestTemperatures() to issue a global temperature // request to all devices on the busSerial.print("Requesting temperatures...");sensors.requestTemperatures(); // Send the command to get temperaturesSerial.println("DONE");// After we got the temperatures, we can print them here.// We use the function ByIndex, and as an example get the temperature from the first sensor only.float tempC = sensors.getTempCByIndex(0);// Check if reading was successfulif(tempC != DEVICE_DISCONNECTED_C) {Serial.print("Temperature for the device 1 (index 0) is: ");Serial.println(tempC);} else{Serial.println("Error: Could not read temperature data");}
}

效果

与网页交换数据

  else if (parm == "wd") //温度{//更新temptrue数据read_temperature();esp8266_server.send(200, "text/plain", String(temperature));}

网页端请求数据

    function wendu() {var xmlhttp;if (window.XMLHttpRequest) {xmlhttp = new XMLHttpRequest();}xmlhttp.onreadystatechange = function () {if (xmlhttp.status == 200) {document.getElementById("wd").innerHTML = xmlhttp.responseText + "℃";}}xmlhttp.open("GET", "/sjhq?sjhq=" + "wd");xmlhttp.send();}

2、主要外围设备连接

因为使用的都是模块,所以就懒得画原理图、弄封装了。这里直接记录8266端口与外围设备的接线:

NodeMcu端口 对应模块接线
D0 喂食继电器
D1 抽水电机继电器
D2 增氧继电器
D5 0.96 OLED SCL
D6 0.96 OLED SDA
D7(8266的GPIO13) 18B20数据端 (5.1K上拉电阻)
D8 灯光控制

继电器使用5v电源,光耦隔离,高电平有效。OLED使用3.3V供电。由于IO口不够使用,使用D0引脚,D0是MCU睡眠唤醒引脚,8266上电时默认会有一个跳变信号,所以继电器会动作一下,8266本来实际有效引脚就很少。

供电

推荐使用USB手机插头或者充电宝供电,不推荐使用8266板载micro usb供电

二、网页端

1.WIFI配网

主要实现步骤:ESP8266先运行在AP模式,手机或者电脑连接热点后,弹出强制门户网站(WiFi配网页面),点击网页上配网按钮,即可扫描周围全部WIFI热点,点击热点名称即可把信息输入SSID文本框,用户只需用输入密码即可。最后点击连接WIFI按钮,ESP8266收到网页的SSID、Password信息后,连接此WIFI,如果连接成功,自动跳转到主页面否则重新刷新该页面,网页上显示密码错误。

写入网页文件地址

使plantform io上传

WIFI 配置部分后台代码

 else{                          //未配置过WIFIif (wifiStatus == false) //未连接{// digitalWrite(2, LOW);WiFi_Status = "0";EEPROM.write(WiFi_State_Addr, 0);EEPROM.commit();WiFi.disconnect(true); //断开连接Serial.println("");Serial.print("Start WiFi config \n softAP starting --> ");Serial.println(AP_name);Serial.print("http://");Serial.println(url);WiFi.mode(WIFI_AP_STA); //配置为热点模式WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));WiFi.softAP(AP_name); //热点地址}}

扫描WIFI 并处理成json

//获取WiFi加密类型并返回
String wifi_type(int typecode)
{if (typecode == ENC_TYPE_NONE)return "Open";if (typecode == ENC_TYPE_WEP)return "WEP ";if (typecode == ENC_TYPE_TKIP)return "WPA ";if (typecode == ENC_TYPE_CCMP)return "WPA2";if (typecode == ENC_TYPE_AUTO)return "WPA*";return "NONE";
}//扫描WiFi,返回json
void wifiScan()
{String req_json = "";Serial.println("Scan WiFi");int n = WiFi.scanNetworks();if (n > 0){int m = 0;req_json = "{\"req\":[";for (int i = 0; i < n; i++){if ((int)WiFi.RSSI(i) >= Signal_filtering){m++;req_json += "{\"ssid\":\"" + (String)WiFi.SSID(i) + "\"," + "\"encryptionType\":\"" + wifi_type(WiFi.encryptionType(i)) + "\"," + "\"rssi\":" + (int)WiFi.RSSI(i) + "},";}}req_json.remove(req_json.length() - 1);req_json += "]}";esp8266_server.send(200, "text/json;charset=UTF-8", req_json);Serial.print("Found ");Serial.print(m);Serial.print(" WiFi!  >");Serial.print(Signal_filtering);Serial.println("dB");Serial.println("scan all wifi :");Serial.println(req_json);}
}

WIFI配置处理部分

//用于WiFi配置,接收ssid、password两个参数
void wifiConfig()
{// 判断请求是否存在这两个参数以及是否未配置if (esp8266_server.hasArg("ssid") && esp8266_server.hasArg("password") && WiFi_Status == "0"){int ssid_len = esp8266_server.arg("ssid").length();int password_len = esp8266_server.arg("password").length();// 判断ssid和密码长度是否合理if ((ssid_len > 0) && (ssid_len < 33) && (password_len > 7) && (password_len < 65)){// 把参数获得的String赋值到ssidString ssid_str = esp8266_server.arg("ssid");String password_str = esp8266_server.arg("password");const char *ssid = ssid_str.c_str();const char *password = password_str.c_str();Serial.print("SSID: ");Serial.println(ssid);Serial.print("Password: ");Serial.println(password);// 开始连接WiFiWiFi.begin(ssid, password);Serial.print("Connenting");//判断是否连接成功,8秒超时unsigned long millis_time = millis();while ((WiFi.status() != WL_CONNECTED) && (millis() - millis_time < 8000)){delay(500);Serial.print(".");}// 判断是否连接成功if (WiFi.status() == WL_CONNECTED){// 连接成功,返回1digitalWrite(2, HIGH);Serial.println("");Serial.println("Connected successfully!");Serial.print("IP Address: ");Serial.println(WiFi.localIP());Serial.print("http://");Serial.println(Hostname);esp8266_server.send(200, "text/plain", "1");delay(300);WiFi_Status = "1";// 记录状态到EEPROM:已配置EEPROM.write(WiFi_State_Addr, '1');EEPROM.commit();//存储WIFI SSID、Password到EEPROM中writeString(10, ssid_str, password_str);Serial.println("save ok");delay(50);//关闭热点WiFi.softAPdisconnect();delay(2000);ESP.restart();}else{esp8266_server.send(200, "text/plain", "0");// 连接失败, 返回0Serial.println("Connenting failed!");}}else{// WiFi密码格式错误Serial.println("Password format error");esp8266_server.send(200, "text/plain", "Password format error");}}else{// 请求参数错误Serial.println("Request parameter error");esp8266_server.send(200, "text/plain", "Request parameter error");}
}

WIFI 配置部分网页端

网页端使用html显示,点击扫描按钮,发送处理请求到ESP8266端,ESP8266调用函数,处理成json数据返回给html,使用Ajax接收数据,接收完毕后会显示所有WIFI列表,用户点击某个WIFI名称后输入密码,此时Ajax返回数据给ESP8266,8266开始调用连接WIFI函数,无论是否连接成功都会返回给网页端数据给html页面上,给用户显示,成功后8266会重启。

存储WIFI SSID、PassWord到EEPROM中

这两个普通操作函数我写了大几个小时、可能那天状态不是很好,各方面测试都试过、包括中文也可以存储到EEPROM中。


/*
*@brief:把SSID 、Password写入EEPROM中
*地址8:ssid_str 长度 地址9:pws_str长度,
*从地址10开始为ssid_str、pws_str连续存储内容
*@return: psw_start 密码地址起始位置
*/
uint8_t writeString(int start,String ssid_str,String psw){//String ssid_str = "micro";//String psw = "arduino01";uint8_t ssid_str_len = ssid_str.length();uint8_t psw_len = psw.length();EEPROM.write(8,ssid_str_len);EEPROM.write(9,psw_len);EEPROM.commit();delay(30);//写入ssid、psw字符串int ssid_start_addre;int ssid_end_addre;int psw_start;int psw_end_addre;//读取ssid的长度、psw的长度//uint8_t ssid_len = EEPROM.read(8);//uint8_t psw_len = EEPROM.read(9);//写入ssid_str      int i;for(i = start;i < start+ssid_str_len;i++){EEPROM.write(i,ssid_str[i-start]);delay(30);}ssid_end_addre = i;psw_start = i+1;EEPROM.commit();//写入psw,在ssid_str结束的下一个位置for(i = psw_start;i < psw_start+psw_len; i++){EEPROM.write(i,psw[i-psw_start]);delay(30);}EEPROM.commit();psw_end_addre = i;return psw_start;
}
/*
*@brief:从地址10开始读取SSID、PAssword
*@Param:uint8_t: flag:0 返回ssid_str  1:返回psw_str
*@return String
*
*/
String getStringInfo(uint8_t flag){//从EEprom中读ssid_strString temp_str = "";int i,psw_start;uint8_t ssid_str_len,pws_str_len;ssid_str_len = EEPROM.read(8);pws_str_len = EEPROM.read(9);Serial.println(ssid_str_len);Serial.println(pws_str_len);if (flag == 0) //ssid_str{for(i = 10;i < 10+ssid_str_len;i++){temp_str += char(EEPROM.read(i));}}else if(flag == 1){    //psw_strpsw_start = 10+ssid_str_len+1;for(i = psw_start;i < pws_str_len+psw_start;i++){temp_str += char(EEPROM.read(i));}}return temp_str;
}

2.网页数据显示、控制

代码如下(示例):

//处理index所有数据获取请求
void sjhq()
{String parm = esp8266_server.arg("sjhq");if (parm == "wd") //温度{Serial.println("respond wen du request.");//更新temptrue数据read_temperature();esp8266_server.send(200, "text/plain", String(temperature));}else if (parm == "light") //灯光按钮{Serial.println("light clicked...");dg = !dg;Serial.println("light:");Serial.println(dg?"on":"off");digitalWrite(Light, dg);esp8266_server.send(200, "text/plain", "ok");}else if (parm == "sxhs"){sxh = !sxh;digitalWrite(ShuiXunHuan, sxh);Serial.println("水循环");esp8266_server.send(200, "text/plain", "ok");}else if(parm == "zy"){   //增氧zeng_yang = !zeng_yang;digitalWrite(ZengYang,zeng_yang);Serial.println("ZengYang:"+zeng_yang);esp8266_server.send(200,"text/plain", "ok");}else if(parm == "zengyangStatus"){ //获取增氧开关状态Serial.println("respond zengyangStatus request.");esp8266_server.send(200, "text/plain", String(digitalRead(ZengYang)?1:0));}else if(parm == "timeFeed"){String value = esp8266_server.arg("value");Serial.println("select timer value:"+value);//电机转3s后停止//digitalWrite(ZengYang,HIGH);digitalWrite(Feed,HIGH);delay(3000);digitalWrite(Feed,LOW);//digitalWrite(ZengYang,LOW);esp8266_server.send(200,"text/plain", "ok");}
}

3、网页端数据请求

下面只展示两个处理、其它大同小异

 function wendu() {var xmlhttp;if (window.XMLHttpRequest) {xmlhttp = new XMLHttpRequest();}xmlhttp.onreadystatechange = function () {if (xmlhttp.status == 200) {document.getElementById("wd").innerHTML = xmlhttp.responseText + "℃";}}xmlhttp.open("GET", "/sjhq?sjhq=" + "wd");xmlhttp.send();}function shuixunhuan() {var xmlhttp;if (window.XMLHttpRequest) {xmlhttp = new XMLHttpRequest();}xmlhttp.onreadystatechange = function () {if (xmlhttp.status == 200) {if (xmlhttp.responseText == "1") {document.getElementById("sxh").innerHTML = "开启"} else {document.getElementById("sxh").innerHTML = "关闭"//  document.getElementById("sxh").innerHTML = xmlhttp.responseText;}}}xmlhttp.open("GET", "/sjhq?sjhq=" + "sxh");xmlhttp.send();}

项目进度

  1. 2022年3月17日
    主要完成了18B20温度传感器软硬件的实现,并调试成功。使用了文件系统并上传网页到ESP8266闪存里、Web 服务器
  2. 2022年3月18日
    今天上课上到下午4点,又排队做核酸检测,头疼。什么都没做
  3. 2022年3月19日
    今天实现了WIFI配网的移植,主要有Ajax技术,但存储WIFI功能还未实现
  4. 2022年3月20日
    今天实现了WIFI配网成功后把WIFI SSID、Password存储到EEPROM中,重启后自动连接此WIFI。
  5. 2022年3月21日
    今天上了一天课,啥都没做。
  6. 2022年3月22日
    今天上课到下午6点,晚上把index.html主页内容显示到8266上,并成功显示了温度数据,每3秒更新一次。但8266连接热点后不能域名解析了。
  7. 2022年3月23日
    今天没做
  8. 2022年3月24日
    今天没做
  9. 2022年3月25日
    今天没做
  10. 2022年3月26日
    今天上午刚收到快递,快递等的实在是太久了!今天把外围设备都焊接调试好了,只逻辑代码了,还需要解决默认进入后台页面地址问题,明天准备接一个OLED屏幕,把每次的ip地址显示出来,直接使用地址来访问页面。
  11. 2022年3月27日
    今天上午实现了OLED屏幕显示,最开始使用u8glib库,但有bug。后来换成另外一个库成功跑通。下午、晚上实现了OLED上显示系统ip、系统提示基本信息。
  12. 2022年3月28日
    今天总体测试,排除可能存在的bug、优化使用体验。
  13. 2022年3月29日
    今天没做
  14. 2022年3月30日
    今天没做
  15. 2022年3月31日
    晚上最后测试。打包快递。

物联网毕设----智能鱼缸相关推荐

  1. 物联网毕设 -- 智能厨房检测系统

    目录 前言 1 连线图 2 功能概括 底层功能 APP功能 云平台 3 底层代码使用方式 4 APP使用方式 前言 在家庭生活中,厨房是必不可少的,所以厨房的安全问题关乎着我们大家的生命,所以提出智能 ...

  2. 物联网毕设 -- 智能家居控制系统(APP+OneNET+WIFI)

    目录 前言 一 连线图 1. 原理图 2. PCB效果 3. 实物效果 4. 功能概括 (1)硬件端 (2)APP端 (3)云平台端 演示视频 二 底层代码使用方式 1. 使用说明 2. 下载程序 3 ...

  3. 物联网毕设 -- 智能花盆系统(蓝牙+APP)

    目录 前言 一 连线图 1. 原理图 2. PCB效果 3. 实物效果 4. 功能概括 (1)硬件端 (2)APP端 演示视频 二 底层代码使用方式 1. 使用说明 2. 下载程序 三 APP使用方式

  4. 物联网毕设 -- 智能热水器(GPRS+APP+OneNET)

    目录 前言 一 连线图 1. 原理图 2. PCB效果 3. 实物效果 4. 功能概括 (1)硬件端: (2)APP端: (3)云平台端 演示视频 二 底层代码使用方式 1. 使用说明 2. 下载程序 ...

  5. 物联网毕设 -- 智能拐杖(APP+GPS)

    前言 本款拐杖利用超声波传感器.心率监测传感器.GPS定位传感器,实时监测前方是否有障碍物阻挡.心率变化以及老人的具体位置.可以设置心率的阈值,在不正常区间内发送报警信号,并将检测到的数据实时联网上传 ...

  6. 物联网毕设 -- 智能火灾烟雾报警系统(APP+OneNET+WIFI)

    目录 前言 一 连线图 1. 原理图 2. PCB效果 3. 实物效果 4. 功能概括 (1)硬件端 (2)APP端 (3)云平台端 演示视频 二 底层代码使用方式 1. 使用说明 2. 下载程序 3 ...

  7. 物联网毕设 -- 智能宠物投喂器(图传+APP+ESP32-CAN)

    目录 前言 一 连线图 1. 原理图 2. PCB效果 3. 实物效果 4. 功能概括 (1)硬件端 (2)APP端 演示视频 二 底层代码使用方式 1. 使用说明 2. 下载程序 三 APP使用方式 ...

  8. 物联网毕设 -- 智能药箱提示系统(GSM+GPRS+APP+OneNet)

    目录 前言 一 连线图 1. 原理图 2. PCB效果 3. 实物效果 4. 功能概括 (1)硬件端 (2)APP端 (3)云平台端 演示视频 二 底层代码使用方式 1. 使用说明 2. 下载程序 3 ...

  9. 动手实践丨手把手教你用STM32做一个智能鱼缸

    摘要:本文基于STM32单片机设计了一款基于物联网的智能鱼缸. 本文分享自华为云社区<基于STM32+华为云IOT设计的物联网鱼缸[玩转华为云]>,作者: DS小龙哥 . 1. 前言 为了 ...

  10. 【物联网毕设】基于arduino与树莓派的智能鱼缸【一】

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 零.智能鱼缸框架与项目整体思路 一.Arduino与传感器部分 1.温度传感器部分 2.水位传感器部分 3.溶解氧传感 ...

最新文章

  1. 转】windows下使用批处理脚本实现多个版本的JDK切换
  2. 让数百万台手机训练同一个模型?Google把这套框架开源了
  3. python在中国的发展-未来十年Python的前景会怎样?
  4. linux离线安装httpd服务,Linux系列之离线安装Apache HTTP
  5. django_4:数据库0——配置数据库
  6. mysql实现高效率随机取数据
  7. 电网调度计算机系统目前有三种,电力系统知识问答(三)
  8. 360网络测速器电脑版
  9. QGC调试px4固件飞控
  10. 傅里叶级数的通俗理解
  11. Android Studio编译错误:Suggestion: use tools:overrideLibrary=xxx.xxx.xxx to force usage
  12. Unity + PicoVr 360全景视频播放
  13. ios第3天的气泡作业
  14. 《打造游戏开源平台 GameHub 》by:eli.ocean
  15. iOS16 中的 3 种新字体宽度样式
  16. Telnet操作步骤
  17. 【数据可视化应用】实现空间栅格(附R语言代码)
  18. HDFS常用命令的学习
  19. Bentley 软件公司将以约 10.5 亿美元的价格收购全球领先的地球科学三维建模软件提供商 Seequent
  20. 【DSP教程】第35章 FIR有限冲击响应滤波器设计

热门文章

  1. 在命令窗中查询当前电脑IP
  2. 一起学Vue自定义组件之拼图小游戏
  3. python 马赛克还原_「马赛克画」利用Python生成马赛克画,简单两步去除马赛克! - seo实验室...
  4. bootstrap-tagsinput 使用方法
  5. School Regional Team Contest, Saratov, 2011-F. Spiders-求树直径
  6. windows下使用endless报错:undefined: syscall.SIGUSR1
  7. linux 关于修改命令提示符
  8. Win10如何优化系统?电脑运行比较卡怎么优化?
  9. 使用Mybatis报错“Type interface com.test.mapper.UserMapper is not known to the MapperRegistry.“
  10. Windows Server 2012开机账户自动登录