Jump to content

Communicating with a RCT-AXV2-2.5kW inverter


Diono

Recommended Posts

Hi,

I recently had a RCT-AXV2-2.5kW inverter installed and have subsequently decided to try and comm with the unit. Can anyone point me in the right direction. I would like to poll the unit for voltage at this time. I do have programming experience.

Thank you for your time.

Cheers,

Dion

Link to comment
Share on other sites

22 hours ago, Diono said:

I would like to poll the unit for voltage at this time. I do have programming experience.

Then you need a protocol manual; search the files section for several.

If you just want a basic monitoring program, you can download WatchPower for free. You might even have an out of date version on a CD-rom that came with the inverter.

There are other monitoring programs, some free, some inexpensive and worth the small one-time cost, e.g. Solar Assistant. I don't use any of these myself.

Edit: I'm assuming that this is an RCT branded Axpert inverter. I don't recognise the model name; maybe it's something else rebranded as RCT. If so, please disregard the above.

Edited by Coulomb
Link to comment
Share on other sites

  • 2 weeks later...

Thanks for the reply Coulomb. I am not sure if this manual can shed any light on the rebranding or not issue. The monitoring apps i looked at wont work. I want to perform certain tasks when values are at predetermined levels. If the unit is a rebranded one, any idea how to listen to the serial port and figure out which protocol is being used?

bf51c427-3bc5-4d94-8429-ee835a623d6c.thumb.jpg.95b5c60fb51fab25bcdacde961573304.jpg

Link to comment
Share on other sites

1 hour ago, Diono said:

I am not sure if this manual can shed any light on the rebranding or not issue.

Ah! It's an AXVM2, that's why I didn't recognise the model. That looks like a Voltronic manual. So it's probably an Axpert VM II. That was the first model to get the high PV voltage solar charge controller, back in about 2015 or so. Voltronic seem to have refreshed it as a VM II Premium recently, but those power levels look like they're not recent models. Voltronic don't seem to make any 12 V models any more, for example.

"2.5K" is however a strange power rating. It's possible that it's a clone, with slightly exaggerated rated apparent power. So that could be a 3.0 kVA model, with a maximum power output of 2.4 kW. Those "PF0.8" models were known by their rated real power output, not their apparent power output. For example, mine is called a PIP-4048; the 48 is the nominal battery voltage, and the 40 represents 4.0 kW rated power. It's rated at 5.0 kVA.

So any older protocol manual should do; there are several in the files section of this forum. Just avoid the Infini protocols with the commands starting with the up-arrow ('^') character.

Link to comment
Share on other sites

Thanks Coulomb. I thought you might be interested in the ratings. Also, do you know where I can get c style program examples of comms with this type of inverter?

Cheers,

Dion

2e8ef076-e477-43ae-b865-6dc8fcecb0f6.thumb.jpg.876ca397713cb1a77979ccc5feffb2c2.jpg

Link to comment
Share on other sites

On 2024/08/30 at 3:29 PM, Diono said:

do you know where I can get c style program examples of comms with this type of inverter?

No, sorry. Usually you would use an app to send the actual serial data; interfacing to say Windows is a bit painful.

The closest I'd have is this "elconsend" program I wrote ages ago to talk to an electric vehicle's charger (Elcon is one of the brand names). It has all the gory details of serial sending, for Windows or for Linux; just change one equate to switch between the two. Obviously, the top level code has to be changed to send actual commands.

The code talks about CAN bus packets;  these chargers use a small box to receive 12 byte (from memory) strings of raw serial bytes (4 address and 8 data) and turns them into CAN bus packets. I  bypassed that small box, and talked directly with the serial port.

I don't think I have code for receiving responses; that's a whole lot harder because serial comms is asynchronous.

The other code you need is the CRC calculation; C code for that is supposed to be at the end of many of the protocol manuals, but often it doesn't appear. Weber's post with the C code is here:

https://forums.aeva.asn.au/viewtopic.php?title=pip4048ms-inverter&p=53760&t=4332#p53760

=======================

/*
 * elconsend: send continuous packets to the elcon charger
 * usage: elsonsend vvv.v i.i com16
 */

#define SEND_101112 0        /* Set to nonzero to send messages 10, 11, and 12 */
#define DEBUG 1                /* Set to nonzero to echo commands to terminal in hex */
#define LINUX 0


#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#if !LINUX
#include "windows.h"
#endif

#if LINUX
struct termios  config;                /* UNIX only */
int fd;
void writeByte(const char* p) {
    write(fd, p, 1);
}
#else        // Windows
HANDLE hComm;

void writeByte(const char* p) {
    OVERLAPPED osWrite = {0};

    // Create this write operation's OVERLAPPED structure's hEvent.
    osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (osWrite.hEvent == NULL) {
        fprintf(stderr, "Error creating overlapped event handle\n");
        exit(1);
    }

    // Issue write.
    if (!WriteFile(hComm, p, 1, NULL, &osWrite)) {
         if (GetLastError() != ERROR_IO_PENDING) { 
            fprintf(stderr, "WriteFile failed, but isn't delayed.\n");
             exit(1);
        }
    }
    CloseHandle(osWrite.hEvent);

#if DEBUG
    printf("%02x ", *p & 0xFF);
#endif
}
#endif

void writeOne(unsigned int n) {
    unsigned char u;
    u = n; writeByte(&u);
}

void writeTwo(unsigned int n) {
    unsigned char u;
    u = n >> 8; writeByte(&u);        // MSB first
    u = n & 0xFF; writeByte(&u);
}

void writeID(unsigned int n) {
    writeTwo(n >> 16);        // MSBs first
    writeTwo(n & 0xFFFF);
}

