项目目的

主要实现网络化测控电池输出功率。首先TENG(摩擦纳米发电机)为电池充电,然后电池为负载供能。为了检测TENG发电以及电池充电的效果,需要测量电池的输出功率。为了实现实时监测,故需要进行远程控制。同时因为模块数量可能较多,因此需要控制单个模块的成本

  • 远程实时监测
  • 成本控制

项目需求

  • 可以实时监测每一个电池模块(发电阵列)的动态数据,包括电流、电压、功率、功率因数等数据

  • 某一个发电模块发生故障时,及时报警,并上传故障数据

  • 监测系统软件具有操作方便、可视化强等特点

  • 系统能在较大范围内进行组网通信

  • 功率因数:衡量电气设备效率高低的一个系数

  • 组网通信:将多个计算机或设备连接和配置成一个网络,使它们能够相互通信和共享资源

系统设计

  • 网络部分,每一个电池模块设置一个监测站点;另外设置一个中心站作为监测系统的核心
  • 每个监测站点应该设置如下设备:电量传感器、数据采集器、无线装置

总结

  • 使用ESP8266-NodeMCU实现无线功能

  • 搭建Arduino IDE和VS Code+PlatformOI两种环境,并逐渐向后者靠拢

  • 目前以实现功能为主,无论哪种环境。遇到可绕过的错误不要死磕

  • 实现了串口通信【Arduino IDE+串口调试助手 & VS Code+PlatformOI】

  • 配置好VS Code的环境,MinGW用的百度网盘别人的拷贝

    • bin文件夹设置环境变量的时候不应该单独设置,应该在原有的Path中新建

    • 要注意launch.json、tasks.json、c_cpp_properties.json三个文件的编写【.vscode文件夹】

    • 斜杠/和反斜杠\

斜杠/和反斜杠\: https://blog.csdn.net/weixin_43593330/article/details/89854744


ESP8266-NodeMCU笔记

开发板详解

主控芯片:ESP8266-12E

波特率:9600


  • GPIO:GPIO全拼叫General Purpose Input Output(通用输入输出)简称IO口也叫总线扩展器,GPIO口是由引脚,功能寄存器组成,不同的架构中的GPIO封装不同,所使用的引脚数与寄存器数不同,具体可以参考芯片手册里的GPIO篇。

  • Arduino语法


NodeMCU接入点模式

  • NodeMCU可以建立WiFi网络供其他设备连接。
/*
NodeMCU接入点模式:此程序用于演示如何将NodeMCU以接入点模式工作。通过此程序,您可以使用电脑或者手机连接NodeMCU所建立WiFi网络。
*/
 
#include <ESP8266WiFi.h>        // 本程序使用ESP8266WiFi库
 
const char *ssid = "zj_nodemcu"; // 这里定义将要建立的WiFi名称。
                                   // 您可以将自己想要建立的WiFi名称填写入此处的双引号中
 
const char *password = "20240513";  // 这里定义将要建立的WiFi密码。
                                    // 您可以将自己想要使用的WiFi密码放入引号内
                                    // 如果建立的WiFi不要密码,则在双引号内不要填入任何信息
 
void setup() {
  Serial.begin(9600);              // 启动串口通讯
 
  WiFi.softAP(ssid, password);     // 此语句是重点。WiFi.softAP用于启动NodeMCU的AP模式。
                                   // 括号中有两个参数,ssid是WiFi名。password是WiFi密码。
                                   // 这两个参数具体内容在setup函数之前的位置进行定义。
 
  Serial.print("  Access Point: ");    // 通过串口监视器输出信息
  Serial.println(ssid);              // 告知用户NodeMCU所建立的WiFi名
  Serial.print("IP address: ");      // 以及NodeMCU的IP地址
  Serial.println(WiFi.softAPIP());   // 通过调用WiFi.softAPIP()可以得到NodeMCU的IP地址
}
 
void loop() { 
}

NodeMCU开发板的无线终端模式

  • ESP8266可通过WiFi连接无线路由器。这与用您的手机通过WiFi连接无线路由器的模式相同

通过WiFi连接无线路由器

/*
NodeMCU无线终端模式连接WiFi,本示例程序用于演示如何使用NodeMCU无线终端模式连接WiFi
*/

#include <ESP8266WiFi.h>        // 本程序使用ESP8266WiFi库

const char* ssid     = "taichi-maker";      // 连接WiFi名(此处使用taichi-maker为示例)
                                            // 请将您需要连接的WiFi名填入引号中
const char* password = "12345678";          // 连接WiFi密码(此处使用12345678为示例)
                                            // 请将您需要连接的WiFi密码填入引号中
                                            
void setup() {
  Serial.begin(9600);         // 启动串口通讯
  
  WiFi.begin(ssid, password);                  // 启动网络连接
  Serial.print("Connecting to ");              // 串口监视器输出网络连接信息
  Serial.print(ssid); Serial.println(" ...");  // 告知用户NodeMCU正在尝试WiFi连接
  
  int i = 0;                                   // 这一段程序语句用于检查WiFi是否连接成功
  while (WiFi.status() != WL_CONNECTED) {      // WiFi.status()函数的返回值是由NodeMCU的WiFi连接状态所决定的。 
    delay(1000);                               // 如果WiFi连接成功则返回值为WL_CONNECTED                       
    Serial.print(i++); Serial.print(' ');      // 此处通过While循环让NodeMCU每隔一秒钟检查一次WiFi.status()函数返回值
  }                                            // 同时NodeMCU将通过串口监视器输出连接时长读秒。
                                               // 这个读秒是通过变量i每隔一秒自加1来实现的。
                                               
  Serial.println("");                          // WiFi连接成功后
  Serial.println("Connection established!");   // NodeMCU将通过串口监视器输出"连接成功"信息。
  Serial.print("IP address:    ");             // 同时还将输出NodeMCU的IP地址。这一功能是通过调用
  Serial.println(WiFi.localIP());              // WiFi.localIP()函数来实现的。该函数的返回值即NodeMCU的IP地址。
}

void loop() {                                   
}

自动连接最强WiFi

#include <ESP8266WiFi.h>          // 本程序使用ESP8266WiFi库
#include <ESP8266WiFiMulti.h>   // 本程序使用ESP8266WiFiMulti库

ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti'

void setup() {
  Serial.begin(9600);            // 启动串口通讯

//通过addAp函数存储  WiFi名称       WiFi密码
  wifiMulti.addAP("taichi-maker", "12345678");  // 这三条语句通过调用函数addAP来记录3个不同的WiFi网络信息。
  wifiMulti.addAP("taichi-maker2", "87654321"); // 这3个WiFi网络名称分别是taichi-maker, taichi-maker2, taichi-maker3。
  wifiMulti.addAP("taichi-maker3", "13572468"); // 这3个网络的密码分别是123456789,87654321,13572468。
                                                // 此处WiFi信息只是示例,请在使用时将需要连接的WiFi信息填入相应位置。
                                                // 另外这里只存储了3个WiFi信息,您可以存储更多的WiFi信息在此处。
                                                
  Serial.println("Connecting ...");         // 通过串口监视器输出信息告知用户NodeMCU正在尝试连接WiFi
  int i = 0;                                 
  while (wifiMulti.run() != WL_CONNECTED) {  // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前
    delay(1000);                             // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU
    Serial.print('.');                       // 将会连接信号最强的那一个WiFi信号。
  }                                           // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是
                                              // 此处while循环判断是否跳出循环的条件。

  
  Serial.println('\n');                     // WiFi连接成功后
  Serial.print("Connected to ");            // NodeMCU将通过串口监视器输出。
  Serial.println(WiFi.SSID());              // 连接的WiFI名称
  Serial.print("IP address:\t");            // 以及
  Serial.println(WiFi.localIP());           // NodeMCU的IP地址
}

void loop() { 
}

NodeMCU建立基本网络服务器

  • 承担网络服务器工作的设备都是运算能力比较强大的电脑

  • ESP866-NodeMCU虽然也能实现网络服务器的一些功能

  • 但是毕竟它的运算能力是无法与那些昂贵的服务器电脑相媲美的,因此ESP8266-NodeMCU只能实现一些基本的网络服务功能

  • 不过这些基本的网络服务功能已经足够我们开发物联网项目了

  • 让ESP8266-NodeMCU实现网络服务功能

NodeMCU网页服务功能

/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
***********************************************************************/
#include <ESP8266WiFi.h>        // 本程序使用 ESP8266WiFi库
#include <ESP8266WiFiMulti.h>   //  ESP8266WiFiMulti库
#include <ESP8266WebServer.h>   //  ESP8266WebServer库

ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti'
 
ESP8266WebServer esp8266_server(80);// 建立ESP8266WebServer对象,对象名称为esp8266_server
                                    // 括号中的数字是网路服务器响应http请求的端口号
                                    // 网络服务器标准http端口号为80,因此这里使用80为端口号

void setup(void){
  Serial.begin(9600);          // 启动串口通讯

  //通过addAp函数存储  WiFi名称       WiFi密码
  wifiMulti.addAP("taichi-maker", "12345678");  // 这三条语句通过调用函数addAP来记录3个不同的WiFi网络信息。
  wifiMulti.addAP("taichi-maker2", "87654321"); // 这3个WiFi网络名称分别是taichi-maker, taichi-maker2, taichi-maker3。
  wifiMulti.addAP("taichi-maker3", "13572468"); // 这3个网络的密码分别是123456789,87654321,13572468。
                                                // 此处WiFi信息只是示例,请在使用时将需要连接的WiFi信息填入相应位置。
                                                // 另外这里只存储了3个WiFi信息,您可以存储更多的WiFi信息在此处。

  int i = 0;                                 
  while (wifiMulti.run() != WL_CONNECTED) {  // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前
    delay(1000);                             // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU
    Serial.print(i++); Serial.print(' ');    // 将会连接信号最强的那一个WiFi信号。
  }                                          // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是
                                             // 此处while循环判断是否跳出循环的条件。
 
  // WiFi连接成功后将通过串口监视器输出连接成功信息 
  Serial.println('\n');                     // WiFi连接成功后
  Serial.print("Connected to ");            // NodeMCU将通过串口监视器输出。
  Serial.println(WiFi.SSID());              // 连接的WiFI名称
  Serial.print("IP address:\t");            // 以及
  Serial.println(WiFi.localIP());           // NodeMCU的IP地址
  
//--------"启动网络服务功能"程序部分开始-------- //  此部分为程序为本示例程序重点1
  esp8266_server.begin();                   //  详细讲解请参见太极创客网站《零基础入门学用物联网》
  esp8266_server.on("/", handleRoot);       //  第3章-第2节 ESP8266-NodeMCU网络服务器-1
  esp8266_server.onNotFound(handleNotFound);        
//--------"启动网络服务功能"程序部分结束--------
  Serial.println("HTTP esp8266_server started");//  告知用户ESP8266网络服务功能已经启动
}


void loop(void){
  esp8266_server.handleClient();     // 处理http服务器访问
}                                                                           
void handleRoot() {   //处理网站根目录“/”的访问请求 
  esp8266_server.send(200, "text/plain", "Hello from ESP8266");   // NodeMCU将调用此函数。
}

// 设置处理404情况的函数'handleNotFound'
void handleNotFound(){                                        // 当浏览器请求的网络资源无法在服务器找到时,
  esp8266_server.send(404, "text/plain", "404: Not found");   // NodeMCU将调用此函数。
}
/**********************************************************************
项目名称/Project          : 零基础入门学用物联网
***********************************************************************/
#include <ESP8266WiFi.h>        // 本程序使用 ESP8266WiFi库
#include <ESP8266WiFiMulti.h>   //  ESP8266WiFiMulti库
#include <ESP8266WebServer.h>   //  ESP8266WebServer库

ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'

ESP8266WebServer esp8266_server(80);// 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)


  const char* css_code = "<style>\n\
    .btn-toggle {\n\
        font-size: 50px; /* 增加文字大小 */\n\
        padding: 10px 20px; /* 增加内边距 */\n\
    }\n\
</style>";

const char* form_code = "<form action=\"/LED\" method=\"POST\">\n\
    <input class=\"btn-toggle\" type=\"submit\" value=\"Toggle LED\">\n\
</form>";

void handleRoot() {
  // esp8266_server.send(200, "text/html", "<form action=\"/LED\" method=\"POST\"><input type=\"submit\" value=\"Toggle LED\"></form>");
   String html_response = String(css_code) + String(form_code);
  esp8266_server.send(200, "text/html", html_response);

}

//处理LED控制请求的函数'handleLED'
void handleLED() {
  digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN));// 改变LED的点亮或者熄灭状态
  esp8266_server.sendHeader("Location","/");          // 跳转回页面根目录
  esp8266_server.send(303);                           // 发送Http相应代码303 跳转
}

// 设置处理404情况的函数'handleNotFound'
void handleNotFound(){
  esp8266_server.send(404, "text/plain", "404: Not found"); // 发送 HTTP 状态 404 (未找到页面) 并向浏览器发送文字 "404: Not found"
}

void setup(void){
  Serial.begin(9600);   // 启动串口通讯

  pinMode(LED_BUILTIN, OUTPUT); //设置内置LED引脚为输出模式以便控制LED

  wifiMulti.addAP("a", "87654321"); // 将需要连接的一系列WiFi ID和密码输入这里
  // wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络
  // wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有
  Serial.println("Connecting ...");                            // 则尝试使用此处存储的密码进行连接。

  int i = 0;
  while (wifiMulti.run() != WL_CONNECTED) {  // 此处的wifiMulti.run()是重点。通过wifiMulti.run(),NodeMCU将会在当前
    delay(1000);                             // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么NodeMCU
    Serial.print(i++); Serial.print(' ');    // 将会连接信号最强的那一个WiFi信号。
  }                                          // 一旦连接WiFI成功,wifiMulti.run()将会返回“WL_CONNECTED”。这也是
                                             // 此处while循环判断是否跳出循环的条件。

  // WiFi连接成功后将通过串口监视器输出连接成功信息
  Serial.println('\n');
  Serial.print("Connected to ");
  Serial.println(WiFi.SSID());              // 通过串口监视器输出连接的WiFi名称
  Serial.print("IP address:\t");
  Serial.println(WiFi.localIP());           // 通过串口监视器输出ESP8266-NodeMCU的IP

  esp8266_server.begin();                           // 启动网站服务
  esp8266_server.on("/", HTTP_GET, handleRoot);     // 设置服务器根目录即'/'的函数'handleRoot'
  esp8266_server.on("/LED", HTTP_POST, handleLED);  // 设置处理LED控制请求的函数'handleLED'
  esp8266_server.onNotFound(handleNotFound);        // 设置处理404情况的函数'handleNotFound'

  Serial.println("HTTP esp8266_server started");//  告知用户ESP8266网络服务功能已经启动
}

void loop(void){
  esp8266_server.handleClient();                     // 检查http服务器访问
}

已经可以控制LED的亮灭以及闪烁的开始和停止

/**********************************************************************
项目名称/Project          : 远程控制LED
***********************************************************************/
#include <ESP8266WiFi.h>      // 本程序使用 ESP8266WiFi库
#include <ESP8266WiFiMulti.h> //  ESP8266WiFiMulti库
#include <ESP8266WebServer.h> //  ESP8266WebServer库

ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'

ESP8266WebServer esp8266_server(80); // 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)

bool isSparkling = false;         // 用于标记LED是否正在闪烁
unsigned long previousMillis = 0; // 用于记录上一次LED状态改变的时间
const long interval = 500;        // 闪烁间隔,单位为毫秒

const char *css_code = "<style>\n\
    .btn-toggle {\n\
        font-size: 50px;\n\
        padding: 10px 20px;\n\
        position: absolute;\n\
        top: 50%;\n\
        left: 50%;\n\
    }\n\
</style>";

const char *code="<!DOCTYPE html>\n\
<html lang=\"en\">\n\
<head>\n\
    <meta charset=\"UTF-8\">\n\
    <meta name=\"viewport\" content=\"width=device-w