If I use the XNet Write on a Signal Out Single-Point session, the rate that the data gets sent to the bus is defined by the database selected. Is there a way to change this rate while the interface is being used?
If this is a Frame Out session type I recognize that there exists the Frame >> CAN >> Transmit Time property, which works on the active frame. I tried changing this for the frame on the signal out session, but get an error -1074384512. I figure this is because I'm trying to change frame settings while in a signal session.
I also tried stopping the session, updating the database, then starting the session again. But this results in error -1074384561 because the database is still locked and I'd need to clear it, not just stop. This does work, but then I'd need to stop and clear all sessions using this database, and then start them all up again.
Is there a prefered way to change the rate that a signal is being sent out, while using the signal out session type? I don't really want to change all my signal out session types, into a frame out, and then perform signal to frame conversion for each.
Solved! Go to Solution.
Actually now that I look at the code a bit closer, changing over to using the Frame Out Singe Point session type might not be all that bad. Still interested in knowing if there a way to do with with the signal session type but for my setup I think I'd be alright without it.
I can modify the transmit time after the session is started, but I don't modify the database itself since it is only read once prior to session creation.
This doesn't actually seem to work for me. I ran your demo (changing the baud rate is all had to do) then ran it to a USB NI-CAN device with the bus monitor and a termination resistor. I set the transmit time to 0.3, but the dt for the frame in the bus monitor was always 0.1. It is interesting that if I disable setting the frame tx rate it goes to 0.01 which is what is defined in the database. Is 0.1 the largest the value can be?
And even if this is able to change the transmit time, how do I specify what frame to modify? I might be sending 10 frames all at different rates?
This is where my comment from earlier came from stating that if I set the Active Frame to one from the Signal (index the Signal array, use a property node to get the Frame) then I get error -1074384512.
Edit: okay I see the Frame >> Active can accept the Signal according to the help, good information but still the rate seems to be limited to 0.1s.
It seems you were moving the variable in the opposite direction I was. My testing involved sending frames faster and setting the value to 0.001.
The key to the different behavior is that setting this property resets the cyclic rate and sends out a new frame. Thus, writing the property every cycle of the loop will send out a new frame every cycle of the loop. Setting the property higher than your loop rate will result in the loop rate limiting the maximum transmit time. We can put the property in the case structure to resolve this.
Thanks this was the issue. So I'm dealing with changing frame rates on the fly, and if I call the property to change the TX time as you mentioned it will send it out immediate. Is there a reason for this? I can see some cases where I wouldn't want to update the timing until the next scheduled transmit. Is there a way to not update the time until then?
I'm not sure it is an issue but imagine a situation where a frame is scheduled to go out every 1000ms. Then I update the time to be 2000ms. On the bus you will see each frame going out every 1000ms, then two frames will be closer than 1000ms, then they will be seen at 2000ms. This likely isn't an issue for most signals, but on something like a byte that is supposed to increment with each write I could seen an issue where I am incrementing, but the device receiving might not see all the frames if they come in too quickly. Again I haven't seen an issue but just an observation.
The timing of the frame is handled in hardware with a counter or timer register of sorts inside of a state machine. The only way to update the counter is to stop the hardware, update the value, and start it back up again. In doing so, all of the steps that happen with a new cyclic frame must be repeated. The start time offset is re-calculated and when it elapses the frame is sent out. We can minimize the drift by setting the offset to zero but it still takes time to reset the hardware with the changes.
The start time offset is re-calculated and when it elapses the frame is sent out. We can minimize the drift by setting the offset to zero but it still takes time to reset the hardware with the changes.
Another great suggestion, you're on a roll today. So my timing isn't as critical, I just shouldn't be faster than the devices on the bus. So I wrote code that whenever the TX rate is updated, the Start Time Offset is updated first, and it is set to a value of 1/2 of the new TX rate setpoint. There is still jitter and an unknown in the timing but this way we won't ever be too fast, we will only be a little slower. I did this because I assumed getting the remaining time until the next transmission (on each frame) isn't possible, correct me if I'm wrong. So again with the 1s and 2s example from earlier.
(Update requested at 2.010, but start offset is 1/2 of the new TX so offset is 1s)
Or with the extreme of almost transmitting the 1s rate then updating to 2s.
(Update requested at 2.900, but start offset is 1/2 of the new TX which so offset is 1s)
And even going from something like 2s to 1s we will have a start offset of 0.5s, so we may send a frame a little faster than we want but we will always have some time between the sending at one rate, and the sending of the next rate.