尝试使用手动开关反馈对 ESP32 进行编程

问题描述

我想制作一个程序,我可以在其中使用 MQTT 消息管理设备以及使用普通开关获取反馈,我尝试了以下代码,但在这种情况下,开关一个和继电器按预期运行,但 switch2 &开关 3 在循环中被调用,开关 2 自动从 0 转换为 1,因此如果条件得到验证并进入循环,请帮助

#include <WiFi.h>
#include <PubSubClient.h>
#include "ArduinoJson.h"


#define relayOne 15
#define switchOne 32
#define relayTwo 2
#define switchTwo 35
#define relayThree 4
#define switchThree 34
#define relayFour 22
#define switchFour 39

const char* ssid = "*******";//replace this with your wifi access point 
const char * password = ""*******";//"; //replace with your wifi password
const char * host = "*.*.*.*"; //IP address of machine on which broker is installed
const int port = 1883;
const char * mqttUser = "user";
const char * mqttPassword = "user";

WiFiClient espClient;
PubSubClient client(espClient);

StaticJsonBuffer < 55 > jsonBuffer;

void callback(char * topic,byte * payload,unsigned int length) {

  Serial.print("Message received in topic: ");
  Serial.print(topic);
  Serial.print("   length is:");
  Serial.println(length);
  Serial.print("Data Received From broker:");

  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    messageTemp += (char) payload[i];
  }
  //Serial.println(messageTemp);
  const size_t capacity = JSON_OBJECT_SIZE(2) + 20;
  DynamicJsonBuffer jsonBuffer(capacity);

  //const char* json = "{\"pin\":14,\"value\":1}";
  const char * json = messageTemp.c_str();

  JsonObject & root = jsonBuffer.parSEObject(json);

  int pin = root["pin"];
  int value = root["value"];

  Serial.println(pin);
  Serial.println(value);
  digitalWrite(pin,value);

}




void setup() {

  Serial.begin(115200);
  
  pinMode(relayOne,OUTPUT);
  pinMode(switchOne,INPUT_PULLUP);
  pinMode(relayTwo,OUTPUT);
  pinMode(switchTwo,INPUT_PULLUP);
  pinMode(relayThree,OUTPUT);
  pinMode(switchThree,INPUT_PULLUP);
  pinMode(relayFour,OUTPUT);
  pinMode(switchFour,INPUT_PULLUP);
  
  WiFi.begin(ssid,password);
  Serial.println("Connecting to WiFi..");
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    yield();
  }
  Serial.println("Connected to the WiFi network");

  client.setServer(host,port);
  client.setCallback(callback);

  while (!client.connected()) {
    Serial.println("Connecting to MQTT...");

    if (client.connect("ESP8266Client",mqttUser,mqttPassword)) {
      Serial.println("connected to MQTT broker");
    } else {
      Serial.print("Failed with state ");
      Serial.print(client.state());
      delay(500);
    }
  }

  Serial.println("ESP32 AS SUBSCRIBER");
  client.subscribe("IOT"); //topic name="Sub"
}

void MQTTPOST(int pin,int value)
{
  Serial.println("in mqttpost");
  //payload formation begins here
  String payload ="{";
  payload +="\"Pin\":"; payload +=pin; payload +=",";
  payload +="\"Value\":"; payload +=value;
  payload +="}";
  
  char attributes[1000];
  payload.tochararray( attributes,1000 );
  client.publish("IOT1",attributes); //topic="Pub" MQTT data post command.
  Serial.println( attributes );
  Serial.println("");
}


int switchOneValue = 0;
int switchTwovalue = 0;
int switchThreeValue = 0;
int switchFourValue = 0;
void loop() {
  client.loop();

  int valueSwitchOne = digitalRead(switchOne);
  Serial.println(valueSwitchOne);
   Serial.println(switchOneValue);
   if(valueSwitchOne == 0 && switchOneValue == 0){
    digitalWrite(relayOne,1);
    switchOneValue = 1;
    MQTTPOST(relayOne,1);
    Serial.println("on");
    delay(200);
   }else if(valueSwitchOne == 1 && switchOneValue == 1) {
    digitalWrite(relayOne,0);
    switchOneValue = 0;
    MQTTPOST(relayOne,0);
    Serial.println("off");
    delay(200);
   }

  int valueSwitchTwo = digitalRead(switchTwo);
  Serial.println(valueSwitchTwo);
   Serial.println(switchTwovalue);
   delay(1000);
   if(valueSwitchTwo == 0 && switchTwovalue == 0){
    digitalWrite(relayTwo,1);
    switchTwovalue = 1;
    MQTTPOST(relayTwo,1);
    Serial.println("on2");
    delay(200);
   }else if(valueSwitchTwo == 1 && switchTwovalue == 1) {
    digitalWrite(relayTwo,0);
    switchTwovalue = 0;
    MQTTPOST(relayTwo,0);
    Serial.println("off2");
    delay(200);
   }

     int valueSwitchThree = digitalRead(switchThree);
   if(valueSwitchThree == 0 && switchThreeValue == 0){
    digitalWrite(relayThree,1);
    switchThreeValue = 1;
    MQTTPOST(relayThree,1);
    Serial.println("on");
    delay(200);
   }else if(valueSwitchThree == 1 && switchThreeValue == 1) {
    digitalWrite(relayThree,0);
    switchThreeValue = 0;
    MQTTPOST(relayThree,0);
    Serial.println("off");
    delay(200);
   }
}

解决方法

这里引用了 esp32 的文档:

附录 A – ESP32 引脚列表

A.1. ESP32 引脚列表注意事项

表 24:ESP32 引脚列表注意事项

GPIO 引脚 34-39 仅供输入。这些引脚具有输出 驱动器或内部上拉/下拉电路。

digitalRead() 可以为这些引脚返回任意值,因为那里没有内置上拉电阻 - 它们实际上悬在空中。

这意味着如果没有外部上拉电阻,以下代码无法工作

#define switchTwo 35
#define switchThree 34
#define switchFour 39

pinMode(switchTwo,INPUT_PULLUP); // THIS DOES NOT WORK for GPIOs: 34-39!!!
pinMode(switchThree,INPUT_PULLUP); // THIS DOES NOT WORK for GPIOs: 34-39 !!!
pinMode(switchFour,INPUT_PULLUP); // THIS DOES NOT WORK for GPIOs: 34-39 !!!

// unpredictable values are here when button is not pressed
int valueSwitchTwo = digitalRead(35);
int valueSwitchThree = digitalRead(34);

解决方案:

  1. 为开关使用不同的引脚
  2. 或在您的原理图中添加真正的硬件电阻