Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Major refactoring proposal #280

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 9 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
myconfig.h
.pioenvs
.piolibdeps
.clang_complete
.gcc-flags.json
.pio
.vscode
.vscode
.DS_Store
.idea
*.code-workspace
/data/conn.json
/data/cam.json
/data/httpd.json
myconfig.h
Thumbs.db
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ script:
- cd $TRAVIS_BUILD_DIR
- export PATH="$HOME/arduino_ide:$PATH"
- arduino --board esp32:esp32:esp32:PSRAM=enabled,PartitionScheme=min_spiffs,CPUFreq=240,FlashMode=qio,FlashFreq=80,DebugLevel=none --pref compiler.warning_level=all --save-prefs
- arduino --verbose --verify esp32-cam-webserver.ino
- cp --preserve --verbose myconfig.sample.h myconfig.h
- arduino --verbose --verify esp32-cam-webserver.ino
# - arduino --verbose --verify esp32-cam-webserver.ino - commented to let platformio to download libs
- platformio run


Expand Down
205 changes: 164 additions & 41 deletions API.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
# Basic HTTP Commands;
It's an API Jim, but not as we know it
# ESP32-CAM Web Server API
The WebUI and camera server communicate in 2 different ways:
1. Via HTTP requests and responses; this makes controlling all functions of the camera via GET requests
possible.
2. Via a Websocket channel. There are 2 types of channels supported:
a. Streaming channel. Used for pushing video/image data from the server to the client
b. Control channel. Used for controlling PWM outputs on GPIO pins of the board. This may be helpful in
some of the use cases - PTZ servo control, for example.

The WebUI and camera server communicate entirely via HTTP requests and responses; this makes controlling all functions of the camera via GET requests possible. An API in effect.
## HTTP requests and responses
### Web UI pages
* `/` Default index (camera view)
* `/view?mode=stream|still` - Go direct to specific page:
* - stream: starting video capture with full screen mode
* - still: taking a still image with full screen mode
* `/dump` - Status page (automatically refreshed every 5 sec)
* `/setup` - Configure network settings (WiFi, OTA, etc)

## URI's
### Http Port
* `/` - Default index
* `/?view=full|simple|portal` - Go direct to specific index
* `/capture` - Return a Jpeg snapshot image
* `/status` - Returns a JSON string with all camera status <key>/<value> pairs listed
* `/control?var=<key>&val=<val>` - Set `<key>` to `<val>`
* `/dump` - Status page
* `/stop` - End all active streams
### Special *key / val* settings and commands

### Stream Port
* `/` - Raw stream
* `/view` - Stream viewer
* `/control?var=<key>&val=<val>` - Set a Control Variable specified by `<key>` to `<val>`
* `/status` - JSON response containing camera settings
* `/system` - JSON response containing all parameters displayed on the `/dump` page

## *key / val* settings and commands

Call the `/status` URI to recieve a JSON response containing all the available settings and current value.

Call `/control?var=<key>&val=<val>` with a settings key and value to set camera properties or trigger actions.

