Integration

Modbus Registers Map

About these Registers:

DEVICE_ID / REMOTE_TERMINAL_UNIT (RTU) / SLAVE_ID:

Each sensor on a single multi-drop bus line must have a unique DEVICE_ID / RTU / SLAVE_ID:
By Default the DEVICE_ID / RTU / SLAVE_ID is the LAST 2 DIGITS OF THE SENSORS SERIAL NUMBER
The serial number (and therefore, the RTU number) can be found on the side of the TriVibe on the white label.

INDEXING:

Note that the listed registers below are considered 0-Indexed (the first value starts at 0)
Some Modbus masters will need to shift all the values up by one value if their master recognized the first Modbus value at 1 (known as 1-indexed).

SERIAL COMMUNICATION SETTINGS:

Baudrate: 115200
Parity: None
Handshakes: None
Data Bits: 8
Stop Bits: 1

FUNCTION CODES:

The function codes supported by TriVibe Sensor are:

0x03 READ MULTIPLE HOLDING REGISTERS 
0x10 WRITE MULTIPLE HOLDING REGISTERS

--- If you want to read or write to just a single register, you can do this by setting the length/offset/number of registers to 1 ---

Endianness:

The TriVibe sensor uses the Big Endian memory allocation paradigm.

In computingendianness is the order or sequence of bytes of a word of digital data in computer memory. Endianness is primarily expressed as big-endian (BE) or little-endian (LE). A big-endian system stores the most significant byte of a word at the smallest memory address and the least significant byte at the largest. A little-endian system, in contrast, stores the least-significant byte at the smallest address.

Address Name Read / Write Type Description / Measurand
0 SYSTEM_INFO Read Only 16-Bit
Unsigned Integer
FirmwareID + Revision
1 SYSTEM_CONTROL Read / Write 16-Bit
Unsigned Integer

Command Values (Use with Caution):

 

[0] - idle
[1] - reset using SCB_AIRCR = 0x05FA0004 command
[2] - clear alarms
[3] - load data
[12398] - unlock all registers as read/write
[12450] - erase eeprom (necessary to unlock all registers and write MODBUS_ERASE_EEPROM to SECURITY register)
[24576] - unlock calibration registers as read/write
[24577] - save calibration registers to non-volatile memory
[42074] - unlock alarm registers as read/write
[42075] - save alarm registers to non-volatile memory
[45555] - unlock config registers as read/write
[45556] - save config registers to non-volatile memory
[55555] - restart the firmware
[60006] - reset DDR controller
[60007] - save data from DATA registers to CLIP buffer
[60008] - read DDR delay to DATA registers
[60009] - write DDR delay from DATA registers and lock

2 SYSTEM_STATUS Read Only 16-bit
Unsigned Integer
  1. command done
  2. command in progress
  3. command error
3 SYSTEM_STATE1 Read Only

16-bit
Unsigned Integer

MACHINE_ON Bit 0
4 SYSTEM_STATE2 Read Only 16-bit
Unsigned Integer
  • POWER_ERROR_BIT 0
  • DRAM_ERROR_BIT 1
  • ADC_ERROR_BIT 2
  • NVM_ERROR_BIT 3
  • TEMPERATURE_ERROR_BIT 4
  • CALIBRATION_ERROR_BIT 5
  • COLLECT_ERROR_BIT 6
  • IMPACT_ERROR_BIT 7
  • ALARM_ERROR_BIT 8
  • ALARM_LEVEL_ERROR_BIT 9
  • COLLECT2_ERROR_BIT 10
  • SIN_TABLE_ERROR_BIT 11
  • DETONATION_ERROR_BIT 12
  • BOARD_TYPE_ERROR_BIT 13
  • ONOFF_ERROR_BIT 14
5 MINUTES_ON Read Only 16-bit
Unsigned Integer
 
6 HOURS_ON Read Only 16-bit
Unsigned Integer
 
7 DAYS_ON Read Only 16-bit
Unsigned Integer
 
8 SYSTEM_DEBUG1 Read Only 16-bit
Unsigned Integer
 
9 SYSTEM_DEBUG2 Read Only 16-bit
Unsigned Integer
 
10 Last Command of SYSTEM_CONTROL Read Only 16-bit
Unsigned Integer
 
11 PERIPHERAL_STATE Read Only 16-bit
Unsigned Integer
I2C_BUS_BIT 0
12 DDR_CONTROLLER_RESTART Read / Write 16-bit
Unsigned Integer
 
13 LAST_SYSTEM_ERROR Read Only 16-bit
Unsigned Integer
 
14 SYSTEM_MODE Read Only 16-bit
Unsigned Integer
ENABLE_COLLECT_BIT 0
ENABLE_IMPACT_BIT 1
ENABLE_DETONATION_BIT 2
ENABLE_EXT_IMPACT_BIT 3
15 SYSTEM_ERROR Read Only 16-bit
Unsigned Integer
 
16 SYSTEM_ECU Read Only 16-bit
Unsigned Integer
 
17 SYSTEM_RTU Read Only 16-bit
Unsigned Integer
 
18 HIGH_DATA_POINTER Read/Write 32-bit
Unsigned Integer
 
19 LOW_DATA_POINTER Read/Write    
20 HIGH_UIDH Read Only 32-bit
Unsigned Integer
 
21 LOW_UIDH Read Only    
22 HIGH_UIDMH Read Only 32-bit
Unsigned Integer
 
23 LOW_UIDMH Read Only    
24 HIGH_UIDML Read Only 32-bit
Unsigned Integer
 
25 LOW_UIDML Read Only    
26 HIGH_SERIAL_NUMBER (UIDL) Read Only 32-bit
Unsigned Integer
 
27 LOW__SERIAL_NUMBER (UIDL) Read Only    
28 TEMP_SENSOR_READ_STATS Read Only 16-bit
Unsigned Integer
 
29 TEMP_SENSOR_READ_ERROR_STATS Read Only 16-bit
Unsigned Integer
 
30 TEMP_SENSOR_TYPE Read Only 16-bit
Unsigned Integer
  • MODBUS_UNKNOWN_TEMPERATURE_SENSOR 0
  • MODBUS_DS1821_TEMPERATURE_SENSOR 1
  • MODBUS_MAX31820_TEMPERATURE_SENSOR 2
  • MODBUS_DS1631_TEMPERATURE_SENSOR 3
31 TEMPERATURE Read Only 16-bit
Signed Integer
Divide Value / 10
32 DDC_AXIS Read / Write 16-bit
Unsigned Integer
  • 0-IDLE
  • 1-A1
  • 2-A2
  • 3-A3
  • 4-virtual
  • 5-A1A2A3 Internal Accel 1
  • 6-A1A2A3 Internal Accel 2
33 DDC_CONTROL_RAW Write Only 16-bit
Unsigned Integer
  • MODBUS_CAPTURE_IDLE 0
  • MODBUS_CAPTURE_START 1
  • MODBUS_SNAPSHOT_CAPTURE_START 2
  • MODBUS_SNAPSHOOT_INIT 3
34 DDC_CAPTURE_ENGINE_STATUS Read / Write 16-bit
Unsigned Integer
  • IDLE 0
  • DONE 1
  • IN-PROGRESS 2
  • ERROR 3-255
35 DDC_CAPTURE_TIME_MS Read / Write 16-bit
Unsigned Integer
 
36 DDC_HIGH_SAMPLES_PER_AXIS Read / Write 32-bit
Unsighed Integer
 
37 DDC_LOW_SAMPLES_PER_AXIS Read / Write    
38 ADC_STATUS Read Only 16-bit
Unsigned Integer
  • MADCSR_SENSOR1_AXIS1_BIT 0
  • MADCSR_SENSOR1_AXIS2_BIT 1
  • MADCSR_SENSOR1_AXIS3_BIT 2
  • MADCSR_SENSOR2_AXIS1_BIT 3
  • MADCSR_SENSOR2_AXIS2_BIT 4
  • MADCSR_SENSOR2_AXIS3_BIT 5
  • MADCSR_ERROR_BIT 15
39 AXIS_1_SENSOR_1_DETONATION Read Only 16-bit
Unsigned Integer
 
40 AXIS_2_SENSOR_1_DETONATION Read Only 16-bit
Unsigned Integer
 
41 AXIS_3_SENSOR_1_DETONATION Read Only 16-bit
Unsigned Integer
 
42 AXIS_1_SENSOR_2_DETONATION Read Only 16-bit
Unsigned Integer
 
43 AXIS_2_SENSOR_2_DETONATION Read Only 16-bit
Unsigned Integer
 
44 AXIS_2_SENSOR_2_DETONATION Read Only 16-bit
Unsigned Integer
 
45 IMPACT_ALERT Read Only 16-bit
Unsigned Integer
 
46 IMPACT_DANGER Read Only 16-bit
Unsigned Integer
 
47 IMPACT_AVERAGED_ALERT Read Only 16-bit
Unsigned Integer
 
48 IMPACT_AVERAGED_DANGER Read Only 16-bit
Unsigned Integer
 
49 DDC_START_SAMPLE Read / Write 16-bit
Unsigned Integer

This register will start by holding a 0 (indicating the 0th sample is in register 50, ready to be read). After successfully reading the data clip sample in register 171, this register should read 122 (indicating the 122nd sample is in register 50, ready to be read).

50-171 DDC_SAMPLES Read Only 16-bit
Unsigned Integers

Block reads of registers 49 - 171 repeatedly until your SAMPLES_PER_AXIS * 3 are collected to your Modbus Master is the recommended approach for collecting dynamic data clips.

171 DDC_SAMPLES_AUTO_INCREMENT Read Only 16-bit
Unsigned Integer

Each time register 171 is successfully read by a Modbus Master. Register 49 is updated to reflect the index of the sample in register 50 and the next set of DDC Samples is loaded into registers 50 - 171.

172 HIGH_AXIS_1_ACCELERATION Read Only 32-bit
Floating Point
g_RMS
173 LOW_AXIS_1_ACCELERATION Read Only    
174 HIGH_AXIS_2_ACCELERATION Read Only 32-bit
Floating Point
g_RMS
175 LOW_AXIS_2_ACCELERATION Read Only    
176 HIGH_AXIS_3_ACCELERATION Read Only 32-bit
Floating Point
g_RMS
177 LOW_AXIS_3_ACCELERATION Read Only    
178 HIGH_AXIS_1_VELOCITY Read Only 32-bit
Floating Point
in/sec2_RMS
179 LOW_AXIS_1_VELOCITY Read Only    
180 HIGH_AXIS_2_VELOCITY Read Only 32-bit
Floating Point
in/sec2_RMS
181 LOW_AXIS_2_VELOCITY Read Only    
182 HIGH_AXIS_3_VELOCITY Read Only 32-bit
Floating Point
in/sec2_RMS
183 LOW_AXIS_3_VELOCITY Read Only    
184 HIGH_AXIS_1_DISPLACEMENT Read Only 32-bit
Floating Point
mils
185 LOW_AXIS_1_DISPLACEMENT Read Only    
186 HIGH_AXIS_2_DISPLACEMENT Read Only 32-bit
Floating Point
mils
187 LOW_AXIS_2_DISPLACEMENT Read Only    
188 HIGH_AXIS_3_DISPLACEMENT Read Only 32-bit
Floating Point
mils
189 LOW_AXIS_3_DISPLACEMENT Read Only    
190 INTERNAL_ACCELEROMETER_1_HIGH_AXIS_1_ACCELERATION Read Only 32-bit
Floating Point
g_RMS
191 INTERNAL_ACCELEROMETER_1_LOW_AXIS_1_ACCELERATION Read Only    
192 INTERNAL_ACCELEROMETER_1_HIGH_AXIS_2_ACCELERATION Read Only 32-bit
Floating Point
g_RMS
193 INTERNAL_ACCELEROMETER_1_LOW_AXIS_2_ACCELERATION Read Only    
194 INTERNAL_ACCELEROMETER_1_HIGH_AXIS_3_ACCELERATION Read Only 32-bit
Floating Point
g_RMS
195 INTERNAL_ACCELEROMETER_1_LOW_AXIS_3_ACCELERATION Read Only    
196 INTERNAL_ACCELEROMETER_1_HIGH_AXIS_1_VELOCITY Read Only 32-bit
Floating Point
in/sec2_RMS
197 INTERNAL_ACCELEROMETER_1_LOW_AXIS_1_VELOCITY Read Only    
198 INTERNAL_ACCELEROMETER_1_HIGH_AXIS_2_VELOCITY Read Only 32-bit
Floating Point
in/sec2_RMS
199 INTERNAL_ACCELEROMETER_1_LOW_AXIS_2_VELOCITY Read Only    
200 INTERNAL_ACCELEROMETER_1_HIGH_AXIS_3_VELOCITY Read Only 32-bit
Floating Point
in/sec2_RMS
201 INTERNAL_ACCELEROMETER_1_LOW_AXIS_3_VELOCITY Read Only    
202 INTERNAL_ACCELEROMETER_1_HIGH_AXIS_1_DISPLACEMENT Read Only 32-bit
Floating Point
mils
203 INTERNAL_ACCELEROMETER_1_LOW_AXIS_1_DISPLACEMENT Read Only    
204 INTERNAL_ACCELEROMETER_1_HIGH_AXIS_2_DISPLACEMENT Read Only 32-bit
Floating Point
mils
205 INTERNAL_ACCELEROMETER_1_LOW_AXIS_2_DISPLACEMENT Read Only    
206 INTERNAL_ACCELEROMETER_1_HIGH_AXIS_3_DISPLACEMENT Read Only 32-bit
Floating Point
mils
207 INTERNAL_ACCELEROMETER_1_LOW_AXIS_3_DISPLACEMENT Read Only    
208 INTERNAL_ACCELEROMETER_2_HIGH_AXIS_1_ACCELERATION Read Only 32-bit
Floating Point
g_RMS
209 INTERNAL_ACCELEROMETER_2_LOW_AXIS_1_ACCELERATION Read Only    
210 INTERNAL_ACCELEROMETER_2_HIGH_AXIS_2_ACCELERATION Read Only 32-bit
Floating Point
g_RMS
211 INTERNAL_ACCELEROMETER_2_LOW_AXIS_2_ACCELERATION Read Only    
212 INTERNAL_ACCELEROMETER_2_HIGH_AXIS_3_ACCELERATION Read Only 32-bit
Floating Point
g_RMS
213 INTERNAL_ACCELEROMETER_2_LOW_AXIS_3_ACCELERATION Read Only    
214 INTERNAL_ACCELEROMETER_2_HIGH_AXIS_1_VELOCITY Read Only 32-bit
Floating Point
in/sec2_RMS
215 INTERNAL_ACCELEROMETER_2_LOW_AXIS_1_VELOCITY Read Only    
216 INTERNAL_ACCELEROMETER_2_HIGH_AXIS_2_VELOCITY Read Only 32-bit
Floating Point
in/sec2_RMS
217 INTERNAL_ACCELEROMETER_2_LOW_AXIS_2_VELOCITY Read Only    
218 INTERNAL_ACCELEROMETER_2_HIGH_AXIS_3_VELOCITY Read Only 32-bit
Floating Point
in/sec2_RMS
219 INTERNAL_ACCELEROMETER_2_LOW_AXIS_3_VELOCITY Read Only    
220 INTERNAL_ACCELEROMETER_2_HIGH_AXIS_1_DISPLACEMENT Read Only 32-bit
Floating Point
mils
221 INTERNAL_ACCELEROMETER_2_LOW_AXIS_1_DISPLACEMENT Read Only    
222 INTERNAL_ACCELEROMETER_2_HIGH_AXIS_2_DISPLACEMENT Read Only 32-bit
Floating Point
mils
223 INTERNAL_ACCELEROMETER_2_LOW_AXIS_2_DISPLACEMENT Read Only    
224 INTERNAL_ACCELEROMETER_2_HIGH_AXIS_3_DISPLACEMENT Read Only 32-bit
Floating Point
mils
225 INTERNAL_ACCELEROMETER_2_LOW_AXIS_3_DISPLACEMENT Read Only    
226 ALARM_1_STATE Read Only 16-bit
Unsigned Integer
  • MODBUS_NO_ALARM 0
  • MODBUS_LO_ALARM 1
  • MODBUS_HI_ALARM 2
  • MODBUS_HIHI_ALARM 3
  • MODBUS_NORMAL_ALARM 4
