如何直接为价廉的ESP8266 WiFi模块编写程序

时间:2022-11-29 22:23:09


如何直接为价廉的ESP8266 WiFi模块编写程序


如果有人说:“我想要一个带有Wifi功能的芯片,那么 ESP8266 无疑是最佳选择。让人惊讶的是,许多工程师和爱好者还未曾听说过这个芯片,或者他们曾经听说过,但并不知道 ESP8266 具备什么功能。ESP8266 基本上可以解决 IoT 领域的许多问题,也可以解决困扰爱好者和市场的许多工程性问题。


ESP8266 是一个处理器,整合了 RAM,一些 ROM,一个 Wifi 发射器,你只需准备如下外部设备即可:4个电容器,一个晶振和一个外部闪存。ESP8266价格并不昂贵,每片仅售约4美元!如果你想把 ESP8266 放在一个功能强大、使用方便且包括了上述所有外部设备的载板上,你只需花5美元。ESP8266 的功耗相对合理1,其信号传输距离之长却让人感到不可思议:无需使用定向设备,其信号传输距离可达3002。如果使用板载PCB天线,其信号传输距离甚至可以达到4千米!


人们需要知道的另一件事情是,如何直接为 ESP8266 芯片编写程序。很多时候,很多工程通过AT指令把ESP8266用作一个支撑。请继续阅读本文,看看如何为这款芯片编写程序。

了解ESP8266芯片

首先,让我们了解一些背景知识。让我们先看看 ESP8266 的照片(由zeptobars开封),图片由swimmmerdude标记。

如何直接为价廉的ESP8266 WiFi模块编写程序

处理器默认频率为80MHz,但是可以提高到160MHz。ESP8266拥有约80KB的DRAM,约35KB的IRAM。是的,这意味着ESP8266使用了哈佛架构。指令内存在启动任意程序时加载,尽管处理器能够以较低速度直接运行外部闪存中的代码。

固件背景信息

当你购买这些外形整洁、体积很小的开发板时,许多开发板默认都带有“AT”固件,这是一个简单易用的工具,能让你把这些工具当做简单的无线调制解调器使用,这些调制解调器通过一个串行接口控制。总而言之,ESP8266 简便易用,但是如果要使用 ESP8266 做一些特别复杂的任务的话,那么还是比较困难的。正如我在上文提到的,这需要使用一个外部处理器。

如何直接为价廉的ESP8266 WiFi模块编写程序

两个不同的 ESP8266 模块

根据部分 GPIO 引脚的具体设置,ESP8266 芯片可以引导数种模式。由于许多爱好者尚未真正开始做这件事,我们将不会讨论“SD卡启动,但是我们将讨论 Flash 启动和 UART 下载。此外,还具备远程固件上传功能,该功能有不同的修正版本、具备不同的可能性,我们将在另外一篇文章中讨论这个问题。

对于我们关心的两个模式,ESP8266 处理器启动时希望拉低 GPIO15,而拉高 GPIO2 。 GPIO0 在我们将要讨论的两个模式之间切换。在正常运行过程中,我们需要使用电容器拉高 GPIO05。这将促使 ESP8266 内部的引导程序从EEPROM芯片中读取数据到 ESP8266 的IRAM中,从而引导我们的程序。但是,如果我们拉低 GPIO0 ,ESP8266 内的引导 ROM 将会启动,然后通过 UART 开始交互。通过使用引导 ROM ,我们可以把程序推到闪存记忆中。使用上述方法的较好方式是连接来自 GPIO0的交换器,这样你可以通过打开开关,把它随意切换为程序模式。

这非常可靠,甚至可以支持不同波特率。我把波特率设定为454800,因此我可以修改我的程序,并且可以快速地测试这些程序。其中一个项目用了一秒钟不到就完成了汇编,花了大约8秒钟完成烧毁。有官方工具可以上传固件 “XTCOM”,但是,我个人更喜欢使用 esptool.py,因为它可以自动刷新。此外,一旦完成刷新芯片,即使 GPIO0 固定在低位,它也会促使你的固件运行起来。然后,如果你的代码重新启动,它将会自动重新进入引导程序,为另外一个编程周期做准备。这意味着你可以在开发时,保持 GPIO0 连接到 GND

如何直接为价廉的ESP8266 WiFi模块编写程序

总而言之,我们的开发工具看起来如下:

· 来自于GPIO0的交换器(上拉电阻一端接到VCC)

· GPIO2 和 CH_PD连接到VCC

· GPIO15 连接到地

· USB 连接到TTL UART 适配器,与 ESP8266 交互,为芯片 USB 供电且电压为3.3V的稳压器提供5V电压

顺便说一句,你可以购买到价格和 TTL级别的 UART 一样便宜的 USB,请访问 electrodragon 网站,购买价格低于1美元/片的芯片!

