Skip to content

Commit dbf7fa2

Browse files
committed
fifoless camara working
1 parent 024257a commit dbf7fa2

File tree

8 files changed

+674
-95
lines changed

8 files changed

+674
-95
lines changed

BMP.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#pragma once
2+
3+
//assuming pixel lines have multiples of 4 bytes sizes
4+
class BMP
5+
{
6+
7+
static void setChar(void *buffer, int pos, char ch)
8+
{
9+
*(char*)(buffer+pos) = ch;
10+
}
11+
12+
static void setLong(void *buffer, int pos, long l)
13+
{
14+
*(long*)(buffer+pos) = l;
15+
}
16+
17+
static void setShort(void *buffer, int pos, short s)
18+
{
19+
*(short*)(buffer+pos) = s;
20+
}
21+
22+
public:
23+
static const int headerSize = 54 + 12;
24+
25+
static void construct16BitHeader(void *buffer, long xres, long yres)
26+
{
27+
setChar(buffer, 0, 'B');
28+
setChar(buffer, 1, 'M');
29+
30+
long bytesPerLine = xres * 2;
31+
setLong(buffer, 2, bytesPerLine * yres + 54 + 12); //filesize
32+
setLong(buffer, 6, 0);
33+
34+
setLong(buffer, 10, 54 + 12); //offset
35+
36+
setLong(buffer, 14, 40); //header size
37+
setLong(buffer, 18, xres);
38+
setLong(buffer, 22, yres);
39+
setShort(buffer, 26, 1); //planes
40+
setShort(buffer, 28, 16); //bits
41+
42+
setLong(buffer, 30, 3); //compression 3 = bit fields
43+
setLong(buffer, 38, 0); //x pix per meter
44+
setLong(buffer, 42, 0); //y pix per meter
45+
46+
setLong(buffer, 46, 0); //biClrUsed
47+
setLong(buffer, 50, 0); //biClrImportant
48+
49+
setLong(buffer, 54, 0xF800); //R mask
50+
setLong(buffer, 58, 0x07E0); //G mask
51+
setLong(buffer, 62, 0x001F); //B mask
52+
}
53+
};
54+
55+

ESP32_I2S_Camera.ino

Lines changed: 137 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,158 @@
1-
//#include Camera.h
2-
#include "soc/soc.h"
3-
#include "soc/gpio_sig_map.h"
4-
#include "soc/i2s_reg.h"
5-
#include "soc/i2s_struct.h"
6-
#include "soc/io_mux_reg.h"
7-
8-
#include <driver/dac.h>
9-
10-
#include "I2S.h"
11-
12-
//esp32 mini kit
13-
//boot 0 2 5
14-
//flash 6(clk) 7(sd0) 8(sd1) 9(sd2) 10(sd3) 11(cmd)
15-
//UART 1(tx) 3(rx)
16-
//free pins 4 12(tdi) 13(tck) 14(tms) 15(tdo) 16 17 27 32 33
17-
//spi 18(sck) 19(miso) 23(mosi) 5(ss)
18-
//i2c 21(sda) 22(scl)
19-
//dac 25 26
20-
//input only 34 35 36(svp) 39(svn)
21-
22-
//pins 0 2 5 are used for boot.. only connect hi-z. can still be used as output without external pullups
23-
//free pins 4 12 13 14 15 16 17 27 32 33
24-
//input only 34, 35, 36(VP), 39(VN)
25-
//dac 25, 26
1+
#include "OV7670.h"
2+
3+
#include <Adafruit_GFX.h> // Core graphics library
4+
#include <Adafruit_ST7735.h> // Hardware-specific library
5+
6+
#include <WiFi.h>
7+
#include <WiFiMulti.h>
8+
#include <WiFiClient.h>
9+
#include "BMP.h"
2610

2711
const int SIOD = 21; //SDA
2812
const int SIOC = 22; //SCL
2913

30-
const int VSYNC = 34;//25;
31-
const int HREF = 35;//23;
14+
const int VSYNC = 34;
15+
const int HREF = 35;
3216

33-
const int XCLK = 32;//21;
17+
const int XCLK = 32;
3418
const int PCLK = 33;
3519

36-
const int D0 = 4;
37-
const int D1 = 12;
38-
const int D2 = 13;
39-
const int D3 = 14;
40-
const int D4 = 15;
41-
const int D5 = 16;
42-
const int D6 = 17;
43-
const int D7 = 27;
20+
const int D0 = 27;
21+
const int D1 = 17;
22+
const int D2 = 16;
23+
const int D3 = 15;
24+
const int D4 = 14;
25+
const int D5 = 13;
26+
const int D6 = 12;
27+
const int D7 = 4;
28+
29+
const int TFT_DC = 2;
30+
const int TFT_CS = 5;
31+
//DIN <- MOSI 23
32+
//CLK <- SCK 18
33+
34+
#define ssid1 "YOUR_WIFI_SSID"
35+
#define password1 "YOUR_PASSWORD"
36+
//#define ssid2 ""
37+
//#define password2 ""
4438

45-
const int DC = 2;
39+
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, 0/*no reset*/);
40+
OV7670 *camera;
4641

