Is it possible to transmit a deterministic signal on a CAN bus?

4 views (last 30 days)
I'm using the Vehicle Network Toolbox and a NI-9860 in a cDAQ
I'm able to trasmit a signal value to the CAN bus like so:
canch1 = canChannel('NI','CAN3');
canch1.Database = canDatabase('example_database.dbc'); %apply a database
start(canch1)
message.Signals.example_signal = 1;
transmit(canch1,message)
stop(canch1)
What I want to do is transmit a sine wave signal to the CAN bus with a time step of 1ms. I tried to implement this using a for loop, however the signal ends up being deformed by the execution time of the code.
t = linspace(0,5,5000); % 5 seconds at 1000 Samples/s
f = 0.5; % sine frequency hz
sine = 0.7 * sin(2*pi*f*t); % create sine
start(canch1)
message = canMessage(canch1.Database,'example_message');
for i = 1:length(sine)
message.Signals.example_signal = sine(i);
pause(1/1000)
transmit(canch1,message)
end
Is there a way to transmit the sine signal onto the CAN bus in a deterministic way?
Can I somehow store the signal in a buffer on the NI hardware and trigger the transmit? Do I need to create an array of CAN messages and transmit that?
It seems to me that if I can create an array of CAN messages and use the trasmit function, the attribute of the CAN database 'GenMsgCycleTime' should define the cycle time of a message in ms. In my database GenMsgCycleTime == 1.

Answers (1)

Harimurali
Harimurali on 8 Feb 2024
Hi Adrian,
To transmit messages with precise timing, you need a real-time system or hardware support for buffering and scheduling messages. The "NI-9860" module in a "cDAQ" chassis does have some capabilities for deterministic timing, but this usually requires using NI's software tools, like LabVIEW with the NI-XNET driver, which is designed for real-time applications.
The timing of your MATLAB script by using a more precise timer object or by adjusting the priorities of MATLAB's execution, but this will not guarantee real-time performance.
Here's an example MATLAB script of how to use a timer object to transmit CAN messages at a more consistent interval:
% Load the DBC file
candb = canDatabase("example_dbcfile.dbc");
message = canMessage(candb, 'example_message');
canch = canChannel('NI','CAN3');
start(canch)
t = linspace(0, 5, 5000); % 5 seconds at 1000 Samples/s
f = 0.5; % Sine frequency Hz
sine = 0.7 * sin(2 * pi * f * t); % Create sine
% Start transmitting the sine wave
transmitSineWave(canch, message, sine, 1000); % 1000 Hz transmission rate
function transmitSineWave(canch, message, sine, frequency)
% Create a timer object
t = timer;
t.ExecutionMode = 'fixedRate'; % Execute the timer repeatedly at a fixed rate
t.Period = 1 / frequency; % Set the period of the timer based on the desired frequency
t.TasksToExecute = length(sine); % Set the number of times to execute the timer
t.TimerFcn = @(~, ~) transmitOneSample(canch, message, sine); % Timer function to call
t.StopFcn = @(~, ~) delete(t); % Clean up the timer after execution
% Start the timer
start(t);
end
function transmitOneSample(canch, message, sine)
persistent index;
if isempty(index)
index = 1;
end
% Update the signal value
message.Signals.example_signal = sine(index);
% Transmit the CAN message
transmit(canch, message);
% Update the index or reset if it reaches the end of the sine array
index = index + 1;
if index > length(sine)
index = 1;
end
end

Categories

Find more on Data Acquisition Toolbox Supported Hardware in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!