Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 4 of 4

Thread: Gamma spectrometer possible?

  1. #1
    Junior Member
    Join Date
    Jun 2019
    Posts
    3

    Gamma spectrometer possible?

    I am a Educator looking to do a DIY gamma spectroscopy project with students (grade 10-12), and recently acquired a soundcard based gamma spectrometer (gamma spectacular) which has been amazing to use, however,
    It was brought up that the ADCs used in sound cards are quite susceptible to pulse pileup at higher count rates. This had me thinking.. Seeing as the ADC capability on the Teensy 3.6 is capable of fast sampling in the Mhz range would it not be possible to make out own gamma spectrometer from such a board?

    We recently acquired a Teensy 3.6 and I am just researching more about its capabilities.


    From what I am reading, correct me if I am wrong that the ADC can sample in the Mhz range.



    This has me rather excited.



    Anyone chime in ?

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    8,556
    Look into this thread for the github.com/pedvide/ADC library ADC-library-update-now-with-support-for-Teensy-3-1

    You don't need the github code as AFAIK it is the current version included with TeensyDuino install

  3. #3
    Junior Member
    Join Date
    Jun 2019
    Posts
    3
    I had a look at ADC library. I am still unsure what the maximum sample rate is using the ADC.
    What I'd like to do is use the Teensy like an external audio card, only sampling at 1Mhz if possible.

    or another alternative option would be use the teensy to do all the processing and binning of incoming pulses directly on board
    sort of like this https://www.instructables.com/id/Mul...troscopy-With/
    except the pulse stretching and conditioning circuit is not needed.

  4. #4
    Junior Member
    Join Date
    Jun 2019
    Posts
    3
    Here is the code I was playing with today. This an for an Arduino based spectrometer.
    The result was that 2 of the libraries shot back errors. Lots of code in here that seems not to work with the Teensy platform.

    Still investigating.






    Code:
    #include <U8glib.h>
    U8GLIB_ST7920_128X64 u8g(13, 11, 12, U8G_PIN_NONE);
    
    // Einstellungs-Tabelle für die Erhöhung der Taktfrequenz
    // ======================================================
    
    //  ADPS2     ADPS1    ADPS0     Division factor
    //    0         0        0              2
    //    0         0        1              2
    //    0         1        0              4
    //    0         1        1              8
    //    1         0        0             16
    //    1         0        1             32
    //    1         1        0             64
    //    1         1        1            128   (Standard)
    
    #define FASTADC 1
    
    // defines for setting and clearing register bits
    #ifndef cbi
    #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    #endif
    #ifndef sbi
    #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    #endif
    
    
    // Variablendeklaration
    // ====================
    
    const int analogInPin = A0;       // Analog input pin für die Pulshöhe
    const int pin_verzoegerung = A1;  // Analog input pin für die über ein Poti einstellbare variable Verzögerung
    const int pin_entleeren = 3;      // Digital output pin für das Entleeren des Speicherkondensators
    const int pin_treffer = 4;        // Digital input pin für vom Monoflop kommenden treffer
    const int pin_switch = 5;         // Digital output pin für switch
    const int pin_test = 7;           // Digital output pin um zu überprüfen, in welcher Phase der Entladekurve von C die Spannungsmessung erfolgt
    const int pin_reset = 8;          // Digital input pin für das Leeren des Pulshöhenarrays um eine neue Messung zu starten
    
    
    int U_puls = 0;              // aktuelle gemessene Pulshöhe
    float Spannung;              // aktuelle gemessene Pulsspannung
    int Index = 0;               // Index der gemessenen Pulshöhe im Intervall [0,127]
    float Faktor = 1;            // Vergrößerungs- bzw. Verkleinerungsfaktor
    int Pulshoehen[128];         // array mit der Anzahl der jeweils 128 verschiedenen Pulshöhen
    int reset_time;              // Zeitdauer in ms der U-Max-Speicherentleerung
    int j;                       // Zählvariable als Maß für die Schnelligkeit der Pulsabfrage
    
    int time_alt, time_neu;      // Variablen zur Ermittlung der Schleifendauer
    int Verzoegerung;            // Verzögerungszeit in µs
    
    
    // ===========================
    // ========== SETUP ==========
    // ===========================
    
    void setup(void)
       {
        Serial.begin(9600);
        
        pinMode(pin_entleeren, OUTPUT);      // U-Speicher-Entleer-pin als output deklariert
        pinMode(pin_switch, OUTPUT);         // switch-pin als output deklariert
        pinMode(pin_test, OUTPUT);           // test-pin als output deklariert
            
        pinMode(pin_treffer, INPUT);         // treffer-pin als input deklariert
        pinMode(pin_reset, INPUT);           // reset-pin für die Anzeige als input deklariert
        
        
        digitalWrite(pin_entleeren, HIGH);   // U_max-Speicher entleeren
        digitalWrite(pin_switch, HIGH);      // Schalter für U-Zuleitung
        digitalWrite(pin_test, LOW);         // Test-pin auf 0 setzen
        
        
        for (int i = 0; i < 128; i++)
           {
            Pulshoehen[i] = 0;           // alle Pulshöhentreffer auf 0 setzen
           }
           
        Faktor = 1;         // Startvergrößerung für die graphische Darstellung
        
        reset_time = 5;     // Zeitdauer in ms der U-Max-Speicherentleerung
        
        
        
        #if FASTADC
        
        // set prescale to 16
        
        sbi(ADCSRA,ADPS2) ;      // ADPS2  auf  1  gesetzt
        cbi(ADCSRA,ADPS1) ;      // ADPS1  auf  0  gesetzt
        cbi(ADCSRA,ADPS0) ;      // ADPS0  auf  0  gesetzt
        
        // cbi = 0; sbi = 1
        
        #endif
        
        
        // Zeichnen der Achsen
        // ===================
        
        u8g.firstPage();
          
        do
           {
            u8g.drawLine(0, 63, 127, 63);
            u8g.drawLine(0, 0, 0, 63);          
           }
        while( u8g.nextPage() );
               
       }
       
       
       
    
    // ===================================
    // ========== HAUPTSCHLEIFE ==========
    // ===================================
    
    void loop(void)
       {
         /*
         Verzoegerung = analogRead(pin_verzoegerung);
         
         Verzoegerung = Verzoegerung * 10;   // Verzögerungsintervall 0 bis 1023 * 10 µs
         
         Serial.print("Verzoegerung im µs = ");
         Serial.println(Verzoegerung);
         */
                
         digitalWrite(pin_entleeren, HIGH);    // U_max-Speicher gelöscht
         delay(reset_time);                    // reset_time ms Wartezeit zum ausreichenden Löschen des U_max-Speichers
         digitalWrite(pin_entleeren, LOW);     // U_max-Speicher bereit
         
         digitalWrite(pin_switch, HIGH);       // Schalter für U-Zuleitung geschlossen; Messung startet... eigentlich unnötig, da ja eh der Kondensator gelöscht wird und auf den ersten Puls gewartet wird
             
         
         // Warte bis ein vom Monoflop verlängerter Puls über DIGITAL-IN registriert wird!
         // ==============================================================================
              
         while(digitalRead(pin_treffer) == LOW)
            {
            }
         
         
         
         //delayMicroseconds(Verzoegerung);    // übers Poti variable Verzögerung, damit der Zuleitungsschalter nicht schon schließt obwohl der Spannungspuls noch nicht sein Maximum erreicht hat!
         delayMicroseconds(10);                // fixe Verzögerung, damit der Zuleitungsschalter nicht zu früh schließt und der Spannungspuls auch zu seinem Maximum anwachsen kann!
         
         digitalWrite(pin_switch, LOW);      // Puls wurde registriert --> Schalter für U-Zuleitung offen; Messung gestoppt
              
         
         // Pulshöhe wird eingelesen
         // ========================     
         
         U_puls = analogRead(analogInPin);             // Einlesen der Pulshöhe 0-5V
         
         
         
         // digitale Ausgabe über den Test-Pin unmittelbar nach Einlesen der Spannung um festzustellen, "wo" in der Entladekurve die Spannung gemessen wird. Soll ja genau im Maximum erfolgen!
         // -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
         /*
         digitalWrite(pin_test, HIGH);      // Test-pin auf 1 setzen
         delay(5);                          // Verzögerung
         digitalWrite(pin_test, LOW);       // Test-pin auf 0 setzen     
         */
         
           
         
         // graphische und Speicher-Verarbeitung der registrierten Pulshöhe
         // ---------------------------------------------------------------
         
         Index = map(U_puls, 0, 1023, 0, 127);         // Index der aktuell gemessenen Pulshöhe im Intervall [0,127]
         
         Pulshoehen[Index] = Pulshoehen[Index] + 1;    // aktuelle Pulshöhe erhält einen Treffer
    
         //Spannung = U_puls * 5.0 / 1023;
         //Serial.print("Pulshoehe = ");                 // serielle Ausgabe der aktuellen Pulshöhe 0-5V
         //Serial.println(Spannung,2);      
    
    
    
         // ==============================================
         // ============ graphische Ausgabe ==============
         // ==============================================
          
         u8g.firstPage();
          
         if (int(Faktor * Pulshoehen[Index]) > 63)    // Zuviele Treffer für die ausreichende y-Darstellung --->  Stauchung um Faktor 2
            {
             Faktor = Faktor / 2; 
            }
        
         do
            {
             u8g.drawLine(0, 63, 127, 63);
             u8g.drawLine(0, 0, 0, 63);
            
             for (int i = 0; i < 128; i++)
                {
                 u8g.drawLine(0+i, 63, 0+i, 63 - int(Faktor * Pulshoehen[i]));     // zeichnen aller Treffer
                }        
            }
         while( u8g.nextPage() );
         
         
             
         // Abfrage, ob der Reset-Knopf betätigt wurde
         // ------------------------------------------
         
         if (digitalRead(pin_reset) == HIGH)
            {
             // Spektrum an den Computer senden
             // ===============================
              
             for (int i = 0; i < 128; i++)
                {
                 Serial.println(Pulshoehen[i]);
                }
    
            
             // Spektrum löschen
             // ================
             
             for (int i = 0; i < 128; i++)
                {
                 Pulshoehen[i] = 0;           // alle Pulshöhentreffer auf 0 setzen
                }
           
             Faktor = 1;         // Startvergrößerung für die graphische Darstellung 
            }
         
       
       
       //delay(2);   // optionale Zeitverzögerung
         
       }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •