Mihaly Vadai
/
muonhunter-K8
MH K8 firmware with HV control.
Fork of muonhunter-K8 by
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 #include "mbed.h" 00002 #include "hvcontrol.cpp" 00003 #include "detection.cpp" 00004 #include <queue> 00005 #include "NOKIA_5110.h" 00006 00007 volatile double targetVoltage1 = 400; 00008 volatile double targetVoltage2 = 400; 00009 00010 00011 //set the initial frequency of the oscillators below 00012 volatile int f1 = 4000; //3500; 00013 volatile int f2 = 4000; 00014 volatile int prevVoltage1; 00015 volatile int prevVoltage2; 00016 int deltaF = 20; 00017 int deltaV = 2; 00018 bool hv1Ready = 0; 00019 bool hv2Ready = 0; 00020 00021 //set the coincidence times in us below 00022 int coincidence_wait = 50; //150; 00023 bool buzzer = 0; 00024 bool muonLED = 0; 00025 00026 /* NO USER CONFIGURABLE OPTIONS BELOW 00027 */ 00028 00029 //typically around 2 min data 00030 //assuming normal background 00031 #define DETECTION_MEMORY_LIMIT 32 //128 00032 00033 //doesn't log the GM hits with a timestamp 00034 //only counts them when set to 1 00035 #define DETECT_MUONS_ONLY 1 00036 00037 bool mdet = 0; 00038 /*volatile*/ int muon_total; 00039 /*volatile*/ int gm1_total; 00040 /*volatile*/ int gm2_total; 00041 int minutes = 0; //global minutes counter 00042 00043 //storing a detections in a FIFO queue 00044 queue<Detection> detections; 00045 00046 //High voltage controls 00047 HVControl hv1(PA_3, PA_0); 00048 HVControl hv2(PB_1, PA_1); 00049 00050 //Serial rpi(PA_9,PA_10); 00051 00052 Timer coincidence_timer; 00053 Timer main_t; 00054 00055 Serial pc(USBTX, USBRX); 00056 // Ticker debug; 00057 Ticker hv1monitor; 00058 Ticker hv2monitor; 00059 //Ticker memory_checker; 00060 00061 DigitalOut led(LED1); 00062 DigitalOut GM1_led(PA_12); 00063 DigitalOut GM2_led(PA_8); 00064 DigitalOut C_led(PA_11); 00065 DigitalOut Buzzer(PF_0); 00066 00067 InterruptIn GM1(PB_0); 00068 InterruptIn GM2(PF_1); 00069 00070 //global variables for voltages 00071 volatile float v1 = 0; 00072 volatile float v2 = 0; 00073 00074 //ui functions 00075 void reset_counters (void) 00076 { 00077 muon_total = 0; 00078 gm1_total = 0; 00079 gm2_total = 0; 00080 } 00081 00082 void muon_buzz(void) 00083 { 00084 if(muonLED) C_led = 1; 00085 00086 if(buzzer) { 00087 for(int i = 0; i < 32; i++) { 00088 Buzzer = !Buzzer; 00089 wait(0.002); 00090 } 00091 } else { 00092 wait(0.001); 00093 } 00094 C_led = 0; 00095 } 00096 00097 void GM1_buzz(void) 00098 { 00099 GM1_led = 1; 00100 if(buzzer) { 00101 for(int i = 0; i < 16; i++) { 00102 Buzzer = !Buzzer; 00103 wait(0.001); 00104 } 00105 } else { 00106 wait(0.001); 00107 } 00108 GM1_led = 0; 00109 } 00110 00111 void GM2_buzz(void) 00112 { 00113 GM2_led = 1; 00114 if(buzzer) { 00115 for(int i = 0; i < 16; i++) { 00116 Buzzer = !Buzzer; 00117 wait(0.001); 00118 } 00119 } else { 00120 wait(0.003); 00121 } 00122 GM2_led = 0; 00123 } 00124 00125 00126 //adds a detection onto the queue 00127 void add_detection(int channel, float time) 00128 { 00129 //Detection* det = new Detection(channel, time); 00130 //detections.push(*det); 00131 //delete det; 00132 } 00133 00134 //callback for GM1 detection 00135 void GM1_hit(void) 00136 { 00137 coincidence_timer.start(); 00138 while(coincidence_timer.read_us() < coincidence_wait) { 00139 if(GM2 == 0 && !mdet) { 00140 add_detection(3, main_t.read_us()); 00141 muon_buzz(); 00142 muon_total++; 00143 gm2_total++; 00144 if(muonLED) mdet = 1; 00145 } 00146 wait(1e-7); 00147 } 00148 coincidence_timer.stop(); 00149 coincidence_timer.reset(); 00150 if(mdet == 0) GM1_buzz(); 00151 if ( !DETECT_MUONS_ONLY ) add_detection(1, main_t.read()); 00152 gm1_total++; 00153 mdet = 0; 00154 } 00155 00156 //callback for GM2 detection 00157 void GM2_hit(void) 00158 { 00159 coincidence_timer.start(); 00160 while(coincidence_timer.read_us() < coincidence_wait) { 00161 if(GM1 == 0 && !mdet) { 00162 add_detection(3, main_t.read()); 00163 muon_buzz(); 00164 muon_total++; 00165 gm1_total++; 00166 if(muonLED) mdet = 1; 00167 } 00168 wait(1e-7); 00169 } 00170 coincidence_timer.stop(); 00171 coincidence_timer.reset(); 00172 if(mdet == 0) GM2_buzz(); 00173 if ( !DETECT_MUONS_ONLY ) add_detection(2, main_t.read()); 00174 gm2_total++; 00175 mdet = 0; 00176 } 00177 00178 // high voltage software monitors 00179 void hv1monitor_(void) 00180 { 00181 prevVoltage1 = (prevVoltage1 + v1) / 2; 00182 v1 = hv1.get_voltage(); 00183 00184 if(prevVoltage1 - v1 > 15){ 00185 f1 = 6000; 00186 hv1.set_frequency(f1); 00187 } 00188 00189 if(targetVoltage1 < 200) targetVoltage1 = 200; 00190 if(targetVoltage1 > 1000) targetVoltage1 = 1000; 00191 00192 if(targetVoltage1 < (v1*(100-deltaV)/100)){ 00193 f1 += deltaF; 00194 }else if(targetVoltage1 > (v1*(100+deltaV)/100)){ 00195 f1 -= deltaF; 00196 } 00197 00198 if(v1 < targetVoltage1*1.05 && v1 > targetVoltage1*0.95) hv1Ready = 1; 00199 else hv1Ready = 0; 00200 00201 hv1.set_frequency(f1); 00202 } 00203 00204 void hv2monitor_(void) 00205 { 00206 prevVoltage2 = (prevVoltage2 + v2) / 2; 00207 v2 = hv2.get_voltage(); 00208 00209 if(prevVoltage2 - v2 > 15){ 00210 f2 = 6000; 00211 hv2.set_frequency(f2); 00212 } 00213 00214 if(targetVoltage2 < 200) targetVoltage2 = 200; 00215 if(targetVoltage2 > 1000) targetVoltage2 = 1000; 00216 00217 if(targetVoltage2 < (v2*(100-deltaV)/100)){ 00218 f2 += deltaF; 00219 }else if(targetVoltage2 > (v2*(100-deltaV)/100)){ 00220 f2 -= deltaF; 00221 } 00222 00223 if(v2 < targetVoltage2*1.05 && v2 > targetVoltage2*0.95) hv2Ready = 1; 00224 else hv2Ready = 0; 00225 00226 hv2.set_frequency(f2); 00227 } 00228 00229 //discarding older items if buffer gets too big 00230 //void memory_checker_(void) 00231 //{ 00232 // if ( detections.size() > (DETECTION_MEMORY_LIMIT - (DETECTION_MEMORY_LIMIT/8)) ) { 00233 // while ( detections.size() > (DETECTION_MEMORY_LIMIT - (DETECTION_MEMORY_LIMIT/4)) ) { 00234 // detections.pop(); 00235 // } 00236 // } 00237 //} 00238 00239 char* itoa(int value, char* result, int base) 00240 { 00241 // check that the base if valid 00242 if ( base < 2 || base > 36 ) { 00243 *result = '\0'; 00244 return result; 00245 } 00246 00247 char* ptr = result, *ptr1 = result, tmp_char; 00248 int tmp_value; 00249 00250 do { 00251 tmp_value = value; 00252 value /= base; 00253 *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)]; 00254 } while ( value ); 00255 00256 // Apply negative sign 00257 if ( tmp_value < 0 ) 00258 *ptr++ = '-'; 00259 *ptr-- = '\0'; 00260 00261 while ( ptr1 < ptr ) { 00262 tmp_char = *ptr; 00263 *ptr-- = *ptr1; 00264 *ptr1++ = tmp_char; 00265 } 00266 00267 return result; 00268 } 00269 00270 int main() 00271 { 00272 //start main timer 00273 pc.baud(230400); 00274 main_t.start(); 00275 LcdPins myPins; 00276 00277 myPins.rst = PA_6; 00278 myPins.sce = PA_4; 00279 myPins.dc = PB_4; 00280 myPins.mosi = PA_7;//SPI_MOSI; 00281 myPins.miso = NC; 00282 myPins.sclk = PA_5;//SPI_SCK; 00283 00284 // Start the LCD 00285 NokiaLcd myLcd( myPins ); 00286 myLcd.InitLcd(); // LCD is reset and DDRAM is cleared 00287 myLcd.DrawString("MUON HUNTER V2"); 00288 myLcd.SetXY(0,1); 00289 myLcd.DrawString("TIME "); 00290 myLcd.SetXY(0,3); 00291 myLcd.DrawString("MUON COUNT"); 00292 myLcd.SetXY(0,4); 00293 myLcd.DrawString("GM1 COUNT"); 00294 myLcd.SetXY(0,5); 00295 myLcd.DrawString("GM2 COUNT"); 00296 hv1.set_frequency(f1); 00297 hv2.set_frequency(f2); 00298 GM1.fall(&GM1_hit); 00299 GM2.fall(&GM2_hit); 00300 00301 //tickers to monitor the high voltage 00302 hv1monitor.attach(&hv1monitor_, 0.1); 00303 hv2monitor.attach(&hv2monitor_, 0.1); 00304 00305 // offset for proto board 00306 targetVoltage2 *= 0.79; 00307 00308 char number[10]; 00309 00310 //ticker to monitor memory usage 00311 //memory_checker.attach(&memory_checker_, 0.2); 00312 while(1) { 00313 00314 myLcd.SetXY(5*6,1); 00315 unsigned int seconds = (int) main_t.read(); 00316 //int minutes = (seconds/60); 00317 if (seconds >= 60) { 00318 main_t.reset(); 00319 minutes++; 00320 } 00321 if (minutes < 10) 00322 myLcd.DrawChar('0'); 00323 itoa(minutes, number, 10); 00324 myLcd.DrawString(number); 00325 myLcd.DrawChar(':'); 00326 if ((seconds%60) < 10) 00327 myLcd.DrawChar('0'); 00328 itoa(seconds%60, number,10); 00329 myLcd.DrawString(number); 00330 00331 myLcd.SetXY(11*6,3); 00332 itoa(muon_total, number, 10); 00333 myLcd.DrawString(number); 00334 00335 myLcd.SetXY(3*6,4); 00336 if(hv1Ready) myLcd.DrawString(" "); 00337 else myLcd.DrawString("*"); 00338 00339 myLcd.SetXY(11*6,4); 00340 itoa(gm1_total, number, 10); 00341 myLcd.DrawString(number); 00342 00343 myLcd.SetXY(3*6,5); 00344 if(hv2Ready) myLcd.DrawString(" "); 00345 else myLcd.DrawString("*"); 00346 00347 myLcd.SetXY(11*6,5); 00348 itoa(gm2_total, number, 10); 00349 myLcd.DrawString(number); 00350 00351 00352 while(!detections.empty()){ 00353 Detection temp = detections.front(); 00354 00355 pc.printf("Ch: %d, Time: %.2fs, V1: %.1fV, V2: %.1fV \n\r", temp.channel, temp.time, v1, v2); 00356 pc.printf("Total GM1: %d, Total GM2: %d, Total Coinc: %d \n\r \n\r", gm1_total, gm2_total, muon_total); 00357 detections.pop(); 00358 } 00359 00360 pc.printf("%.fs, GM1: %d, GM2: %d, Muons: %d \n\r", main_t.read(), gm1_total, gm2_total, muon_total); 00361 pc.printf("V1: %.1fV, V2: %.1fV \n\r", v1, v2); 00362 wait(1); 00363 } 00364 }
Generated on Thu Jul 21 2022 03:16:53 by 1.7.2