experiment using the Teensy 3.6 as a MCA

Gamma spectacular, theremino adapters, non-sound card based, etc...
Post Reply
Conor Whyte
Posts: 46
Joined: 28 Apr 2019, 15:06
Contact:

experiment using the Teensy 3.6 as a MCA

Post by Conor Whyte » 24 Jun 2019, 17:29

Hello, I have been playing around with the GS-USB-PRO and I came across this little gem of a program for a single board computer known as the Teensy 3.6

It is design to pull incoming pulses off its internal ADC. The ADC clock is 18Mhz @ 16bits.

Pins 13,14 and 15 are used... Pin 13 in the pulse collector, 14 and 15 are interrupts..

Details of the build come from here https://forum.pjrc.com/threads/25321-Te ... +analyzer


The code below works and
i have been playing with it. I have overclocked my Teensy to 240Mhz.
I am right now debugging the peak detector/

More coming soon. High voltage is being supplied by the GS-PRO-USB and works well.

Code: Select all

// __MK66FX1M0__ = Teensy 3.6
#ifndef __MK66FX1M0__
  #error This code is for Teensy 3.6!
#endif

// Assumes Teensy 3.1

// Result from ADC
int ADC_res;

void setup() {
  // Prepare USB connection
  Serial.begin(0);
  
  // Prepare output signal
  pinMode(13, OUTPUT);
  
  // Prepare reset signal
  pinMode(15, OUTPUT);
  
  // Prepare intterrupt signal
  pinMode(14, INPUT);
  attachInterrupt(14, processData, RISING);
  
  // Configure ADC
  /*  DEFAULT
      0       ADLPC (Low-Power Configuration)
      0       ADIV (Clock Divide Select)
      0
      0       ADLSMP (Sample time configuration)
      0       MODE (Conversion mode selection) (00=8/9, 01=12/13, 10=10/11, 11=16/16 bit; diff=0/1)
      0
      0       ADICLK (Input Clock Select)
      0
  */
  ADC0_CFG1 = 0b00011000;
  
  /*  DEFAULT
      0       MUXSEL (ADC Mux Select)
      0       ADACKEN (Asynchrononous Clock Output Enable)
      0       ADHSC (High-Speed Configuration)
      0       ADLSTS (Long Sample Time Select) (00=+20 cycles, 01=+12, 10=+6, 11=+2)
      0
  */
  ADC0_CFG2 = 0b00000;
  
  /*  DEFAULT
      0       ADTRG (Conversion Trigger Select)
      0       ACFE (Compare Function Enable)
      0       ACFGT (Compare Function Greater than Enable)
      0       ACREN (Compare Function Range Enable)
      0       ACREN (COmpare Function Range Enable)
      0       DMAEN (DMA Enable)
      0       REFSEL (Voltage Reference Selection) (00=default,01=alternate,10=reserved,11=reserved)
  */
  ADC0_SC2 = 0b0000000;
  
  /*  DEFAULT
      0       CAL (Calibration)
      0       CALF (read only)
      0       (Reserved)
      0
      0       ADCO (Continuous Conversion Enable)
      0       AVGS (Hardware Average Enable)
      0       AVGS (Hardware Average Select) (00=4 times, 01=8, 10=16, 11=32)
      0
  */
  ADC0_SC3 = 0b10000111;
  
  // Waiting for calibration to finish. The documentation is confused as to what flag to be waiting for (SC3[CAL] on page 663 and SC1n[COCO] on page 687+688).
  while (ADC0_SC3 & ADC_SC3_CAL) {}
  
  // Apply calibration data (code from officiel Teensy library)
  /* Teensyduino Core Library
  * http://www.pjrc.com/teensy/
  * Copyright (c) 2013 PJRC.COM, LLC.
  
  \teensy\cores\teensy3\analog.c
  */
  uint16_t sum;
  sum = ADC0_CLPS + ADC0_CLP4 + ADC0_CLP3 + ADC0_CLP2 + ADC0_CLP1 + ADC0_CLP0;
  sum = (sum / 2) | 0x8000;
  ADC0_PG = sum;
  sum = ADC0_CLMS + ADC0_CLM4 + ADC0_CLM3 + ADC0_CLM2 + ADC0_CLM1 + ADC0_CLM0;
  sum = (sum / 2) | 0x8000;
  ADC0_MG = sum;
  /* End of borrowed code */
}

void loop() {
}

void processData() {
  // Wait for signal to reach peak
  delayMicroseconds(15);
  
  // DEBUG: Signal HIGH that ADC and then USB will be running
  //GPIOC_PDOR |= 1<<5;
  
  // Start ADC
  /*  DEFAULT
      0       AIEN (Interrupt Enable)
      0       DIFF (0=single, 1=diff)
      1       ADCH (00000=A10 for DIFF=0; 00000=A10+A11 for DIFF=1; See page 98 in documentation)
      1
      1
      1
      1
  */
  ADC0_SC1A = 0b0000000;
  
  // Wait for ADC
  while (!(ADC0_SC1A & ADC_SC1_COCO)) {}
  
  // Retrieve data from ADC
  ADC_res = ADC0_RA;
  
  // Send data away
  Serial.println( ADC_res );
  Serial.send_now();
  
  // Set RESET signal to HIGH for 1 µs
  GPIOC_PDOR |= 1; // 1 = 1<<0
  delayMicroseconds(1);
  
  // DEBUG: Signal LOW that ADC and USB are done (takes ~40 µs with max cycles and sampling at 16 bit)
  // And set RESET signal to LOW
  //GPIOC_PDOR &= ~(1<<5 | 1);
  GPIOC_PDOR &= ~1;
}
The reset signal opens a MOSFET that short circuits the capacitor holding the signal from the peak detector.

https://imgur.com/a/Qmkuw

Conor Whyte
Posts: 46
Joined: 28 Apr 2019, 15:06
Contact:

Re: experiment using the Teensy 3.6 as a MCA

Post by Conor Whyte » 28 Jun 2019, 00:49

Here is the additional circuit for the pulse processing.
UY2f6vq.png
UY2f6vq.png (46.1 KiB) Viewed 583 times

stamasd
Posts: 93
Joined: 29 Oct 2017, 02:12
Contact:

Re: experiment using the Teensy 3.6 as a MCA

Post by stamasd » 28 Jun 2019, 01:57

This is very interesting. I've been playing recently with some STM32F103-based boards and ESP32 boards. I wonder if those would be usable too - especially the latter. The main difference as far as signal acquisition is the ADC which is 12-bit instead of 16. I see you use 10 bits only for the conversion so it should translate to these boards too.
Real name: Silviu Tamasdan

Conor Whyte
Posts: 46
Joined: 28 Apr 2019, 15:06
Contact:

Re: experiment using the Teensy 3.6 as a MCA

Post by Conor Whyte » 29 Jun 2019, 15:29

There is apparently an issue when going to 16bits as the ADC conversion at 40µSec starts to randomly artifact the output.
I was told to drop it to 10 bits and the artifacting is no longer an issue.

stamasd
Posts: 93
Joined: 29 Oct 2017, 02:12
Contact:

Re: experiment using the Teensy 3.6 as a MCA

Post by stamasd » 30 Jun 2019, 03:00

Do you mind if I steal some of the above? I'll try to make something similar with an ESp32 board for SiPM data acquisition. I'll probably use opamps with higher speed than the venerable TL072. Thinking OPA354 or 356, inspired by http://physicsopenlab.org/2017/11/28/fr ... -for-sipm/
Real name: Silviu Tamasdan

Conor Whyte
Posts: 46
Joined: 28 Apr 2019, 15:06
Contact:

Re: experiment using the Teensy 3.6 as a MCA

Post by Conor Whyte » 30 Jun 2019, 09:36

This is not my code. This code posted above was modified by me to run on the more powerful Teensy 3.6 instead of the 3.1. The orginal was actually posted on the teensy PJRC forum back in 2014 by a fellow doing Alpha spectroscopy. I contacted him.
The input code is being modified to run on MATLAB 2019a .. .the graphing code has a few issues still that I am unsure about, though stock it'll run on MATLAB 2016b without issue.

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests