Skip to content

Instantly share code, notes, and snippets.

@mhanuel26
Created March 5, 2019 01:19
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/13ba34b277f562c7164bf113a7ac67e7 to your computer and use it in GitHub Desktop.
Save mhanuel26/13ba34b277f562c7164bf113a7ac67e7 to your computer and use it in GitHub Desktop.
#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