WIFI模块(ESP8266)学习1


补充前言、固件下载错误进行擦除:

参考:【一起玩esp8266】flash的擦除方法——专治疑难杂症

【ESP8266】安装esptool.py - MicroPython开源版块 - 电子工程世界-论坛

​ 8266烧录固件的ESP FLASH DOWNLOAD TOOL,但是这个工具只能向8266写入固件程序,无法对flash进行擦除操作,因而可能会由于某些原因造成烧录的固件运行不正常。使用esptool.py(一个Python程序,需在Python2环境下运行)。

​ ESPtool.py是一个python开发的针对ESP8266的小工具,可以实现底层的操作,弥补ESP8266官方工具的不足。flash的小工具,可以弥补ESP8266官方工具的不足。它也是一个开源项目,项目在github上进行托管:https://github.com/themadinventor/esptool

​ 虽然可以直接从github上下载使用,但是更好的方法是通过网络的方式进行安装,这样不会缺少依赖模块,减少运行中的故障。下面就介绍它的安装方法。

  1. 因为esptool.py需要使用python2,所以我们先需要安装python2,并将python加入系统路径(path)。

  2. 安装python的包管理器pip,通常是使用get-pip.py进行安装。在 https://pip.pypa.io/en/latest/installing/ 可以找到安装的说明和需要下载的文件,按照说明可以很容易安装pip。(如果同时安装了python2和python3,pip可能默认是pip3,需要用pip2来代替下面的pip,在Linux上需要用sudo权限安装)。

  3. 用pip安装esptool
    pip install esptool

  4. 因为esptool需要使用串口,所以还需要安装pyserial。

pip install pyserial

  1. 安装后,在Linux下,通常就可以直接运行esptool.py,在Windwos下,esptool一般安装在python2\Scripts\目录下,需要输入完整目录才能运行,如:

c:\Python27\Scripts\esptool.py

​ 如果不清楚esptool.py的用法,可以输入-h查看帮助,如

esptool.py -h

​ 甚至可以查看某个用法的帮助:

esptool.py read_flash -h

  1. 擦除flash。
    首先要确认一下8266所连接的串口号,要以串口号作为指令的参数,如我的设备是在COM4,我运行的指令就是esptool.py –port COM4 erase_flash
    img
    此处需要注意,执行擦除的指令前,需要像烧录固件一样,让8266进入升级模式,即按住板上的flash键不放,按下rst键,等待两秒,松开rst键,再松开flash键。否则会出现如下的错误提示: img 这样flash的擦除工作就完成了,重新再烧录固件之后即可解决固件运行异常的问题。

一、esp8266系列模块基础知识:

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

  模块核心处理器 ESP8266 在较小尺寸封装中集成了业界领先的 Tensilica L106 超低功耗 32 位微型 MCU,带有 16 位精简模式,主频支持 80 MHz 和 160 MHz,支持 RTOS,集成 Wi-Fi MAC/ BB/RF/PA/LNA,板载天线。支持标准的 IEEE802.11 b/g/n 协议,完整的 TCP/IP 协议栈。用户可以使用该模块为现有的设备添加联网功能,也可以构建独立的网络控制器。

  ESP8266 是高性能无线 SoC,以最低成本提供最大实用性,为 Wi-Fi 功能嵌入其他系统提供无限可能。

  特点

  • 802.11 b/g/n
  • 内置Tensilica L106 超低功耗 32 位微型 MCU,主频支持 80 MHz 和160 MHz,支持 RTOS
  • 内置10 bit高精度ADC
  • 内置TCP/IP协议栈
  • 内置TR 开关、balun、LNA、功率放大器和匹配网络
  • 内置PLL、稳压器和电源管理组件,802.11b 模式下+18 dBm的输出功率
  • A-MPDU 、 A-MSDU 的聚合和 0.4 s的保护间隔
  • Wi-Fi @ 2.4 GHz,支持 WPA/WPA2 安全模式
  • 支持AT本地升级及云端OTA升级
  • 支持 STA/AP/STA+AP 工作模式
  • 支持 Smart Config 功能(包括 Android 和 IOS 设备)
  • HSPI 、UART、I2C、I2S、IR Remote Control、PWM、GPIO
  • 深度睡眠保持电流为 20 uA,关断电流小于 5 uA
  • 2 ms 之内唤醒、连接并传递数据包
  • 待机状态消耗功率小于1.0 mW (DTIM3)
  • 工作温度范围:详情请见具体型号规格书

fCFrdK.png

二、环境准备(Arduino开发):

1、硬件准备:

GPIO0决定板子处于什么模式(下载模式)

①、ESP-01系列:

WhEJnU.md.pngfCZ14f.png

②、用的最多的12F:

Whud4e.md.png
SMD-22封装,GPIO0-GPIO16共17个通用IO口,一个单通道ADC,GPIO6-GPIO11用于连接外部flash,不可用,支持SPI总线通信:GPIO12-GPIO15,支持I2C总线:GPIO4-GPIO5,串口通信:GPIO1-GPIO3。

  • 12F一般D0-D8(除D3口即GPIO0下载用);

  • D0:INPUT(输入)、OUTPUT(输出)、INPUT_PULLDOWN(输入,默认下拉,低电平);

  • 其余IO口:INPUT(输入)、OTPUT(输出)、INPUT_PULLUP(输入,默认上拉,高电平);

WhEdhR.md.png

注意:烧录模式GPIO0接地,正常模式GPIO悬空。

③、NodeMcu(ESP-12F开发板):

WhKk5D.md.png
WhKla8.md.png

④、8266-12E:

fCJX6I.jpg

2、软件准备:

①、Arduino安装+8266包安装:

fCmCY6.png

②、芯片检测程序:

/**
 *    测试ESP8266 demo,打印ESP8266模块信息
 *    1.打印Arduino Core For ESP8266 版本
 *    2.打印Flash的唯一性芯片id
 *    3.打印Flash实际大小
 *    4.打印IDE配置的使用Flash大小
 *    5.打印IDE配置的Flash连接通信的频率
 *    6.打印Flash连接模式:QIO QOUT DIO DOUT,可以理解为Flash传输速率
 */
void setup() {
  Serial.begin(115200);
  //使能软件看门狗的触发间隔
  //规定时间(5S)内不喂狗,系统复位
  ESP.wdtEnable(5000);
}
void loop() {
  //喂狗
  ESP.wdtFeed();
  FlashMode_t ideMode = ESP.getFlashChipMode();
  String coreVersion = ESP.getCoreVersion();
  Serial.print(F("Arduino Core For ESP8266 Version: "));
  Serial.println(coreVersion);
  Serial.printf("Flash real id(唯一标识符):   %08X\n", ESP.getFlashChipId());
  Serial.printf("Flash 实际大小: %u KBytes\n", ESP.getFlashChipRealSize()/1024);
  Serial.printf("IDE配置Flash大小: %u KBytes,往往小于实际大小\n", ESP.getFlashChipSize()/1024);
  Serial.printf("IDE配置Flash频率 : %u MHz\n", ESP.getFlashChipSpeed()/1000000);
  Serial.printf("Flash ide mode:  %s\n\n", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT" : ideMode == FM_DIO ? "DIO" : ideMode == FM_DOUT ? "DOUT" : "UNKNOWN"));  
  delay(1000);
}

WhVRqU.md.png

三、相关外设使用:

1、计时和延时:

/**
*     计时和延时:
*     delay(ms);
*     delayMicroseconds(us);延时中不能做其他事
*     millis(); //返回重启后所经过的毫秒数
*     micros(); //返回重启后所经过的微秒数
**/
long debouncdDelay = 60;//延时间隔
long lastDebounceTime = 0; //最近记录的一次时间
// 判断时间间隔是否大于设定的时间间隔。
if(millis()-lastDebounceTime>debouncdDelay){
    lastDebounceTime = millis();
}

2、IO口(Blink):

/**
 * LED灯闪烁实验
 * 12E模块,LED在GPIO2口,即NodeMCU的D4
 */
void setup() {
    pinMode(D4, OUTPUT);   // 初始化D1引脚为输出引脚
} 
void loop() {
    digitalWrite(D4, LOW); // 亮灯
    delay(1000); // 延时1s
    digitalWrite(D4, HIGH);// 灭灯
    delay(1000); // 延时1s
}

3、中断:

(除了DO/GPIO16,中断可以绑到任意GPIO脚)

相关函数:

  1. attachInterrupt(pin,function,mode); 在指定引脚设置为响应中断。pin:要设置的中断号,function:中断时执行的函数,不带任何参数,无返回,Interrupt type/mode:中断触发条件(CHANGE:改变沿;RISING:上升沿;FALLING:下降沿)
  2. detachInterrupt(pin); 禁用指定GPIO引脚上的中断。pin:要禁用的中断的GPIO引脚,无返回值。
  3. digitalPinToInterrupt(pin); 获取指定GPIO引脚的中断号。
/**
 * 功能描述:ESP8266中断演示
 * D2口接下拉电阻到地,同时也通过一个按键开关接到VCC
 * 当开关按下,D2接到上升沿,开启中断,进入中断函数
 */ 
void setup() {
 Serial.begin(115200);//设置串口波特率
 attachInterrupt(digitalPinToInterrupt(D2), InterruptFunc, RISING);//设置中断号、响应函数、触发方式
}
void loop() {
}
/**
 * 中断响应函数
 */ 
ICACHE_RAM_ATTR void InterruptFunc(){
 Serial.println("Hello ESP8266");
}

4、模拟输入(ADC):

esp8266只用一个10位ADC通道(和芯片供电电压复用:即可设置为测量系统电压或者外部电压)

①、测量外部电压:

  • 方法:analogRead(A0);
  • 0-1.0V
  • 测量精度:10位ADC:0~$2^{10}$​​​
  • 注意:开发板上做了电阻分压器,使其能够测量0 ~ 3.3V(220K与100K电阻分压)
/**
 * 功能描述:ESP8266 ADC 读取外部电压
 * 在串口调试器查看效果
 */
void setup() {
  Serial.begin(115200);//配置波特率
}
void loop() {
  Serial.print("ADC Value: ");
  Serial.println(analogRead(A0));//输出0-1023 对应 外部输入电压 0-1.0v
  //延时1s
  delay(1000);
}

②、测量系统外部电压:

  • 方法: ESP.getVcc()

  • 单位: mv

  • ADC引脚要悬空。读取前要更改ADC模式(在#include行后面)ADC_TOUT (对外部电压),ADC_VCC(对系统电压),默认读取外部

    /**
     * 功能描述:ESP8266 ADC 读取系统电压
     * 在串口调试器查看效果
     */
    ADC_MODE(ADC_VCC);//设置ADC模式为读取系统电压
    void setup() {
      Serial.begin(115200);
    }
    void loop() {
      Serial.print("ESP8266当前系统电压(mV): ");
      Serial.println(ESP.getVcc());
      delay(1000);
    }

5、模拟输出(PWM):

方法:

  • analogWrite(pin,val) 在指定引脚上启用PWM;pin:GPIO; val:一般0 ~ PWMRANGE,默认PWMRANGE=1023;无返回值;analogWrite(pin,0)相当于禁用指定引脚上的PWM;

  • analogWriteRange(new_range) 改变PWMRANGE数值;new_range:新的PWMRANGE数值;无返回值;(可以调节PWM精度);

  • analogWriteFreq(new_frequency) 改变PWM频率;默认1KHz

    • Arduino For ESP8266的PWM频率范围为100Hz ~40KHz:

      源码:

      static uint16_t analogFreq = 1000;
      extern void __analogWriteFreq(uint32_t freq) {
        if (freq < 100) {
          analogFreq = 100;
        } else if (freq > 40000) {
          analogFreq = 40000;
        } else {
          analogFreq = freq;
        }
      }

例程(呼吸灯):

/**
 * 功能描述:ESP8266 PWM演示例程
 */
#define PIN_LED D6
void setup() {
  pinMode(PIN_LED,OUTPUT);
  analogWrite(PIN_LED,0);
}
void loop() {
  for(int val=0;val<1024;val++){
     //占空比不断增大  亮度渐亮
	 analogWrite(PIN_LED,val);
	 delay(2);
  } 
  for(int val=1023;val>=0;val--){
     //占空比不断变小  亮度渐暗
	 analogWrite(PIN_LED,1023);
	 delay(2);
  }
}

6、串口通信:

与传统Arduino设备完全一样。除硬件FIFO(128字节用于TX和RX)之外,硬件串口还有额外的256字节的TX和RX缓存。发送和接受全部由中断驱动。当FIFO/缓存满时,Write函数会阻塞工程代码执行,等待空闲空间。当FIFO/缓存空时,read函数也会阻塞工程代码的执行,等待串口数据进来。

  • NodeMcu上有两组串口,Serial和Serial1(都是硬件串口)。

    • Serial使用UART0,默认GPIO1(TX)和GPIO3(RX);Serial.begin执行之后,调用Serial.swap()可以将Serial重新映射到GPIO15(TX)和GPIO13(RX)。可来回调用。一般默认

      /**
       * 功能描述:ESP8266 Serial映射例程
       */
      void setup() {
        Serial.begin(115200);
        Serial.println("GPIO1(TX),GPIO3(RX)");
        //调用映射方法
        Serial.swap();
        Serial.println("GPIO15(TX),GPIO13(RX)");
        //重新映射回来
        Serial.swap();
        Serial.println("GPIO1(TX),GPIO3(RX)");
      }
      void loop() {
      }
    • Serial1使用UART1,默认对应GPIO2(TX)。Serial1不能接收数据(RX被flash芯片占用),Serial1.begin(baudrate)

      void setup() {
        Serial.begin(115200);
        Serial.println("Hello Serial");
        Serial1.begin(115200);
        Serial1.println("Hello Serial1");
      }
      void loop() {
      }
  • 若不用Serial1且不映射串口,可将UART0的TX映射到GPIO2:在Serial.begin()之后调用Serial.set_tx(2)或者直接调用Serial.begin(baud,config,mode,2) ;

  • 默认当调用Serial.begin后,将禁用WIFI库的诊断输出,再次启动:Serial.setDebugOutput(true)若将调试输出映射到Serial1时:Serial1.setDebugOutput(true) ;

  • Serial.setRxBufferSize(size_t size)定义接收缓冲区大小,默认256;

  • Serial和Serial1对象都支持5,6,7,8个数据位,奇数(O),偶数(E)和无(N)奇偶校验,1或2个停止位:Serial.begin(baudrate,SERIAL_8N1)

  • 获取当前波特率设置:Serial.baudRate()Serial1.baudRate()

  • ESP8266软件串口功能

  • 检测进入Serial的未知波特率的数据:Serial.detectBaudrate(time_t timeoutMillis) : 尝试在timeoutMillis ms的时间内检测波特率,检测成功返回波特率,失败返回0。detectBaudrate()方法在Serial.begin()之前调用。可使用Serial.begin(detectedBaudrate)

示例(WIFI连接):

/**
 * statin模式下,创建一个连接到可接入点(wifi热点),并且打印IP地址
 */
#include <ESP8266WiFi.h>
 
#define AP_SSID "xxxxx" //这里改成你的wifi名字
#define AP_PSW  "xxxxx"//这里改成你的wifi密码
//以下三个定义为调试定义
#define DebugBegin(baud_rate)    Serial.begin(baud_rate)
#define DebugPrintln(message)    Serial.println(message)
#define DebugPrint(message)    Serial.print(message)
 
void setup(){
  //设置串口波特率,以便打印信息
  DebugBegin(115200);
  //延时2s 为了演示效果
  delay(2000);
  DebugPrintln("Setup start");
  //启动STA模式,并连接到wifi网络
  WiFi.begin(AP_SSID, AP_PSW);
 
  DebugPrint(String("Connecting to ")+AP_SSID);
  //判断网络状态是否连接上,没连接上就延时500ms,并且打出一个点,模拟连接过程
  //笔者扩展:加入网络一直都连不上 是否可以做个判断,由你们自己实现
  while (WiFi.status() != WL_CONNECTED){
    delay(500);
    DebugPrint(".");
  }
  DebugPrintln("");
 
  DebugPrint("Connected, IP address: ");
  //输出station IP地址,这里的IP地址由DHCP分配
  DebugPrintln(WiFi.localIP());
  DebugPrintln("Setup End");
}
 
void loop() {
}

文章作者: 旧时南风
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 旧时南风 !
评论
  目录