My primary goal is to use the recommended approach for using a daq object to read/write in the background so as to not affect the timing of the control loop happening in the foreground.
What I’ve tried:
- I created a control matrix, u, in my main function, and then started a while loop for the duration of the controlled operation, and then have two separate if statements (one for writing to the daq and one for reading) within that while loop whose conditions are time dependent to manage the timing of read/write operations. I would then overwrite certain rows of the control matrix to affect control commands. Here I used start(daq_obj, “repeatoutput”)
- Result: The timing of the loops have to be strictly controlled and are very dependent on anything else happening in the while loop, e.g. updating the commanded outputs from the controller, how much I’m plotting each time through the loop, and whether the main loop needs to call additional code, if any abnormal conditions are found in any of the 44 parameters collected in the “read” portion of the loop. Ultimately, I could not reliably run the system using this method, e.g. I would make repeated runs without changing anything and sometimes it worked fine and othertimes, in a seemingly quite random way, I would get errors like, “Output underflow event: last valid scan was number x”, or “Trigger timestamp not received.”
- In this method, when I created the daq object, I gave function handles to the ScansAvailableFcn (read_stuff.m) and ScansRequiredFcn (load_more_data.m). I created 2 sec of control parameters (a 2x11 matrix of doubles) (1Hz) and used preload(daq_obj, u); start(daq_obj, ‘Continuous’). With this method, as I understand it, the daq creates a listener for the daq object’s input buffer event ‘ElementsAvailable’. It then runs my read_stuff.m, which uses read(daq_obj, ‘all’, ‘outputformat’, ‘matrix’) to read data. This is the data I was saying I could see within the function’s workspace using a breakpoint or printing to the cmd window. To get the data, I’ve tried saving it to the preexisting daq object’s UserData field. I’ve tried saving it to a .mat file and writing it to a .txt file and each method failed.
- Result: The 1x44 vector of data from read would show up empty in the UserData field, and the .mat and .txt files would be empty. [Actually, the .mat was prepopulated with [7;7] (random), and after a run it would be empty.]
- I then tried creating a structure in daq_obj.UserData field with 46 fields and populating 44 of them with the elements of the 1x44 vector, and one Boolean “status” (when I changed from false to true if the object was written to) and one double “reads” (to count how many times data was read and the object was written to).
- Result: The “status” and “reads” fields where written to and would show as much back in my main function. Excellent, but writing the actual data fails. “Warning: Error occurred while executing the listener callback for event ElementsAvailable defined for class daq.Buffer: Index exceeds the number of array elements (44).”
- I tried using assignin/evalin as described below, but
- Result: this provided an empty matrix in the mat file.
Let’s see…
- Using readwrite errors out telling me to use write then read, separately.
- Using read and write separately errors out telling me to use readwrite.
- My belief is this error occurs when the timing of the reads and writes is incorrect. Thus I looked into the daq's callbacks, because the reads and writes occur on demand.
- Using read in the daq’s ScansAvailable callback and write in the daq’s ScansRequired callback, doesn’t work because it has no outputs, global variables don’t work, storing the data in the daq’s UserData field don’t work (shows up empty), and fprintf’ing to a .txt works only the first 1 or 2 cycles and then fscanf just pulls empty each iteration (though I can see the data in callback’s workspace and in the .txt file.
- I tried using only the ScansRequired callback to write and kept read in my main function. This errors out saying I need to read before I can write. I altered the code so it only writes immediately after a successful read, but this errors out as well, with an underflow event (which I believe is due to not writing fast enough).
I appreciate your help!!