#### Settings
#### Supported Control Variables:
```
lamp - Lamp value in percent; integer, 0 - 100 (-1 = disabled)
cmdout - send a string to the Serial port. Allows to communicate with external devices (can be other
Arduino board).
lamp - Lamp value in percent; integer, 0 - 100 (-1 = disabled). Controls the brightness of the
flash lamp instantly.
autolamp - 0 = disable, 1 = enable. When set, the flash lamp will be triggered when taking the
still photo.
flashlamp - Sets the level of the flashlamp, which will be automatically triggered at taking the still
image. Values are percentage integers (0-100)
framesize - See below
min_frame_time - Minimal frame duration in ms; used to limit max FPS. Must be positive integer
frame_rate - Frame rate in FPS. Must be positive integer. It is not reccomended to set the frame rate
higher than 50 FPS, otherwise the board may get unstable and stop streaming.
quality - 10 to 63 (ov3660: 4 to 10)
contrast - -2 to 2 (ov3660: -3 to 3)
brightness - -2 to 2 (ov3660: -3 to 3)
Expand Down Expand Up @@ -55,16 +62,8 @@ vflip - 0 = disable, 1 = enable
rotate - Rotation Angle; integer, only -90, 0, 90 values are recognised
dcw - 0 = disable, 1 = enable
colorbar - Overlays a color test pattern on the stream; integer, 1 = enabled
face_detect - Face Detection; 1 = enabled, Only settable if framesize <= 4 (CIF)
face_recognize - Face recognition; 1 = enabled, only settable if Face detection is already enabled
```
#### Read Only
These values are returned in the `/status` JSON response, but cannot be set via the `/control` URI.
```
cam_name - Camera Name; String
code_ver - Code compile date and time; String
stream_url - Raw stream URL; string
```

##### Framesize values
These may vary between different ESP framework releases
```
Expand All @@ -84,14 +83,22 @@ Only for 3Mp+ camera modules:
14 - FHD (1920x1080)
17 - QXGA (2048x1536)
```


#### Commands
These are commands; they can be sent by calling the `/control` URI with them as the `<key>` *(a `<val>` must also be supplied, but can be any value and is ignored)*.
These are commands; they can be sent by calling the `/control` URI with them as
the `<key>` parameter.
```
face_enroll - Enroll a new face in the FaceDB (only when face recognition is avctive)
save_prefs - Saves preferences file
clear_prefs - Deletes the preferences file
reboot - Reboots the camera
* save_prefs - Saves preferences
`val=cam` or not specified will save camera preferences
`val=conn` will save network preferences
* remove_prefs - Deletes camera the preferences
`val=cam` or not specified will reset camera preferences
`val=conn` will reset network preferences. Attention! after this the server will boot as access point after restart, and all
connection settings will be lost.
* reboot - Reboots the board
```

