Skip to content

Instantly share code, notes, and snippets.

@AD7ZJ
Last active February 28, 2024 07:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AD7ZJ/495f9b74469aa339b8d62549826db9ac to your computer and use it in GitHub Desktop.
Save AD7ZJ/495f9b74469aa339b8d62549826db9ac to your computer and use it in GitHub Desktop.
modbus_rrd.c
/*
* 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