-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
24 changed files
with
2,194 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#include "c12880.h" | ||
|
||
#define SPEC_TRG A0 // ADC signal trigger to microcontroller | ||
#define SPEC_ST A1 // Sensor start pulse from microcontroller | ||
#define SPEC_CLK A2 // Sensor clock from microcontroller | ||
#define SPEC_VIDEO A3 // Sensor signal, buffered, low impedance to microcontroller | ||
#define SPEC_EOS A4 // Sensor End of Scan, not connected yet, to microcontroller | ||
#define FLASH_TRIGGER A5 // Light on/off from microcontroller | ||
|
||
/* | ||
ST Cycle minimum length is 381/f_clk | ||
ST High period minimum 6/f_clk | ||
ST Low perdiod minimum 375/f_clk | ||
ST Low is start configuration | ||
ST High starts sequence | ||
Integration starts at 4th clock cycle | ||
ST Low | ||
Integration finishes 51 cycles after ST switched to low | ||
Integration time is ST high length plus 48 clks | ||
Signal appears at 89th pulse and continues 288 pulses | ||
*/ | ||
|
||
IntervalTimer flashTimer; | ||
|
||
uint16_t spectrum[C12880_NUM_CHANNELS]; | ||
|
||
C12880 c12880(SPEC_TRG,SPEC_ST,SPEC_CLK,SPEC_VIDEO); | ||
|
||
/******************************************************************************/ | ||
void setup(){ | ||
|
||
pinMode(FLASH_TRIGGER,OUTPUT); | ||
digitalWrite(FLASH_TRIGGER,LOW); | ||
|
||
while (!Serial && millis() < 3000) ; | ||
Serial.begin(Serial.baud()); | ||
Serial.setTimeout(1); // Serial read timeout | ||
printHelp(); | ||
|
||
memset((void*)spectrum, 0, sizeof(spectrum)); | ||
c12880.begin(); | ||
|
||
} | ||
|
||
/******************************************************************************/ | ||
char inBuff[] = "----------------"; | ||
int bytesread; | ||
String value = "0.01"; | ||
String command = "o"; | ||
float integrationTime = 0.01; | ||
float triggerTime = 0.01; | ||
bool continous = false; | ||
bool BINARY = false; | ||
|
||
void loop(){ | ||
if (Serial.available()) { | ||
bytesread=Serial.readBytesUntil('\n', inBuff, 16); // Read from serial until CR is read or timeout exceeded | ||
inBuff[bytesread]='\0'; | ||
String instruction = String(inBuff); | ||
processInstruction(instruction); | ||
} | ||
if (continous) { | ||
c12880.read(spectrum); | ||
transmitSpectrum(spectrum); | ||
} else { | ||
delay(10); | ||
} | ||
} | ||
|
||
/******************************************************************************/ | ||
// SerialCommand handlers | ||
|
||
void processInstruction(String instruction) { | ||
int instructionLength = instruction.length(); | ||
if (instructionLength > 0) { command = instruction.substring(0,1); } | ||
if (instructionLength > 1) { value = instruction.substring(1,instructionLength); } | ||
//Serial.println(command); | ||
//Serial.println(value); | ||
|
||
if (command =='I') { // set integration Time | ||
integrationTime = value.toFloat(); | ||
if ((integrationTime < 0.0) || (integrationTime > 9999.99)) { Serial.println("Integration time out of valid Range"); } | ||
c12880.set_integration_time(integrationTime); | ||
Serial.printf("Integratin time is: %g\n", integrationTime); | ||
} else if (command =='i') { // display integration time | ||
Serial.printf("Integration time is: %g\n", integrationTime); | ||
|
||
} else if (command == "f") { // turn off flash | ||
Serial.printf("Flash is off\n"); | ||
} else if (command == "F") { // turn on flash | ||
int trig_micros = (int)(triggerTime*1e6); | ||
trig_micros = constrain(trig_micros,25,10000000); | ||
flashTimer.begin(flash_trigger, trig_micros); | ||
Serial.println("Flash is on\n"); | ||
|
||
} else if (command == "b") { // verbose | ||
BINARY = false; | ||
Serial.printf("Verbose is on\n"); | ||
} else if (command == "B") { // binary | ||
BINARY = true; | ||
Serial.println("Binary is on\n"); | ||
|
||
} else if (command == "r") { // readout once | ||
continous = false; | ||
c12880.read(spectrum); | ||
transmitSpectrum(spectrum); | ||
} else if (command == "R") { // readout continous | ||
continous = true; | ||
} else { // invalid input, display status | ||
printHelp(); | ||
|
||
} // end if else switch | ||
} | ||
|
||
void printHelp() { | ||
Serial.println("C12880 Controller"); | ||
Serial.println("================="); | ||
Serial.println("Set Intergation time: I0.01"); | ||
Serial.println("Show Integration time: i"); | ||
Serial.println("Use/Dont use flash: F/f"); | ||
Serial.println("Use/Dont use binary: B/b"); | ||
Serial.println("Read one spectrum: r"); | ||
Serial.println("Read continous spectra: R"); | ||
} | ||
|
||
void transmitSpectrum(uint16_t *data) { | ||
size_t i; | ||
if (BINARY) { | ||
for (i = 0; i < C12880_NUM_CHANNELS; i++) { | ||
Serial.write( (byte *) &data[i], sizeof(data[i])); | ||
} | ||
} else { | ||
for (i = 0; i < C12880_NUM_CHANNELS; i++) { | ||
Serial.printf("%d, ",data[i]); | ||
} | ||
} | ||
Serial.write('\n'); | ||
} | ||
|
||
void flash_trigger(){ | ||
digitalWrite(FLASH_TRIGGER,HIGH); | ||
flashTimer.end(); | ||
digitalWrite(FLASH_TRIGGER,LOW); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# arduino-microspec | ||
Arduino firmware for Hamamatsu C12880 microspectrometer |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
#include <SerialCommand.h> /* http://github.com/p-v-o-s/Arduino-SerialCommand */ | ||
#include <ADC.h> /* https://github.com/pedvide/ADC */ | ||
#include "c12880.h" | ||
|
||
#define SPEC_TRG A0 // ADC signal trigger to microcontroller | ||
#define SPEC_ST A1 // Sensor start pulse from microcontroller | ||
#define SPEC_CLK 10 // Sensor clock from microcontroller | ||
#define SPEC_VIDEO A3 // Sensor signal, buffered, low impedance to microcontroller | ||
#define SPEC_EOS // Sensor End of Scan, not connected yet, to microcontroller | ||
#define FLASH_TRIGGER 12 // Light on/off from microcontroller | ||
|
||
/* | ||
ST Cycle minimum length is 381/f_clk | ||
ST High period minimum 6/f_clk | ||
ST Low perdiod minimum 375/f_clk | ||
ST Low is start configuration | ||
ST High starts sequence | ||
Integration starts at 4th clock cycle | ||
ST Low | ||
Integration finishes 51 cycles after ST switched to low | ||
Integration time is ST high length plus 48 clks | ||
Signal appears at 89th pulse and continues 288 pulses | ||
*/ | ||
|
||
IntervalTimer flashTimer; | ||
|
||
uint16_t data[C12880_NUM_CHANNELS]; | ||
|
||
C12880_Class spec(SPEC_TRG,SPEC_ST,SPEC_CLK,SPEC_VIDEO); | ||
|
||
SerialCommand sCmd(Serial);// the SerialCommand parser object | ||
/******************************************************************************/ | ||
void setup(){ | ||
pinMode(FLASH_TRIGGER,OUTPUT); | ||
digitalWrite(FLASH_TRIGGER,LOW); | ||
Serial.begin(115200); // Baud Rate set to 115200 | ||
|
||
// Setup callbacks for SerialCommand commands | ||
sCmd.setDefaultHandler(UNRECOGNIZED_sCmd_default_handler); | ||
sCmd.addCommand("SPEC.INTEG", SPEC_INTEG_sCmd_config_handler); //configures integration time | ||
sCmd.addCommand("SPEC.READ?", SPEC_READ_sCmd_query_handler); //reads out the whole spectrum | ||
sCmd.addCommand("SPEC.TIMING?", SPEC_TIMING_sCmd_query_handler); //reads out timings | ||
sCmd.addCommand("FLASH.TIMER_ONCE!", FLASH_TIMER_ONCE_sCmd_action_handler); //set flash to trigger on microsecond delay | ||
spec.begin(); | ||
|
||
} | ||
/******************************************************************************/ | ||
void loop(){ | ||
int num_bytes = sCmd.readSerial(); // fill the buffer | ||
if (num_bytes > 0){ | ||
sCmd.processCommand(); // process the command | ||
} | ||
delay(10); | ||
} | ||
|
||
/******************************************************************************/ | ||
// SerialCommand handlers | ||
|
||
// Unrecognized command | ||
void UNRECOGNIZED_sCmd_default_handler(SerialCommand this_sCmd) | ||
{ | ||
SerialCommand::CommandInfo command = this_sCmd.getCurrentCommand(); | ||
this_sCmd.print(F("### Error: command '")); | ||
this_sCmd.print(command.name); | ||
this_sCmd.print(F("' not recognized ###\n")); | ||
} | ||
|
||
void SPEC_INTEG_sCmd_config_handler(SerialCommand this_sCmd){ | ||
char *arg = this_sCmd.next(); | ||
float integ_time; | ||
if (arg == NULL){ | ||
this_sCmd.print(F("### Error: SPEC.INTEG requires 1 argument 'time' (s)\n")); | ||
} | ||
else{ | ||
integ_time = atof(arg); | ||
spec.set_integration_time(integ_time); | ||
} | ||
} | ||
|
||
void SPEC_READ_sCmd_query_handler(SerialCommand this_sCmd){ | ||
spec.read_into(data); | ||
for (int i = 0; i < C12880_NUM_CHANNELS - 1; i++){ | ||
this_sCmd.print(data[i]); | ||
this_sCmd.print(','); | ||
} | ||
//last value gets special formatting | ||
this_sCmd.print(data[C12880_NUM_CHANNELS - 1]); | ||
this_sCmd.print("\n"); | ||
} | ||
|
||
void SPEC_TIMING_sCmd_query_handler(SerialCommand this_sCmd){ | ||
for(int i=0; i < 9; i++){ | ||
this_sCmd.print(spec.get_timing(i)); | ||
this_sCmd.print(","); | ||
} | ||
this_sCmd.print(spec.get_timing(9)); | ||
this_sCmd.print("\n"); | ||
} | ||
|
||
void FLASH_TIMER_ONCE_sCmd_action_handler(SerialCommand this_sCmd){ | ||
char *arg = this_sCmd.next(); | ||
float trig_time; | ||
if (arg == NULL){ | ||
this_sCmd.print(F("### Error: FLASH.TIMER_ONCE! requires 1 argument 'time' (s)\n")); | ||
} | ||
else{ | ||
trig_time = atof(arg); | ||
trig_time = max(25e-6,trig_time); | ||
int trig_micros = (int)(trig_time*1e6); | ||
trig_micros = constrain(trig_micros,25,10000000); | ||
flashTimer.begin(flash_trigger, trig_micros); | ||
} | ||
} | ||
|
||
void flash_trigger(){ | ||
digitalWrite(FLASH_TRIGGER,HIGH); | ||
flashTimer.end(); | ||
digitalWrite(FLASH_TRIGGER,LOW); | ||
} |
Oops, something went wrong.