工具链

在刚开始的时候,为ESP8266芯片编写程序有一些困难,但你一旦开始做,事情就会变得非常简单。在 Linux 和 OSX平台上制作工具链,你有多项选择,在Windows平台上你也有多个选择。我尝试在我的 ws2812esp8266 自述文件中列出一个工具链清单,并尽力更新这个清单。制作工具链的具体细节不在这篇文章的讨论范围内,但是如果你遵守了这个手册,或者这个可能内容更新的工具链教程,你应该不会再碰到什么难题。一旦你成功制作出一个工具链,你就可以汇编一个固件(就像我的 WS2812ESP8266 固件),那么阅读下面的文章对你来说应该会变得很容易。

乐鑫免费发放 SDK,这一点做得非常好。7这个举动对整个社区都产生了极大震撼!这个举动非常慷慨,很少有公司这么做。乐鑫的 SDK 包含一个示例、ROM 的头信息以及乐鑫的库。重要的是,我们应该注意到有一个社区库,但是每次我使用这个社区库的时候,我都会觉得社区库的成熟度没有乐鑫的库的成熟度高。也许未来这会有所改变。

请务必检查乐鑫 SDK 中的“include”文件夹。这个文件夹中包括了许多非常棒的功能,能帮助你在极短时间内从菜鸟变成绝顶高手!

编程:存在一个ROM

为 ESP8266 编写程序时,需要注意一些事情。其中一件是 ROM 中集成了一些你可以使用的函数。这意味着你无需(也不该)重新执行 MD5 即使有hmac),SHA1带有外部闪存的通讯软件,SPIUART函数,软件浮点功能,AES,内存命令,printf,低位输入输出工具,甚至是一个实时的事件调度程序,以及最重要的802.11


芯片上 ROM 中包含的功能的完整列表可以在 eagle.rom.addr.v6.ld 中找到。这会吸引你看一看 eagle.rom.addr.v6.ld,发现很棒的东西。


除了芯片上的 ROM 之外,乐鑫 API 具备更多功能,可以让使用 ESP8266 变得非常简单。我们可以看到许多促进工具。因为 ESP8266 可以作为接入点或者客户端发挥作用(或者两个都可以,尽管我从来没有尝试过),ESP8266 具备多种你可以使用的功能。默认情况下,ESP8266 拥有自己特定的 API,如果你给 ESP8266 供电,并启动 API,它将开启主机模式,运行自己的 DHCP 服务器。你可以通过寻找无线网找到它。

拥抱抽象

如果你希望写主函数并且有自己的主回路,这将不会发生。虽然你可以写主函数,但预计 API 将会获得自己的主回路。从这层意义上说,为 ESP8266 编写程序和为 Arduino 编写程序非常相似。

static void ICACHE_FLASH_ATTR procTask(os_event_t *events)
{
system_os_post(procTaskPrio, 0, 0 );
printf( "Idle Task\n" );
}


void user_init(void)
{
system_os_task(procTask, procTaskPrio, procTaskQueue, procTaskQueueLen);
system_os_post(procTaskPrio, 0, 0 );
}

如果你需要事件以固定时间间隔发生的话,也有计时函数,比如 os_timer_setfn, os_timer_arm,可以在固定的时间间隔调用一个函数。

对整个开发环境来说,这简直是太棒了。但是,实际上我们还没有讨论如何使用 ESP8266 的功能完成任何任务。让我们讨论一下如何使用802.11。如果你害怕了,我并不会责备你。试着改变802.11的设置或者连接到网络,etc 是一个让人感到害怕的提议。曾经尝试在 Linux 系统或者 Windows 系统中编写程序吗?这真让人感到害怕。但是在 ESP8266上,这是一件非常简单的事!

用八行代码把ESP8266连接到AP

一旦启动你的ESP8266,如果在它应当连接到现有网络时发生了一些意外的话,写入下面的代码,就会连接到AP

const char ssid[32] = "my_home_ssid";
const char password[32] = "my_home_password";

struct station_config stationConf;

wifi_set_opmode( STATION_MODE );
os_memcpy(&stationConf.ssid, ssid, 32);
os_memcpy(&stationConf.password, password, 32);
wifi_station_set_config(&stationConf);
wifi_station_connect();

是的,就是这么简单。ESP8266 就连接到了你的 AP获得一个IP并且停留在那儿。非常简单。最重要的是,ESP8266 将记住这个操作,下次你启动它时,它将立刻连接到 AP。当我把 ESP8266 连接到一个信号较好的 AP 上之后,它就可以在启动后两秒自动连接到 AP 上。是的,速度就是这么快。

为TCP服务

如果让一个 TCP 服务器可以监听端口并且发送回数据将会怎么样?当然这很困难。并非如此。下面是一个来自 HTTP 服务器的例子:

