按钮+AP+esp8266(We Mos D1)驱动MG996R和dfplayer mini MP3模块

按下物理开关时,舵机旋转160度,延迟几秒后喇叭发出声音。

通过AP网络连接后,通过网页的开门1/2/3按钮控制舵机旋转,延迟几秒后喇叭发出声音。

附上接线图:

全部代码:

#include <Servo.h>  
#include <Arduino.h>
#include "ESP8266WiFi.h"
#include "ESP8266WebServer.h"
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>

   
Servo myservo;  
SoftwareSerial mySerial(D0, D1); // RX, TX。与mp3有关
ESP8266WebServer server(80);
const int switchPin1 = D8;  // 定义外置开关的一个引脚  
bool switchState = false;  // 用于存储开关状态

void handleRoot() {
    String html = "<!DOCTYPE html>\n"  
    "<html lang=\"en\">\n"  
    "<head>\n"  
    "<meta charset=\"UTF-8\">\n"  
    "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"  
    "<style>\n"  
    "body, html {\n"  
    "  height: 100%;\n"  
    "  margin: 0;\n"  
    "  display: flex;\n"  
    "  justify-content: center;\n"  
    "  align-items: center;\n"  
    "  font-family: Arial, sans-serif;\n"  
    "  box-sizing: border-box;\n"  
    "}\n"  
    "\n"  
    ".button-container {\n"  
    "  display: flex;\n"  
    "  flex-direction: column;\n"  
    "  align-items: center;\n"  
    "  width: 100%;\n"  
    "  padding: 10px;\n"  
    "  text-align: center;\n"  
    "}\n"  
    "\n"  
    ".button {\n"  
    "  width: calc(100% - 40px);\n" /* 减去左右padding的宽度,保持按钮内部内容居中 */  
    "  padding: 15px 20px;\n"  
    "  font-size: 16px;\n"  
    "  font-weight: bold;\n"  
    "  text-align: center;\n"  
    "  text-decoration: none;\n"  
    "  color: #fff;\n"  
    "  background-color: #007BFF;\n"  
    "  border: none;\n"  
    "  border-radius: 5px;\n"  
    "  cursor: pointer;\n"  
    "  margin: 10px 0;\n"  
    "  box-sizing: border-box;\n"  
    "  transition: background-color 0.3s ease;\n"  
    "}\n"  
    "\n"  
    "@media (min-width: 600px) {\n" /* 当屏幕宽度大于或等于600px时 */  
    "  .button {\n"  
    "    font-size: 18px;\n" /* 增大字体 */  
    "    padding: 20px 30px;\n" /* 增大内边距 */  
    "  }\n"  
    "}\n"  
    "\n"  
    ".button:hover {\n"  
    "  background-color: #0056b3;\n"  
    "}\n"  
    "\n"  
    ".button:active {\n"  
    "  background-color: #004085;\n"  
    "}\n"  
    "</style>\n"  
    "</head>\n"  
    "<body>\n"  
    "<div class=\"button-container\">\n"  
    "<h2>WIFI控制开关</h2>\n"  
    "<a href=\"/on\" class=\"button\">开门1</a>\n"  
    "<a href=\"/off\" class=\"button\">开门2</a>\n"  
    "<a href=\"/fw\" class=\"button\">开门3</a>\n"  
    "<a href=\"/xh\" class=\"button\">测试舵机</a>\n"  
    "</div>\n"  
    "</body>\n"  
    "</html>\n";  
    server.send(200, "text/html", html);   
}

void handleOn() {
    myservo.write(135); // 旋转到135度  
    delay(1000);
    myservo.write(0); 
    delay(2000);
    mp3_play(2); //播放第0002
    server.sendHeader("Location", "/");
    server.send(303);
}

void handleOff() {
    myservo.write(160); // 旋转到160度
    delay(1000);
    myservo.write(0);
    delay(2000);
    mp3_play(2); //播放第0002 
    server.sendHeader("Location", "/");
    server.send(303);
}

void handleFw() {
    myservo.write(180); // 旋转到180度
    delay(1000);
    myservo.write(0);
    mp3_set_volume(15);//mp3声音
    mp3_play(1); //播放第0001
    server.sendHeader("Location", "/");
    server.send(303);
}

void handleXh() {
    myservo.write(0); // 旋转到0度
    delay(2000);
    myservo.write(90);// 旋转到90度
    delay(2000);
    myservo.write(180);// 旋转到180度
    delay(2000);
    myservo.write(0);// 旋转到0度
    server.sendHeader("Location", "/");
    server.send(303);
}


void setup() {  
  Serial.begin(115200); //设置舵机波特率
  mySerial.begin(9600); //设置MP3波特率
  myservo.attach(D5,500,2500);//定义舵机引脚和频率
  mp3_set_serial(mySerial);//这是MP3模块
  mp3_set_volume(30);//初始化声音为30
  myservo.write(0); // 初始化舵机-舵机初始位置
  WiFi.mode(WIFI_AP);  //设置WiFi模式为AP
  WiFi.softAP("WIFI_AP", "12345678");  //设置名称,密码

  server.begin();  //开启服务
  //设置网页的跳转四个按钮
  server.on("/", handleRoot);
  server.on("/on", handleOn);
  server.on("/off", handleOff);
  server.on("/fw", handleFw);
  server.on("/xh", handleXh);

  pinMode(switchPin1, INPUT_PULLUP);  // 设置开关引脚为上拉输入模式  

}  


void loop() {  
  server.handleClient();
  
  // 读取开关状态  
  bool currentState = digitalRead(switchPin1) == LOW;  // 假设按下开关时引脚电平为LOW
   // 如果开关状态发生变化  
  if (currentState != switchState) {  
    switchState = currentState;  
    // 根据开关状态控制舵机旋转  
    if (switchState) {  
      myservo.write(160);  // 例如,按下开关时舵机旋转到160度  
      
    } else {  
      myservo.write(0);  // 例如,松开开关时舵机旋转到0度  
      delay(2500);
      mp3_play(1); //播放第0001

    }  
    // 打印调试信息
     Serial.println(switchState ? "Switch ON" : "Switch OFF");
      // 延时一段时间,避免过于频繁的读取开关状态  
    delay(1500);
}
}

import datetime # a = datetime.datetime.now() def day_get(d): if type(d).__name__ == "str": d = datetime.datetime.strptime(d, &#39;%Y-%m-%d %H:%M:%S&#39;) oneday = datetime.timedelta(days=1) day = d - oneday date_from = datetime.datetime(day.year, day.month, day.day, 0, 0, 0) date_to = datetime.datetime(day.year, day.month, day.day, 23, 59, 59) print(&#39;---&#39;.join([str(date_from), str(date_to)])) def week_get(d): if type(d).__name__ == "str": d = datetime.datetime.strptime(d, &#39;%Y-%m-%d %H:%M:%S&#39;) dayscount = datetime.timedelta(days=d.isoweekday()) dayto = d - dayscount sixdays = datetime.timedelta(days=6) dayfrom = dayto - sixdays date_from = datetime.datetime(dayfrom.year, dayfrom.month, dayfrom.day, 0, 0, 0) date_to = datetime.datetime(dayto.year, dayto.month, dayto.day, 23, 59, 59) datelist = [[str(date_from)], [str(date_to)]] # print(&#39;---&#39;.join([str(date_from), str(date_to)])) return datelist def multi_week_get(d, num): if type(d).__name__ == "str": d = datetime.datetime.strptime(d, &#39;%Y-%m-%d %H:%M:%S&#39;) date_num = [] # date_num = [date_to1] for i in range(num - 1, 0, -1): dayscount = datetime.timedelta(days=d.isoweekday()) dayto = d - dayscount sixdays = datetime.timedelta(days=6 * i) dayfrom = dayto - sixdays date_from = str(datetime.datetime(dayfrom.year, dayfrom.month, dayfrom.day, 10, 0, 0)) date_num.append(date_from) dayscount1 = datetime.timedelta(days=d.isoweekday()) onedays = datetime.timedelta(days=1) dayto1 = d - dayscount1 + onedays date_to1 = str(datetime.datetime(dayto1.year, dayto1.month, dayto1.day, 10, 0, 0)) date_num.append(date_to1) return date_num def month_get(d): if type(d).__name__ == "str": d = datetime.datetime.strptime(d, &#39;%Y-%m-%d %H:%M:%S&#39;) dayscount = datetime.timedelta(days=d.day) dayto = d - dayscount date_from = datetime.datetime(dayto.year, dayto.month, 1, 0, 0, 0) date_to = datetime.datetime(dayto.year, dayto.month, dayto.day, 23, 59, 59) # print(&#39;---&#39;.join([str(date_from), str(date_to)])) datelist = [[str(date_from)], [str(date_to)]] return datelist class op_date(object): def week_get(self, param): pass if __name__ == "__main__": op_date = op_date() # print(op_date.week_get("2023-06-09 23:00:00")[0]) print(op_date.week_get("2023-06-09 23:00:00")[1]) print(multi_week_get("2023-06-09 23:00:00", 4))
06-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值