RocketLogger 2.1.1
meter.c
Go to the documentation of this file.
1
32#include <stdint.h>
33
34#include <ncurses.h>
35
36#include "pru.h"
37#include "rl.h"
38#include "util.h"
39
40#include "meter.h"
41
43char const *const RL_CHANNEL_UNITS[RL_CHANNEL_COUNT] = {
44 "V", "V", "V", "V", "uA", "mA", "uA", "mA", "ms"};
45
48 100000000, 100000000, 100000000, 100000000, 100000,
49 1000000, 100000, 1000000, 1000000};
50
55
56void meter_init(void) {
57 // init ncurses mode
58 initscr();
59 // hide cursor
60 curs_set(0);
61
62 mvprintw(1, 1, "Starting RocketLogger Meter ...");
63 refresh();
64}
65
66void meter_deinit(void) { endwin(); }
67
68void meter_print_buffer(int32_t const *analog_buffer,
69 uint32_t const *digital_buffer, size_t buffer_size,
70 rl_timestamp_t const *const timestamp_realtime,
71 rl_timestamp_t const *const timestamp_monotonic,
72 rl_config_t const *const config) {
73 // aggregation buffer and configuration
74 uint32_t aggregate_digital = ~(0);
75 double aggregate_analog[RL_CHANNEL_COUNT] = {0};
76
77 // process data buffers
78 for (size_t i = 0; i < buffer_size; i++) {
79 // point to sample buffer
80 int32_t const *const analog_data = analog_buffer + i * RL_CHANNEL_COUNT;
81 uint32_t const *const digital_data = digital_buffer + i;
82
83 // aggregate data
84 switch (config->aggregation_mode) {
86 // use first sample of buffer only, skip storing others
87 if (i == 0) {
88 for (int j = 0; j < RL_CHANNEL_COUNT; j++) {
89 aggregate_analog[j] = (double)analog_data[j];
90 }
91 aggregate_digital = *digital_data;
92 }
93 break;
94
95 default:
97 // accumulate data of the aggregate window, store at the end
98 for (int j = 0; j < RL_CHANNEL_COUNT; j++) {
99 aggregate_analog[j] += (double)*(analog_data + j);
100 }
101 aggregate_digital = aggregate_digital & *digital_data;
102 break;
103 }
104 }
105
106 // on last sample of the window: average analog data and store
108 for (int j = 0; j < RL_CHANNEL_COUNT; j++) {
109 aggregate_analog[j] = aggregate_analog[j] / buffer_size;
110 }
111 }
112
113 // display data
114 // clear screen
115 erase();
116
117 // display values
118 mvprintw(1, 28, "RocketLogger CLI Monitor");
119
120 mvprintw(3, 10, "Time:");
121 mvprintw(3, 20, "% 12lld.%09lld (monotonic)", timestamp_monotonic->sec,
122 timestamp_monotonic->nsec);
123 mvprintw(4, 20, "% 12lld.%09lld (realtime)", timestamp_realtime->sec,
124 timestamp_realtime->nsec);
125
126 int current_index = 0;
127 int voltage_index = 0;
128 for (int i = 0; i < RL_CHANNEL_COUNT; i++) {
129 if (is_current(i)) {
130 // current
131 mvprintw(9 + 2 * current_index, 40, "%s:", RL_CHANNEL_NAMES[i]);
132 mvprintw(9 + 2 * current_index, 50, "%12.6f %s",
133 (aggregate_analog[i] / RL_CHANNEL_SCALES[i]),
135 current_index++;
136 } else {
137 // voltage
138 mvprintw(9 + 2 * voltage_index, 10, "%s:", RL_CHANNEL_NAMES[i]);
139 mvprintw(9 + 2 * voltage_index, 20, "%9.6f %s",
140 (aggregate_analog[i] / RL_CHANNEL_SCALES[i]),
142 voltage_index++;
143 }
144 }
145
146 // display titles, range information
147 mvprintw(7, 10, "Voltages:");
148 mvprintw(7, 40, "Currents:");
149 if (aggregate_digital & PRU_DIGITAL_I1L_VALID_MASK) {
150 mvprintw(9, 70, "I1L valid");
151 } else {
152 mvprintw(9, 70, "I1L invalid");
153 }
154 if (aggregate_digital & PRU_DIGITAL_I2L_VALID_MASK) {
155 mvprintw(13, 70, "I2L valid");
156 } else {
157 mvprintw(13, 70, "I2L invalid");
158 }
159
160 // digital inputs
161 if (config->digital_enable) {
162 mvprintw(20, 10, "Digital Inputs:");
163
164 for (int i = 0; i < 3; i++) {
165 mvprintw(20 + 2 * i, 30, "%s:", RL_CHANNEL_DIGITAL_NAMES[i]);
166 mvprintw(20 + 2 * i, 38, "%d",
167 (aggregate_digital & DIGITAL_INPUT_BITS[i]) > 0);
168 }
169 for (int i = 3; i < 6; i++) {
170 mvprintw(20 + 2 * (i - 3), 50, "%s:", RL_CHANNEL_DIGITAL_NAMES[i]);
171 mvprintw(20 + 2 * (i - 3), 58, "%d",
172 (aggregate_digital & DIGITAL_INPUT_BITS[i]) > 0);
173 }
174 } else {
175 mvprintw(20, 10, "Digital inputs disabled.");
176 }
177
178 // move cursor for warning outputs on new line
179 mvprintw(27, 2, "");
180
181 refresh();
182}
uint32_t const DIGITAL_INPUT_BITS[RL_CHANNEL_DIGITAL_COUNT]
Digital input bit location in binary data.
Definition meter.c:52
void meter_init(void)
Definition meter.c:56
char const *const RL_CHANNEL_UNITS[RL_CHANNEL_COUNT]
Analog channel units.
Definition meter.c:43
void meter_print_buffer(int32_t const *analog_buffer, uint32_t const *digital_buffer, size_t buffer_size, rl_timestamp_t const *const timestamp_realtime, rl_timestamp_t const *const timestamp_monotonic, rl_config_t const *const config)
Definition meter.c:68
double const RL_CHANNEL_SCALES[RL_CHANNEL_COUNT]
Analog channel scales.
Definition meter.c:47
void meter_deinit(void)
Definition meter.c:66
#define PRU_DIGITAL_INPUT1_MASK
Definition pru.h:54
#define PRU_DIGITAL_I1L_VALID_MASK
Definition pru.h:60
#define PRU_DIGITAL_INPUT5_MASK
Definition pru.h:58
#define PRU_DIGITAL_INPUT3_MASK
Definition pru.h:56
#define PRU_DIGITAL_I2L_VALID_MASK
Definition pru.h:61
#define PRU_DIGITAL_INPUT6_MASK
Definition pru.h:59
#define PRU_DIGITAL_INPUT4_MASK
Definition pru.h:57
#define PRU_DIGITAL_INPUT2_MASK
Definition pru.h:55
char const *const RL_CHANNEL_NAMES[RL_CHANNEL_COUNT]
RocketLogger channel names.
Definition rl.c:95
char const *const RL_CHANNEL_DIGITAL_NAMES[RL_CHANNEL_DIGITAL_COUNT]
RocketLogger digital channel names.
Definition rl.c:103
#define RL_CHANNEL_DIGITAL_COUNT
Number of RocketLogger digital channels.
Definition rl.h:60
#define RL_CHANNEL_COUNT
Number of RocketLogger analog channels.
Definition rl.h:56
@ RL_AGGREGATION_MODE_AVERAGE
Aggregate using down sampling.
Definition rl.h:130
@ RL_AGGREGATION_MODE_DOWNSAMPLE
Definition rl.h:129
rl_aggregation_mode_t aggregation_mode
Sample aggregation mode (for sampling rates below lowest native one)
Definition rl.h:172
bool digital_enable
Enable digital inputs.
Definition rl.h:174
int64_t nsec
Nanoseconds.
Definition util.h:53
int64_t sec
Seconds in UNIX time (UTC)
Definition util.h:51
bool is_current(int index)
Definition util.c:49