05-22-2012 08:34 PM
So I'm having some kind of very bizarre issue with a ring control and a graph. I'm using LabWindows/CVI on a Windows 7 machine. The part of the program I'm looking at is basically for navigating through data - there are multiple "transients" (repetitions of an experiment), and you can select which one you want to look at from a list.
Normally you'd select the transient from the list, it plots the data, then it's done, basically. However, suddenly (don't know how long it's been happening for), when I select anything except "Average", it does all the plotting and such, then it changes the ring control back to "Average" (it doesn't plot the average data or generate any callbacks as far as I can tell).
Now the most bizarre thing as you can see below, it seems like the switch just happens when I plot something on the graph:
So, that's just bizarre. The code for this section is here:
if(uidc.polyon) { polynomial_subtraction(curr_data, np, uidc.polyord, 0); // 0 Skip for now } // Scale the curr_data for gains, then pre-scale the FFT data // to have no change in the power spectrum (multiply by (2/np) for(j = 0; j < np; j++) { fft_data[j] = curr_data[j]*2/np; curr_data[j] = curr_data[j]*uidc.fgain[i] + uidc.foff[i]; } uidc.fplotids[i] = PlotY(dc.fid, dc.fgraph, curr_data, np, VAL_DOUBLE, VAL_THIN_LINE, VAL_NO_POINT, VAL_SOLID, 1, uidc.fchans[i]?uidc.fcol[i]:VAL_TRANSPARENT); // Prepare the data. FFTEx(fft_data, np, npfft, NULL, FALSE, curr_fft); // Do the fourier transform
dc is a struct I use to better organize some of the UI controls, and uidc is for cacheing display variables, so dc.fid is the panel that's embedded in the "FID" tab, dc.fgraph = FID_Graph, and corresponds to the graph control. The ring control is actually in a child panel, dc.cloc[0]. FID_Graph has a callback it can generate, but the callback is empty (haven't coded anything there yet).
I have also considered that maybe something in another thread (I don't think there are any, but whatever) that I can't see is causing this, however, this behavior always happens on that one line. I've tried breaking in different places, waiting, then continuing, as well as adding a for loop containing Delay(0.01), looping 100 times. Always happens after the plot.
Does anyone have any idea why this could be happening?
Solved! Go to Solution.
05-22-2012 08:45 PM - edited 05-22-2012 08:53 PM
I have more information. It turns out that dc.ctrans == 2 (the ring control) and dc.fgraph == 2. However, dc.fid ==3 and dc.cloc[0] == 17, but it seems like maybe it's some kind of cross-talk.
Additionally, it seems to only happen to the panel which makes the change. This function actually plots both the direct measurement and the FFT of the measurement. When I switch to the FFT tab and use identical controls there, the same thing happens, but now to dc.ctrans on dc.cloc[1] (the embedded nav panel on the Spectrum tab). This time it happens a bit further down in the code, though, at the point where the data are plotted on the FFT tab. But again, happens on the first PlotY.
Edit
I managed to change ctrans to 17 and this is still happening, so apparently it's not that....
05-23-2012 12:09 AM
May there be the possibility that the ring control callback manipulates some object pointed to by 'panel' and/or 'control' variables? (e.g. with a DefaultCtrl (panel, control)?
05-23-2012 12:57 AM
I don't really understand what that means. Are you saying that DefaultCtrl can be triggered by the graph being plotted? The ring control always reverts as soon as something is plotted, for whatever reason.
05-23-2012 01:49 AM - edited 05-23-2012 01:50 AM
Hi,
i do not have the solution but there is some thigs that can help.
You can use "Run\Stack Trace"(CVI/IDE menu) to check the way of program flow to actual (break) point.This can be useful to check if Ring callbak is called in time when your plot function i s already in run(assuming you call ProcessSystemEvents() or similar)
When you found where problem is, you can eventualy protect you function or callback to be called in only one instance by something like this: (not multithread safe)
void func() { static int runonce=0; if (runonce!=0)return; runonce=1; //... some code //... some code runonce=0; return; }
be careful to insert runonce=0; before any return; in function;
Two tips about changed value of Ring:
a)if control callback return value 1 , some event is swallowed and control change its value back like before the user click.
b)maybe on some other place in program you call SetCtrlVal/SetCtrlAttribute with wrong panel handle/control value
It seems to me that you use "Tab" control, maybe it is related to it, do you corectly get panel handle by GetPanelHandleFromTabPage on all places?
05-23-2012 02:37 AM
PaulGanssle ha scritto:
I don't really understand what that means. Are you saying that DefaultCtrl can be triggered by the graph being plotted? The ring control always reverts as soon as something is plotted, for whatever reason.
I am asking if for some reason there may be a SetCtrlVal or a DefaultCtrl or some other function in the ring callback that does not address a specific object but rather uses 'panel' and 'control' variables defined in the callback itself. Since these variables contain the panel handle and the ID of the control that is calling the callback, using them instead of the desired handle / ID would have the effect of changing the ring value instead of the expected object .
05-23-2012 12:15 PM
Hi Paul,
I also don't have a solution but I wanted to point out that, even though you are seeing the ring change its value only when you call the plotting function, this doesn't mean that it is this function call that is really changing the value of the ring. In CVI, certain drawing operations are batched, for performance reasons, and the panel only updates visually at certain times. One of those times is when you plot data to a graph. Yes, the ring is changing visually at that time, but it's probably simply "catching up" with an earlier change.
As you're stepping through the code, looking for when the ring value changes, you can use the Run>>Refresh User Interface command to force the panel to update, so that you don't have to wait for the plotting function and hopefully see this change happening earlier.
Luis
05-23-2012 02:47 PM
@LuisG wrote:
Hi Paul,
I also don't have a solution but I wanted to point out that, even though you are seeing the ring change its value only when you call the plotting function, this doesn't mean that it is this function call that is really changing the value of the ring. In CVI, certain drawing operations are batched, for performance reasons, and the panel only updates visually at certain times. One of those times is when you plot data to a graph. Yes, the ring is changing visually at that time, but it's probably simply "catching up" with an earlier change.
As you're stepping through the code, looking for when the ring value changes, you can use the Run>>Refresh User Interface command to force the panel to update, so that you don't have to wait for the plotting function and hopefully see this change happening earlier.
Luis
Perfect! This is exactly what I was looking for. By refreshing at various breakpoints I found that somewhere earlier in the function it was refreshing itself in a weird way. Fixed now. Thanks!