MH K8 firmware with HV control.

Dependencies:   mbed NOKIA_5110

Fork of muonhunter-K8 by Oliver Keller

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);
    }
}