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

目录

简单的喷淋实验(2):

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

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

任务2:

具体过程:

所用的头文件:

data_global.h

mqtt.h

主程序:mian.c

运行结果:

运行过程视频:

上述程序存在问题:

初步破局:

继续探讨:


简单的喷淋实验(2):

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

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

任务2

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

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

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

参考:

#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
#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
#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
#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秒钟:

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

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

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

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

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

完整代码:

#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,那么程序就会继续执行,而不会等待数据准备就绪。为了解决这个问题,可以使用一个循环来判断数据是否已经准备就绪,并设置一个最大等待时间。

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

#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;
}
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,这是一个比较基础的cc2530ADC实验。您需要先准备好以下材料和工具: - cc2530开发板 - 光敏电阻 - LED - 面包板 - 杜邦线 - 电脑 - 烧录器 - 串口调试助手 步骤如下: 1. 将光敏电阻连接到cc2530开发板的ADC口(一般是P0_5口)。具体连线方式可参考面包板上的接线图。 2. 将LED连接到cc2530开发板的某个IO口(如P1_0口)。 3. 打开CC2530的开发环境,新建一个工程。 4. 编写代码,实现光照强度自动控制LED亮灭,并通过串口调试助手实时显示光照强度。以下是参考代码: ``` #include "ioCC2530.h" #define LED P1_0 #define ADC_PORT P0_5 void init_adc(){ ADCCON3 = 0x08; //选择ADC通道 ADCCON1 = 0x20; //ADC时钟为16MHz/4=4MHz ADCCON2 = 0x00; //不启用ADC参考电压 } unsigned int read_adc(){ unsigned int adc_data; ADCCON1 |= 0x40; //开始ADC转换 while (ADCCON1 & 0x40); //等待转换完成 adc_data = ADCL; adc_data |= ((unsigned int)ADCH) << 8; return adc_data; } void delay(unsigned long i){ while(i--); } void main(void){ unsigned int adc_value; P1SEL &= ~(1<<0); //将P1_0口设为普通IO口 P1DIR |= (1<<0); //将P1_0口设为输出模式 init_adc(); //初始化ADC while(1){ adc_value = read_adc(); //读取ADC值 if(adc_value > 1000){ //当光照强度较强时,LED熄灭 LED = 0; } else{ //当光照强度较弱时,LED点亮 LED = 1; } printf("ADC Value:%d\r\n",adc_value); //通过串口调试助手实时显示光照强度 delay(1000000); //延时1s } } ``` 5. 将代码烧录到cc2530开发板上。 6. 打开串口调试助手,设置波特率为115200,选择正确的串口号,点击打开串口。 7. 接上电源,观察LED的亮灭情况,并在串口调试助手上实时查看光照强度值。 希望这个步骤可以帮助到您。如果您还有其他问题,请随时提出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

captain_dong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值