问题描述
我想制作一个程序,我可以在其中使用 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);
解决方案:
- 为开关使用不同的引脚
- 或在您的原理图中添加真正的硬件电阻