Skip to content

Instantly share code, notes, and snippets.

@heborras
Last active October 12, 2017 10:00
Show Gist options
  • Save heborras/60d382e86f5c65be1923d49111610765 to your computer and use it in GitHub Desktop.
Save heborras/60d382e86f5c65be1923d49111610765 to your computer and use it in GitHub Desktop.
Development firmware for the CosmicPi V1.5
/*
Description:
Development firmware for the CosmicPi V1.5.
With this one can set the high voltage and thresholds for the detector on the fly, all while listening to events.
Usage:
Set sensible default values for:
The high voltage: HV_DEFAULT_VAL
Both thresholds: Thresh_default_val
Wether to use the DAC or the MAX5387 for thershold setting: useDAC
Compile and flash to Arduino DUE
Connect to the Arduino via serial (NOTE: Baudrate=115200)
Follow the interactive menue that prints out on start.
Current options are:
[1= set both thrsholds, 2= set HV, 3= reset event count]
Select one and input a value you want to test.
Then reset the counter and do your measurement.
Event count and time in ms will be printed on the screen.
Features:
Working:
Set HV
Set Threshold
Print out events
*/
#include <Wire.h>
#define LED1_pin 12 // green and lower one
#define LED2_pin 11 // red and upper one
#define TRIGOUT 5
#define STRIGBOUT A0
#define STRIGAOUT A5
#define MAX5387_PA0_pin A9
#define MAX5387_PA1_pin A10
#define MAX5387_PA2_pin A11
#define ref1_pin A1
#define ref2_pin A2
const int HV_MAX_VAL = 89;
const int HV_MIN_VAL = 255;
const byte HV_DEFAULT_VAL = 104;
const int Thresh_default_val = 1600;
const bool useDAC = true;
//set up the pins to remap SPI by hand
const int num_devices = 2;
const int SS_pin[num_devices] = {14, 15};
const int SCK_pin = 17;
const int MOSI_pin = 16;
byte thresh1;
byte thresh2;
unsigned long timemeasure;
unsigned long timeoffset;
float instarate;
unsigned long event_count = 0;
extern volatile unsigned long timer0_millis;
unsigned long new_value=0;
void setup() {
//setup analogue writemode
analogWriteResolution(12);
// setup pins
setPinModes();
setConstantPins();
attachInterrupt(digitalPinToInterrupt(TRIGOUT), [=] () {printTimeAndPin(TRIGOUT, "SiPM_c");}, RISING);
// setup serial comm
Serial.begin(115200);
// setup initial thresholds
if (useDAC){
Serial.print("Setting thresholds to: ");
Serial.println(Thresh_default_val);
analogWrite(DAC0, Thresh_default_val);
analogWrite(DAC1, Thresh_default_val);
} else {
setThreshold(1, Thresh_default_val);
setThreshold(2, Thresh_default_val);
}
// set HV to default
Serial.print("Setting HV to: ");
Serial.println(HV_DEFAULT_VAL);
bitBang(HV_DEFAULT_VAL);
timeoffset = 0;
}
void loop() {
Serial.println("Input a command!");
Serial.println("[1= set both thrsholds, 2= set HV, 3= reset event count]");
int cmd = readIntFromSerial();
switch(cmd){
case 1:
{
Serial.println("Set a threshold value [1,4096]: ");
int value = readIntFromSerial();
if (useDAC){
Serial.print("Setting both thresholds to: ");
Serial.println(value);
analogWrite(DAC0, value);
analogWrite(DAC1, value);
} else {
setThreshold(3, value);
}
break;
}
case 2:
{
Serial.println("Input a voltage value [1=highest,255=lowest]");
byte sendValue = (byte) readIntFromSerial();
if (sendValue < HV_MAX_VAL){
Serial.print("HV Value is too high! Setting HV to:");
Serial.println(HV_MAX_VAL);
bitBang(HV_MAX_VAL); // Transmit data
} else{
Serial.print("Setting HV to:");
Serial.println(sendValue);
bitBang(sendValue); // Transmit data
}
break;
}
case 3:
event_count = 0;
timeoffset = millis();
Serial.println("Event counter and timer set to 0!");
break;
}
}
void setPinModes(){
// I2C adress pins for the MAX5387
pinMode(MAX5387_PA0_pin, OUTPUT);
pinMode(MAX5387_PA1_pin, OUTPUT);
pinMode(MAX5387_PA2_pin, OUTPUT);
// Analoge input pins form the threshold
pinMode(ref1_pin, INPUT);
pinMode(ref2_pin, INPUT);
// status LEDs
pinMode(LED1_pin, OUTPUT);
pinMode(LED2_pin, OUTPUT);
// trigger pins
pinMode(TRIGOUT, INPUT);
// HV pins
digitalWrite(SS, HIGH); // Start with SS high
for (int i=0; i<num_devices; i++){
pinMode(SS_pin[i], OUTPUT);
digitalWrite(SS_pin[i], HIGH);
}
pinMode(SCK_pin, OUTPUT);
//pinMode(MISO_pin, INPUT); //this is the avalanche pin, not implemented yet
pinMode(MOSI_pin, OUTPUT);
}
void setConstantPins(){
// I2C adress pins for the MAX5387
digitalWrite(MAX5387_PA0_pin, LOW);//configure the address of the MAX5387 pot
digitalWrite(MAX5387_PA1_pin, LOW);//configure the address of the MAX5387 pot
digitalWrite(MAX5387_PA2_pin, LOW);//configure the address of the MAX5387 pot
}
// this function sets the thresholds for the MAX5387
// 1 is the first channel, 2 the second and 3 sets both at the same time
void setThreshold(int pot_channel, int value){
// do a value check
if (value > 255 || value < 1){
return;
} else {
value = byte(value);
}
Wire.begin();
Wire.beginTransmission(byte(0x28)); // transmit to device #112
switch(pot_channel){
case 1:
Serial.print("Setting channel 1 to: ");
Serial.println(value);
Wire.write(byte(B00010001)); //sets value to the first channel
Wire.write(value);
thresh1 = value;
break;
case 2:
Serial.print("Setting channel 2 to: ");
Serial.println(value);
Wire.write(byte(B00010010)); //sets value to the second channel
Wire.write(value);
thresh2 = value;
break;
case 3:
Serial.print("Setting both channels channel to: ");
Serial.println(value);
Wire.write(byte(B00010011)); //sets value to both channels
Wire.write(value);
thresh1 = value;
thresh2 = value;
break;
}
Wire.endTransmission();
}
byte bitBang(byte _send) // This function is what bitbangs the data
{
//reception isn't implemented in this version.
//byte _receive = 0;
for(int j=0; j<num_devices; j++){
digitalWrite(SS_pin[j], LOW); // SS low
for(int i=0; i<8; i++) // There are 8 bits in a byte
{
digitalWrite(MOSI_pin, bitRead(_send, 7-i)); // Set MOSI
//delay(1);
digitalWrite(SCK_pin, HIGH); // SCK high
//bitWrite(_receive, i, digitalRead(MISO_pin)); // Capture MISO
digitalWrite(SCK_pin, LOW); // SCK low
//digitalWrite(MOSI_pin, LOW); // Set MOSI
}
digitalWrite(SS_pin[j], HIGH); // SS high again
}
//return _receive; // Return the received data
}
void printTimeAndPin(int pin, String name){
// print when and which pin was interrupted
event_count++;
Serial.print(name);
Serial.print(";count=");
Serial.print(event_count);
Serial.print(";time=");
timemeasure=millis();
Serial.println(timemeasure-timeoffset);
/* This code works out the instant rate and prints it as well. more likely to cause crashes as it's in the interrupt.
Serial.print(";time=");
timemeasure = millis();
Serial.print(timemeasure);
Serial.print(";rate=");
instarate = ((event_count*1000)/timemeasure);
Serial.println(instarate);
*/
}
int readIntFromSerial(){
int val = Serial.parseInt();
while (val == 0){
delay(100);
val = Serial.parseInt();
}
return val;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment