Skip to content

Instantly share code, notes, and snippets.

@mhanuel26
Last active March 4, 2019 00:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mhanuel26/41306bf920724df4695c32c641ff0325 to your computer and use it in GitHub Desktop.
Save mhanuel26/41306bf920724df4695c32c641ff0325 to your computer and use it in GitHub Desktop.
/*
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