Last active
February 28, 2024 07:40
-
-
Save AD7ZJ/495f9b74469aa339b8d62549826db9ac to your computer and use it in GitHub Desktop.
modbus_rrd.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This is a simple way to read data from a MorningStar SunSaver solar charge controller | |
* over modbus. Data is output to allow entry into rrdtool: | |
* batteryVoltage:arrayVoltage:chargeCurrent:loadCurrent:ambientTemp:heatsinkTemp | |
* An example output--- 12.308:0.000:0.002:1.358:5:5 | |
* Modbus spec: https://www.morningstarcorp.com/wp-content/uploads/technical-doc-sunsaver-mppt-modbus-specification-en.pdf | |
* On a debian system, you need to install the libmodbus-dev package. | |
* Compile using: gcc -I/usr/include/modbus modbus_rrd.c -lmodbus -o modbus_rrd.o | |
*/ | |
#include <stdio.h> | |
#include <modbus.h> | |
#include <errno.h> | |
#include <string.h> | |
const int REMOTE_ID = 0x01; | |
int main(void) { | |
modbus_t *mb; | |
uint16_t tab_reg[50]; | |
memset(tab_reg, 0, sizeof(tab_reg)); | |
mb = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 2); | |
if (mb == NULL) | |
{ | |
fprintf(stderr, "Unable to create the libmodbus context\n"); | |
return -1; | |
} | |
modbus_set_slave(mb, REMOTE_ID); | |
if(modbus_connect(mb) == -1) | |
{ | |
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno)); | |
modbus_free(mb); | |
return -1; | |
} | |
// Read all 50 registers | |
if(modbus_read_registers(mb, 8, 50, tab_reg) == -1) | |
{ | |
fprintf(stderr, "Modbus Error: %s\n", modbus_strerror(errno)); | |
} | |
else | |
{ | |
double batteryVoltage = (double)(tab_reg[0] * 100) / 32768.0; | |
double arrayVoltage = (double)(tab_reg[1] * 100) / 32768.0; | |
double loadVoltage = (double)(tab_reg[2] * 100) / 32768.0; | |
double chargeCurrent = (double)(tab_reg[3] * 79.16) / 32768.0; | |
double loadCurrent = (double)(tab_reg[4] * 79.16) / 32768.0; | |
double minBattVoltage = (double)(tab_reg[43] * 100) / 32768.0; | |
double maxBattVoltage = (double)(tab_reg[44] * 100) / 32768.0; | |
printf("%.3f:%.3f:%.3f:%.3f:%d:%d\n", batteryVoltage, arrayVoltage, chargeCurrent, loadCurrent, (int8_t)tab_reg[5], (int8_t)tab_reg[7]); | |
} | |
modbus_close(mb); | |
modbus_free(mb); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment