Digital IO(数字输入输出接口)
Arduino中的管脚编号和ESP8266 GPIO管脚编号相对应。可以直接使用pinMode
,digitalRead
,digitalWrite
,例如读GPIO2,使用digitalRead(2)
。
引脚 0-15 可以使用INPUT, OUTPUT, INPUT_PULLUP
。 引脚 16 可以使用INPUT, OUTPUT, INPUT_PULLDOWN_16
。 启动时引脚被设置成INPUT
。
引脚也可以用于其他功能,像 Serial, I2C, SPI。这些功能有对应的库。常见的ESP-12模块引脚对应关系如下图。
引脚功能
图中没有显示 6-11引脚,正常情况它们用来连接模块上的闪存芯片。把这些引脚作为IO引脚使用可能导致程序崩溃。
有些开发板和模块(ESP-12ED, NodeMCU 1.0)会把引脚9和11分离出来。如果flash芯片工作在DIO模式下(而不是默认的QIO模式),就可以作为IO使用。
可以通过attachInterrupt
,detachInterrupt
提供引脚中断功能。除GPIO16外,中断可以附加到任何GPIO引脚上。支持标准Arduino中断类型:CHANGE
, RISING
, FALLING
。
Analog input(模拟输入)
ESP8266提供一个ADC通道。它既可用于读取ADC引脚的电压,也可用于读取模块供电电压(VCC)。
若要读取附加在ADC上的外部电压,可以使用analogRead(A0)
。ESP8266输入电压范围是0-1.0V,有些开发板可能会使用分压。安全起见最好<1.0V。例如0.5V在512附近取值,则最大电压为1.0V,但是在150附近取值,则最大电压是3.3V, 3.3V可能会损坏ESP8266。
使用ESP.getVcc()
读取VCC电压,ADC引脚必须断开并在程序中添加如下代码:
ADC_MODE(ADC_VCC);
这行必须在所有函数体外,比如放在#include
行后面。
Analog output(模拟输出)
analogWrite(pin, value)
在指定的引脚上启用PWM功能。PWM可以在0-16引脚上使用。使用analogWrite(pin, 0)
来禁用引脚的PWM功能。value
取值范围在0 - PWMRANGE
,默认是1023,PWM取值范围可以使用analogWriteRange(new_range)
来设定。
PWM默认频率为1kHz。可以用analogWriteFreq(new_frequency)
来改变频率。
Timing and delays(定时和延迟)
millis()
和 micros()
分别返回重置后经过的毫秒数和微妙数。
delay(ms)
程序暂停(毫秒)并允许运行WiFi和TCP/IP任务。delayMicroseconds(us)
程序暂停(微妙)。
当连接WiFi时,除了主程序外还需要在芯片上运行很多代码。每次loop()
函数完成或者调用延时函数,WiFi 和 TCP/IP库都有机会处理挂起的任务。如果你的程序某处有一个循环需要花费很多时间(>50ms)而没有调用延时函数,你可以考虑添加一个延时函数调用来保存WiFi堆栈稳定运行。
还有一个yield()
函数,它相当于delay(0)
。另一个要注意的是delayMicroseconds函数排斥其他任务,因此不推荐使用延迟超过20ms。
Serial(串行)
Serial
对象的工作方式与常规Arduino的工作方式大致相同。 除硬件FIFO(TX和RX为128字节)外,Serial
还有256字节的TX和RX缓冲区。 发送和接收都是中断驱动的。 当相应的FIFO缓冲区满/空时,写和读功能仅打断主程序的运行。 请注意,可以自定义额外的256位缓冲区的长度。
Serial
使用UART0,映射到引脚GPIO1(TX)和GPIO3(RX)。 通过在Serial.begin
之后调用Serial.swap()
,可以将串行重新映射到GPIO15(TX)和GPIO13(RX)。 再次调用Serial.swap()
将UART0映射回GPIO1和GPIO3。
Serial1
使用UART1,TX引脚是GPIO2.UART1不能用于接收数据,因为通常它被用来连接闪存芯片。要使用Serial1
可以调用Serial1.begin(baudrate)
。
如果未使用Serial1
且未交换Serial
,则可以通过在Serial.begin
之后调用Serial.set_tx(2)
或直接使用Serial.begin(baud,config,mode,2)
将UART0的TX映射到GPIO2。
默认情况下,调用Serial.begin
时,将禁用WiFi库的诊断输出。 要再次启用调试输出,请调用 Serial.setDebugOutput(true)
。 要将调试输出重定向到Serial1
,请调用Serial1.setDebugOutput(true)
。
你也需要使用Serial.setDebugOutput(true)
来启用printf()
函数的输出功能。
Serial.setRxBufferSize(size_t size)
方法允许定义接收缓冲区深度。 默认值为256。
Serial
和Serial1
对象都支持5,6,7,8位数据,奇(O),偶(E),无奇偶(N)校验,以及1或2个停止位。 要设置所需模式,请调用Serial.baudRate()
,Serial1.baudRate()
.返回一个表示当前波特率的int
值。例如
Serial.begin(57600); //将波特率设置为57600
int br = Serial.baudRate(); //获取当前波特率
Serial.printf("串口速率是 %d bps", br); //输出 "串口速率是 57600 bps"
Serial
和Serial1
对象都是HardwareSerial
类的实例。
原作者做过ESP8266官方的Software Serial库,具体请查看pull request.
请注意,此实现仅适用于基于ESP8266的模块,不适用于其他Arduino模块。
要检测串行口上未知波特率数据,请使用Serial.detectBaudrate(time_t timeoutMillis)
。 此方法尝试检测波特率最大超时毫秒数。 如果未检测到波特率,则返回零,否则返回检测到的波特率。 可以在调用Serial.begin()
之前调用detectBaudrate()
函数,因为它不需要接收缓冲区和串行配置参数。
UART无法检测其他参数,如启动或停止位数,数据位数或奇偶校验。
检测本身不会改变波特率,检测后应使用Serial.begin(detectedBaudrate)
设置。
检测速度非常快,只需几个输入字节。
SerialDetectBaudrate.ino是一个完整的用法示例。
Progmem(程序)
程序存储器功能与常规Arduino的工作方式大致相同; 将只读数据和字符串放在只读存储器中并为应用程序释放堆栈。 重要的区别在于,在ESP8266上,文字字符串不是合并的。 这意味着在F(“”)
和/或PSTR(“”)
内定义的相同文字字符串将占用代码中每个实例的空间。 因此,你需要自己管理重复的字符串。
有一个辅助宏FPSTR()
可以很方便的将const PROGMEM
字符串传递给__FlashStringHelper
。
String response1;
response1 += F("http:");
...
String response2;
response2 += F("http:");
使用FPSTR...
const char HTTP[] PROGMEM = "http:";
...
{
String response1;
response1 += FPSTR(HTTP);
...
String response2;
response2 += FPSTR(HTTP);
}