Using Memorator trig pins as digital IO

  • July 14, 2021
  • Lars-Göran Fredriksson

The functions mentioned in this paper have been tested with:

Kvaser Memorator Pro 5xHS         EAN: 73-30130-00778-9
Kvaser Memorator Pro 2xHS v2    EAN: 73-30130-00819-9

Kvaser Drivers for Windows               V5.35
Kvaser CANlib SDK                             V5.35

Pre-requisites

In order to test using the trig pins, you will of course need a Kvaser Memorator Pro. You do not need an GPS/Arduino test board, but a signal generator can be very handy when testing. An oscilloscope is also very good to have, if you want to see the relationship between the different signals. 

Why use Memorator trigger I/O Pins?

There might be situations where you want to detect a digital signal, or want to send a digital signal if a desired action has happened. A Memorator will never replace a PLC or an advanced I/O unit, but in some cases, one digital channel can be enough.

From the USER GUIDE:

The Kvaser Memorator Pro 2xHS v2 can be set up to trigger on an external signal and can be configured to react on both falling and rising edges.

The Kvaser Memorator Pro 2xHS v2 can be set up to send an external pulsethrough the External trigger output pin.

On channel CAN1, there is a TRIGGER input and on channel CAN2, there is a TRIGGER output. Both are 5 volt logic and can use TTL levels. Their purpose is to indicate when a certain event happens and perform some kind of action.

When Kvaser introduced the Kvaser DIN Rail SE400S-X10 and its additional units, we included support for handling the I/O pins on the Kvaser Memorator Pro v2 devices. We can now directly control the digital input and output on the Kvaser Memorator Pro units.

It is possible to use the TRIGGER-input on CAN1 and TRIGGER-output on CAN2, as digital I/O controlled via CANLib or t-program.

I will try to show in this paper how to do it and also a little bit of what we can expect from the I/O pins.

I will use Kvaser t-programming for the demonstration, but it is also possible to use CANlib. The procedures used in CANLib are almost identical with the one used in t-programs.

You can find the t-programming manual here

Some useful information about CANLib I/O functions;

https://www.kvaser.com/canlib-webhelp/page_user_guide_kviopin.html

1 My signal generator & test setup

To be able to show the behavior of the digital signals, I must have a signal generator that generates a digital signal. I will use an oscilloscope to show the relationship between the CAN-frames and the digital signals.

I use a small Arduino computer that is connected to a GPS module and also to a MCP2515 module (CAN controller).

The GPS generates a 1PPS (1 Pulse Per Second) signal [GREEN wire]. This signal is connected to one of the digital inputs on the Arduino and to my oscilloscope. 

Every time the GPS sends the 1PPS signal, the Arduino generates a 35 ms long pulse [RED wire]. This pulse is sent to the TRIG input on a Memorator Pro. At the same time the Arduino sends a “0x201 msg” to the CAN bus [BLUE wire].

The Memorator can also control the TRIG output on CAN2 [ORANGE wire]. It is connected to the Arduino, and the Arduino has a built-in pullup resistor.

All described signals are connected to a differential USB oscilloscope.

As you can see in the picture, the GPS[GREEN] uses 3.3V logic and the Arduino creates a 5V negative pulse [RED].

If we look a bit closer, then we see that when 1PPS [GREEN] goes high, the TRIG [RED] will go low after approximately 16 μs. After approximately 140 μs we can see that the Arduino via the MCP2515 sends out a CAN message [BLUE]. It has the ID of 0x201 (dec 513).

The program that runs on the Arduino is not listed in this paper. Please send an email to [email protected] and I will email it to you.

2 Using the TRIG pins with t programming

(You can find the t program in 2 Appendix A – “Test_Memorator_Trigger_V100.t”)

First we will need some constants and variables:

variables {
  int status = 0;

  // Memorator Pro
  const int MAX_CHANNELS = 2;
  const int DIGITAL_IN   = 0;
  const int DIGITAL_OUT  = 1;

  CanMessage Test_msg202;
  CanMessage Test_msg203;
}

We define the initialization procedure:

on start {
  int ch;
  printf("[START]\n");

  Test_msg202.id=0x202;//Dummy msg 202
  Test_msg202.dlc=0;
  Test_msg202.flags=0;
  Test_msg202.data="\x11\x22\x33\x44\x55\x66\x77\x88";
  
  Test_msg203.id=0x203;//Dummy msg 203 
  Test_msg203.dlc=1;
  Test_msg203.flags=0;
  Test_msg203.data="\x11\x22\x33\x44\x55\x66\x77\x88";


  status = kvIoPinSetInfo(0,kvIO_INFO_SET_DI_LOW_HIGH_FILTER,3000);
  status = kvIoPinSetInfo(0,kvIO_INFO_SET_DI_HIGH_LOW_FILTER,3000);

  status = kvIoConfirmConfig();
  if (status != 0) {
	printf("kvIoConfirmConfig failed: %d\n", status);
 }
  for (ch=0;ch < MAX_CHANNELS; ch++) {
	canBusOff(ch);
	canSetCommunicationMode(ch, canMODE_CAN);
	canSetBitrate(ch, canBITRATE_250K);
	canSetBusOutputControl(ch, canDRIVER_NORMAL);
	canBusOn(ch);
  }
}

And do not forget the cleanup procedure:

on stop {
  int ch;
  printf("[STOP]\n");
  for (ch=0;ch < MAX_CHANNELS; ch++) {
	canBusOff(ch);
  }
}

Let’s connect the Memorator and start the t-program for our test bus, and see what happens.

The 1PPS [GREEN] goes high once per second,
the Arduino detects it and lowers the TRIG [RED] (taking approx 35 ms).
The Arduino also sends “message 201” on the CAN bus.

As expected, nothing exciting seems to happen, because we have only asked the Memorator to go BUS-ON and we haven’t yet done anything.

But there is one important line in the code:
status = kvIoConfirmConfig();

This line must be called before we call any I/O functions.

Adding an ON CANMESSAGE hook:

Let us add this hook:

on CanMessage <0> 0x201
{
canWrite(Test_msg202);
}

The purpose of this hook is to show that the Memorator is alive. When it sees a “201” message, it sends a “202” message. You can see it in the picture above as the second blue mark.

Add some DIGITAL IO

on CanMessage <0> 0x201

{

  status = kvIoPinSetDigital(DIGITAL_OUT, 0);  

  canWrite(Test_msg202);

  status = kvIoPinSetDigital(DIGITAL_OUT, 1);  

}

With the command “kvIoPinSetDigital(DIGITAL_OUT, 0);”, we can now control the digital output pin on the CAN2 channel. In the picture above, we can see that the digital output on CAN2 goes low when sending the “202” message.

Add an event that detects TRIG

on IoEvent <DIGITAL_IN> kvIO_EVENT_FALLING_EDGE {
  status = kvIoPinSetDigital(DIGITAL_OUT, 0); 
  canWrite(1,Test_msg203);
  status = kvIoPinSetDigital(DIGITAL_OUT, 1); 
}

This a new event, the IoEvent. It can detect a falling edge. Please note, the TRIG input is always defined as active low.

Every time the Memorator detects a falling digital input, it will send a “203 message”. I also added instructions for activating the digital output.

In the picture above, we see the “203 message” after approximately 7ms. (I have turned the “202 message” off).

Is 7 ms response time a typical response time?

Let’s investigate that.

How fast can the Memorator detect TRIG?

When testing the IoEvent, it is easy to see that it detects TRIG within 14 to 21 ms. It seems to be moving in a predefined pattern. Let us measure the delay for one hour:

In the picture above, more than one hour of measurements have been overlaid and we can see that the delay is evenly distributed between 3ms and 11ms.

According to the documentation, the TRIG pulse must be 30 ms or longer (debounce check), so a delay time of 3-11 ms is totally OK for all normal operations.

3 Summary

It is very easy to add support for reading and writing the digital I/O channels on the Memorator (TRIG IN and TRIG OUT).
We only needed five new procedures and one new hook:

kvIoPinSetInfo();
kvIoGetNumberOfPins();
kvIoConfirmConfig();
kvIoPinSetDigital();
kvIoPinGetDigital();

on IoEvent <DIGITAL_IN> kvIO_EVENT_FALLING_EDGE
The latency of the digital IO is approximately 3-11 ms.
The digital IO can also be controlled via CANlib; the commands are the same except the hook is not supported in CANlib.

Any questions or comments, please send me an email!

Field Application Engineer

Lars-Göran Fredriksson

[email protected]

4 Appendix A - “Test_Memorator_Trigger_V100.t”

variables {
  int status = 0;

  // Memorator Pro 2xHS
  const int MAX_CHANNELS = 2;
  const int DIGITAL_IN   = 0;
  const int DIGITAL_OUT  = 1;

  CanMessage Test_msg202;
  CanMessage Test_msg203;
}

on start {
  int ch;
  printf("[START]\n");

  //Dummy msg 202  
  Test_msg202.id=0x202;
  Test_msg202.dlc=0;
  Test_msg202.flags=0;
  Test_msg202.data="\x11\x22\x33\x44\x55\x66\x77\x88";

  //Dummy msg 203  
  Test_msg203.id=0x203;
  Test_msg203.dlc=0;
  Test_msg203.flags=0;
  Test_msg203.data="\x11\x22\x33\x44\x55\x66\x77\x88";

  int pinCount = 0;
  status = kvIoGetNumberOfPins(&pinCount);
  
  status = kvIoPinSetInfo(0,kvIO_INFO_SET_DI_LOW_HIGH_FILTER,3000 );
  status = kvIoPinSetInfo(0,kvIO_INFO_SET_DI_HIGH_LOW_FILTER,3000  );
  
  status = kvIoConfirmConfig();

  if (status != 0) {
    printf("kvIoConfirmConfig failed: %d\n", status);
 }

  for (ch=0;ch < MAX_CHANNELS; ch++) {
    canBusOff(ch);
    canSetCommunicationMode(ch, canMODE_CAN); 
    canSetBitrate(ch, canBITRATE_250K);
    canSetBusOutputControl(ch, canDRIVER_NORMAL);
    canBusOn(ch);
  }

  int value = 0;

  status = kvIoPinGetDigital(DIGITAL_IN, &value);

  status = kvIoPinSetDigital(DIGITAL_OUT, 1);  
}

on stop {
  int ch;
  printf("[STOP]\n");
  for (ch=0;ch < MAX_CHANNELS; ch++) {
    canBusOff(ch);
  }
  status = kvIoPinSetDigital(DIGITAL_OUT, 1);
  if (status == 0) {
    printf("Restored digital out\n");
  } else {
    printf("FAILED: %d\n", status);
  }
}

on IoEvent <DIGITAL_IN> kvIO_EVENT_FALLING_EDGE
{
  status = kvIoPinSetDigital(DIGITAL_OUT, 0);  
  canWrite(0,Test_msg203);
  status = kvIoPinSetDigital(DIGITAL_OUT, 1);  
}

5 Appendix B GPS Signal Generator

If you are interested in the source code, please send me an email and I will send you a link.

Field Application Engineer

Lars-Göran Fredriksson

[email protected]
Author Image

Lars-Göran Fredriksson

Lars-Göran Fredriksson is a Field Application Engineer for Kvaser AB. His background is in geographic information system (GIS) and Remote Sensing and his current focus is on connecting the deep knowledge of Kvaser's developers with the practical questions of our end users. If you doubt his passion for CAN, just know that his first week in the office he created an interactive CAN Trivia game that sent the office scouring the halls for the correct answers. He is a passionate fisherman who would like to develop new environmentally friendly fishing methods. Biggest catch and release fish is for the moment a Bluefin Tuna at appr 325kg / 715lbs.