-
Notifications
You must be signed in to change notification settings - Fork 3
/
lasershow.cpp
100 lines (84 loc) · 2.92 KB
/
lasershow.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdexcept>
#include <time.h>
#include <unistd.h>
#include <iostream>
#include <string>
#include <chrono>
#include <wiringPi.h>
#include "ABE_ADCDACPi.h"
#include "Points.h"
#include "IldaReader.h"
using namespace std;
using namespace ABElectronics_CPP_Libraries;
void onInterrupt(int);
int main(int argc, char **argv) {
// Validate arguments.
if (argc < 3) {
cout << "ERROR: Arguments missing." << endl;
cout << "Required: [pointDelay] [fileName]" << endl;
return 1;
}
// Read arguments.
int pointDelay = atoi(argv[1]);
string fileName = argv[2];
double frameDuration = 0.033; // ~30fps (1/30=0.033..).
// Setup hardware communication stuff.
wiringPiSetup();
ADCDACPi adcdac;
// Control laser diode on wiringPi pin 0 (GPIO17, D1, header pin 11).
pinMode(0, OUTPUT);
// Open the DAC SPI channel.
if (adcdac.open_dac() != 1) return(1);
// Set the DAC gain to 1 which will give a voltage range of 0 to 2.048V.
adcdac.set_dac_gain(1);
// Setup ILDA reader.
Points points;
IldaReader ildaReader;
if (ildaReader.readFile(fileName)) {
printf("Provided file is a valid ILDA file.\n");
ildaReader.getNextFrame(&points);
printf("Points loaded in first frame: %d\n", points.size);
} else {
printf("Error opening ILDA file.\n");
return(1);
}
// Subscribe program to exit/interrupt signal.
signal(SIGINT, onInterrupt);
// Start the scanner loop with the current time.
std::chrono::time_point<std::chrono::system_clock> start = std::chrono::system_clock::now();
while(true) {
// Exit if no points found.
if (points.size == 0) break;
// Move galvos to x,y position. (4096 is to invert horizontally)
adcdac.set_dac_raw(4096-points.store[points.index*3],1);
adcdac.set_dac_raw(points.store[(points.index*3)+1],2);
// Turn on/off laser diode.
if (points.store[(points.index*3)+2] == 1) digitalWrite(0, HIGH);
else digitalWrite(0, LOW);
// Maybe wait a while there.
if (pointDelay > 0) usleep(pointDelay);
// In case there's no more points in the current frame check if it's time to load next frame.
if (!points.next()) {
std::chrono::duration<double> elapsedSeconds = std::chrono::system_clock::now() - start;
if(elapsedSeconds.count() > frameDuration) {
start = std::chrono::system_clock::now();
digitalWrite(0, LOW);
ildaReader.getNextFrame(&points);
}
}
}
// Cleanup and exit.
ildaReader.closeFile();
adcdac.close_dac();
return (0);
}
// Function that is called when program needs to be terminated.
void onInterrupt(int) {
printf("Turn off laser diode.\n");
digitalWrite(0, LOW);
printf("Program was interrupted.\n");
exit(1);
}