/
DeepDishCamera
985 lines (755 loc) · 27.6 KB
/
DeepDishCamera
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
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
//#include <Wire.h> (only need this for Arduino. Photon's documentation is from https://docs.particle.io/reference/firmware/photon/#read-)
//PIN DEFINITIONS
#define WRST A5 // Output Write Pointer Reset
#define RRST A4 // Output Read Pointer Reset
#define WEN A2 // Output Write Enable
#define VSYNC D2 // Input Vertical Sync marking frame capture
#define RCLK A3 // Output FIFO buffer output clock
#define DO7 D7
#define DO6 D6
#define DO5 D5
#define DO4 D4
#define DO3 D3
/*#define DO2 D2 //D02-D00 NOT READ OR WIRED
#define DO1 D1
#define DO0 D0 */
//REGISTER DEFINITIONS
// VGA Default
int PHOTO_WIDTH = 640;
int PHOTO_HEIGHT = 480;
int PHOTO_BYTES_PER_PIXEL = 1;
enum ResolutionType
{
VGA,
VGAP,
QVGA,
QQVGA,
None
};
ResolutionType Resolution = None; //WHAT IS THIS LINE FOR?
//REGISTER ADDRESSES AND SETUP
#define CLKRC 0x11
#define CLKRC_VALUE_VGA 0x01 // Raw Bayer
#define CLKRC_VALUE_QVGA 0x01
#define CLKRC_VALUE_QQVGA 0x01
#define CLKRC_VALUE_NIGHTMODE_FIXED 0x03 // Fixed Frame
#define CLKRC_VALUE_NIGHTMODE_AUTO 0x80 // Auto Frame Rate Adjust
#define COM7 0x12
#define COM7_VALUE_VGA 0x01 // Raw Bayer
#define COM7_VALUE_VGA_COLOR_BAR 0x03 // Raw Bayer
#define COM7_VALUE_VGA_PROCESSED_BAYER 0x05 // Processed Bayer
#define COM7_VALUE_QVGA 0x00
#define COM7_VALUE_QVGA_COLOR_BAR 0x02
#define COM7_VALUE_QVGA_PREDEFINED_COLOR_BAR 0x12
#define COM7_VALUE_QQVGA 0x00
#define COM7_VALUE_QQVGA_COLOR_BAR 0x02
#define COM7_VALUE_QCIF 0x08 // Predefined QCIF format
#define COM7_VALUE_COLOR_BAR_QCIF 0x0A // Predefined QCIF Format with ColorBar
#define COM7_VALUE_RESET 0x80
#define COM3 0x0C
#define COM3_VALUE_VGA 0x00 // Raw Bayer
#define COM3_VALUE_QVGA 0x04
#define COM3_VALUE_QQVGA 0x04 // From Docs
#define COM3_VALUE_QQVGA_SCALE_ENABLED 0x0C // Enable Scale and DCW
#define COM3_VALUE_QCIF 0x0C // Enable Scaling and enable DCW
#define COM14 0x3E
#define COM14_VALUE_VGA 0x00 // Raw Bayer
#define COM14_VALUE_QVGA 0x19
#define COM14_VALUE_QQVGA 0x1A
#define COM14_VALUE_MANUAL_SCALING 0x08 // Manual Scaling Enabled
#define COM14_VALUE_NO_MANUAL_SCALING 0x00 // Manual Scaling DisEnabled
#define SCALING_XSC 0x70
#define SCALING_XSC_VALUE_VGA 0x3A // Raw Bayer
#define SCALING_XSC_VALUE_QVGA 0x3A
#define SCALING_XSC_VALUE_QQVGA 0x3A
#define SCALING_XSC_VALUE_QQVGA_SHIFT1 0x3A
#define SCALING_XSC_VALUE_COLOR_BAR 0xBA
#define SCALING_XSC_VALUE_QCIF_COLOR_BAR_NO_SCALE 0x80 // Predefined QCIF with Color Bar and NO Scaling
#define SCALING_YSC 0x71
#define SCALING_YSC_VALUE_VGA 0x35 // Raw Bayer
#define SCALING_YSC_VALUE_QVGA 0x35
#define SCALING_YSC_VALUE_QQVGA 0x35
#define SCALING_YSC_VALUE_COLOR_BAR 0x35 // 8 bar color bar
#define SCALING_YSC_VALUE_COLOR_BAR_GREY 0xB5 // fade to grey color bar
#define SCALING_YSC_VALUE_COLOR_BAR_SHIFT1 0xB5 // fade to grey color bar
#define SCALING_YSC_VALUE_QCIF_COLOR_BAR_NO_SCALE 0x00 // Predefined QCIF with Color Bar and NO Scaling
#define SCALING_DCWCTR 0x72
#define SCALING_DCWCTR_VALUE_VGA 0x11 // Raw Bayer
#define SCALING_DCWCTR_VALUE_QVGA 0x11
#define SCALING_DCWCTR_VALUE_QQVGA 0x22
#define SCALING_PCLK_DIV 0x73
#define SCALING_PCLK_DIV_VALUE_VGA 0xF0 // Raw Bayer
#define SCALING_PCLK_DIV_VALUE_QVGA 0xF1
#define SCALING_PCLK_DIV_VALUE_QQVGA 0xF2
#define SCALING_PCLK_DELAY 0xA2
#define SCALING_PCLK_DELAY_VALUE_VGA 0x02 // Raw Bayer
#define SCALING_PCLK_DELAY_VALUE_QVGA 0x02
#define SCALING_PCLK_DELAY_VALUE_QQVGA 0x02
// works with COM13 for YUV
#define TSLB 0x3A
#define TSLB_VALUE_YUYV_AUTO_OUTPUT_WINDOW_ENABLED 0x01 // No custom scaling
#define TSLB_VALUE_YUYV_AUTO_OUTPUT_WINDOW_DISABLED 0x00 // For adjusting HSTART, etc. YUYV format
#define TSLB_VALUE_UYVY_AUTO_OUTPUT_WINDOW_DISABLED 0x08
#define TSLB_VALUE_TESTVALUE 0x04 // From YCbCr Reference
#define COM13 0x3D
#define COM13_VALUE_DEFAULT 0x88
#define COM13_VALUE_NOGAMMA_YUYV 0x00
#define COM13_VALUE_GAMMA_YUYV 0x80
#define COM13_VALUE_GAMMA_YVYU 0x82
#define COM13_VALUE_YUYV_UVSATAUTOADJ_ON 0x40
// Works with COM4
#define COM17 0x42
#define COM17_VALUE_AEC_NORMAL_NO_COLOR_BAR 0x00
#define COM17_VALUE_AEC_NORMAL_COLOR_BAR 0x08 // Activate Color Bar for DSP
#define COM4 0x0D
// RGB Settings and Data format
#define COM15 0x40
// Night Mode
#define COM11 0x3B
#define COM11_VALUE_NIGHTMODE_ON 0x80 // Night Mode
#define COM11_VALUE_NIGHTMODE_OFF 0x00
#define COM11_VALUE_NIGHTMODE_ON_EIGHTH 0xE0 // Night Mode 1/8 frame rate minimum
#define COM11_VALUE_NIGHTMODE_FIXED 0x0A
#define COM11_VALUE_NIGHTMODE_AUTO 0xEA // Night Mode Auto Frame Rate Adjust
// Color Matrix Control YUV
#define MTX1 0x4f
#define MTX1_VALUE 0x80
#define MTX2 0x50
#define MTX2_VALUE 0x80
#define MTX3 0x51
#define MTX3_VALUE 0x00
#define MTX4 0x52
#define MTX4_VALUE 0x22
#define MTX5 0x53
#define MTX5_VALUE 0x5e
#define MTX6 0x54
#define MTX6_VALUE 0x80
#define CONTRAS 0x56
#define CONTRAS_VALUE 0x40
#define MTXS 0x58
#define MTXS_VALUE 0x9e
// COM8
#define COM8 0x13
#define COM8_VALUE_AWB_OFF 0xE5
#define COM8_VALUE_AWB_ON 0xE7
// Automatic White Balance
#define AWBC1 0x43
#define AWBC1_VALUE 0x14
#define AWBC2 0x44
#define AWBC2_VALUE 0xf0
#define AWBC3 0x45
#define AWBC3_VALUE 0x34
#define AWBC4 0x46
#define AWBC4_VALUE 0x58
#define AWBC5 0x47
#define AWBC5_VALUE 0x28
#define AWBC6 0x48
#define AWBC6_VALUE 0x3a
#define AWBC7 0x59
#define AWBC7_VALUE 0x88
#define AWBC8 0x5A
#define AWBC8_VALUE 0x88
#define AWBC9 0x5B
#define AWBC9_VALUE 0x44
#define AWBC10 0x5C
#define AWBC10_VALUE 0x67
#define AWBC11 0x5D
#define AWBC11_VALUE 0x49
#define AWBC12 0x5E
#define AWBC12_VALUE 0x0E
#define AWBCTR3 0x6C
#define AWBCTR3_VALUE 0x0A
#define AWBCTR2 0x6D
#define AWBCTR2_VALUE 0x55
#define AWBCTR1 0x6E
#define AWBCTR1_VALUE 0x11
#define AWBCTR0 0x6F
#define AWBCTR0_VALUE_NORMAL 0x9F
#define AWBCTR0_VALUE_ADVANCED 0x9E
// Gain
#define COM9 0x14
#define COM9_VALUE_MAX_GAIN_128X 0x6A
#define COM9_VALUE_4XGAIN 0x10 // 0001 0000
#define BLUE 0x01 // AWB Blue Channel Gain
#define BLUE_VALUE 0x40
#define RED 0x02 // AWB Red Channel Gain
#define RED_VALUE 0x40
#define GGAIN 0x6A // AWB Green Channel Gain
#define GGAIN_VALUE 0x40
#define COM16 0x41
#define COM16_VALUE 0x08 // AWB Gain on
#define GFIX 0x69
#define GFIX_VALUE 0x00
// Edge Enhancement Adjustment
#define EDGE 0x3f
#define EDGE_VALUE 0x00
#define REG75 0x75
#define REG75_VALUE 0x03
#define REG76 0x76
#define REG76_VALUE 0xe1
// DeNoise
#define DNSTH 0x4c
#define DNSTH_VALUE 0x00
#define REG77 0x77
#define REG77_VALUE 0x00
// Denoise and Edge Enhancement
#define COM16_VALUE_DENOISE_OFF_EDGE_ENHANCEMENT_OFF_AWBGAIN_ON 0x08 // Denoise off, AWB Gain on
#define COM16_VALUE_DENOISE_ON__EDGE_ENHANCEMENT_OFF__AWBGAIN_ON 0x18
#define COM16_VALUE_DENOISE_OFF__EDGE_ENHANCEMENT_ON__AWBGAIN_ON 0x28
#define COM16_VALUE_DENOISE_ON__EDGE_ENHANCEMENT_ON__AWBGAIN_ON 0x38 // Denoise on, Edge Enhancement on, AWB Gain on
// 30FPS Frame Rate , PCLK = 24Mhz
#define CLKRC_VALUE_30FPS 0x80
#define DBLV 0x6b
#define DBLV_VALUE_30FPS 0x0A
#define EXHCH 0x2A
#define EXHCH_VALUE_30FPS 0x00
#define EXHCL 0x2B
#define EXHCL_VALUE_30FPS 0x00
#define DM_LNL 0x92
#define DM_LNL_VALUE_30FPS 0x00
#define DM_LNH 0x93
#define DM_LNH_VALUE_30FPS 0x00
#define COM11_VALUE_30FPS 0x0A
// Saturation Control
#define SATCTR 0xc9
#define SATCTR_VALUE 0x60
// AEC/AGC - Automatic Exposure/Gain Control
#define GAIN 0x00
#define GAIN_VALUE 0x00
#define AEW 0x24
#define AEW_VALUE 0x95
#define AEB 0x25
#define AEB_VALUE 0x33
#define VPT 0x26
#define VPT_VALUE 0xe3
/*
// Gamma
#define SLOP 0x7a
#define SLOP_VALUE 0x20
#define GAM1 0x7b
#define GAM1_VALUE 0x10
#define GAM2 0x7c
#define GAM2_VALUE 0x1e
#define GAM3 0x7d
#define GAM3_VALUE 0x35
#define GAM4 0x7e
#define GAM4_VALUE 0x5a
#define GAM5 0x7f
#define GAM5_VALUE 0x69
#define GAM6 0x80
#define GAM6_VALUE 0x76
#define GAM7 0x81
#define GAM7_VALUE 0x80
#define GAM8 0x82
#define GAM8_VALUE 0x88
#define GAM9 0x83
#define GAM9_VALUE 0x8f
#define GAM10 0x84
#define GAM10_VALUE 0x96
#define GAM11 0x85
#define GAM11_VALUE 0xa3
#define GAM12 0x86
#define GAM12_VALUE 0xaf
#define GAM13 0x87
#define GAM13_VALUE 0xc4
#define GAM14 0x88
#define GAM14_VALUE 0xd7
#define GAM15 0x89
#define GAM15_VALUE 0xe8
*/
// AEC/AGC Control- Histogram
#define HAECC1 0x9f
#define HAECC1_VALUE 0x78
#define HAECC2 0xa0
#define HAECC2_VALUE 0x68
#define HAECC3 0xa6
#define HAECC3_VALUE 0xd8
#define HAECC4 0xa7
#define HAECC4_VALUE 0xd8
#define HAECC5 0xa8
#define HAECC5_VALUE 0xf0
#define HAECC6 0xa9
#define HAECC6_VALUE 0x90
#define HAECC7 0xaa // AEC Algorithm selection
#define HAECC7_VALUE_HISTOGRAM_AEC_ON 0x94
#define HAECC7_VALUE_AVERAGE_AEC_ON 0x00
/*
// Gamma
#define SLOP 0x7a
#define SLOP_VALUE 0x20
#define GAM1 0x7b
#define GAM1_VALUE 0x10
#define GAM2 0x7c
#define GAM2_VALUE 0x1e
#define GAM3 0x7d
#define GAM3_VALUE 0x35
#define GAM4 0x7e
#define GAM4_VALUE 0x5a
#define GAM5 0x7f
#define GAM5_VALUE 0x69
#define GAM6 0x80
#define GAM6_VALUE 0x76
#define GAM7 0x81
#define GAM7_VALUE 0x80
#define GAM8 0x82
#define GAM8_VALUE 0x88
#define GAM9 0x83
#define GAM9_VALUE 0x8f
#define GAM10 0x84
#define GAM10_VALUE 0x96
#define GAM11 0x85
#define GAM11_VALUE 0xa3
#define GAM12 0x86
#define GAM12_VALUE 0xaf
#define GAM13 0x87
#define GAM13_VALUE 0xc4
#define GAM14 0x88
#define GAM14_VALUE 0xd7
#define GAM15 0x89
#define GAM15_VALUE 0xe8
*/
// Array Control
#define CHLF 0x33
#define CHLF_VALUE 0x0b
#define ARBLM 0x34
#define ARBLM_VALUE 0x11
// ADC Control
#define ADCCTR1 0x21
#define ADCCTR1_VALUE 0x02
#define ADCCTR2 0x22
#define ADCCTR2_VALUE 0x91
#define ADC_ 0x37 // "ADC_" USED TO BE CALLED "ADC" BUT THAT GAVE AN ERROR WITH EXISTING LIBRARY DEFINTIONS OF ADC
#define ADC_VALUE 0x1d
#define ACOM 0x38
#define ACOM_VALUE 0x71
#define OFON 0x39
#define OFON_VALUE 0x2a
// Black Level Calibration
#define ABLC1 0xb1
#define ABLC1_VALUE 0x0c
#define THL_ST 0xb3
#define THL_ST_VALUE 0x82
// Window Output
#define HSTART 0x17
#define HSTART_VALUE_DEFAULT 0x11
#define HSTART_VALUE_VGA 0x13
#define HSTART_VALUE_QVGA 0x13
#define HSTART_VALUE_QQVGA 0x13 // Works
#define HSTOP 0x18
#define HSTOP_VALUE_DEFAULT 0x61
#define HSTOP_VALUE_VGA 0x01
#define HSTOP_VALUE_QVGA 0x01
#define HSTOP_VALUE_QQVGA 0x01 // Works
#define HREF 0x32
#define HREF_VALUE_DEFAULT 0x80
#define HREF_VALUE_VGA 0xB6
#define HREF_VALUE_QVGA 0x24
#define HREF_VALUE_QQVGA 0xA4
#define VSTRT 0x19
#define VSTRT_VALUE_DEFAULT 0x03
#define VSTRT_VALUE_VGA 0x02
#define VSTRT_VALUE_QVGA 0x02
#define VSTRT_VALUE_QQVGA 0x02
#define VSTOP 0x1A
#define VSTOP_VALUE_DEFAULT 0x7B
#define VSTOP_VALUE_VGA 0x7A
#define VSTOP_VALUE_QVGA 0x7A
#define VSTOP_VALUE_QQVGA 0x7A
#define VREF 0x03
#define VREF_VALUE_DEFAULT 0x03
#define VREF_VALUE_VGA 0x0A
#define VREF_VALUE_QVGA 0x0A
#define VREF_VALUE_QQVGA 0x0A
// I2C
#define OV7670_I2C_ADDRESS 0x21
#define I2C_ERROR_WRITING_START_ADDRESS 11
#define I2C_ERROR_WRITING_DATA 22
#define DATA_TOO_LONG 1 // data too long to fit in transmit buffer
#define NACK_ON_TRANSMIT_OF_ADDRESS 2 // received NACK on transmit of address
#define NACK_ON_TRANSMIT_OF_DATA 3 // received NACK on transmit of data
#define OTHER_ERROR 4 // other error
#define I2C_READ_START_ADDRESS_ERROR 33
#define I2C_READ_DATA_SIZE_MISMATCH_ERROR 44
// Helper functions
byte ReadRegisterValue(int RegisterAddress)
{
byte data = 0;
Wire.beginTransmission(OV7670_I2C_ADDRESS); // Unchanged - same syntax as Arduino: https://docs.particle.io/reference/firmware/photon/#wire-i2c-
Wire.write(RegisterAddress);
Wire.endTransmission();
Wire.requestFrom(OV7670_I2C_ADDRESS, 1);
while(Wire.available() < 1);
data = Wire.read();
return data;
}
// Creates data byte from D0:7 high/low
byte ConvertPinValueToByteValue(int PinValue, int PinPosition)
{
byte ByteValue = 0;
if (PinValue == HIGH)
{
ByteValue = 1 << PinPosition;
}
return ByteValue;
}
//I2C debugging
String ParseI2CResult(int result)
{
String sresult = "";
switch(result)
{
case 0:
sresult = "I2C Operation OK ...";
break;
case I2C_ERROR_WRITING_START_ADDRESS:
sresult = "I2C_ERROR_WRITING_START_ADDRESS";
break;
case I2C_ERROR_WRITING_DATA:
sresult = "I2C_ERROR_WRITING_DATA";
break;
case DATA_TOO_LONG:
sresult = "DATA_TOO_LONG";
break;
case NACK_ON_TRANSMIT_OF_ADDRESS:
sresult = "NACK_ON_TRANSMIT_OF_ADDRESS";
break;
case NACK_ON_TRANSMIT_OF_DATA:
sresult = "NACK_ON_TRANSMIT_OF_DATA";
break;
case OTHER_ERROR:
sresult = "OTHER_ERROR";
break;
default:
sresult = "I2C ERROR TYPE NOT FOUND...";
break;
}
return sresult;
}
void PulseLowEnabledPin(int PinNumber, int DurationMicroSecs)
{
// For Low Enabled Pins , 0 = on and 1 = off
digitalWrite(PinNumber, LOW); // Sets the pin on - SAME AS ARDUINO SYNTAX
delayMicroseconds(DurationMicroSecs); // Pauses for DurationMicroSecs microseconds
digitalWrite(PinNumber, HIGH); // Sets the pin off
delayMicroseconds(DurationMicroSecs); // Pauses for DurationMicroSecs microseconds
}
void PulsePin(int PinNumber, int DurationMicroSecs)
{
digitalWrite(PinNumber, HIGH); // Sets the pin on
delayMicroseconds(DurationMicroSecs); // Pauses for DurationMicroSecs microseconds
digitalWrite(PinNumber, LOW); // Sets the pin off
delayMicroseconds(DurationMicroSecs); // Pauses for DurationMicroSecs microseconds
}
//I2C commands
// I2C helper function - write
int OV7670Write(int start, const byte *pData, int size)
{
int n, error;
Wire.beginTransmission(OV7670_I2C_ADDRESS);
n = Wire.write(start); // write the start address
if (n != 1)
{
return (I2C_ERROR_WRITING_START_ADDRESS);
}
n = Wire.write(pData, size); // write data bytes
if (n != size)
{
return (I2C_ERROR_WRITING_DATA);
}
error = Wire.endTransmission(true); // release the I2C-bus
if (error != 0)
{
return (error);
}
return 0; // return : no error
}
// I2C writing a single register
int OV7670WriteReg(int reg, byte data)
{
int error;
error = OV7670Write(reg, &data, 1);
return (error);
}
// I2C helper function - read
int OV7670Read(int start, byte *buffer, int size)
{
int i, n; // THERE USED TO BE ANOTHER int CALLED "error" BUT THAT GAVE ME AN ERROR
Wire.beginTransmission(OV7670_I2C_ADDRESS);
n = Wire.write(start);
if (n != 1)
{
return (I2C_READ_START_ADDRESS_ERROR);
}
n = Wire.endTransmission(false); // hold the I2C-bus
if (n != 0)
{
return (n);
}
// Third parameter is true: relase I2C-bus after data is read.
Wire.requestFrom(OV7670_I2C_ADDRESS, size, true);
i = 0;
while(Wire.available() && i<size)
{
buffer[i++] = Wire.read();
}
if ( i != size)
{
return (I2C_READ_DATA_SIZE_MISMATCH_ERROR);
}
return (0); // return no error
}
//
// A function to read a single register
//
int OV7670ReadReg(int reg, byte *data)
{
int error;
error = OV7670Read(reg, data, 1);
return (error);
}
void setup() {
//0. Turn on Serial and SPI communication
Serial.begin(9600);
Serial.printf("Starting Serial - Jackie")
Wire.begin();
Serial.printf("Starting wire - Jackie")
//1. Reset camera registers
// from "ResetCameraRegisters"
//Detail: "Reading needed to prevent error"
byte data = ReadRegisterValue(COM7);
int result = OV7670WriteReg(COM7, COM7_VALUE_RESET );
String sresult = ParseI2CResult(result);
Serial.println("RESETTING ALL REGISTERS BY SETTING COM7 REGISTER to 0x80: " + sresult);
// Delay at least 500ms
delay(500);
// from "ReadRegisters()"
data = 0; //THIS USED TO SAY "byte data = 0" BUT "data" WAS ALREADY DEFINED AS BYTE AROUND LINE 693
data = ReadRegisterValue(CLKRC);
data = ReadRegisterValue(COM7);
data = ReadRegisterValue(COM3);
data = ReadRegisterValue(COM14);
data = ReadRegisterValue(SCALING_XSC);
data = ReadRegisterValue(SCALING_YSC);
data = ReadRegisterValue(SCALING_DCWCTR);
data = ReadRegisterValue(SCALING_PCLK_DIV);
data = ReadRegisterValue(SCALING_PCLK_DELAY);
data = ReadRegisterValue(TSLB);
data = ReadRegisterValue(COM13);
data = ReadRegisterValue(COM17);
data = ReadRegisterValue(COM4);
data = ReadRegisterValue(COM15);
data = ReadRegisterValue(COM11);
data = ReadRegisterValue(COM8);
data = ReadRegisterValue(HAECC7);
data = ReadRegisterValue(GFIX);
data = ReadRegisterValue(HSTART);
data = ReadRegisterValue(HSTOP);
data = ReadRegisterValue(HREF);
data = ReadRegisterValue(VSTRT);
data = ReadRegisterValue(VSTOP);
data = ReadRegisterValue(VREF);
// 2. Set up the camera
// from "SetupCamera"
Serial.println(F("Initializing OV7670 Camera ..."));
//Set WRST to 0 and RRST to 0 , 0.1ms after power on.
int DurationMicroSecs = 1;
// Set mode for pins wither input or output
pinMode(WRST , OUTPUT);
pinMode(RRST , OUTPUT);
pinMode(WEN , OUTPUT);
pinMode(VSYNC, INPUT);
pinMode(RCLK , OUTPUT);
// FIFO Ram output pins
pinMode(DO7 , INPUT);
pinMode(DO6 , INPUT);
pinMode(DO5 , INPUT);
pinMode(DO4 , INPUT);
pinMode(DO3 , INPUT);
// pinMode(DO2 , INPUT);
// pinMode(DO1 , INPUT);
// pinMode(DO0 , INPUT);
// Delay 1 ms
delay(1);
PulseLowEnabledPin(WRST, DurationMicroSecs);
// Need to clock the fifo manually to get it to reset
digitalWrite(RRST, LOW);
PulsePin(RCLK, DurationMicroSecs);
PulsePin(RCLK, DurationMicroSecs);
digitalWrite(RRST, HIGH);
// 3. Setting camera registers
result = 0; //THIS USED TO SAY "int reslt" BUT "result" WAS ALREADY DEFINED AS BYTE AROUND LINE 695
result = OV7670WriteReg(AWBC1, AWBC1_VALUE); //AWB
result = OV7670WriteReg(AWBC2, AWBC2_VALUE);
result = OV7670WriteReg(AWBC3, AWBC3_VALUE);
result = OV7670WriteReg(AWBC4, AWBC4_VALUE);
result = OV7670WriteReg(AWBC5, AWBC5_VALUE);
result = OV7670WriteReg(AWBC6, AWBC6_VALUE);
result = OV7670WriteReg(AWBC7, AWBC7_VALUE);
result = OV7670WriteReg(AWBC8, AWBC8_VALUE);
result = OV7670WriteReg(AWBC9, AWBC9_VALUE);
result = OV7670WriteReg(AWBC10, AWBC10_VALUE);
result = OV7670WriteReg(AWBC11, AWBC11_VALUE);
result = OV7670WriteReg(AWBC12, AWBC12_VALUE);
result = OV7670WriteReg(AWBCTR3, AWBCTR3_VALUE);
result = OV7670WriteReg(AWBCTR2, AWBCTR2_VALUE);
result = OV7670WriteReg(AWBCTR1, AWBCTR1_VALUE);
result = OV7670WriteReg(0xB0, 0x84); //improves color
result = OV7670WriteReg(CLKRC, CLKRC_VALUE_30FPS); //30 FPS
result = OV7670WriteReg(DBLV, DBLV_VALUE_30FPS);
result = OV7670WriteReg(EXHCH, EXHCH_VALUE_30FPS);
result = OV7670WriteReg(EXHCL, EXHCL_VALUE_30FPS);
result = OV7670WriteReg(DM_LNL, DM_LNL_VALUE_30FPS);
result = OV7670WriteReg(DM_LNH, DM_LNH_VALUE_30FPS);
result = OV7670WriteReg(COM11, COM11_VALUE_30FPS);
result = OV7670WriteReg(ABLC1, ABLC1_VALUE); //ABLC
result = OV7670WriteReg(THL_ST, THL_ST_VALUE);
result = OV7670WriteReg(CLKRC, CLKRC_VALUE_VGA); //Resolution VGA
result = OV7670WriteReg(COM7, COM7_VALUE_VGA );
result = OV7670WriteReg(COM3, COM3_VALUE_VGA);
result = OV7670WriteReg(COM14, COM14_VALUE_VGA );
result = OV7670WriteReg(SCALING_XSC,SCALING_XSC_VALUE_VGA );
result = OV7670WriteReg(SCALING_YSC,SCALING_YSC_VALUE_VGA );
result = OV7670WriteReg(SCALING_DCWCTR, SCALING_DCWCTR_VALUE_VGA );
result = OV7670WriteReg(SCALING_PCLK_DIV, SCALING_PCLK_DIV_VALUE_VGA);
result = OV7670WriteReg(SCALING_PCLK_DELAY,SCALING_PCLK_DELAY_VALUE_VGA);
result = OV7670WriteReg(COM17, COM17_VALUE_AEC_NORMAL_NO_COLOR_BAR); //Color bar test
result = OV7670WriteReg(0xB0, 0x8c); //Green to Red color correction
result = OV7670WriteReg(AEW, AEW_VALUE); // AEC (Auto Exposure Control)-average
result = OV7670WriteReg(AEB, AEB_VALUE);
result = OV7670WriteReg(VPT, VPT_VALUE);
result = OV7670WriteReg(HAECC7, HAECC7_VALUE_AVERAGE_AEC_ON);
result = OV7670WriteReg(SATCTR, SATCTR_VALUE); // Saturation
result = OV7670WriteReg(CHLF, CHLF_VALUE); //Camera array control
result = OV7670WriteReg(ARBLM, ARBLM_VALUE);
result = OV7670WriteReg(ADCCTR1, ADCCTR1_VALUE); // ADC
result = OV7670WriteReg(ADCCTR2, ADCCTR2_VALUE);
result = OV7670WriteReg(ADC_, ADC_VALUE); // CHANGED "ADC" TO "ADC_" BECAUSE OF ERROR - SEE ITS DEFINITION AROUND LINE 451
result = OV7670WriteReg(ACOM, ACOM_VALUE);
result = OV7670WriteReg(OFON, OFON_VALUE);
result = OV7670WriteReg(HSTART, HSTART_VALUE_VGA ); // Window output parameters
result = OV7670WriteReg(HSTOP, HSTOP_VALUE_VGA );
result = OV7670WriteReg(HREF, HREF_VALUE_VGA );
result = OV7670WriteReg(VSTRT, VSTRT_VALUE_VGA );
result = OV7670WriteReg(VSTOP, VSTOP_VALUE_VGA );
result = OV7670WriteReg(VREF, VREF_VALUE_VGA );
result = OV7670WriteReg(COM9, COM9_VALUE_4XGAIN); // Gain
result = OV7670WriteReg(BLUE, BLUE_VALUE);
result = OV7670WriteReg(RED, RED_VALUE);
result = OV7670WriteReg(GGAIN, GGAIN_VALUE);
result = OV7670WriteReg(COM16, COM16_VALUE);
result = OV7670WriteReg(SATCTR, SATCTR_VALUE); //Saturation
result = OV7670WriteReg(MTX1, MTX1_VALUE); //YUV Color Matrix
result = OV7670WriteReg(MTX2, MTX2_VALUE);
result = OV7670WriteReg(MTX3, MTX3_VALUE);
result = OV7670WriteReg(MTX4, MTX4_VALUE);
result = OV7670WriteReg(MTX5, MTX5_VALUE);
result = OV7670WriteReg(MTX6, MTX6_VALUE);
result = OV7670WriteReg(CONTRAS, CONTRAS_VALUE);
result = OV7670WriteReg(MTXS, MTXS_VALUE);
result = OV7670WriteReg(DNSTH, DNSTH_VALUE); //Denoise
result = OV7670WriteReg(REG77, REG77_VALUE);
result = OV7670WriteReg(EDGE, EDGE_VALUE); //Edge enhancement
result = OV7670WriteReg(REG75, REG75_VALUE);
result = OV7670WriteReg(REG76, REG76_VALUE);
delay(100);
/* // Set up the SD card
pinMode(HardwareSSPin, OUTPUT);
if (!SD.begin(chipSelect))
{
Serial.println("Couldn't initialize SD card with chipSelect.");
return;
}*/
}
// DON'T NEED TO USE SD CARD FOR PHOTON
void loop() {
// put your main code here, to run repeatedly:
byte PixelData = 0;
byte PinVal7 = 0;
byte PinVal6 = 0;
byte PinVal5 = 0;
byte PinVal4 = 0;
byte PinVal3 = 0;
// byte PinVal2 = 0; NOT USING THESE DATA PINS - see the first lines of this code
// byte PinVal1 = 0;
// byte PinVal0 = 0;
//CREATE AND SAVE IMAGE FILE
Serial.println(F("Running loop to read and transmit photo."));
unsigned long DurationStart = 0;
unsigned long DurationStop = 0;
//Capture one frame into FIFO memory
// 1. VSync pulse to indicate START of image
DurationStart = pulseIn(VSYNC, HIGH);
// 2. Reset Write Pointer to 0
PulseLowEnabledPin(WRST, 6); // 6 microseconds
// 3. Set FIFO Write Enable high to write to RAM
digitalWrite(WEN, HIGH);
// 4.VSync pulse to indicate END of image
DurationStop = pulseIn(VSYNC, HIGH);
// 5. Set FIFO Write Enable to low to end write
digitalWrite(WEN, LOW);
Serial.print(F("VSync start (microsecs) = "));
Serial.println(DurationStart);
Serial.print(F("VSync end (microsecs) = "));
Serial.println(DurationStop);
delay(2);
/* //Create the image file
String Ext = ".raw";
String Filename = "";
Filename = "VGA" + PhotoTakenCount + Ext;
File Filename;
ImageOutputFile = SD.open(Filename.c_str(), FILE_WRITE);
//Test if file is open
if (!ImageOutputFile)
{ Serial.println(F("Error, can't open Image File to write to"));
return; } */
//Set Read Reset to start of frame
digitalWrite(RRST, LOW);
PulsePin(RCLK, 1);
PulsePin(RCLK, 1);
PulsePin(RCLK, 1);
digitalWrite(RRST, HIGH);
//Read and write each pixel
unsigned long ByteCounter = 0;
for (int height = 0; height < PHOTO_HEIGHT; height++)
{
for (int width = 0; width < PHOTO_WIDTH; width++)
{
for (int bytenumber = 0; bytenumber < PHOTO_BYTES_PER_PIXEL; bytenumber++)
{
// Pulse the read clock RCLK to bring in new byte of data.
PulsePin(RCLK, 1);
// Convert Pin values to byte values for pins 0-7 of incoming pixel byte
PinVal7 = ConvertPinValueToByteValue(digitalRead(DO7), 7);
PinVal6 = ConvertPinValueToByteValue(digitalRead(DO6), 6);
PinVal5 = ConvertPinValueToByteValue(digitalRead(DO5), 5);
PinVal4 = ConvertPinValueToByteValue(digitalRead(DO4), 4);
PinVal3 = ConvertPinValueToByteValue(digitalRead(DO3), 3);
//PinVal2 = ConvertPinValueToByteValue(digitalRead(DO2), 2);
//PinVal1 = ConvertPinValueToByteValue(digitalRead(DO1), 1);
//PinVal0 = ConvertPinValueToByteValue(digitalRead(DO0), 0);
PixelData = PinVal7 | PinVal6 | PinVal5 | PinVal4 | PinVal3 /*| PinVal2 | PinVal1 | PinVal0*/;
// ByteCounter = ByteCounter + ImageOutputFile.write(PixelData); CHANGE WRITING TO SD TO WRITING TO SERIAL
ByteCounter = ByteCounter + Serial.write(PixelData);
}
}
}
/*ImageOutputFile.close();*/
Serial.print(F("Total bytes = "));
Serial.println(ByteCounter);
/*
//CREATE AND SAVE IMAGE'S INFO FILE
String Ext = ".txt";
String Filename = "";
Filename = "VGA" + PhotoTakenCount + Ext;
String Info = "";
Info = "VGA" + " " + FPSParam + " " + AWBParam + " " + AECParam + " " + YUVMatrixParam + " " +
DenoiseParam + " " + EdgeParam + " " + ABLCParam;
File InfoFile;
InfoFile = SD.open(Filename.c_str(), FILE_WRITE);
//Test if file is open
if (!InfoFile)
{ Serial.println(F("Error, can't open Info File to write to"));
return;}
InfoFile.println(Info);
InfoFile.close();*/
}