Implement IoT temperature measuring
This commit is contained in:
		
							parent
							
								
									cf237f74a1
								
							
						
					
					
						commit
						7804e553a9
					
				| @ -1,3 +1,3 @@ | |||||||
| all: main.c | all: main.c mqtt.c temperature.c | ||||||
| 	$(CC) -lmosquitto main.c | 	$(CC) -lmosquitto -lpthread -li2c main.c mqtt.c temperature.c | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										55
									
								
								iot/main.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								iot/main.c
									
									
									
									
									
								
							| @ -1,43 +1,46 @@ | |||||||
| #include <mosquitto.h> | #include <pthread.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <string.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
| #include "config.h" | #include "mqtt.h" | ||||||
|  | #include "temperature.h" | ||||||
| 
 | 
 | ||||||
| void on_connect(struct mosquitto *client, void *obj, int rc) | void *watch_temperature(void *arg) | ||||||
| { | { | ||||||
| 	if (rc != 0) { | 	init_temperature(); | ||||||
| 		fprintf(stderr, "%s\n", mosquitto_connack_string(rc)); | 
 | ||||||
| 		return; | 	get_temperature(); | ||||||
|  | 
 | ||||||
|  | 	while (true) { | ||||||
|  | 		double temperature = get_temperature(); | ||||||
|  | 
 | ||||||
|  | 		char *str = malloc(snprintf(NULL, 0, "%lf", temperature) + 1); | ||||||
|  | 		sprintf(str, "%lf", temperature); | ||||||
|  | 
 | ||||||
|  | 		mqtt_send_message("/temperature", str); | ||||||
|  | 
 | ||||||
|  | 		free(str); | ||||||
|  | 
 | ||||||
|  | 		printf("Temperature: %lf\n", temperature); | ||||||
|  | 
 | ||||||
|  | 		sleep(60); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	puts("Connected to " MQTT_IP); | 	return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) | void mqtt_on_connect(void) | ||||||
| { | { | ||||||
| 	printf("Received message on topic %s\n", message->topic); | 	pthread_t temperature_thread; | ||||||
|  | 	pthread_create(&temperature_thread, NULL, watch_temperature, NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int main(void) | int main(void) | ||||||
| { | { | ||||||
| 	int version[3]; | 	init_mqtt(); | ||||||
| 	mosquitto_lib_init(); |  | ||||||
| 	mosquitto_lib_version(&version[0], &version[1], &version[2]); |  | ||||||
| 	printf("Using mosquitto library version %i.%i.%i\n", version[0], version[1], version[2]); |  | ||||||
| 
 |  | ||||||
| 	struct mosquitto *mosq = mosquitto_new(NULL, true, NULL); |  | ||||||
| 
 |  | ||||||
| 	mosquitto_connect_callback_set(mosq, on_connect); |  | ||||||
| 	mosquitto_message_callback_set(mosq, on_message); |  | ||||||
| 
 |  | ||||||
| 	mosquitto_username_pw_set(mosq, MQTT_USER, MQTT_PASSWORD); |  | ||||||
| 	mosquitto_connect(mosq, MQTT_IP, MQTT_PORT, 60); |  | ||||||
| 
 |  | ||||||
| 	mosquitto_loop_forever(mosq, -1, 1); |  | ||||||
| 
 |  | ||||||
| 	mosquitto_destroy(mosq); |  | ||||||
| 	mosquitto_lib_cleanup(); |  | ||||||
| 
 | 
 | ||||||
| 	return EXIT_SUCCESS; | 	return EXIT_SUCCESS; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										57
									
								
								iot/mqtt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								iot/mqtt.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | #include <mosquitto.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <stdbool.h> | ||||||
|  | 
 | ||||||
|  | #include "config.h" | ||||||
|  | 
 | ||||||
|  | struct mosquitto *mosq; | ||||||
|  | 
 | ||||||
|  | void mqtt_on_connect(void); | ||||||
|  | 
 | ||||||
|  | void on_connect(struct mosquitto *client, void *obj, int rc) | ||||||
|  | { | ||||||
|  | 	if (rc != 0) { | ||||||
|  | 		fprintf(stderr, "%s\n", mosquitto_connack_string(rc)); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	puts("Connected to " MQTT_IP); | ||||||
|  | 
 | ||||||
|  | 	mqtt_on_connect(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) | ||||||
|  | { | ||||||
|  | 	printf("Received message on topic %s\n", message->topic); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void mqtt_send_message(char *topic, char *message) | ||||||
|  | { | ||||||
|  | 	int result = mosquitto_publish(mosq, NULL, topic, strlen(message), message, 0, false); | ||||||
|  | 	if (result != MOSQ_ERR_SUCCESS) { | ||||||
|  | 		fprintf(stderr, "Error sending message: %d\n", result); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void init_mqtt(void) | ||||||
|  | { | ||||||
|  | 	int version[3]; | ||||||
|  | 	mosquitto_lib_init(); | ||||||
|  | 	mosquitto_lib_version(&version[0], &version[1], &version[2]); | ||||||
|  | 	printf("Using mosquitto library version %i.%i.%i\n", version[0], version[1], version[2]); | ||||||
|  | 
 | ||||||
|  | 	mosq = mosquitto_new(NULL, true, NULL); | ||||||
|  | 
 | ||||||
|  | 	mosquitto_connect_callback_set(mosq, on_connect); | ||||||
|  | 	mosquitto_message_callback_set(mosq, on_message); | ||||||
|  | 
 | ||||||
|  | 	mosquitto_username_pw_set(mosq, MQTT_USER, MQTT_PASSWORD); | ||||||
|  | 	mosquitto_connect(mosq, MQTT_IP, MQTT_PORT, 60); | ||||||
|  | 
 | ||||||
|  | 	mosquitto_loop_forever(mosq, -1, 1); | ||||||
|  | 
 | ||||||
|  | 	mosquitto_destroy(mosq); | ||||||
|  | 	mosquitto_lib_cleanup(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										4
									
								
								iot/mqtt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								iot/mqtt.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | void init_mqtt(void); | ||||||
|  | 
 | ||||||
|  | void mqtt_send_message(char *topic, char *message); | ||||||
|  | 
 | ||||||
							
								
								
									
										94
									
								
								iot/temperature.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								iot/temperature.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | |||||||
|  | #include <linux/i2c-dev.h> | ||||||
|  | #include <i2c/smbus.h> | ||||||
|  | #include <stdint.h> | ||||||
|  | #include <fcntl.h> | ||||||
|  | #include <byteswap.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <errno.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <sys/ioctl.h> | ||||||
|  | 
 | ||||||
|  | #define MPC9808_BUS	"/dev/i2c-2" | ||||||
|  | #define MPC9808_ADR	0x18 | ||||||
|  | 
 | ||||||
|  | #define CONFIG_REG 0x01 | ||||||
|  | #define TUPPER_REG 0x02 | ||||||
|  | #define TLOWER_REG 0x03 | ||||||
|  | #define TCRIT_REG  0x04 | ||||||
|  | #define TA_REG     0x05 | ||||||
|  | #define MANID_REG  0x06 | ||||||
|  | #define DEVID_REG  0x07 | ||||||
|  | #define RES_REG    0x08 | ||||||
|  | 
 | ||||||
|  | int file; | ||||||
|  | 
 | ||||||
|  | uint8_t get_byte_in_integer(int num, int n) | ||||||
|  | { | ||||||
|  | 	return (num >> (8*n)) & 0xff; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | double get_temperature() | ||||||
|  | { | ||||||
|  | 	double temperature; | ||||||
|  | 	int32_t reg32; | ||||||
|  | 	uint8_t temperatureUpper; | ||||||
|  | 	uint8_t temperatureLower; | ||||||
|  | 
 | ||||||
|  | 	reg32 = i2c_smbus_read_word_data(file, TA_REG); | ||||||
|  | 	reg32 = bswap_16(reg32); // swap to little endian
 | ||||||
|  | 	reg32 = reg32 & 0x1FFF; // clear unused flags
 | ||||||
|  | 	temperatureUpper = get_byte_in_integer(reg32, 1); | ||||||
|  | 	temperatureLower = get_byte_in_integer(reg32, 0); | ||||||
|  | 
 | ||||||
|  | 	if ((temperatureUpper & 0x10) == 0x10) { | ||||||
|  | 			temperatureUpper = temperatureUpper & 0x0F; // clear negative flag
 | ||||||
|  | 			temperature = 256.0 - (temperatureUpper * 16.0 + temperatureLower / 16.0); | ||||||
|  | 	} else { | ||||||
|  | 			temperature = (temperatureUpper * 16.0 + temperatureLower / 16.0); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return temperature; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void init_temperature(void) | ||||||
|  | { | ||||||
|  | 	file = open(MPC9808_BUS, O_RDWR); | ||||||
|  | 	if (file < 0) { | ||||||
|  | 		fprintf(stderr, "Error opening temperature sensor device (%s): %s\n", MPC9808_BUS, strerror(errno)); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (ioctl(file, I2C_SLAVE, MPC9808_ADR) == -1) { | ||||||
|  | 		fprintf(stderr, "ERROR: setting  address %d on i2c bus %s with ioctl() - %s", MPC9808_ADR, MPC9808_BUS, strerror(errno)); | ||||||
|  | 		exit(1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	int32_t reg32; | ||||||
|  | 	uint16_t * const reg16poi = (uint16_t *) ®32; | ||||||
|  | 	uint8_t  * const reg8poi  = (uint8_t *)  ®32; | ||||||
|  | 
 | ||||||
|  | 	// Read manufactorer ID
 | ||||||
|  | 	reg32 = i2c_smbus_read_word_data(file, MANID_REG); | ||||||
|  | 
 | ||||||
|  | 	if ( reg32 < 0 ) { | ||||||
|  | 			fprintf(stderr, "ERROR: Read failed  on i2c bus register %d - %s\n",  MANID_REG,strerror(errno)); | ||||||
|  | 			exit(1); | ||||||
|  | 	} | ||||||
|  | 	if (bswap_16(reg16poi[0]) != 0x0054) { | ||||||
|  | 			fprintf(stderr, "Manufactorer ID wrong is 0x%x should be 0x54\n",__bswap_16(reg16poi[0])); | ||||||
|  | 			exit(1); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Read device ID and revision
 | ||||||
|  | 	reg32 = i2c_smbus_read_word_data(file, DEVID_REG); | ||||||
|  | 	if (reg32 < 0) { | ||||||
|  | 			fprintf(stderr, "ERROR: Read failed  on i2c bus register %d - %s\n",  DEVID_REG,strerror(errno) ); | ||||||
|  | 			exit(1); | ||||||
|  | 	} | ||||||
|  | 	if (reg8poi[0] != 0x04) { | ||||||
|  | 			fprintf(stderr, "Manufactorer ID OK but device ID wrong is 0x%x should be 0x4\n",reg8poi[0]); | ||||||
|  | 			exit(1); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										4
									
								
								iot/temperature.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								iot/temperature.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | void init_temperature(); | ||||||
|  | 
 | ||||||
|  | double get_temperature(); | ||||||
|  | 
 | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user