TSL3301
Dependencies: BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG mbed
Fork of DISCO-F746NG_TSL3301 by
main.cpp@2:6d7063605e3a, 2018-03-20 (annotated)
- Committer:
- oZGi
- Date:
- Tue Mar 20 12:06:47 2018 +0000
- Revision:
- 2:6d7063605e3a
- Parent:
- 1:979d4820e32a
- Child:
- 3:cb16c3af98de
1;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
codebreaker7 | 0:96ad87d71144 | 1 | #include "mbed.h" |
oZGi | 2:6d7063605e3a | 2 | #include "TS_DISCO_F746NG.h" |
oZGi | 2:6d7063605e3a | 3 | #include "LCD_DISCO_F746NG.h" |
oZGi | 2:6d7063605e3a | 4 | |
oZGi | 2:6d7063605e3a | 5 | LCD_DISCO_F746NG lcd; |
oZGi | 2:6d7063605e3a | 6 | int line = 1; |
codebreaker7 | 0:96ad87d71144 | 7 | |
codebreaker7 | 0:96ad87d71144 | 8 | DigitalIn miso(D8); |
codebreaker7 | 0:96ad87d71144 | 9 | DigitalOut mosi(D7); |
codebreaker7 | 0:96ad87d71144 | 10 | DigitalOut clk(D6); |
codebreaker7 | 0:96ad87d71144 | 11 | |
codebreaker7 | 0:96ad87d71144 | 12 | unsigned char lcam_buffer[102]; |
oZGi | 2:6d7063605e3a | 13 | unsigned char max_area; |
codebreaker7 | 0:96ad87d71144 | 14 | |
codebreaker7 | 0:96ad87d71144 | 15 | void lcam_pulse(void) { |
codebreaker7 | 0:96ad87d71144 | 16 | clk = 1; |
codebreaker7 | 0:96ad87d71144 | 17 | clk = 0; |
codebreaker7 | 0:96ad87d71144 | 18 | } |
codebreaker7 | 0:96ad87d71144 | 19 | |
codebreaker7 | 0:96ad87d71144 | 20 | void lcam_pulse_clock(uint8_t times){ |
codebreaker7 | 0:96ad87d71144 | 21 | for(unsigned char i = 0; i < times; i++) |
codebreaker7 | 0:96ad87d71144 | 22 | { |
codebreaker7 | 0:96ad87d71144 | 23 | lcam_pulse(); |
codebreaker7 | 0:96ad87d71144 | 24 | } |
codebreaker7 | 0:96ad87d71144 | 25 | } |
codebreaker7 | 0:96ad87d71144 | 26 | |
codebreaker7 | 0:96ad87d71144 | 27 | void lcam_send(uint8_t value){ |
codebreaker7 | 0:96ad87d71144 | 28 | // Start bit |
codebreaker7 | 0:96ad87d71144 | 29 | mosi = 0; |
codebreaker7 | 0:96ad87d71144 | 30 | lcam_pulse(); |
codebreaker7 | 0:96ad87d71144 | 31 | // Send 8 bits to camera |
codebreaker7 | 0:96ad87d71144 | 32 | for(unsigned char i = 0; i < 8; i++) |
codebreaker7 | 0:96ad87d71144 | 33 | { |
codebreaker7 | 0:96ad87d71144 | 34 | mosi = ((value >> i) & 1); |
codebreaker7 | 0:96ad87d71144 | 35 | lcam_pulse(); |
codebreaker7 | 0:96ad87d71144 | 36 | } |
codebreaker7 | 0:96ad87d71144 | 37 | // Stop bit |
codebreaker7 | 0:96ad87d71144 | 38 | mosi = 1; |
codebreaker7 | 0:96ad87d71144 | 39 | lcam_pulse(); |
codebreaker7 | 0:96ad87d71144 | 40 | } |
codebreaker7 | 0:96ad87d71144 | 41 | |
codebreaker7 | 0:96ad87d71144 | 42 | void lcam_reset(void){ |
codebreaker7 | 0:96ad87d71144 | 43 | wait_ms(1); |
codebreaker7 | 0:96ad87d71144 | 44 | |
codebreaker7 | 0:96ad87d71144 | 45 | // 10 clock impulsions with SDIN held high to clear the receiver logic |
codebreaker7 | 0:96ad87d71144 | 46 | mosi = 1; |
codebreaker7 | 0:96ad87d71144 | 47 | lcam_pulse_clock(10); |
codebreaker7 | 0:96ad87d71144 | 48 | // 3 reset instructions to clear the control logic |
codebreaker7 | 0:96ad87d71144 | 49 | lcam_send(0x1b); |
codebreaker7 | 0:96ad87d71144 | 50 | lcam_send(0x1b); |
codebreaker7 | 0:96ad87d71144 | 51 | lcam_send(0x1b); |
codebreaker7 | 0:96ad87d71144 | 52 | // 30 clock impulsions to assure the state of SDOUT |
codebreaker7 | 0:96ad87d71144 | 53 | lcam_pulse_clock(30); |
codebreaker7 | 0:96ad87d71144 | 54 | |
codebreaker7 | 0:96ad87d71144 | 55 | // register write mode |
codebreaker7 | 0:96ad87d71144 | 56 | lcam_send(0X5F); |
codebreaker7 | 0:96ad87d71144 | 57 | // Clear mode register (single chip, not sleep) |
codebreaker7 | 0:96ad87d71144 | 58 | lcam_send(0x00); |
codebreaker7 | 0:96ad87d71144 | 59 | } |
codebreaker7 | 0:96ad87d71144 | 60 | |
codebreaker7 | 0:96ad87d71144 | 61 | void lcam_setup(void){ |
codebreaker7 | 0:96ad87d71144 | 62 | lcam_reset(); |
codebreaker7 | 0:96ad87d71144 | 63 | |
codebreaker7 | 0:96ad87d71144 | 64 | // set inputs and outputs |
codebreaker7 | 0:96ad87d71144 | 65 | //clk = 1; |
codebreaker7 | 0:96ad87d71144 | 66 | //pin_mode(LCAM_PORT, LCAM_SDIN, 1); |
codebreaker7 | 0:96ad87d71144 | 67 | //pin_mode(LCAM_PORT, LCAM_SDOUT, 0); |
codebreaker7 | 0:96ad87d71144 | 68 | // make sure the clock is cleared |
codebreaker7 | 0:96ad87d71144 | 69 | clk = 0; |
codebreaker7 | 0:96ad87d71144 | 70 | |
codebreaker7 | 0:96ad87d71144 | 71 | // Left offset |
codebreaker7 | 0:96ad87d71144 | 72 | lcam_send(0x40); |
codebreaker7 | 0:96ad87d71144 | 73 | lcam_send(0); |
codebreaker7 | 0:96ad87d71144 | 74 | // Left gain |
codebreaker7 | 0:96ad87d71144 | 75 | lcam_send(0x41); |
codebreaker7 | 0:96ad87d71144 | 76 | lcam_send(15); |
codebreaker7 | 0:96ad87d71144 | 77 | // Middle offset |
codebreaker7 | 0:96ad87d71144 | 78 | lcam_send(0x42); |
codebreaker7 | 0:96ad87d71144 | 79 | lcam_send(0); |
codebreaker7 | 0:96ad87d71144 | 80 | // Middle gain |
codebreaker7 | 0:96ad87d71144 | 81 | lcam_send(0x43); |
codebreaker7 | 0:96ad87d71144 | 82 | lcam_send(15); |
codebreaker7 | 0:96ad87d71144 | 83 | // Right offset |
codebreaker7 | 0:96ad87d71144 | 84 | lcam_send(0x44); |
codebreaker7 | 0:96ad87d71144 | 85 | lcam_send(0); |
codebreaker7 | 0:96ad87d71144 | 86 | // Right gain |
codebreaker7 | 0:96ad87d71144 | 87 | lcam_send(0x45); |
codebreaker7 | 0:96ad87d71144 | 88 | lcam_send(15); |
codebreaker7 | 0:96ad87d71144 | 89 | } |
codebreaker7 | 0:96ad87d71144 | 90 | |
codebreaker7 | 0:96ad87d71144 | 91 | void lcam_startintegration(void){ |
codebreaker7 | 0:96ad87d71144 | 92 | // Send start integration command |
codebreaker7 | 0:96ad87d71144 | 93 | lcam_send(0x08); |
codebreaker7 | 0:96ad87d71144 | 94 | // delayed until the pixel reset cycle has been completed (22-clock delay) |
codebreaker7 | 0:96ad87d71144 | 95 | lcam_pulse_clock(22); |
codebreaker7 | 0:96ad87d71144 | 96 | } |
codebreaker7 | 0:96ad87d71144 | 97 | |
codebreaker7 | 0:96ad87d71144 | 98 | void lcam_endintegration(void){ |
codebreaker7 | 0:96ad87d71144 | 99 | // Sample int command |
codebreaker7 | 0:96ad87d71144 | 100 | lcam_send(0x10); |
codebreaker7 | 0:96ad87d71144 | 101 | // pixel reset sequence is initiated, requires 22 clocks |
codebreaker7 | 0:96ad87d71144 | 102 | lcam_pulse_clock(22); |
codebreaker7 | 0:96ad87d71144 | 103 | } |
codebreaker7 | 0:96ad87d71144 | 104 | |
codebreaker7 | 0:96ad87d71144 | 105 | void lcam_integrate(unsigned int microseconds){ |
codebreaker7 | 0:96ad87d71144 | 106 | lcam_startintegration(); |
codebreaker7 | 0:96ad87d71144 | 107 | wait_us(microseconds); |
codebreaker7 | 0:96ad87d71144 | 108 | lcam_endintegration(); |
codebreaker7 | 0:96ad87d71144 | 109 | } |
codebreaker7 | 0:96ad87d71144 | 110 | |
codebreaker7 | 0:96ad87d71144 | 111 | unsigned char* lcam_getdata(void){ |
codebreaker7 | 0:96ad87d71144 | 112 | return lcam_buffer; |
codebreaker7 | 0:96ad87d71144 | 113 | } |
codebreaker7 | 0:96ad87d71144 | 114 | |
codebreaker7 | 0:96ad87d71144 | 115 | void lcam_read(void){ |
codebreaker7 | 0:96ad87d71144 | 116 | unsigned char i, pixel_bit, pixel; |
codebreaker7 | 0:96ad87d71144 | 117 | // Read pixel command |
codebreaker7 | 0:96ad87d71144 | 118 | lcam_send(0x02); |
codebreaker7 | 0:96ad87d71144 | 119 | // 44-clock cycle delay until the first pixel data is output |
codebreaker7 | 0:96ad87d71144 | 120 | lcam_pulse_clock(44); |
codebreaker7 | 0:96ad87d71144 | 121 | // Read the 102 pixels from the camera |
codebreaker7 | 0:96ad87d71144 | 122 | for(i = 0; i < 102; i++) |
codebreaker7 | 0:96ad87d71144 | 123 | { |
codebreaker7 | 0:96ad87d71144 | 124 | pixel = 0; |
codebreaker7 | 0:96ad87d71144 | 125 | // pulse the pixel start bit (SDOUT = 0) |
codebreaker7 | 0:96ad87d71144 | 126 | lcam_pulse(); |
codebreaker7 | 0:96ad87d71144 | 127 | // read a byte, bit by bit |
codebreaker7 | 0:96ad87d71144 | 128 | for(pixel_bit = 0; pixel_bit < 8; pixel_bit++) |
codebreaker7 | 0:96ad87d71144 | 129 | { |
codebreaker7 | 0:96ad87d71144 | 130 | clk = 1; |
codebreaker7 | 0:96ad87d71144 | 131 | // read pin while clock is at 1 |
codebreaker7 | 0:96ad87d71144 | 132 | pixel |= (((miso) & 1) << pixel_bit); |
codebreaker7 | 0:96ad87d71144 | 133 | clk = 0; |
codebreaker7 | 0:96ad87d71144 | 134 | } |
codebreaker7 | 0:96ad87d71144 | 135 | // store byte to buffer |
codebreaker7 | 0:96ad87d71144 | 136 | lcam_buffer[i] = pixel; |
codebreaker7 | 0:96ad87d71144 | 137 | // pulse the pixel stop bit (SDOUT = 1) |
codebreaker7 | 0:96ad87d71144 | 138 | lcam_pulse(); |
codebreaker7 | 0:96ad87d71144 | 139 | } |
codebreaker7 | 0:96ad87d71144 | 140 | } |
codebreaker7 | 0:96ad87d71144 | 141 | |
oZGi | 2:6d7063605e3a | 142 | unsigned char lcam_getpic(void) |
oZGi | 2:6d7063605e3a | 143 | { |
oZGi | 2:6d7063605e3a | 144 | unsigned char i, value, highest = 0, max_region = 0; |
oZGi | 2:6d7063605e3a | 145 | unsigned int average = 0; |
oZGi | 2:6d7063605e3a | 146 | for(i = 0; i < 25; i++) |
oZGi | 2:6d7063605e3a | 147 | { |
oZGi | 2:6d7063605e3a | 148 | // take 4-byte average and divide by 4 (shift to right by 2) |
oZGi | 2:6d7063605e3a | 149 | value = ((lcam_buffer[i*4] + lcam_buffer[i*4+1] + lcam_buffer[i*4+2] + lcam_buffer[i*4+3]) >> 2); |
oZGi | 2:6d7063605e3a | 150 | if(value > highest) |
oZGi | 2:6d7063605e3a | 151 | { |
oZGi | 2:6d7063605e3a | 152 | highest = value; |
oZGi | 2:6d7063605e3a | 153 | max_region = i; |
oZGi | 2:6d7063605e3a | 154 | } |
oZGi | 2:6d7063605e3a | 155 | average += value; |
oZGi | 2:6d7063605e3a | 156 | } |
oZGi | 2:6d7063605e3a | 157 | |
oZGi | 2:6d7063605e3a | 158 | average /= 25; |
oZGi | 2:6d7063605e3a | 159 | |
oZGi | 2:6d7063605e3a | 160 | if(highest > average + 30) |
oZGi | 2:6d7063605e3a | 161 | { |
oZGi | 2:6d7063605e3a | 162 | return max_region; |
oZGi | 2:6d7063605e3a | 163 | } |
oZGi | 2:6d7063605e3a | 164 | else |
oZGi | 2:6d7063605e3a | 165 | { |
oZGi | 2:6d7063605e3a | 166 | return 0; |
oZGi | 2:6d7063605e3a | 167 | } |
oZGi | 2:6d7063605e3a | 168 | } |
oZGi | 2:6d7063605e3a | 169 | |
codebreaker7 | 0:96ad87d71144 | 170 | int main() { |
codebreaker7 | 1:979d4820e32a | 171 | lcam_setup(); |
codebreaker7 | 0:96ad87d71144 | 172 | while(1) { |
oZGi | 2:6d7063605e3a | 173 | if (line == 10){ |
oZGi | 2:6d7063605e3a | 174 | line = 1; |
oZGi | 2:6d7063605e3a | 175 | } |
oZGi | 2:6d7063605e3a | 176 | |
oZGi | 2:6d7063605e3a | 177 | lcd.Clear(LCD_COLOR_WHITE); |
oZGi | 2:6d7063605e3a | 178 | lcd.SetBackColor(LCD_COLOR_WHITE); |
oZGi | 2:6d7063605e3a | 179 | lcd.SetTextColor(LCD_COLOR_RED); |
oZGi | 2:6d7063605e3a | 180 | |
oZGi | 2:6d7063605e3a | 181 | lcam_integrate(10); |
oZGi | 2:6d7063605e3a | 182 | |
oZGi | 2:6d7063605e3a | 183 | lcam_read(); |
oZGi | 2:6d7063605e3a | 184 | |
oZGi | 2:6d7063605e3a | 185 | max_area = lcam_getpic(); |
oZGi | 2:6d7063605e3a | 186 | |
oZGi | 2:6d7063605e3a | 187 | lcd.DisplayStringAt(0, LINE(line), (uint8_t *)max_area, CENTER_MODE); |
oZGi | 2:6d7063605e3a | 188 | line +=1; |
oZGi | 2:6d7063605e3a | 189 | wait_ms(200); |
codebreaker7 | 0:96ad87d71144 | 190 | } |
codebreaker7 | 0:96ad87d71144 | 191 | } |