//Allocate an "espconn"
pHTTPServer = (struct espconn *)os_zalloc(sizeof(struct espconn));
ets_memset( pHTTPServer, 0, sizeof( struct espconn ) );

//Initialize the ESPConn
espconn_create( pHTTPServer );
pHTTPServer->type = ESPCONN_TCP;
pHTTPServer->state = ESPCONN_NONE;

//Make it a TCP conention.
pHTTPServer->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
pHTTPServer->proto.tcp->local_port = 80;

//"httpserver_connectcb" gets called whenever you get an incoming connetion.
espconn_regist_connectcb(pHTTPServer, server_connectcb);

//Start listening!
espconn_accept(pHTTPServer);

//I don't know what default is, but I always set this.
espconn_regist_time(pHTTPServer, 15, 0);

怎样接收连接呢?请根据下面的步骤操作:

//This function gets called whenever
void ICACHE_FLASH_ATTR server_connectcb(void *arg)
{
int i;
struct espconn *pespconn = (struct espconn *)arg;

//espconn's have a extra flag you can associate extra information with a connection.
pespconn->reverse = my_http;

//Let's register a few callbacks, for when data is received or a disconnect happens.
espconn_regist_recvcb( pespconn, http_recvcb );
espconn_regist_disconcb( pespconn, http_disconnetcb );
}

就是这么简单。发送数据? espconn_sent。关闭连接? espconn_disconnect。无论说明时候你获得数据,都将通过 recv 回调函数进行传递。

你可能已经注意到我使用了 ICACHE_FLASH_ATTR 指令,是吧?嗯,你是否记得我们没有太多 IRAM 时发生的情况了吗?这样做会保证函数存在于闪存上。指令被缓存,但是从闪存上加载却不会花太多时间。 

与GPIO协同工作

在这篇文章中我想讨论的最后一个问题是 GPIO。引脚有可选的内部上拉电阻(GPIO0..15)和下拉电阻(GPIO0..16)。它们都可以配置为输入或者输出。有许多效用函数可以处理 GPIO 问题。你需要调用 gpio_init(…) ,有些是宏命令,比如 PIN_PULLDWN_DIS(…),PIN_PULLUP_EN(…)以及其它一些可以在 SDK 中找到的函数。你可以使用 gpio_output_set 配置输入/输出。许多 GPIO 可能具备许多功能,有些功能是默认的,比如说,在启动时,除非 GPIO12 和 GPIO14 被选择为 GPIO ,否则,你无法对 GPIO12 和 GPIO14 执行任何操作。

    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12); 
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14);

学习如何为ESP8266编写程序就像和在其它环境中学习编写程序一样。当你试图弄清具体情况时,或者看看是否有更简便的方法去实现你的目标时,SDK提供的头信息文件夹的帮助非常大。目前为止,数据表对我的帮助还不是特别大,但是,Google是目前为止搜索关于ESP8266信息的最佳工具。

社区

因为 ESP8266 可以解决很多问题,它已经让爱好者社区为之倾倒!在类似于esp8266.com 和俄罗斯论坛 esp8266.ru 等论坛上,许多人都在尝试使用 ESP8266 去做一些非常棒的事情!论坛上有很多人都在相互学习,研究如何发挥 ESP8266 的最大功能。

资源

[1] A general wiki for a lot of information surrounding this chip such as electrical characteristics, etc. Much of this is translated from the Chinese data sheets. https://nurdspace.nl/ESP8266

[2] Range tests I performed on the ESP8266. https://www.youtube.com/watch?v=7BYdZ_24yg0

[3] The reddit post where swimmmerdude gave his guesses at what the decapped chip looks like http://www.reddit.com/r/electronics/comments/2jq22l/esp8266_wifiserial_chip_decapped_its_actually/

[4] Memory map for address space, SPI Flash layout, registers including IOMUX: https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map

[5] Discussion on the start modes of the ESP8266: http://www.esp8266.com/viewtopic.php?f=6&t=33

[6] The esptool.py site that contains information about uploading programs to the ESP8266 and alternative wiring schemes that can help with flashing. https://github.com/themadinventor/esptool/

[7] The official espressif post for the ESP SDK 0.9.5 http://bbs.espressif.com/viewtopic.php?f=5&t=154

Posted in Featuredhow-tosliderwireless hacks Tagged 802.11cnlohrESP8266espressifprogrammingtoolchaintutorialwifi

版权声明:

本译文仅用于学习和交流目的。非商业转载请注明译者、出处,并保留文章在译言的完整链接。

原文来源http://hackaday.com/

原文标题:How to Directly Program an Inexpensive ESP8266 WiFi Module

原文地址:http://hackaday.com/2015/03/18/how-to-directly-program-an-inexpensive-esp8266-wifi-module/