## Examples
* Flash light: on/mid/off
* `http://<IP-ADDRESS>/control?var=lamp&val=100`
Expand All @@ -100,11 +107,127 @@ reboot - Reboots the camera
* Set resolution to VGA
* `http://<IP-ADDRESS>/control?var=framesize&val=8`
* Show camera details and settings
* All settings are returned via single `status` call in [JSON](https://www.json.org/) format.
* All settings are returned via single `status` call in [JSON](https://www.json.org/)
format.
* `http://<IP-ADDRESS>/status`
* Returns:
``` {"lamp":0,"autolamp":0,"min_frame_time":0,"framesize":9,"quality":10,"xclk":8,"brightness":0,"contrast":0,"saturation":0,"sharpness":0,"special_effect":0,"wb_mode":0,"awb":1,"awb_gain":1,"aec":1,"aec2":0,"ae_level":0,"aec_value":204,"agc":1,"agc_gain":0,"gainceiling":0,"bpc":0,"wpc":1,"raw_gma":1,"lenc":1,"vflip":1,"hmirror":1,"dcw":1,"colorbar":0,"cam_name":"ESP32 test camera","code_ver":"Mar 10 2022 @ 14:00:45","rotate":"0","stream_url":"http://10.0.0.181:81/"}```

```json
{"cam_name":"ESP32 CAM Web Server","code_ver":"Jan 7 2023 @ 19:16:55","lamp":0,"autolamp":false,"lamp":0,"flashlamp":0,"rotate":0,"xclk":8,"frame_rate":12,"framesize":8,"quality":12,"brightness":0,"contrast":0,"saturation":0,"sharpness":0,"denoise":0,"special_effect":0,"wb_mode":0,"awb":1,"awb_gain":1,"aec":1,"aec2":0,"ae_level":0,"aec_value":204,"agc":1,"agc_gain":0,"gainceiling":0,"bpc":0,"wpc":1,"raw_gma":1,"lenc":1,"vflip":0,"hmirror":0,"dcw":1,"colorbar":0,"cam_pid":38,"cam_ver":66,"debug_mode":false}
```
* Reboot the camera
* `http://<IP-ADDRESS>/control?var=reboot&val=0`

You can try these yourself in a browser address bar, from the commandline with `curl` and co. or use them programatically from your scripting language of choice.
You can try these yourself in a browser address bar, from the command line with `curl`
and co. or use them programmatically from your scripting language of choice.

## ESP32CAM WebSocket API
This API is intended for fast stateful communication between the server and the browser. You can think of a websocket as a state machine, which can be accessed and programmed from the client side, using JavaScript or any other language, which supports Websocket API.

In order to use the WebSocket API, you need to open the Websocket first. The url of the websocket is always
`ws://<your-ip:your-port>/ws`. In Java Script, you simply need to add the following lines to your page:

```
ws = new WebSocket(websocketURL);
ws.binaryType = 'arraybuffer'; //
```
Once the `ws` object is created successfully, you can handle its events on the page and do whatever is necessary in response. The following key events are supported:

- `onopen()`
If you plan to create a control socket, you need to add the following command to the event handler:
```
ws.send('c); // this instructs the ws that this socket client will be used for control.
```

- `onclose()`
This event is triggered when the client is disconnecting from the socket

- `onerror()`
You may add some code here for handling web socket exceptions

- `onmessage()`
This event is usually processed on the streaming websocket client. Once the stream is started, the server will be pushing the image frames and they need to be processed on the client. Here is a simple example
of the handler for this message:

```
ws.onmessage = function(event) {
var arrayBufferView = new Uint8Array(event.data);
var blob = new Blob([arrayBufferView], {type: "image/jpeg"});
var imageUrl = urlCreator.createObjectURL(blob);
video.src = imageUrl; // "video" here represents an img element on the page where frames are displayed
}
```

Once the websocket is open, you may also send commands and data to the server. Commands are sent with help of the `ws.send(command)` function where the `command` is to be a binary Uint8Array. The first byte of this
array reflects the command code while the rest of bytes can host additional parameters of the command.

The following commands are supported:

- 's' - starts the stream. Once the command is issued, the server will start pushing the frames to the client
according to the camera settings.
- 'p' - similar to the previous command but there will be only one frame taken and pushed to the client.
- 't' - terminates the stream. Only makes sense after 's' commands.
- 'c' - tells the server that this websocket will be used for PWM control commands.
- 'w' - writes the PWM duty value to the pin. This command has additional parameters passed in the bytes of the
`command` array, as follows:

byte0 - 'w' - code of the command
byte1 - pin number. If you use the ESP32CAM-DEV board, the available pins are usually limited to 4,
12, 13 and 33. The 4th pin is connected to the flash lamp so you can control the lamp brightness
by sending value to this pin via the websocket. Pin 33 is connected to the onboard LED. So, only
12 and 13 are the ones you can use, provided that you also use the SD card for storage.
if you use the internal LittleFS for storage, you may be able to use other pins otherwise
utilized by the SD card interface.
byte2 - send 1 for servo mode and 2 for any other PWM.
byte3 - number of bytes in the PWM duty value, which will be written to the pin. Can be either 1 or 2
bytes (either 8bit or 16bit value).
byte4 - duty value to be written to the PWM (lo-byte). For servo it can be either an angle (0-180) or a
byte5 value in seconds (500-2500), which will require byte5 for hi-byte of the value.


## Attaching PWM to the GPIO pins
GPIO pins used for PWM can be defined in the `/httpd.json`, in the `pwm` parameter:

```json
{
"my_name": "ESP32 Web Server",
"lamp":0,
"autolamp":true,
"flashlamp":100,
"pwm": [{"pin":4, "frequency":50000, "resolution":9, "default":0}],
"mapping":[ {"uri":"/img", "path": "/www/img"},
{"uri":"/css", "path": "/www/css"},
{"uri":"/js", "path": "/www/js"}],
"debug_mode": false
}
```

The `pwm` parameter is defined as a JSON array where each object of the array is a definition of one PWM.
Attributes of a pwm object are explained below:

- `pin` - GPIO pin number
- `frequency` - PWM frequency in Herz.
- `resolution` - precision of the PWM (number of bits).
- `default` - initial value of the PWM. if this attribute is not defined, 0 will be used for default.

if the `lamp` parameter in the httpd config is greater or equal to 0, the 1st element of the pwm array
will be used for definition of flash lamp PWM. In the example above, the lamp PWM is configured for pin 4
(used by the flash lamp), 50kHz frequency, 9-bit precision.

Here is another example of the PWM configuration, used for the popular SG90 servo motor on pin 12:

```json
{
"my_name": "ESP32 Web Server",
"lamp":0,
"autolamp":true,
"flashlamp":100,
"pwm": [{"pin":4, "frequency":50000, "resolution":9, "default":0},
{"pin":12, "frequency":50, "resolution":10, "default": 42}],
"mapping":[ {"uri":"/img", "path": "/www/img"},
{"uri":"/css", "path": "/www/css"},
{"uri":"/js", "path": "/www/js"}],
"debug_mode": false
}
```

34 changes: 20 additions & 14 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# Contributing to ESP32-CAM revisited
I love your input! and want to make contributing to this project as easy and transparent as possible, whether it's:
We love your input and want to make contributing to this project as easy and transparent
as possible, whether it's:

- Reporting a bug
- Discussing the current state of the code
- Submitting a fix
- Proposing new features
- Becoming a maintainer

## I Develop with Github
I use github to host code, to track issues and feature requests, as well as accept pull requests.
## We Develop with Github
We use github to host code, to track issues and feature requests, as well as accept pull
requests.

## I Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests
Pull requests are the best way to propose changes to the codebase (I use [Github Flow](https://guides.github.com/introduction/flow/index.html)). I actively welcome your pull requests:
## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html)
So All Code Changes Happen Through Pull Requests. Pull requests are the best way to
propose changes to the codebase (use [Github Flow](https://guides.github.com/introduction/flow/index.html)).
We actively welcome your pull requests:

1. Fork the repo and create your branch from `master`.
2. Give your branch a clear descriptive name and do your changes there.
Expand All @@ -20,10 +24,12 @@ Pull requests are the best way to propose changes to the codebase (I use [Github
5. Clearly describe your changes and the reason for them in the pull request.

## Any contributions you make will be under the GNU Lesser General Public License v2.1
In short, when you submit code changes, your submissions are understood to be under the same [License](./LICENSE) that covers the project.
In short, when you submit code changes, your submissions are understood to be under
the same [License](./LICENSE) that covers the project.

## Report bugs using Github's [issues](https://github.com/easytarget/esp32-cam-webserver/issues)
We use GitHub issues to track public bugs. Report a bug by opening a new issue; it's that easy!
## Report bugs using Github's issues
We use GitHub issues to track public bugs. Report a bug by opening a new issue; it's that
easy!

## Write bug reports with detail, background, and sample code

Expand All @@ -34,16 +40,16 @@ We use GitHub issues to track public bugs. Report a bug by opening a new issue;
- Be specific!
- What you expected would happen
- What actually happens
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)

People *love* thorough bug reports. I'm not even kidding.
- Notes (possibly including why you think this might be happening, or stuff you
tried that didn't work)

## Use a Consistent Coding Style
* 4 spaces for indentation rather than tabs in the main code

## License
By contributing, you agree that your contributions will be licensed under its GNU Lesser General Public License v2.1
By contributing, you agree that your contributions will be licensed under its GNU
Lesser General Public License v2.1



## References
This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md)
21 changes: 0 additions & 21 deletions Docs/favicon-README.md

This file was deleted.

Loading