Add MH-Z14B CO2 Sensor

This commit is contained in:
aixiao 2024-01-09 15:27:17 +08:00
parent eee4b0ba11
commit 60f349df59
11 changed files with 219 additions and 39 deletions

View File

@ -1,8 +1,3 @@
# raspberrypi # Raspberrypi GPIO
raspberrypi zero w GPIO 实现的智能家居 raspberrypi GPIO C 程序
- 参考:http://shumeipai.nxez.com/2016/06/26/raspberry-pi-diy-with-a-smart-home-server.html
- 我发现传感器的数据是实时的,传感器的工作必须是实时的
- 有时做不到数据的准确
- 就做了多进程的shell(不同pid)来满足传感器数据现状,一个进程收集传感器数据,另一个进程处理数据.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -3,7 +3,7 @@ CC := $(CROSS_COMPILE)gcc
STRIP := $(CROSS_COMPILE)strip STRIP := $(CROSS_COMPILE)strip
CFLAGS += -g -O2 -Wall CFLAGS += -g -O2 -Wall
LIBS = -lwiringPi LIBS = -lwiringPi
BIN = infrared light pin sound ultrasound wind dht11 dht12 helement key_light BIN = infrared light pin sound ultrasound wind dht11 dht12 helement key_light ch4 pasco2v01
all: $(BIN) all: $(BIN)
@ -28,6 +28,11 @@ helement: helement.o
key_light: key_light.o key_light: key_light.o
$(CC) $(CFLAGS) -o key_light $^ $(LIBS) $(CC) $(CFLAGS) -o key_light $^ $(LIBS)
ch4: ch4.o
$(CC) $(CFLAGS) -o ch4 $^ $(LIBS)
pasco2v01: pasco2v01.o
$(CC) $(CFLAGS) -o pasco2v01 $^ $(LIBS)
.c.o: .c.o:
$(CC) $(CFLAGS) -c $< $(LIBS) $(CC) $(CFLAGS) -c $< $(LIBS)

47
gpio/ch4.c Normal file
View File

@ -0,0 +1,47 @@
/*
*
* N55A甲烷气体传感器
*
*/
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
void setup(int pin) {
wiringPiSetup();
pinMode(pin, INPUT);
}
int readMethaneLevel(int pin) {
int methaneDetected = digitalRead(pin);
return methaneDetected;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Error: Invalid number of arguments.\n");
printf("Usage: %s PIN\n", argv[0]);
exit(1);
}
int pin = atoi(argv[1]);
if (pin < 0) {
printf("Error: Invalid PIN value.\n");
exit(1);
}
setup(pin);
while(1) {
int result = readMethaneLevel(pin);
if (result == HIGH) {
printf("CH4\n");
}
delay(1000); // 每隔1秒读取一次传感器
}
return 0;
}

View File

@ -7,49 +7,46 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
//#include <linux/type.h>
#include <ctype.h> #include <ctype.h>
static int is_num(char *str) int is_num(const char *str) {
{ while (*str != '\0') {
int i, len; if (!isdigit(*str)) {
for (i = 0, len = strlen(str); i < len; i++) { return 0;
if (isdigit(str[i]) == 0) {
printf("不是数字\n");
return 1;
} }
str++;
} }
return 1;
return 0;
} }
int main(int argc, char *argv[])
{ int main(int argc, char *argv[]) {
if (argc != 3) { if (argc != 3) {
printf("Parameter error.\n"); printf("Error: Invalid number of arguments.\n");
exit(1); printf("Usage: %s PIN VALUE\n", argv[0]);
} exit(1);
}
if (is_num(argv[1]) == 1) {
printf("Parameter error, parameter 1 is PIN pin value\n"); int pin = atoi(argv[1]);
exit(1); if (!is_num(argv[1]) || (pin < 0)) {
} printf("Error: Invalid PIN value.\n");
exit(1);
if (is_num(argv[2]) == 1) { }
printf("Parameter error, parameter 2 is true or false\n");
int value = atoi(argv[2]);
if (!is_num(argv[2]) || (value != 0 && value != 1)) {
printf("Error: Invalid value. Please enter 0 or 1.\n");
exit(1); exit(1);
} }
int pin = atol(argv[1]);
wiringPiSetup(); wiringPiSetup();
pinMode(pin, OUTPUT); pinMode(pin, OUTPUT);
if (atol(argv[2]) == 1) {
digitalWrite(pin, HIGH); if (digitalRead(pin) != value) {
digitalWrite(pin, value);
} }
if (atol(argv[2]) == 0) {
digitalWrite(pin, LOW); return value;
} }
return atol(argv[2]);
}

71
gpio/mh-z14b.c Normal file
View File

@ -0,0 +1,71 @@
/*
*
* MH-Z14B CO2 Sensor
* Based on Raspberry Pi wiringPi library
* Time: 20240109
*
*/
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <unistd.h>
// 校准
static void calibration(int fd)
{
// 校准传感器零点ZERO
char zero[9] = { 0XFF, 0X01, 0X87, 0X00, 0X00, 0X00, 0X00, 0X00, 0X78 };
write(fd, zero, 9);
delay(200);
return;
}
int main()
{
int fd = 0;
char checksum = 0;
int High = 0;
int Low = 0;
int ppm = 0;
char read_command[9] = { 0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79 };
char data[9] = { 0 };
if ((fd = serialOpen("/dev/serial0", 9600)) < 0) {
printf("Unable to open device\n");
return 1;
} else {
printf("ttyAMA0 initialised ok\n");
}
while (1) {
// 写入读取命令
write(fd, read_command, 9);
delay(100);
// 读取
read(fd, data, 9);
checksum = (0xFF - (data[1] + data[2] + data[3] + data[4] + data[5] + data[6] + data[7])) + 1;
High = (int)data[2];
Low = (int)data[3];
ppm = (256 * High) + Low;
if (data[8] == checksum) {
for (int loop = 0; loop <= 8; loop++) {
printf("data%d: %X\n", loop, data[loop]);
}
printf("checksum: %X = %X\n", data[8], checksum);
printf("CO2 Concentration: %d ppm\n\r\n", ppm);
} else {
calibration(fd);
continue;
}
delay(3000);
}
return 0;
}

65
gpio/pasco2v01.c Normal file
View File

@ -0,0 +1,65 @@
/*
*
* CO2 PASCO2V01
*
*/
#include <stdio.h>
#include <wiringPiI2C.h>
// Pasco2V01 设备地址
#define DEVICE_ADDRESS 0x76
// 最大尝试次数
#define MAX_RETRY 100
int main() {
// 初始化 I2C 总线
int fd = wiringPiI2CSetup(DEVICE_ADDRESS);
if (fd < 0) {
printf("Failed to initialize I2C\n");
return -1;
}
// 发送命令开始测量
int result = wiringPiI2CWrite(fd, 0x00);
if (result < 0) {
printf("Failed to write command\n");
return -1;
}
// 等待传感器完成测量
int retry = 0;
while (retry < MAX_RETRY) {
int status = wiringPiI2CReadReg8(fd, 0x00);
if (status < 0) {
printf("Failed to read status\n");
return -1;
}
if (status & 0x08) {
break;
}
retry++;
}
if (retry >= MAX_RETRY) {
printf("Measurement timeout\n");
return -1;
}
// 读取测量结果
unsigned char data[3];
data[0] = wiringPiI2CReadReg8(fd, 0x02);
data[1] = wiringPiI2CReadReg8(fd, 0x03);
data[2] = wiringPiI2CReadReg8(fd, 0x04);
// 转换为浓度值
unsigned int concentration = (data[0] << 16) | (data[1] << 8) | data[2];
// 打印浓度值
printf("Gas Concentration: %u ppm\n", concentration);
return 0;
}