@@ -446,6 +446,94 @@ function parseFLASHB(xdata, pressure, temperature) {
446446 return _output
447447}
448448
449+ function parseSKYDEW ( xdata ) {
450+ // Attempt to parse an XDATA string from a Peltier-based chilled-mirror hygrometer SKYDEW
451+ // Returns an object with parameters to be added to the sondes telemetry.
452+ //
453+ // References:
454+ // Peltier-based chilled-mirror hygrometer “SKYDEW” XDATA protocol (draft)
455+ //
456+ // Sample data: 3F0144A75446416100160ECAFFFF6EC8000006 (length = 38 characters)
457+
458+ // Run some checks over the input
459+ if ( xdata . length != 38 ) {
460+ // Invalid SKYDEW dataset
461+ return { } ;
462+ }
463+
464+ if ( xdata . substr ( 0 , 2 ) !== '3F' ) {
465+ // Not a SKYDEW (shouldn't get here)
466+ return { } ;
467+ }
468+
469+ var _output = { } ;
470+
471+ // Instrument number is common to all XDATA types.
472+ _output [ 'skydew_instrument_number' ] = parseInt ( xdata . substr ( 2 , 2 ) , 16 ) ;
473+
474+ // Mirror temperature value
475+ // This requires the four coefficients to actually get a value
476+ _output [ 'skydew_mirror_temperature_value' ] = parseInt ( xdata . substr ( 4 , 4 ) , 16 ) ;
477+
478+ // Scattered light level
479+ _scattered_light_value = parseInt ( xdata . substr ( 8 , 4 ) , 16 ) ;
480+ _scattered_light_value = _scattered_light_value * 0.0000625 // V
481+ _output [ 'skydew_scattered_light' ] = Math . round ( _scattered_light_value * 10000 ) / 10000 ; // 4 DP
482+
483+ // Reference resistance
484+ // Used to calculate mirror temperature
485+ _reference_resistance = parseInt ( xdata . substr ( 12 , 4 ) , 16 ) ;
486+
487+ // Offset value
488+ // Used to calculate mirror temperature
489+ _offset_value = parseInt ( xdata . substr ( 16 , 4 ) , 16 ) ;
490+
491+ // Peltier current
492+ _peltier_current_value = parseInt ( xdata . substr ( 20 , 4 ) , 16 ) ;
493+ _peltier_current_value = ( _peltier_current_value * 0.00040649414 - 1.5 ) * 2 ; // A
494+ _output [ 'skydew_peltier_current' ] = Math . round ( _peltier_current_value * 10000 ) / 10000 ; // 4 DP
495+
496+ // Heatsink temperature
497+ _heatsink_temperature = parseInt ( xdata . substr ( 24 , 2 ) , 16 ) ;
498+ _heatsink_temperature = ( Math . pow ( ( ( ( Math . log ( ( ( _heatsink_temperature / 8192 ) * 141.9 ) / ( 3.3 - ( _heatsink_temperature / 8192 ) * 3.3 ) / 6 ) ) / 3390 ) + 1 ) / 273.16 , - 1 ) - 276.16 ) ; // Degrees C
499+ _output [ 'skydew_heatsink_temperature' ] = Math . round ( _heatsink_temperature * 100 ) / 100 ; // 2 DP
500+
501+ // Circuit board temperature
502+ _circuit_board_temperature = parseInt ( xdata . substr ( 26 , 2 ) , 16 ) ;
503+ _circuit_board_temperature = ( Math . pow ( ( ( ( Math . log ( ( ( _circuit_board_temperature / 8192 ) * 39.6 ) / ( 3.3 - ( _circuit_board_temperature / 8192 ) * 3.3 ) / 6 ) ) / 3390 ) + 1 ) / 273.16 , - 1 ) - 276.16 ) ; // Degrees C
504+ _output [ 'skydew_circuit_board_temperature' ] = Math . round ( _circuit_board_temperature * 100 ) / 100 ; // 2 DP
505+
506+ // Battery
507+ _output [ 'skydew_battery' ] = parseInt ( xdata . substr ( 28 , 2 ) , 16 ) ;
508+
509+ // PID
510+ _output [ 'skydew_pid' ] = parseInt ( xdata . substr ( 30 , 2 ) , 16 ) ;
511+
512+ // Parameter
513+ var parameter = parseInt ( xdata . substr ( 32 , 4 ) , 16 ) ;
514+
515+ // Coefficent type
516+ var parameterType = parseInt ( xdata . substr ( 36 , 2 ) , 16 ) ;
517+
518+ // Parameter Type
519+ switch ( parameterType ) {
520+ case 0 :
521+ _output [ 'skydew_serial_number' ] = parameter ;
522+ case 1 :
523+ _output [ 'skydew_coefficient_b' ] = parameter ;
524+ case 2 :
525+ _output [ 'skydew_coefficient_c' ] = parameter ;
526+ case 3 :
527+ _output [ 'skydew_coefficient_d' ] = parameter ;
528+ case 4 :
529+ _output [ 'skydew_coefficient_e' ] = parameter ;
530+ case 5 :
531+ _output [ 'skydew_firmware_version' ] = parameter ;
532+ }
533+
534+ return _output
535+ }
536+
449537function parseXDATA ( data , pressure , temperature ) {
450538 // Accept an XDATA string, or multiple XDATA entries, delimited by '#'
451539 // Attempt to parse each one, and return an object
@@ -487,6 +575,10 @@ function parseXDATA(data, pressure, temperature){
487575 if ( ! _instruments . includes ( "OIF411" ) ) _instruments . push ( 'OIF411' ) ;
488576 } else if ( _instrument === '08' ) {
489577 // CFH
578+ // 0803B922067F1D0707CD0144
579+ // 0803ABD602800F7907D9015D
580+ // 08038AB16A7FBF4908E50161
581+ // https://www.en-sci.com/cryogenic-frost-point-hygrometer/
490582 if ( ! _instruments . includes ( "CFH" ) ) _instruments . push ( 'CFH' ) ;
491583 } else if ( _instrument === '10' ) {
492584 // FPH
@@ -520,6 +612,8 @@ function parseXDATA(data, pressure, temperature){
520612 if ( ! _instruments . includes ( "TRAPS" ) ) _instruments . push ( 'TRAPS' ) ;
521613 } else if ( _instrument === '3F' ) {
522614 // SKYDEW
615+ _xdata_temp = parseSKYDEW ( _current_xdata ) ;
616+ _output = Object . assign ( _output , _xdata_temp ) ;
523617 if ( ! _instruments . includes ( "SKYDEW" ) ) _instruments . push ( 'SKYDEW' ) ;
524618 } else if ( _instrument === '41' ) {
525619 // CICANUM
0 commit comments