本帖最后由 France 于 2022-11-14 14:08 编辑  
 
我的家门口对着马路,所以我装了个大门,但是每次开车进出门都得自己下来打开关闭,这实在是太不方便了。网上看了下自动门的价格,额,还是自己动手做个吧! 我之前做了一版,但这次我又做了次改进。我用了新升级内置了霍尔传感器的线性执行器,新的ESP32主板,每个通道可达到15A@13.8V的新双电机驱动器模块,以及新的防水超声波传感器。  
这就是最后的效果:  
材料清单如下:  
 5. 防水柔性LED灯带  ×2 6. LD1117V33 电源管理芯片  ×1 7. 10 µF电容 ×2 8. 12V 350W 电源 ×1 9. 霍尔线性执行器 12V/12A IP65  ×2 软件 10. NPN mos管 ×4   
软件平台  
 
工具 接线看起来很复杂,但是你真正上手时会发现其实还好。本项目对应的接线如下:  
电机驱动板 – FireBeetle 主板:  
- M2Speed - IO17
 - M2Dir - IO13
 - M1Speed - IO16
 - M1Dir - IO14
 - +5V - VCC
 - GND - GND
 
  超声波距离传感器- FireBeetle主板: 
- +3.3V - +3.3V
 - GND - GND
 - RX - IO22
 - TX - IO21
 
 
  
      聚光灯 - FireBeetle:      LED 灯带 - FireBeetle: - 第一个晶体管gate - IO25
 - 第二个晶体管gate - IO27
 - 第三个晶体管 gate - IO5
 
 
  
    磁力锁- FireBeetle:  
 
    电流传感器 - FireBeetle: 具体细节参考下图:  
  
  
  
 Blynk  
这是桌面模板完成后的外观:  
  
 手机上的样例:  
  
 
 
 
 
 
 
代码  
 这个项目的代码很长。你要用的话可能需要更改一些内容。例如,我的左执行器似乎打开得比关闭得慢,所以我必须调整打开和关闭功能来解决这个问题。 drivewaygates.ino:  
 
			
			
			- #define BLYNK_TEMPLATE_ID "************"
 - #define BLYNK_DEVICE_NAME "********"
 - #define BLYNK_AUTH_TOKEN "*******************************"
 - #define BLYNK_PRINT Serial
 
  复制代码
  
 首先,我们必须设置Blynk凭据。在指定的行中输入模板id、设备名称和身份验证令牌。  
- #include <WiFi.h>
 - #include <WiFiClient.h>
 - #include <BlynkSimpleEsp32.h>
 - #include <WiFiUdp.h>
 - #include <ArduinoOTA.h>
 - #include <SoftwareSerial.h>
 
  复制代码
 接下来,我们需要的所有库都包括在内;WiFi、Blynk、OTA和软件系列。  
 - #define motorAspeed   16//D11
 - #define motorBspeed   17//D10
 - #define motorAdir     14//D6
 - #define motorBdir     13//D7
 - #define hall          26//D3
 - #define ultra1        22
 - #define ultra2        21
 - #define currentIn     A0
 - #define pinRed        D4
 - #define pinGreen      D3
 - #define pinBlue       4//D12
 - #define magnet        D9//D13
 - #define light         4//D12
 
  复制代码
  
  
 在这里,我们定义了哪些引脚连接到哪些零件。任何不以“D”开头的引脚都是FireBeetle上的 IO口。  
- /* Current Sensor (currently not working)
 - const int numReadings = 30;
 - float readings[numReadings];      // the readings from the analog input
 - int inde = 0;                  // the inde of the current reading
 - float total = 0;                  // the running total
 - float average = 0;                // the average
 - float currentValue = 0;
 - */
 
  复制代码
 以下是当前传感器读数和变量,但在编写本文时,此部分不起作用。我希望尽快更新!  
 - int ppi = 300; //pulses per inch (for the PA-04 Linear Actuator).  Change this according to your specs.
 - int usedAct = 6; //inches of actuator used
 - char ssid[] = "************";//WiFi network name
 - char pass[] = "********";//WiFi network password
 
  复制代码
  
 所有这些变量都必须更改!首先是ppi变量,它代表“每英寸脉冲数”。该值取决于所使用的线性执行器,一英寸对应的霍尔传感器的脉冲量。接下来是usedAct变量。该变量是使用的线性执行器上的英寸数。您可能需要多次调整此数字以获得所需效果。最后,是WiFi证书。输入您希望模块连接到的WiFi网络名称和密码。  
 - //Gate button value for Blynk
 - int button;
 - int timer;
 - //current sensor value
 - float voltage;
 - //ultrasonic sensor
 - unsigned char data[4] = {};
 - float distance;
 - float inches;
 - int car;
 - int carDist = 24;//alter this value! This value is distance in inches before something is activated
 - int tim = 10000;
 - long hallCount;
 - //gate status flag
 - boolean flag = false;
 - //LED strip starting values
 - int red = 255;
 - int green = 255;
 - int blue = 255;
 
  复制代码
  
这些是使用的所有其他变量。唯一需要修改的是carDist变量。这是汽车被定义为存在之前的英寸数。  
 - SoftwareSerial ultraSerial;
 
  复制代码
  
这里,我们定义了超声传感器的软件序列实例。  
 - BLYNK_WRITE(V0){
 -   button = param.asInt();
 - }
 - BLYNK_WRITE(V1){
 -   red = param.asInt();
 - }
 - BLYNK_WRITE(V2){
 -   green = param.asInt();
 - }
 - BLYNK_WRITE(V3){
 -   blue = param.asInt();
 - }
 - BLYNK_WRITE(V4){
 -   int spotlight = param.asInt();
 -   if (spotlight){
 -     digitalWrite(light, HIGH);
 -   }
 -   else {
 -     digitalWrite(light, LOW);
 -   }
 - }
 - String string;
 - BLYNK_WRITE(V10) {
 -   string = param.asStr();
 -   if (string == "restart"){
 -     Blynk.virtualWrite(V10, "Restarting...");
 -     Serial.println("Restarting...");
 -     delay(2000);
 -     ESP.restart();
 -   }
 - }
 
  复制代码
 这些都是用于接收值的Blynk函数  
 - //gate status flag
 - boolean isOpen = false;
 
  复制代码
  
 这是一个布尔变量,用于指示门是打开还是关闭。  
 - //PWM information
 - const int freq = 5000;
 - const int resolution = 8;
 - const int redChannel = 1;
 - const int greenChannel = 2;
 - const int blueChannel = 3;
 - const int motorA = 4;
 - const int motorB = 5;
 
  复制代码
  
 与Arduino相比,ESP32上的PWM稍微复杂一些,但更易于定制。这里,我们设置频率、分辨率,然后设置需要PWM的信道。  
 - void setup() {
 -   Serial.begin(115200);
 -   ultraSerial.begin(9600, SWSERIAL_8N1, ultra1, ultra2, false); // RX, TX
 -   if (!ultraSerial) { // If the object did not initialize, then its configuraiton is invalid
 -     Serial.println("Invalid SoftwareSerial pin configuration, check config");
 -   }
 
  复制代码
  
 在voidsetup()中,我们首先启动串行进行调试(请记住,只有当设备通过导线连接到您的PC时,这才有效;不要用OTA),为超声波传感器启动串行口,并检查以确保传感器已启动。  
 - //set pinModes
 -   pinMode(motorAspeed, OUTPUT);
 -   pinMode(motorBspeed, OUTPUT);
 -   pinMode(motorAdir, OUTPUT);
 -   pinMode(motorBdir, OUTPUT); 
 -   pinMode(pinRed, OUTPUT);
 -   pinMode(pinGreen, OUTPUT); 
 -   pinMode(pinBlue, OUTPUT);
 -   pinMode(hall, INPUT_PULLUP);
 -   pinMode(currentIn, INPUT);
 -   pinMode(magnet, OUTPUT);
 -   pinMode(light, OUTPUT);
 
  复制代码
  
 接下来,我们设置pinmodes;除霍尔传感器外,它们都是输出,霍尔传感器是一个输入上拉。  
 - //attach PWM channels to the correct pins
 -   ledcAttachPin(pinRed, redChannel);
 -   ledcAttachPin(pinGreen, greenChannel);
 -   ledcAttachPin(pinBlue, blueChannel);
 -   ledcAttachPin(motorAspeed, motorA);
 -   ledcAttachPin(motorBspeed, motorB);
 - 
 -   //setup the PWM channels
 -   ledcSetup(redChannel, freq, resolution);
 -   ledcSetup(greenChannel, freq, resolution);
 -   ledcSetup(blueChannel, freq, resolution);
 -   ledcSetup(motorA, freq, resolution);
 -   ledcSetup(motorB, freq, resolution);
 
  复制代码
 这里,PWM已设置。首先,我们将引脚连接到正确的通道,然后为每个通道设置通道频率和分辨率。  
 - //connect to the WiFi
 -   wificonnect();
 - 
 -   //Start Blynk
 -   Serial.println("Blynk Starting...");
 -   Blynk.config(BLYNK_AUTH_TOKEN);
 - 
 -   //Start OTA
 -   Serial.println("OTA Starting...");
 -   OTAStart();
 
  复制代码
  
 这三个部分能让我们的无线网络正常运行。首先,我们连接到WiFi,然后配置Blynk,最后启动OTA。OTA默认密码为“maker”;这可以在OTAStart()函数中更改。  
 - //open the gates all the way at the beginning to set the hall sensor back at 0
 -   Serial.println("Begin opening...");
 -   delay(1000);
 -   beginOpen();
 -   hallCount = ppi*usedAct;
 -   isOpen = true;
 -   Serial.println("Attaching interrupt...");
 -   attachInterrupt(digitalPinToInterrupt(hall), interruptName, FALLING);//Interrupt initialization
 -   //then close to the correct place, keeping track of the hall count
 -   Serial.println("Closing to correct place...");
 -   close();
 -   Serial.println("Done closing!");
 -   Serial.println("Ready");
 -   isOpen = false;
 
  复制代码
 闸门设置完成了voidsetup(); 设置,首先,闸门在不使用霍尔传感器的情况下一直打开。这就像一种校准,因为当闸门完全打开到极限时,我们就能确定霍尔传感器的位置!接下来,连接霍尔传感器,因为如果我们在打开功能开始之前连接霍尔传感器中断,霍尔传感器将开始计数,我们不想在校准时这样做。现在我们可以靠近正确的位置,一边走边计数霍尔脉冲,以确保闸门正确关闭。当它们已关闭,我们将闸门状态布尔值设置为false,表示闸门已成功关闭。  
 - void loop() {
 -   //if WiFi was lost, reconnect
 -   if (WiFi.status() == WL_CONNECTION_LOST){
 -     Serial.println("Connection lost...");
 -     wificonnect();
 -   }
 -   //handle the OTA
 -   ArduinoOTA.handle();
 
  复制代码
  
 在voidloop()检查WiFi连接,处理OTA。  
 - //ultrasonic sensor reading
 -   for (int i=0;i<4;i++){
 -     Serial.println("Checkdist();");
 -     ArduinoOTA.handle();
 -     checkDist();
 -   }
 -   Blynk.virtualWrite(V8,inches);
 -   if (inches <= carDist){
 -     Serial.println("Car");
 -     Blynk.virtualWrite(V9, HIGH);
 -   }
 -   else {
 -     Blynk.virtualWrite(V9, LOW);
 -   }
 
  复制代码
 这里,我们多次读取超声波传感器,以确保获得良好的读数。然后我们将值发送给Blynk,检查是否有车,并相应地更新Blynk的LED。  
 - //if Blynk button pressed, switch the flag
 -   if (button == HIGH){
 -     flag = !flag;
 -   }
 -   //check to see if the flag is true, then check if the gates are closed and open them
 -   if (flag == true && isOpen == false) {
 -     digitalWrite(magnet, LOW);
 -     delay(100);
 -     open();
 -     isOpen = true;
 -   }
 -   //else, check to see if the gates are open, and close them
 -   else if (flag == false && isOpen == true) {
 -     close();
 -     delay(100);
 -     digitalWrite(magnet, HIGH);
 -     isOpen = false;
 
  复制代码
  
 如果按下Blynk的“门”按钮,则切换标志。如果标志为真,且闸门关闭,磁铁闭合,打开闸门,并将状态设置为打开!如果标志为假且闸门打开,关闭闸门,磁铁打开,并将状态设置为关闭。  
 - //write the Blynk values to the LED strips
 -   ledcWrite(redChannel, red);
 -   ledcWrite(greenChannel, green);
 -   ledcWrite(blueChannel, blue);
 - 
 -   //run Blynk, yield() to prevent unwanted resets, and delay 1 millisecond to keep track of time
 -   Blynk.run();
 -   yield();
 -   delay(1);
 
  复制代码
 在voidloop()的最后一部分中,Blynk值被写入LED灯带中,Blynk运行,我们确保yield();如果我们不增加yield,ESP32将意外重启,并可能导致问题。  
 - void wificonnect(){
 -   Serial.println("WiFi Connecting...");
 -   WiFi.mode(WIFI_STA);
 -   WiFi.begin(ssid, pass);
 -   while (WiFi.status() != WL_CONNECTED){
 -     Serial.print(".");
 -     delay(1000);
 -   }
 -   Serial.println("");
 -   while (WiFi.waitForConnectResult() != WL_CONNECTED) {
 -     Serial.println("Connection Failed! Rebooting...");
 -     delay(5000);
 -     ESP.restart();
 -   }
 - }
 - 
 - void checkDist(){
 -   retry:
 -   do {
 -     for (int i = 0; i < 4; i++){
 -       data[i] = ultraSerial.read();
 -     }
 -   }
 -   while (ultraSerial.read() == 0xff);
 -   ultraSerial.flush();
 -   if (data[0] == 0xff) {
 -     int sum;
 -     sum = (data[0] + data[1] + data[2]) & 0x00FF;
 -     if (sum == data[3]) {
 -       distance = (data[1] << 8) + data[2];
 -       if (distance > 20) {
 -         inches = distance / 25.4; //mm to inches
 -         Serial.print(distance / 10);
 -         Serial.println("in");
 -       } else {
 -         inches = 0;
 -         Serial.println("Below the lower limit");
 -       }
 -     } else goto retry;//Serial.println("ERROR");
 -   }
 -   delay(100);
 - }
 - 
 - void beginOpen(){
 -   bodo:
 -   digitalWrite(motorAdir, HIGH);
 -   digitalWrite(motorBdir, HIGH);
 -   ledcWrite(motorA, 255);
 -   ledcWrite(motorB, 255);
 -   yield();
 -   timer++;
 -   delay(1);
 -   while (timer < 24000){
 -     yield();
 -     goto bodo;
 -   }
 -   timer = 0;
 -   Serial.println("Done!");
 -   ledcWrite(motorA, 0);
 -   ledcWrite(motorB, 0);
 - }
 - 
 - void open(){
 -   int times=0;
 -   hallCount = 0;
 -   redo:
 -   digitalWrite(motorAdir, HIGH);
 -   digitalWrite(motorBdir, HIGH);
 -   ledcWrite(motorA, 255);
 -   ledcWrite(motorB, 255);
 -   while (hallCount < ppi*usedAct){
 -     yield();
 -     Serial.print("Hall count: ");
 -     Serial.println(hallCount);
 -     goto redo;
 -   }
 -   delay(500);
 -   tedo:
 -   digitalWrite(motorAdir, HIGH);
 -   digitalWrite(motorBdir, HIGH);
 -   ledcWrite(motorA, 255);
 -   ledcWrite(motorB, 255);
 -   times++;
 -   delay(1);
 -   yield();
 -   while (times < 7000){
 -     goto tedo;
 -   }
 -   times=0;
 -   yield();
 -   ledcWrite(motorA, 0);
 -   ledcWrite(motorB, 0);
 - }
 - 
 - void close(){
 -   hallCount = ppi*usedAct;
 -   redone:
 -   digitalWrite(motorAdir, LOW);
 -   digitalWrite(motorBdir, LOW);
 -   ledcWrite(motorA, 255);
 -   ledcWrite(motorB, 255);
 -   while (hallCount > 0){
 -     yield();
 -     Serial.print("Hall count: ");
 -     Serial.println(hallCount);
 -     goto redone; //goto endy;
 -   }
 -   yield();
 -   ledcWrite(motorA, 0);
 -   ledcWrite(motorB, 0);
 -   digitalWrite(motorAdir, HIGH);
 -   digitalWrite(motorBdir, HIGH);
 -   Serial.println("Gates closed");
 - }
 - 
 - void OTAStart(){
 -   // Port defaults to 8266
 -   ArduinoOTA.setPort(8266);
 -   // Hostname defaults to esp8266-[ChipID]
 -   ArduinoOTA.setHostname("DrivewayESP");
 -   // No authentication by default . 
 -   ArduinoOTA.setPassword("maker");
 -   // Password can be set with it's md5 value as well
 -   // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
 -   // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
 -   ArduinoOTA.onStart([]() {
 -   //open();
 -   String type;
 -   if (ArduinoOTA.getCommand() == U_FLASH) {
 -     type = "sketch";
 -   } else { // U_FS
 -     type = "filesystem";
 -   }
 -   // NOTE: if updating FS this would be the place to unmount FS using FS.end()
 -   Serial.println("Start updating " + type);
 -   });
 -   ArduinoOTA.onEnd([]() {
 -     Serial.println("\nEnd");
 -   });
 -   ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
 -     Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
 -   });
 -   ArduinoOTA.onError([](ota_error_t error) {
 -   Serial.printf("Error[%u]: ", error);
 -   if (error == OTA_AUTH_ERROR) {
 -     Serial.println("Auth Failed");
 -   } else if (error == OTA_BEGIN_ERROR) {
 -     Serial.println("Begin Failed");
 -   } else if (error == OTA_CONNECT_ERROR) {
 -     Serial.println("Connect Failed");
 -   } else if (error == OTA_RECEIVE_ERROR) {
 -     Serial.println("Receive Failed");
 -   } else if (error == OTA_END_ERROR) {
 -     Serial.println("End Failed");
 -   }
 -   });
 -   ArduinoOTA.begin();
 -   Serial.println("Ready");
 -   Serial.print("IP address: ");
 -   Serial.println(WiFi.localIP());
 - }
 - 
 - ICACHE_RAM_ATTR void interruptName() {
 -   if (isOpen == false){
 -     hallCount++;
 -     if (hallCount >= ppi*usedAct){
 -       //ledcWrite(motorA, 0);
 -       //ledcWrite(motorB, 0);
 -       digitalWrite(hall, HIGH);
 -       hallCount = ppi*usedAct;
 -       //delay(1000);
 -     }
 -   }
 -   else if (isOpen == true){
 -     hallCount--;
 -     if (hallCount <= 0){
 -       ledcWrite(motorA, 0);
 -       ledcWrite(motorB, 0);
 -       digitalWrite(hall, HIGH);
 -       hallCount = 0;
 -       //delay(1000);
 -     }
 -   }
 -   //currentVal();
 - }
 
  复制代码
  
 这些都是我为简化代码而做的所有函数。注意最后一个函数有什么不同吗?这就是中断函数。有关ESP32中断的更多信息,请查看此链接。  
 
 
 
 
 
 
 
 
 
 
 
原出处:https://www.hackster.io/k-gray/automated-driveway-gates-version-2-6d9b2e  
  
 
 
 
 
 
 
 
 |