int main(int argc, char* argv[]) {

    unsigned int uVoltage, uCurrent;

    if (argc != 4) {
        fprintf(stderr, "Usage: elconsend comport vvv.v ii.i\n");
        fprintf(stderr, "Example: elconsend com17 100.8 1.0\n");
        exit(1);
    }

#if LINUX
    fd = open(argv[1], O_RDWR | O_NOCTTY | O_NDELAY );
    if(!isatty(fd)) { printf("Error - not a tty!\n"); exit(1); }
    if(tcgetattr(fd, &config) < 0) {
        printf("Error - getattr failed\n"); exit(1);
    }
    //
    // Input flags - Turn off input processing
    // convert break to null byte, no CR to NL translation,
    // no NL to CR translation, don't mark parity errors or breaks
    // no input parity check, don't strip high bit off,
    // no XON/XOFF software flow control
    //
    config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
                        INLCR | PARMRK | INPCK | ISTRIP | IXON);
    //
    // Output flags - Turn off output processing
    // no CR to NL translation, no NL to CR-NL translation,
    // no NL to CR translation, no column 0 CR suppression,
    // no Ctrl-D suppression, no fill characters, no case mapping,
    // no local output processing
    //
    // config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
    //                     ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
    config.c_oflag = 0;
    //
    // No line processing:
    // echo off, echo newline off, canonical mode off, 
    // extended input processing off, signal chars off
    //
    config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
    //
    // Turn off character processing
    // clear current char size mask, no parity checking,
    // no output processing, force 8 bit input
    //
    config.c_cflag &= ~(CSIZE | PARENB);
    config.c_cflag |= CS8;
    //
    // One input byte is enough to return from read()
    // Inter-character timer off
    //
    config.c_cc[VMIN]  = 1;
    config.c_cc[VTIME] = 0;
    //
    // Communication speed (simple version, using the predefined
    // constants)
    //
    if(cfsetispeed(&config, B2400) < 0 || cfsetospeed(&config, B2400) < 0) {
        printf("Error - can't set baud rate to 2400\n");
        exit(1);
    }
    //
    // Finally, apply the configuration
    //
    if(tcsetattr(fd, TCSAFLUSH, &config) < 0) { 
        printf("Error - could not set configuration\n");
        exit(1);
    }
#else
    {
        char sName[32];
        COMMCONFIG  lpCC;
        sprintf(sName, "\\\\.\\%s", argv[1]);
        hComm = CreateFile(sName,
                    GENERIC_READ | GENERIC_WRITE, 
                    0, 
                    0, 
                    OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL,
                    0);
        if (hComm == INVALID_HANDLE_VALUE) {
              fprintf(stderr, "Error opening port %s\n", argv[1]);
            exit(1);
        }
        GetCommState( hComm, &lpCC.dcb);

         /* Initialisation of parameters */
        lpCC.dcb.BaudRate = CBR_2400;
        lpCC.dcb.ByteSize = 8;
        lpCC.dcb.StopBits = ONESTOPBIT;
        lpCC.dcb.Parity = NOPARITY;
        lpCC.dcb.fParity = 0;        /* Just in case */
        lpCC.dcb.fBinary = 1;        /* MVE */
        lpCC.dcb.fDtrControl = DTR_CONTROL_ENABLE;    /* MVE: turn on DTR, leave it on */
        lpCC.dcb.fRtsControl = RTS_CONTROL_DISABLE;
        SetCommState(hComm, &lpCC.dcb );

    }
            
#endif

    uVoltage = (unsigned int) (atof(argv[2]) * 10.0);
    uCurrent = (unsigned int) (atof(argv[3]) * 10.0);

    while (1) {
        writeID(0x1806E5F4);    /* This is the ID on the CAN box that the charger is expecting */
        writeTwo(uVoltage);
        writeTwo(uCurrent);
        writeTwo(0x000);        /* Turn on charger (0x100=0ff) */
        writeTwo(0);

#if SEND_101112
#if DEBUG
    printf("\n");
#endif
        /* Message 10 */
        writeID(0x1806E6F4);    /* PDF document says to use this ID */
        writeTwo(uVoltage);
        writeTwo(uCurrent);
        writeOne(0);            /* Enable charger */
        writeOne(24);            /* Max discharge current/10: 240 A */
        writeOne(0);            /* Reserved */
        writeOne(1);            /* Page (message subtype) = 1 */


#if DEBUG
    printf("\n");
#endif
        /* Message 11 */
        writeID(0x1806E6F4);    /* PDF document says to use this ID */
        writeTwo(400);            /* Nominal AH of battery */
        writeTwo(410);            /* Actual AH of battery */
        writeTwo(3650);            /* Cell maximum protection voltage, mV */
        writeOne(114);            /* Number of cells (?) */
        writeOne(2);            /* Page (message subtype) = 2 */

#if DEBUG
    printf("\n");
#endif
        /* Message 12 */
        writeID(0x1806E6F4);    /* PDF document says to use this ID */
        writeTwo(3600);            /* Single cell maximum present voltage, mV */
        writeTwo(3000);            /* Single cell minimum present voltage, mV */
        writeTwo(2500);            /* Single cell minimum protection voltage, mV */
        writeOne(0);            /* Battery state; 0 = normal */
        writeOne(3);            /* Page (message subtype) = 3 */

#endif

#if DEBUG
    printf("\n");
#endif
        sleep(1);                /* Do nothing for next second */
    }


#if LINUX
    close(fd);
#else
    CloseHandle(hComm);
#endif
    printf("Done\n");
    return 0;
}

 

Edited by Coulomb
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...