Transmit multiple DM1 DTCs

Discuss issues and ideas you have to configuring displays with PowerVision
alb
Posts: 43
Joined: Wed Dec 15, 2010 1:30 pm

Transmit multiple DM1 DTCs

Post by alb » Wed Jan 09, 2013 3:33 pm

I need to process 10-20 variables and conditionally generate anywhere from 0-20 DTCs accordingly. The correct way to do this of course, is a multipacket message (if numDTCs > 1) with the transport protocol. Since the length of my message is variable, I can't visualize a method to pack those freeform CAN bytes sequentially with smWrite aiming at a moving target.

Code: Select all

smWrite(VariableIDs.FreeFormCAN_TP_DM1_1, varFirstDM1);
And ....2....3....4....so on up to a maximum of 104 for 20 active DTCs(unlikely).

Can we index VariableIDs and increment that index as we would any other variable? One workaround could be to static index all my DTCs and pack the unused DTCs with FF bytes? Sounds like overkill to send a 13 packet message full of FF's though.

The expedient route might be to shove all the DM1's through unique PGN 65226 messages on a 1000ms period. That leaves almost 50ms per DM1 if all 20 were active. Seems doable. However, I've found my 3 DM1 test sequentially smWriting the freeform can bytes then sendEventing them transmits the same DM1 3 times per 1000ms rather than 3 separate dm1s per 1000ms. I think there needs to be a pause and wait for the J1939 application to finish Tx Ext Free Form before sending the transition event on that state machine again.

Is there a simple method to handle timing in scripts?

The origin is one PV750, the destination is a 2nd PV750 displaying the DTCs using the MSTD approach. Potentially, this could need to be integrated into one PV750 using internal DM1 or similar.

My test case, transmits 3 SPN 333's back-to-back every time the script event SCR Check DM1s is called (as long as all conditional expressions evaluate to true):

Code: Select all

//---------------------------------------------------------------------------------------------
// Murphy Scripting
// - Leave EventName as $SCR Check DM1s$ for main script method
//---------------------------------------------------------------------------------------------
void $SCR Check DM1s$ () 
{
    double var1;
	double var2;
	uint var3;
	uint xmitready=1;
	
	//smRead(VariableIDs.XMIT_ready,xmitready);
	
	//if (smRead(VariableIDs.J1939_Engine_Engine_Oil_Pressure,var1) && var1 < 500)
	if (smRead(VariableIDs.Test_Var1,var1) && var1 < 5 && xmitready==1)
	{
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Malfunction_Indicator_Lamp_Status, 0);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Amber_Warning_Lamp_Status,1);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Red_Stop_Lamp_Status, 0);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Protect_Lamp_Status, 0);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_SPN, 111);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_FMI, 18);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_OC, 1);
	sendEvent(EventIDs.TR_XMIT_DM1);
	}
	//if (smRead(VariableIDs.J1939_Engine_Engine_Oil_Temperature,var2) && var2 > 50)
	if (smRead(VariableIDs.Test_Var2,var2) && var2 > 5 && xmitready==1)
	{
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Malfunction_Indicator_Lamp_Status, 0);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Amber_Warning_Lamp_Status,0);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Red_Stop_Lamp_Status, 1);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Protect_Lamp_Status, 0);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_SPN, 222);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_FMI, 16);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_OC, 1);
	sendEvent(EventIDs.TR_XMIT_DM1);
	}
	if (smRead(VariableIDs.Test_Var3,var3) && var3 > 30 && xmitready==1)
	{
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Malfunction_Indicator_Lamp_Status, 0);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Amber_Warning_Lamp_Status,0);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Red_Stop_Lamp_Status, 1);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_Protect_Lamp_Status, 0);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_SPN, 333);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_FMI, 16);
	smWrite(VariableIDs.FreeFormCAN_DM1_XMIT_OC, 1);
	sendEvent(EventIDs.TR_XMIT_DM1);
	}
	//smWrite(VariableIDs.Test_Var1,var1);
	//smWrite(VariableIDs.Test_Var2,var2);
	//var3=var3+1;
	//smWrite(VariableIDs.Test_Var3,var3);
}
ksaenz
Enovation Controls Development
Enovation Controls Development
Posts: 263
Joined: Thu Aug 19, 2010 7:53 am

Re: Transmit multiple DM1 DTCs

Post by ksaenz » Thu Jan 10, 2013 10:56 am

Hello alb,

To generate and send DTCs from a PV750 I would recommend to add them to a queue first and then process that queue with a script fired from a state machine with a timer and you would only need to have two FreeFormCAN messages (EC00 & EB00) and only send the ones you need.

VariableIDs are uints so you could put many of them in an array and access them with an index.

Code: Select all

uint[] dtcs = {
VariableIDs.dtc1,
VariableIDs.dtc2,
VariableIDs.dtc3,
};
Since scripts don't have timers one way to do that is to fire the script from state machine with a timer and execute a different block of code on each pass.

Code: Select all

int pass = 0;

void $test_script$ ()
{
   switch(pass)
   {
      case 0:
      break;

      case 1:
      break;

      default:
      break;
   }

   pass++;

   sendEvent(EvenIDs.someEvent);
}
Another way for both PV750s to show the DTCs would be to have them both generate internal DM1s.

If the second PV750 doesn't see the CAN messages you could repeat them on the 1st one, or instead of repeating every message you could send a proprietary PGN with 2 bits per fault and use that to generate internal DM1s.

I hope this helps and let us know if you have other questions.

Regards,

ksaenz
alb
Posts: 43
Joined: Wed Dec 15, 2010 1:30 pm

Re: Transmit multiple DM1 DTCs

Post by alb » Wed Jan 16, 2013 10:49 am

Kristian, thanks for the ideas, many I've shared, so it's good to feel like I'm on the right track. Implementing them is still presenting some headaches. The switch(pass) function seems like the only viable method to handle the rotating bytes of the sequential 7-byte transport protocol frames. There is probably a way to modulo the function down to a basic repeating pattern of manageable size, but I found no expedient solution, so I have to switch all possible cases 0->n.

Since I need to build a queue in one script function and and transmit the data in a separate, recursively called function, I planned to build the queue in these arrays:

uint[]dtcSPN;
uint[]dtcFMI;
uint[]dtcOC;

Not sure if the syntax is correct there, but the whole concept is flawed on the premise this local queue, once built, can't be accessed in the transmit function using the switch statement.

Are shared memory database handles in the Programming Items tree the only way to access and work with global variables in scripting? Does this preclude arrays as global variables? The scripting guide makes mention of defining global variables within scripts, but does not illustrate the technique if there is one.

Do I have to define dtCSPN_1, dtcSPN_2... dtcSPN_n, ad infinitum, in the Programming Items tree, then find a way to pump the queue in/out of those globals with a uint array of VariableIDs like you demonstrated?
ksaenz
Enovation Controls Development
Enovation Controls Development
Posts: 263
Joined: Thu Aug 19, 2010 7:53 am

Re: Transmit multiple DM1 DTCs

Post by ksaenz » Wed Jan 16, 2013 3:13 pm

You can define variables outside functions and they will be globals accessible to all scripts.

Code: Select all

uint[] dtcSPN(20);
uint[] dtcFMI(20);
uint[] dtcOC(20);

void $functionX$ ()
{
   ...
}
Regards,

ksaenz