diff --git a/iot/Makefile b/iot/Makefile index 563e22c..1635675 100644 --- a/iot/Makefile +++ b/iot/Makefile @@ -1,3 +1,3 @@ -all: main.c - $(CC) -lmosquitto main.c +all: main.c mqtt.c temperature.c + $(CC) -lmosquitto -lpthread -li2c main.c mqtt.c temperature.c diff --git a/iot/main.c b/iot/main.c index 3862f39..06b99d6 100644 --- a/iot/main.c +++ b/iot/main.c @@ -1,43 +1,46 @@ -#include +#include #include +#include +#include +#include #include -#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) { - fprintf(stderr, "%s\n", mosquitto_connack_string(rc)); - return; + init_temperature(); + + 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 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]); - - 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(); + init_mqtt(); return EXIT_SUCCESS; } diff --git a/iot/mqtt.c b/iot/mqtt.c new file mode 100644 index 0000000..ae9de13 --- /dev/null +++ b/iot/mqtt.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include + +#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(); +} + diff --git a/iot/mqtt.h b/iot/mqtt.h new file mode 100644 index 0000000..d3b52a8 --- /dev/null +++ b/iot/mqtt.h @@ -0,0 +1,4 @@ +void init_mqtt(void); + +void mqtt_send_message(char *topic, char *message); + diff --git a/iot/temperature.c b/iot/temperature.c new file mode 100644 index 0000000..7f8348e --- /dev/null +++ b/iot/temperature.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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); + } +} + diff --git a/iot/temperature.h b/iot/temperature.h new file mode 100644 index 0000000..8bd0a39 --- /dev/null +++ b/iot/temperature.h @@ -0,0 +1,4 @@ +void init_temperature(); + +double get_temperature(); +