当前位置: 首页 > news >正文

ESP8266 制作一个网页控制程序

    ​手上的这块MCU为ESP8266,在arduino中进行开发需要安装对应的支持包,这里up选择nodemcu 1.0 ESP-12E版本。

    ​

一、核心硬件清单

首先确认需要准备的硬件,避免接线时遗漏:

  • ESP8266 开发板(如 NodeMCU、D1 mini,引脚定义需与代码一致)

  • SSD1306 128×32 OLED 显示屏(I2C 接口)

  • 舵机(SG90 等常见型号,支持 500-2500μs 脉冲控制)

  • 按键(1 个,用于触发舵机往复转动)

  • LED(1 个,需串联 220Ω 限流电阻,防止烧毁)

  • 杜邦线(公对母 / 公对公若干)

  • 电源(ESP8266 建议 5V/1A 供电,舵机若电流较大需单独 5V 供电)

 

代码:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Servo.h>
#include <WiFiManager.h>
#include <ESP8266WebServer.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)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);Servo myservo;  // create servo object to control a servoconst int buttonPin = D5;    // the number of the pushbutton pin
int buttonState = 0;         // variable for reading the pushbutton statusconst int togglePin = D0;    // the number of the toggle pin
bool toggleState = false;    // variable for storing the toggle stateconst int ledPin = D7;       // LED 连接的引脚ESP8266WebServer server(80);void setup() {Serial.begin(115200);// Initialize the OLED displayif (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {Serial.println(F("SSD1306 allocation failed"));for (;;); // Don't proceed, loop forever}display.clearDisplay();display.setTextSize(1);      // Normal 1:1 pixel scaledisplay.setTextColor(SSD1306_WHITE); // Draw white textdisplay.setCursor(0, 0);     // Start at top-left cornerdisplay.println("Initializing...");display.display();// WiFi 配置WiFiManager wifiManager;if (!wifiManager.autoConnect("ESP8266_AP")) {Serial.println("Failed to connect and hit timeout");// 可以在这里添加更多错误处理逻辑delay(3000);// 重置并尝试重新连接ESP.reset();delay(5000);}Serial.println("Connected to WiFi");display.clearDisplay();display.setCursor(0, 0);display.println("Connected to WiFi");display.print("IP: ");display.println(WiFi.localIP());display.display();// Attach the servo on pin D6 to the servo objectmyservo.attach(D6, 500, 2500); // Adjust min and max pulse widths// Set up the button pin as an inputpinMode(buttonPin, INPUT_PULLUP); // Internal pull-up resistor// Set up the toggle pin as an outputpinMode(togglePin, OUTPUT);digitalWrite(togglePin, LOW); // Initial state is LOW// Set up the LED pin as an outputpinMode(ledPin, OUTPUT);// Initial position of the servomyservo.write(90);// 处理根路径请求server.on("/", []() {String page = "<!DOCTYPE html>";page += "<html lang=\"en\">";page += "<head>";page += "<meta charset=\"UTF-8\">";page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">";page += "<script src=\"https://cdn.tailwindcss.com\"></script>";page += "<title>Device Control</title>";page += "</head>";page += "<body class=\"bg-gray-100 font-sans flex justify-center items-center h-screen\">";page += "<div class=\"bg-white p-8 rounded shadow-md w-full max-w-md\">";page += "<h1 class=\"text-2xl font-bold mb-6 text-center\">Device Control</h1>";page += "<form action='/setServo' method='get' class=\"mb-4\">";page += "<label for=\"angle\" class=\"block text-sm font-medium text-gray-700\">Set Servo Angle:</label>";page += "<input type='number' name='angle' min='0' max='180' class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm\">";page += "<button type='submit' class=\"mt-4 w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500\">Set</button>";page += "</form>";page += "<form action='/toggleLED' method='get' class=\"mb-4\">";page += "<button type='submit' class=\"w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500\">Toggle LED</button>";page += "</form>";page += "<form action='/toggleD0' method='get'>";page += "<button type='submit' class=\"w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-yellow-600 hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500\">Toggle D0</button>";page += "</form>";page += "</div>";page += "</body>";page += "</html>";server.send(200, "text/html", page);});// 处理设置舵机角度请求server.on("/setServo", []() {if (server.hasArg("angle")) {int angle = server.arg("angle").toInt();if (angle >= 0 && angle <= 180) {myservo.write(angle);updateDisplay(angle);server.send(200, "text/plain", "Servo angle set to " + String(angle));} else {server.send(400, "text/plain", "Invalid angle value");}} else {server.send(400, "text/plain", "Missing angle parameter");}});// 处理切换 LED 请求server.on("/toggleLED", []() {toggleState = !toggleState;digitalWrite(ledPin, toggleState);updateDisplay(myservo.read());server.send(200, "text/plain", "LED state toggled");});// 处理切换 D0 请求server.on("/toggleD0", []() {toggleState = !toggleState;digitalWrite(togglePin, toggleState);updateDisplay(myservo.read());server.send(200, "text/plain", "D0 state toggled");});// 启动服务器server.begin();Serial.println("Server started");
}void loop() {server.handleClient();// Read the state of the button valuebuttonState = digitalRead(buttonPin);// Check if the button is pressedif (buttonState == LOW) {// Rotate the servo from 0 to 180 degreesfor (int pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degreesmyservo.write(pos);              // tell servo to go to position in variable 'pos'updateDisplay(pos);delay(15);                       // waits 15ms for the servo to reach the position}// Rotate the servo back from 180 to 0 degreesfor (int pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degreesmyservo.write(pos);              // tell servo to go to position in variable 'pos'updateDisplay(pos);delay(15);                       // waits 15ms for the servo to reach the position}// Wait until the button is releasedwhile (digitalRead(buttonPin) == LOW) {delay(50); // Debounce delay}}// Toggle D0 pin every 5 secondsstatic unsigned long lastToggleTime = 0;if (millis() - lastToggleTime > 5000) {lastToggleTime = millis();toggleState = !toggleState;digitalWrite(togglePin, toggleState);updateDisplay(myservo.read());}
}void updateDisplay(int servoPosition) {display.clearDisplay();display.setTextSize(1);      // Normal 1:1 pixel scaledisplay.setTextColor(SSD1306_WHITE); // Draw white text// Display Servo Positiondisplay.setCursor(0, 0);display.print("Servo: ");display.print(servoPosition);display.println(" deg");// Draw progress bar for servo positiondrawProgressBar(0, 15, SCREEN_WIDTH - 2, 7, servoPosition / 180.0);// Display D0 Statedisplay.setCursor(0, 24);display.print("D0: ");display.print(digitalRead(togglePin) ? "HIGH" : "LOW");// Draw sun or moon icon based on D0 stateif (digitalRead(togglePin)) {drawSunIcon(SCREEN_WIDTH - 20, 24);} else {drawMoonIcon(SCREEN_WIDTH - 20, 24);}display.display();
}void drawProgressBar(int x, int y, int width, int height, float percentage) {display.drawRect(x, y, width, height, SSD1306_WHITE);int fillWidth = width * percentage;display.fillRect(x + 1, y + 1, fillWidth - 2, height - 2, SSD1306_WHITE);
}void drawSunIcon(int x, int y) {// Sun icon: small circle with raysdisplay.fillCircle(x, y, 3, SSD1306_WHITE);display.drawLine(x, y - 5, x, y - 8, SSD1306_WHITE); // Top raydisplay.drawLine(x, y + 5, x, y + 8, SSD1306_WHITE); // Bottom raydisplay.drawLine(x - 5, y, x - 8, y, SSD1306_WHITE); // Left raydisplay.drawLine(x + 5, y, x + 8, y, SSD1306_WHITE); // Right raydisplay.drawLine(x - 4, y - 4, x - 7, y - 7, SSD1306_WHITE); // Top-left raydisplay.drawLine(x + 4, y - 4, x + 7, y - 7, SSD1306_WHITE); // Top-right raydisplay.drawLine(x - 4, y + 4, x - 7, y + 7, SSD1306_WHITE); // Bottom-left raydisplay.drawLine(x + 4, y + 4, x + 7, y + 7, SSD1306_WHITE); // Bottom-right ray
}void drawMoonIcon(int x, int y) {// Moon icon: half-circledisplay.drawCircle(x, y, 3, SSD1306_WHITE);display.drawLine(x - 3, y, x + 3, y, SSD1306_WHITE); // Horizontal line through centerdisplay.drawLine(x - 3, y - 1, x + 3, y - 1, SSD1306_WHITE); // Line above centerdisplay.drawLine(x - 3, y + 1, x + 3, y + 1, SSD1306_WHITE); // Line below centerdisplay.drawLine(x - 3, y - 2, x + 3, y - 2, SSD1306_WHITE); // Line above centerdisplay.drawLine(x - 3, y + 2, x + 3, y + 2, SSD1306_WHITE); // Line below centerdisplay.drawLine(x - 3, y - 3, x + 3, y - 3, SSD1306_WHITE); // Line above centerdisplay.drawLine(x - 3, y + 3, x + 3, y + 3, SSD1306_WHITE); // Line below center
}    

 

 

