-
Notifications
You must be signed in to change notification settings - Fork 0
/
Pro33RILT_10Mhz.ino
630 lines (529 loc) · 21.2 KB
/
Pro33RILT_10Mhz.ino
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
/////////////////////////////////////////////////////////////////////////////////////
// The Ridiculously Inexpensive Lag Tester (RILT) - Arduino Pro Mini 3.3v edition
//
// Concept: The goal was to create an inexpensive analog display lag testing device.
// The design consists of a small microcontroller board (Arduino Pro Mini),
// a relatively fast photodiode (for display light detection),
// a couple of resistors, a common transistor, and a single RCA connector
// for analog video output.
// Since the ATMega328P has a 16-bit timer (Timer1), we use this.
// We set up Timer1 for CTC mode, and set the OCR1A value appropriately.
//
// Note: This is the 240p/480p Y (luma) version (Y of YPbPbr) for the Pro Mini.
// The Arduino Pro Mini (8Mhz) is used (which contains an ATMega328p),
// However, the crystal oscillator was replaced with a more precise 10Mhz one,
// So this needs to be flashed with a standard AVR ISP programmer.
// The arduino IDE can be used to compile, but manual flashing is needed.
//
// Port B is used.
//
// PB0 - Negative Sync Active (0v), Negative Sync Inactive (3.3v)
// PB1 - Black (0v), White (3.3v)
// PB0 and PB1 are used to generate the Y signal, which has built-in sync
//
// Sync
// PB0-----/\/\/\/------|
// R0 560 Ohm |
// B/W |
// PB1-----/\/\/\/------*-----Output To Display (Vo)... ---/\/\/\/---GND
// R1 270 Ohm Rt 75 Ohm (termination at display)
//
//
// PB1 | PB0 | ~Vo (terminated)
// --------------------------
// 0v | 0v | 0v (in sync pulse)
// 0v |3.3v | 0.313v (Black)
// 3.3v | 0v | 0.649v (Grey)
// 3.3v |3.3v | 0.962v (White)
//
// Vo (terminated) = Rt ( (Vpb0*R1 + Vpb1*R0) / (R0*R1 + R1*Rt + R0*Rt) )
//
// Future features:
//
// PB2 - Connection to light sensor used to detect presence of white on the display.
// PB2 requires a fast photodiode (e.g. recommend quicker than 100us response)
// Future revision will use Vishay TEFD4300 (100ns rise/fall time) to control
// the transistor (2N3904).
//
// VCC
// |
// |---------/\/\/\/--------*----PB2
// | 5k Ohm |
// | |
// | /
// |---|>|-------/\/\/\/--| 2N3904
// Photo 50k Ohm \
// diode |
// (TEFD4300) |
// GND
//
//
// PB3 - Mode select (240p/480p)
// Pull PB3 to ground for 480p mode.
// Leave PB3 pulled up to 5v for 240p mode (ATMega328p internal pullup enabled).
//
//
//
//
/////////////////////////////////////////////////////////////////////////////////////
#define RILT_PORT PORTB
#define RILT_PIN PINB
#define RILT_DDR DDRB
#define SYNC_PORT_PIN 0 // PB0
#define VID_PORT_PIN 1 // PB1
#define SENSOR_PORT_PIN 2 // PB2
#define VIDMODE_PORT_PIN 3 // PB3
#define BOX_START_LINE_240P 125
#define BOX_END_LINE_240P 146
#define BOX_START_LINE_480P 265
#define BOX_END_LINE_480P 305
#define VIDMODE_240P 0
#define VIDMODE_480P 1
#define RESULT_WAIT_IN_LINES 62492
#define OCR1A_VALUE_FOR_240P 634 // 10,000,000 / (634+1) = 15,748 Hz
#define OCR1A_VALUE_FOR_480P 318 // 10,000,000 / (317+1) = 31,447 Hz
uint8_t vidMode;
uint16_t horizontalLineCount;
bool measuringLag;
bool drawBox;
uint16_t lagLineCounter;
uint16_t resultLinesWaited;
bool printSerialFlag;
void setup() {
// Initialize GPIO
// Set our Sync and Video pins to output mode
RILT_DDR |= ( (1<<SYNC_PORT_PIN) | (1<<VID_PORT_PIN) );
// Set our Mode and Sensor pins to input mode
RILT_DDR &= ~( (1<<VIDMODE_PORT_PIN) | (1<<SENSOR_PORT_PIN) );
// Set our Sync and Video pins to an initial value of sync inactive / black
RILT_PORT &= ~(1<<VID_PORT_PIN);
RILT_PORT |= (1<<SYNC_PORT_PIN);
// Activate pullup resistors for the Mode and Sensor pins.
RILT_PORT |= ( (1<<VIDMODE_PORT_PIN) | (1<<SENSOR_PORT_PIN) );
// Initialize Serial and send a welcome message
Serial.begin(9600);
Serial.println("Welcome to RILT: The Ridiculously Inexpensive Lag Tester");
Serial.println(" (3.3v Arduino Pro Mini Edition)");
// Initialize Timer1
cli(); // stop interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0; // counter is initially 0
// Determine if we're in 240p or 480p mode.
uint8_t mode = RILT_PIN & (1<<VIDMODE_PORT_PIN);
if(mode) {
// We're in 240p mode (the Mode pin was high)
vidMode = VIDMODE_240P;
OCR1A = OCR1A_VALUE_FOR_240P;
Serial.println("Operating mode: 240p");
Serial.println(" To obtain time (in milliseconds), multiply the lines of lag reported");
Serial.println(" by 63.55us per line, then multiply by 1,000 (1,000us in 1ms).");
} else {
// We're in 480p mode (the Mode pin was low)
vidMode = VIDMODE_480P;
OCR1A = OCR1A_VALUE_FOR_480P;
Serial.println("Operating mode: 480p (Future Feature, not yet implemented)");
Serial.println(" To obtain time (in milliseconds), multiply the lines of lag reported");
Serial.println(" by 31.77us per line, then multiply by 1,000 (1,000us in 1ms).");
}
// Continue initializing Timer1
TCCR1B |= (1<<WGM12); // Turn on CTC mode
TCCR1B |= (1<<CS10); // clk/1 prescaler
TIMSK1 |= (1<<OCIE1A); // enable timer compare interrupt
horizontalLineCount = 1;
drawBox = true;
measuringLag = true;
lagLineCounter = 0;
resultLinesWaited = 0;
printSerialFlag = false;
sei();
}
////////////////////////////// Implementation which generates 240p //////////////////////////
void generate240p() {
// Set to sync inactive / black
// Vid should already be 0
RILT_PORT &= ~(1<<VID_PORT_PIN);
RILT_PORT |= (1<<SYNC_PORT_PIN);
// We're in the Front Porch region
// for 1.5us (approx 15 clock ticks at 10Mhz)
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 11 clocks (overhead)
// We enter the sync pulse for 4.7us (approximately 47 clock ticks at 8Mhz)
// Set to sync active
RILT_PORT &= ~(1<<SYNC_PORT_PIN);
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 10th clock
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 20th clock
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 30th clock
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 35th clock (overhead)
// If we're in the VSync region (i.e. on line 4, 5, or 6 (3 FP, 3 SP, 16 BP) for 240p,
// then keep sync LOW (the back porch is 0 during VSync)
// The Back Porch is 1.5us, or approximately 12 clock ticks at 8Mhz.
// Note: The if() is structured this way to descrease jitter for
// when we're not in the VSync region. The idea is that all parts
// of the AND would need to be evaluated to true. This might need to be
// replaced with assembly to prevent compiler optimizations from getting in
// our way of our goal to reduce jitter.
if( (horizontalLineCount != 4) && (horizontalLineCount != 5) && (horizontalLineCount != 6) ) {
// We're not in the VSync region
// Set to sync inactive / black
RILT_PORT |= (1<<SYNC_PORT_PIN);
if(horizontalLineCount == 262) {
// We've reached the last line
// The last things we do is reset the line counter and return
horizontalLineCount = 1;
return;
}
// If we're in the region to draw the line white,
// then wait the rest of the Back Porch duration,
// then draw the line white
if( (horizontalLineCount > BOX_START_LINE_240P) && (horizontalLineCount < BOX_END_LINE_240P) ) {
// Waiting for back porch to complete (approximately 15 clocks minus overhead)
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 4 clocks (overhead)
if(drawBox) {
// set Vid to high (i.e. start drawing a white line of the box)
RILT_PORT |= (1<<VID_PORT_PIN);
// Wait for 25% of the screen to turn Vid back to black
// The visible line time for 240p is
// 63.55us -1.5us(FP) -4.7us(Sync) -1.5us(BP) = 55.85us.
// 0.25 * 55.85us = 13.96us
// 13.96us / 0.100 = 140 cycles
// Doesn't have to be exact, just enough to make a visible white box.
uint8_t waitCounter = 13;
while(waitCounter) {
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 10th clock
waitCounter--;
}
RILT_PORT &= ~(1<<VID_PORT_PIN);
}
} else if(horizontalLineCount == 50) {
// draw a pilot line
// Waiting for back porch to complete
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 10th clock
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 15th clock
// set Vid to high (i.e. start drawing a white line of the box)
RILT_PORT |= (1<<VID_PORT_PIN);
}
} else {
// We're in the VSync region.
// Keep sync line LOW.
}
// At this point, we've drawn the Front Porch and Sync Pulse.
// If we were drawing the the box lines, we're just after
// the end of the box line being drawn (when the line
// has been turned from white to black).
// If we aren't drawing the box lines, we're near the start
// of the back porch. The Back Porch for 240p is approx 1.5us,
// and drawing the white line of the box adds approx 13.96us,
// so we accept this margin of error.
// If we're supposed to be measuring lag, then we check to see
// if the sensor has detected light.
// If it has detected light, then we can set measuringLag to false,
//
// we increment the lagLineCounter.
if(measuringLag) {
// We're checking if the SENSOR_PORT_PIN is LOW (light detected).
uint8_t pin = RILT_PIN & (1<<SENSOR_PORT_PIN);
if(lagLineCounter == 1310) {pin = 0;} // Remove after implementing photodiode
if( pin == 0 ) {
// Light was detected.
// We are no longer measuring lag.
measuringLag = false;
// The value of lagLineCounter will be used
// in another part of the code to show results.
// We also don't need to draw the box.
drawBox = false;
} else {
// Light was not detected.
// Increment the lagLineCounter and move on.
lagLineCounter++;
}
} else {
// We're not measuring lag.
// This means that light was detected.
// We print the result over serial, then wait for
// the number of lines designated by resultLinesWaited
// and reset values
if(resultLinesWaited == RESULT_WAIT_IN_LINES) {
// We've finished waiting.
// We set measuringLag to true, drawBox to true,
// and reset the lagLineCounter
measuringLag = true;
drawBox = true;
lagLineCounter = 0;
// We reset resultWaitInLines
resultLinesWaited = 0;
} else {
if(resultLinesWaited == 0) {
printSerialFlag = true;
Serial.print(lagLineCounter);
Serial.print(" lines of lag detected\n");
}
resultLinesWaited++;
}
}
horizontalLineCount++;
return;
}
////////////////////////////// Implementation which generates 480p //////////////////////////
void generate480p() {
// Set to sync inactive / black
// Vid should already be 0
RILT_PORT &= ~(1<<VID_PORT_PIN);
RILT_PORT |= (1<<SYNC_PORT_PIN);
// We're in the Front Porch region
// for 0.5925us, however, we need to maintain good VSync pulse timing
// so we choose 2.33us (approx 23 clock ticks at 10Mhz)
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 10th clock
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 20th clock (overhead)
// We enter the sync pulse for 2.33us (approximately 24 clock ticks at 10Mhz)
// Set to sync active
RILT_PORT &= ~(1<<SYNC_PORT_PIN);
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 10th clock
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 12th clock (overhead)
// If we're in the VSync region (i.e. on line 7, 8, 9, 10, 11, or 12, (6 FP, 6 SP, 32 BP) for 480p,
// then keep sync LOW (the back porch is 0 during VSync)
// The Back Porch is 2.1886us, or approximately 22 clock ticks at 10Mhz.
// Note: The if() is structured this way to descrease jitter for
// when we're not in the VSync region. The idea is that all parts
// of the AND would need to be evaluated to true. This might need to be
// replaced with assembly to prevent compiler optimizations from getting in
// our way of our goal to reduce jitter.
if( (horizontalLineCount > 6) && (horizontalLineCount < 13) ) {
// We're in the VSync region.
// Keep sync line LOW.
} else {
// We're not in the VSync region
// Set to sync inactive / black
RILT_PORT |= (1<<SYNC_PORT_PIN);
if(horizontalLineCount == 525) {
// We've reached the last line
// The last things we do is reset the line counter and return
horizontalLineCount = 1;
return;
}
// If we're in the region to draw the line white,
// then wait the rest of the Back Porch duration,
// then draw the line white
if( (horizontalLineCount > BOX_START_LINE_480P) && (horizontalLineCount < BOX_END_LINE_480P) ) {
// Waiting for back porch to complete
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 11th clock (overhead)
if(drawBox) {
// set Vid to high (i.e. start drawing a white line of the box)
RILT_PORT |= (1<<VID_PORT_PIN);
// Wait for 25% of the screen to turn Vid back to black
// The visible line time for 480p is
// Doesn't have to be exact, just enough to make a visible white box.
uint8_t waitCounter = 6;
while(waitCounter) {
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 10th clock
waitCounter--;
}
RILT_PORT &= ~(1<<VID_PORT_PIN);
}
} else if(horizontalLineCount == 75) {
// draw a pilot line
// Waiting for back porch to complete (approximately 22 clocks minus overhead)
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 10th clock
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t");
__asm__ __volatile__ ("nop\n\t"); // 20th clock
// set Vid to high (i.e. start drawing a white line of the box)
RILT_PORT |= (1<<VID_PORT_PIN);
}
}
// At this point, we've drawn the Front Porch and Sync Pulse.
// If we were drawing the the box lines, we're just after
// the end of the box line being drawn (when the line
// has been turned from white to black).
// If we aren't drawing the box lines, we're near the start
// of the back porch. The Back Porch for 480p is approx 1.9066us,
// and drawing the white line of the box adds approx 6.355us,
// so we accept this margin of error.
// If we're supposed to be measuring lag, then we check to see
// if the sensor has detected light.
// If it has detected light, then we can set measuringLag to false,
//
// we increment the lagLineCounter.
if(measuringLag) {
// We're checking if the SENSOR_PORT_PIN is LOW (light detected).
uint8_t pin = RILT_PIN & (1<<SENSOR_PORT_PIN);
if(lagLineCounter == 1575) {pin = 0;} // Remove once photodiode is implemented
if( pin == 0 ) {
// Light was detected.
// We are no longer measuring lag.
measuringLag = false;
// The value of lagLineCounter will be used
// in another part of the code to show results.
// We also don't need to draw the box.
drawBox = false;
} else {
// Light was not detected.
// Increment the lagLineCounter and move on.
lagLineCounter++;
}
} else {
// We're not measuring lag.
// This means that light was detected.
// We print the result over serial, then wait for
// the number of lines designated by resultLinesWaited
// and reset values
if(resultLinesWaited == RESULT_WAIT_IN_LINES) {
// We've finished waiting.
// We set measuringLag to true, drawBox to true,
// and reset the lagLineCounter
measuringLag = true;
drawBox = true;
lagLineCounter = 0;
// We reset resultWaitInLines
resultLinesWaited = 0;
} else {
if(resultLinesWaited == 0) {
printSerialFlag = true;
Serial.print(lagLineCounter);
Serial.print(" lines of lag detected\n");
}
resultLinesWaited++;
}
}
horizontalLineCount++;
return;
}
////////////////////////////// Interrupt service routing for Timer1 compare //////////////////////////
ISR(TIMER1_COMPA_vect) {
if(vidMode == VIDMODE_240P) {
generate240p();
} else {
generate480p();
}
}
void loop() {
if(printSerialFlag) {
Serial.print(lagLineCounter);
Serial.print(" lines of lag detected\n");
printSerialFlag = false;
}
}