Tube test1
This first piece of code is trying to exercise the communications between the processor and the a/d-d/a on the tube control card. It should detect a failure to either set or readback the desired value and generate a print out on the serial port. The test "cycle2" is the primary piece of test code and reads back the a/d values 25 times verifying they are reporting the correct values.
<pre> static void failure(int cnt, float v, float av, float a, float aa, float vd, float ad, int i) { unsigned int hex; char buf[256];
sprintf(buf,"cnt %d kV:%3.3f (%3.3f)\n\ri %d, uA:%3.3f (%3.3f)\n\rVdiff %3.3f Adiff %3.3f",cnt,av,v,i,aa,a,vd,ad); s_msg(buf); hex = (unsigned int) (getTubeKVScaleFactor() * v); s_msg("kV 0x%x", hex); hex = (unsigned int) (getTubeUAScaleFactor() * a); s_msg("uA 0x%x", hex); sprintf(buf,"cnt %d kV:%3.3f (%3.3f)\ni %d, uA:%3.3f (%3.3f)\nVdiff %3.3f Adiff %3.3f",cnt,av,v,i,aa,a,vd,ad); TEXT_SetText(WM_GetDialogItem ( hXrayTest, ID_STATUS_TEXT ),buf); }
static int stopFlag; static void cycle1( void ) { float Vdiff=0.0,Adiff=0.0,actualKV,actualUA; int cnt = 0; int failed = 0; float error = 2.0; char buf[256] = "Starting cycle1 test"; float kV=0.0,uA=0.0; int selectedFilter = DROPDOWN_GetSel (WM_GetDialogItem(hXrayTest, ID_DROPDOWN_FILTER));
s_msg(buf); TEXT_SetText(WM_GetDialogItem ( hXrayTest, ID_STATUS_TEXT ),buf); BUTTON_GetText(WM_GetDialogItem(hXrayTest, XRAY_KV_BUTTON),buf,sizeof(buf)); sscanf(buf,"%f",&kV); BUTTON_GetText(WM_GetDialogItem(hXrayTest, XRAY_UA_BUTTON),buf,sizeof(buf)); sscanf(buf,"%f",&uA); ChangeFilterBlocking(selectedFilter); // move filter to desired filter
stopFlag = 0; while ( failed == 0 ) { StartXrayTubeDirect(kV,uA); NU_Sleep(1000*5); actualKV = getTubeActualKV( ) ; actualUA = getTubeActualCurrent( ); Vdiff = abs(kV - actualKV); if (Vdiff > error) { failed = 1; break; } Adiff = abs(uA - actualUA); if (Adiff > error) { failed = 1; break; } StopXrayTube(); sprintf(buf,"cnt %d\nVerr %f\nAerr %f",cnt,Vdiff,Adiff); TEXT_SetText(WM_GetDialogItem ( hXrayTest, ID_STATUS_TEXT ),buf); cnt++; GUI_Delay(1000); //NU_Sleep(800); if (stopFlag == 1) break; } if (failed == 0) { sprintf(buf,"Cycle test finished\ncnt %d\n",cnt); TEXT_SetText(WM_GetDialogItem ( hXrayTest, ID_STATUS_TEXT ),buf); } else { failure(cnt, kV, actualKV, uA, actualUA, Vdiff, Adiff, -1); StopXrayTube(); } }
static void simplePlot(float *V, float *C, int cnt) { GRAPH_DATA_Handle vdata, cdata; short *v, *c; float vmin = 1e6, cmin = 1e6, vmax = 0, cmax = 0; float wsi = 0.0; int xs = 300; // from window size above
for (int i = 0; i < cnt; i++) { if (V[i] < vmin) { vmin = V[i]; } if (V[i] > vmax) { vmax = V[i]; } if (C[i] < cmin) { cmin = C[i]; } if (C[i] > cmax) { cmax = C[i]; } } float vscale = 5000 / (vmax - vmin); float cscale = 5000 / (cmax - cmin); v = (short *) OSCalloc(xs,sizeof(short)); c = (short *) OSCalloc(xs,sizeof(short)); for (int i = 0; i < xs; i++) { v[i] = (short) (V[(int)wsi]*vscale); c[i] = (short) (C[(int)wsi]*cscale); wsi += (float)cnt / (float)xs; } vdata = GRAPH_DATA_YT_Create(GUI_RED, cnt, v, cnt); GRAPH_DATA_XY_SetLineStyle(vdata, GUI_LS_SOLID); GRAPH_AttachData(WM_GetDialogItem(hXrayTest, GUI_ID_SPECTRA), vdata); cdata = GRAPH_DATA_YT_Create(GUI_BLUE, cnt, c, cnt); GRAPH_DATA_XY_SetLineStyle(cdata, GUI_LS_SOLID); GRAPH_AttachData(WM_GetDialogItem(hXrayTest, GUI_ID_SPECTRA), cdata); OSFree(v); OSFree(c); }
- define LOOPCNT 25
extern void set_tube_current(float microamps); static void cycle2(void) { int loopcnt = LOOPCNT; float Vdiff[LOOPCNT],Adiff[LOOPCNT],actualKV,actualUA; int cnt = 0; int failed = -1; float error = 2.0; char buf[256] = "Starting cycle2 test"; float kV,uA,iuA; int selectedFilter = DROPDOWN_GetSel (WM_GetDialogItem(hXrayTest, ID_DROPDOWN_FILTER));
s_msg(buf); GRAPH_SetColor(WM_GetDialogItem(hXrayTest, GUI_ID_SPECTRA), GUI_WHITE, GRAPH_CI_BK); TEXT_SetText(WM_GetDialogItem ( hXrayTest, ID_STATUS_TEXT ),buf); BUTTON_GetText(WM_GetDialogItem(hXrayTest, XRAY_KV_BUTTON),buf,sizeof(buf)); sscanf(buf,"%f",&kV); BUTTON_GetText(WM_GetDialogItem(hXrayTest, XRAY_UA_BUTTON),buf,sizeof(buf)); sscanf(buf,"%f",&uA); iuA = uA; ChangeFilterBlocking(selectedFilter); // move filter to desired filter
stopFlag = 0; while ( failed == -1 ) { uA = iuA; StartXrayTubeDirect(kV,uA); GUI_Delay(1000*1); //NU_Sleep(1000*2); for (int i = 0; i < loopcnt; i++) { actualKV = getTubeActualKV( ) ; actualUA = getTubeActualCurrent( ); Vdiff[i] = abs(kV - actualKV); Adiff[i] = abs(uA - actualUA); if (Vdiff[i] > error) {failed = i; break; } if (Adiff[i] > error) {failed = i; break; } } //simplePlot(Vdiff, Adiff, loopcnt); if (failed != -1) goto bypass; if (uA > 50.0) { uA *= 0.25; // decrease current } else { uA *= 3.90; // increase current } set_tube_current( uA ); GUI_Delay(1000*1); //NU_Sleep(1000*2); for (int i = 0; i < loopcnt; i++) { actualKV = getTubeActualKV( ); actualUA = getTubeActualCurrent( ); Vdiff[i] = abs(kV - actualKV); Adiff[i] = abs(uA - actualUA); if (Vdiff[i] > error) {failed = i; break; } if (Adiff[i] > error) {failed = i; break; } } //simplePlot(Vdiff, Adiff, loopcnt); if (failed != -1) goto bypass; StopXrayTube(); sprintf(buf,"cnt %d %3.3f %3.3f\nVerr %f\nAerr %f",cnt,iuA,uA,Vdiff[0],Adiff[0]); TEXT_SetText(WM_GetDialogItem ( hXrayTest, ID_STATUS_TEXT ),buf); //s_msg(buf); cnt++; GUI_Delay(200); //NU_Sleep(800); bypass: if (stopFlag == 1) break; } if (failed == -1) { sprintf(buf,"Cycle test finished\ncnt %d\n",cnt); TEXT_SetText(WM_GetDialogItem ( hXrayTest, ID_STATUS_TEXT ),buf); } else { failure(cnt, kV, actualKV, uA, actualUA, Vdiff[failed], Adiff[failed], failed); StopXrayTube(); } }
static void stopXrayTest( void ) { StopXrayTube( ); WM_DeleteTimer( hScreenUpdateTimer ); WM_DeleteTimer( hTubeUpdateTimer ); //disable the close button when testing is active BUTTON_SetBkColor ( WM_GetDialogItem(hXrayTest,GUI_ID_CLOSE_BUTTON), BUTTON_CI_PRESSED, GUI_WHITE); BUTTON_SetBkColor ( WM_GetDialogItem(hXrayTest,GUI_ID_CLOSE_BUTTON), BUTTON_CI_UNPRESSED, GUI_WHITE); stopFlag = 1; }
</pre>
Possible issue with the selection of the a/d on the tube control card
<pre> unsigned short cmd_ltc186X(int channel) { int i; unsigned value = 0;
select_ad_da(TYPE_AD); NU_Sleep(2); select_ad_da(TYPE_NONE); set_bit(MCU, CLK); // Note: needs a delay of 2ms for proper selection of channel NU_Sleep(2); select_ad_da(TYPE_AD); delay_time(1); for (i = 11; i >= 0; i--) { if (i == 11) set_bit(MCU, DOUT); if (i == 10) if (channel) set_bit(MCU, DOUT); else clr_bit(MCU, DOUT); clr_bit(MCU, CLK); delay_time(1); set_bit(MCU, CLK); delay_time(1); value |= (get_bit(MCU, DIN) & 0x1) << i; } select_ad_da(TYPE_NONE); return(value); }
</pre>
The following is a modified version of StartXrayTubeDirect...
<pre>
- if 0
//starts xray tube based on direct inputs void StartXrayTubeDirect(float fVoltage,float fCurrent) {
- ifdef START_TUBE_DEBUG
char buf[512]; char buf3[128];
- endif
float settleTime = getTubeDetectorDelayTime ( ); float biasedDetectorTemp; float unBiasedDetectorTemp = 0.0; float newDetectorTemp;
unBiasedDetectorTemp = getDetectorTemp();
setTubeCurrent( fCurrent );
setTubeVoltage (fVoltage );
NU_Sleep(150);
setTubeOnOff( tubeOn );
if (settleTime > 0 ) {
NU_Sleep( (int)settleTime );//need to sleep here so that tube is on and creates noise
biasedDetectorTemp=getDetectorTemp(); newDetectorTemp = detectorParams.setTemp + (biasedDetectorTemp-unBiasedDetectorTemp); SetDetTemp(newDetectorTemp);
- ifdef START_TUBE_DEBUG
s_msg("unBiased:%f biased:%f desired:%f new:%f", unBiasedDetectorTemp,biasedDetectorTemp,detectorParams.setTemp,newDetectorTemp);
- endif
}
}
- else /* 0 */
void StartXrayTubeDirect(float fVoltage,float fCurrent) {
- ifdef START_TUBE_DEBUG
char buf[512]; char buf3[128];
- endif
float settleTime = getTubeDetectorDelayTime ( ); float biasedDetectorTemp; float unBiasedDetectorTemp = 0.0; float newDetectorTemp;
unBiasedDetectorTemp = getDetectorTemp();
setTubeOnOff( tubeOn ); setTubeCurrent( 0.0 ); setTubeVoltage ( 0.0 ); setTubeOnOff( tubeOn ); for (int i = 5; i < (int) fVoltage; i++) { setTubeVoltage ( (float) i ); NU_Sleep(10); } setTubeCurrent( fCurrent ); setTubeVoltage (fVoltage );
NU_Sleep(150);
if (settleTime > 0 ) {
NU_Sleep( (int)settleTime );//need to sleep here so that tube is on and creates noise
biasedDetectorTemp=getDetectorTemp(); newDetectorTemp = detectorParams.setTemp + (biasedDetectorTemp-unBiasedDetectorTemp); SetDetTemp(newDetectorTemp);
- ifdef START_TUBE_DEBUG
s_msg("unBiased:%f biased:%f desired:%f new:%f", unBiasedDetectorTemp,biasedDetectorTemp,detectorParams.setTemp,newDetectorTemp);
- endif
}
}
- endif /* 0 */
</pre>
Here is another snipet which tries to fudge with the way we turn the tube on. This didn't prove useful in limiting the noise issues I was chasing at the time. <pre> void StartXrayTubeDirect(float fVoltage,float fCurrent) {
- ifdef START_TUBE_DEBUG
char buf[512];
- endif
float settleTime = getTubeDetectorDelayTime ( ); float biasedDetectorTemp; float unBiasedDetectorTemp = 0.0; float newDetectorTemp;
unBiasedDetectorTemp = getDetectorTemp();
- if 0
setTubeCurrent( 0.0 ); setTubeVoltage ( 0.0 ); setTubeOnOff( tubeOn ); NU_Sleep(5); setTubeCurrent( 1.0 ); NU_Sleep(5); for (int i = 5; i < (int) fVoltage; i++) { setTubeVoltage ( (float) i ); NU_Sleep(5); } setTubeCurrent( fCurrent ); setTubeVoltage (fVoltage ); //NU_Sleep(150);
- else
setTubeCurrent( fCurrent ); setTubeVoltage (fVoltage ); setTubeOnOff( tubeOn );
- endif
if (settleTime > 0 ) {
NU_Sleep( (int)settleTime );//need to sleep here so that tube is on and creates noise
biasedDetectorTemp=getDetectorTemp(); newDetectorTemp = detectorParams.setTemp + (biasedDetectorTemp-unBiasedDetectorTemp); SetDetTemp(newDetectorTemp);
- ifdef START_TUBE_DEBUG
sprintf(buf,"unBiased:%f biased:%f desired:%f new:%f\r\n", unBiasedDetectorTemp,biasedDetectorTemp,detectorParams.setTemp,newDetectorTemp); Serial_SCIFSend(strlen ( buf ),buf );
- endif
}
setTubeStartTime ( GUI_X_GetTime() );
- ifdef START_TUBE_DEBUG
sprintf(buf,"In direct kv:%f cur:%f\r\n",fVoltage,fCurrent); NU_SIO_Puts((char *)buf);
- endif
} </pre>