-
-
Save mhanuel26/41306bf920724df4695c32c641ff0325 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Spresense Basic BMP HTML Web Camera - No streaming, still image only. | |
*/ | |
#include <SPI.h> | |
#include <Ethernet.h> | |
#include "BMP.h" | |
#include <Camera.h> | |
#define WIZSSIZE 8192 | |
#define PIN_SPI_SS_ETHERNET_LIB 8 | |
// Enter a MAC address and IP address for your controller below. | |
// The IP address will be dependent on your local network: | |
byte mac[] = { | |
0x00, 0x08, 0xDC, 0x1D, 0x2C, 0x3D | |
}; | |
IPAddress ip(192, 168, 1, 145); | |
// Initialize the Ethernet server library | |
// with the IP address and port you want to use | |
// (port 80 is default for HTTP): | |
EthernetServer server(80); | |
volatile bool camStreamRdy = false; | |
unsigned char bmpHeader[BMP::headerSize]; | |
uint8_t * imageBuf = NULL; | |
size_t imageSize = 0; | |
int imageHeight = 0; | |
int imageWidth = 0; | |
void setup() { | |
// Open serial communications and wait for port to open: | |
Serial.begin(115200); | |
while (!Serial) { | |
; // wait for serial port to connect. Needed for native USB port only | |
} | |
/* begin() without parameters means that | |
* number of buffers = 1, 30FPS, QVGA, YUV 4:2:2 format */ | |
Serial.println("Prepare camera"); | |
theCamera.begin(1, | |
CAM_VIDEO_FPS_30, | |
CAM_IMGSIZE_QVGA_H, | |
CAM_IMGSIZE_QVGA_V, | |
CAM_IMAGE_PIX_FMT_YUV422); | |
/* Start video stream. | |
* If received video stream data from camera device, | |
* camera library call CamCB. | |
*/ | |
Serial.println("Start streaming"); | |
theCamera.startStreaming(false, CamCB); | |
/* Auto white balance configuration */ | |
Serial.println("Set Auto white balance parameter"); | |
theCamera.setAutoWhiteBalanceMode(CAM_WHITE_BALANCE_SHADE); | |
/* Set parameters about still picture. | |
* In the following case, QUADVGA and JPEG. | |
*/ | |
Serial.println("Start streaming"); | |
theCamera.setStillPictureImageFormat( | |
CAM_IMGSIZE_QVGA_H, | |
CAM_IMGSIZE_QVGA_V, | |
CAM_IMAGE_PIX_FMT_JPG); | |
// start the Ethernet connection and the server: | |
Ethernet.init(8); | |
Ethernet.begin(mac, ip); | |
server.begin(); | |
Serial.print("server is at "); | |
Serial.println(Ethernet.localIP()); | |
} | |
/** | |
* Callback from Camera library when video frame is captured. | |
*/ | |
void CamCB(CamImage img) | |
{ | |
/* Check the img instance is available or not. */ | |
if (img.isAvailable()) | |
{ | |
/* If you want RGB565 data, convert image data format to RGB565 */ | |
img.convertPixFormat(CAM_IMAGE_PIX_FMT_RGB565); | |
imageBuf = img.getImgBuff(); | |
imageSize = img.getImgSize(); | |
imageHeight = img.getHeight(); | |
imageWidth = img.getWidth(); | |
/* You can use image data directly by using getImgSize() and getImgBuff(). | |
* for displaying image to a display, etc. */ | |
camStreamRdy = true; | |
} | |
else | |
{ | |
Serial.print("Failed to get video stream image\n"); | |
} | |
theCamera.startStreaming(false, CamCB); | |
} | |
void serve() | |
{ | |
EthernetClient client = server.available(); | |
if (client) | |
{ | |
Serial.println("New Client."); | |
String currentLine = ""; | |
while (client.connected()) | |
{ | |
if (client.available()) | |
{ | |
char c = client.read(); | |
Serial.write(c); | |
if (c == '\n') | |
{ | |
if (currentLine.length() == 0) | |
{ | |
Serial.println("sending response"); | |
client.println("HTTP/1.1 200 OK"); | |
client.println("Content-type:text/html"); | |
client.println(); | |
client.print( | |
"<style>body{margin: 0}\nimg{height: auto; width: auto}</style>" | |
"<img id='a' src='/camera' onload='this.style.display=\"initial\"; var b = document.getElementById(\"b\"); b.style.display=\"none\"; b.src=\"camera?\"+Date.now(); '>" | |
"<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(); '>"); | |
client.println(); | |
break; | |
} | |
else | |
{ | |
currentLine = ""; | |
} | |
} | |
else if (c != '\r') | |
{ | |
currentLine += c; | |
} | |
if(currentLine.endsWith("GET /camera")) | |
{ | |
imageBuf = NULL; | |
theCamera.startStreaming(true, CamCB); | |
for(int j=0; j < 1000; j++){ | |
delay(1); | |
if(camStreamRdy == true){ | |
theCamera.startStreaming(false, CamCB); | |
break; | |
} | |
} | |
if (camStreamRdy == true) | |
{ | |
camStreamRdy = false; | |
if(imageBuf != NULL){ | |
client.println("HTTP/1.1 200 OK"); | |
client.println("Content-Type: image/bmp"); | |
client.println(); | |
BMP::construct16BitHeader(bmpHeader, imageWidth, imageHeight); | |
for(int i = 0; i < BMP::headerSize; i++){ | |
client.write(bmpHeader[i]); | |
} | |
size_t len = imageSize; | |
int i = 0; | |
while(len > 0){ | |
if(len > WIZSSIZE){ | |
client.write(&imageBuf[i], WIZSSIZE); | |
i += WIZSSIZE; | |
len -= WIZSSIZE; | |
}else{ | |
client.write(&imageBuf[i], len); | |
break; | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
// close the connection: | |
client.stop(); | |
// Serial.println("Client Disconnected."); | |
} | |
} | |
void loop() { | |
serve(); | |
} | |
// EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment