Last active
October 12, 2017 10:00
-
-
Save heborras/60d382e86f5c65be1923d49111610765 to your computer and use it in GitHub Desktop.
Development firmware for the CosmicPi V1.5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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