Mihaly Vadai
/
muonhunter-K8
MH K8 firmware with HV control.
Fork of muonhunter-K8 by
main.cpp
- Committer:
- mihaly
- Date:
- 2019-04-22
- Revision:
- 11:5a5f16e09f10
- Parent:
- 10:534172e71f4f
File content as of revision 11:5a5f16e09f10:
#include "mbed.h" #include "hvcontrol.cpp" #include "detection.cpp" #include <queue> #include "NOKIA_5110.h" volatile double targetVoltage1 = 400; volatile double targetVoltage2 = 400; //set the initial frequency of the oscillators below volatile int f1 = 4000; //3500; volatile int f2 = 4000; volatile int prevVoltage1; volatile int prevVoltage2; int deltaF = 20; int deltaV = 2; bool hv1Ready = 0; bool hv2Ready = 0; //set the coincidence times in us below int coincidence_wait = 50; //150; bool buzzer = 0; bool muonLED = 0; /* NO USER CONFIGURABLE OPTIONS BELOW */ //typically around 2 min data //assuming normal background #define DETECTION_MEMORY_LIMIT 32 //128 //doesn't log the GM hits with a timestamp //only counts them when set to 1 #define DETECT_MUONS_ONLY 1 bool mdet = 0; /*volatile*/ int muon_total; /*volatile*/ int gm1_total; /*volatile*/ int gm2_total; int minutes = 0; //global minutes counter //storing a detections in a FIFO queue queue<Detection> detections; //High voltage controls HVControl hv1(PA_3, PA_0); HVControl hv2(PB_1, PA_1); //Serial rpi(PA_9,PA_10); Timer coincidence_timer; Timer main_t; Serial pc(USBTX, USBRX); // Ticker debug; Ticker hv1monitor; Ticker hv2monitor; //Ticker memory_checker; DigitalOut led(LED1); DigitalOut GM1_led(PA_12); DigitalOut GM2_led(PA_8); DigitalOut C_led(PA_11); DigitalOut Buzzer(PF_0); InterruptIn GM1(PB_0); InterruptIn GM2(PF_1); //global variables for voltages volatile float v1 = 0; volatile float v2 = 0; //ui functions void reset_counters (void) { muon_total = 0; gm1_total = 0; gm2_total = 0; } void muon_buzz(void) { if(muonLED) C_led = 1; if(buzzer) { for(int i = 0; i < 32; i++) { Buzzer = !Buzzer; wait(0.002); } } else { wait(0.001); } C_led = 0; } void GM1_buzz(void) { GM1_led = 1; if(buzzer) { for(int i = 0; i < 16; i++) { Buzzer = !Buzzer; wait(0.001); } } else { wait(0.001); } GM1_led = 0; } void GM2_buzz(void) { GM2_led = 1; if(buzzer) { for(int i = 0; i < 16; i++) { Buzzer = !Buzzer; wait(0.001); } } else { wait(0.003); } GM2_led = 0; } //adds a detection onto the queue void add_detection(int channel, float time) { //Detection* det = new Detection(channel, time); //detections.push(*det); //delete det; } //callback for GM1 detection void GM1_hit(void) { coincidence_timer.start(); while(coincidence_timer.read_us() < coincidence_wait) { if(GM2 == 0 && !mdet) { add_detection(3, main_t.read_us()); muon_buzz(); muon_total++; gm2_total++; if(muonLED) mdet = 1; } wait(1e-7); } coincidence_timer.stop(); coincidence_timer.reset(); if(mdet == 0) GM1_buzz(); if ( !DETECT_MUONS_ONLY ) add_detection(1, main_t.read()); gm1_total++; mdet = 0; } //callback for GM2 detection void GM2_hit(void) { coincidence_timer.start(); while(coincidence_timer.read_us() < coincidence_wait) { if(GM1 == 0 && !mdet) { add_detection(3, main_t.read()); muon_buzz(); muon_total++; gm1_total++; if(muonLED) mdet = 1; } wait(1e-7); } coincidence_timer.stop(); coincidence_timer.reset(); if(mdet == 0) GM2_buzz(); if ( !DETECT_MUONS_ONLY ) add_detection(2, main_t.read()); gm2_total++; mdet = 0; } // high voltage software monitors void hv1monitor_(void) { prevVoltage1 = (prevVoltage1 + v1) / 2; v1 = hv1.get_voltage(); if(prevVoltage1 - v1 > 15){ f1 = 6000; hv1.set_frequency(f1); } if(targetVoltage1 < 200) targetVoltage1 = 200; if(targetVoltage1 > 1000) targetVoltage1 = 1000; if(targetVoltage1 < (v1*(100-deltaV)/100)){ f1 += deltaF; }else if(targetVoltage1 > (v1*(100+deltaV)/100)){ f1 -= deltaF; } if(v1 < targetVoltage1*1.05 && v1 > targetVoltage1*0.95) hv1Ready = 1; else hv1Ready = 0; hv1.set_frequency(f1); } void hv2monitor_(void) { prevVoltage2 = (prevVoltage2 + v2) / 2; v2 = hv2.get_voltage(); if(prevVoltage2 - v2 > 15){ f2 = 6000; hv2.set_frequency(f2); } if(targetVoltage2 < 200) targetVoltage2 = 200; if(targetVoltage2 > 1000) targetVoltage2 = 1000; if(targetVoltage2 < (v2*(100-deltaV)/100)){ f2 += deltaF; }else if(targetVoltage2 > (v2*(100-deltaV)/100)){ f2 -= deltaF; } if(v2 < targetVoltage2*1.05 && v2 > targetVoltage2*0.95) hv2Ready = 1; else hv2Ready = 0; hv2.set_frequency(f2); } //discarding older items if buffer gets too big //void memory_checker_(void) //{ // if ( detections.size() > (DETECTION_MEMORY_LIMIT - (DETECTION_MEMORY_LIMIT/8)) ) { // while ( detections.size() > (DETECTION_MEMORY_LIMIT - (DETECTION_MEMORY_LIMIT/4)) ) { // detections.pop(); // } // } //} char* itoa(int value, char* result, int base) { // check that the base if valid if ( base < 2 || base > 36 ) { *result = '\0'; return result; } char* ptr = result, *ptr1 = result, tmp_char; int tmp_value; do { tmp_value = value; value /= base; *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)]; } while ( value ); // Apply negative sign if ( tmp_value < 0 ) *ptr++ = '-'; *ptr-- = '\0'; while ( ptr1 < ptr ) { tmp_char = *ptr; *ptr-- = *ptr1; *ptr1++ = tmp_char; } return result; } int main() { //start main timer pc.baud(230400); main_t.start(); LcdPins myPins; myPins.rst = PA_6; myPins.sce = PA_4; myPins.dc = PB_4; myPins.mosi = PA_7;//SPI_MOSI; myPins.miso = NC; myPins.sclk = PA_5;//SPI_SCK; // Start the LCD NokiaLcd myLcd( myPins ); myLcd.InitLcd(); // LCD is reset and DDRAM is cleared myLcd.DrawString("MUON HUNTER V2"); myLcd.SetXY(0,1); myLcd.DrawString("TIME "); myLcd.SetXY(0,3); myLcd.DrawString("MUON COUNT"); myLcd.SetXY(0,4); myLcd.DrawString("GM1 COUNT"); myLcd.SetXY(0,5); myLcd.DrawString("GM2 COUNT"); hv1.set_frequency(f1); hv2.set_frequency(f2); GM1.fall(&GM1_hit); GM2.fall(&GM2_hit); //tickers to monitor the high voltage hv1monitor.attach(&hv1monitor_, 0.1); hv2monitor.attach(&hv2monitor_, 0.1); // offset for proto board targetVoltage2 *= 0.79; char number[10]; //ticker to monitor memory usage //memory_checker.attach(&memory_checker_, 0.2); while(1) { myLcd.SetXY(5*6,1); unsigned int seconds = (int) main_t.read(); //int minutes = (seconds/60); if (seconds >= 60) { main_t.reset(); minutes++; } if (minutes < 10) myLcd.DrawChar('0'); itoa(minutes, number, 10); myLcd.DrawString(number); myLcd.DrawChar(':'); if ((seconds%60) < 10) myLcd.DrawChar('0'); itoa(seconds%60, number,10); myLcd.DrawString(number); myLcd.SetXY(11*6,3); itoa(muon_total, number, 10); myLcd.DrawString(number); myLcd.SetXY(3*6,4); if(hv1Ready) myLcd.DrawString(" "); else myLcd.DrawString("*"); myLcd.SetXY(11*6,4); itoa(gm1_total, number, 10); myLcd.DrawString(number); myLcd.SetXY(3*6,5); if(hv2Ready) myLcd.DrawString(" "); else myLcd.DrawString("*"); myLcd.SetXY(11*6,5); itoa(gm2_total, number, 10); myLcd.DrawString(number); while(!detections.empty()){ Detection temp = detections.front(); pc.printf("Ch: %d, Time: %.2fs, V1: %.1fV, V2: %.1fV \n\r", temp.channel, temp.time, v1, v2); pc.printf("Total GM1: %d, Total GM2: %d, Total Coinc: %d \n\r \n\r", gm1_total, gm2_total, muon_total); detections.pop(); } pc.printf("%.fs, GM1: %d, GM2: %d, Muons: %d \n\r", main_t.read(), gm1_total, gm2_total, muon_total); pc.printf("V1: %.1fV, V2: %.1fV \n\r", v1, v2); wait(1); } }