An example using the Myriota Modbus library with Myriota's "FlexSense" board. This example demonstrates how to read the temperature and humidity from the "DFRobot SEN0438" sensor, via the FlexSenses Myriota Modbus library.
#include <stdio.h>
#include <string.h>
#include "flex.h"
#include "myriota/modbus.h"
#define APPLICATION_NAME "DFRobot SEN0438 Modbus Driver Application"
#define MESSAGES_PER_DAY 4
#define SENSOR_READ_MAX_RETRIES 3
#define SENSOR_POWER_STABILIZATION_MS 1500
typedef struct {
uint8_t sequence_number;
uint32_t time;
int32_t latitude;
int32_t longitude;
int16_t temperature;
int16_t humidity;
typedef struct {
uint32_t baud_rate;
uint32_t rx_timeout_ticks;
} SerialContext;
typedef struct {
SerialContext serial_context;
} ApplicationContext;
static ApplicationContext application_context = {0};
static int serial_init(void *const ctx) {
SerialContext *const serial = ctx;
}
static void serial_deinit(void *const ctx) {
(void)ctx;
}
static ssize_t serial_read(void *const ctx, uint8_t *const buffer, const size_t count) {
SerialContext *const serial = ctx;
uint8_t *curr = buffer;
const uint8_t *const end = buffer + count;
const uint32_t end_ticks =
FLEX_TickGet() + serial->rx_timeout_ticks;
if (curr >= end) {
return -1;
}
if (num_bytes < 0) {
return -1;
}
if (num_bytes == 1) {
++curr;
}
}
return curr - buffer;
}
static ssize_t serial_write(void *const ctx, const uint8_t *const buffer, const size_t count) {
(void)ctx;
if (result != FLEX_SUCCESS) {
return result;
}
return count;
}
inline uint16_t merge_i16(const uint8_t hi, const uint8_t low) {
return (int16_t)((uint16_t)hi << 8 | (uint16_t)low);
}
static void read_temperature_and_humidity(int16_t *const temperature, int16_t *const humidity) {
if (result != FLEX_SUCCESS) {
printf("Failed to power sensor: %d\n", result);
return;
}
uint8_t bytes[4] = {0};
for (uint8_t retries = 0; retries < SENSOR_READ_MAX_RETRIES; ++retries) {
if (result == MODBUS_SUCCESS) {
*humidity = merge_i16(bytes[0], bytes[1]);
*temperature = merge_i16(bytes[2], bytes[3]);
break;
}
printf("Sensor Read Failed: %d\n", result);
}
}
static time_t send_message(void) {
static uint8_t sequence_number = 0;
Message message = {0};
message.sequence_number = sequence_number++;
int32_t latitude = 0;
int32_t longitude = 0;
message.latitude = latitude;
message.longitude = longitude;
int16_t temperature = 0;
int16_t humidity = 0;
read_temperature_and_humidity(&temperature, &humidity);
message.temperature = temperature;
message.humidity = humidity;
printf("Scheduled message: \n");
printf(" sequence_number: %u\n", message.sequence_number);
printf(" time: %lu\n", message.time);
printf(" latitude: %ld\n", message.latitude);
printf(" longitude: %ld\n", message.longitude);
printf(" temperature: %d\n", message.temperature);
printf(" humidity: %d\n", message.humidity);
}
void FLEX_AppInit() {
printf("%s\n", APPLICATION_NAME);
application_context.serial_context.baud_rate = 9600;
application_context.serial_context.rx_timeout_ticks = 2000;
.serial_interface =
{
.ctx = &application_context.serial_context,
.init = serial_init,
.deinit = serial_deinit,
.read = serial_read,
.write = serial_write,
},
};
if (application_context.modbus_handle <= 0) {
printf("Failed to initialized Modbus: %d\n", application_context.modbus_handle);
while (true) {
};
}
}