ESP8266( 多)玩法
本文章中有很多參考,如有侵權,請告知,第一時間洗掉!
本人第一次寫博客,寫的不好莫見怪,
文章目錄
- ESP8266( 多)玩法
- 一、 基礎知識
- 針腳
- 引導期間使用的引腳
- 引導時引腳為高電平
- **[參考帖子](https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/)**
- 記憶體
- 二、環境配置
- 編程環境
- 三、玩法
- 1.控制舵機(物聯網開關)
- 2.led螢屏顯示 Hello World
- 3.WebServer控制開關
- 4.WebServer+OLED顯示狀態
- 5.傳感器獲取(DHT11)
- 6.WiFi時鐘
- 待續
- 參考論壇
一、 基礎知識
針腳
針腳與開發板印刷是不一一對應的!!!
這里使用的是nodemuc,其實就是把ESP8266集成了CH340/CP2100 編碼燒寫器的開發板,好處是所有的針腳都引出來了,更好的拓展性,
另外,針腳的使用也有一點的規則:
引導期間使用的引腳
如果某些引腳被拉低或拉高,則可以防止 ESP8266 啟動, 以下串列顯示了以下引腳在 BOOT 上的狀態:
- GPIO16: 引腳在 BOOT 時為高電平
- GPIO0: 如果拉低啟動失敗
- GPIO2 :引腳在 BOOT 時為高電平,如果拉低則啟動失敗
- GPIO15 :如果拉高則啟動失敗
- GPIO3 :引腳在 BOOT 時為高電平
- GPIO1 : 引腳在 BOOT 時為高電平,如果拉低則啟動失敗
- GPIO10 :引腳在 BOOT 時為高電平
- GPIO9 :引腳在 BOOT 時為高電平
以綠色突出顯示的引腳可以使用, 以黃色突出顯示的那些可以使用,但您需要注意,因為它們可能主要在啟動時出現意外行為, 不建議將紅色突出顯示的引腳用作輸入或輸出,
| 標簽 | 通用輸入輸出介面 | 輸入 | 輸出 | 筆記 |
|---|---|---|---|---|
| D0 | GPIO16 | 沒有中斷 | 不支持 PWM 或 I2C | 開機時高 習慣從深度睡眠中醒來 |
| D1 | GPIO5 | 行 | 行 | 通常用作 SCL (I2C) |
| D2 | GPIO4 | 行 | 行 | 通常用作 SDA (I2C) |
| D3 | GPIO0 | 拉上來 | 行 | 連接到FLASH按鈕,如果拉低啟動失敗 |
| D4 | GPIO2 | 拉上來 | 行 | 開機時高 連接到板載 LED,如果拉低啟動失敗 |
| D5 | GPIO14 | 行 | 行 | SPI (SCLK) |
| D6 | GPIO12 | 行 | 行 | SPI (味噌) |
| D7 | GPIO13 | 行 | 行 | SPI (MOSI) |
| D8 | GPIO15 | 拉到地 | 行 | SPI (CS) 如果拉高啟動失敗 |
| 接收 | GPIO3 | 行 | RX pin | 開機時高 |
| TX | GPIO1 | TX引腳 | 行 | 開機時高 啟動時的除錯輸出,如果拉低啟動失敗 |
| A0 | ADC0 | 模擬輸入 | X |
引導時引腳為高電平
當 ESP8266 啟動時,某些引腳會輸出 3.3V 信號, 如果您將繼電器或其他外圍設備連接到這些 GPIO,這可能會出現問題, 以下 GPIO 在啟動時輸出高電平信號:
- GPIO16
- GPIO3
- GPIO1
- GPIO10
- GPIO9
參考帖子
記憶體
總的flash只有4MB,
nodemcu給程式的容量是1MB,編程時盡量不要超過1MB,這是指編譯后的大小,IDE會提示的,
還有3MB左右的data空間,系統韌體什么的也在這3MB里,
二、環境配置
- 安裝Arduino
- 安裝CH340/CP2100的串口驅動
- 查看開發板的串口編號(COM X)
編程環境
ESP8266和nodemuc都沒有官方的編程軟體,但是可以通過Arduino安裝ESP的拓展包來對ESP編程,
拓展–檔案—>首選項—>添加網址:http://arduino.esp8266.com/stable/package_esp8266com_index.json