联网后可进行网页控制

硬件连接:

三、关键模块接线图解(以 NodeMCU 为例)

1. OLED 显示屏(I2C 接口)

SSD1306 OLED 通常有 4 个引脚:VCC、GND、SDA、SCL,接线如下:

  • OLED VCC → ESP8266 3.3V(不可接 5V! OLED 多数为 3.3V 供电)

  • OLED GND → ESP8266 GND

  • OLED SDA → ESP8266 D2(板载 SDA 引脚,代码中 Wire 库默认使用此引脚)

  • OLED SCL → ESP8266 D1(板载 SCL 引脚,代码中 Wire 库默认使用此引脚)

2. 舵机(SG90 为例)

舵机通常有 3 根线:电源(红)、地(棕)、信号(橙):

  • 舵机 红线 → 5V 电源(ESP8266 3.3V 可能供电不足,建议单独 5V

  • 舵机 棕线 → ESP8266 GND(必须与 ESP 共地)

  • 舵机 橙线 → ESP8266 D6(代码中 myservo.attach(D6)

3. 按键(上拉输入模式)

代码中按键使用 INPUT_PULLUP(内部上拉电阻),无需外部上拉电阻,接线最简单:

  • 按键一端 → ESP8266 D5

  • 按键另一端 → ESP8266 GND

  • 按下按键时,D5 引脚被拉到 GND(LOW),触发舵机转动逻辑

4. LED(带限流电阻)

LED 必须串联限流电阻(220Ω~1kΩ),防止电流过大烧毁 ESP8266 引脚:

  • LED 正极 → 220Ω 电阻 → ESP8266 D7

  • LED 负极 → ESP8266 GND

四、接线注意事项(避坑指南)

  1. 舵机供电问题ESP8266 的 5V 引脚电流有限(通常≤500mA),若舵机转动时出现抖动或不响应,需给舵机单独供 5V 电源(如充电宝、18650 电池组),但必须保证 舵机 GND 与 ESP8266 GND 共地,否则信号无法正常传输。

  2. OLED 地址匹配代码中 OLED 初始化用 display.begin(SSD1306_SWITCHCAPVCC, 0x3C),若 OLED 显示异常(如白屏、不显示),可能是 I2C 地址不匹配(部分 OLED 为 0x3D),需修改地址后重试。

  3. D0 引脚的特殊性ESP8266 的 D0 引脚(GPIO16)在复位时会输出高电平,且不能用于外部中断,代码中仅作为普通输出控制设备,避免用它接需要中断触发的模块(如红外接收、人体感应)。

  4. 共地原则所有模块(OLED、舵机、按键、LED)的 GND 必须连接到 ESP8266 的 GND,否则会因电位差导致通信失败(如 OLED 乱码、舵机不转、按键无响应)。

  5. 电源稳定性若同时接多个模块(如舵机 + OLED+LED),建议用 5V/1A 以上的电源给 ESP8266 供电,避免因电压不足导致 ESP 频繁重启(表现为串口打印断断续续、WiFi 频繁断开)。

五、接线后测试步骤

  1. 硬件检查:接线完成后,先检查是否有短路(如 VCC 与 GND 误接),确认无误后再通电。

  2. 串口调试:ESP8266 接电脑,打开 Arduino IDE 串口监视器(波特率 115200),通电后查看:

    • 若显示 SSD1306 allocation failed:检查 OLED 接线或 I2C 地址。

    • 若显示 Connected to WiFi + IP 地址:WiFi 配网成功,可通过该 IP 访问 Web 控制页。

  3. 功能测试

    • 按下按键(D5):舵机应从 0°→180°→0° 往复转动,OLED 实时显示舵机角度。

    • 访问 Web 页(ESP 的 IP 地址):点击 Toggle LED 应控制 D7 引脚的 LED 亮灭;输入舵机角度点击 Set 应控制舵机转到对应角度。

    • 等待 5 秒:D0 引脚电平应自动翻转(可通过万用表测量 D0 与 GND 之间的电压,高电平约 3.3V,低电平约 0V)。

http://www.dtcms.com/a/440677.html

相关文章:

  • 投诉举报网站 建设方案房产中介网站建设的目的
  • a站是什么如何建设一个生活服务网站
  • 建设免费网站登录网址网站建设开发案例
  • 化妆品建设网站的目的wordpress 小米商城模板
  • 手机网站自动跳转让人做网站 需要准备什么条件
  • 做项目挣钱的网站wordpress没有php.ini
  • wordpress搜索收录自己建个网站做优化
  • 国内做视频的网站有哪些有没有做粤菜的网站
  • 专门做瑜伽的网站标签在线设计平台
  • 宿迁企业网站建设thinkphp企业网站
  • 分析苏宁易购的网站建设做百度药材种苗网站
  • 服装商务网站建设策划书如何做贷款网站推广
  • Google Drive云盘清理,一键释放海量空间!
  • 地址 上海石门二路 网站建设亚马逊seo搜索什么意思
  • 网站域名解析ip地址如何 申请个人网站
  • 服装网站建设需要什么内容网站常用特效
  • 网站换服务器 备案网络营销有本科吗
  • 重庆可视化网站制作go语言 做网站
  • 网站开发运营地方门户网站app
  • 在线做logo印章网站企业营业执照查询系统
  • 私人免费网站怎么下载企业制作网站服务
  • 做网站购买域名洛阳网站搭建
  • 我自己做个网站怎么做成都小程序建设乚成都柚米
  • 光明新区建设网站上海公司注册核名官网
  • 网站seo运营培训机构绘图软件有哪些
  • 徐州市城乡和城乡建设厅网站首页微信小程序开发定制公司
  • 【FreeRTOS】第八课(1):信号量(Semaphore)
  • 广州网站建设网站开发怎么做多语言网站
  • 重庆专业做淘宝网站抖音代运营排名
  • 怎么让自己的网站稍微变前面点中国互联网排名前十的公司