Skip to content

RPICT Full Output Firmware

The Full Output Firmware provide the most complete and accurate way to use the RPICT card. The differences to the factory firmware are:

  • Serial data do not have an output rate but are streamed out as soon as a sampling & computation is performed.
  • All computed values are sent out.
  • Field format differ line to line depending on the type of computation performed.
  • Each line provide the coordinate of the reading (i.e. which sensors are involved)
  • Some extra fields are computed like E+ E- and Total Power in 3 phase.

Installation

We assume the Raspberrypi has been prepared with the guide below.

Howto_setup_Raspbian_for_serial_read

Get the firmware and flash it with:
Any version 5 hardware

wget lechacal.com/RPICT/sketch/RPICT_FULL_OUTPUT_001_v5.1.1_atmega.ino.hex  
lcl-upload-sketch.sh RPICT_FULL_OUTPUT_001_v5.1.1_atmega.ino.hex

Any version 6 hardware

wget lechacal.com/RPICT/sketch/RPICT_FULL_OUTPUT_001_v5.1.1_db32.ino.hex  
lcl-upload-sketch.sh RPICT_FULL_OUTPUT_001_v5.1.1_db32.ino.hex -p avr32db32

RPICT3V1T1 hardware

wget lechacal.com/RPICT/sketch/RPICT_FULL_OUTPUT_001_v5.1.1_db28_temp_PD6.ino.hex  
lcl-upload-sketch.sh RPICT_FULL_OUTPUT_001_v5.1.1_db28_temp_PD6.ino.hex -p avr32db28

Configuration

The configuration mechanism remain the same as for the default factory firmware.

Over_Serial_Configuration_-_Sketch_4

The web tool can be used in exactly the same way.

RPICT configuration web tool

The use lcl-rpict-config.py command line tool can also be used with this firmware.

Ignored parameters

The section 'Output Channels' in the web tool can be left empty as the full output firmware will not use this and have its own control of the output. In the actual configuration file this corresponds to parameters CHID CH_node_type CH_field_type.

The parameter output_rate has no effect on this firmware. Data are sent out as soon as computation is done. Only the number of cycles Ncycles affects how long a computation last.

Usage

Plain output

The lcl-run shows the plain output of the serial port.

lcl-run

Linux terminal with energy monitoring output from Raspberry Pi

The output format is described in detail in the next part of this guide.

There is one line per computation node.

Decoded Output

We have created a small python library to decode the data.

This is below a simple usage example in Python.

import rpictpylib as rpict
import serial

if __name__ == "__main__":
    ser = serial.Serial("/dev/ttyAMA0", 38400)
    ser.flush()

    while True:
        try:
            line = ser.readline().decode().strip()
            dec  = rpict.decode_full_output(line, ['rpict4v3'])

            if dec != None:

                print("---------------------------------")
                print(dec)

        except KeyboardInterrupt:
            ser.close()
            break

        except UnicodeDecodeError:
            pass

The serial port is read and stores each received line in the line parameter. The parameter dec is the decoded information in the form of a python dictionary.

decode_full_output() function is used to decode the line. It takes a list of the stack of RPICT cards used which is a list composed of any 'rpict7v1' 'rpict8' 'rpict4v3'.

Download the above example using the command below

wget lechacal.com/RPICT/example/fulloutput-demo.py

Run it using

python3 fulloutput-demo.py

This prints out python dictionary containing the data like below.

Decoded energy monitoring data from RPICT card.

Clearly this is not the most human readable form. This is why we have created a couple of additional functions.

  • print_sequential(dec)
  • display_matrix()

Sequential Print Out

We invite you to look inside the python script called lcl-fulloutput-decode.py which demonstrate how these are used.

To present the data in sequential form you can run

lcl-fulloutput-decode rpict4v3 -s

(replace rpict4v3 with whatever you have. If you have a stacked setup use for example rpict4v3,rpict8)

The text below will be shown.

Decoded energy monitoring data from RPICT card.

This is a little bit easier to read and you can see the complete information. Note for example that you can see the time which is the time since the microcontroller started.

In the above command replace rpict4v3 with the card model that is used. For example if a stacked system is used one would run

lcl-fulloutput-decode rpict4v3,rpict8 -s

Matrix Print Out

The matrix display is certainly the most comfortable for real time monitoring. The time information disappear as several computation output are shown and are not from the same computation time.

Just use the command without the -s option.

lcl-fulloutput-decode rpict4v3

Decoded energy monitoring data from RPICT card.

rpictpylib usage

Library import

The library is imported using

import rpictpylib as rpict

decode_full_output(line, model_list)

This function decodes the data from the RPICT serial stream and convert each line into a dictionary.

dec = decode_full_output(line, model_list)

line is the text string string received by the serial port obtained with serial.readline().
model_list is the list of RPICT model used. This must be a list and it defaults to ['rpict8']. The list must contain any of rpict7v1 or rpict4v3 or rpict8. If using a staked system the parameter could be for example ['rpict7v1', 'rpict8'].

The function returns a dictionary. The content of the dictionary depends on the computation node type used.

Single Signal 'type_idx' 'type_txt' 'port_idx' 'port_txt' 'level_idx' 'level_txt' 'time_start' 'time_end' 'rms' 'pest' 'e_plus'

Power 'type_idx' 'type_txt' 'port_I_idx' 'port_I_txt' 'level_I_idx' 'level_I_txt' 'port_V_idx' 'port_V_txt' 'level_V_idx' 'level_V_txt' 'time_start' 'time_end' 'irms' 'vrms' 'active_power' 'apparent_power' 'reactive_power' 'power_factor' 'e_plus' 'e_minus'