然后添加庫 工具–>庫管理:添加8266的庫和需要或者相關的庫,沒有庫編譯呼叫是會報錯的,
之后重啟IDE即可,,,,,,,
三、玩法
1.控制舵機(物聯網開關)
這里使用的是D4口(GPIO2),舵機有三根線,
| 顏色 | 功能 |
|---|---|
| 紅 | 電源(3–6)V |
| 黑 | 地 GND |
| 黃 | pmw信號 |
pmw是通過調節一個固定周期為2.5毫秒的方波的占空比來實作轉動(舵機的旋轉度數)
最簡單的控制舵機的代碼
#include<Servo.h> //參考庫
Servo myservo; //創建物件
int dmax,dmin; //定義旋轉角度
void setup(){
myservo.attach(2,554,2500);//(針腳,方波最小,方波最大)
}
void loop(){
myservo.write(dmin); //旋轉最小
delay(1500); //延遲1.5s
myservo.write(dmax); //旋轉最大
delay(1500);
}
當然也可以縫合:
//..........................//與其他一樣,縫合庫,申明什么的
Servo myservo;
myservo.attach(2,554,2500);
myservo.write(30);
//..........................
//這里是縫合了點燈科技的代碼
void button2_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
digitalWrite(5, !digitalRead(5));//*一個普通的控制一個引腳的高低電平,前面還有設定針腳模式的,具 體看官方檔案*//
if(digitalRead(5)==1){ //這里判斷針腳電平
duoji(1); //轉60度
}
else if(digitalRead(5)==0){
duoji(2); //轉回0度
}
}
void duoji(int d){ //普通的函式呼叫
switch(d){
case 1:myservo.write(60);break;//轉60度
case 2:myservo.write(0);break; //轉回0度
}
//delay(1500);
}
這個代碼有一個缺陷,就是控制一個IO口的電平,還有舵機PMW信號輸出又占用一個IO,對于IO口少的開發板就不是很友好,相當于浪費了一個io,當然也有其他解決方法,比如接個燈泡或者繼電器,或者直接編程通過網頁讓io口直接輸出想要的信號,這就涉及到網頁http請求了,我也不是很透徹,
這里是完整的代碼,修改自己的WiFi和密碼和阿里云密鑰即可:(pmw口是GPIO2)
#define BLINKER_WIFI
#define BLINKER_WITHOUT_SSL
#include <Blinker.h>
#include<Servo.h>
Servo myservo;
char auth[] = "********";//密鑰
char ssid[] = "********";//wifi名字
char pswd[] = "********";//密碼
// 新建組件物件
BlinkerButton Button1("btn-abc");//板載led
BlinkerButton Button2("btn-2");
BlinkerButton Buttond("btn-d"); //舵機
BlinkerNumber Number1("num-abc");
int counter = 0;
// 按下按鍵即會執行該函式
void button1_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
void button2_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
digitalWrite(5, !digitalRead(5));
if(digitalRead(5)==1){
duoji(1);
}
else if(digitalRead(5)==0){
duoji(2);
}
}
void buttond_callback(const String & state)
{
BLINKER_LOG("get button state: ", state);
// digitalWrite(2, !digitalRead(2));
}
void duoji(int d){
switch(d){
case 1:myservo.write(60);break;
case 2:myservo.write(0);break;
}
//delay(1500);
}
// 如果未系結的組件被觸發,則會執行其中內容
void dataRead(const String & data)
{
BLINKER_LOG("Blinker readString: ", data);
counter++;
Number1.print(counter);
}
void setup()
{
// 初始化串口
Serial.begin(115200);
BLINKER_DEBUG.stream(Serial);
BLINKER_DEBUG.debugAll();
// 初始化有LED的IO
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
// 初始化blinker
Blinker.begin(auth, ssid, pswd);
Blinker.attachData(dataRead);
myservo.attach(2,554,2500);
myservo.write(30);
Button1.attach(button1_callback);
Button2.attach(button2_callback);
Buttond.attach(buttond_callback);
}
void loop() {
Blinker.run();
}
2.led螢屏顯示 Hello World

介面這里使用的是D1(GPIO5), D2(GPIO4),具體接法:**
| nodemcu | OLED | 說明 |
|---|---|---|
| D1 | SCL | 串口iis |
| D2 | SDA | 串口iis |
| VCC | VCC | 電源 |
| GND | GND | 地 |
具體代碼:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//庫
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
//解析度
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
delay(2000); //初始化螢屏
display.clearDisplay(); //清屏
display.setTextSize(1); //顯示字號
display.setTextColor(WHITE); //顏色
display.setCursor(0, 10); //位置
// Display static text
display.println("Hello, world!"); //顯示文本
display.display();
}
void loop() {
}
就是這么簡單!具體使用縫合看你的腦袋了,比如很火的wifi時鐘,粉絲計數器等,,,,,
3.WebServer控制開關
訪問esp的ip即可,控制這幾個埠的高低電位,接上繼電器也是物聯網開關,
這里就用到了**http** 協議的 GET 和**POST**了
流程就是–>esp聯網–>提供webserver設定變數系結—>psot/get 變數值—>IO輸出–>回圈
代碼:
別看代碼長,其實是添加了HTML代碼,CSS代碼,JS代碼的,使用略微長,也可以呼叫閃存來存盤網頁代碼,
// Import required libraries
#include "ESP8266WiFi.h"
#include "ESPAsyncWebServer.h"
// Set to true to define Relay as Normally Open (NO)
#define RELAY_NO true
// Set number of relays
#define NUM_RELAYS 5
// Assign each GPIO to a relay
int relayGPIOs[NUM_RELAYS] = {5, 4, 14, 12, 13};
// Replace with your network credentials
const char* ssid = ""; //wifi
const char* password = ""; //
const char* PARAM_INPUT_1 = "relay";
const char* PARAM_INPUT_2 = "state";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 3.0rem;}
p {font-size: 3.0rem;}
body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
.switch {position: relative; display: inline-block; width: 120px; height: 68px}
.switch input {display: none}
.slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 34px}
.slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px}
input:checked+.slider {background-color: #2196F3}
input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
</style>
</head>
<body>
<h2>ESP Web Server</h2>
%BUTTONPLACEHOLDER%
<script>function toggleCheckbox(element) {
var xhr = new XMLHttpRequest();
if(element.checked){ xhr.open("GET", "/update?relay="+element.id+"&state=1", true); }
else { xhr.open("GET", "/update?relay="+element.id+"&state=0", true); }
xhr.send();
}</script>
</body>
</html>
)rawliteral";
// Replaces placeholder with button section in your web page
String processor(const String& var){
//Serial.println(var);
if(var == "BUTTONPLACEHOLDER"){
String buttons ="";
for(int i=1; i<=NUM_RELAYS; i++){
String relayStateValue = relayState(i);
buttons+= "<h4>Relay #" + String(i) + " - GPIO " + relayGPIOs[i-1] + "</h4><label class=\"switch\"><input type=\"checkbox\" οnchange=\"toggleCheckbox(this)\" id=\"" + String(i) + "\" "+ relayStateValue +"><span class=\"slider\"></span></label>";
}
return buttons;
}
return String();
}
String relayState(int numRelay){
if(RELAY_NO){
if(digitalRead(relayGPIOs[numRelay-1])){
return "";
}
else {
return "checked";
}
}
else {
if(digitalRead(relayGPIOs[numRelay-1])){
return "checked";
}
else {
return "";
}
}
return "";
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
// Set all relays to off when the program starts - if set to Normally Open (NO), the relay is off when you set the relay to HIGH
for(int i=1; i<=NUM_RELAYS; i++){
pinMode(relayGPIOs[i-1], OUTPUT);
if(RELAY_NO){
digitalWrite(relayGPIOs[i-1], HIGH);
}
else{
digitalWrite(relayGPIOs[i-1], LOW);
}
}
// Connect to Wi-Fi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
// Print ESP8266 Local IP Address
Serial.println(WiFi.localIP());
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", index_html, processor);
});
// Send a GET request to <ESP_IP>/update?relay=<inputMessage>&state=<inputMessage2>
server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
String inputMessage;
String inputParam;
String inputMessage2;
String inputParam2;
// GET input1 value on <ESP_IP>/update?relay=<inputMessage>
if (request->hasParam(PARAM_INPUT_1) & request->hasParam(PARAM_INPUT_2)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
inputParam2 = PARAM_INPUT_2;
if(RELAY_NO){
Serial.print("NO ");
digitalWrite(relayGPIOs[inputMessage.toInt()-1], !inputMessage2.toInt());
}
else{
Serial.print("NC ");
digitalWrite(relayGPIOs[inputMessage.toInt()-1], inputMessage2.toInt());
}
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
Serial.println(inputMessage + inputMessage2);
request->send(200, "text/plain", "OK");
});
// Start server
server.begin();
}
void loop() {
}
4.WebServer+OLED顯示狀態
顯示當前控制IO口的狀態

IP 網頁
這個代碼就是典型的縫合,縫合了oled顯示,和webserver控制io口,滑稽!
/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com
*********/
// Load Wi-Fi library
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// Replace with your network credentials
// Replace with your network credentials
const char* ssid = ""; //WIFI資訊
const char* password = ""; //
//String c;
//int a1,a2,a3;
// Set web server port number to 80
WiFiServer server(80);
// Variable to store the HTTP request
String header;
// Auxiliar variables to store the current output state
String output14State = "off";
String output12State = "off";
String output2State = "off";
// Assign output variables to GPIO pins
const int output14 = 14;
const int output12 = 12;
const int output2 = 2;
// Current time
unsigned long currentTime = millis();
// Previous time
unsigned long previousTime = 0;
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;
void setup() {
Serial.begin(115200);
// Initialize the output variables as outputs
pinMode(output14, OUTPUT);
pinMode(output12, OUTPUT);
pinMode(output2, OUTPUT);
// Set outputs to LOW
digitalWrite(output14, LOW);
digitalWrite(output12, LOW);
digitalWrite(output2, LOW);
// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
}
void lcddisplay(){
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
delay(200);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 10);
//display.printf("%s\n",s);
if(output2State=="on"&&output14State=="on"&&output12State=="on")
{//7
display.printf("G2:ON\nG14:ON\nG12:ON");
}
else if(output2State=="off"&&output14State=="off"&&output12State=="off")
{//0
display.printf("G2:OFF\nG14:OFF\nG12:OFF");
}
else if(output2State=="off"&&output14State=="off"&&output12State=="on")
{//1
display.printf("G2:OFF\nG14:OFF\nG12:ON");
}
else if(output2State=="off"&&output14State=="on"&&output12State=="off")
{//2
display.printf("G2:OFF\nG14:ON\nG12:OFF");
}
else if(output2State=="off"&&output14State=="on"&&output12State=="on")
{//3
display.printf("G2:OFF\nG14:ON\nG12:ON");
}
else if(output2State=="on"&&output14State=="off"&&output12State=="off")
{//4
display.printf("G2:ON\nG14:OFF\nG12:OFF");
}
else if(output2State=="on"&&output14State=="off"&&output12State=="on")
{//5
display.printf("G2:ON\nG14:OFF\nG12:ON");
}
else if(output2State=="on"&&output14State=="on"&&output12State=="off")
{//6
display.printf("G2:ON\nG14:ON\nG12:OFF");
}
display.display();
}
void loop(){
WiFiClient client = server.available(); // Listen for incoming clients
if (client) { // If a new client connects,
Serial.println("New Client."); // print a message out in the serial port
String currentLine = ""; // make a String to hold incoming data from the client
currentTime = millis();
previousTime = currentTime;
while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
currentTime = millis();
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// turns the GPIOs on and off
if (header.indexOf("GET /2/on") >= 0)
{
Serial.println("GPIO 2 on");
output2State = "on";
//a1=1;
digitalWrite(output2, HIGH);
}
else if (header.indexOf("GET /2/off") >= 0)
{
Serial.println("GPIO 2 off");
output2State = "off";
//a1=0;
digitalWrite(output2, LOW);
}
else if (header.indexOf("GET /14/on") >= 0)
{
Serial.println("GPIO 14 on");
output14State = "on";
//a2=1;
digitalWrite(output14, HIGH);
}
else if (header.indexOf("GET /14/off") >= 0)
{
Serial.println("GPIO 14 off");
output14State = "off";
//a2=0;
digitalWrite(output14, LOW);
}
else if (header.indexOf("GET /12/on") >= 0)
{
Serial.println("GPIO 12 on");
output12State = "on";
// a3=1;
digitalWrite(output12, HIGH);
}
else if (header.indexOf("GET /12/off") >= 0)
{
Serial.println("GPIO 12 off");
output12State = "off";
//a3=0;
digitalWrite(output12, LOW);
}
// Display the HTML web page
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS to style the on/off buttons
// Feel free to change the background-color and font-size attributes to fit your preferences
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #195B6A; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #77878A;}</style></head>");
// Web Page Heading
client.println("<body><h1>ESP8266 Web Server</h1>");
// Display current state, and ON/OFF buttons for GPIO 2
client.println("<p>GPIO 2 - State " + output2State + "</p>");
// If the output2State is off, it displays the ON button
if (output2State=="off") {
client.println("<p><a href=\"/2/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/2/off\"><button class=\"button button2\">OFF</button></a></p>");
}
// Display current state, and ON/OFF buttons for GPIO 14
client.println("<p>GPIO 14 - State " + output14State + "</p>");
// If the output14State is off, it displays the ON button
if (output14State=="off") {
client.println("<p><a href=\"/14/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/14/off\"><button class=\"button button2\">OFF</button></a></p>");
}
// Display current state, and ON/OFF buttons for GPIO 12
client.println("<p>GPIO 12 - State " + output12State + "</p>");
// If the output12State is off, it displays the ON button
if (output12State=="off") {
client.println("<p><a href=\"/12/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/12/off\"><button class=\"button button2\">OFF</button></a></p>");
}
client.println("</body></html>");
// The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
lcddisplay();
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
5.傳感器獲取(DHT11)
還沒到,,,,待續,,,,
6.WiFi時鐘
也還沒到,,,,待續,,,,
待續
參考論壇
我很多的代碼都是參考這里然后縫合的,說抄的都行,,,,,(手動滑稽)
點擊這里
https://randomnerdtutorials.com/projects-esp8266/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/292803.html
標籤:其他
