Opt22 controller code for sending engine parameters to MFD (works on Raymarine )

Discussion in 'General Computing' started by GB424, Jan 26, 2024.

  1. GB424
    Joined: Jan 2024
    Posts: 1
    Likes: 1, Points: 1
    Location: Maryland

    GB424 New Member

    Posting some code that might be useful for anyone using Opt22 products that want to interface with MFD's via N2K. I'm using an Opto22 Ultimate I/O with analog and discrete modules to monitor my engine sensors. This uses the serial port on the controller and a cheap import serial to CAN converter. You could instead by an expensive CAN module from OPTO22 for more capabilities.



    // comm opened in set up block, 9600, n, 8, 1
    // no flow control
    // set port to no PPP in ioManager

    // pin 1 of UIO is TD, connect to DB9 pin 2 of computer or 3 of CAN converter
    // pin 2 of UIO is RD, connect to DB9 pin 3 of computer or 2 of CAN
    // pin 3 of UIO is GND, connect to DB9 pin 5

    if (IsCommunicationOpen( nmea_serial)) then
    i_nmea_seq = i_nmea_seq +1 ;
    if (i_nmea_seq == 15) then //
    i_nmea_seq = 0 ;
    endif

    // CAN Header is 29 bits:
    // 000 is highest priority +
    // PGN 127489 engine parameters dynamic = 0x1F201 +
    // 8 bit source ID
    //

    // 0x01F20100 CAN ID is added by the rs232 to CAN converter
    // use WS_CAN_TOOL software or software for specific device for config of the device
    // Jumper RS to CAN_L. VCC not required on bus
    // total data bytes = 26 requiring (4) 64-bit data frames
    // fast packet 1 starts with sequence counter (4 bits), then frame counter (4 bits)
    // followed by total number of expected frames (8 bits)
    // Additional packets start with sequence counter and frame counter
    // CAN/NMEA 2000 sends in little endian. OPTO serial sends LSB first.

    // build port engine data

    i_nmea_data[0] = (i_nmea_seq << 4) +

    // ( 0i64 ) + // packet 0

    (26i64 << 8) + // 26 data byte total

    // (0i64 << 16) + // engine instance

    ((i_nmea_units_long[0] bitand 0x000000FF) << 24) + // oil press lower byte

    ((i_nmea_units_long[0] bitand 0x0000FF00) << 24) + // oil press

    ((i_nmea_units_long[1] bitand 0x000000FF) << 40) + // trans oil temp lower byte

    ((i_nmea_units_long[1] bitand 0x0000FF00) << 40) + // trans oil temp

    ((i_nmea_units_long[2] bitand 0x000000FF) << 56 ) ; // eng coolant temp lower byte


    i_nmea_data[1] = (i_nmea_seq << 4 ) +

    ( 1i64 ) + // packet 1

    ((i_nmea_units_long[2] bitand 0x0000FF00) ) + // eng coolant temp upper byte

    (( p_instr_V bitand 0x0000FFFF) << 16) ; // ALT volts x100


    i_nmea_data[2] = (i_nmea_seq << 4) +

    ( 2i64 ) + // packet 3

    ( 15i64 << 32 ) ; // nmea field 10 reserved F


    i_nmea_data[3] = (i_nmea_seq << 4) +

    ( 3i64 ) + // packet 4

    (( P_limit_alarm_flag bitand 0x00000001) << 24) ; // Field12 bit0 Warning Level1


    if( p_temp_alarm_flag ) then

    i_nmea_data[3] = i_nmea_data[3] + (1i64 << 9) ; // Field11 Bit1 Over Temp

    endif

    if (p_pres_alarm_flag ) then

    i_nmea_data[3] = i_nmea_data[3] + (1i64 << 10) ; // Field11 Bit2 Low Pres

    endif



    // Send port data

    comm_status = TransmitNumTable(4, 0, i_nmea_data, nmea_serial ) ;

    comm_status = TransmitNewline( nmea_serial );


    // build starboard engine data

    i_nmea_data[4] = (i_nmea_seq << 4) +

    // ( 0i64 ) + // packet 0

    (26i64 << 8) + // 26 data byte total

    (1i64 << 16) + // engine instance

    ((i_nmea_units_long[3] bitand 0x000000FF) << 24) + // oil press lower byte

    ((i_nmea_units_long[3] bitand 0x0000FF00) << 24) + // oil press

    ((i_nmea_units_long[4] bitand 0x000000FF) << 40) + // trans oil temp lower byte

    ((i_nmea_units_long[4] bitand 0x0000FF00) << 40) + // trans oil temp

    ((i_nmea_units_long[5] bitand 0x000000FF) << 56 ) ; // eng coolant temp lower byte

    i_nmea_data[5] = (i_nmea_seq << 4 ) +

    ( 1i64 ) + // packet 1

    ((i_nmea_units_long[5] bitand 0x0000FF00) ) + // eng coolant temp upper byte

    (( s_instr_V bitand 0x0000FFFF) << 16) ; // ALT volts x100



    i_nmea_data[6] = (i_nmea_seq << 4) +

    ( 2i64 ) + // packet 3

    ( 15i64 << 32 ) ; // nmea field10 reserved F



    i_nmea_data[7] = (i_nmea_seq << 4) +

    ( 3i64 ) + // packet 4

    (( s_limit_alarm_flag bitand 0x00000001) << 24) ; // Field12 bit0 Warning L1



    if( s_temp_alarm_flag ) then

    i_nmea_data[7] = i_nmea_data[7] + (1i64 << 9) ; // Field11 Bit1 Over Temp

    endif

    if (s_pres_alarm_flag ) then

    i_nmea_data[7] = i_nmea_data[7] + (1i64 << 10) ; // Field11 Bit2 Low Pres

    endif





    // Send starboard data

    comm_status = TransmitNumTable(4, 4, i_nmea_data, nmea_serial ) ;

    comm_status = TransmitNewline( nmea_serial );





    endif // comm open



    DelayMSec(950) ;




    OptoScript Block: Convert Data Units (Id: 1)

    Exit to: Build CAN packets (Id: 3)


    // pressure in 100 Pa

    i_nmea_units[0] = p_pres_corr * 68.9476 ;


    // Oil Temp in K k=(y °F - 32) x 5/9 + 273.15

    i_nmea_units[1] = ((p_ttemp_corr - 32 ) * 5/9 + 273.15 ) * 10 ; // 1.0 K


    // Engine Temp in K

    i_nmea_units[2] = ((p_etemp_corr - 32 ) * 5/9 + 273.15 ) * 100 ; // 0.1 K


    i_nmea_units_long[0] = MakeInt64(0, i_nmea_units[0]);

    i_nmea_units_long[1] = MakeInt64(0, i_nmea_units[1]);

    i_nmea_units_long[2] = MakeInt64(0, i_nmea_units[2]);

    p_instr_V = Truncate (Port_Instr_V_AD3 * 100 ) ; // Alt Volt x 100



    // pressure in 100 Pa

    i_nmea_units[3] = s_pres_corr * 68.9476 ;



    // Oil Temp in K k=(y °F - 32) x 5/9 + 273.15

    i_nmea_units[4] = ((s_ttemp_corr - 32 ) * 5/9 + 273.15 ) * 10 ;



    // Engine Temp in K

    i_nmea_units[5] = ((s_etemp_corr - 32 ) * 5/9 + 273.15 ) * 100 ;



    i_nmea_units_long[3] = MakeInt64(0, i_nmea_units[3]);

    i_nmea_units_long[4] = MakeInt64(0, i_nmea_units[4]);

    i_nmea_units_long[5] = MakeInt64(0, i_nmea_units[5]);



    s_instr_V = Truncate (Star_Intr_V_AD3 * 100 ) ; // Alt Volt x 100
     
    fallguy likes this.
Forum posts represent the experience, opinion, and view of individual users. Boat Design Net does not necessarily endorse nor share the view of each individual post.
When making potentially dangerous or financial decisions, always employ and consult appropriate professionals. Your circumstances or experience may be different.