save loops

Dependencies:   mbed

Committer:
mbedalvaro
Date:
Tue Dec 02 04:39:15 2014 +0000
Revision:
0:df6fdd9b99f0
this new version of skinGames will have a function that stops scanning as the laser reaches the same position (i.e., loops) with a certain precision. It is for extracting contours for Takashita project. It can then save on a file or send on osc

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedalvaro 0:df6fdd9b99f0 1 #include "hardwareIO.h"
mbedalvaro 0:df6fdd9b99f0 2
mbedalvaro 0:df6fdd9b99f0 3 HardwareIO IO; // preintantiation of cross-file global object IO
mbedalvaro 0:df6fdd9b99f0 4
mbedalvaro 0:df6fdd9b99f0 5 // -------------------------------------- (0) SETUP ALL IO (call this in the setup() function in main program)
mbedalvaro 0:df6fdd9b99f0 6
mbedalvaro 0:df6fdd9b99f0 7 Serial pc(USBTX, USBRX); // tx, rx
mbedalvaro 0:df6fdd9b99f0 8 LocalFileSystem local("local"); // Create the local filesystem under the name "local"
mbedalvaro 0:df6fdd9b99f0 9
mbedalvaro 0:df6fdd9b99f0 10 SPI spiDAC(MOSI_PIN, MISO_PIN, SCK_PIN); // mosi, miso, sclk
mbedalvaro 0:df6fdd9b99f0 11 DigitalOut csDAC(CS_DAC_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 12
mbedalvaro 0:df6fdd9b99f0 13 DigitalOut Laser_Red(LASER_RED_PIN); // NOTE: this is NOT the lock in sensing laser (actually, not used yet)
mbedalvaro 0:df6fdd9b99f0 14 DigitalOut Laser_Green(LASER_GREEN_PIN);
mbedalvaro 0:df6fdd9b99f0 15 DigitalOut Laser_Blue(LASER_BLUE_PIN);
mbedalvaro 0:df6fdd9b99f0 16
mbedalvaro 0:df6fdd9b99f0 17 // Some manual controls over the hardware function:
mbedalvaro 0:df6fdd9b99f0 18 InterruptIn switchOne(SWITCH_ONE);
mbedalvaro 0:df6fdd9b99f0 19 InterruptIn switchTwo(SWITCH_TWO);
mbedalvaro 0:df6fdd9b99f0 20 AnalogIn ainPot(POT_ANALOG_INPUT);
mbedalvaro 0:df6fdd9b99f0 21 //DigitalIn RotaryEncoderPinA(ROTARY_ENCODER_PINA); // not needed: this is done in the CRotaryEncoder library (as input or interrupt)
mbedalvaro 0:df6fdd9b99f0 22 //DigitalIn RotaryEncoderPinB(ROTARY_ENCODER_PINB);
mbedalvaro 0:df6fdd9b99f0 23
mbedalvaro 0:df6fdd9b99f0 24 DigitalIn twoStateSwitch(TWO_STATE_SWITCH);
mbedalvaro 0:df6fdd9b99f0 25
mbedalvaro 0:df6fdd9b99f0 26 void HardwareIO::init(void) {
mbedalvaro 0:df6fdd9b99f0 27
mbedalvaro 0:df6fdd9b99f0 28 // Set laser powers down:
mbedalvaro 0:df6fdd9b99f0 29 setRedPower(0);// TTL red laser (not used - actually not present)
mbedalvaro 0:df6fdd9b99f0 30 setGreenPower(0);
mbedalvaro 0:df6fdd9b99f0 31 setBluePower(0);
mbedalvaro 0:df6fdd9b99f0 32
mbedalvaro 0:df6fdd9b99f0 33 //Serial Communication setup:
mbedalvaro 0:df6fdd9b99f0 34 pc.baud(115200);//
mbedalvaro 0:df6fdd9b99f0 35 //pc.printf("Serial Connection established \r\n");
mbedalvaro 0:df6fdd9b99f0 36 // pc.baud(921600);//115200);//
mbedalvaro 0:df6fdd9b99f0 37
mbedalvaro 0:df6fdd9b99f0 38 // Setup for lock-in amplifier and pwm references:
mbedalvaro 0:df6fdd9b99f0 39 setLaserLockinPower(1);// actually this is the Red laser in the hardware
mbedalvaro 0:df6fdd9b99f0 40 lockin.init();
mbedalvaro 0:df6fdd9b99f0 41
mbedalvaro 0:df6fdd9b99f0 42 // Setup for DAC control to move the mirrors:
mbedalvaro 0:df6fdd9b99f0 43 // Set spi for 8 bit data, high steady state clock,
mbedalvaro 0:df6fdd9b99f0 44 // second edge capture, with a 10MHz clock rate:
mbedalvaro 0:df6fdd9b99f0 45 csDAC = 1;
mbedalvaro 0:df6fdd9b99f0 46 spiDAC.format(16,0);
mbedalvaro 0:df6fdd9b99f0 47 spiDAC.frequency(16000000);
mbedalvaro 0:df6fdd9b99f0 48
mbedalvaro 0:df6fdd9b99f0 49 // default initial mirror position:
mbedalvaro 0:df6fdd9b99f0 50 writeOutX(CENTER_AD_MIRROR_X);
mbedalvaro 0:df6fdd9b99f0 51 writeOutY(CENTER_AD_MIRROR_Y);
mbedalvaro 0:df6fdd9b99f0 52
mbedalvaro 0:df6fdd9b99f0 53 // Rotary encoder 1 (to set the FIXED THRESHOLD VALUE):
mbedalvaro 0:df6fdd9b99f0 54 rotaryEncoder1.SetMinMax(0,255);
mbedalvaro 0:df6fdd9b99f0 55 rotaryEncoder1.Set(0); // initial value
mbedalvaro 0:df6fdd9b99f0 56
mbedalvaro 0:df6fdd9b99f0 57 // Rotary encoder 2 (to set the additional correction angle):
mbedalvaro 0:df6fdd9b99f0 58 rotaryEncoder2.SetMinMax(-10,10);
mbedalvaro 0:df6fdd9b99f0 59 rotaryEncoder2.Set(0); // initial value
mbedalvaro 0:df6fdd9b99f0 60
mbedalvaro 0:df6fdd9b99f0 61 // Load LUT table:
mbedalvaro 0:df6fdd9b99f0 62 setLUT();
mbedalvaro 0:df6fdd9b99f0 63
mbedalvaro 0:df6fdd9b99f0 64 // Set interrupts on RAISING edge for button-switch functions:
mbedalvaro 0:df6fdd9b99f0 65 // Note: The pin input will be logic '0' for any voltage on the pin below 0.8v, and '1' for any voltage above 2.0v.
mbedalvaro 0:df6fdd9b99f0 66 // By default, the InterruptIn is setup with an internal pull-down resistor, but for security and clarity I will do it explicitly here:
mbedalvaro 0:df6fdd9b99f0 67 switchOne.mode(PullUp); // pull down seems not very good
mbedalvaro 0:df6fdd9b99f0 68 switchTwo.mode(PullUp);
mbedalvaro 0:df6fdd9b99f0 69 switchOne.fall(this, &HardwareIO::switchOneInterrupt); // attach the address of the flip function to the falling edge
mbedalvaro 0:df6fdd9b99f0 70 switchTwo.fall(this, &HardwareIO::switchTwoInterrupt); // attach the address of the flip function to the falling edge
mbedalvaro 0:df6fdd9b99f0 71 switchOneState=true;
mbedalvaro 0:df6fdd9b99f0 72 switchTwoState=false;
mbedalvaro 0:df6fdd9b99f0 73 switchOneChange=false;
mbedalvaro 0:df6fdd9b99f0 74 switchTwoChange=false;
mbedalvaro 0:df6fdd9b99f0 75
mbedalvaro 0:df6fdd9b99f0 76 // ATTENTION: initial state of the switch should correspond to the inital state of the threshold mode in the constructor of the laser trajectory objects (not nice):
mbedalvaro 0:df6fdd9b99f0 77 setSwitchOneState(true); //equal to switchOneState=true, plus set led value. False means fixed threshold, true AUTO THRESHOLD (will be the default mode)
mbedalvaro 0:df6fdd9b99f0 78 // NOTE: actually this interrupt switches are not used anymore to change threhold...
mbedalvaro 0:df6fdd9b99f0 79
mbedalvaro 0:df6fdd9b99f0 80 // Initial state of the two state switch (and don't forget to set the internal pullup resistors!):
mbedalvaro 0:df6fdd9b99f0 81 twoStateSwitch.mode(PullUp);// Use internal pullup for pushbutton
mbedalvaro 0:df6fdd9b99f0 82 twoStateSwitchState=twoStateSwitch.read(); // attention: twoStateSwitch is actually a method (this is equal to twoStateSwitch.read());
mbedalvaro 0:df6fdd9b99f0 83 twoStateSwitchChange=true; // this will force reading the initial threshold mode the first time the program runs
mbedalvaro 0:df6fdd9b99f0 84
mbedalvaro 0:df6fdd9b99f0 85 // Read and update pot value:
mbedalvaro 0:df6fdd9b99f0 86 // updatePotValue(); // the value will be ajusted in the range 0-255
mbedalvaro 0:df6fdd9b99f0 87 }
mbedalvaro 0:df6fdd9b99f0 88
mbedalvaro 0:df6fdd9b99f0 89 void HardwareIO::setSwitchOneState(bool newstate) {
mbedalvaro 0:df6fdd9b99f0 90 switchOneState=newstate;
mbedalvaro 0:df6fdd9b99f0 91 //ledSwitchOne=(switchOneState? 1 :0);
mbedalvaro 0:df6fdd9b99f0 92 }
mbedalvaro 0:df6fdd9b99f0 93
mbedalvaro 0:df6fdd9b99f0 94 // these ISR could do more (like debouncing).
mbedalvaro 0:df6fdd9b99f0 95 // For the time being, I will debounce electrically with a small capacitor.
mbedalvaro 0:df6fdd9b99f0 96 void HardwareIO::switchOneInterrupt() {
mbedalvaro 0:df6fdd9b99f0 97 switchOneState=!switchOneState;
mbedalvaro 0:df6fdd9b99f0 98 switchOneChange=true;
mbedalvaro 0:df6fdd9b99f0 99 }
mbedalvaro 0:df6fdd9b99f0 100
mbedalvaro 0:df6fdd9b99f0 101 void HardwareIO::switchTwoInterrupt() {
mbedalvaro 0:df6fdd9b99f0 102 switchTwoState=!switchTwoState;
mbedalvaro 0:df6fdd9b99f0 103 switchTwoChange=true;
mbedalvaro 0:df6fdd9b99f0 104 }
mbedalvaro 0:df6fdd9b99f0 105
mbedalvaro 0:df6fdd9b99f0 106 bool HardwareIO::switchOneCheck(bool& new_state) {
mbedalvaro 0:df6fdd9b99f0 107 new_state=switchOneState;
mbedalvaro 0:df6fdd9b99f0 108 if (switchOneChange) {
mbedalvaro 0:df6fdd9b99f0 109 switchOneChange=false;
mbedalvaro 0:df6fdd9b99f0 110 return(true);
mbedalvaro 0:df6fdd9b99f0 111 } else
mbedalvaro 0:df6fdd9b99f0 112 return(false);
mbedalvaro 0:df6fdd9b99f0 113 }
mbedalvaro 0:df6fdd9b99f0 114
mbedalvaro 0:df6fdd9b99f0 115 bool HardwareIO::switchTwoCheck(bool& new_state) {
mbedalvaro 0:df6fdd9b99f0 116 new_state=switchTwoState;
mbedalvaro 0:df6fdd9b99f0 117 if (switchTwoChange) {
mbedalvaro 0:df6fdd9b99f0 118 switchTwoChange=false;
mbedalvaro 0:df6fdd9b99f0 119 return(true);
mbedalvaro 0:df6fdd9b99f0 120 } else return(false);
mbedalvaro 0:df6fdd9b99f0 121 }
mbedalvaro 0:df6fdd9b99f0 122
mbedalvaro 0:df6fdd9b99f0 123 // NOT interrupt-based switch:
mbedalvaro 0:df6fdd9b99f0 124 bool HardwareIO::twoStateSwitchCheck(bool& new_state) {
mbedalvaro 0:df6fdd9b99f0 125 new_state=twoStateSwitch; // note: twoStateSwitch is a method!
mbedalvaro 0:df6fdd9b99f0 126 if (twoStateSwitchState==new_state) {
mbedalvaro 0:df6fdd9b99f0 127 // this means that the switch did not change state:
mbedalvaro 0:df6fdd9b99f0 128 return(false);
mbedalvaro 0:df6fdd9b99f0 129 } else {
mbedalvaro 0:df6fdd9b99f0 130 twoStateSwitchState=new_state;
mbedalvaro 0:df6fdd9b99f0 131 return(true);
mbedalvaro 0:df6fdd9b99f0 132 }
mbedalvaro 0:df6fdd9b99f0 133 }
mbedalvaro 0:df6fdd9b99f0 134
mbedalvaro 0:df6fdd9b99f0 135
mbedalvaro 0:df6fdd9b99f0 136 // THIS IS NOT WORKING!!!!!!
mbedalvaro 0:df6fdd9b99f0 137 unsigned char HardwareIO::updatePotValue() { // this will update the pot value, and return it too.
mbedalvaro 0:df6fdd9b99f0 138 //The value will be ajusted in the range 0-255
mbedalvaro 0:df6fdd9b99f0 139 //The 0.0v to 3.3v range of the AnalogIn is represented in software as a normalised floating point number from 0.0 to 1.0.
mbedalvaro 0:df6fdd9b99f0 140
mbedalvaro 0:df6fdd9b99f0 141 // potValue=(unsigned char )(ainPot*255);
mbedalvaro 0:df6fdd9b99f0 142 // Attention: go back to burst mode:
mbedalvaro 0:df6fdd9b99f0 143 // lockin.setADC_forLockin(1);
mbedalvaro 0:df6fdd9b99f0 144 // wait(1);
mbedalvaro 0:df6fdd9b99f0 145
mbedalvaro 0:df6fdd9b99f0 146 //USING the adc library:
mbedalvaro 0:df6fdd9b99f0 147 // unset fast adc for lockin, and set normal adc for conversion from analog input pin:
mbedalvaro 0:df6fdd9b99f0 148 lockin.setADC_forLockin(0);
mbedalvaro 0:df6fdd9b99f0 149 // wait(1);
mbedalvaro 0:df6fdd9b99f0 150
mbedalvaro 0:df6fdd9b99f0 151 //Measure pin POT_ANALOG_INPUT
mbedalvaro 0:df6fdd9b99f0 152 adc.select(POT_ANALOG_INPUT);
mbedalvaro 0:df6fdd9b99f0 153 //Start ADC conversion
mbedalvaro 0:df6fdd9b99f0 154 adc.start();
mbedalvaro 0:df6fdd9b99f0 155 //Wait for it to complete
mbedalvaro 0:df6fdd9b99f0 156 while(!adc.done(POT_ANALOG_INPUT));
mbedalvaro 0:df6fdd9b99f0 157 potValue=adc.read(POT_ANALOG_INPUT);
mbedalvaro 0:df6fdd9b99f0 158
mbedalvaro 0:df6fdd9b99f0 159 //Unset pin POT_ANALOG_INPUT
mbedalvaro 0:df6fdd9b99f0 160 adc.setup(POT_ANALOG_INPUT,0);
mbedalvaro 0:df6fdd9b99f0 161
mbedalvaro 0:df6fdd9b99f0 162 lockin.setADC_forLockin(1);
mbedalvaro 0:df6fdd9b99f0 163 wait(0.5);
mbedalvaro 0:df6fdd9b99f0 164
mbedalvaro 0:df6fdd9b99f0 165 return(potValue);
mbedalvaro 0:df6fdd9b99f0 166 }
mbedalvaro 0:df6fdd9b99f0 167
mbedalvaro 0:df6fdd9b99f0 168 //write on the first DAC, output A (mirror X)
mbedalvaro 0:df6fdd9b99f0 169 void HardwareIO::writeOutX(unsigned short value){
mbedalvaro 0:df6fdd9b99f0 170 if(value > MAX_AD_MIRRORS) value = MAX_AD_MIRRORS;
mbedalvaro 0:df6fdd9b99f0 171 if(value < MIN_AD_MIRRORS) value = MIN_AD_MIRRORS;
mbedalvaro 0:df6fdd9b99f0 172
mbedalvaro 0:df6fdd9b99f0 173 value |= 0x7000;
mbedalvaro 0:df6fdd9b99f0 174 value &= 0x7FFF;
mbedalvaro 0:df6fdd9b99f0 175
mbedalvaro 0:df6fdd9b99f0 176 csDAC = 0; // this means the chip is enabled (negated logic), so CLK and SDI (data) can be transfered
mbedalvaro 0:df6fdd9b99f0 177 spiDAC.write(value);
mbedalvaro 0:df6fdd9b99f0 178 csDAC = 1; // rising the pin actually writes the data in the corresponding DAC register...
mbedalvaro 0:df6fdd9b99f0 179 }
mbedalvaro 0:df6fdd9b99f0 180
mbedalvaro 0:df6fdd9b99f0 181 //write on the first DAC, output B (mirror Y)
mbedalvaro 0:df6fdd9b99f0 182 void HardwareIO::writeOutY(unsigned short value){
mbedalvaro 0:df6fdd9b99f0 183 if(value > MAX_AD_MIRRORS) value = MAX_AD_MIRRORS;
mbedalvaro 0:df6fdd9b99f0 184 if(value < MIN_AD_MIRRORS) value = MIN_AD_MIRRORS;
mbedalvaro 0:df6fdd9b99f0 185
mbedalvaro 0:df6fdd9b99f0 186 value |= 0xF000;
mbedalvaro 0:df6fdd9b99f0 187 value &= 0xFFFF;
mbedalvaro 0:df6fdd9b99f0 188
mbedalvaro 0:df6fdd9b99f0 189 csDAC = 0;
mbedalvaro 0:df6fdd9b99f0 190 spiDAC.write(value);
mbedalvaro 0:df6fdd9b99f0 191 csDAC = 1;
mbedalvaro 0:df6fdd9b99f0 192 }
mbedalvaro 0:df6fdd9b99f0 193
mbedalvaro 0:df6fdd9b99f0 194 void HardwareIO::setLaserLockinPower(int powerValue){
mbedalvaro 0:df6fdd9b99f0 195 if(powerValue > 0){
mbedalvaro 0:df6fdd9b99f0 196 lockin.setLaserPower(true);
mbedalvaro 0:df6fdd9b99f0 197 }
mbedalvaro 0:df6fdd9b99f0 198 else{
mbedalvaro 0:df6fdd9b99f0 199 lockin.setLaserPower(false);
mbedalvaro 0:df6fdd9b99f0 200 }
mbedalvaro 0:df6fdd9b99f0 201 }
mbedalvaro 0:df6fdd9b99f0 202 // THE TTL controlled lasers:
mbedalvaro 0:df6fdd9b99f0 203 // Note: the red one is not used here
mbedalvaro 0:df6fdd9b99f0 204 void HardwareIO::setRedPower(int powerValue){
mbedalvaro 0:df6fdd9b99f0 205 if(powerValue > 0){
mbedalvaro 0:df6fdd9b99f0 206 Laser_Red = 1;
mbedalvaro 0:df6fdd9b99f0 207 }
mbedalvaro 0:df6fdd9b99f0 208 else{
mbedalvaro 0:df6fdd9b99f0 209 Laser_Red = 0;
mbedalvaro 0:df6fdd9b99f0 210 }
mbedalvaro 0:df6fdd9b99f0 211 }
mbedalvaro 0:df6fdd9b99f0 212 void HardwareIO::setGreenPower(int powerValue){
mbedalvaro 0:df6fdd9b99f0 213 if(powerValue > 0){
mbedalvaro 0:df6fdd9b99f0 214 Laser_Green = 1;
mbedalvaro 0:df6fdd9b99f0 215 }
mbedalvaro 0:df6fdd9b99f0 216 else{
mbedalvaro 0:df6fdd9b99f0 217 Laser_Green = 0;
mbedalvaro 0:df6fdd9b99f0 218 }
mbedalvaro 0:df6fdd9b99f0 219 }
mbedalvaro 0:df6fdd9b99f0 220 void HardwareIO::setBluePower(int powerValue){
mbedalvaro 0:df6fdd9b99f0 221 if(powerValue > 0){
mbedalvaro 0:df6fdd9b99f0 222 Laser_Blue = 1;
mbedalvaro 0:df6fdd9b99f0 223 }
mbedalvaro 0:df6fdd9b99f0 224 else{
mbedalvaro 0:df6fdd9b99f0 225 Laser_Blue = 0;
mbedalvaro 0:df6fdd9b99f0 226 }
mbedalvaro 0:df6fdd9b99f0 227 }
mbedalvaro 0:df6fdd9b99f0 228
mbedalvaro 0:df6fdd9b99f0 229 void HardwareIO::setRGBPower(unsigned char color) {
mbedalvaro 0:df6fdd9b99f0 230 lockin.setLaserPower((color&0x04)>0? true : false); // NOTE: here the "red" is the lockin laser, not the TTL one (not used yet)
mbedalvaro 0:df6fdd9b99f0 231 Laser_Green=(color&0x02)>>1;
mbedalvaro 0:df6fdd9b99f0 232 Laser_Blue =color&0x01;
mbedalvaro 0:df6fdd9b99f0 233 }
mbedalvaro 0:df6fdd9b99f0 234
mbedalvaro 0:df6fdd9b99f0 235 void HardwareIO::showLimitsMirrors(int seconds) {
mbedalvaro 0:df6fdd9b99f0 236 unsigned short pointsPerLine=150;
mbedalvaro 0:df6fdd9b99f0 237 int shiftX = (MAX_AD_MIRRORS - MIN_AD_MIRRORS) / pointsPerLine;
mbedalvaro 0:df6fdd9b99f0 238 int shiftY = (MAX_AD_MIRRORS - MIN_AD_MIRRORS) / pointsPerLine;
mbedalvaro 0:df6fdd9b99f0 239
mbedalvaro 0:df6fdd9b99f0 240 Laser_Green=1;
mbedalvaro 0:df6fdd9b99f0 241
mbedalvaro 0:df6fdd9b99f0 242 //for (int repeat=0; repeat<times; repeat++) {
mbedalvaro 0:df6fdd9b99f0 243
mbedalvaro 0:df6fdd9b99f0 244 Timer t;
mbedalvaro 0:df6fdd9b99f0 245 t.start();
mbedalvaro 0:df6fdd9b99f0 246 while(t.read_ms()<seconds*1000) {
mbedalvaro 0:df6fdd9b99f0 247
mbedalvaro 0:df6fdd9b99f0 248 writeOutX(MIN_AD_MIRRORS);writeOutY(MIN_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 249
mbedalvaro 0:df6fdd9b99f0 250 for(int j=0; j<pointsPerLine; j++){
mbedalvaro 0:df6fdd9b99f0 251 wait_us(200);//delay between each points
mbedalvaro 0:df6fdd9b99f0 252 writeOutY(j*shiftY + MIN_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 253 }
mbedalvaro 0:df6fdd9b99f0 254
mbedalvaro 0:df6fdd9b99f0 255 writeOutX(MIN_AD_MIRRORS);writeOutY(MAX_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 256 for(int j=0; j<pointsPerLine; j++) {
mbedalvaro 0:df6fdd9b99f0 257 wait_us(200);//delay between each points
mbedalvaro 0:df6fdd9b99f0 258 writeOutX(j*shiftX + MIN_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 259 }
mbedalvaro 0:df6fdd9b99f0 260
mbedalvaro 0:df6fdd9b99f0 261 writeOutX(MAX_AD_MIRRORS);writeOutY(MAX_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 262 for(int j=0; j<pointsPerLine; j++) {
mbedalvaro 0:df6fdd9b99f0 263 wait_us(200);//delay between each points
mbedalvaro 0:df6fdd9b99f0 264 writeOutY(-j*shiftX + MAX_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 265 }
mbedalvaro 0:df6fdd9b99f0 266
mbedalvaro 0:df6fdd9b99f0 267 writeOutX(MAX_AD_MIRRORS);writeOutY(MIN_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 268 for(int j=0; j<pointsPerLine; j++) {
mbedalvaro 0:df6fdd9b99f0 269 wait_us(200);//delay between each points
mbedalvaro 0:df6fdd9b99f0 270 writeOutX(-j*shiftX + MAX_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 271 }
mbedalvaro 0:df6fdd9b99f0 272
mbedalvaro 0:df6fdd9b99f0 273 }
mbedalvaro 0:df6fdd9b99f0 274 t.stop();
mbedalvaro 0:df6fdd9b99f0 275 Laser_Green=0;
mbedalvaro 0:df6fdd9b99f0 276 }
mbedalvaro 0:df6fdd9b99f0 277
mbedalvaro 0:df6fdd9b99f0 278 void HardwareIO::scan_serial(unsigned short pointsPerLine){
mbedalvaro 0:df6fdd9b99f0 279 //scan the total surface with a custom resolution
mbedalvaro 0:df6fdd9b99f0 280 //send the lockin value for each point as a byte on the serial port to the PC
mbedalvaro 0:df6fdd9b99f0 281 //use "scanSLP_save" to see the data on processing
mbedalvaro 0:df6fdd9b99f0 282 // First, set the red laser on, and other off:
mbedalvaro 0:df6fdd9b99f0 283 setRGBPower(0x4);
mbedalvaro 0:df6fdd9b99f0 284 wait_us(1000); // just to give time to the lockin to set
mbedalvaro 0:df6fdd9b99f0 285
mbedalvaro 0:df6fdd9b99f0 286 int shiftX = (MAX_AD_MIRRORS - MIN_AD_MIRRORS) / pointsPerLine;
mbedalvaro 0:df6fdd9b99f0 287 int shiftY = (MAX_AD_MIRRORS - MIN_AD_MIRRORS) / pointsPerLine;
mbedalvaro 0:df6fdd9b99f0 288
mbedalvaro 0:df6fdd9b99f0 289 for(int j=0; j<pointsPerLine; j++){
mbedalvaro 0:df6fdd9b99f0 290 writeOutX(MIN_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 291 writeOutY(j*shiftY + MIN_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 292
mbedalvaro 0:df6fdd9b99f0 293 wait_us(300);//begining of line delay
mbedalvaro 0:df6fdd9b99f0 294 for(int i=0; i<pointsPerLine; i++){
mbedalvaro 0:df6fdd9b99f0 295 writeOutX(i*shiftX + MIN_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 296
mbedalvaro 0:df6fdd9b99f0 297 wait_us(200);//delay between each points
mbedalvaro 0:df6fdd9b99f0 298
mbedalvaro 0:df6fdd9b99f0 299 // SEND A VALUE BETWEEN 0 and 255:
mbedalvaro 0:df6fdd9b99f0 300 pc.putc(int(255.0*lockin.getMedianValue()/4095));//printf("%dL",int(valueLockin*255));//pc.putc(int(lockin*255));//
mbedalvaro 0:df6fdd9b99f0 301 }
mbedalvaro 0:df6fdd9b99f0 302 }
mbedalvaro 0:df6fdd9b99f0 303 }
mbedalvaro 0:df6fdd9b99f0 304
mbedalvaro 0:df6fdd9b99f0 305 //load Look-up Table from LUT.TXT file
mbedalvaro 0:df6fdd9b99f0 306 //or create the file with scanLUT() if not existing.
mbedalvaro 0:df6fdd9b99f0 307 void HardwareIO::setLUT(){
mbedalvaro 0:df6fdd9b99f0 308
mbedalvaro 0:df6fdd9b99f0 309 FILE *fp = fopen(LUT_FILENAME, "r"); // Open file on the local file system for writing
mbedalvaro 0:df6fdd9b99f0 310 if(fp){
mbedalvaro 0:df6fdd9b99f0 311 //load the file into the lut table; keep the SAME resolution!
mbedalvaro 0:df6fdd9b99f0 312 fread(lut,sizeof(uint16),LUT_RESOLUTION*LUT_RESOLUTION,fp);
mbedalvaro 0:df6fdd9b99f0 313 fclose(fp);
mbedalvaro 0:df6fdd9b99f0 314 }
mbedalvaro 0:df6fdd9b99f0 315 else{
mbedalvaro 0:df6fdd9b99f0 316 //fclose(fp);
mbedalvaro 0:df6fdd9b99f0 317 //if the file "LUT.TXT" doesn't exist, create one with scanLUT()
mbedalvaro 0:df6fdd9b99f0 318 lockin.setLaserPower(true);
mbedalvaro 0:df6fdd9b99f0 319 scanLUT();
mbedalvaro 0:df6fdd9b99f0 320 }
mbedalvaro 0:df6fdd9b99f0 321
mbedalvaro 0:df6fdd9b99f0 322 }
mbedalvaro 0:df6fdd9b99f0 323
mbedalvaro 0:df6fdd9b99f0 324 //scan the total surface with a fixed 2^x resolution
mbedalvaro 0:df6fdd9b99f0 325 //create the Look-Up Table used to "flatten" the scan according to the position
mbedalvaro 0:df6fdd9b99f0 326 //
mbedalvaro 0:df6fdd9b99f0 327 //To Do: maybe detect high frequency to be sure the area is clean and empty?
mbedalvaro 0:df6fdd9b99f0 328 void HardwareIO::scanLUT(){
mbedalvaro 0:df6fdd9b99f0 329
mbedalvaro 0:df6fdd9b99f0 330 //reset lut table
mbedalvaro 0:df6fdd9b99f0 331 for(int j=0; j<LUT_RESOLUTION; j++){
mbedalvaro 0:df6fdd9b99f0 332 for(int i=0; i<LUT_RESOLUTION; i++){
mbedalvaro 0:df6fdd9b99f0 333 lut[i][j] =0;
mbedalvaro 0:df6fdd9b99f0 334 }
mbedalvaro 0:df6fdd9b99f0 335 }
mbedalvaro 0:df6fdd9b99f0 336
mbedalvaro 0:df6fdd9b99f0 337 int delayScanning = 300; //in us
mbedalvaro 0:df6fdd9b99f0 338
mbedalvaro 0:df6fdd9b99f0 339 //define the distance between each points (from 0 to 4096) and the offset (here 0)
mbedalvaro 0:df6fdd9b99f0 340 float shiftX = 1.0*(MAX_AD_MIRRORS - MIN_AD_MIRRORS) / (LUT_RESOLUTION-1);
mbedalvaro 0:df6fdd9b99f0 341 float shiftY = 1.0*(MAX_AD_MIRRORS - MIN_AD_MIRRORS) / (LUT_RESOLUTION-1);
mbedalvaro 0:df6fdd9b99f0 342 float offsetX = MIN_AD_MIRRORS;
mbedalvaro 0:df6fdd9b99f0 343 float offsetY = MIN_AD_MIRRORS;
mbedalvaro 0:df6fdd9b99f0 344
mbedalvaro 0:df6fdd9b99f0 345 //move the mirrors to the first position
mbedalvaro 0:df6fdd9b99f0 346 writeOutX(MAX_AD_MIRRORS);writeOutY(MIN_AD_MIRRORS);
mbedalvaro 0:df6fdd9b99f0 347 wait_us(500);
mbedalvaro 0:df6fdd9b99f0 348
mbedalvaro 0:df6fdd9b99f0 349 float x, y;
mbedalvaro 0:df6fdd9b99f0 350
mbedalvaro 0:df6fdd9b99f0 351 //scan the surface NB_SCANS times
mbedalvaro 0:df6fdd9b99f0 352 //the total value in lut[i][j] shouldn't exceed uint16 !!!
mbedalvaro 0:df6fdd9b99f0 353 for(int loop=0; loop<NB_SCANS; loop++){
mbedalvaro 0:df6fdd9b99f0 354 for(int j=0; j<LUT_RESOLUTION; j++){
mbedalvaro 0:df6fdd9b99f0 355 y = shiftY*j + offsetY ;
mbedalvaro 0:df6fdd9b99f0 356 writeOutY(int(y));
mbedalvaro 0:df6fdd9b99f0 357 //scan from right to left
mbedalvaro 0:df6fdd9b99f0 358 for(int i=LUT_RESOLUTION-1; i>=0; i--){
mbedalvaro 0:df6fdd9b99f0 359 x = shiftX*i + offsetX;
mbedalvaro 0:df6fdd9b99f0 360 writeOutX(int(x));
mbedalvaro 0:df6fdd9b99f0 361 wait_us(delayScanning);
mbedalvaro 0:df6fdd9b99f0 362 lut[i][j] += lockin_read();
mbedalvaro 0:df6fdd9b99f0 363 }
mbedalvaro 0:df6fdd9b99f0 364 //re-scan from left to right
mbedalvaro 0:df6fdd9b99f0 365 for(int i=0; i<LUT_RESOLUTION; i++){
mbedalvaro 0:df6fdd9b99f0 366 x = shiftX*i + offsetX;
mbedalvaro 0:df6fdd9b99f0 367 writeOutX(int(x));
mbedalvaro 0:df6fdd9b99f0 368 wait_us(delayScanning);
mbedalvaro 0:df6fdd9b99f0 369 lut[i][j] += lockin_read();
mbedalvaro 0:df6fdd9b99f0 370 }
mbedalvaro 0:df6fdd9b99f0 371 }
mbedalvaro 0:df6fdd9b99f0 372 }
mbedalvaro 0:df6fdd9b99f0 373
mbedalvaro 0:df6fdd9b99f0 374
mbedalvaro 0:df6fdd9b99f0 375 //save tab in file
mbedalvaro 0:df6fdd9b99f0 376 FILE *fp;
mbedalvaro 0:df6fdd9b99f0 377 #ifdef LUT_FILENAME
mbedalvaro 0:df6fdd9b99f0 378 fp = fopen(LUT_FILENAME, "w"); // Open file on the local file system for writing
mbedalvaro 0:df6fdd9b99f0 379 fwrite(lut,sizeof(uint16),LUT_RESOLUTION*LUT_RESOLUTION,fp);
mbedalvaro 0:df6fdd9b99f0 380 fclose(fp); //close the file (the mBed will appear connected again)
mbedalvaro 0:df6fdd9b99f0 381 #endif
mbedalvaro 0:df6fdd9b99f0 382
mbedalvaro 0:df6fdd9b99f0 383 #ifdef LUT_H_FILENAME
mbedalvaro 0:df6fdd9b99f0 384 //save tab in Human readable file (not used by the program, this is just for checking)
mbedalvaro 0:df6fdd9b99f0 385 // NOTE: we divide the content of the lut table by NB_SCANS, for easy reading (values should be between 0-4095)
mbedalvaro 0:df6fdd9b99f0 386 fp = fopen(LUT_H_FILENAME, "w"); // Open file on the local file system for writing
mbedalvaro 0:df6fdd9b99f0 387 fprintf(fp, "scan resolution: %d x %d\r\n",LUT_RESOLUTION, LUT_RESOLUTION);
mbedalvaro 0:df6fdd9b99f0 388 for(int j=0; j<LUT_RESOLUTION; j++){
mbedalvaro 0:df6fdd9b99f0 389 for(int i=0; i<LUT_RESOLUTION; i++){
mbedalvaro 0:df6fdd9b99f0 390 fprintf(fp, "X=%d,\tY=%d,\tI=%d\t \r\n", int(shiftX*i + offsetX), int(shiftY*j + offsetY), int(1.0*lut[i][j]/NB_SCANS) );
mbedalvaro 0:df6fdd9b99f0 391 }
mbedalvaro 0:df6fdd9b99f0 392 }
mbedalvaro 0:df6fdd9b99f0 393 fclose(fp); //close the file (the mBed will appear connected again)
mbedalvaro 0:df6fdd9b99f0 394 #endif
mbedalvaro 0:df6fdd9b99f0 395
mbedalvaro 0:df6fdd9b99f0 396 }
mbedalvaro 0:df6fdd9b99f0 397
mbedalvaro 0:df6fdd9b99f0 398
mbedalvaro 0:df6fdd9b99f0 399 //Return the lockin value "corrected with the Look-UpTable" - this means a RATIO between two reflectivities (and normally, this is <1).
mbedalvaro 0:df6fdd9b99f0 400 float HardwareIO::lockInCorrectedValue(unsigned short x, unsigned short y){
mbedalvaro 0:df6fdd9b99f0 401 //*******Correction using DIRECT approximation
mbedalvaro 0:df6fdd9b99f0 402 #ifdef LUT_DIRECT
mbedalvaro 0:df6fdd9b99f0 403 return 2.0* NB_SCANS * lockin_read() / (lut[x >> LUT_BITS_SHIFT][y >> LUT_BITS_SHIFT]); // 2 * NB_SCANS is the number of recorded sample added to one position of the LUT (scan is performed twice: left-right and right-left)
mbedalvaro 0:df6fdd9b99f0 404 #endif
mbedalvaro 0:df6fdd9b99f0 405
mbedalvaro 0:df6fdd9b99f0 406 //*******Correction using BILINEAR approximation
mbedalvaro 0:df6fdd9b99f0 407 #ifdef LUT_BILINEAR
mbedalvaro 0:df6fdd9b99f0 408 unsigned short X = x >> LUT_BITS_SHIFT; //mirror "x" is 12bits, LUT "X" needs 4bits when lut is 17x17
mbedalvaro 0:df6fdd9b99f0 409 unsigned short Y = y >> LUT_BITS_SHIFT; //mirror "y" is 12bits, LUT "Y" needs 4bits when lut is 17x17
mbedalvaro 0:df6fdd9b99f0 410 float dx = 1.0*(x & LUT_BITS_MASK)/(LUT_BITS_MASK+1); //weight to apply on X (mask with 255 and norm)
mbedalvaro 0:df6fdd9b99f0 411 float dy = 1.0*(y & LUT_BITS_MASK)/(LUT_BITS_MASK+1); //weight to apply on Y (mask with 255 and norm)
mbedalvaro 0:df6fdd9b99f0 412
mbedalvaro 0:df6fdd9b99f0 413 //Wheighted mean approximation of the Look-Up Table at the position (x,y):
mbedalvaro 0:df6fdd9b99f0 414 float wmLUT = (1-dy)*( (1-dx)*lut[X][Y] + dx*lut[X+1][Y] ) + dy*( (1-dx)*lut[X][Y+1] + dx*lut[X+1][Y+1] );
mbedalvaro 0:df6fdd9b99f0 415
mbedalvaro 0:df6fdd9b99f0 416 return 2.0* NB_SCANS * lockin_read() / wmLUT;// 2 * NB_SCANS is the number of recorded sample added to one position of the LUT (scan is performed twice: left-right and right-left)
mbedalvaro 0:df6fdd9b99f0 417 #endif
mbedalvaro 0:df6fdd9b99f0 418
mbedalvaro 0:df6fdd9b99f0 419 //*******Correction using LINEAR approximation
mbedalvaro 0:df6fdd9b99f0 420 #ifdef LUT_LINEAR
mbedalvaro 0:df6fdd9b99f0 421 unsigned short X = x >> LUT_BITS_SHIFT; //mirror "x" is 12bits, LUT "X" needs 4bits when lut is 17x17
mbedalvaro 0:df6fdd9b99f0 422 unsigned short Y = y >> LUT_BITS_SHIFT; //mirror "y" is 12bits, LUT "Y" needs 4bits when lut is 17x17
mbedalvaro 0:df6fdd9b99f0 423 float dx = 1.0*(x & LUT_BITS_MASK)/(LUT_BITS_MASK+1); //weight to apply on X (mask with 255 and norm)
mbedalvaro 0:df6fdd9b99f0 424 float dy = 1.0*(y & LUT_BITS_MASK)/(LUT_BITS_MASK+1); //weight to apply on Y (mask with 255 and norm)
mbedalvaro 0:df6fdd9b99f0 425 float linearLUT, dzx, dzy;
mbedalvaro 0:df6fdd9b99f0 426
mbedalvaro 0:df6fdd9b99f0 427 if(dx>dy){ //if the position is on the "top-right" triangle
mbedalvaro 0:df6fdd9b99f0 428 dzx = (lut[X+1][Y] - lut[X][Y]) * dx;
mbedalvaro 0:df6fdd9b99f0 429 dzy = (lut[X+1][Y+1] - lut[X+1][Y]) * dy;
mbedalvaro 0:df6fdd9b99f0 430 }
mbedalvaro 0:df6fdd9b99f0 431 else{ //if the position is on the "bottom-left" triangle
mbedalvaro 0:df6fdd9b99f0 432 dzy = (lut[X][Y+1] - lut[X][Y]) * dy;
mbedalvaro 0:df6fdd9b99f0 433 dzx = (lut[X+1][Y+1] - lut[X][Y+1]) * dx;
mbedalvaro 0:df6fdd9b99f0 434 }
mbedalvaro 0:df6fdd9b99f0 435
mbedalvaro 0:df6fdd9b99f0 436 //linear approximation of the Look-Up Table at the position (x,y):
mbedalvaro 0:df6fdd9b99f0 437 linearLUT = lut[X][Y] + dzx + dzy;
mbedalvaro 0:df6fdd9b99f0 438 return 2.0* NB_SCANS * lockin_read() / linearLUT; // 2 * NB_SCANS is the number of recorded sample added to one position of the LUT (scan is performed twice: left-right and right-left)
mbedalvaro 0:df6fdd9b99f0 439
mbedalvaro 0:df6fdd9b99f0 440 #endif
mbedalvaro 0:df6fdd9b99f0 441
mbedalvaro 0:df6fdd9b99f0 442 //*******No corrections, just return the value divided by 4096 (this means we are assuming that the surface is everywhere perfectly reflective - we supposedly get the max value always)
mbedalvaro 0:df6fdd9b99f0 443 #ifdef NO_LUT
mbedalvaro 0:df6fdd9b99f0 444 return 1.0* lockin_read()/4096;
mbedalvaro 0:df6fdd9b99f0 445 #endif
mbedalvaro 0:df6fdd9b99f0 446
mbedalvaro 0:df6fdd9b99f0 447 }