3Phase 'type_idx' 'type_txt' 'port_I1_idx' 'port_I1_txt' 'level_I1_idx' 'level_I1_txt' 'port_V1_idx' 'port_V1_txt' 'level_V1_idx' 'level_V1_txt' 'port_I2_idx' 'port_I2_txt' 'level_I2_idx' 'level_I2_txt' 'port_V2_idx' 'port_V2_txt' 'level_V2_idx' 'level_V2_txt' 'port_I3_idx' 'port_I3_txt' 'level_I3_idx' 'level_I3_txt' 'port_V3_idx' 'port_V3_txt' 'level_V3_idx' 'level_V3_txt' 'time_start' 'time_end' 'irms_1' 'irms_2' 'irms_3' 'vrms_1' 'vrms_2' 'vrms_3' 'active_power_1' 'active_power_2' 'active_power_3' 'apparent_power_1' 'apparent_power_2' 'apparent_power_3' 'reactive_power_1' 'reactive_power_2' 'reactive_power_3' 'power_factor_1' 'power_factor_2' 'power_factor_3' 'active_power_total' 'apparent_power_total' 'reactive_power_total' 'e_plus_1' 'e_minus_1' 'e_plus_2' 'e_minus_2' 'e_plus_3' 'e_minus_3'

Frequency 'type_idx' 'type_txt' 'port_idx' 'port_txt' 'level_idx' 'level_txt' 'time_start' 'time_end' 'frequency'

Temperature 'type_idx' 'type_txt' 'address' 'port_txt' 'time_start' 'time_end' 'temperature'

Note all the e_plus and e_minus above are only created once the update_storage() function has been used. See below.

rpict.print_sequential(dec)

rpict.print_sequential(dec)

The function prints out the decoded data in a nice human readable way.

realtime_storage()

The decoding function explained above only decode the data but does not have any storage functionality. We have created a class to store the latest data received. This is handy to display the data on demand and calculate energy.

rt_data = rpict.realtime_storage()

This creates an instance of realtime storage called rt_data.

rt_data.update_storage(dec)

rt_data.update_storage(dec)

This function takes the decoded data as input and update it in the realtime storage class.

This function also computes accumulated energy using previous power and time data.

rt_data.display_matrix()

rt_data.display_matrix()

Displays the realtime storage in a matrix way.

Below is the above example adapted with realtime_storage. Note this will now include E+ and E- and allow matrix display.

import rpictpylib as rpict
import serial

if __name__ == "__main__":
    ser = serial.Serial("/dev/ttyAMA0", 38400)
    ser.flush()

    rt_data = rpict.realtime_storage()

    while True:
        try:
            line = ser.readline().decode().strip()
            dec  = rpict.decode_full_output(line, ['rpict4v3'])
            rt_data.update_storage(dec)

            if dec != None:

                print("---------------------------------")
                #print(dec)
                rt_data.display_matrix()

        except KeyboardInterrupt:
            ser.close()
            break

        except UnicodeDecodeError:
            pass

Output Format

The output format follow the following group rule.

{node_type}{coordinates}{time}{data}

  • node_type is an id describing the type of computation used. See table below.
  • coordinates provides information on which ports are used.
  • time gives the start and end time since mcu boot.
  • data are all usual data like Irms Vrms Active Power etc.

Node Types

We call a node a single computation performed by the mcu. They are all listed below.

code Node Type Description
2 snode Signal Node.
3 pnode Power Node.
4 fnode Frequency Node.
5 tnode Three Phase Node.
7 Temperature

Table 1: Node Types

Using the very first output we see on this page (plain output) we can see the first code for each line is 2 4 4 4 and 5. This means we are using one single signal node then three frequency node and one 3phase node.

Coordinates

The coordinates are used to point to the ports used to read the signals. For example CT1 on slave 1 and V1 on master card.

We call CT1 CT2 V1 V2 etc 'ports'.

We call slave 1 slave 2 master etc 'levels'.

In the output they are given as integer with a specific code shown in tables below. Each node type has different coordinates structure.

  • Single Signal node: port level
  • Power node: port_I level_I port_V level_V
  • Frequency: port level
  • 3phase: port_I1 level_I1 port_V1 level_V1 port_I2 level_I2 port_V2 level_V2 port_I3 level_I3 port_V3 level_V3

Codes for ports and levels are given below.

Port Code RPICT7V1 RPICT8 RPICT4V3
0 V1 CT8 V3
1 CT7 CT7 V2
2 CT6 CT6 V1
3 CT5 CT5 nc
4 CT4 CT4 CT4
5 CT3 CT3 CT3
6 CT2 CT2 CT2
7 CT1 CT1 CT1

Note the code differ between Version 6 and Version 5 hardware.

Level Code V6 Level Code V5 Board type
0 10 Master
1 6 Slave 1
2 7 Slave 2
3 8 Slave 3
4 9 Slave 4

Time

This is the time in milliseconds since MCU boot of the beginning and end of the computation.

time_start time_end

Note the time return to zero after 4'294'967 seconds. This is about 49 days and 17 hours.

Data

These are the physical data being measured and computed. The format depends on the type of node type.

  • Single Signal node: Irms estimated_power
  • Power node: Irms Vrms active_power apparent_power reactive_power power_factor
  • Frequency: frequency
  • 3phase: Irms1 Irms2 Irms3 Vrms1 Vrms2 Vrms3 active_power1 active_power2 active_power3 apparent_power1 apparent_power2 apparent_power3 reactive_power1 reactive_power2 reactive_power3 power_factor1 power_factor2 power_factor3