47-
//const int DAC1 = 25;
48-
//const int DAC2 = 26;
49-
#include <math.h>
42+
WiFiMulti wifiMulti;
43+
WiFiServer server(80);
5044

51-
const int XRES = 640;
52-
const int YRES = 480;
45+
unsigned char bmpHeader[BMP::headerSize];
46+
47+
void serve()
48+
{
49+
WiFiClient client = server.available();
50+
if (client)
51+
{
52+
//Serial.println("New Client.");
53+
String currentLine = "";
54+
while (client.connected())
55+
{
56+
if (client.available())
57+
{
58+
char c = client.read();
59+
//Serial.write(c);
60+
if (c == '\n')
61+
{
62+
if (currentLine.length() == 0)
63+
{
64+
client.println("HTTP/1.1 200 OK");
65+
client.println("Content-type:text/html");
66+
client.println();
67+
client.print(
68+
"<style>body{margin: 0}\nimg{height: 100%; width: auto}</style>"
69+
"<img id='a' src='/camera' onload='this.style.display=\"initial\"; var b = document.getElementById(\"b\"); b.style.display=\"none\"; b.src=\"camera?\"+Date.now(); '>"
70+
"<img id='b' style='display: none' src='/camera' onload='this.style.display=\"initial\"; var a = document.getElementById(\"a\"); a.style.display=\"none\"; a.src=\"camera?\"+Date.now(); '>");
71+
client.println();
72+
break;
73+
}
74+
else
75+
{
76+
currentLine = "";
77+
}
78+
}
79+
else if (c != '\r')
80+
{
81+
currentLine += c;
82+
}
83+
84+
if(currentLine.endsWith("GET /camera"))
85+
{
86+
client.println("HTTP/1.1 200 OK");
87+
client.println("Content-type:image/bmp");
88+
client.println();
89+
90+
for(int i = 0; i < BMP::headerSize; i++)
91+
client.write(bmpHeader[i]);
92+
for(int i = 0; i < camera->xres * camera->yres * 2; i++)
93+
client.write(camera->frame[i]);
94+
}
95+
}
96+
}
97+
// close the connection:
98+
client.stop();
99+
//Serial.println("Client Disconnected.");
100+
}
101+
}
53102

54103
void setup()
55104
{
56105
Serial.begin(115200);
57-
I2S::init(XRES, YRES, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7);
58-
//dac_output_enable(DAC_CHANNEL_1); //25
59-
//dac_output_enable(DAC_CHANNEL_2); //26
106+
107+
wifiMulti.addAP(ssid1, password1);
108+
//wifiMulti.addAP(ssid2, password2);
109+
Serial.println("Connecting Wifi...");
110+
if(wifiMulti.run() == WL_CONNECTED) {
111+
Serial.println("");
112+
Serial.println("WiFi connected");
113+
Serial.println("IP address: ");
114+
Serial.println(WiFi.localIP());
115+
}
116+
117+
camera = new OV7670(OV7670::Mode::QQVGA_RGB565, SIOD, SIOC, VSYNC, HREF, XCLK, PCLK, D0, D1, D2, D3, D4, D5, D6, D7);
118+
BMP::construct16BitHeader(bmpHeader, camera->xres, camera->yres);
60119

120+
tft.initR(INITR_BLACKTAB);
121+
tft.fillScreen(0);
122+
server.begin();
123+
}
124+
125+
void displayY8(unsigned char * frame, int xres, int yres)
126+
{
127+
tft.setAddrWindow(0, 0, yres - 1, xres - 1);
128+
int i = 0;
129+
for(int x = 0; x < xres; x++)
130+
for(int y = 0; y < yres; y++)
131+
{
132+
i = y * xres + x;
133+
unsigned char c = frame[i];
134+
unsigned short r = c >> 3;
135+
unsigned short g = c >> 2;
136+
unsigned short b = c >> 3;
137+
tft.pushColor(r << 11 | g << 5 | b);
138+
}
61139
}
62140

141+
void displayRGB565(unsigned char * frame, int xres, int yres)
142+
{
143+
tft.setAddrWindow(0, 0, yres - 1, xres - 1);
144+
int i = 0;
145+
for(int x = 0; x < xres; x++)
146+
for(int y = 0; y < yres; y++)
147+
{
148+
i = (y * xres + x) << 1;
149+
tft.pushColor((frame[i] | (frame[i+1] << 8)));
150+
}
151+
}
63152

64153
void loop()
65154
{
66-
Serial.print(I2S::blocksReceived);
67-
Serial.print(' ');
68-
Serial.println(I2S::framesReceived);
69-
Serial.print(' ');
70-
for(int i = 0; i < 16; i++)
71-
{
72-
if(I2S::dmaBuffer[0]->buffer[i] < 16) Serial.print('0');
73-
Serial.print(I2S::dmaBuffer[0]->buffer[i], HEX);
74-
}
75-
Serial.println();
76-
delay(1000);
155+
camera->oneFrame();
156+
serve();
157+
displayRGB565(camera->frame, camera->xres, camera->yres);
77158
}

0 commit comments

Comments
 (0)