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
#include <SPI.h> | |
#include <Ethernet.h> | |
#include <WebSockets.h> | |
#include <WebSocketsClient.h> | |
#include <WebSocketsServer.h> | |
#include "canvas_htm.h" | |
#include <Camera.h> | |
#define WIZSSIZE 4096 // 4 sockets | |
#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); | |
String HTTP_req; // stores the HTTP request | |
volatile bool camStreamRdy = false; | |
uint8_t * imageBuf = NULL; | |
size_t imageSize = 0; | |
int imageHeight = 0; | |
int imageWidth = 0; | |
unsigned char start_flag = 0xAA; | |
unsigned char end_flag = 0xFF; | |
unsigned char ip_flag = 0x11; | |
IPAddress localip; | |
WebSocketsServer webSocket(81); // create a websocket server on port 81 | |
void startWebSocket() { // Start a WebSocket server | |
webSocket.begin(); // start the websocket server | |
webSocket.onEvent(webSocketEvent); // if there's an incomming websocket message, go to function 'webSocketEvent' | |
Serial.println("WebSocket server started."); | |
} | |
void startWebServer() | |
{ | |
server.begin(); | |
localip = Ethernet.localIP(); | |
Serial.print("HTTP server is at "); | |
Serial.println(localip); | |
} | |
void serve() { | |
static int request = 1; | |
EthernetClient client = server.available(); | |
if (client) | |
{ | |
//Serial.println("New Client."); | |
String currentLine = ""; | |
while (client.connected()) | |
{ | |
if (client.available()) | |
{ | |
char c = client.read(); | |
HTTP_req += c; | |
//Serial.write(c); | |
if (c == '\n') | |
{ | |
if (currentLine.length() == 0) | |
{ | |
client.println("HTTP/1.1 200 OK"); | |
if (HTTP_req.indexOf("/favicon.ico") > -1) { | |
client.println("Content-Type: image/x-icon"); | |
client.println(); | |
}else{ | |
client.println("Content-type:text/html"); | |
client.println(); | |
client.print(canvas_htm); | |
client.println(); | |
} | |
HTTP_req = ""; | |
break; | |
} | |
else | |
{ | |
currentLine = ""; | |
} | |
} | |
else if (c != '\r') | |
{ | |
currentLine += c; | |
} | |
} | |
} | |
// close the connection: | |
client.stop(); | |
} | |
} | |
void webSocketEvent(uint8_t num, WStype_t typein, uint8_t * payload, size_t payloadlength) { // When a WebSocket message is received | |
int blk_count = 0; | |
char canvas_Q_VGA[] = "canvas-Q-VGA"; | |
char ipaddr[26]; | |
switch (typein) { | |
case WStype_DISCONNECTED: // if the websocket is disconnected | |
Serial.printf("[%d]", num); | |
Serial.print(" Disconnected!\n"); | |
break; | |
case WStype_CONNECTED: { // if a new websocket connection is established | |
webSocket.sendBIN(0, &ip_flag, 1); | |
// Serial.println("WS Connected"); | |
// IPAddress ip = webSocket.remoteIP(num); | |
// Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); | |
// parse local IP address | |
sprintf(ipaddr, "%d.%d.%d.%d", localip[0], localip[1], localip[2], localip[3]); | |
webSocket.sendTXT(0, (const char *)ipaddr); | |
} | |
break; | |
case WStype_TEXT: // if new text data is received | |
if (payloadlength == sizeof(canvas_Q_VGA)-1) { | |
if (memcmp(canvas_Q_VGA, payload, payloadlength) == 0) { | |
webSocket.sendBIN(0, &end_flag, 1); | |
} | |
} | |
// capture image from camera stream | |
theCamera.startStreaming(true, CamCB); | |
for(int j=0; j < 1000; j++){ | |
delay(1); | |
if(camStreamRdy == true){ | |
break; | |
} | |
} | |
if (camStreamRdy == true) | |
{ | |
camStreamRdy = false; | |
theCamera.startStreaming(false, CamCB); | |
if(imageBuf != NULL){ | |
size_t len = imageSize/2; | |
blk_count = 2; | |
int j = 0; | |
for (int i=0; i<blk_count; i++) { | |
if (i == 0) { | |
webSocket.sendBIN(0, &start_flag, 1); | |
} | |
if (i == blk_count-1) { | |
webSocket.sendBIN(0, &end_flag, 1); | |
} | |
webSocket.sendBIN(0, &imageBuf[j], len); | |
j += len; | |
} | |
} //imageBuf != NULL | |
} | |
break; | |
case WStype_ERROR: // if new text data is received | |
Serial.println("Error"); | |
default: | |
Serial.print("WStype "); | |
Serial.print(typein); | |
Serial.println(" not handled \n"); | |
} | |
} | |
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("WebSockets Camera Demo"); | |
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. | |
*/ | |
// start the Ethernet connection and the server: | |
Ethernet.init(8); | |
Ethernet.begin(mac, ip); | |
startWebSocket(); | |
startWebServer(); | |
} | |
/** | |
* 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"); | |
} | |
} | |
void loop() | |
{ | |
webSocket.loop(); | |
serve(); | |
} | |
// EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment