imuncle / imuncle.github.io

大叔的个人小站
https://imuncle.github.io/
78 stars 17 forks source link

ESP8266调试总结 #92

Open imuncle opened 4 years ago

imuncle commented 4 years ago

一切都要追溯回硬件组组长建议我搞无线下载器的那天开始,掐指一算刚好一个月,就在今天,我终于搞定了两个ESP8266模块在不借助额外的WiFi的情况下实现相互通信,搞定这一步后做一个串口转WiFi透传模块那还不是轻轻松松。

ESP8266简介

ESP8266这个词可以理解为ESP8266EX芯片(当然,后面也有可能出现了其他芯片,这里首推ESP8266EX)以及依赖ESP8266EX芯片开发的系列模组的简称。

ESP8266EX是由乐鑫信息科技公司(Espressif)出品的一款应用于物联网编程的WiFi芯片。从它被设计出来,就引起了物联网开发的热潮,获得了业界同行的肯定。芯片的具体相关介绍,笔者这里就不占用章节篇幅,请读者自行查看乐鑫官网详细介绍。

ESP8266系列模组是深圳安信可(Ai-thinker)公司开发的一系列基于乐鑫ESP8266EX的超低功耗的UART-WiFi模块的模组,可以方便地进行二次开发,接入云端服务,实现手机3/4G全球随时随地的控制,加速产品原型设计。

从厂商角度来看,乐鑫是ESP8266的芯片厂商,安信可是依赖ESP8266生产模组,在ESP8266芯片的基础上,完善了外围器件布局和优化天线,并提供一系列开发方案的厂家。

这款芯片的设计初衷是针对loT物联网的,它可以作为station连接WiFi访问其他设备,可以作为soft access port配置为一个WiFi热点让其他设备连接,可以作为web服务器,也可以作为客户端请求数据,什么智能家居,远程操控,它都能搞定。

最最最棒的是,它的成本非常便宜,批发价格不到10块,太值了吧!

特点

型号

image

官方资料

官方资料主要分为两部分,一部分是芯片的制造商乐鑫,从它的官网里可以下载芯片的数据手册、原厂固件、硬件设计指南、SDK指南等。另一部分是模块的智商上安信可,从它的官网里可以下载开发文档、代码示例、固件、SDK等。

ESP8266编程方式

网上关于ESP8266的资料真实太多太繁杂了,可见这款芯片的火爆。目前ESP8266的固件版本有好几种,乐鑫原厂的SDK主要有两个版本:RTOS-SDKNONOS-SDK,前者带操作系统,后者是裸机,另外有一个AT指令的固件版本,可以只用AT指令配置模块。安信可在ESP8266-12F的基础上设计了NodeMCU,它有自己的固件版本,是将乐鑫的NONOS-DSKNodeLua结合起来,可以使用Lua语言编程。最后,有大神将ESP8266整个系列都arduino化,开发出Arduino ESP版本,是基于RTOS-SDKArduino Core的开发框架。

以上固件的相关的链接如下:

此外NodeMCU还支持自定义固件:NodeMCU custom builds

使用以上几种固件中的任何一种都可以对ESP8266进行开发。当然,不同的固件其编程方式不同,下载工具也有些不同,但本质上ESP8266的编程都是通过串口下载,这一点和arduino是一样的。

下载工具

下载工具主要用于第一次给ESP8266刷写固件,固件的来源大致就是上面几个途径,当然也可以根据SDK自己编译固件,拿到固件之后就使用下载工具下载。

这里的固件也有好几种,一种是被合并过的一体化的固件,这种固件直接从0x00地址烧写就行了,另一种是分块的,这种固件需要按照固件的对应说明书按指定地址下载,这时候下载工具的作用就体现出来了。

目前主流的就两种,这里展示一下分块固件的下载截图: image

另外要注意,上电时模块会判断GPIO0引脚的电平,GPIO0口如果是低电平,模块进入固件下载模式,如果是高电平或悬空,模块从flash启动。

编程环境搭建

对于SDK开发,因为涉及到编译问题,可能会涉及到相关的编译工具链的配置,官方的说明文档里是在Lubuntu系统里演示的,我并没有基于SDK开发,所以这里给不出实质性的建议。

另外乐鑫提供了一个基于Eclipse的一体化开发环境,可以在上面的安信可工具合集里面下载。这款工具集成了所有东西,可以直接编译下载SDK,看起来确实挺好的,但是我当时的第一反应是:“在?为什么想不开要基于Eclipse?”说实话它要是出了一个基于文本编辑器(比如VS Code)的教程我可能就直接玩SDK了,但是如果还要我另外再下载一个Eclipse,对不起,我们不认识。

对于AT固件的开发,很简单,一个USB转TTL的模块就行了,不过要注意其他关键引脚的连线,比如GPIO0、RST等。连线搞定后就参照AT指令集手册发送指令配置就行了。

对于NodeMCU开发,有一款由NodeMCU团队中的一个人以个人名义发布的编译下载一体化工具,需要jre(Java Run Environment)的支持,还好我工具所需的STM32CubeMX也需要JRE,所以我安装有,要不然也会被劝退,真心不想因为一个ESP8266下载这么多新的东西,又不是以后常用的。这款工具叫做Esplorer,很小巧,但是界面有点小丑: image

因为是针对NodeMCU的,所以使用的是Lua脚本编程,相关的API手册在这里,我尝试着写了一些简单程序,但是体验效果并不是太好,我设置一个定时器后反复烧录,结果每烧录一次模块里就多了一个定时器,最后全乱了,没办法,可能这个工具还不是太完善。

最后,对于Arduino ESP固件,使用大名鼎鼎的Arduino,我平时偶尔也会写一些arduino程序,因为arduino用来对一个功能进行快速测试真的很方便。将arduino配置为ESP8266开发环境也很简单,参考这篇博客:Arduino IDE 搭建 ESP8266 开发环境及项目演示,一步到位。另外官网的API手册在这里

上手编程

AT指令集编程

这算是最容易上手的一种编程,但也局限性最大,因为指令集真的很有限,缺少很多用户自定义的可能,但AT指令集很火,现在很多蓝牙、WiFi、2.4G无线模块等都支持AT指令集编程,很方便。

AT指令集编程我参考了(一)esp8266透传简单使用这篇文章,实际测试确实能实现功能,服务器端是STA+AP的工作模式,客户端是STA模式。

服务器端配置:

AT+CWMODE=3  //设置为STA+AP
AT+RST  //复位以启用设置
AT+CWJAP=”public”,”123456789”  配置热点名称和密码
AT+CIPMUX=1  //设置为多路连接模式
AT+CIPSERVER=1,8080  //打开8080端口

客户端配置:

AT+CWMODE=1  //设置为STA模式
AT+RST  //复位以启用设置
AT+CWJAP=”public”,”123456789”   //连入局域网
AT+CIPMUX=0  //设置为单连接模式
AT+CIPMODE=1  //设置为串口透传模式
AT+CIPSTART=”TCP”,”192.168.4.1”,8080 //连接上服务器,如果没有单独配置,则服务器给自己分配的IP地址默认为192.168.4.1
AT+CIPSEND  //开启透传

之后就可以相互通信了。不过我觉得非常不方便,一方面是俩模块,尤其是客户端,每次断电重启之后都需要重新配置,很麻烦,另一方面服务器端接收数据打印出来时,总会夹带一些额外的字符串信息,但我是传给MCU的,MCU处理字符串信息很烦,因为这两个原因,最后我放弃了使用AT固件。

Arduino编程

Arduino编程也是我最后尝试并决定使用的编程方式,一开始我觉得arduino编程好像很low的样子,没有什么挑战性(事实上确实没有),就没仔细研究,后来尝试了其他方法四处碰壁后,转了一圈最后又回到arduino上,才感觉到

真香!

照例还是闪一个小灯,我手里的NodeMCU采用的芯片是ESP8266-12F,上面的LED小灯连接的是GPIO2,于是我用下面的小程序测试了一下:

