Skip to content

Commit c8e9497

Browse files
authored
v10.5.4
1 parent 0e25c1f commit c8e9497

File tree

7 files changed

+58
-32
lines changed

7 files changed

+58
-32
lines changed

ESP32-CAM_MJPEG2SD.ino

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,6 @@ void setup() {
6161
#if INCLUDE_TGRAM
6262
prepTelegram();
6363
#endif
64-
#ifndef AUXILIARY
65-
prepRecording();
66-
#endif
6764
#if INCLUDE_I2C
6865
prepI2C();
6966
#if INCLUDE_TELEM
@@ -73,8 +70,11 @@ void setup() {
7370
#if INCLUDE_PERIPH
7471
startHeartbeat();
7572
#endif
76-
#if INCLUDE_RTSP
73+
#ifndef AUXILIARY
74+
prepRecording();
75+
#if INCLUDE_RTSP
7776
prepRTSP();
77+
#endif
7878
#endif
7979
checkMemory();
8080
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44
Application for ESP32 / ESP32S3 with OV2640 / OV5640 camera to record JPEGs to SD card as AVI files and playback to browser as an MJPEG stream. The AVI format allows recordings to replay at correct frame rate on media players. If a microphone is installed then a WAV file is also created and stored in the AVI file.
55
The application supports:
6-
* [RTSP Server](#rtsp) stream Video, Audio and Subtitles
76
* [Motion detection by camera](#motion-detection-by-camera) or PIR / radar sensor
87
* Time lapse recording
98
* [Audio Recording](#audio-recording) from I2S or PDM microphones
109
* Camera pan / tilt servos and lamp control
10+
* [RTSP Server](#rtsp) stream Video, Audio and Subtitles
1111
* [Telemetry Recording](#telemetry-recording) during camera recording.
1212
* [Remote Control](#remote-control) of camera mounted vehicle.
1313
* Alert notification using [Telegram](#telegram-bot) or Email
@@ -30,11 +30,11 @@ To suggest an improvement or enhancement use Discussions.***
3030

3131
Changes up to version 10.5.4:
3232
* Stream to [NVR](#stream-to-nvr) using integration to RTSPServer library contributed by [@rjsachse](https://github.com/rjsachse).
33-
* RTSP server now has multiple client support as well as user/pass authentication.
3433
* Frame resolution selection mismatch corrected due to [#10801](https://github.com/espressif/arduino-esp32/issues/10801) in arduino core v3.1.0
3534
* SD card 4 bit mode configurable (see `utilsFS.cpp`)
3635
* Shared I2C fixed following code changes in Arduino core v3.1.1
3736
* 24Mhz camera clock available for faster frame rate on ESP32S3, contributed by [@josef2600](https://github.com/josef2600).
37+
* RTSP server now has multiple client support as well as user/pass authentication.
3838

3939
## Purpose
4040

appGlobals.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
#define INCLUDE_EXTHB false // externalHeartbeat.cpp (heartbeat to remote server)
6363
#define INCLUDE_PGRAM false // photogram.cpp (photogrammetry feature). Needs INCLUDE_PERIPH true
6464
#define INCLUDE_MCPWM false // mcpwm.cpp (BDC motor control). Needs INCLUDE_PERIPH true
65-
#define INCLUDE_RTSP false // rtsp.cpp (RTSP Streaming). Requires additional library: Latest ESP32-RTSPServer (https://github.com/rjsachse/ESP32-RTSPServer)
65+
#define INCLUDE_RTSP false // rtsp.cpp (RTSP Streaming). Requires additional library: ESP32-RTSPServer
6666
#define INCLUDE_DS18B20 false // if true, requires INCLUDE_PERIPH and additional libraries: OneWire and DallasTemperature
6767
#define INCLUDE_I2C false // periphsI2C.cpp (support for I2C peripherals)
6868

@@ -282,6 +282,7 @@ bool setOutputPeripheral(uint8_t cmd, uint32_t rxValue);
282282
void setSteering(int steerVal);
283283
void setStepperPin(uint8_t pinNum, uint8_t pinPos);
284284
void setStickTimer(bool restartTimer, uint32_t interval = 0);
285+
bool shareI2C(int sdaShare, int sclShare);
285286
void startAudioRecord();
286287
void startHeartbeat();
287288
void startSustainTasks();

appSpecific.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ bool updateAppStatus(const char* variable, const char* value, bool fromUser) {
228228
else if (!strcmp(variable, "uartTxdPin")) uartTxdPin = intVal;
229229
else if (!strcmp(variable, "uartRxdPin")) uartRxdPin = intVal;
230230
#endif
231+
231232
#ifndef AUXILIARY
232233
// camera settings
233234
else if (!strcmp(variable, "xclkMhz")) xclkMhz = intVal;

mjpeg2sd.cpp

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ uint8_t xclkMhz = 20; // camera clock rate MHz
3535
bool doKeepFrame = false;
3636
static bool haveSrt = false;
3737
char camModel[10];
38+
static int siodGpio = SIOD_GPIO_NUM;
39+
static int siocGpio = SIOC_GPIO_NUM;
3840

3941
// header and reporting info
4042
static uint32_t vidSize; // total video size
@@ -841,7 +843,7 @@ static esp_err_t changeXCLK(camera_config_t config) {
841843
.speed_mode = LEDC_LOW_SPEED_MODE,
842844
.duty_resolution = LEDC_TIMER_1_BIT,
843845
.timer_num = config.ledc_timer,
844-
.freq_hz = (uint32_t)config.xclk_freq_hz, // Fix arduino warning: narrowing conversion from 'int' to 'uint32_t'
846+
.freq_hz = (uint32_t)config.xclk_freq_hz,
845847
.clk_cfg = LEDC_AUTO_CLK
846848
};
847849
res = ledc_timer_config(&ledc_timer);
@@ -873,7 +875,14 @@ bool prepCam() {
873875
if (FRAMESIZE_INVALID != sizeof(frameData) / sizeof(frameData[0]))
874876
LOG_ERR("framesize_t entries %d != frameData entries %d", FRAMESIZE_INVALID, sizeof(frameData) / sizeof(frameData[0]));
875877
if (!camPower()) return false;
876-
878+
#if INCLUDE_I2C
879+
if (shareI2C(SIOD_GPIO_NUM, SIOC_GPIO_NUM)) {
880+
// if shared, set camera to use shared
881+
siodGpio = -1;
882+
siocGpio = -1;
883+
}
884+
#endif
885+
877886
bool res = false;
878887
// buffer sizing depends on psram size (4M or 8M)
879888
// FRAMESIZE_QSXGA = 1MB, FRAMESIZE_UXGA = 375KB (as JPEG)
@@ -894,8 +903,8 @@ bool prepCam() {
894903
config.pin_pclk = PCLK_GPIO_NUM;
895904
config.pin_vsync = VSYNC_GPIO_NUM;
896905
config.pin_href = HREF_GPIO_NUM;
897-
config.pin_sccb_sda = SIOD_GPIO_NUM;
898-
config.pin_sccb_scl = SIOC_GPIO_NUM;
906+
config.pin_sccb_sda = siodGpio;
907+
config.pin_sccb_scl = siocGpio;
899908
config.pin_pwdn = PWDN_GPIO_NUM;
900909
config.pin_reset = RESET_GPIO_NUM;
901910
config.xclk_freq_hz = xclkMhz * OneMHz;
@@ -906,7 +915,7 @@ bool prepCam() {
906915
config.frame_size = maxFS;
907916
config.jpeg_quality = 10;
908917
config.fb_count = FB_CNT;
909-
config.sccb_i2c_port = 0;// using I2C 0. to be sure what port we are using. it can be changed.
918+
config.sccb_i2c_port = 0;// using I2C 0. to be sure what port we are using.
910919

911920
#if defined(CAMERA_MODEL_ESP_EYE)
912921
pinMode(13, INPUT_PULLUP);
@@ -921,14 +930,14 @@ bool prepCam() {
921930
if (err == ESP_OK) err = changeXCLK(config);
922931
if (err != ESP_OK) {
923932
// power cycle the camera, provided pin is connected
924-
#if (defined(PWDN_GPIO_NUM)) && (PWDN_GPIO_NUM > -1) // both ckecks are needed. if we send -1 to digitalWrite, it can cause crashe or errors.
925-
digitalWrite(PWDN_GPIO_NUM, 1);
926-
delay(100);
927-
digitalWrite(PWDN_GPIO_NUM, 0);
928-
delay(100);
929-
#else
930-
delay(200);
931-
#endif
933+
#if (defined(PWDN_GPIO_NUM)) && (PWDN_GPIO_NUM > -1) // both ckecks are needed. if send -1 to digitalWrite, it can cause crash.
934+
digitalWrite(PWDN_GPIO_NUM, 1);
935+
delay(100);
936+
digitalWrite(PWDN_GPIO_NUM, 0);
937+
delay(100);
938+
#else
939+
delay(200);
940+
#endif
932941
retries--;
933942
}
934943
}

motionDetect.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ bool checkMotion(camera_fb_t* fb, bool motionStatus, bool lightLevelOnly) {
184184
if (fsizePtr > 16) {
185185
LOG_WRN("Frame size %s too large for processing", frameData[fsizePtr].frameSizeStr);
186186
useMotion = false;
187-
} else LOG_WRN("jpg2rgb() failure");
187+
}
188188
return motionStatus;
189189
}
190190
LOG_VRB("JPEG to rescaled %s bitmap conversion %u bytes in %lums", colorDepth == RGB888_BYTES ? "color" : "grayscale", sampleWidth * sampleHeight * colorDepth, millis() - dTime);
@@ -377,5 +377,6 @@ static bool jpg2rgb(const uint8_t* src, size_t src_len, uint8_t* out, jpg_scale_
377377
jpeg.output = out;
378378
jpeg.data_offset = 0;
379379
esp_err_t res = esp_jpg_decode(src_len, scale, _jpg_read, _rgb_write, (void*)&jpeg);
380+
if (res != ESP_OK) LOG_WRN("jpg2rgb failure: %s", espErrMsg(res));
380381
return (res == ESP_OK) ? true : false;
381382
}

periphsI2C.cpp

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ int I2Csda = -1;
2828
int I2Cscl = -1;
2929
static byte I2CDATA[10]; // store I2C data received or to be sent
3030
static int I2Cdevices = -1;
31+
static bool isShared = false;
3132

3233
// I2C device names, indexed by address
3334
static bool deviceStatus[128] = {false}; // whether device present
@@ -101,20 +102,33 @@ static bool sendI2Cdata(int clientAddr, uint8_t controlByte, uint8_t numBytes) {
101102
return sendTransmission(clientAddr, false);
102103
}
103104

105+
bool shareI2C(int sdaShare, int sclShare) {
106+
// apply given pins if bus to be shared
107+
// await cam lib fix
108+
// if (I2Csda < 0) {
109+
// // I2C bus shared with another peripheral, eg camera
110+
// I2Csda = sdaShare;
111+
// I2Cscl = sclShare;
112+
// isShared = true;
113+
// Wire.begin(I2Csda, I2Cscl); // Join I2C bus as master
114+
// LOG_INF("I2C bus shared with camera");
115+
// }
116+
return isShared;
117+
}
118+
104119
bool prepI2C() {
105-
// start I2C port and prep I2C peripherals
106-
if (I2Csda < 0) {
107-
// I2C bus shared with camera
108-
I2Csda = SIOD_GPIO_NUM;
109-
I2Cscl = SIOC_GPIO_NUM;
110-
LOG_INF("I2C bus shared with camera");
111-
} else if (I2Csda == I2Cscl) {
112-
LOG_ALT("I2C pins not defined");
120+
// start I2C port if not shared then prep I2C peripherals
121+
if (I2Csda == I2Cscl) {
122+
LOG_ALT("I2C pins not defined: %d", I2Csda);
113123
return false;
114124
}
115-
Wire.begin(I2Csda, I2Cscl); // Join I2C bus as master
116-
//Wire.setClock(400000); // default 100kHz, max 400kHz
117-
LOG_INF("I2C initialised at %dkHz using pins SDA: %d, SCL: %d", Wire.getClock() / 1000, I2Csda, I2Cscl);
125+
// start I2C
126+
if (!isShared) {
127+
Wire.begin(I2Csda, I2Cscl); // Join I2C bus as master
128+
//Wire.setClock(400000); // default 100kHz, max 400kHz
129+
}
130+
LOG_INF("%sI2C initialised at %dkHz using pins SDA: %d, SCL: %d", isShared ? "Shared " : "", Wire.getClock() / 1000, I2Csda, I2Cscl);
131+
118132
I2Cdevices = 0;
119133
scanI2C();
120134
return prepI2Cdevices();

0 commit comments

Comments
 (0)