RPICT Full Output Firmware: Difference between revisions

From lechacal
Jump to navigation Jump to search
No edit summary
 
(30 intermediate revisions by the same user not shown)
Line 1: Line 1:
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=
=Installation=


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


[[Howto_setup_Raspbian_for_serial_read]]
[[Howto_setup_Raspbian_for_serial_read]]
Line 42: Line 50:
==Plain output==
==Plain output==


When using the lcl-run command produces the following output.
The lcl-run shows the plain output of the serial port.


  lcl-run
  lcl-run
Line 50: Line 58:
The output format is described in detail in the next part of this guide.
The output format is described in detail in the next part of this guide.


There is one line per computation node.  
There is one line per computation node.


==Decoded Output==
==Decoded Output==
Line 129: Line 137:


[[File:Fulloutput_001.png]]
[[File:Fulloutput_001.png]]
=rpictpylib usage=
==Library import==
The library is imported using
<syntaxhighlight lang="python">
import rpictpylib as rpict
</syntaxhighlight>
==decode_full_output(line, model_list)==
This function decodes the data from the RPICT serial stream and convert each line into a dictionary.
<syntaxhighlight lang="python">
dec = decode_full_output(line, model_list)
</syntaxhighlight>
'''line''' is the text string string received by the serial port obtained with serial.readline(). <br>
'''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'''<br>
<span style="font-family: courier;">
'type_idx'<br>
'type_txt'<br>
'port_idx'<br>
'port_txt'<br>
'level_idx'<br>
'level_txt'<br>
'time_start'<br>
'time_end'<br>
'rms'<br>
'pest'<br>
'e_plus'<br>
</span>
'''Power'''<br>
<span style="font-family: courier;">
'type_idx'<br>
'type_txt'<br>
'port_I_idx'<br>
'port_I_txt'<br>
'level_I_idx'<br>
'level_I_txt'<br>
'port_V_idx'<br>
'port_V_txt'<br>
'level_V_idx'<br>
'level_V_txt'<br>
'time_start'<br>
'time_end'<br>
'irms'<br>
'vrms'<br>
'active_power'<br>
'apparent_power'<br>
'reactive_power'<br>
'power_factor'<br>
'e_plus'<br>
'e_minus'<br>
</span>
'''3Phase'''<br>
<span style="font-family: courier;">
'type_idx'<br>
'type_txt'<br>
'port_I1_idx'<br>
'port_I1_txt'<br>
'level_I1_idx'<br>
'level_I1_txt'<br>
'port_V1_idx'<br>
'port_V1_txt'<br>
'level_V1_idx'<br>
'level_V1_txt'<br>
'port_I2_idx'<br>
'port_I2_txt'<br>
'level_I2_idx'<br>
'level_I2_txt'<br>
'port_V2_idx'<br>
'port_V2_txt'<br>
'level_V2_idx'<br>
'level_V2_txt'<br>
'port_I3_idx'<br>
'port_I3_txt'<br>
'level_I3_idx'<br>
'level_I3_txt'<br>
'port_V3_idx'<br>
'port_V3_txt'<br>
'level_V3_idx'<br>
'level_V3_txt'<br>
'time_start'<br>
'time_end'<br>
'irms_1'<br>
'irms_2'<br>
'irms_3'<br>
'vrms_1'<br>
'vrms_2'<br>
'vrms_3'<br>
'active_power_1'<br>
'active_power_2'<br>
'active_power_3'<br>
'apparent_power_1'<br>
'apparent_power_2'<br>
'apparent_power_3'<br>
'reactive_power_1'<br>
'reactive_power_2'<br>
'reactive_power_3'<br>
'power_factor_1'<br>
'power_factor_2'<br>
'power_factor_3'<br>
'active_power_total'<br>
'apparent_power_total'<br>
'reactive_power_total'<br>
'e_plus_1'<br>
'e_minus_1'<br>
'e_plus_2'<br>
'e_minus_2'<br>
'e_plus_3'<br>
'e_minus_3'<br>
</span>
'''Frequency'''<br>
<span style="font-family: courier;">
'type_idx'<br>
'type_txt'<br>
'port_idx'<br>
'port_txt'<br>
'level_idx'<br>
'level_txt'<br>
'time_start'<br>
'time_end'<br>
'frequency'<br>
</span>
'''Temperature'''<br>
<span style="font-family: courier;">
'type_idx'<br>
'type_txt'<br>
'address'<br>
'port_txt'<br>
'time_start'<br>
'time_end'<br>
'temperature'<br>
</span>
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)==
<syntaxhighlight lang="python">
rpict.print_sequential(dec)
</syntaxhighlight>
The function prints out the decoded data in a nice humen 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.
<syntaxhighlight lang="python">
rt_data = rpict.realtime_storage()
</syntaxhighlight>
This creates an instance of realtime storage called rt_data.
==rt_data.update_storage(dec)==
<syntaxhighlight lang="python">
rt_data.update_storage(dec)
</syntaxhighlight>
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()==
<syntaxhighlight lang="python">
rt_data.display_matrix()
</syntaxhighlight>
Displays the realtime storage in a matrix way.


=Output Format=
=Output Format=
Line 171: Line 365:
|Three Phase Node.  
|Three Phase Node.  
|Same as pnode but for three phase.
|Same as pnode but for three phase.
|-
|7
|
|Temperature
|
|}
|}


Line 264: Line 463:
|-
|-
|}
|}
==Time==
This is the time in milliseconds since MCU boot of the beginning and end of the computation.
<span style="font-family: courier;">time_start time_end</span>
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: <span style="font-family: courier;">Irms estimated_power</span>
* Power node: <span style="font-family: courier;">Irms Vrms active_power apparent_power reactive_power power_factor</span>
* Frequency: <span style="font-family: courier;">frequency</span>
* 3phase: <span style="font-family: courier;">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</span>

Latest revision as of 21:10, 10 November 2023

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

We also assume the packages to flash the Arduino have been setup.

Upload_Arduino_sketch_from_Raspberrypi_to_RPICT

Get the firmware:

wget lechacal.com/RPICT/sketch/RPICT_FULL_OUTPUT_001_v4.1.0.ino.hex

Flash it with:

lcl-upload-sketch.sh RPICT_FULL_OUTPUT_001_v4.1.0.ino.hex

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

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.

The zip package downloaded above contains a very simple example usage.

 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'.

Run it using

python3 fulloutput-demo.py

This prints out python dictionary containing the data like below.

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.

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

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 humen 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.

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.

Table 1: Node Types
code Node Type Description
2 snode Signal Node. Compute RMS only of a single channel. Efficient and lightweight computation.
3 pnode Power Node. Computes all power related values of a current/voltage pair. Requires definition of both current and voltage sensor ports.
4 fnode Frequency Node. Computes frequency only on a given sensor port.
5 tnode Three Phase Node. Same as pnode but for three phase.
7 Temperature

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 are given below.

Table 2: ports
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


Table 3: levels
Code Board type
10 Master
6 Slave 1
7 Slave 2
8 Slave 3
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