Clear Filters
Clear Filters

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

5 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

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!