MH K8 firmware with HV control.

Dependencies:   mbed NOKIA_5110

Fork of muonhunter-K8 by Oliver Keller

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }