树莓派4+DHT11温湿度模块通过MQTT发送温湿度数据(C语言)
前段时间在树莓派上做了一个用MQTT发送温湿度数据的小程序,参考了已有的博客,发现使用的语言全是python,然而项目要求必须用C语言,花了很久的时间,也学习了许多C语言的知识,现在把学习的过程记录一下,请有需要的同学自取~
前期准备
·树莓派4
·DHT11温湿度传感器
·mosquitto(可参照树莓派安装mosquitto的博客)
代码简要说明
·MQTT服务器IP地址为192.168.1.111(使用时记得改成自己的IP地址)
·使用gpio1口读取数据,下面是树莓派4的管脚图
·主题为tempHumi
·每隔三秒发送一次
代码部分
#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <mosquitto.h>
#include <string.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;
#define HIGH_TIME 32
int pinNumber = 1; //use gpio1 to read data
uint32 databuf;
#define HOST "192.168.1.111"
#define PORT 1883
#define KEEP_ALIVE 60
#define MSG_MAX_SIZE 512
#define TOPIC_NUM 1
bool session = true;
uint8 readSensorData(void)
{
uint8 crc;
uint8 i;
pinMode(pinNumber,OUTPUT); // set mode to output
digitalWrite(pinNumber, 1); // output a low level
delayMicroseconds(4);
digitalWrite(pinNumber, 0); // output a high level
delay(25);
digitalWrite(pinNumber, 1); // output a low level
delayMicroseconds(60);
pinMode(pinNumber, INPUT); // set mode to input
pullUpDnControl(pinNumber,PUD_UP);
if(digitalRead(pinNumber)==0) //SENSOR ANS
{
while(!digitalRead(pinNumber)); //wait to high
delayMicroseconds(80);
for(i=0;i<32;i++)
{
while(digitalRead(pinNumber)); //data clock start
while(!digitalRead(pinNumber)); //data start
delayMicroseconds(HIGH_TIME);
databuf*=2;
if(digitalRead(pinNumber)==1) //1
{
databuf++;
}
}
for(i=0;i<8;i++)
{
while(digitalRead(pinNumber)); //data clock start
while(!digitalRead(pinNumber)); //data start
delayMicroseconds(HIGH_TIME);
crc*=2;
if(digitalRead(pinNumber)==1) //1
{
crc++;
}
}
return 1;
}
else
{
return 0;
}
}
const static char* topic[TOPIC_NUM] =
{
"tempHumi",
};
void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
{
if(message->payloadlen){
printf("%s %s", message->topic, (char *)message->payload);
}else{
printf("%s (null)\n", message->topic);
}
fflush(stdout);
}
void my_connect_callback(struct mosquitto *mosq, void *userdata, int result)
{
int i;
if(!result){
/* Subscribe to broker information topics on successful connect. */
mosquitto_subscribe(mosq, NULL, "ycy ", 2);
}else{
fprintf(stderr, "Connect failed\n");
}
}
void my_subscribe_callback(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos)
{
int i;
printf("Subscribed (mid: %d): %d", mid, granted_qos[0]);
for(i=1; i<qos_count; i++){
printf(", %d", granted_qos[i]);
}
printf("\n");
}
void my_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str)
{
/* Pring all log messages regardless of level. */
printf("%s\n", str);
}
int main()
{
struct mosquitto *mosq = NULL;
char buff[MSG_MAX_SIZE];
if (-1 == wiringPiSetup()) {
//printf("Setup wiringPi failed!");
return 1;
}
pinMode(pinNumber, OUTPUT); // set mode to output
digitalWrite(pinNumber, 1); // output a high level
mosquitto_lib_init();
mosq = mosquitto_new(NULL,session,NULL);
if(!mosq){
printf("create client failed..\n");
mosquitto_lib_cleanup();
return 1;
}
mosquitto_log_callback_set(mosq, my_log_callback);
mosquitto_connect_callback_set(mosq, my_connect_callback);
mosquitto_message_callback_set(mosq, my_message_callback);
mosquitto_subscribe_callback_set(mosq, my_subscribe_callback);
if(mosquitto_connect(mosq, HOST, PORT, KEEP_ALIVE)){
fprintf(stderr, "Unable to connect.\n");
return 1;
}
int loop = mosquitto_loop_start(mosq);
if(loop != MOSQ_ERR_SUCCESS)
{
printf("mosquitto loop error\n");
return 1;
}
//while(fgets(buff, MSG_MAX_SIZE, stdin) != NULL)
while(1)
{
pinMode(pinNumber,OUTPUT); // set mode to output
digitalWrite(pinNumber, 1); // output a high level
if(readSensorData())
{
printf("OK!\n");
printf("RH:%d.%d\n",(databuf>>24)&0xff,(databuf>>16)&0xff);
printf("TMP:%d.%d\n",(databuf>>8)&0xff,databuf&0xff);
// databuf=0;
}
else
{
printf("Error!\n");
}
sprintf(buff,"TMP:%d.%d,RH:%d.%d",(databuf>>8)&0xff,databuf&0xff,(databuf>>24)&0xff,(databuf>>16)&0xff);
mosquitto_publish(mosq,NULL,"tempHumi",strlen(buff),buff,0,0);
memset(buff,0,sizeof(buff));
delay(3000);
}
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 0;
}
注:最后编译时,在终端输入编译指令记得加上-lmosquitto和-lwiringPi链接必要的库
例:
gcc test.c -o test.exe -lmosquitto -lwiringPi