227 ALARM_2_STATE Read Only 16-bit
Unsigned Integer
  • MODBUS_NO_ALARM 0
  • MODBUS_LO_ALARM 1
  • MODBUS_HI_ALARM 2
  • MODBUS_HIHI_ALARM 3
  • MODBUS_NORMAL_ALARM 4
228 ALARM_3_STATE Read Only 16-bit
Unsigned Integer
  • MODBUS_NO_ALARM 0
  • MODBUS_LO_ALARM 1
  • MODBUS_HI_ALARM 2
  • MODBUS_HIHI_ALARM 3
  • MODBUS_NORMAL_ALARM 4
229 ALARM_4_STATE Read Only 16-bit
Unsigned Integer
  • MODBUS_NO_ALARM 0
  • MODBUS_LO_ALARM 1
  • MODBUS_HI_ALARM 2
  • MODBUS_HIHI_ALARM 3
  • MODBUS_NORMAL_ALARM 4
230 HIGH_ALARM_1_HIGHEST_VALUE Read Only 32-bit
Floating Point
 
231 LOW_ALARM_1_HIGHEST_VALUE Read Only    
232 HIGH_ALARM_2_HIGHEST_VALUE Read Only 32-bit
Floating Point
 
233 LOW_ALARM_2_HIGHEST_VALUE Read Only    
234 HIGH_ALARM_3_HIGHEST_VALUE Read Only 32-bit
Floating Point
 
235 LOW_ALARM_3_HIGHEST_VALUE Read Only    
236 HIGH_ALARM_4_HIGHEST_VALUE Read Only 32-bit
Floating Point
 
237 LOW_ALARM_4_HIGHEST_VALUE Read Only    
238 ALARM_CONTROL Read / Write 16-bit
Unsigned Integer
  • RESET_ALARM1_HIGHEST_VALUES_BIT 0
  • RESET_ALARM2_HIGHEST_VALUES_BIT 1
  • RESET_ALARM3_HIGHEST_VALUES_BIT 2
  • RESET_ALARM4_HIGHEST_VALUES_BIT 3
239 HIGH_ALARM_1_NORMAL Read / Write 32-bit
Floating Point
 
240 LOW_ALARM_1_NORMAL Read / Write    
241 HIGH_ALARM_2_NORMAL Read / Write 32-bit
Floating Point
 
242 LOW_ALARM_2_NORMAL Read / Write    
243 HIGH_ALARM_3_NORMAL Read / Write 32-bit
Floating Point
 
244 LOW_ALARM_3_NORMAL Read / Write    
245 HIGH_ALARM_4_NORMAL Read / Write 32-bit
Floating Point
 
246 LOW_ALARM_4_NORMAL Read / Write    
247 HIGH_ALARM_1_LO Read / Write 32-bit
Floating Point
 
248 LOW_ALARM_1_LO Read / Write    
249 HIGH_ALARM_2_LO Read / Write 32-bit
Floating Point
 
250 LOW_ALARM_2_LO Read / Write    
251 HIGH_ALARM_3_LO Read / Write 32-bit
Floating Point
 
252 LOW_ALARM_3_LO Read / Write    
253 HIGH_ALARM_4_LO Read / Write 32-bit
Floating Point
 
254 LOW_ALARM_4_LO Read / Write    
255 HIGH_ALARM_1_HI Read / Write 32-bit
Floating Point
 
256 LOW_ALARM_1_HI Read / Write    
257 HIGH_ALARM_2_HI Read / Write 32-bit
Floating Point
 
258 LOW_ALARM_2_HI Read / Write    
259 HIGH_ALARM_3_HI Read / Write 32-bit
Floating Point
 
260 LOW_ALARM_3_HI Read / Write    
261 HIGH_ALARM_4_HI Read / Write 32-bit
Floating Point
 
262 LOW_ALARM_4_HI Read / Write    
263 HIGH_ALARM_1_HIHI Read / Write 32-bit
Floating Point
 
264 LOW_ALARM_1_HIHI Read / Write    
265 HIGH_ALARM_2_HIHI Read / Write 32-bit
Floating Point
 
266 LOW_ALARM_2_HIHI Read / Write    
267 HIGH_ALARM_3_HIHI Read / Write 32-bit
Floating Point
 
268 LOW_ALARM_3_HIHI Read / Write    
269 HIGH_ALARM_4_HIHI Read / Write 32-bit
Floating Point
 
270 LOW_ALARM_4_HIHI Read / Write    
272 ALARM_MULTIPLIER Read / Write    
273-276 RESERVED - - -
277 MODBUS_RELEASE Read Only 16-bit
Unsigned Integer
 
278 AXIS_1_SENSOR_1_EXT_IMPACT_ALERT Read Only 16-bit
Unsigned Integer
 
279 AXIS_2_SENSOR_1_EXT_IMPACT_ALERT Read Only 16-bit
Unsigned Integer
 
280 AXIS_3_SENSOR_1_EXT_IMPACT_ALERT Read Only 16-bit
Unsigned Integer
 
281 AXIS_1_SENSOR_2_EXT_IMPACT_ALERT Read Only 16-bit
Unsigned Integer
 
282 AXIS_2_SENSOR_2_EXT_IMPACT_ALERT Read Only 16-bit
Unsigned Integer
 
283 AXIS_3_SENSOR_2_EXT_IMPACT_ALERT Read Only 16-bit
Unsigned Integer
 
284 AXIS_1_SENSOR_1_EXT_IMPACT_DANGER Read Only 16-bit
Unsigned Integer
 
285 AXIS_2_SENSOR_1_EXT_IMPACT_DANGER Read Only 16-bit
Unsigned Integer
 
286 AXIS_3_SENSOR_1_EXT_IMPACT_DANGER Read Only 16-bit
Unsigned Integer
 
287 AXIS_1_SENSOR_2_EXT_IMPACT_DANGER Read Only 16-bit
Unsigned Integer
 
288 AXIS_2_SENSOR_2_EXT_IMPACT_DANGER Read Only 16-bit
Unsigned Integer
 
289 AXIS_3_SENSOR_2_EXT_IMPACT_DANGER Read Only 16-bit
Unsigned Integer
 
290 AXIS_1_SENSOR_1_EXT_IMPACT_SEVERITY Read Only 16-bit
Unsigned Integer
Returned Value = GPK*10
291 AXIS_2_SENSOR_1_EXT_IMPACT_SEVERITY Read Only 16-bit
Unsigned Integer
Returned Value = GPK*10
292 AXIS_3_SENSOR_1_EXT_IMPACT_SEVERITY Read Only 16-bit
Unsigned Integer
Returned Value = GPK*10
293 AXIS_1_SENSOR_2_EXT_IMPACT_SEVERITY Read Only 16-bit
Unsigned Integer
Returned Value = GPK*10
294 AXIS_2_SENSOR_2_EXT_IMPACT_SEVERITY Read Only 16-bit
Unsigned Integer
Returned Value = GPK*10
295 AXIS_3_SENSOR_2_EXT_IMPACT_SEVERITY Read Only 16-bit
Unsigned Integer
Returned Value = GPK*10
296 ALGORITHM_TIME Read / Write 16-bit
Unsigned Integer
Milliseconds
297 INVALID_DATA_COUNTER Read Only 16-bit
Unsigned Integer
 
298 SECURITY_REGSTER Read Only 16-bit
Unsigned Integer
 
299 HIGH_A1S1_SENSITIVITY_REGISTER Read / Write 32-bit
Floating Point
 
300 LOW_A1S1_SENSITIVITY_REGISTER Read / Write    
301 HIGH_A2S1_SENSITIVITY_REGISTER Read / Write 32-bit
Floating Point
 
302 LOW_A2S1_SENSITIVITY_REGISTER Read / Write    
303 HIGH_A3S1_SENSITIVITY_REGISTER Read / Write 32-bit
Floating Point
 
304 LOW_A3S1_SENSITIVITY_REGISTER Read / Write    
305 HIGH_A1S2_SENSITIVITY_REGISTER Read / Write 32-bit
Floating Point
 
306 LOW_A1S2_SENSITIVITY_REGISTER Read / Write    
307 HIGH_A2S2_SENSITIVITY_REGISTER Read / Write 32-bit
Floating Point
 
308 LOW_A2S2_SENSITIVITY_REGISTER Read / Write    
309 HIGH_A3S2_SENSITIVITY_REGISTER Read / Write 32-bit
Floating Point
 
310 LOW_A3S2_SENSITIVITY_REGISTER Read / Write    
311 ALARM_TRIP_DELAY Read / Write 16-bit
Unsigned Integer

This delay is applied to all 4 Alarm Channels

312 ALARM1_AXIS Read / Write 16-bit
Unsigned Integer
  • ALARM_AXIS_IDLE 0
  • ALARM_AXIS_1 1
  • ALARM_AXIS_2 2
  • ALARM_AXIS_3 3
  • ALARM_AXIS_T 4
  • ALARM_AXIS_IT 5
  • ALARM_AXIS_IC 6
  • ALARM_AXIS_1_D 7
  • ALARM_AXIS_2_D 8
  • ALARM_AXIS_3_D 9
  • ALARM_AXIS_1_IT 10
  • ALARM_AXIS_2_IT 11
  • ALARM_AXIS_3_IT 12
  • ALARM_AXIS_1_IC 13
  • ALARM_AXIS_2_IC 14
  • ALARM_AXIS_3_IC 15
313 ALARM1_TYPE Read / Write 16-bit
Unsigned Integer
  • ALARM_TYPE_IDLE 0
  • ALARM_TYPE_VELOCITY 1
  • ALARM_TYPE_ACCELERATION 2
  • ALARM_TYPE_DISPLACEMENT 3
  • ALARM_TYPE_TEMPERATURE 4
  • ALARM_TYPE_ALERT 5
  • ALARM_TYPE_DANGER 6
  • ALARM_TYPE_DETONATION 7
314 ALARM1_LO_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
315 ALARM1_LO_LEVEL_LOW Read / Write    
316 ALARM1_HI_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
317 ALARM1_HI_LEVEL_LOW Read / Write    
318 ALARM1_HIHI_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
319 ALARM1_HIHI_LEVEL_LOW Read / Write    
320 ALARM1_HYSTERESIS_HIGH Read / Write 32-bit
Floating Point
 
321 ALARM1_HYSTERESIS_LOW Read / Write    
322 ALARM2_AXIS Read / Write 16-bit
Unsigned Integer
  • ALARM_AXIS_IDLE 0
  • ALARM_AXIS_1 1
  • ALARM_AXIS_2 2
  • ALARM_AXIS_3 3
  • ALARM_AXIS_T 4
  • ALARM_AXIS_IT 5
  • ALARM_AXIS_IC 6
  • ALARM_AXIS_1_D 7
  • ALARM_AXIS_2_D 8
  • ALARM_AXIS_3_D 9
  • ALARM_AXIS_1_IT 10
  • ALARM_AXIS_2_IT 11
  • ALARM_AXIS_3_IT 12
  • ALARM_AXIS_1_IC 13
  • ALARM_AXIS_2_IC 14
  • ALARM_AXIS_3_IC 15
323 ALARM2_TYPE Read / Write 16-bit
Unsigned Integer
  • ALARM_TYPE_IDLE 0
  • ALARM_TYPE_VELOCITY 1
  • ALARM_TYPE_ACCELERATION 2
  • ALARM_TYPE_DISPLACEMENT 3
  • ALARM_TYPE_TEMPERATURE 4
  • ALARM_TYPE_ALERT 5
  • ALARM_TYPE_DANGER 6
  • ALARM_TYPE_DETONATION 7
324 ALARM2_LO_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
325 ALARM2_LO_LEVEL_LOW Read / Write    
326 ALARM2_HI_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
327 ALARM2_HI_LEVEL_LOW Read / Write    
328 ALARM2_HIHI_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
329 ALARM2_HIHI_LEVEL_LOW Read / Write    
330 ALARM2_HYSTERESIS_HIGH Read / Write 32-bit
Floating Point
 
331 ALARM2_HYSTERESIS_LOW Read / Write    
332 ALARM3_AXIS Read / Write 16-bit
Unsigned Integer
  • ALARM_AXIS_IDLE 0
  • ALARM_AXIS_1 1
  • ALARM_AXIS_2 2
  • ALARM_AXIS_3 3
  • ALARM_AXIS_T 4
  • ALARM_AXIS_IT 5
  • ALARM_AXIS_IC 6
  • ALARM_AXIS_1_D 7
  • ALARM_AXIS_2_D 8
  • ALARM_AXIS_3_D 9
  • ALARM_AXIS_1_IT 10
  • ALARM_AXIS_2_IT 11
  • ALARM_AXIS_3_IT 12
  • ALARM_AXIS_1_IC 13
  • ALARM_AXIS_2_IC 14
  • ALARM_AXIS_3_IC 15
333 ALARM3_TYPE Read / Write 16-bit
Unsigned Integer
  • ALARM_TYPE_IDLE 0
  • ALARM_TYPE_VELOCITY 1
  • ALARM_TYPE_ACCELERATION 2
  • ALARM_TYPE_DISPLACEMENT 3
  • ALARM_TYPE_TEMPERATURE 4
  • ALARM_TYPE_ALERT 5
  • ALARM_TYPE_DANGER 6
  • ALARM_TYPE_DETONATION 7
334 ALARM3_LO_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
335 ALARM3_LO_LEVEL_LOW Read / Write    
336 ALARM3_HI_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
337 ALARM3_HI_LEVEL_LOW Read / Write    
338 ALARM3_HIHI_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
339 ALARM3_HIHI_LEVEL_LOW Read / Write    
340 ALARM3_HYSTERESIS_HIGH Read / Write 32-bit
Floating Point
 
341 ALARM3_HYSTERESIS_LOW Read / Write    
342 ALARM4_AXIS Read / Write 16-bit
Unsigned Integer
  • ALARM_AXIS_IDLE 0
  • ALARM_AXIS_1 1
  • ALARM_AXIS_2 2
  • ALARM_AXIS_3 3
  • ALARM_AXIS_T 4
  • ALARM_AXIS_IT 5
  • ALARM_AXIS_IC 6
  • ALARM_AXIS_1_D 7
  • ALARM_AXIS_2_D 8
  • ALARM_AXIS_3_D 9
  • ALARM_AXIS_1_IT 10
  • ALARM_AXIS_2_IT 11
  • ALARM_AXIS_3_IT 12
  • ALARM_AXIS_1_IC 13
  • ALARM_AXIS_2_IC 14
  • ALARM_AXIS_3_IC 15
343 ALARM4_TYPE Read / Write 16-bit
Unsigned Integer
  • ALARM_TYPE_IDLE 0
  • ALARM_TYPE_VELOCITY 1
  • ALARM_TYPE_ACCELERATION 2
  • ALARM_TYPE_DISPLACEMENT 3
  • ALARM_TYPE_TEMPERATURE 4
  • ALARM_TYPE_ALERT 5
  • ALARM_TYPE_DANGER 6
  • ALARM_TYPE_DETONATION 7
344 ALARM4_LO_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
345 ALARM4_LO_LEVEL_LOW Read / Write    
346 ALARM4_HI_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
347 ALARM4_HI_LEVEL_LOW Read / Write    
348 ALARM4_HIHI_LEVEL_HIGH Read / Write 32-bit
Floating Point
 
349 ALARM4_HIHI_LEVEL_LOW Read / Write    
350 ALARM4_HYSTERESIS_HIGH Read / Write 32-bit
Floating Point
 
351 ALARM4_HYSTERESIS_LOW Read / Write    
352 A1S1_ZERO Read / Write 16-bit
Unsigned Integer
 
353 A2S1_ZERO Read / Write 16-bit
Unsigned Integer
 
354 A3S1_ZERO Read / Write 16-bit
Unsigned Integer
 
355 A1S2_ZERO Read / Write 16-bit
Unsigned Integer
 
356 A2S2_ZERO Read / Write 16-bit
Unsigned Integer
 
357 A3S2_ZERO Read / Write 16-bit
Unsigned Integer
 
358 BUFFER_1_SECONDS Read / Write 16-bit
Unsigned Integer
 
359 BUFFER_1_FFT_POINTS Read / Write 16-bit
Unsigned Integer
 
360 BUFFER_1_FILTER_TYPE Read / Write 16-bit
Unsigned Integer
  • HIGHPASS_FILTER 0
  • LOWPASS_FILTER 1
361 BUFFER_1_FILTER_MODE Read / Write 16-bit
Unsigned Integer
  • BUFFER_PROCESS_BIT 0
  • AXIS_PROCESS_BIT 1 --- 0-STATIC, 1-DYNAMIC
  • FIR_PROCESS_BIT 2 --- 0-FIR disabled, 1-FIR enabled
362 BUFFER_2_SECONDS Read / Write 16-bit
Unsigned Integer
 
363 BUFFER_2_FFT_POINTS Read / Write 16-bit
Unsigned Integer
 
364 BUFFER_2_FILTER_TYPE Read / Write 16-bit
Unsigned Integer
  • HIGHPASS_FILTER 0
  • LOWPASS_FILTER 1
365 BUFFER_2_FILTER_MODE Read / Write 16-bit
Unsigned Integer
  • BUFFER_PROCESS_BIT 0
  • AXIS_PROCESS_BIT 1 --- 0-STATIC, 1-DYNAMIC
  • FIR_PROCESS_BIT 2 --- 0-FIR disabled, 1-FIR enabled
366 BOARD_TYPE Read / Write 16-bit
Unsigned Integer
  • UNDEFINED 0xFFFF
  • 2G2G 1
  • 2G4G 2
  • 4G2G 3
  • 2G832M 4
  • 4G832M 5
  • 832M2G(25G2G) 6
  • 832M4G 7
  • 4G10G 8
  • 10G4G 9
  • 100G10G 10
367 SENSOR_RTU Read / Write 16-bit
Unsigned Integer
 
368 IMPACT_ALERT_THRESHOLD      
369        
370 IMPACT_DANGER_THRESHOLD      
371        
372 MACHINE_SPEED_CONFIG      
373 CONFIG_SYSTEM_MODE      
374 RESET_COUNTER_CONFIG      
375 LOW_PASS_FREQUENCY

CONFIG

1. Unlock: write [45555] to

SYSTEM_CONTROL


2. Write New Value to LOW_PASS_FREQUENCY


3. Save: write [45556] to

SYSTEM_CONTROL

16-bit
Unsigned Integer

0.1 Hz per bit

 

Example: If wish for a lowpass filter of 2500Hz, Write value [25000]

 

This value must be higher than your setting for HIGH_PASS_FREQUENCY.

376 HIGH_PASS_FREQUENCY

CONFIG

1. Unlock: write [45555] to

SYSTEM_CONTROL


2. Write New Value to HIGH_PASS_FREQUENCY


3. Save: write [45556] to

SYSTEM_CONTROL

16-bit
Unsigned Integer

0.1 Hz per bit

 

Example: If wish for a highpass filter of 25Hz, Write value [250]

 

This value must be lower than your setting for LOW_PASS_FREQUENCY.

377 LATCH_TYPE     */
#define MODBUS_LATCH_TYPE_REGISTER (40378-40001)
#define MODBUS_LATCH_TYPE_IDLE 0
/*
Catch the "highest value clip" commands
*/
#define MODBUS_LATCH_TYPE_VELOCITY 10
#define MODBUS_LATCH_TYPE_A1_VELOCITY 11
#define MODBUS_LATCH_TYPE_A2_VELOCITY 12
#define MODBUS_LATCH_TYPE_A3_VELOCITY 13
//
#define MODBUS_LATCH_TYPE_ACCELERATION 20
#define MODBUS_LATCH_TYPE_A1_ACCELERATION 21
#define MODBUS_LATCH_TYPE_A2_ACCELERATION 22
#define MODBUS_LATCH_TYPE_A3_ACCELERATION 23
//
#define MODBUS_LATCH_TYPE_TEMPERATURE 30
/*
Catch the "first value clip" commands
*/
#define MODBUS_LATCH_TYPE_FIRST_OFFSET 0x100
#define MODBUS_LATCH_TYPE_FIRST_VELOCITY (MODBUS_LATCH_TYPE_VELOCITY+MODBUS_LATCH_TYPE_FIRST_OFFSET)
#define MODBUS_LATCH_TYPE_A1_FIRST_VELOCITY (MODBUS_LATCH_TYPE_A1_VELOCITY+MODBUS_LATCH_TYPE_FIRST_OFFSET)
#define MODBUS_LATCH_TYPE_A2_FIRST_VELOCITY (MODBUS_LATCH_TYPE_A2_VELOCITY+MODBUS_LATCH_TYPE_FIRST_OFFSET)
#define MODBUS_LATCH_TYPE_A3_FIRST_VELOCITY (MODBUS_LATCH_TYPE_A3_VELOCITY+MODBUS_LATCH_TYPE_FIRST_OFFSET)
//
#define MODBUS_LATCH_TYPE_FIRST_ACCELERATION (MODBUS_LATCH_TYPE_ACCELERATION+MODBUS_LATCH_TYPE_FIRST_OFFSET)
#define MODBUS_LATCH_TYPE_A1_FIRST_ACCELERATION (MODBUS_LATCH_TYPE_A1_ACCELERATION+MODBUS_LATCH_TYPE_FIRST_OFFSET)
#define MODBUS_LATCH_TYPE_A2_FIRST_ACCELERATION (MODBUS_LATCH_TYPE_A2_ACCELERATION+MODBUS_LATCH_TYPE_FIRST_OFFSET)
#define MODBUS_LATCH_TYPE_A3_FIRST_ACCELERATION (MODBUS_LATCH_TYPE_A3_ACCELERATION+MODBUS_LATCH_TYPE_FIRST_OFFSET)
//
#define MODBUS_LATCH_TYPE_FIRST_TEMPERATURE (MODBUS_LATCH_TYPE_TEMPERATURE+MODBUS_LATCH_TYPE_FIRST_OFFSET)
/*
378 LATCH LEVEL HIGH      
379 LATCH LEVEL LOW
     
380 SENSOR CONTROL    
  • SENSOR1_AXIS1_BIT 0
  • SENSOR1_AXIS2_BIT 1
  • SENSOR1_AXIS3_BIT 2
  • SENSOR2_AXIS1_BIT 3
  • SENSOR2_AXIS2_BIT 4
  • SENSOR2_AXIS3_BIT 5
381 ALGORITHM_REGISTER    
  • ALGORITHM_BIT 0 --- 0-CONVENTIONAL, 1-DSP
382 CONFIG_ALARM_MULTIPLIER      
383 OFF_THRESHOLD_HIGH      
384 OFF_THRESHOLD_LOW
     
385 ON_THRESHOLD_HIGH      
386 ON_THRESHOLD_LOW
     
387 OFF_TIME      
388 ON_TIME
     
389 RESERVED NON-VOLATILE CONFIG      
390 RESET COUNTER      
391 RESET_SOURCE    
  • 32 - WDT
  • 130 - POR
  • 1024 - SOFT RESET
392 RESET_STATUS    
  • RESET_IDLE_STATUS 0
  • RESET_REMOTE_STATUS 1
  • RESET_INVALID_DATA_STATUS 2
  • RESET_INVALID_MEMORY_STATUS 3
393 LATCH_COMMAND    
  • COMMAND_IDLE 0
  • COMMAND_BLOCK 1
  • COMMAND_START 2
394 LATCH_STATUS    
  • STATUS_IDLE 0
  • STATUS_DONE 1
  • STATUS_INPROGRESS 2
  • STATUS_ERROR 3
  • STATUS_BLOCKED 4

 

LED Status

Note for users: If you see any states besides Solid GREEN or Blinking GREEN, please contact Machine Saver technical support for troubleshooting assistance.

LED State

Description

Solid GREEN

All subsystems are good, no vibration alarms

Blinking GREEN

Vibration Alarms

Solid RED

Internal Hardware Error

Alternating 2RED, 2GREEN

Bootloader Mode

Alternating

1RED, 1GREEN

Bootloader Mode (Older Version )

Alternating

3RED, 1GREEN

Calibration Issue

 

Jupyter Notebook Setup

About Jupyter Notebooks:

https://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/

Installing and Opening Jupyter Notebook Instructions:

  1. Installing Anaconda (Python 3.7 Version) to your computer - https://www.anaconda.com/distribution/
  2. Make sure that during installation you select the option:
    Add Anaconda to my PATH environment variable
  3. After installation is complete open up an Anaconda Prompt
  4. In the Anaconda Prompt type the command:
    conda install -c conda-forge minimalmodbus

    If HTTPS error occurs…
    Connect to the internet and re-run the previous command.

  5. When prompted to Proceed ([y]/n)?
    Respond: yes or y

    Press the ENTER key to submit
    This will install the necessary Modbus master library that is required by the attached notebook.

  6. In the Anaconda Prompt type the command:
    conda install plotly
  7. When prompted to Proceed ([y]/n)?

    Respond: yes or y

    Press the ENTER key to submit

    This will install the necessary plotting library that is required by the attached notebook.
  8. Open Anaconda Navigator
  9. Once Navigator is open, launch Jupyter Notebooks
  10. Upon launching Jupyter Notebooks, a web browser should open.
  11. Using the interface within the web browser, navigate to the directory/folder where you extracted and saved the notebook file (often in Downloads) and click on the notebook file:

    https://gitlab.com/machine_saver_public/notebooks/-/blob/master/modbus_master_examples.ipynb

 

 

Analysis Data (Time Waveform & Vibration Spectrum)

TriVibe supports raw data (analysis data used by Vibration Experts and Machine Learning Algorithms to identify component failures) export via Modbus Read/Write commands.
Machine Saver provides sample Python code to handle this entire process just scroll past this block diagram.

The Process in a Block Diagram

Sample Python Script which Handles the Entire Procedure Described Above

It also handles the following:
  1. Saving a minified JSON file of the timewave form which may be easily passed over MQTT or HTTP/HTTPS or your preferred data route to be processed elsewhere.
  2. It provides the Transform Function to move from the time domain to the frequency domain.
  3. It provides code to chart the data in format which has zoom and highlight features.
#!/usr/bin/env python
# coding: utf-8

# In[1]:


from datetime import datetime
import json, math, minimalmodbus
import numpy as np
import os
import plotly.graph_objects as go
from scipy.fftpack import fft
import serial.tools.list_ports
import time


# # Helper Functions

# In[2]:


def twf_x_axis(data):
    
    """ Using the samplerate and time of the analysis data capture this function will return an x-axis value
    (milliseconds passed since timestamp/capture trigger) for each corresponding y-axis value (amplitude of vibration (gPK))."""
    
    fs = data["samples_per_axis"]/(data["capture_time_ms"]/1000)
    twf_x = np.arange(0,data["capture_time_ms"]/1000,1/fs)
    return twf_x

def process_to_twf(data, axis):
    
    """ || RAW ADC Counts -> Acceleration TWF || Takes a single axis array/list of ADC counts from a TriAxial Accelerometer,
    arranges values above 0 as positive, below 0 as negative values and at the virtual center as 0.
    Scales the values by constant_k (3000mV/16-bits) and finally applies the sensitivity conversion factor
    to get Gs of acceleration."""
    
    if(axis==1):
        axis_raw=data["axis_1_RAW"]
        sensitivity=data["sensitivity_s1_a1"]
    elif(axis==2):
        axis_raw=data["axis_2_RAW"]
        sensitivity=data["sensitivity_s1_a2"]
    elif(axis==3):
        axis_raw=data["axis_3_RAW"]
        sensitivity=data["sensitivity_s1_a3"]
    elif(axis==4):
        axis_raw=data["axis_1_RAW"]
        sensitivity=data["sensitivity_s2_a1"]
    elif(axis==5):
        axis_raw=data["axis_2_RAW"]
        sensitivity=data["sensitivity_s2_a2"]
    elif(axis==6):
        axis_raw=data["axis_3_RAW"]
        sensitivity=data["sensitivity_s2_a3"]
    
    virtual_center = (max(axis_raw)-min(axis_raw))/2+min(axis_raw)
    constant_k = 3000/65535
    axis_twf = axis_raw.copy()
    for position in range(len(axis_twf)):
        if axis_twf[position]>virtual_center:
            axis_twf[position] = (abs(axis_twf[position] - virtual_center)*constant_k)/sensitivity
        elif axis_twf[position]<virtual_center:
            axis_twf[position] = (-abs(axis_twf[position] - virtual_center)*constant_k)/sensitivity
        else:
            axis_twf[position] = 0
    return(axis_twf)

def spectrum_x_axis(data):
    
    """ Using the samplerate and capture time of the analysis data this function will return an x-axis value
    (frequency bins of vibration energy) for each corresponding y-axis value of a spectrum plot (amplitude of vibration (gPK))."""
    
    fs = data["samples_per_axis"]/(data["capture_time_ms"]/1000)
    twf_x = np.arange(0,data["capture_time_ms"]/1000,1/fs)
    n = np.size(twf_x)
    fbin = (fs/2)*np.linspace(0,1,n//2)
    return fbin

def process_to_spectrum(data, axis):
    
    """ || Acceleration TWF -> Acceleration Spectrum || Converts acceleration (gPK) in the time domain to acceleration (gPK) frequency domain."""

    if(axis==1):
        axis_twf=data["axis_1_TWF"]
    elif(axis==2):
        axis_twf=data["axis_2_TWF"]
    elif(axis==3):
        axis_twf=data["axis_3_TWF"]
    elif(axis==4):
        axis_twf=data["axis_4_TWF"]
    elif(axis==5):
        axis_twf=data["axis_5_TWF"]
    elif(axis==6):
        axis_twf=data["axis_6_TWF"]
    
    fs = data["samples_per_axis"]/(data["capture_time_ms"]/1000)
    twf_x = np.arange(0,data["capture_time_ms"]/1000,1/fs)
    n = np.size(twf_x)
    fbin = (fs/2)*np.linspace(0,1,n//2)
    y = fft(axis_twf)
    y_normalized = (2/n)*abs(y[0:np.size(fbin)])
    return y_normalized.tolist()


def save_clip_json(dictionary):
    
    """Takes a python dictionary of unprocessed analysis data, turns it into a serialized JSON 
    and saves it to a file with the associated sensor serial number and the timestamp of the collection.
    Data size (assuming a minified JSON file --- no spaces) for 49,152 samples (16,384 samples_per_axis * 3 axes) is 289kB. 
    Therefore, using 1GB of storage could store upto 3460 data clips with this number of samples."""
    
    encoded_json=json.JSONEncoder().encode(dictionary)
    file_name = str(dictionary["serial_number"])+"_"+str(dictionary["unix_timestamp"])+".json"
    f = open(file_name, "w")
    f.write(encoded_json)
    f.close()
    return(None)


# # Port Finder

# In[3]:


ports = list(serial.tools.list_ports.comports())
if len(ports)==0:
    print('Please connect a USB to RS485 serial converter into PC.')
else:
    for p in ports:
        print (p)


# # Slave Setup

# In[4]:


trivibe=minimalmodbus.Instrument(port='COM3', slaveaddress=64)

# update current slave settings for Tri-Vibe defaults and some useful variables
trivibe.serial.port                        # this is the serial port name
trivibe.address                            # this is the slave address (set this to the last 2 digits of the serial number of the Tri-Vibe that you want to communicate with)
trivibe.serial.baudrate = 115200           # Baudrate fixed 115200
trivibe.serial.bytesize = 8                # Bytesize fixed 8
trivibe.serial.parity   = "N"              # Parity fixed None 
trivibe.serial.stopbits = 1                # Stopbits fixed 1
trivibe.serial.timeout  = 0.10             # Seconds
trivibe.close_port_after_each_call = True  # Helps communication for Windows Devices (can be set to false on many Linux devices)
trivibe.mode = minimalmodbus.MODE_RTU      # modbus mode fixed RTU Mode
trivibe.clear_buffers_before_each_transaction = True

print(trivibe)                             # check updated slave communication settings


# # Local Dictionary for Analysis Data Storage (JSON)

# In[5]:


# example_json = {
#     "serial_number": 21030569,
#     "sensitivity_s1_a1": 66.74067687988281,
#     "sensitivity_s1_a2": 67.11312103271484,
#     "sensitivity_s1_a3": 66.40936279296875,
#     "sensitivity_s2_a1": 331.8104553222656,
#     "sensitivity_s2_a2": 331.3285217285156,
#     "sensitivity_s2_a3": 329.0369873046875,
#     "internal_accelerometer": 5,
#     "capture_time_ms": 1000,
#     "samples_per_axis": 5,
#     "unix_timestamp": 1644420691,
#     "axis_1_raw":[32768,32785,32792,32765,32755],
#     "axis_2_raw":[32770,32762,32760,32775,32780],
#     "axis_3_raw":[32755,32762,32768,32771,32759]
# }

# A simple container to hold important processing information for an analysis clip
# Use the helper function "save_clip_json(dictionary)" to write the dictionary file to your PC after collecting a data clip.

data = {}


# # Serial Number

# In[6]:


data["serial_number"] = trivibe.read_long(26, functioncode=3)
print(data["serial_number"])


# # Revision

# In[7]:


sensor_revision = trivibe.read_register(0, functioncode=3)
print('Sensor Software Revision:', sensor_revision-768)


# # Error

# In[8]:


error = trivibe.read_register(4, functioncode=3)
print(error)


# # Uptime

# In[9]:


sensor_uptime = trivibe.read_registers(5, 3, functioncode=3)
print('Days:', str(sensor_uptime[2]),', Hours:',str(sensor_uptime[1]),', Minutes:',str(sensor_uptime[0]))


# # Set Sensitivity

# In[10]:


# trivibe.write_register(1, 24576)
# trivibe.write_float(299, 500.0, number_of_registers=2)
# trivibe.write_float(301, 500.0, number_of_registers=2)
# trivibe.write_float(303, 500.0, number_of_registers=2)
# trivibe.write_float(305, 500.0, number_of_registers=2)
# trivibe.write_float(307, 500.0, number_of_registers=2)
# trivibe.write_float(309, 500.0, number_of_registers=2)
# trivibe.write_register(1, 24577)


# # Sensitivity

# In[11]:


data["sensitivity_s1_a1"] = trivibe.read_float(299, functioncode=3, number_of_registers=2, byteorder=0)
data["sensitivity_s1_a2"] = trivibe.read_float(301, functioncode=3, number_of_registers=2, byteorder=0)
data["sensitivity_s1_a3"] = trivibe.read_float(303, functioncode=3, number_of_registers=2, byteorder=0)
data["sensitivity_s2_a1"] = trivibe.read_float(305, functioncode=3, number_of_registers=2, byteorder=0)
data["sensitivity_s2_a2"] = trivibe.read_float(307, functioncode=3, number_of_registers=2, byteorder=0)
data["sensitivity_s2_a3"] = trivibe.read_float(309, functioncode=3, number_of_registers=2, byteorder=0)

print(data)


# # Overall - Filters

# In[12]:


dytran=trivibe.read_register(375, functioncode=3)
print("LowPass", dytran/10, "Hz")
dytran=trivibe.read_register(376, functioncode=3)
print("HighPass", dytran/10, "Hz")


# # Overall - Acceleration

# In[13]:


dytran=trivibe.read_float(190, functioncode=3)
print("S1_A1_Accel", dytran)
dytran=trivibe.read_float(192, functioncode=3)
print("S1_A2_Accel", dytran)
dytran=trivibe.read_float(194, functioncode=3)
print("S1_A3_Accel", dytran)
dytran=trivibe.read_float(208, functioncode=3)
print("S2_A1_Accel", dytran)
dytran=trivibe.read_float(210, functioncode=3)
print("S2_A2_Accel", dytran)
dytran=trivibe.read_float(212, functioncode=3)
print("S2_A3_Accel", dytran)


# # Overall - Velocity

# In[14]:


dytran=trivibe.read_float(196, functioncode=3)
print("S1_A1_Vel", dytran)
dytran=trivibe.read_float(198, functioncode=3)
print("S1_A2_Vel", dytran)
dytran=trivibe.read_float(200, functioncode=3)
print("S1_A3_Vel", dytran)
dytran=trivibe.read_float(214, functioncode=3)
print("S2_A1_Vel", dytran)
dytran=trivibe.read_float(216, functioncode=3)
print("S2_A2_Vel", dytran)
dytran=trivibe.read_float(218, functioncode=3)
print("S2_A3_Vel", dytran)


# # Set Capture Parameters

# In[15]:


# High Frequency Accelerometer = 5
accelerometer = 5
trivibe.write_register(32, accelerometer)

capture_time_ms=1000
trivibe.write_register(35, capture_time_ms)

samples_per_axis=16384
trivibe.write_long(36, samples_per_axis, signed=False, byteorder=0)

data["internal_accelerometer"] = trivibe.read_register(32, functioncode=3)
data["capture_time_ms"] = trivibe.read_register(35, functioncode=3)
data["samples_per_axis"] = trivibe.read_long(36, functioncode=3)

print(data)


# # Trigger Capture + Timestamp

# In[16]:


trivibe.write_register(33, 1)
data["unix_timestamp"] = int(str(time.time())[slice(10)])
snapshotTime = datetime.fromtimestamp(data["unix_timestamp"])
print(data)


# # Check Capture Status on Sensor

# In[17]:


capture_engine_status = trivibe.read_register(34, functioncode=3)
print('capture_engine_status: '+str(capture_engine_status))

# wait for data capture on the Tri-Vibe to complete
while capture_engine_status==2:
    capture_engine_status = trivibe.read_register(34, functioncode=3)
    print('capture_engine_status: '+str(capture_engine_status))
    time.sleep(2)
    
# show capture engine is complete (capturing done)
capture_engine_status = trivibe.read_register(34, functioncode=3)
print('capture_engine_status: '+str(capture_engine_status))


# # Collect RAW ADC Data from Sensor 

# In[18]:


twf_x = twf_x_axis(data)


# In[19]:


triaxial_raw =[]
while len(triaxial_raw)<data["samples_per_axis"]*3:
    read_set = trivibe.read_registers(49, 123, functioncode=3)
    read_set.pop(0)
    triaxial_raw.extend(read_set)

# unless samples/axis*3 is evenly divisable by 122, this slices off the erroneous zeros that are tacked to the last reading of the 122 data registers... 
triaxial_raw = triaxial_raw[0:data["samples_per_axis"]*3]

data['axis_1_RAW'] = triaxial_raw[0:data["samples_per_axis"]]
data['axis_2_RAW'] = triaxial_raw[data["samples_per_axis"]:data["samples_per_axis"]*2]
data['axis_3_RAW'] = triaxial_raw[data["samples_per_axis"]*2:data["samples_per_axis"]*3]


# # Save Raw Data into JSON File

# In[20]:


save_clip_json(data)


# In[21]:


fig = go.Figure()
fig.add_trace(
    go.Scatter(
        x=twf_x,
        y=data['axis_1_RAW'],
        mode="lines",
        line=go.scatter.Line(color="#FF006D"),
        showlegend=True,
        name="Axis 1 RAW")
)

fig.add_trace(
    go.Scatter(
        x=twf_x,
        y=data['axis_2_RAW'],
        mode="lines",
        line=go.scatter.Line(color="#FFDD00"),
        showlegend=True,
        name="Axis 2 RAW")
)

fig.add_trace(
    go.Scatter(
        x=twf_x,
        y=data['axis_3_RAW'],
        mode="lines",
        line=go.scatter.Line(color="#01BEFE"),
        showlegend=True,
        name="Axis 3 RAW")
)

fig.show()


# # Process + Plot Timewave Form

# In[22]:


data["axis_1_TWF"]=process_to_twf(data, 1)
data["axis_2_TWF"]=process_to_twf(data, 2)
data["axis_3_TWF"]=process_to_twf(data, 3)


# In[23]:


fig = go.Figure()
fig.add_trace(
    go.Scatter(
        x=twf_x,
        y=data["axis_1_TWF"],
        mode="lines",
        line=go.scatter.Line(color="#FF006D"),
        showlegend=True,
        name="Axis 1 TWF")
)

fig.add_trace(
    go.Scatter(
        x=twf_x,
        y=data["axis_2_TWF"],
        mode="lines",
        line=go.scatter.Line(color="#FFDD00"),
        showlegend=True,
        name="Axis 2 TWF")
)

fig.add_trace(
    go.Scatter(
        x=twf_x,
        y=data["axis_3_TWF"],
        mode="lines",
        line=go.scatter.Line(color="#01BEFE"),
        showlegend=True,
        name="Axis 3 TWF")
)

fig.show()


# # Process + Plot Spectrum Form

# In[24]:


spectrum_x = spectrum_x_axis(data)

data["axis_1_SPEC"]=process_to_spectrum(data, 1)
data["axis_2_SPEC"]=process_to_spectrum(data, 2)
data["axis_3_SPEC"]=process_to_spectrum(data, 3)


# In[25]:


save_clip_json(data)


# In[27]:


fig = go.Figure()
fig.add_trace(
    go.Scatter(
        x=spectrum_x,
        y=data["axis_1_SPEC"],
        mode="lines",
        line=go.scatter.Line(color="#FF006D"),
        showlegend=True,
        name="Axis 1 Spectrum")
)

fig.add_trace(
    go.Scatter(
        x=spectrum_x,
        y=data["axis_2_SPEC"],
        mode="lines",
        line=go.scatter.Line(color="#FFDD00"),
        showlegend=True,
        name="Axis 2 Spectrum")
)

fig.add_trace(
    go.Scatter(
        x=spectrum_x,
        y=data["axis_3_SPEC"],
        mode="lines",
        line=go.scatter.Line(color="#01BEFE"),
        showlegend=True,
        name="Axis 3 Spectrum")
)

fig.show()


# # Low-Frequency - Data Capture

# In[28]:


# LowFrequency Accelerometer = 6 
accelerometer = 6
trivibe.write_register(32, accelerometer)

capture_time_ms=1000
trivibe.write_register(35, capture_time_ms)

samples_per_axis=16384
trivibe.write_long(36, samples_per_axis, signed=False, byteorder=0)


# In[29]:


# Trigger Sensor to Start Collecting
trivibe.write_register(33, 1)

# Metadata to be used when displaying our charts to users, Removes the portion of the timestamp beyond seconds
timestamp = int(str(time.time())[slice(10)])

# Human Readable Timestamp Format
snapshotTime = datetime.fromtimestamp(timestamp)


# In[30]:


capture_engine_status = trivibe.read_register(34, functioncode=3)
print('capture_engine_status: '+str(capture_engine_status))

# wait for data capture on the Tri-Vibe to complete
while capture_engine_status==2:
    capture_engine_status = trivibe.read_register(34, functioncode=3)
    print('capture_engine_status: '+str(capture_engine_status))
    time.sleep(2)
    
# show capture engine is complete (capturing done)
capture_engine_status = trivibe.read_register(34, functioncode=3)
print('capture_engine_status: '+str(capture_engine_status))