Laser Sensing Display for UI interfaces in the real world

Dependencies:   mbed

Fork of skinGames_forktest by Alvaro Cassinelli

Committer:
mbedalvaro
Date:
Thu Apr 17 08:04:14 2014 +0000
Revision:
47:199042980678
Parent:
41:74e24a0e6e50
publishing for sharing with Ken Iwasaki

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedalvaro 34:1244fa3f2559 1
mbedalvaro 34:1244fa3f2559 2 #ifndef hardwareIO_h
mbedalvaro 34:1244fa3f2559 3 #define hardwareIO_h
mbedalvaro 34:1244fa3f2559 4
mbedalvaro 34:1244fa3f2559 5 #include "mbed.h"
mbedalvaro 34:1244fa3f2559 6 #include "lockin.h"
mbedalvaro 34:1244fa3f2559 7
mbedalvaro 40:3ba2b0ea9f33 8 //#define USING_EXTENAL_DAC // ... or we can do both at the same time: external plus the output for the mbed DAC pins
mbedalvaro 40:3ba2b0ea9f33 9 // ARG: MBED has only one "true" analog output (p18) - the others are pwm.. but perhaps we can set a fast PWM cycle and have enough resolution?
mbedalvaro 40:3ba2b0ea9f33 10 // 10 bit resolution (0-1023) should be ok (a display 1024x1024...). What is the max pwm cycle then? I want to be able to write a point every 100us or so (see
mbedalvaro 40:3ba2b0ea9f33 11 // laserSensingDisplay.h), which means 10kHz. Assuming I have a low pass filter, and I filter several cycles - at least 10 - this means I need a freq of about
mbedalvaro 40:3ba2b0ea9f33 12 // 100kHz (presumably it will work with less than that). Possible? I found this: http://mbed.org/questions/192/what-is-the-maximum-frequency-of-the-PWM/
mbedalvaro 40:3ba2b0ea9f33 13 // It seems that the minimum step is 1us... so, at 100kHz (period of 10us) we will only have 10 levels! (about 3 bits). More precisely, if I want 10 bits resolution, the max
mbedalvaro 40:3ba2b0ea9f33 14 // frequency will be 2^10x1us = 1024us, or about 1kHz... too slow!! 10kHz? => about two bits less, ie, 8 bits (256 levels). Mmm... Perhaps good for testing
mbedalvaro 40:3ba2b0ea9f33 15 // on an osciloscope, but not good for mirror control.
mbedalvaro 40:3ba2b0ea9f33 16 // #define mbedAnalogX p18
mbedalvaro 40:3ba2b0ea9f33 17 // #define mbedAnalogY
mbedalvaro 40:3ba2b0ea9f33 18
mbedalvaro 40:3ba2b0ea9f33 19
mbedalvaro 40:3ba2b0ea9f33 20 // Serial communication speed:
mbedalvaro 41:74e24a0e6e50 21 #define SERIAL_SPEED 115200//230400//115200 //230400
mbedalvaro 34:1244fa3f2559 22
mbedalvaro 34:1244fa3f2559 23 // potentiometer to change sensitivity by hand, or other things.
mbedalvaro 34:1244fa3f2559 24 #define POT_ANALOG_INPUT p15 // note: analog inputs in the mbed are from 15 to 20
mbedalvaro 34:1244fa3f2559 25
mbedalvaro 34:1244fa3f2559 26 // switches triggering interrupt functions:
mbedalvaro 34:1244fa3f2559 27 // (Any of the numbered mbed pins can be used as an InterruptIn, except p19 and p20)
mbedalvaro 34:1244fa3f2559 28 // NOTE: do not use pins from p21 to p26 because they are all set as pwm output (see lockin.h)
mbedalvaro 34:1244fa3f2559 29 #define LED_SWITCH_ONE p9 // digital output pin
mbedalvaro 34:1244fa3f2559 30 #define SWITCH_ONE p10 // interrupt pin
mbedalvaro 34:1244fa3f2559 31 #define SWITCH_TWO p11 // interrupt pin
mbedalvaro 34:1244fa3f2559 32
mbedalvaro 40:3ba2b0ea9f33 33 //SPI library (for DAC chip) uses the following pins, but we don't have to set them and inputs or outputs
mbedalvaro 40:3ba2b0ea9f33 34 // (this is done when the library is initialized, which is done by pre-instantiation:
mbedalvaro 34:1244fa3f2559 35 #define SCK_PIN p7 //SPI Clock
mbedalvaro 34:1244fa3f2559 36 #define MISO_PIN p6 //SPI input (data comming from DAC, here not connected)
mbedalvaro 34:1244fa3f2559 37 #define MOSI_PIN p5 //SPI output (data going to DAC)
mbedalvaro 34:1244fa3f2559 38
mbedalvaro 34:1244fa3f2559 39 //**** CHIP SELECT pins for MP4922 DAC (mirrors and red laser)
mbedalvaro 34:1244fa3f2559 40 // VERY IMPORTANT: the chip select for the DACs should be different from the default SPI "SS" pin (Slave Select), which is 53 by default (and will be used by the Ethernet Shield).
mbedalvaro 34:1244fa3f2559 41 #define CS_DAC_MIRRORS p8 //Chip Select of the first DAC (mirrors)
mbedalvaro 34:1244fa3f2559 42
mbedalvaro 34:1244fa3f2559 43 //**** LASERS pins:
mbedalvaro 40:3ba2b0ea9f33 44 #define LASER_RED_PIN p28 // NOT YET USED (TTL control). NOTE: this is NOT the locking sensing laser!
mbedalvaro 34:1244fa3f2559 45 #define LASER_GREEN_PIN p29 // USED (TTL control)
mbedalvaro 34:1244fa3f2559 46 #define LASER_BLUE_PIN p30 // USED (TTL control)
mbedalvaro 34:1244fa3f2559 47
mbedalvaro 34:1244fa3f2559 48 //**** MIRRORS:
mbedalvaro 34:1244fa3f2559 49 //The DAC is 12 bytes capable (Max=4096), but we will limit this a little.
mbedalvaro 34:1244fa3f2559 50 #define MAX_AD_MIRRORS 3845 // note: 4095 is the absolute maximum for the SPI voltage (5V). This is for checking hardware compliance, but max and min angles can be defined for X and Y in each LivingSpot instance.
mbedalvaro 34:1244fa3f2559 51 #define MIN_AD_MIRRORS 250 // note: 0 is 0 volts for the SPI voltage.
mbedalvaro 34:1244fa3f2559 52 // We assume that the center of the mirror is at MAX_AD_MIRRORS/2 = 2000:
mbedalvaro 34:1244fa3f2559 53 #define CENTER_AD_MIRROR_X 2047 // This MUST BE the direction of the photodetector.
mbedalvaro 34:1244fa3f2559 54 #define CENTER_AD_MIRROR_Y 2047 // This MUST BE the direction of the photodetector.
mbedalvaro 34:1244fa3f2559 55
mbedalvaro 34:1244fa3f2559 56
mbedalvaro 34:1244fa3f2559 57 //**** Look-Up Table:
mbedalvaro 34:1244fa3f2559 58 #define uint16 unsigned short
mbedalvaro 34:1244fa3f2559 59 #define LUT_RESOLUTION 33 // resolution of the Look-Up Table (power of 2 +1)
mbedalvaro 34:1244fa3f2559 60 #define LUT_BITS_SHIFT 7 // bits shift from mirror DAC (12 bits) to LUT ( root_square(LUT_RESOLUTION - 1) )
mbedalvaro 34:1244fa3f2559 61 #define LUT_BITS_MASK 127 // bits mask to obtain the position remainder ( 2^LUT_BITS_SHIFT - 1 )
mbedalvaro 34:1244fa3f2559 62 // possible configurations:
mbedalvaro 34:1244fa3f2559 63 // LUT_RESOLUTION LUT_BITS_SHIFT LUT_BITS_MASK
mbedalvaro 34:1244fa3f2559 64 // 9 9 511
mbedalvaro 34:1244fa3f2559 65 // 17 8 255
mbedalvaro 34:1244fa3f2559 66 // 33 7 127
mbedalvaro 34:1244fa3f2559 67 // 65 6 63
mbedalvaro 34:1244fa3f2559 68 // ...
mbedalvaro 34:1244fa3f2559 69 #define NB_SCANS 8 // number of scans performed to generate the LUT table (actually, each site CUMULATES NB_SCANS values)
mbedalvaro 34:1244fa3f2559 70 // IMPORTANT: NB_SCANS*4095 should not exceed the capacity of uint16, this is 2^16-1=65535.
mbedalvaro 34:1244fa3f2559 71 // In other terms, NB_SCANS should be < 65535/4095=16
mbedalvaro 34:1244fa3f2559 72
mbedalvaro 34:1244fa3f2559 73 #define LUT_FILENAME "/local/LUT.txt"
mbedalvaro 34:1244fa3f2559 74
mbedalvaro 34:1244fa3f2559 75 // For checking (define if human readable file is required - note: it is not used by the program, just as output for human reading)
mbedalvaro 34:1244fa3f2559 76 #define LUT_H_FILENAME "/local/LUT_pos.txt"
mbedalvaro 34:1244fa3f2559 77
mbedalvaro 34:1244fa3f2559 78 // Current Look-up table approximation (only one at a time!):
mbedalvaro 34:1244fa3f2559 79 //#define LUT_BILINEAR
mbedalvaro 34:1244fa3f2559 80 //#define LUT_DIRECT
mbedalvaro 34:1244fa3f2559 81 //#define LUT_LINEAR
mbedalvaro 34:1244fa3f2559 82 #define NO_LUT
mbedalvaro 34:1244fa3f2559 83
mbedalvaro 34:1244fa3f2559 84 //Current method for lockin data acquisition and correction
mbedalvaro 34:1244fa3f2559 85 #define lockin_read() lockin.getMedianValue() // lockin.getSmoothValue(); //return the average of the value stored on the buffer
mbedalvaro 34:1244fa3f2559 86 // lockin.getLastValue(); //return the last conversion of the ADC
mbedalvaro 34:1244fa3f2559 87 // lockin.getMedianValue(); //return the median value of the buffer
mbedalvaro 34:1244fa3f2559 88
mbedalvaro 34:1244fa3f2559 89
mbedalvaro 40:3ba2b0ea9f33 90 extern DigitalOut Laser_Red, Laser_Green, Laser_Blue;
mbedalvaro 40:3ba2b0ea9f33 91
mbedalvaro 40:3ba2b0ea9f33 92 // LEDS for debugging:
mbedalvaro 40:3ba2b0ea9f33 93 extern DigitalOut myLed1, myLed2, myLed3, myLed4;
mbedalvaro 34:1244fa3f2559 94
mbedalvaro 34:1244fa3f2559 95 // **** REFERENCE SIGNAL:
mbedalvaro 34:1244fa3f2559 96 /*
mbedalvaro 34:1244fa3f2559 97 #define testPin_OC1A 11 // this is, output compare pin OC1A //connected to CK2 = lockIn clock
mbedalvaro 34:1244fa3f2559 98 #define testPin_OC1B 12 // this is, output compare pin OC1B //connected to CK1 = laser clock
mbedalvaro 34:1244fa3f2559 99 #define testPin_OC1C 13
mbedalvaro 34:1244fa3f2559 100 */
mbedalvaro 34:1244fa3f2559 101
mbedalvaro 34:1244fa3f2559 102 // ==================================================================================================================================================================
mbedalvaro 34:1244fa3f2559 103
mbedalvaro 34:1244fa3f2559 104 class HardwareIO {
mbedalvaro 34:1244fa3f2559 105 public:
mbedalvaro 34:1244fa3f2559 106
mbedalvaro 34:1244fa3f2559 107
mbedalvaro 34:1244fa3f2559 108 void init(void);
mbedalvaro 34:1244fa3f2559 109
mbedalvaro 34:1244fa3f2559 110 //Lock-in acquisition methods:
mbedalvaro 34:1244fa3f2559 111 // float LockInRead_Volts();
mbedalvaro 34:1244fa3f2559 112 // int LockInRead_AD();
mbedalvaro 34:1244fa3f2559 113 // float LockInAD_to_Volts(int);
mbedalvaro 34:1244fa3f2559 114
mbedalvaro 34:1244fa3f2559 115 //Look-Up Table:
mbedalvaro 34:1244fa3f2559 116 unsigned short lut[LUT_RESOLUTION][LUT_RESOLUTION]; //Look-Up Table (uint16 is "unsigned short")
mbedalvaro 34:1244fa3f2559 117 void scanLUT(); //create and save the Look-Up Table
mbedalvaro 34:1244fa3f2559 118 void setLUT(); //set the Look-Up Table: either from scanning, or from the file LUT.TXT (if it is present)
mbedalvaro 34:1244fa3f2559 119 float lockInCorrectedValue(unsigned short x, unsigned short y); //return the lockin value corrected with the Look-UpTable (this is, a RATIO of reflectivities, and <1)
mbedalvaro 34:1244fa3f2559 120
mbedalvaro 34:1244fa3f2559 121 void scan_serial(unsigned short pointsPerLine = 400);
mbedalvaro 34:1244fa3f2559 122
mbedalvaro 40:3ba2b0ea9f33 123 void showLimitsMirrors( unsigned short pointsPerLine, unsigned short timeInSeconds );
mbedalvaro 40:3ba2b0ea9f33 124 // void showLimitsConcentric(int pointsPerSide, int times);
mbedalvaro 40:3ba2b0ea9f33 125 // void showCircle(int cv, int cy, float radius, int nmpoints, int times);
mbedalvaro 40:3ba2b0ea9f33 126 // void showGrid(float cx, float cy, int nx, int ny, float pasx, float pasy, int repeat);
mbedalvaro 40:3ba2b0ea9f33 127 // void gridCircles(float cx, float cy, int nx, int ny, float pasx, float pasy, float radius, int repeat, boolean sym);
mbedalvaro 40:3ba2b0ea9f33 128 // void showContinuousGrid(int nx, int ny, float cx, float cy, int width, int height, float pasx, float pasy, int repeat);
mbedalvaro 40:3ba2b0ea9f33 129
mbedalvaro 34:1244fa3f2559 130
mbedalvaro 34:1244fa3f2559 131 // SPI control for DAC for mirrors and red laser power (low level):
mbedalvaro 34:1244fa3f2559 132 void writeOutX(unsigned short value);
mbedalvaro 34:1244fa3f2559 133 void writeOutY(unsigned short value);
mbedalvaro 40:3ba2b0ea9f33 134 void writeOutXY(unsigned short valueX, unsigned short valueY) {writeOutX(valueX); writeOutY(valueY);};
mbedalvaro 34:1244fa3f2559 135
mbedalvaro 34:1244fa3f2559 136 // mirror degree-to-AD units conversion factors:
mbedalvaro 34:1244fa3f2559 137 //float AD_to_Deg_MIRROR_X;//=1.0*(MAX_DEG_MIRROR_X-MIN_DEG_MIRROR_X)/(MAX_AD_MIRRORS-MIN_AD_MIRRORS);
mbedalvaro 34:1244fa3f2559 138 //float AD_to_Deg_MIRROR_Y;//=1.0*(MAX_DEG_MIRROR_Y-MIN_DEG_MIRROR_Y)/(MAX_AD_MIRRORS-MIN_AD_MIRRORS);
mbedalvaro 34:1244fa3f2559 139
mbedalvaro 34:1244fa3f2559 140 /*
mbedalvaro 34:1244fa3f2559 141 // Mirror position:
mbedalvaro 34:1244fa3f2559 142 void setMirrorX_Deg(float _Az);
mbedalvaro 34:1244fa3f2559 143 void setMirrorY_Deg(float _El);
mbedalvaro 34:1244fa3f2559 144 void setMirrorX_AD(int _AzAD);
mbedalvaro 34:1244fa3f2559 145 void setMirrorY_AD(int _ElAD);
mbedalvaro 34:1244fa3f2559 146 void setMirrorsXY_AD(int _xAD, int _yAD);
mbedalvaro 34:1244fa3f2559 147 void setMirrorsCenter();
mbedalvaro 34:1244fa3f2559 148 void getAnglesFromAD(float &Az, float &El, int _xAD, int _yAD);
mbedalvaro 34:1244fa3f2559 149 //void setZoneDelimiters(...) // this could be here, instead on the LivingSpot class
mbedalvaro 34:1244fa3f2559 150 */
mbedalvaro 34:1244fa3f2559 151
mbedalvaro 40:3ba2b0ea9f33 152 // Setting the laser power of the SENSING LASER (note: for the moment this is TTL, but could be analog):
mbedalvaro 40:3ba2b0ea9f33 153 void setLaserLockinPower(int powerLockingLaser); //if powerValue > 0 ==> 'true'; else 'false'
mbedalvaro 40:3ba2b0ea9f33 154 // Setting the power of the DISPLAYING lasers:
mbedalvaro 40:3ba2b0ea9f33 155 // Again: for the moment laser are TTL but these could be analog. Now, it is just: powerValue > 0 ==> 'true'; else 'false'
mbedalvaro 40:3ba2b0ea9f33 156 // Red laser:
mbedalvaro 34:1244fa3f2559 157 void setRedPower(int powerRed);
mbedalvaro 34:1244fa3f2559 158 // Green laser:
mbedalvaro 34:1244fa3f2559 159 void setGreenPower(int powerGreen);
mbedalvaro 34:1244fa3f2559 160 // Blue laser:
mbedalvaro 34:1244fa3f2559 161 void setBluePower(int powerBlue);
mbedalvaro 40:3ba2b0ea9f33 162 // Setting all colors at once:
mbedalvaro 40:3ba2b0ea9f33 163 void setRGBPower(unsigned char color); // we will use the 3 LSB bits to set each color
mbedalvaro 40:3ba2b0ea9f33 164 void switchOffDisplayLasers() {setRGBPower(0x00);}
mbedalvaro 34:1244fa3f2559 165
mbedalvaro 34:1244fa3f2559 166 //void setupPWM();
mbedalvaro 34:1244fa3f2559 167 /* IN ADVANCED HARDWARE:
mbedalvaro 34:1244fa3f2559 168 // init PWM for reference generation:
mbedalvaro 34:1244fa3f2559 169 void initPWM();
mbedalvaro 34:1244fa3f2559 170 // reference signal:
mbedalvaro 34:1244fa3f2559 171 void setRefFreq(int);
mbedalvaro 34:1244fa3f2559 172 void incRefFreq(int inc=1);
mbedalvaro 34:1244fa3f2559 173 void decRefFreq(int dec=1);
mbedalvaro 34:1244fa3f2559 174 */
mbedalvaro 34:1244fa3f2559 175
mbedalvaro 34:1244fa3f2559 176 //float refFreq; // could be private
mbedalvaro 40:3ba2b0ea9f33 177
mbedalvaro 34:1244fa3f2559 178 bool switchOneChange, switchTwoChange;
mbedalvaro 34:1244fa3f2559 179 void switchOneInterrupt();
mbedalvaro 34:1244fa3f2559 180 void switchTwoInterrupt();
mbedalvaro 34:1244fa3f2559 181 bool switchOneCheck(bool& state);
mbedalvaro 34:1244fa3f2559 182 bool switchTwoCheck(bool& state);
mbedalvaro 35:35af5086ab4f 183 void setSwitchOneState(bool newstate);
mbedalvaro 34:1244fa3f2559 184
mbedalvaro 34:1244fa3f2559 185 unsigned char updatePotValue(); // the value will be ajusted in the range 0-255
mbedalvaro 34:1244fa3f2559 186 unsigned char potValue;
mbedalvaro 34:1244fa3f2559 187
mbedalvaro 34:1244fa3f2559 188 bool switchOneState, switchTwoState;
mbedalvaro 34:1244fa3f2559 189
mbedalvaro 34:1244fa3f2559 190 private:
mbedalvaro 34:1244fa3f2559 191 //DigitalOut Laser_Red, Laser_Green, Laser_Blue;
mbedalvaro 34:1244fa3f2559 192 };
mbedalvaro 34:1244fa3f2559 193
mbedalvaro 34:1244fa3f2559 194
mbedalvaro 34:1244fa3f2559 195 extern HardwareIO IO; // allows the object IO to be used in other .cpp files (IO is pre-instantiated in hardwareIO.cpp)
mbedalvaro 34:1244fa3f2559 196 // NOTE: IO encapsulates many IO functions, but perhaps it is better not to have an IO object - just use each IO function separatedly (as with pc object for instance)
mbedalvaro 34:1244fa3f2559 197 extern Serial pc; // allows pc to be manipulated by other .cpp files, even if pc is defined in the hardwareIO.cpp
mbedalvaro 34:1244fa3f2559 198
mbedalvaro 34:1244fa3f2559 199
mbedalvaro 34:1244fa3f2559 200 #endif
mbedalvaro 40:3ba2b0ea9f33 201