简单的喷淋实验(2):(1)根据土壤湿度自动控制喷淋开关;(2)根据光照强度控制风扇以及灯的开关---嵌入式实训

目录

简单的喷淋实验(2):

(1)根据土壤湿度自动控制喷淋开关;

(2)根据光照强度控制风扇以及灯的开关---嵌入式实训

任务2:

具体过程:

所用的头文件:

data_global.h

mqtt.h

主程序:mian.c

运行结果:

运行过程视频:

上述程序存在问题:

初步破局:

继续探讨:


简单的喷淋实验(2):

(1)根据土壤湿度自动控制喷淋开关;

(2)根据光照强度控制风扇以及灯的开关---嵌入式实训

任务 2

在所给的 irrigate-1 文件夹中创建一个main.c 完成以下内容:

(1)根据土壤湿度自动控制喷淋开关

(2)根据光照强度控制风扇以及灯的开关

参考:

cpp 复制代码
#include <stdio.h>
#include <unistd.h>
#include "mqtt.h"
#include "parse_config.h"

#define SUB_TOPIC  "1703161172612/AIOTSIM2APP"   //定阅的主题
#define PUB_TOPIC  "1703161172612/APP2AIOTSIM"  //发布主题

#define IRRIGATED_ON "{\"irrigated\":true}"
#define IRRIGATED_OFF "{\"irrigated\":false}"

#define FAN_ON		"{\"fan\":true}"
#define FAN_OFF		"{\"fan\":false}"

#define LAMP_ON		"{\"lamp\":true}"
#define LAMP_OFF		"{\"lamp\":false}"

#define ALARM_ON		"{\"alarm\":true}"
#define ALARM_OFF		"{\"alarm\":false}"

int main(int argc, const char *argv[])
{
	ENV msg_env={};
	//1.初始化mqtt协议
	if(mqtt_init()!=0)
	{
		printf("mqtt init err.\n");
		return -1;
	}
	//订阅别人发布的消息
	if(mqtt_subscribe(SUB_TOPIC) < 0)
	{
		printf("sub err.\n");
		return -1;
	}
	//循环获取温湿度
	//当大于阈值关闭灌溉,小于就打开
	while(1)
	{
		sleep(1);
		//获取值
		msg_env=get_virtual_env();

		if(msg_env.ill < 20000)
		{
			mqtt_publish(PUB_TOPIC,FAN_OFF);
			mqtt_publish(PUB_TOPIC,LAMP_ON);
		}else if(msg_env.ill > 50000)
		{
			mqtt_publish(PUB_TOPIC,FAN_ON);
			mqtt_publish(PUB_TOPIC,LAMP_OFF);
		}
		printf("ill:%f\n",msg_env.ill);


		if(msg_env.soil < 30)
		{
			mqtt_publish(PUB_TOPIC,IRRIGATED_ON);
		}else if(msg_env.soil > 50)
		{
			mqtt_publish(PUB_TOPIC,IRRIGATED_OFF);
		}
		printf("soilhum:%f\n",msg_env.soil);

		// if(msg_env.infrared == 1)
		// {
		// 	mqtt_publish(PUB_TOPIC,ALARM_ON);
		// }else {
		// 	mqtt_publish(PUB_TOPIC,ALARM_OFF);
		// }
		// printf("infrared:%d\n",msg_env.infrared);

	}
	exit_mqtt();
	return 0;
}

具体过程:

所用的头文件:
data_global.h
cpp 复制代码
#ifndef __DATA_GLOBAL__H__
#define __DATA_GLOBAL__H__

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <time.h>
#include <termios.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdbool.h>
struct env_info
{
	float soil;  //土壤湿度
	float light; //光照强度
	float temp;   //空气温度
	uint8_t gas;    //有害气体
};

extern struct env_info env_msg;

//设备编号
#define FAN  0x00
#define BEEP 0x10
#define LED  0x20
#define PUMP 0X30

#define DATA_ARRIVE SIGUSR1 //数据到达信号


//订阅、发布主题
#define ENV_PUB_TOPIC "FS_VRJJ/control"

//虚拟仿真硬件协议
#define LAMP_ON    "{\"lamp\":true}"
#define LAMP_OFF   "{\"lamp\":false}"

#define ALARM_ON   "{\"alarm\":true}"
#define ALARM_OFF  "{\"alarm\":false}"

#define SUNSHADE_FOR "{\"sunshade\":\"forward\"}"
#define SUNSHADE_REV	"{\"sunshade\":\"reverse\"}"
#define SUNSHADE_STOP	"{\"sunshade\":\"stop\"}"

#define VIR_FAN_ON	"{\"fan\":true}"
#define VIR_FAN_OFF "{\"fan\":false}"

#define IRRIGATED_OFF "{\"irrigated\":false}"
#define IRRIGATED_ON "{\"irrigated\":true}"
#endif
mqtt.h
cpp 复制代码
#ifndef __MQTT_SMART_H_
#define __MQTT_SMART_H_


typedef struct env
{
	float soil;//土壤湿度
	float ill;//光照
	int smog;//烟雾
	int infrared;//人体红外
}ENV;
int mqtt_init();
void exit_mqtt();
int mqtt_subscribe(const char*topic);
int mqtt_publish(const char *topic, char *msg);
ENV get_virtual_env();

#endif
主程序:mian.c
cpp 复制代码
#include<stdio.h>
#include"mqtt.h"
#include<unistd.h>
#include"data_global.h"
 
#define subscribe "1703503856299/AIOTSIM2APP"
#define publish "1703503856299/APP2AIOTSIM"
int main(int argc, char *argv[]){
    //1-连接服务器
    mqtt_init();
 
    //2-订阅元宇宙平台主题,获得数据串
        //通过目标节点的发布主题,才能的得到发布的内容
    mqtt_subscribe(subscribe);

 
    //4.循环获取数据,下发控制指令
    while (1){
        sleep(1);
        ENV env= get_virtual_env();
        if (env.soil>60){
            mqtt_publish(publish, IRRIGATED_OFF);
            printf("关闭喷淋。。。。\n");
        }
        else if (env.soil<30){
            mqtt_publish(publish, IRRIGATED_ON);
            printf("打开喷淋\n");
        }

        printf("当前土壤湿度:%.2f\n", env.soil);

        if (env.ill>27000)
        {
            mqtt_publish(publish, VIR_FAN_ON);
            mqtt_publish(publish,  LAMP_OFF);
            printf("打开风扇,关闭灯。。。。\n");
        }
        else if (env.ill<25000)
        {
            mqtt_publish(publish,  VIR_FAN_OFF);
            mqtt_publish(publish,  LAMP_ON);
            printf("关闭风扇,打开灯。。。。。。\n");
        }
        
        sleep(1);
        printf("当前光照强度:%.2f\n", env.ill);
        printf("++++++++++++++++++++++++++++\n");
    }
    exit_mqtt();
    return 0;
}
运行结果:

元宇宙未运行时:

元宇宙运行后:

运行过程视频:

嵌入式实训2023-12-25 20-19-53


上述程序存在问题:

初步破局:

在元宇宙实验平台还没开始运行时,各种数据都是0,就会导致程序通过if、else if判断语句来控制各种机器运作,这是不正确的。为了避免这种情况,可以添加一些额外的判断来解决这个问题。

首先,我们可以在while循环之前添加一个延时等待,让实验平台有足够的时间来获取和发送数据。例如,我们可以使用sleep函数来等待5秒钟:

cpp 复制代码
sleep(5); // 等待5秒钟,让实验平台有足够的时间来获取和发送数据

然后,我们可以在if、else if判断语句之前添加一个判断,检查所需的数据是否已经被正确地获取。例如,我们可以检查土壤湿度是否为0来确定是否成功获取了土壤湿度数据:

cpp 复制代码
ENV env= get_virtual_env();
if (env.soil == 0) {
    printf("未成功获取到土壤湿度数据,等待下一次获取...\n");
    sleep(1);
    continue; // 跳过本次循环,等待下一次循环
}

// 在此之后添加if、else if判断语句进行控制

同样,我们可以添加类似的判断来检查光照强度等数据是否已经被正确获取。这样做可以避免在数据未准备好时误操作机器,保证程序的正确性。

完整代码:

cpp 复制代码
#include<stdio.h>
#include"mqtt.h"
#include<unistd.h>
#include"data_global.h"
 
#define subscribe "1703503856299/AIOTSIM2APP"
#define publish "1703503856299/APP2AIOTSIM"
int main(int argc, char *argv[]){
    //1-连接服务器
    mqtt_init();
 
    //2-订阅元宇宙平台主题,获得数据串
        //通过目标节点的发布主题,才能的得到发布的内容
    mqtt_subscribe(subscribe);

    //3.等待数据准备就绪
    printf("等待数据准备就绪...\n");
    sleep(5); // 等待5秒钟,让实验平台有足够的时间来获取和发送数据

    //4.循环获取数据,下发控制指令
    while (1){
        ENV env= get_virtual_env();
        if (env.soil == 0) {
            printf("未成功获取到土壤湿度数据,等待下一次获取...\n");
            sleep(1);
            continue; // 跳过本次循环,等待下一次循环
        }

        if (env.soil>60){
            mqtt_publish(publish, IRRIGATED_OFF);
            printf("关闭喷淋。。。。\n");
        }
        else if (env.soil<30){
            mqtt_publish(publish, IRRIGATED_ON);
            printf("打开喷淋\n");
        }

        printf("当前土壤湿度:%.2f\n", env.soil);

        if (env.ill == 0) {
            printf("未成功获取到光照强度数据,等待下一次获取...\n");
            sleep(1);
            continue; // 跳过本次循环,等待下一次循环
        }

        if (env.ill>27000)
        {
            mqtt_publish(publish, VIR_FAN_ON);
            mqtt_publish(publish,  LAMP_OFF);
            printf("打开风扇,关闭灯。。。。\n");
        }
        else if (env.ill<25000)
        {
            mqtt_publish(publish,  VIR_FAN_OFF);
            mqtt_publish(publish,  LAMP_ON);
            printf("关闭风扇,打开灯。。。。。。\n");
        }
        
        printf("当前光照强度:%.2f\n", env.ill);
        printf("++++++++++++++++++++++++++++\n");
        sleep(1);
    }

    exit_mqtt();
    return 0;
}

继续探讨:

还是有点问题,如果等待5秒后,实验平台运行了,但是土壤湿度和光照强度又恰好是0呢?这样是没有错误的呀

上述提出了一个很好的问题。确实,在等待5秒后,如果土壤湿度和光照强度仍然是0,那么程序就会继续执行,而不会等待数据准备就绪。为了解决这个问题,可以使用一个循环来判断数据是否已经准备就绪,并设置一个最大等待时间。

下面是修改后的代码示例:

cpp 复制代码
#include<stdio.h>
#include"mqtt.h"
#include<unistd.h>
#include"data_global.h"
 
#define subscribe "1703503856299/AIOTSIM2APP"
#define publish "1703503856299/APP2AIOTSIM"
int main(int argc, char *argv[]){
    //1.连接服务器
    mqtt_init();
 
    //2.订阅元宇宙平台主题,获得数据串
    //通过目标节点的发布主题,才能的得到发布的内容
    mqtt_subscribe(subscribe);

    //3.等待数据准备就绪
    printf("等待数据准备就绪...\n");
    int max_wait_time = 10; // 最大等待时间为10秒
    int wait_time = 0; // 已等待的时间
    ENV env;
    while (1){
        env= get_virtual_env();
        if (env.soil != 0 && env.ill != 0) {
            break; // 数据已准备就绪,跳出循环
        }

        sleep(1);
        wait_time++;
        if(wait_time >= max_wait_time){
            printf("超过最大等待时间,未成功获取到数据!\n");
            exit_mqtt();
            return 0;
        }
    }

    //4.循环获取数据,下发控制指令
    while (1){
        if (env.soil>60){
            mqtt_publish(publish, IRRIGATED_OFF);
            printf("关闭喷淋。。。。\n");
        }
        else if (env.soil<30){
            mqtt_publish(publish, IRRIGATED_ON);
            printf("打开喷淋\n");
        }

        printf("当前土壤湿度:%.2f\n", env.soil);

        if (env.ill>27000)
        {
            mqtt_publish(publish, VIR_FAN_ON);
            mqtt_publish(publish,  LAMP_OFF);
            printf("打开风扇,关闭灯。。。。\n");
        }
        else if (env.ill<25000)
        {
            mqtt_publish(publish,  VIR_FAN_OFF);
            mqtt_publish(publish,  LAMP_ON);
            printf("关闭风扇,打开灯。。。。。。\n");
        }
        
        printf("当前光照强度:%.2f\n", env.ill);
        printf("++++++++++++++++++++++++++++\n");
        sleep(1);
    }

    exit_mqtt();
    return 0;
}
相关推荐
Horacek18 分钟前
《C++ 实现生成多个弹窗程序》
java·开发语言·c++·学习·算法
zero_one_Machel30 分钟前
leetcodeQ76最小覆盖子串
java·开发语言·算法
qincjun31 分钟前
算法:快排(三指针算法)
算法·leetcode
Helene190031 分钟前
Leetcode 968-监控二叉树
算法·leetcode·职场和发展
luky!36 分钟前
算法----查找列表中元素的最小值和最大值
开发语言·python·算法
Tang Paofan1 小时前
C++ constexpr
开发语言·c++
数据智能老司机2 小时前
Python现代时间序列预测——时间序列简介
人工智能·算法·机器学习
AICodeThunder2 小时前
C++知识点总结(57):STL综合
java·c++·算法
薔薇十字2 小时前
【代码随想录day32】【C++复健】509. 斐波那契数;70. 爬楼梯;746. 使用最小花费爬楼梯
开发语言·c++·算法
qq_1873526342 小时前
c++基础36时间复杂度
c++·c++基础36时间复杂度