Skip to content

Instantly share code, notes, and snippets.

@AD7ZJ
Created February 11, 2024 07:14
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/525e2973fee1669ceeba2ad0223c2f78 to your computer and use it in GitHub Desktop.
Save AD7ZJ/525e2973fee1669ceeba2ad0223c2f78 to your computer and use it in GitHub Desktop.
Simple modbus read for MorningStar SS-MPPT-15 solar charge controller.
/*
* This is a simple way to read data from a MorningStar SunSaver solar charge controller
* over modbus. Data is read into the array "tab_reg" and you can manipulate as needed.
* 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_test.c -lmodbus -o modbus_test.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("Battery: %.3f V\n", batteryVoltage);
printf("Array: %.3f V\n", arrayVoltage);
printf("Load: %.3f V\n", loadVoltage);
printf("Charging: %.3f A\n", chargeCurrent);
printf("Consuming: %.3f A\n", loadCurrent);
printf("Heatsink temp: %d C\n", tab_reg[5]);
printf("Ambient temp: %d C\n", tab_reg[7]);
printf("Charge State: %d\n", tab_reg[9]);
printf("Min Battery Voltage: %.3f V\n", minBattVoltage);
}
modbus_close(mb);
modbus_free(mb);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment