Created
December 9, 2020 13:37
-
-
Save cibomahto/021a3b777d9fcc0ed1abbd077ac35076 to your computer and use it in GitHub Desktop.
plot.pde
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
// Modified sensor code for Arduino | |
#define bitSet(value, bit) ((value) |= (1UL << (bit))) | |
#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) | |
/* | |
* Macro Definitions | |
*/ | |
#define SPEC_TRG A0 | |
#define SPEC_ST A1 | |
#define SPEC_CLK A2 | |
#define SPEC_VIDEO A3 | |
#define WHITE_LED A4 | |
#define LASER_404 A5 | |
#define SPEC_CHANNELS 288 // New Spec Channel | |
uint16_t data[SPEC_CHANNELS]; | |
inline void __attribute__((always_inline)) clockPulse() { | |
// digitalWrite(SPEC_CLK, HIGH); | |
// delayMicroseconds(delayTime); | |
// digitalWrite(SPEC_CLK, LOW); | |
// delayMicroseconds(delayTime); | |
// see: https://docs.google.com/spreadsheets/d/1zFkrNUWS6-ow6kGBxUObfnzK1ZsuW7VK3vRO1FoV8fc/edit#gid=0 | |
bitSet(PORTF, PIN5); | |
bitClear(PORTF, PIN5); | |
} | |
void setup(){ | |
//Set desired pins to OUTPUT | |
pinMode(SPEC_CLK, OUTPUT); | |
pinMode(SPEC_ST, OUTPUT); | |
pinMode(LASER_404, OUTPUT); | |
pinMode(WHITE_LED, OUTPUT); | |
//digitalWrite(WHITE_LED, HIGH); // Set SPEC_CLK High | |
digitalWrite(SPEC_CLK, HIGH); // Set SPEC_CLK High | |
digitalWrite(SPEC_ST, LOW); // Set SPEC_ST Low | |
Serial.begin(115200); // Baud Rate set to 115200 | |
// Fast ADC clock (http://r6500.blogspot.com/2015/01/fast-adc-on-arduino-leonardo.html) | |
// ADCSRA=(ADCSRA&0xF80)|0x04; | |
} | |
/* | |
* This functions reads spectrometer data from SPEC_VIDEO | |
* Look at the Timing Chart in the Datasheet for more info | |
*/ | |
void readSpectrometer(){ | |
int delayTime = 1; // delay time | |
// Start clock cycle and set start pulse to signal start | |
digitalWrite(SPEC_CLK, LOW); | |
clockPulse(); | |
// digitalWrite(SPEC_ST, HIGH); | |
// delayMicroseconds(delayTime); | |
bitSet(PORTF, PIN6); | |
//Sample for a period of time | |
for(int i = 0; i < 2500; i++){ | |
clockPulse(); | |
} | |
//Set SPEC_ST to low | |
// digitalWrite(SPEC_ST, LOW); | |
bitClear(PORTF, PIN6); | |
//Sample for a period of time | |
for(int i = 0; i < 85; i++){ | |
clockPulse(); | |
} | |
//One more clock pulse before the actual read | |
clockPulse(); | |
//Read from SPEC_VIDEO | |
for(int i = 0; i < SPEC_CHANNELS; i++){ | |
data[i] = analogRead(SPEC_VIDEO); | |
clockPulse(); | |
} | |
digitalWrite(SPEC_CLK, HIGH); | |
delayMicroseconds(delayTime); | |
} | |
/* | |
* The function below prints out data to the terminal or | |
* processing plot | |
*/ | |
void printData(){ | |
for (int i = 0; i < SPEC_CHANNELS; i++){ | |
Serial.print(data[i]); | |
Serial.print(','); | |
} | |
Serial.print("\n"); | |
} | |
void loop(){ | |
readSpectrometer(); | |
printData(); | |
delay(10); | |
} | |
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
//Processing sketch to display data + simple peak detector | |
import processing.serial.*; | |
Serial myPort; | |
String val; | |
int[] data; | |
float[] summed; | |
int sum_count = 0; | |
boolean draw_sum = false; | |
final int dc_offset = 100; // Correct for the DC offset in the measurement | |
final int POINT_COUNT = 289; | |
// Given calibration data and a sample, determine the wavelength | |
float wavelength(int pix) { | |
// Note; Replace these with the values for your sensr | |
final double A0 = 3.062951791E+02; | |
final double B1 = 2.720613040E+00; | |
final double B2 = -1.302773396E-03; | |
final double B3 = -7.101037823E-06; | |
final double B4 = 8.279199710E-09; | |
final double B5 = 5.742926217E-12; | |
//wavelength resolution = 9.2nm | |
double wavelength = A0 + B1*pix + B2*(pix^2) + B3*(pix^3) + B4*(pix^4) + B5*(pix^5); | |
return (float)wavelength; | |
} | |
float val(int i) { | |
if(draw_sum) | |
return summed[i]/sum_count; | |
else | |
return data[i]; | |
} | |
void plotdata() | |
{ | |
if(sum_count == 0) | |
return; | |
background(0); | |
stroke(255); | |
for (int i=0; i<data.length-1; i++) { | |
line(i, height, i, height-val(i)); | |
} | |
final int window = 10; | |
final float noise_floor = 40; | |
int peak_count = 0; | |
stroke(255,0,0); | |
fill(255,0,0); | |
for (int i=window; i<(data.length-1-window); i++) { | |
boolean top = true; | |
for (int j = i-window; j < i+window; j++) { | |
if ((i != j) && (val(j) >= val(i))) { | |
top = false; | |
} | |
} | |
if (top && (val(i) > noise_floor)) { | |
ellipse(i, height-val(i),4,4); | |
text(wavelength(i), 20, 20+20*peak_count); | |
peak_count+=1; | |
} | |
} | |
} | |
void setup() | |
{ | |
println(Serial.list()); | |
String portName = Serial.list()[1]; //This is the index into the serial list, if you only have one serial device the index is 0 | |
myPort = new Serial(this, portName, 115200); | |
summed = new float[POINT_COUNT]; | |
for (int i = 0; i < POINT_COUNT; i++) | |
{ | |
summed[i] = 0; | |
} | |
// Processign design bug: can't use a constant here. | |
size(289, 750); | |
} | |
void draw() | |
{ | |
if ( myPort.available() <= 0) | |
return; | |
val = myPort.readStringUntil('\n'); // read it and store it in val | |
if (val == null) | |
return; | |
data = int(split(val, ',')); | |
for(int i = 0; i < data.length; i++) { | |
data[i] = data[i] - dc_offset; | |
} | |
// Discard first frame if it is the wrong size | |
if(data.length != POINT_COUNT) | |
return; | |
for (int i = 0; i < data.length; i++) { | |
if (i<summed.length) { | |
summed[i] += data[i]; | |
} | |
} | |
sum_count++; | |
plotdata(); | |
} | |
void keyPressed() { | |
if (key == 'c' ) | |
{ | |
for (int i = 0; i < summed.length; i++) | |
{ | |
summed[i] = 0; | |
} | |
sum_count = 0; | |
} else if (key == 't' ) | |
{ | |
draw_sum = !draw_sum; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment