1、wifi模块有时候会检测不到
2、arduino想要发送温湿度、co2浓度、光照强度、土壤湿度等其他数据 上传不了那么多,串口会显示乱码然后不发生数据消息到mqtt
3、用node-red制作了一个网页端 用来控制led、舵机、风扇、加水机,但是每次控制加水机的时候,按钮按完发送消息,加水机打开后mqtt就会断开重连不上(电池拿掉只控制继电器的话是正常的,电池装了后控制后就会不能继续运行),其他的控制暂时没出现问题
4、有环境变化自动控制,但是网页端控制希望在因为环境变化的时候风扇开启,但是我可以用网页端关掉正在运行风扇(没思路)
#include <dht11.h>
#include "SGP30.h"
#include "WiFiEspAT.h"
#include "SoftwareSerial.h"
#include <LiquidCrystal.h>
SoftwareSerial Serial1(0,6); // RX, TX
#include <PubSubClient.h> // 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);
}
}
}
主要问题是加水机通电后,用网页端控制开关喷灌机,会断开连不上mqtt,单纯控制继电器是没问题的
因为不会做,所以我对于网页端控制arduino我的思路就是利用按钮的开关发送0或者1或者其他数字消息到mqtt主题,然后arduino里收到消息做出反应
1、喷灌机通电后网页端也可以流畅的控制他的开关
2、例:当温度大于22度的时候,风扇会开启,但是我要通过网页控制他关闭,不管环境怎么样(led、舵机、加水机也想这样,不管环境怎么样,网页要他开就开要关就关)希望给出代码 我想不出来
(希望可以帮我出个主意,改一下代码,我很多都不懂所以只能凭感觉做成这样)
根据所提供的信息,这里可以看到几个不同的问题,每个问题都有自己特定的现象和背景,可以分开解决。
WiFi模块有时候会检测不到
现象:WiFi模块无法正常连接网络,Arduino无法通过MQTT发送数据。
背景:可能是由于WiFi模块连接到的路由器不稳定,或者模块自身存在问题。
解决方案:
确认WiFi模块连接的路由器是否正常工作。
尝试重新连接WiFi模块,或者更换一个新的模块。
调整WiFi模块的天线,尽可能减少干扰和阻碍。
上传的数据太多,MQTT无法正常工作
现象:通过串口发送的数据出现乱码,并且MQTT无法正常工作。
背景:可能是由于上传的数据量太大,导致MQTT无法正常处理。
解决方案:
尝试通过分批发送的方式减少数据量,或者使用更高效的数据传输方式。
确认Arduino的串口波特率设置是否正确,或者尝试更换串口线缆或端口。
检查代码逻辑,确保MQTT发布消息的时机和方式正确。
控制喷灌机时MQTT会断开连接
现象:在控制喷灌机时,MQTT会断开连接。
背景:可能是由于继电器操作时电流波动导致的,也有可能是代码逻辑的问题。
解决方案:
确认继电器和其他电路元件的工作状态是否正常,检查是否存在电流波动等问题。
尝试通过更改代码逻辑、延迟操作等方式来解决问题。
如果有可能,可以使用其他的MQTT服务器进行测试,以确定问题是否出现在MQTT服务器本身。
网页端控制不能正常工作
现象:通过网页端控制时,风扇无法按照预期的方式工作。
背景:可能是由于代码逻辑的问题,或者是因为Arduino无法正确解析网页端发送的命令。
解决方案:
确认代码逻辑是否正确,或者尝试更改代码逻辑以适应新的要求。
确认Arduino是否能够正确解析网页端发送的命令,或者尝试更换Arduino板卡或使用其他的通信方式
以下答案基于ChatGPT与GISer Liu编写:
WiFi模块有时候会检测不到:
这可能是由于WiFi信号不稳定或者WiFi模块有故障导致的。你可以尝试重新设置WiFi模块或者更换一个新的WiFi模块,看看是否能够解决问题。另外,你可以使用一些WiFi信号稳定的地方来测试你的设备,例如在一个没有障碍物的区域测试。
Arduino想要发送温湿度、CO2浓度、光照强度、土壤湿度等其他数据上传不了那么多,串口会显示乱码然后不发生数据消息到MQTT:
你可以考虑将数据进行压缩或者使用更高效的传输协议,例如JSON或者二进制格式。另外,如果你的数据量太大,可以考虑使用其他的数据存储方式,例如使用SD卡来存储数据,然后在需要的时候读取数据并上传到MQTT。
每次控制喷灌机的时候,MQTT就会断开重连不上:
这可能是由于喷灌机控制时电流过大导致的。你可以考虑使用一个外部的电源来为你的设备供电,或者使用一个电源开关来控制喷灌机的电流。另外,你可以在代码中添加一些延时来等待设备稳定后再进行下一步操作,以避免设备崩溃或者断开连接。
网页端控制希望在因为环境变化的时候风扇开启,但是我可以用网页端关掉正在运行风扇:
你可以在代码中添加一些判断逻辑,例如检测风扇是否已经开启,如果已经开启则不再开启。另外,你可以考虑使用一个定时器来控制风扇的开启和关闭,以避免频繁的开关机对设备的寿命造成影响。
该回答引用ChatGPT
您可以使用Arduino Uno和ESP01s来构建一个基于MQTT的温室智能系统。首先,您需要将Arduino Uno和ESP01s连接到同一个网络,然后使用MQTT协议将Arduino Uno和ESP01s连接起来。接下来,您可以使用Arduino Uno来控制LED、舵机、风扇和喷灌器,并使用ESP01s来接收来自网页的控制信号,从而实现温室智能系统的控制。
(1) 这可能是由于WiFi模块连接的不稳定,也有可能是因为电源不稳定
(2) 可能是由于串口传输速率过低,数据量过大,建议调整串口波特率,或将数据转换成二进制编码后发送
(3) 可能是由于继电器的电压与节点MCU的工作电压不匹配,或者继电器电压过低
(4) 可能是由于代码逻辑错误,建议检查代码中的条件语句和控制逻辑是否正确