Arduino UNO 与 ESP01S 利用MQTT控制LED、舵机、风扇、喷灌器开关

用node-red做一个简单的网页端控制arduino连接的灯等其他东西的开关
####问题
1、控制灯开关的时候,比如说我现在条件一直是snguangmin>500,应该是一直亮着灯才对,我设置的延迟是两秒,但是他会亮两秒暗两秒会跳到ddkg=0里面去关灯两秒
2、我的想法是收到ddkg=0灭灯,ddkg=1开灯,来达到网页控制灯的亮灭的效果,但是这个只有在snguangmin<500的时候可以控制,我想要达到的效果是>500的时候也可以控制他的亮灭,这部分我不知道怎么做所以没写。(相关代码部分)

if(snguangmin>500)
{ 
       digitalWrite(ledpin,HIGH);
  
  }
  else{
   if (ddkg==0){
           digitalWrite(ledpin,LOW);}
           else{
           digitalWrite(ledpin,HIGH);}
    }

3、想要利用网页控制灯、舵机、风扇、喷灌机(不管条件是什么样 网页端要他关就关要开就开)
####全部代码

#include 
#include "SGP30.h"
#include "WiFiEspAT.h"
#include "SoftwareSerial.h"
#include 
SoftwareSerial Serial1(0,6);    // RX, TX
#include          // MQTT通信使用的库
 
 
unsigned long previousMillis = 0;
 
const long interval = 2000; 
 
 
int ledpin=10;//定义数字10 接口
const int snpin=A0;//室内光敏电阻
const int swpin=A1;//室外光敏电阻
int fsPin = 8;//继电器引脚
int djPin = 7;    //定义舵机接口数字接口7 也就是舵机的橙色信号线。
int sensorPin = A2;    // 设置模拟口A2土壤湿度传感器
int pgjPin = 13;      // 设置继电器控制引脚为13
int sensorValue = 0;  // 存放模拟信号量的变量
 
int state=LOW;
int ddkg=0;
int fskg=2;
int pgkg=4;
int jlkg=6;
 
 
char ssid[] = "kk01";    // your network SSID (name)
char pass[] = "kk011209..";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status
    
long lastMsg = 0;
char msg[50];
 
int value=0;
WiFiClient client;
 
PubSubClient pubSubClient(client); 
char server[] = "broker-cn.emqx.io";
 
int port = 1883;
 
 
//char topic[] = "fjjxu/13/303/temp15";
char topic[] = "fjjxu/13/303/light15";
 
int count = 0;
int countPub = 0;
 
dht11 DHT11;
#define DHT11PIN 9 //定义温湿度针脚号为9号引脚
 
 
 
 
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
 
 
 
SGP mySGP30;
 
u16 CO2Data,TVOCData;//定义CO2浓度变量与TVOC浓度变量
u32 sgp30_dat;
 
void servopulse(int angle)//定义一个脉冲函数,这个函数的频率是50hz的,20000us=20ms=1/50hz
 
{
  
  for(int i=0;i<100;i++){
  int pulsewidth=(angle*11)+500;  //将角度转化为500-2480的脉宽值
  digitalWrite(djPin,HIGH);    //将舵机接口电平至高,反过来也是可以的
  delayMicroseconds(pulsewidth);  //延时脉宽值的微秒数
  digitalWrite(djPin,LOW);     //将舵机接口电平至低
  delayMicroseconds(20000-pulsewidth);}
}
 
 
void callback(char* topic, byte* payload, unsigned int length) {  //回调函数
  count++;
 // char str[length]={0};
  Serial.print(count );
  Serial.print(" - Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    //str[i] = (char)payload[i]; 
    Serial.print((char)payload[i]);
  }
  Serial.println();//
//char a=str[0];
//String c =(String)str;
//String b=c.substring(1,4);
//int j = atoi(b.c_str());
// int n=atoi(&a);
 
  if((char)payload[0]=='0')//电灯
   {  ddkg=0;}  
   else if((char)payload[0]=='1')
   { ddkg=1;}
  else if((char)payload[0]=='2')//风扇
   {  fskg=2; }
  else if((char)payload[0]=='3')
   {  fskg=3; }
  else if((char)payload[0]=='4')//喷灌机
   {  pgkg=4; }
  else if((char)payload[0]=='5')
   {  pgkg=5; }
  else if((char)payload[0]=='6')//卷帘机
   {  jlkg=6; }
  else if((char)payload[0]=='7')
   {  jlkg=7; }
   
    Serial.println((char)payload[0]);
 
}
 
 
void connectToInternet() {
 
  Serial1.begin(9600);
  WiFi.init(Serial1);
 
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("【ERROR】WiFi shield not present");
   
    while (true);
  }
 
  while ( status != WL_CONNECTED) {
    Serial.print("【INFO】Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
  
    status = WiFi.begin(ssid, pass);
  }
 
  Serial.println("【INFO】Connection Successful");
 
}
 
 
 
void setup()
{
pinMode(ledpin,OUTPUT);//定义小灯接口为输出接口
pinMode(fsPin, OUTPUT);  //继电器输出模式
pinMode(djPin, OUTPUT); //设定舵机接口为输出接口
pinMode(pgjPin, OUTPUT);  //设置对应的引脚为输出
  lcd.begin(16, 2);
 
  Serial.begin(9600);
 connectToInternet();
 
 pubSubClient.setServer(server, port);
 pubSubClient.setCallback(callback);
 
  reconnect();
  
mySGP30.SGP30_Init();
  mySGP30.SGP30_Write(0x20,0x08);
  sgp30_dat = mySGP30.SGP30_Read();//读取SGP30的值
  CO2Data = (sgp30_dat & 0xffff0000) >> 16;
  TVOCData = sgp30_dat & 0x0000ffff; 
  //SGP30模块开机需要一定时间初始化,在初始化阶段读取的CO2浓度为400ppm,TVOC为0ppd且恒定不变,因此上电后每隔一段时间读取一次
  //SGP30模块的值,如果CO2浓度为400ppm,TVOC为0ppd,发送“正在检测中...”,直到SGP30模块初始化完成。
  //初始化完成后刚开始读出数据会波动比较大,属于正常现象,一段时间后会逐渐趋于稳定。
  //气体类传感器比较容易受环境影响,测量数据出现波动是正常的,可自行添加滤波函数。
  while(CO2Data == 400 && TVOCData == 0)
  {
    mySGP30.SGP30_Write(0x20,0x08);
    sgp30_dat = mySGP30.SGP30_Read();//读取SGP30的值
    CO2Data = (sgp30_dat & 0xffff0000) >> 16;//取出CO2浓度值
    TVOCData = sgp30_dat & 0x0000ffff;       //取出TVOC值
    Serial.println("正在检测中...");
    delay(500);
  }
}
 
 
void loop()
{
  if (pubSubClient.connected()) //如果没有成功连接服务器
  {
     pubSubClient.loop();//保持客户端心跳
    }
  else{
   reconnect();//尝试连接
  }
 
  
  lcd.clear();
  lcd.setCursor(0, 1);
 
  Serial.println("\n");
 
  DHT11.read(DHT11PIN);
 
 float tem=(float)DHT11.temperature;        //将温度值赋值给tem
 float hum=(float)DHT11.humidity; 
 int t=tem;
  int g=analogRead(swpin);
 
  g=map(g,0,1023,100,0);
  //float gg=analogRead(snpin);
  int c = CO2Data;
  c=map(c,0,1023,0,100);
  
  int tr = analogRead(sensorPin);
int  r=map(tr,0,1023,100,0);
  
 char b[50]="";
String date="{\"t\":"+String(t)+",\"c\":"+String(c)+",\"r\":"+String(r)+",\"g\":"+String(g)+"}";
 
 strcpy(b,date.c_str());//转格式字符数组  不能接收字符串
 
 
 
  Serial.print("Humidity (%): ");
  Serial.println(hum);
 
  Serial.print("Temperature (oC): ");
  Serial.println(tem);
 
    lcd.clear();//清屏,光标回到左上角
      lcd.print("Hum:");//共12个字符
      lcd.setCursor(4,0);//光标定位到上面字符的后面,即第1行第13列
      lcd.print(hum,1);//显示采集到湿度值,保留小数点后1位
      lcd.print("%");
      lcd.setCursor(0,1);//光标定位到第1列第2行
      lcd.print("Tem:");//8个字符
      lcd.setCursor(4,1);//光标定位到第9列第2行
      lcd.print(tem,1);//显示采集到温度值,保留小数点后1位
      lcd.print("C");
       lcd.setCursor(9,0);//光标定位到第1列第2行
   lcd.print("Tu:");
       lcd.setCursor(12,0);//光标定位到第1列第2行
       lcd.print(sensorValue);
       
   lcd.setCursor(9,1);//光标定位到第9列第2行
   lcd.print("CO2:");
       lcd.setCursor(13,1);//光标定位到第1列第2行
       lcd.print(CO2Data,DEC);
     
     
  if (tem >22)        //如果温度大于22摄氏度
    {
      digitalWrite(fsPin, LOW);        //继电器开,风扇开
      Serial.println(" OPEN!");
    } else
    {  
      if(fskg==2){ digitalWrite(fsPin,HIGH);
      Serial.println("CLOSE!");}
  else{ digitalWrite(fsPin, LOW); 
    Serial.println("OPEN!");
  }
   
      
    }
 
 
//灯
int snguangmin=analogRead(snpin);   //读入光敏电阻产生的模拟信号(范围:0~1023)
  Serial.print("snvalue= ");
  Serial.print(snguangmin);
 // snguangmin=map(snguangmin,0,1023,0,255);  //map函数 将0~1023范围映射到255~0
  //这里反着写255,0;因为想实现随着光强增加LED变亮
  //analogWrite(ledpin,snguangmin);    //让13号引脚发出PWM波
 
 
if(snguangmin>500)
{ 
       digitalWrite(ledpin,HIGH);
  
  }
  else{
   if (ddkg==0){
           digitalWrite(ledpin,LOW);}
           else{
           digitalWrite(ledpin,HIGH);}
  
 
    }
 
 
//喷灌机
sensorValue = analogRead(sensorPin);
  
  if(sensorValue<900)//当读取的值小于700时,启动
  {
   digitalWrite(pgjPin, HIGH);
  }else
  {
        if(pgkg==4){ digitalWrite(pgjPin, LOW);}
  else{ digitalWrite(pgjPin, HIGH);}
   
  }
   Serial.print("turang= ");
  Serial.println(sensorValue);
 
 
 
 //舵机
 int swguangmin=analogRead(swpin); 
 Serial.print("swvalue= ");
  Serial.println(swguangmin);
if(swguangmin>500)
{
  servopulse(0);
 
  }else
  {
       if(jlkg==6){ servopulse(180);}
  else{ servopulse(0);}
    
    }
 
 
//CO2检测
  mySGP30.SGP30_Write(0x20,0x08);
  sgp30_dat = mySGP30.SGP30_Read();//读取SGP30的值
  CO2Data = (sgp30_dat & 0xffff0000) >> 16;//取出CO2浓度值
  TVOCData = sgp30_dat & 0x0000ffff;       //取出TVOC值
  Serial.print("CO2:");
  Serial.print(CO2Data);
  Serial.println("ppm");
 
 long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    
    snprintf (msg,75, b, value);
  
    Serial.print("Publish message: ");
    
    Serial.println(msg);
    
     pubSubClient.publish("fjjxu/13/303/date15", msg);
  
  }
 
delay(2000);
}
 
 
void reconnect() {
 
  while (!pubSubClient.connected()) {
    Serial.println("【INFO】 Retry  connect  MQTT  ...");
  
    String clientId = "Arduinoskw66-";
    clientId += String(random(0xffff), HEX);   //产生随机的ClientID
   
 
    if (pubSubClient.connect(clientId.c_str())) {
      Serial.println("connected");
  
     
      pubSubClient.subscribe(topic);   //订阅主题
 
      Serial.print("【INFO】 Successfully Subscribed to MQTT Topic:");
      Serial.println(topic);     
    } else {
      Serial.print("【ERR】 failed, rc=");
      Serial.print(pubSubClient.state());
      Serial.println(" try again in 5 seconds");
    
      delay(5000);
    }
  }
}