23 #define SOLENOID_B_PORT PORTB |
23 #define SOLENOID_B_PORT PORTB |
24 #define SOLENOID_A_PIN PB1 |
24 #define SOLENOID_A_PIN PB1 |
25 #define SOLENOID_B_PIN PB2 |
25 #define SOLENOID_B_PIN PB2 |
26 |
26 |
27 #define TRACKSWITCH_TYPE 2 // 1=double, 2=single, 3=pitlane |
27 #define TRACKSWITCH_TYPE 2 // 1=double, 2=single, 3=pitlane |
28 |
28 #define MAX_SENSORS 3 |
29 |
29 |
30 // internal analog comparator doesnt work well |
30 // internal analog comparator doesnt work well |
31 //#define ANALOG_COMPARATOR 1 |
31 //#define ANALOG_COMPARATOR 1 |
|
32 |
|
33 typedef struct { |
|
34 unsigned speed:4; |
|
35 unsigned trackswitch:1; |
|
36 unsigned inside:1; |
|
37 } cardata; |
|
38 |
|
39 typedef struct { |
|
40 unsigned car:4; |
|
41 unsigned state:4; |
|
42 uint16_t old, new; |
|
43 } sensordata; |
|
44 |
|
45 volatile cardata slot[MAX_SLOTS]; |
|
46 volatile sensordata sens[MAX_SENSORS]; |
32 |
47 |
33 volatile uint16_t data = 0; |
48 volatile uint16_t data = 0; |
34 volatile uint8_t data_len = 0; |
49 volatile uint8_t data_len = 0; |
35 volatile uint8_t bitbuf_len = 0; |
50 volatile uint8_t bitbuf_len = 0; |
36 volatile uint16_t bitbuf = 0; |
51 volatile uint16_t bitbuf = 0; |
37 volatile uint8_t car_speed[8]; |
|
38 volatile uint8_t car_switch[8]; |
|
39 volatile uint16_t car0, car1, car2; |
|
40 volatile uint16_t car0_new, car0_old; |
|
41 volatile uint16_t car1_new, car1_old; |
|
42 volatile uint16_t car2_new, car2_old; |
|
43 |
52 |
44 volatile uint8_t response = 0; |
53 volatile uint8_t response = 0; |
45 uint8_t self_id = 0b1111; // ONLY ONE pitlane |
54 uint8_t self_id = 0b1111; // ONLY ONE pitlane |
|
55 |
|
56 void solenoid_delay(void) { |
|
57 _delay_ms(10); |
|
58 } |
46 |
59 |
47 void send_response(uint16_t data) { |
60 void send_response(uint16_t data) { |
48 /* frame format: |
61 /* frame format: |
49 1 startbit |
62 1 startbit |
50 2 car id |
63 2 car id |
114 |
127 |
115 //data = bitbuf; // output data |
128 //data = bitbuf; // output data |
116 // write data of controllers to array |
129 // write data of controllers to array |
117 if (data_len == 10) { // controller data packet |
130 if (data_len == 10) { // controller data packet |
118 clock = (bitbuf >> 6) & 0b00000111; |
131 clock = (bitbuf >> 6) & 0b00000111; |
119 car_speed[clock] = (bitbuf >> 1) & 0x0F; |
132 slot[clock].speed = (bitbuf >> 1) & 0x0F; |
120 car_switch[clock] = (bitbuf >> 5) & 1; |
133 slot[clock].trackswitch = (bitbuf >> 5) & 1; |
121 // current response for this car? |
134 // current response for this car? |
122 if (response != 0) { |
135 if (response != 0) { |
123 if ( ((response & 0b00001110) >> 1) == clock) { |
136 if ( ((response & 0b00001110) >> 1) == clock) { |
124 // add our ID to response: |
137 // add our ID to response: |
125 send_response(response | (self_id << 6)); |
138 send_response(response | (self_id << 6)); |
145 } |
158 } |
146 } |
159 } |
147 |
160 |
148 |
161 |
149 ISR (TIMER1_OVF_vect) { |
162 ISR (TIMER1_OVF_vect) { |
150 // reset both car counters to overflow |
163 // reset car counters to overflow |
151 car0_old = 0xffff; |
164 uint8_t i; |
152 car1_old = 0xffff; |
165 for (i=0;i<MAX_SENSORS;i++) |
153 // pitlane exit sensor |
166 sens[i].old = 0xffff; |
154 car2_old = 0xffff; |
167 } |
|
168 |
|
169 void detect_car(uint8_t idx) { |
|
170 uint16_t tmp = 0; |
|
171 sens[idx].new = TCNT1; // get current counter |
|
172 if (sens[idx].old < sens[idx].new) { |
|
173 // calculate difference |
|
174 if (sens[idx].car == 0) tmp = sens[idx].new-sens[idx].old; |
|
175 if ( (tmp > 54) && (tmp < 74) ) tmp = 1; |
|
176 else if ( (tmp > 118) && (tmp < 138) ) tmp = 2; |
|
177 else if ( (tmp > 186) && (tmp < 206) ) tmp = 3; |
|
178 else if ( (tmp > 246) && (tmp < 266) ) tmp = 4; |
|
179 else if ( (tmp > 310) && (tmp < 330) ) tmp = 5; |
|
180 else if ( (tmp > 374) && (tmp < 394) ) tmp = 6; |
|
181 else tmp = 0; |
|
182 sens[idx].car = tmp; |
|
183 } |
|
184 sens[idx].old = sens[idx].new; |
155 } |
185 } |
156 |
186 |
157 ISR (INT1_vect) { |
187 ISR (INT1_vect) { |
158 // car0 detector |
188 // car0 detector |
159 uint16_t tmp = 0; |
189 detect_car(0); |
160 car0_new = TCNT1; // get current counter |
|
161 if (car0_old < car0_new) { |
|
162 // calculate difference |
|
163 if (car0 == 0) tmp = car0_new-car0_old; |
|
164 if ( (tmp > 54) && (tmp < 74) ) car0 = 1; |
|
165 if ( (tmp > 118) && (tmp < 138) ) car0 = 2; |
|
166 if ( (tmp > 186) && (tmp < 206) ) car0 = 3; |
|
167 if ( (tmp > 246) && (tmp < 266) ) car0 = 4; |
|
168 if ( (tmp > 310) && (tmp < 330) ) car0 = 5; |
|
169 if ( (tmp > 374) && (tmp < 394) ) car0 = 6; |
|
170 } |
|
171 car0_old = car0_new; |
|
172 } |
190 } |
173 |
191 |
174 // ISR (TIMER1_CAPT_vect) { |
192 // ISR (TIMER1_CAPT_vect) { |
175 #ifdef ANALOG_COMPARATOR |
193 #ifdef ANALOG_COMPARATOR |
176 ISR (ANA_COMP_vect) { |
194 ISR (ANA_COMP_vect) { |
177 // car1 detector |
195 // car1 detector |
178 uint16_t tmp = 0; |
196 detect_car(1); |
179 car1_new = TCNT1; // get current counter |
|
180 if (car1_old < car1_new) { |
|
181 // calculate difference |
|
182 if (car1 == 0) tmp = car1_new-car1_old; |
|
183 if ( (tmp > 50) && (tmp < 78) ) car1 = 1; |
|
184 if ( (tmp > 114) && (tmp < 146) ) car1 = 2; |
|
185 if ( (tmp > 183) && (tmp < 210) ) car1 = 3; |
|
186 if ( (tmp > 242) && (tmp < 270) ) car1 = 4; |
|
187 if ( (tmp > 310) && (tmp < 330) ) car1 = 5; |
|
188 if ( (tmp > 374) && (tmp < 394) ) car1 = 6; |
|
189 } |
|
190 car1_old = car1_new; |
|
191 } |
197 } |
192 #else |
198 #else |
193 // ALTERNATIV: |
199 // ALTERNATIV: |
194 ISR (TIMER1_CAPT_vect) { |
200 ISR (TIMER1_CAPT_vect) { |
195 // car1 detector |
201 // car1 detector |
196 uint16_t tmp = 0; |
202 detect_car(1); |
197 car1_new = TCNT1; // get current counter |
|
198 if (car1_old < car1_new) { |
|
199 // calculate difference |
|
200 if (car1 == 0) tmp = car1_new-car1_old; |
|
201 if ( (tmp > 50) && (tmp < 78) ) car1 = 1; |
|
202 if ( (tmp > 114) && (tmp < 146) ) car1 = 2; |
|
203 if ( (tmp > 183) && (tmp < 210) ) car1 = 3; |
|
204 if ( (tmp > 242) && (tmp < 270) ) car1 = 4; |
|
205 if ( (tmp > 310) && (tmp < 330) ) car1 = 5; |
|
206 if ( (tmp > 374) && (tmp < 394) ) car1 = 6; |
|
207 } |
|
208 car1_old = car1_new; |
|
209 } |
203 } |
210 #endif |
204 #endif |
211 |
|
212 void solenoid_delay(void) { |
|
213 _delay_ms(10); |
|
214 } |
|
215 |
|
216 |
|
217 |
205 |
218 |
206 |
219 int main(void) |
207 int main(void) |
220 { |
208 { |
221 uint8_t car0_state, car1_state; |
|
222 |
|
223 // setup data bit timer2 |
209 // setup data bit timer2 |
224 TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match |
210 TCCR2 = (1<<CS21) | (1<<WGM21); //divide by 8, set compare match |
225 OCR2 = TIMER2_50US; |
211 OCR2 = TIMER2_50US; |
226 |
212 |
227 // initialize timer1 for IR signal detection |
213 // initialize timer1 for IR signal detection |
268 0 = AA |
254 0 = AA |
269 1 = AB |
255 1 = AB |
270 2 = BB |
256 2 = BB |
271 3 = BA |
257 3 = BA |
272 */ |
258 */ |
273 if (car0 != car0_state) { |
259 if (sens[0].car != sens[0].state) { |
274 car0_state = car0; |
260 sens[0].state = sens[0].car; |
275 if ( (car0_state != 0) && (car_switch[car0_state-1] == 0) && (car_speed[car0_state-1]>0) ) { |
261 if ( (sens[0].state != 0) && (slot[sens[0].state-1].trackswitch == 0) && (slot[sens[0].state-1].speed>0) ) { |
276 response = (1 | ((car0_state-1)<<1) | (1 << 4)); |
262 response = (1 | ((sens[0].state-1)<<1) | (1 << 4)); |
277 // trigger solenoid A |
263 // trigger solenoid A |
278 RS232_putc('A'); |
264 RS232_putc('A'); |
279 RS232_putc('B'); |
265 RS232_putc('B'); |
280 RS232_putc('0'+car0_state); |
266 RS232_putc('0'+sens[0].state); |
281 RS232_putc('\n'); |
267 RS232_putc('\n'); |
282 |
268 |
283 SOLENOID_A_PORT |= _BV(SOLENOID_A_PIN); |
269 SOLENOID_A_PORT |= _BV(SOLENOID_A_PIN); |
284 solenoid_delay(); |
270 solenoid_delay(); |
285 SOLENOID_A_PORT &= ~_BV(SOLENOID_A_PIN); |
271 SOLENOID_A_PORT &= ~_BV(SOLENOID_A_PIN); |
286 solenoid_delay(); |
272 solenoid_delay(); |
287 } |
273 } |
288 if (car0_state != 0) { |
274 if (sens[0].state != 0) { |
289 response = (1 | ((car0_state-1)<<1)); |
275 response = (1 | ((sens[0].state-1)<<1)); |
290 RS232_putc('A'); |
276 RS232_putc('A'); |
291 RS232_putc('A'); |
277 RS232_putc('A'); |
292 RS232_putc('0'+car0_state); |
278 RS232_putc('0'+sens[0].state); |
293 RS232_putc('\n'); |
279 RS232_putc('\n'); |
294 } |
280 } |
295 } car0 = 0; |
281 } sens[0].car = 0; |
296 |
282 |
297 |
283 |
298 if (car1 != car1_state) { |
284 if (sens[1].car != sens[1].state) { |
299 car1_state = car1; |
285 sens[1].state = sens[1].car; |
300 if ( (car1_state != 0) && (car_switch[car1_state-1] == 0) && (car_speed[car1_state-1]>0) ) { |
286 if ( (sens[1].state != 0) && (slot[sens[1].state-1].trackswitch == 0) && (slot[sens[1].state-1].speed>0) ) { |
301 response = (1 | ((car1_state-1)<<1) | (3 << 4)); |
287 response = (1 | ((sens[1].state-1)<<1) | (3 << 4)); |
302 // trigger solenoid B |
288 // trigger solenoid B |
303 RS232_putc('B'); |
289 RS232_putc('B'); |
304 RS232_putc('A'); |
290 RS232_putc('A'); |
305 RS232_putc('0'+car1_state); |
291 RS232_putc('0'+sens[1].state); |
306 RS232_putc('\n'); |
292 RS232_putc('\n'); |
307 |
293 |
308 SOLENOID_B_PORT |= _BV(SOLENOID_B_PIN); |
294 SOLENOID_B_PORT |= _BV(SOLENOID_B_PIN); |
309 solenoid_delay(); |
295 solenoid_delay(); |
310 SOLENOID_B_PORT &= ~_BV(SOLENOID_B_PIN); |
296 SOLENOID_B_PORT &= ~_BV(SOLENOID_B_PIN); |
311 solenoid_delay(); |
297 solenoid_delay(); |
312 } |
298 } |
313 if (car1_state != 0) { |
299 if (sens[1].state != 0) { |
314 response = (1 | ((car1_state-1)<<1) | (2 << 4)); |
300 response = (1 | ((sens[1].state)<<1) | (2 << 4)); |
315 RS232_putc('B'); |
301 RS232_putc('B'); |
316 RS232_putc('B'); |
302 RS232_putc('B'); |
317 RS232_putc('0'+car1_state); |
303 RS232_putc('0'+sens[1].state); |
318 RS232_putc('\n'); |
304 RS232_putc('\n'); |
319 } |
305 } |
320 } car1 = 0; |
306 } sens[0].car = 0; |
321 |
307 |
322 |
308 |
323 } // main loop end |
309 } // main loop end |
324 }; |
310 }; |
325 |
311 |