01

写在前面;

     上篇关于如何在内置仅1M的Esp8285做到 OTA 升级的同步到微信公众号,竟然被安信可的某些运维人员看到了,想要转载,我很欣慰,竟然自己的笔记可以被这么大型的公司员工认可!

     我是一个非常热爱学习的程序员,单单是乐鑫的 esp8266esp32 我个人花钱买的开发板都忘记有多少个了,而且还玩安信可的 A9g,或者是 ble mesh 模块,下面晒晒我的最近的开发板,我是每天带着他们上下班的,有时候还带回宿舍开发;

     写完这差不多50篇关于 esp8266的文章,我发现我沉迷挚爱 esp8266了,因为我2017年当初毕业的时候对计算机网络也是一概不通,对于 Wi-Fi 网络协议不知从何学起,其实 Wi-Fi 网络协议我觉得是最简单的,不用担心 OSI七层模型与 TCP/IP五层模型的关系(这是我后面恶补的),绝对目前大多数应用是应用层开发,就是我们常说的 TcpudpMqttlora 等协议,当你接触最近兴起的 BleMesh 或者 天猫精灵蓝牙直连的 Sigmesh协议之后,你才发现是多么难学!!

     之前说过的乐鑫esp32做蓝牙耳机或者官网的 esp-adf 框架一些 demo ,我后面会陆陆续续地开源出来,当然了,我不是说自己多牛逼,我也是借鉴前辈技术,站在巨人肩膀上领域学习!只是有这么一颗心,助国内物联网蓬勃发展贡献自己一份努力!

   

使用android 写一个串口发送_android 串口通信


上电后串口打印数据不能取消;


  esp8266从最早设计的 SDK 版本开始,上电开机打印都是不可取消的,这是乐鑫官网当初设计的,我觉得这个是蛮合理的,至少我们从串口打印知道上电后设备的一些情况,比如电压电流不够?上次软件或硬件看门狗复位?还是非法指针导致?

     当然也有不合理的情况,就是在我们正常串口通讯时候,上电开机总是伴有乱码,不友好的表现。

     我们知道,只要我们的数据发现乱码,我们立即就会调串口工具的波特率到 74880 ,您知道这个数字为何这么特别么?因为他是和模块的晶振有关,毕竟我们最最常用的 安信可 esp8266 模块都是基于 26Mhz的晶振,所以是 74880 ,下面是官网抠出来的默认波特率和晶振大小关系表,当您的晶振变了,默认波特率记得查询这个!

使用android 写一个串口发送_android串口通信_02

上电后的打印数据的详细分析;


      以下信息由乐鑫官网人员乐呵乐呵的CSDN博客参考:

      ESP8266 上电时打印的 boot 模式信息代表什么?如何改变 boot 模式?

      ESP8266 上电时会判断 boot strapping 管脚的状态,并决定 boot 模式。例如,ESP8266 上电时打印的 boot 模式信息如下:

ets Jan 8 2013,rst cause:1, boot mode:(3,2)


     其中打印的 boot mode 的第一位数字(3)代表当前的 boot 模式。     Boot 模式由 strapping 管脚的 3 位值 [GPIO15,GPIO0,GPIO2] 共同决定。如下表所示:

使用android 写一个串口发送_android 串口开发_03

 烧写失败定位?

确保 boot 模式在 UART boot.

     将 ESP8266 拨到烧写模式,看烧写口的 log(默认 74880 查看). 正常烧写应该是 boot mode:(1,n), 其中n任意,第二个参数和 SDIO 相关,不用关心!

     看 log 乱码/无打印定位,确保 boot 模式在 Flash boot!

     将 ESP8266 拨到运行模式,看 log 口的输出. 正常log应该是 boot mode:(3,n),第二个参数和 SDIO 相关,不用关心!

  • 1.确保波特率正确
  • 2.确保无串口占用

3.1

判断是什么原因重启设备?

     我觉得这个最大的用处就是可以判断上次死机或其他原因重启的原因,我上个公司开发的灯具无缘无故亮了起来,于是乎我加了这个,就可以知道是否用户控制电源开关导致硬件重启,还是软件异常导致,如果是软件异常导致则继续执行上次的灯的状态(比如是关灯,然而软件异常导致重启竟然开灯!半夜吓得客户投诉!!)但是有了这个判断之后,就是只要是软件重启之后都是关灯啦!


     这个代码可以判断是否软件复位或者硬件复位,或者判断是否正常重启(包括看门狗复位、非法指针);

适合 3.0SDK 以下:
 
   
  
 struct rst_info *rtc_info = system_get_rst_info();
 
   
  
 printf( "reset reason: %x\n", rtc_info->reason);
 
   
  
 if (rtc_info->reason == REASON_WDT_RST ||
 
   
  
 rtc_info->reason == REASON_EXCEPTION_RST ||
 
   
  
 rtc_info->reason == REASON_SOFT_WDT_RST){
 
   
  
 if (rtc_info->reason == REASON_EXCEPTION_RST)
 
   
  
 {
 
   
  
 GIZWITS_LOG("Fatal exception (%d):\n", rtc_info->exccause);
 
   
  
 }
 
   
  
 printf( "epc1=0x%08x, epc2=0x%08x, epc3=0x%08x, excvaddr=0x%08x, depc=0x%08x\n",
 
   
  
 rtc_info->epc1, rtc_info->epc2, rtc_info->epc3, rtc_info->excvaddr, rtc_info->depc);
 
   
  
 }
 
   
  
      适合 rtos 3.0 idf 的思路:
     通过调用 esp_reset_reason();的返回值判断,我也草草人工翻译了下,毕竟有些我也是不常用:
 
   
  
/**
 
   
  
 * @brief Reset reasons
 
   
  
 */
 
   
  
typedef enum {
 
   
  
 ESP_RST_UNKNOWN = 0, //!< Reset reason can not be determined
 
   
  
 ESP_RST_POWERON, //!< Reset due to power-on event 电源复位
 
   
  
 ESP_RST_EXT, //!< Reset by external pin (not applicable for ESP8266)
 
   
  
 ESP_RST_SW, //!< Software reset via esp_restart 代码调用esp_restart()方法复位
 
   
  
 ESP_RST_PANIC, //!< Software reset due to exception/panic 代码异常
 
   
  
 ESP_RST_INT_WDT, //!< Reset (software or hardware) due to interrupt watchdog 软件或硬件中断异常导致看门狗
 
   
  
 ESP_RST_TASK_WDT, //!< Reset due to task watchdog 任务超时导致看门狗复位
 
   
  
 ESP_RST_WDT, //!< Reset due to other watchdogs 其他看门狗
 
   
  
 ESP_RST_DEEPSLEEP, //!< Reset after exiting deep sleep mode 睡眠模式唤醒导致
 
   
  
 ESP_RST_BROWNOUT, //!< Brownout reset (software or hardware)
 
   
  
 ESP_RST_SDIO, //!< Reset over SDIO
 
   
  
} esp_reset_reason_t;
 
   
  
四
01
串口通信时候如何做到上电后不乱吗打印?
    上面不是说了 上电后必然乱码打印 吗?这下怎么又说了如何做到上电后不乱码打印?嗯,是的,我是做到了!不过,我是现在的管脚和原本的通讯管脚通过交换了管脚,但是原本的通讯管脚依然是乱码打印的哈!
     2 个 UART 接⼝的数据传输均由硬件实现。数据传输速度可达 115200*40(4.5Mbps)。UART0 可以⽤做通信接⼝,⽀持流控。由于 UART1 ⽬前只有数据传输功能,所以⼀般⽤作打印 log。
     esp8266有2组串口,下面表所示:
 
     为了不影响上电后串口通讯,上电期间将 U0TXD、U0RXD 分别与 U0RTS (MTDO),U0CTS(MTCK) 交换,以屏蔽打印。 下面就是教程,如何交换!!
     因为最近是做 rtos3.0 版本的项目,所以这只研究 rtos3.0 版本的!只教大家如何在 rtos3.0 版本代码实现:
4.1
方法1
    直接调用 uart_enable_swap(); 即可:比如下面代码:
 
   
  
#define BUF_SIZE (1024)
 
   
  
static void echo_task()
 
   
  
{
 
   
  
 uart_enable_swap(); //交换
 
   
  
 uart_config_t uart_config = {
 
   
  
 .baud_rate = 9600,
 
   
  
 .data_bits = UART_DATA_8_BITS,
 
   
  
 .parity = UART_PARITY_DISABLE,
 
   
  
 .stop_bits = UART_STOP_BITS_1,
 
   
  
 .flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
 
   
  
 uart_param_config(UART_NUM_0, &uart_config);
 
   
  
 uart_driver_install(UART_NUM_0, BUF_SIZE * 2, 0, 0, NULL);
 
   
  
 // Configure a temporary buffer for the incoming data
 
   
  
 uint8_t *data = (uint8_t *) malloc(BUF_SIZE);
 
   
  
 while (1) {
 
   
  
 // 读取数据
 
   
  
 int len = uart_read_bytes(UART_NUM_0, data, BUF_SIZE, 20 / portTICK_RATE_MS);
 
   
  
 if (!len)
 
   
  
 continue;
 
   
  
 // Write data back to the UART
 
   
  
 uart_write_bytes(UART_NUM_0, (const char *) data, len);
 
   
  
 }
 
   
  
}
 
   
  
4.2
方法2
     通过在 make menuconfig 配置 ,首先我们必须要串口一(GPIO2)打印日志,但是串口0用作串口通讯!
 
   
  
 ----> component config
 
   
  
 ----> ESP8266-specific
 
   
  
 ----> [*] swap Uart0 I/O pins




使用android 写一个串口发送_使用android 写一个串口发送_04


4.3

交换之后的接线图;

             既然提到了用 GPIO13和GPIO15做通信管脚,那么接线如下:

使用android 写一个串口发送_android 串口开发_05