int LED_BUILTIN = 2
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
  // but actually the LED is on; this is because
  // it is active low on the ESP-01)
  delay(1000);                      // Wait for a second
  digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
  delay(1000);                      // Wait for two seconds (to demonstrate the active low LED)
}

下载进去后LED就开始闪烁起来了。说实话看到灯闪起来的时候非常激动,毕竟这是我研究ESP8266这么久以来第一次成功控制LED灯(是真的菜)。之后就顺利多了,参照官方手册一步步走,基本能使用模块的基本功能了。

这里展示一个让我很喜欢的功能,就是用ESP8266做一个网站服务器,代码如下:

#include <ESP8266WiFi.h>

const char *ssid = "ESP8266 Website";
const char *password = "12345678";
WiFiServer server(80);
void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.print("Setting soft-AP ... ");

  IPAddress softLocal(192,168,1,1); 
  IPAddress softGateway(192,168,1,1);
  IPAddress softSubnet(255,255,255,0);

  WiFi.softAPConfig(softLocal, softGateway, softSubnet); 
  WiFi.softAP(ssid, password);

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
 server.begin();
 Serial.printf("Web server started, open %s in a web browser\n", WiFi.softAPIP().toString().c_str());

}

void loop()
{
 WiFiClient client = server.available();
 if (client)
  {
    Serial.println("\n[Client connected]");
    while (client.connected())
    {
      if (client.available())
      {
       //  String line = client.readStringUntil(13);// arduino换行符号  ascll码 13
        String line = client.readStringUntil('\r');
        Serial.println(line);   
        // wait for end of client's request, that is marked with an empty line
        if (line.length() == 1 && line[0] == '\n'){
          //返回响应内容
          String htmlPage = String("HTTP/1.1 200 OK\r\n") +
            "Content-Type: text/html\r\n" +
            "Connection: close\r\n" +  // the connection will be closed after completion of the response
            "Refresh: 5\r\n" +  // refresh the page automatically every 5 sec
            "\r\n" +
            "<!DOCTYPE HTML>" +
            "<html><head><title>ESP8066 Website</title><link rel='icon' href='https://imuncle.github.io/images/avatar.jpg'><meta charset='utf-8'></head>" +
            "<body><h1>Hello World!</h1><p>本网页由ESP8266模块展示</p><p>Designed by big_uncle</p></body>" +
            "</html>" +
            "\r\n";
          client.println(htmlPage);
          break;
        }
      }
    }
    delay(500);

    client.stop();
    Serial.println("[Client disonnected]");
  }
 }

这里首先用ESP8266建立了一个名外“ESP8266 Website”的WiFi,密码是12345678,设置自己的IP地址为192.168.1.1,创建一个服务器,监听80端口,然后当其他设备访问80端口时,返回一个网页信息。

运行效果如下: image

这个例子的实现也意味着,我也可以实现两个ESP8266在没有额外的WiFi的环境下相互通信的功能,这正是我最开始想要实现的功能。

如果不想其他设备连接这个WiFi,还可以选择隐藏SSID,让别的设备扫描不到这个WiFi。另外因为两个模块是通过TCP协议进行通信,数据稳定性也得到了保障,非常nice。

最后,推荐一个写的非常详细的Arduino ESP8266编程教程系列:ESP8266开发之旅 基础篇① 走进ESP8266的世界

最后的最后,让我再说一句:

ESP8266牛逼!

参考


顺便一提,昨晚我把正点原子的无线调试器拆开看了一下,发现里面的模块并不是硬件组告诉的ESP8266,而是音视频传输模块-ZM2461PA03,里面搭载的是笙科电子的A7196芯片,不过这款产品在淘宝搜索不到,所以我就原谅硬件组吧。

LUCKandII commented 3 years ago

啊啊啊这所以为啥没有用它做无线下载器,有啥不可实现的问题->_->(挂了梯子还是打不开小站,就只能直接看issue了。。。)