├── LICENSE ├── README.md ├── de-solder.png ├── de-solder3.png ├── demo1.jpg ├── demo2.jpg ├── demo3.jpg ├── demo4.jpg ├── demo_fritz.jpg ├── demo_fritz2.jpg ├── demo_fritz3.jpg ├── deom5.jpg ├── newfm.jpg ├── old ├── README.md ├── v23 │ ├── ESP32FtpServer.cpp │ ├── ESP32FtpServer.h │ ├── README.md │ └── TimeLapseAvi23x.ino ├── v39 │ ├── ESP32FtpServer.cpp │ ├── ESP32FtpServer.h │ ├── README.md │ └── TimeLapseAvi39x.ino ├── v60 │ ├── ESP32FtpServer.cpp │ ├── ESP32FtpServer.h │ ├── README.MD │ └── TimeLapseAvi60x.ino ├── v86 │ ├── ESP32FtpServer.cpp │ ├── ESP32FtpServer.h │ ├── TimeLapseAvi86x.ino │ ├── UniversalTelegramBot.cpp │ ├── UniversalTelegramBot.h │ ├── readme.md │ ├── rtc_cntl.h │ ├── settings.h │ ├── v86-Telegram.jpg │ ├── v86-status.jpg │ ├── v86-stop.jpg │ └── v86.jpg ├── v89 │ ├── ESP32FtpServer.cpp │ ├── ESP32FtpServer.h │ ├── TimeLapseAvi89x.ino │ ├── UniversalTelegramBot.cpp │ ├── UniversalTelegramBot.h │ ├── readme.md │ ├── rtc_cntl.h │ └── settings.h └── v94 │ ├── ESP32FtpServer.cpp │ ├── ESP32FtpServer.h │ ├── TimeLapseAvi94x.ino │ ├── UniversalTelegramBot.cpp │ ├── UniversalTelegramBot.h │ ├── readme │ ├── rtc_cntl.h │ ├── settings.h │ └── web_v94.jpg ├── sample-output └── readme.txt ├── sample └── samples.txt ├── telegram1.jpg ├── telegram2.jpg ├── telegram3.jpg ├── v98-WiFiMan ├── ESP32FtpServer.cpp ├── ESP32FtpServer.h ├── TimeLapseAvi98x-WiFiMan.ino ├── UniversalTelegramBot.cpp ├── UniversalTelegramBot.h ├── readme.md ├── rtc_cntl.h └── settings.h ├── v98 ├── ESP32FtpServer.cpp ├── ESP32FtpServer.h ├── TimeLapseAvi98x.ino ├── UniversalTelegramBot.cpp ├── UniversalTelegramBot.h ├── readme.md ├── rtc_cntl.h └── settings.h ├── v99 ├── ESP32FtpServer.cpp ├── ESP32FtpServer.h ├── README.md ├── TimeLapseAvi99x.ino ├── UniversalTelegramBot.cpp ├── UniversalTelegramBot.h ├── rtc_cntl.h ├── settings.h └── v99.jpg └── vA1 ├── CRC32.cpp ├── CRC32.h ├── ESPxWebFlMgr.cpp ├── ESPxWebFlMgr.h ├── ESPxWebFlMgrWp.h ├── ESPxWebFlMgrWpF.h ├── README.md ├── TimeLapseAviA1x.ino ├── UniversalTelegramBot.cpp ├── UniversalTelegramBot.h └── settings.h /README.md: -------------------------------------------------------------------------------- 1 | # ESP32-CAM-Video-Recorder 2 | Video Recorder for ESP32-CAM with http server for config and ftp server to download video 3 | 4 | TimeLapseAvi 5 | 6 | ESP32-CAM Video Recorder 7 | 8 | This program records an MJPEG AVI video on the SD Card of an ESP32-CAM. 9 | 10 | by James Zahary July 20, 2019 11 | jamzah.plc@gmail.com 12 | 13 | https://github.com/jameszah/ESP32-CAM-Video-Recorder 14 | 15 | jameszah/ESP32-CAM-Video-Recorder is licensed under the GNU General Public License v3.0 16 | 17 | vA1 for arduino-esp32 2.0.2 18 | v99 for arduino-esp32 1.0.6 19 | v98 for arduino-esp32 1.0.4 20 | 21 | ## Update Jan 12, 2022 - esp32-arduino 2.0.2 and replace ftp with http file transfer 22 | 23 | Version A1 - Jan 1, 2022 24 | - switch from ftp to http file tranfer 25 | https://github.com/jameszah/ESPxWebFlMgr/tree/master/esp32_sd_file_manager 26 | - changes for esp32-arduino 1.06 -> 2.02 27 | - added link to telegram to download completed avi with one-click 28 | - delete low-voltage handler (serves no purpose) 29 | - get rid of touch (not much used i think) 30 | 31 | The esp32-arduino 2.0.2 contains some nicer camera code that clears away little glitches that used to pop up. 32 | It is very clean now! 33 | 34 | You can hardcode your ssid and password into settings.h, or put in a 1 character long ssid, and it will use WiFiManager to set your ssid and password. 35 | If you want Telegram bot to work, you still have to hardcode them into settings.h 36 | 37 | 38 | More commentary coming ... and refinements ... test it before you use it. 39 | 40 | Also the newer quicker version (with fewer features) over at https://github.com/jameszah/ESP32-CAM-Video-Recorder-junior 41 | 42 | You can download the videos to your computer or phone with just a click on the file from your browser -- no need for an ftp program anymore! 43 | 44 | 45 | 46 | If you have the telegram bot turned on, it will send your telegram app the first frame of a new recording, and give you a link to the previous recording for you to download to your phone or computer with one click. 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | Jan 17, 2022 - small update to fix the file delete when disk full required by 2.0.2 59 | 60 | ---- 61 | 62 | old stuff below - might contain details not applicable to current version 63 | 64 | ---- 65 | 66 | 67 | Note line 1413 -- this current version uses the WiFiManager for all WiFi setup. Change this line if you want to use the previous version of hardcoded ssid and password. 68 | 69 | https://github.com/jameszah/ESP32-CAM-Video-Recorder/blob/f90207b74c8ac247ef20f3cde9664b5f80844a02/v99/TimeLapseAvi99x.ino#L1413 70 | 71 | ## Update Sep 1, 2021 - small update for arduino-esp32 1.0.6 72 | 73 | Minimal update for arduino-esp32 1.0.6. 74 | 75 | The framesizes numbers changed which I had used on the http url command, so those were updated. 76 | Add the new frame size HD (1280x720). 77 | Some updates for the new SSL libraries to keep the telegram interface working. 78 | You need all the files in the v99 folder. And Arduino esp32 board library set to 1.0.6. 79 | You can still use the previous version with the esp32 board library set to 1.0.4. 80 | 81 | 82 | 83 | Lightly tested! 84 | 85 | More frequent updates with better code at these spin-offs of this original project. 86 | 87 | https://github.com/jameszah/ESP32-CAM-Video-Recorder-junior 88 | This simple fast recording and streaming, with http just for information - no controls or ftp. 89 | 90 | https://github.com/jameszah/ESP32-CAM-Video-Telegram 91 | This records and sends a short video to telegram on request or PIR event, using the telegram interface. 92 | 93 | ## Update Jun 10, 2021 - new program to check out 94 | 95 | It records a video and sends it to your Telegram account - no SD card! 96 | Now I just need to do some updates on this one! 97 | 98 | https://github.com/jameszah/ESP32-CAM-Video-Telegram 99 | 100 | ## Update Mar 17, 2021 - arduino-esp32 ver 1.05 101 | 102 | It would be best to use arduino-esp32 version 1.04 until I scan through this for update problems. 103 | 1.05 was released in late Feb 2021, has has some new framesizes, aspect rations, and some changes in the WiFi, that need some code changes. 104 | 105 | ![image](https://user-images.githubusercontent.com/36938190/111499024-21b61000-8708-11eb-8e6a-5e35f411c694.png) 106 | 107 | ## Update Jan 06, 2021 - Version 98-WiFiMan 108 | 109 | Just the same as Verion 98, but you can configure the ssid and password using WiFiManager. 110 | Use the normal WiFiManager procedure to set up ssid with 192.168.4.1 etc https://github.com/tzapu/WiFiManager 111 | The only difference is that you have to reboot the esp32 after you have set the ssid/pass for it to work correctly. 112 | Read more about it here https://github.com/tzapu/WiFiManager/issues/1184 113 | 114 | And you must use the latest WiFiManager code which supports the ESP32 - currently 2.0.3-alpha which can be installed from Arduino IDE - Manage Libraries. 115 | The WiFiManager could be enhanced to set parameters that cannot be set from hhtp, such as Telegram name and password, but haven't done that yet. 116 | 117 | 118 | https://github.com/jameszah/ESP32-CAM-Video-Recorder/tree/master/v98-WiFiMan 119 | 120 | ## Update Sep 29, 2020 - Version 98 121 | 122 | Added a feature to automatically delete your oldest day of videos when the SD reaches 90% full. 123 | 124 | There are also some compile directives in the settings.h file to cut out entire sections of code like the ftp or telegram, if you need resouces to add your own stuff. 125 | 126 | 127 | ## Update Sep 13, 2020 128 | 129 | Check out a much simpler, somewhat faster version ESP32-CAM-Video_Recorder-junior. 130 | 131 | It gets rid of wifi, http, time, ftp, telegram, pir, touch, .... and just records very fast -- pretty much at the full speed of the camera -- with a decent SD card and reasonable quality parameters. 132 | 133 | The latest version of junior v07 adds back the streaming video, and series of photos over wifi, and will record at 6 fps UXGA and 24 fps SVGA, but otherwise remains quite uncomplicated. 134 | 135 | https://github.com/jameszah/ESP32-CAM-Video-Recorder-junior 136 | 137 | ## Update Aug 29, 2020 Version 94 - live stream and filter bad jpegs 138 | 139 | A couple new things. 140 | 141 | I added some code to filter out bad jpegs. This happens when you have high quality jpeg settings, and then take a movie in bright light, and some of the jpegs exceed the memory allocated, and you get a partial jpeg, which will screw up the index, and break an entire avi. So there is now code to find those bad jpegs, and get a new frame that is good. Read more about this here if interested. 142 | https://github.com/espressif/esp32-camera/issues/162 143 | 144 | This means it is safe to increase the jpeg quality to 7 (maybe 6?) from the standard setting of 10, or 12 in bright sun. Lower number is higher quality. Higher quality will mean more bytes, bigger files, and slower to write. It is debatable if you want very high quality jpegs if they are flashing along at 24 frames per second. 145 | 146 | Another new feature is a streaming video. There is the single frame on the main status screen so you code see what your camera sees, but the streaming has been much requested to get a better look through the viewfinder, and maybe save the stream. 147 | 148 | You set a parameter in settings.h of milli-seconds between updates, and then click on the /stream link on the main web page and it will stream to a new browser window. Hit "back" to get back to the main page. 149 | 150 | To save the video coming to the browser, do the following -- I tried to figure this out before but could not find it on google. 151 | 152 | 1. Click on the /stream on the web page, and you will see the moving picture. 153 | 2. Right-click and select "save image as ...", type a name, and it will start saving the series of jpegs to a file. 154 | 3. You have to stop the save, which as far as I can figure out, you have to select cancel from the menu of the ever increasing file. But that will delete the file that you have been saving. So the kludge is to "show in folder" to find the file, then copy the file, then do the cancel. Then you have to rename that file to x.mjpeg, and then you can play it. Most programs that play .avi files will not play the .mjpeg, but some will. See VLC below. Very inelegant. 155 | 156 | Another method is to use the VLC media player program. 157 | 1. Media - Open Network Stream - paste in the url such as http://192.168.1.90/stream 158 | 2. Then in the Play menu, switch it to Convert, click on "Dump Raw Input" and type filename ending in .mjpeg, and click Start. When you are down saving, click the square stop button. You will get a .mjpeg file which can be played in VLC and some other video or picture players. An mjpeg does not understand time, so it will play the picture as quick as it can, and you have have to enter new information about the time between frames to get it to play as you want. 159 | 160 | VLC seems to have controls there to convert the file to various formats like h264, wmv, etc. but I could not get that to work. 161 | 162 | If anyone has better ways to capture the live stream, or capture and covert it, please let us know in the comments. 163 | 164 | I have not really studied how the streaming interacts with the recording. But 3 fps streaming seems to work fine with 8 fps svga recording. More work to be done there. I reduced the http task priorty to below the picture-taking and avi-writing tasks, so the the streaming should slow down before the recording. It seems the esp32 http server can only handle one client at a time, so you cannot stream to one browser and check the status on another browser. 165 | 166 | Another small feature is that you can now tell the recorder to /stop, and then /start with no parameters, and it will restart according to the original start parameters. Not only the framesize and interval, but if you set it to record 100 videos, and it has 5 left, after a /stop and /start it will restart at 100 videos. 167 | 168 | Also if you have some parameters in EPROM, and your are doing a new compile with changes and you do not want to use those EPROM parameters, there is a setting called MagicNumber in the settings.h. Just change the MagicNumber, and the program will skip the EPROM settings and write your new settings from settings.h 169 | 170 | I changed to default startup settings to VGA 10 frames per second, play at realtime, with no PIR or BOT. 171 | 172 | 173 | 174 | 175 | ## Update Jul 15, 2020 Version 89 - more new stuff 176 | 177 | - added some code to save the configuration in eprom, so your device will always reboot to the state set in your most recent /start command. The previous system just had a hardcoded configuration, and let you /stop and /start in a new configuration, but after a series of squirrel attacks, I moved to the eprom solution. It always starts where it was, although a movie in progress during the squirrel attack will be lost. You can enable or disable the telegram bot or PIR sensor with a web-page click, and that too will be added to the eprom, so it reboots with or without bot updates or PIR control. On reboot, it will check your eprom to see if there are parameters, and if so it will use them, or else use the hardcoded parameters from settings.h, and then write those paramters into eprom for next boot. Change the eprom parameters with the /start command below. 178 | 179 | - changed the movie start procedure a little. It now takes a snapshot at beginning of movie, saves it as a .jpg, and if Telegram bot is enabled sends that same picture to your telegram so you can monitor the activity on your phone, or use that jpg if you want. It does take several seconds to send the picture to telegram. And only after that does it start recording the movie. I attempted to do the telegram send after the movie started recording, but the telegram uses SSL security which needs 50k or more of heap, which would sometimes leave too little heap to work the SD card. Also the reboot from deepsleep takes a couple seconds, then starting internet takes a couple seconds, then telegram bot takes a couple seconds, and then the movie starts. So if you want fast-start, then don't use deepsleep, turn off internet, and obviously turn off telegram. 180 | 181 | - changed reprogramming the camera a little. It used to re-set frame-size, quality with every movie, but now it is just when you make changes and at reboot. 182 | 183 | - I have switched to quality = 12 which is better for sunny days, and does noticably increase frame-rate. I can usually get SVGA working at 10 frames per second, which is decent realtime video. 184 | 185 | - http://desklens.local/bot_enable 186 | - http://desklens.local/bot_disable 187 | - http://desklens.local/pir_enable 188 | - http://desklens.local/pir_disable 189 | 190 | - http://desklens.local/ ... look through viewfinder and see status 191 | 192 | - http://desklens.local/stop 193 | - http://desklens.local/start ... with existing or default parameters 194 | - http://desklens.local/start?framesize=VGA&length=1800&interval=250&quality=10&repeat=100&speed=1&gray=0&pir=0&bot=1 195 | 196 | - framesize can be UXGA, SVGA, VGA, CIF 197 | - length is length in seconds of the recording 198 | - interval is the milli-seconds between frames 199 | - quality is a number 10..50 for the jpeg - smaller number is higher quality with bigger and more detailed jpeg 200 | - repeat is a number of how many of the same recordings should be made 201 | - speed is a factor to speed up realtime for a timelapse recording - 1 is realtime 202 | - gray is 1 for a grayscale video 203 | - pir is 1 to start a 15 seconds movie if pir sensor pulls high, and continue to 10 seconds after pir goes low 204 | - bot is 1 will send the opening frame of movie to your Telegram App 205 | 206 | - ftp://desklens.local/ ... use ftp to download or erase old files ... username and password "esp" which is set in the code 207 | 208 | The serial debug monitor shows you your ip address, and the web page uses the ip, rather than hoping that you can resolve mDNS everytime. 209 | 210 | You just need the files from the /v89 folder. Edit the settings.h file for your wifi and startup configuration. 211 | 212 | ## Update Jun 30, 2020 Version 86 - some new features 213 | 214 | 215 | 216 | # Software 217 | - redo camera scheduler to reduce frame skips with slight delays between frames 218 | - move more processing to separate priority tasks, and remove from idle loop() 219 | - most tasks suspend waiting for events, rather than looping checking for events, ... except ftp which still loops wating for ftp requests 220 | - added a sd card snapshot jpg at beginning of every movie 221 | - added a telegram.org message with opening picture and info about diskspace and rssi to follow camera activity on your computer or phone 222 | - added deepsleep feature to wake on PIR, and then deepsleep after movie is recorded 223 | - added touch sensor on pin12 to enable/disable the pir sensor 224 | - added more careful setup of difficult pins 12, 13, and 4 - used for SD and re-used for PIR, Touch, and Blinding Disk-Active Light 225 | - added brownout handler to close files on brownout, which didn't work, but at least I can deepsleep to prevent multiple brownout reboots. (Inside a brownout handler, you have only 300ms and you cannot access wifi, sd, or flash, ... so cannot close files, or send message.) 226 | - re-used pin 4 Blinding Disk-Active Light to blink gently at beginning of movie, and at a Touch - ironically, also turns on during Brownout ;-) 227 | - added several functions to enable / disable pir or bot using internet 228 | 229 | - http://desklens.local/bot_enable 230 | - http://desklens.local/bot_disable 231 | - http://desklens.local/pir_enable 232 | - http://desklens.local/pir_disable 233 | 234 | - http://desklens.local/ ... look through viewfinder and see status 235 | 236 | - http://desklens.local/stop 237 | - http://desklens.local/start ... with existing or default parameters 238 | - http://desklens.local/start?framesize=VGA&length=1800&interval=250&quality=10&repeat=100&speed=1&gray=0 239 | - see below or settings.h 240 | 241 | - moved many settings to a separate file "settings.h" so you edit that, rather than digging through the main file to set your wifi password, startup defaults, and enable/disable internet, pir, telegram, etc 242 | - not super-elegant code ... still haven't written the avi writer into a nice library 243 | - read comment on rtc_cntl.h below which may or may not be updated in the esp32 board library - links and info below 244 | - This includes a v1.2 (slight mods) of https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot for the Telegram stuff, plus the ftp and ArduCam mentioned below (major rewrite on ArduCam) 245 | - You just need the files from the /v86 folder. Edit the settings.h file for your wifi and starup configuration. 246 | 247 | # Hardware 248 | - to use PIR function, put an active high PIR or microwave on pin 13 with a 10k resistor (brown,black,orange) between pin 13 and PIR output to avoid antagonizing sd card 249 | - to use Touch function, put a wire (with optional metal touch point) on pin 12 and touch it to enable/disable pir 250 | - Blinding Disk-Active Light will give little blink during a touch, or when starting a recording 251 | - red led on back with blink with every frame if you have that enabled in settings 252 | 253 | 254 | Here is the "/" status page 255 | 256 | 257 | 258 | And the /stop page to restart with new parameters 259 | 260 | 261 | 262 | And what it looks like on your phone Telegram App 263 | 264 | 265 | 266 | ## Update Feb 29, 2020 Sample Hardware for Microwave Camera 267 | 268 | This is a bit of hardware to set up a camera recording to SD Card whenever something moves, as seen through a microwave device, and adds a led so you can see when the camera sees you! 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | ## Update Feb 25, 2020 Sample Hardware for PIR Camera 277 | 278 | This is a bit of hardware to set up a camera recording to SD Card whenever something moves. 279 | 280 | (my microUSB adapter is different from the one in the library) 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | ## Update Feb 26, 2020 TimeLapseAvi60x.ino 289 | 290 | New version # 60 291 | - moved from 4 bit SD access to 1 bit, which frees up gpio pins 4, 12, and 13 292 | - the Blinding Disk-Access Light is now OFF, without soldering or tape 293 | - pin 12 can now be used for a PIR or switch - pull it high to start a 15 second video, continuing until 10 seconds after it goes low 294 | - to use PIR or switch, the machine must not be recording, so edit "record_on_reboot" to 0, or use web to stop recording 295 | - if you want no internet, just leave the fake ssid and password, and it will date your PIR recordings as 1970, but keep all your PIR clips timed and dated after 1970, which is better than just numbering them 296 | - default startup is VGA, 10 fps, quailty 10, 30 minutes long, playback realtime, repeat 100 times, and it starts automatically after a reboot -- this is actually a little aggressive for my LEXAR 300x 32GB microSDHC UHS-I, which will usually keep up with 10 fps, but will sometimes start skipping 297 | - BlinkWithWrite #define of 1 will blink the little red led with every frame, or #define 0 will just blink SOS if the camera or sd card are broken, or if you are skipping frames because sd cannot keep up 298 | - also implemented dates and times in ftp which had been mysteriously missing. The "Date Modified" on Windows should now be the correct time the file was completed on the ESP32. The "Date Created" will be the time you ftp'ed it. And the time in the file name is the time the file was started recording on the ESP32. 299 | - also note that the file names of the PIR files are all just "L15" (the original creation of the file), but the files themselves will be as long as the PIR had activity. I haven't updated the filename for the eventual length. 300 | - you just need the 3 files from the /v60 folder 301 | - I'll rewrite this intro with v60 instructions ... at some point 302 | 303 | Also, someone did an instructables.com explanation and video about the Sep 15, 2019 version, which is not bad. 304 | I am refered to as "The Team" :-) 305 | 306 | https://www.instructables.com/id/Video-Capture-Using-the-ESP32-CAM-Board/ 307 | 308 | Other general advice about the ESP32-CAM. 309 | - put a capacitor between the +5 and Ground to prevent the frequent "brownout" problems. I saw 220 microFarad recommended somewhere, and it works good. 310 | - keep the antenna part of the chip - the part with the squiggly line - above and away from your circuit board or any wires. The internet speed will improve dramatically with just 1 or 2 mm of extra space. 311 | 312 | ## Update Feb 18, 2020 313 | - Check out https://github.com/s60sc/ESP32-CAM_MJPEG2SD 314 | 315 | It is a similar program, but makes a ".mjpeg" file rather than an ".avi" file. 316 | 317 | It will also give you the live-stream through the camera to your 318 | browser, it will play the videos for you through the browser, and 319 | it will record based on a PIR or other sensor that grounds a pin. 320 | 321 | And it solves the "Blinding Disk-Active Light" without any soldering or tape. 322 | 323 | Reference by amirjak over in the "Issues" section. 324 | 325 | I will be borrowing a few of these good ideas in days to come! 326 | 327 | 328 | ## Update Oct 15, 2019 329 | - Make sure you are using esp32 board library 1.03 or better 330 | - 1.02 has major wifi problems !!! 331 | 332 | 333 | ## Update Sep 15, 2019 TimeLapseAvi39x.ino 334 | "work-in-progress" I'm publishing this as a few people have been asking or working on this. 335 | - program now uses both cores with core 0 taking pictures and queueing them for a separate task on core 1 writing them to the avi file on the sd card 336 | - the loop() task on core 1 now just handles the ftp system and http server 337 | - dropped fixed ip and switch to mDNS with name "desklens", which can be typed into browser, and also used as wifi name on router 338 | - small change to ftp to cooperate with WinSCP program 339 | - fixed bug so Windows would calulcate the correct length (time length) of avi 340 | - when queue of frames gets full, it skips every other frame to try to catch up 341 | - camera is re-configued when changing from UXGA <> VGA to allow for more buffers with the smaller frames 342 | 343 | You just need the 3 files in the /v23 folder for July version, which takes a picture and stores it 344 | or the 3 files in the /v39 folder for the current which adds the queueing system to get better 345 | frame rates, and keep recording if there is a small delay on file system. 346 | 347 | ## Original July 2019 Intro 348 | 349 | Acknowlegements: 350 | 351 | 1. https://robotzero.one/time-lapse-esp32-cameras/ 352 | Timelapse programs for ESP32-CAM version that sends snapshots of screen. 353 | 2. https://github.com/nailbuster/esp8266FTPServer 354 | ftp server (slightly modifed to get the directory function working) 355 | 3. https://github.com/ArduCAM/Arduino/tree/master/ArduCAM/examples/mini 356 | ArduCAM Mini demo (C)2017 LeeWeb: http://www.ArduCAM.com 357 | I copied the structure of the avi file, some calculations. 358 | 359 | The is Arduino code, with standard setup for ESP32-CAM 360 | - Board ESP32 Wrover Module 361 | - Partition Scheme Huge APP (3MB No OTA) 362 | 363 | This program records an AVI video on the SD Card of an ESP32-CAM. 364 | 365 | It will record realtime video at limited framerates, or timelapses with the full resolution of the ESP32-CAM. 366 | It is controlled by a web page it serves to stop and start recordings with many parameters, and look through the viewfinder. 367 | 368 | You can control framesize (UXGA, VGA, ...), quality, length, and fps to record, and fps to playback later, etc. 369 | 370 | There is also an ftp server to download the recordings to a PC. 371 | 372 | Instructions: 373 | 374 | The program uses a fixed IP of 192.168.1.222, so you can browse to it from your phone or computer. 375 | 376 | http://192.168.1.222/ -- this gives you the status of the recording in progress and lets you look through the viewfinder 377 | 378 | http://192.168.1.222/stop -- this stops the recording in progress and displays some sample commands to start new recordings 379 | 380 | ftp://192.168.1.222/ -- gives you the ftp server 381 | 382 | The ftp for esp32 seems to not be a full ftp. The Chrome Browser and the Windows command line ftp's did not work with this, but 383 | the Raspbarian command line ftp works fine, and an old Windows ftp I have called CoffeeCup Free FTP also works, which is what I have been using. 384 | You can download at about 450 KB/s -- which is better than having to retreive the SD chip if you camera is up in a tree! 385 | 386 | http://192.168.1.222/start?framesize=VGA&length=1800&interval=250&quality=10&repeat=100&speed=1&gray=0 387 | -- this is a sample to start a new recording 388 | 389 | - framesize can be UXGA, SVGA, VGA, CIF (default VGA) 390 | - length is length in seconds of the recording 0..3600 (default 1800) 391 | - interval is the milli-seconds between frames (default 200) 392 | - quality is a number 10..50 for the jpeg - smaller number is higher quality with bigger and more detailed jpeg (default 10) 393 | - repeat is a number of who many of the same recordings should be made (default 100) 394 | - speed is a factor to speed up realtime for a timelapse recording - 1 is realtime (default 1) 395 | - gray is 1 for a grayscale video (default 0 - color) 396 | 397 | These factors have to be within the limit of the SD chip to receive the data. 398 | For example, using a LEXAR 300x 32GB microSDHC UHS-I, the following works for me: 399 | 400 | - UXGA quality 10, 2 fps (or interval of 500ms) 401 | - SVGA quality 10, 5 fps (200ms) 402 | - VGA quality 10, 10 fps (100ms) 403 | - CIF quality 10, 20 fps (50ms) 404 | 405 | If you increase fps, you might have to reduce quality or framesize to keep it from dropping frames as it writes all the data to the SD chip. 406 | 407 | Also, other SD chips will be faster or slower. I was using a SanDisk 16GB microSDHC "Up to 653X" - which was slower and more unpredictable than the LEXAR ??? 408 | 409 | Search for "zzz" to find places to modify the code for: 410 | 1. Your wifi name and password 411 | 2. Your preferred ip address (with default gateway, etc) 412 | 3. Your Timezone for use in filenames 413 | 4. Defaults for framesize, quality, ... and if the recording should start on reboot of the ESP32 without receiving a command 414 | 415 | Sample videos produced by the program in the /sample-output folder -- it is not GoPro quality, but then GoPro's don't cost $10. 416 | 417 | While not necessay, following is how I dealt with the "Flash" led on the front of the ESP32-CAM chip. 418 | 419 | Picture below shows my solution to the "Flash" led, aka "the Blinding Disk-Active light". The led turns on whenever you are are writing data to the SD chip, which is normally after you have taken the picture, so you don't need the flash on any more! 420 | 421 | Quick de-solder of the collector on the top of the J3Y transistor just above the led, then put in some tape to keep it clear -- you can solder it back later if you want to use it. 422 | 423 | 424 | 425 | 426 | -------------------------------------------------------------------------------- /de-solder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/de-solder.png -------------------------------------------------------------------------------- /de-solder3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/de-solder3.png -------------------------------------------------------------------------------- /demo1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/demo1.jpg -------------------------------------------------------------------------------- /demo2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/demo2.jpg -------------------------------------------------------------------------------- /demo3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/demo3.jpg -------------------------------------------------------------------------------- /demo4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/demo4.jpg -------------------------------------------------------------------------------- /demo_fritz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/demo_fritz.jpg -------------------------------------------------------------------------------- /demo_fritz2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/demo_fritz2.jpg -------------------------------------------------------------------------------- /demo_fritz3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/demo_fritz3.jpg -------------------------------------------------------------------------------- /deom5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/deom5.jpg -------------------------------------------------------------------------------- /newfm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/newfm.jpg -------------------------------------------------------------------------------- /old/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /old/v23/ESP32FtpServer.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * FTP SERVER FOR ESP8266 4 | * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) 5 | * based on Jean-Michel Gallego's work 6 | * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | // 2017: modified by @robo8080 22 | // 2019: modified by @fa1ke5 23 | 24 | /******************************************************************************* 25 | ** ** 26 | ** DEFINITIONS FOR FTP SERVER ** 27 | ** ** 28 | *******************************************************************************/ 29 | 30 | // Uncomment to print debugging info to console attached to ESP8266 31 | //#define FTP_DEBUG 32 | 33 | #ifndef FTP_SERVERESP_H 34 | #define FTP_SERVERESP_H 35 | 36 | //#include "Streaming.h" 37 | #include "SD_MMC.h" 38 | #include 39 | #include 40 | 41 | #define FTP_SERVER_VERSION "FTP-2016-01-14" 42 | 43 | #define FTP_CTRL_PORT 21 // Command port on wich server is listening 44 | #define FTP_DATA_PORT_PASV 50009 // Data port in passive mode 45 | 46 | #define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity 47 | #define FTP_CMD_SIZE 255 + 8 // max size of a command 48 | #define FTP_CWD_SIZE 255 + 8 // max size of a directory name 49 | #define FTP_FIL_SIZE 255 // max size of a file name 50 | 51 | //#define FTP_BUF_SIZE 512 //512 // size of file buffer for read/write 52 | //#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write 53 | #define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. 54 | 55 | 56 | class FtpServer 57 | { 58 | public: 59 | void begin(String uname, String pword); 60 | void handleFTP(); 61 | 62 | private: 63 | bool haveParameter(); 64 | bool makeExistsPath( char * path, char * param = NULL ); 65 | void iniVariables(); 66 | void clientConnected(); 67 | void disconnectClient(); 68 | boolean userIdentity(); 69 | boolean userPassword(); 70 | boolean processCommand(); 71 | boolean dataConnect(); 72 | boolean doRetrieve(); 73 | boolean doStore(); 74 | void closeTransfer(); 75 | void abortTransfer(); 76 | boolean makePath( char * fullname ); 77 | boolean makePath( char * fullName, char * param ); 78 | uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, 79 | uint8_t * phour, uint8_t * pminute, uint8_t * second ); 80 | char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); 81 | int8_t readChar(); 82 | 83 | IPAddress dataIp; // IP address of client for data 84 | WiFiClient client; 85 | WiFiClient data; 86 | 87 | File file; 88 | 89 | boolean dataPassiveConn; 90 | uint16_t dataPort; 91 | char buf[ FTP_BUF_SIZE ]; // data buffer for transfers 92 | char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client 93 | char cwdName[ FTP_CWD_SIZE ]; // name of current directory 94 | char command[ 5 ]; // command sent by client 95 | boolean rnfrCmd; // previous command was RNFR 96 | char * parameters; // point to begin of parameters sent by client 97 | uint16_t iCL; // pointer to cmdLine next incoming char 98 | int8_t cmdStatus, // status of ftp command connexion 99 | transferStatus; // status of ftp data transfer 100 | uint32_t millisTimeOut, // disconnect after 5 min of inactivity 101 | millisDelay, 102 | millisEndConnection, // 103 | millisBeginTrans, // store time of beginning of a transaction 104 | bytesTransfered; // 105 | String _FTP_USER; 106 | String _FTP_PASS; 107 | 108 | 109 | 110 | }; 111 | 112 | #endif // FTP_SERVERESP_H 113 | -------------------------------------------------------------------------------- /old/v23/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /old/v39/ESP32FtpServer.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * FTP SERVER FOR ESP8266 4 | * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) 5 | * based on Jean-Michel Gallego's work 6 | * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | // 2017: modified by @robo8080 22 | // 2019: modified by @fa1ke5 23 | 24 | /******************************************************************************* 25 | ** ** 26 | ** DEFINITIONS FOR FTP SERVER ** 27 | ** ** 28 | *******************************************************************************/ 29 | 30 | // Uncomment to print debugging info to console attached to ESP8266 31 | #define FTP_DEBUG 32 | 33 | #ifndef FTP_SERVERESP_H 34 | #define FTP_SERVERESP_H 35 | 36 | //#include "Streaming.h" 37 | #include "SD_MMC.h" 38 | #include 39 | #include 40 | 41 | #define FTP_SERVER_VERSION "FTP-2016-01-14" 42 | 43 | #define FTP_CTRL_PORT 21 // Command port on wich server is listening 44 | #define FTP_DATA_PORT_PASV 50009 // Data port in passive mode 45 | 46 | #define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity 47 | #define FTP_CMD_SIZE 255 + 8 // max size of a command 48 | #define FTP_CWD_SIZE 255 + 8 // max size of a directory name 49 | #define FTP_FIL_SIZE 255 // max size of a file name 50 | 51 | //#define FTP_BUF_SIZE 512 //512 // size of file buffer for read/write 52 | //#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write 53 | #define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. 54 | 55 | 56 | class FtpServer 57 | { 58 | public: 59 | void begin(String uname, String pword); 60 | void handleFTP(); 61 | 62 | private: 63 | bool haveParameter(); 64 | bool makeExistsPath( char * path, char * param = NULL ); 65 | void iniVariables(); 66 | void clientConnected(); 67 | void disconnectClient(); 68 | boolean userIdentity(); 69 | boolean userPassword(); 70 | boolean processCommand(); 71 | boolean dataConnect(); 72 | boolean doRetrieve(); 73 | boolean doStore(); 74 | void closeTransfer(); 75 | void abortTransfer(); 76 | boolean makePath( char * fullname ); 77 | boolean makePath( char * fullName, char * param ); 78 | uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, 79 | uint8_t * phour, uint8_t * pminute, uint8_t * second ); 80 | char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); 81 | int8_t readChar(); 82 | 83 | IPAddress dataIp; // IP address of client for data 84 | WiFiClient client; 85 | WiFiClient data; 86 | 87 | File file; 88 | 89 | boolean dataPassiveConn; 90 | uint16_t dataPort; 91 | char buf[ FTP_BUF_SIZE ]; // data buffer for transfers 92 | char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client 93 | char cwdName[ FTP_CWD_SIZE ]; // name of current directory 94 | char command[ 5 ]; // command sent by client 95 | boolean rnfrCmd; // previous command was RNFR 96 | char * parameters; // point to begin of parameters sent by client 97 | uint16_t iCL; // pointer to cmdLine next incoming char 98 | int8_t cmdStatus, // status of ftp command connexion 99 | transferStatus; // status of ftp data transfer 100 | uint32_t millisTimeOut, // disconnect after 5 min of inactivity 101 | millisDelay, 102 | millisEndConnection, // 103 | millisBeginTrans, // store time of beginning of a transaction 104 | bytesTransfered; // 105 | String _FTP_USER; 106 | String _FTP_PASS; 107 | 108 | 109 | 110 | }; 111 | 112 | #endif // FTP_SERVERESP_H 113 | -------------------------------------------------------------------------------- /old/v39/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /old/v60/ESP32FtpServer.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * FTP SERVER FOR ESP8266 4 | * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) 5 | * based on Jean-Michel Gallego's work 6 | * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | // 2017: modified by @robo8080 22 | // 2019: modified by @fa1ke5 23 | 24 | /******************************************************************************* 25 | ** ** 26 | ** DEFINITIONS FOR FTP SERVER ** 27 | ** ** 28 | *******************************************************************************/ 29 | 30 | // Uncomment to print debugging info to console attached to ESP8266 31 | //#define FTP_DEBUG 32 | 33 | #ifndef FTP_SERVERESP_H 34 | #define FTP_SERVERESP_H 35 | 36 | //#include "Streaming.h" 37 | #include "SD_MMC.h" 38 | #include 39 | #include 40 | 41 | #define FTP_SERVER_VERSION "FTP-2016-01-14" 42 | 43 | #define FTP_CTRL_PORT 21 // Command port on wich server is listening 44 | #define FTP_DATA_PORT_PASV 50009 // Data port in passive mode 45 | 46 | #define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity 47 | #define FTP_CMD_SIZE 255 + 8 // max size of a command 48 | #define FTP_CWD_SIZE 255 + 8 // max size of a directory name 49 | #define FTP_FIL_SIZE 255 // max size of a file name 50 | 51 | //#define FTP_BUF_SIZE 512 //512 // size of file buffer for read/write 52 | //#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write 53 | #define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. 54 | 55 | 56 | class FtpServer 57 | { 58 | public: 59 | void begin(String uname, String pword); 60 | void handleFTP(); 61 | 62 | private: 63 | bool haveParameter(); 64 | bool makeExistsPath( char * path, char * param = NULL ); 65 | void iniVariables(); 66 | void clientConnected(); 67 | void disconnectClient(); 68 | boolean userIdentity(); 69 | boolean userPassword(); 70 | boolean processCommand(); 71 | boolean dataConnect(); 72 | boolean doRetrieve(); 73 | boolean doStore(); 74 | void closeTransfer(); 75 | void abortTransfer(); 76 | boolean makePath( char * fullname ); 77 | boolean makePath( char * fullName, char * param ); 78 | uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, 79 | uint8_t * phour, uint8_t * pminute, uint8_t * second ); 80 | char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); 81 | int8_t readChar(); 82 | 83 | IPAddress dataIp; // IP address of client for data 84 | WiFiClient client; 85 | WiFiClient data; 86 | 87 | File file; 88 | 89 | boolean dataPassiveConn; 90 | uint16_t dataPort; 91 | char buf[ FTP_BUF_SIZE ]; // data buffer for transfers 92 | char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client 93 | char cwdName[ FTP_CWD_SIZE ]; // name of current directory 94 | char command[ 5 ]; // command sent by client 95 | boolean rnfrCmd; // previous command was RNFR 96 | char * parameters; // point to begin of parameters sent by client 97 | uint16_t iCL; // pointer to cmdLine next incoming char 98 | int8_t cmdStatus, // status of ftp command connexion 99 | transferStatus; // status of ftp data transfer 100 | uint32_t millisTimeOut, // disconnect after 5 min of inactivity 101 | millisDelay, 102 | millisEndConnection, // 103 | millisBeginTrans, // store time of beginning of a transaction 104 | bytesTransfered; // 105 | String _FTP_USER; 106 | String _FTP_PASS; 107 | 108 | 109 | 110 | }; 111 | 112 | #endif // FTP_SERVERESP_H 113 | -------------------------------------------------------------------------------- /old/v60/README.MD: -------------------------------------------------------------------------------- 1 | v60 implements dates and times for ftp that v59 did not have 2 | -------------------------------------------------------------------------------- /old/v86/ESP32FtpServer.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * FTP SERVER FOR ESP8266 4 | * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) 5 | * based on Jean-Michel Gallego's work 6 | * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | // 2017: modified by @robo8080 22 | // 2019: modified by @fa1ke5 23 | 24 | /******************************************************************************* 25 | ** ** 26 | ** DEFINITIONS FOR FTP SERVER ** 27 | ** ** 28 | *******************************************************************************/ 29 | 30 | // Uncomment to print debugging info to console attached to ESP8266 31 | //#define FTP_DEBUG 32 | 33 | #ifndef FTP_SERVERESP_H 34 | #define FTP_SERVERESP_H 35 | 36 | //#include "Streaming.h" 37 | #include "SD_MMC.h" 38 | #include 39 | #include 40 | 41 | #define FTP_SERVER_VERSION "FTP-2016-01-14" 42 | 43 | #define FTP_CTRL_PORT 21 // Command port on wich server is listening 44 | #define FTP_DATA_PORT_PASV 50009 // Data port in passive mode 45 | 46 | #define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity 47 | #define FTP_CMD_SIZE 255 + 8 // max size of a command 48 | #define FTP_CWD_SIZE 255 + 8 // max size of a directory name 49 | #define FTP_FIL_SIZE 255 // max size of a file name 50 | 51 | //#define FTP_BUF_SIZE 512 //512 // size of file buffer for read/write 52 | //#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write 53 | //#define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. 54 | //#define FTP_BUF_SIZE 8192 reduce in v82 55 | //#define FTP_BUF_SIZE 2048 56 | 57 | #define FTP_BUF_SIZE 4096 58 | 59 | 60 | class FtpServer 61 | { 62 | public: 63 | void begin(String uname, String pword); 64 | void handleFTP(); 65 | 66 | private: 67 | bool haveParameter(); 68 | bool makeExistsPath( char * path, char * param = NULL ); 69 | void iniVariables(); 70 | void clientConnected(); 71 | void disconnectClient(); 72 | boolean userIdentity(); 73 | boolean userPassword(); 74 | boolean processCommand(); 75 | boolean dataConnect(); 76 | boolean doRetrieve(); 77 | boolean doStore(); 78 | void closeTransfer(); 79 | void abortTransfer(); 80 | boolean makePath( char * fullname ); 81 | boolean makePath( char * fullName, char * param ); 82 | uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, 83 | uint8_t * phour, uint8_t * pminute, uint8_t * second ); 84 | char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); 85 | int8_t readChar(); 86 | 87 | IPAddress dataIp; // IP address of client for data 88 | WiFiClient client; 89 | WiFiClient data; 90 | 91 | File file; 92 | 93 | boolean dataPassiveConn; 94 | uint16_t dataPort; 95 | char buf[ FTP_BUF_SIZE ]; // data buffer for transfers 96 | char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client 97 | char cwdName[ FTP_CWD_SIZE ]; // name of current directory 98 | char command[ 5 ]; // command sent by client 99 | boolean rnfrCmd; // previous command was RNFR 100 | char * parameters; // point to begin of parameters sent by client 101 | uint16_t iCL; // pointer to cmdLine next incoming char 102 | int8_t cmdStatus, // status of ftp command connexion 103 | transferStatus; // status of ftp data transfer 104 | uint32_t millisTimeOut, // disconnect after 5 min of inactivity 105 | millisDelay, 106 | millisEndConnection, // 107 | millisBeginTrans, // store time of beginning of a transaction 108 | bytesTransfered; // 109 | String _FTP_USER; 110 | String _FTP_PASS; 111 | 112 | 113 | 114 | }; 115 | 116 | #endif // FTP_SERVERESP_H 117 | -------------------------------------------------------------------------------- /old/v86/UniversalTelegramBot.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 Brian Lough. All right reserved. 3 | 4 | UniversalTelegramBot - Library to create your own Telegram Bot using 5 | ESP8266 or ESP32 on Arduino IDE. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | /* 23 | **** Note Regarding Client Connection Keeping **** 24 | Client connection is established in functions that directly involve use of 25 | client, i.e sendGetToTelegram, sendPostToTelegram, and 26 | sendMultipartFormDataToTelegram. It is closed at the end of 27 | sendMultipartFormDataToTelegram, but not at the end of sendGetToTelegram and 28 | sendPostToTelegram as these may need to keep the connection alive for respose 29 | / response checking. Re-establishing a connection then wastes time which is 30 | noticeable in user experience. Due to this, it is important that connection 31 | be closed manually after calling sendGetToTelegram or sendPostToTelegram by 32 | calling closeClient(); Failure to close connection causes memory leakage and 33 | SSL errors 34 | */ 35 | 36 | // James Zahary June 30, 2020 37 | // - small mods to add caption to photos, and slow down transmit to telegram 38 | 39 | #include "UniversalTelegramBot.h" 40 | 41 | UniversalTelegramBot::UniversalTelegramBot(String token, Client &client) { 42 | _token = token; 43 | #ifdef ARDUINO_ESP8266_RELEASE_2_5_0 44 | //client->setInsecure(); 45 | #endif 46 | this->client = &client; 47 | } 48 | 49 | String UniversalTelegramBot::sendGetToTelegram(String command) { 50 | String mess = ""; 51 | long now; 52 | bool avail; 53 | 54 | // Connect with api.telegram.org if not already connected 55 | if (!client->connected()) { 56 | #ifdef _debug 57 | Serial.println(F("[BOT]Connecting to server")); 58 | #endif 59 | if (!client->connect(HOST, SSL_PORT)) { 60 | #ifdef _debug 61 | Serial.println(F("[BOT]Conection error")); 62 | #endif 63 | } 64 | } 65 | if (client->connected()) { 66 | 67 | #ifdef _debug 68 | Serial.println(F(".... connected to server")); 69 | #endif 70 | 71 | String a = ""; 72 | char c; 73 | int ch_count = 0; 74 | client->println("GET /" + command); 75 | now = millis(); 76 | avail = false; 77 | while (millis() - now < longPoll * 1000 + waitForResponse) { 78 | while (client->available()) { 79 | char c = client->read(); 80 | if (ch_count < maxMessageLength) { 81 | mess = mess + c; 82 | ch_count++; 83 | } 84 | avail = true; 85 | } 86 | if (avail) { 87 | #ifdef _debug 88 | Serial.println(); 89 | Serial.println(mess); 90 | Serial.println(); 91 | #endif 92 | break; 93 | } 94 | } 95 | } 96 | 97 | return mess; 98 | } 99 | 100 | String UniversalTelegramBot::sendPostToTelegram(String command, JsonObject payload) { 101 | 102 | String body = ""; 103 | String headers = ""; 104 | long now; 105 | bool responseReceived = false; 106 | 107 | // Connect with api.telegram.org if not already connected 108 | if (!client->connected()) { 109 | #ifdef _debug 110 | Serial.println(F("[BOT Client]Connecting to server")); 111 | #endif 112 | if (!client->connect(HOST, SSL_PORT)) { 113 | #ifdef _debug 114 | Serial.println(F("[BOT Client]Conection error")); 115 | #endif 116 | } 117 | } 118 | if (client->connected()) { 119 | // POST URI 120 | client->print("POST /" + command); 121 | client->println(F(" HTTP/1.1")); 122 | delay(100); 123 | // Host header 124 | client->print(F("Host:")); 125 | client->println(HOST); 126 | delay(100); 127 | // JSON content type 128 | client->println(F("Content-Type: application/json")); 129 | delay(100); 130 | 131 | // Content length 132 | int length = measureJson(payload); 133 | client->print(F("Content-Length:")); 134 | client->println(length); 135 | delay(100); 136 | // End of headers 137 | client->println(); 138 | // POST message body 139 | String out; 140 | serializeJson(payload, out); 141 | 142 | client->println(out); 143 | delay(100); 144 | 145 | int ch_count = 0; 146 | now = millis(); 147 | bool finishedHeaders = false; 148 | bool currentLineIsBlank = true; 149 | while (millis() - now < waitForResponse) { 150 | while (client->available()) { 151 | char c = client->read(); 152 | responseReceived = true; 153 | 154 | if (!finishedHeaders) { 155 | if (currentLineIsBlank && c == '\n') { 156 | finishedHeaders = true; 157 | } else { 158 | headers = headers + c; 159 | } 160 | } else { 161 | if (ch_count < maxMessageLength) { 162 | body = body + c; 163 | ch_count++; 164 | } 165 | } 166 | 167 | if (c == '\n') currentLineIsBlank = true; 168 | else if (c != '\r') currentLineIsBlank = false; 169 | 170 | } 171 | 172 | if (responseReceived && ch_count > 5) { //jz 173 | #ifdef _debug 174 | Serial.println(); 175 | Serial.println(body); 176 | Serial.println(); 177 | #endif 178 | //Serial.print(millis() - now); Serial.println(" sendPostToTelegram - breaking"); 179 | break; 180 | } 181 | } 182 | } 183 | 184 | return body; 185 | } 186 | 187 | String UniversalTelegramBot::sendMultipartFormDataToTelegram( 188 | String command, String binaryProperyName, String fileName, 189 | String contentType, String chat_id, int fileSize, 190 | MoreDataAvailable moreDataAvailableCallback, 191 | GetNextByte getNextByteCallback, 192 | GetNextBuffer getNextBufferCallback, 193 | GetNextBufferLen getNextBufferLenCallback) { 194 | 195 | String body = ""; 196 | String headers = ""; 197 | long now; 198 | bool responseReceived = false; 199 | bool finishedHeaders = false; 200 | bool currentLineIsBlank = true; 201 | 202 | String boundry = F("------------------------b8f610217e83e29b"); 203 | 204 | // Connect with api.telegram.org if not already connected 205 | if (!client->connected()) { 206 | #ifdef _debug 207 | Serial.println(F("[BOT Client]Connecting to server")); 208 | #endif 209 | if (!client->connect(HOST, SSL_PORT)) { 210 | #ifdef _debug 211 | Serial.println(F("[BOT Client]Conection error")); 212 | #endif 213 | } 214 | } 215 | if (client->connected()) { 216 | 217 | String start_request = ""; 218 | String end_request = ""; 219 | 220 | start_request = start_request + "--" + boundry + "\r\n"; 221 | start_request = start_request + "content-disposition: form-data; name=\"chat_id\"" + "\r\n"; 222 | start_request = start_request + "\r\n"; 223 | start_request = start_request + chat_id + "\r\n"; 224 | 225 | start_request = start_request + "--" + boundry + "\r\n"; 226 | start_request = start_request + "content-disposition: form-data; name=\"caption\"" + "\r\n"; 227 | start_request = start_request + "\r\n"; 228 | start_request = start_request + "caption here!" + "\r\n"; 229 | 230 | start_request = start_request + "--" + boundry + "\r\n"; 231 | start_request = start_request + "content-disposition: form-data; name=\"" + binaryProperyName + "\"; filename=\"" + fileName + "\"" + "\r\n"; 232 | 233 | start_request = start_request + "Content-Type: " + contentType + "\r\n"; 234 | start_request = start_request + "\r\n"; 235 | 236 | end_request = end_request + "\r\n"; 237 | end_request = end_request + "--" + boundry + "--" + "\r\n"; 238 | 239 | client->print("POST /bot" + _token + "/" + command); 240 | client->println(F(" HTTP/1.1")); 241 | // Host header 242 | client->print(F("Host: ")); 243 | client->println(HOST); 244 | client->println(F("User-Agent: arduino/1.0")); 245 | Serial.print("*") ; delay(100); //jz 246 | client->println(F("Accept: */*")); 247 | Serial.print("*") ; delay(100); //jz 248 | 249 | int contentLength = fileSize + start_request.length() + end_request.length(); 250 | #ifdef _debug 251 | Serial.println("Content-Length: " + String(contentLength)); 252 | #endif 253 | client->print("Content-Length: "); 254 | client->println(String(contentLength)); 255 | client->println("Content-Type: multipart/form-data; boundary=" + boundry); 256 | Serial.print("*") ; delay(100); //jz 257 | client->println(""); 258 | Serial.print("*") ; delay(100); //jz 259 | client->print(start_request); 260 | Serial.print("Start request: " + start_request); 261 | #ifdef _debug 262 | Serial.print("Start request: " + start_request); 263 | #endif 264 | 265 | if (getNextByteCallback == nullptr) { 266 | while (moreDataAvailableCallback()) { 267 | client->write((const uint8_t *)getNextBufferCallback(), getNextBufferLenCallback()); 268 | #ifdef _debug 269 | Serial.println(F("Sending photo from buffer")); 270 | #endif 271 | } 272 | } else { 273 | #ifdef _debug 274 | Serial.println(F("Sending photo by binary")); 275 | #endif 276 | byte buffer[512]; //jz 512 277 | int count = 0; 278 | char ch; 279 | while (moreDataAvailableCallback()) { 280 | buffer[count] = getNextByteCallback(); 281 | count++; 282 | if (count == 512) { //jz 512 283 | // yield(); 284 | #ifdef _debug 285 | //Serial.println(F("Sending binary photo full buffer")); 286 | #endif 287 | client->write((const uint8_t *)buffer, 512); //jz 512 288 | Serial.print("*") ; delay(100); //jz 289 | count = 0; 290 | } 291 | } 292 | 293 | if (count > 0) { 294 | #ifdef _debug 295 | Serial.println(F("Sending binary photo remaining buffer")); 296 | #endif 297 | client->write((const uint8_t *)buffer, count); 298 | Serial.print("*") ; delay(100); //jz 299 | } 300 | } 301 | 302 | client->print(end_request); 303 | //#ifdef _debug 304 | Serial.print("End request: " + end_request); 305 | //#endif 306 | 307 | Serial.print("... Done Sending. Client.Available = "); Serial.println(client->available()); 308 | delay(2000); 309 | Serial.print("... 2 secs later. Client.Available = "); Serial.println(client->available()); 310 | 311 | int ch_count = 0; 312 | now = millis(); 313 | 314 | while (millis() - now < waitForResponse) { 315 | while (client->available()) { 316 | char c = client->read(); 317 | responseReceived = true; 318 | 319 | if (!finishedHeaders) { 320 | if (currentLineIsBlank && c == '\n') { 321 | finishedHeaders = true; 322 | } else { 323 | headers = headers + c; 324 | } 325 | } else { 326 | if (ch_count < maxMessageLength) { 327 | body = body + c; 328 | ch_count++; 329 | } 330 | } 331 | 332 | if (c == '\n') currentLineIsBlank = true; 333 | else if (c != '\r') currentLineIsBlank = false; 334 | } 335 | 336 | if (responseReceived && ch_count > 5) { //jz && ch_count > 5 337 | #ifdef _debug 338 | Serial.println(); 339 | Serial.println(body); 340 | Serial.println(); 341 | #endif 342 | //Serial.print(millis() - now); Serial.println(" sendMultipartFormDataToTelegram - breaking"); 343 | break; 344 | } 345 | } 346 | } 347 | 348 | closeClient(); 349 | return body; 350 | } 351 | 352 | String UniversalTelegramBot::sendMultipartFormDataToTelegramWithCaption( 353 | String command, String binaryProperyName, String fileName, 354 | String contentType, String caption, String chat_id, int fileSize, 355 | MoreDataAvailable moreDataAvailableCallback, 356 | GetNextByte getNextByteCallback, 357 | GetNextBuffer getNextBufferCallback, 358 | GetNextBufferLen getNextBufferLenCallback) { 359 | 360 | String body = ""; 361 | String headers = ""; 362 | long now; 363 | bool responseReceived = false; 364 | bool finishedHeaders = false; 365 | bool currentLineIsBlank = true; 366 | 367 | String boundry = F("------------------------b8f610217e83e29b"); 368 | 369 | // Connect with api.telegram.org if not already connected 370 | if (!client->connected()) { 371 | #ifdef _debug 372 | Serial.println(F("[BOT Client]Connecting to server")); 373 | #endif 374 | if (!client->connect(HOST, SSL_PORT)) { 375 | #ifdef _debug 376 | Serial.println(F("[BOT Client]Conection error")); 377 | #endif 378 | } 379 | } 380 | if (client->connected()) { 381 | 382 | String start_request = ""; 383 | String end_request = ""; 384 | 385 | 386 | //Serial.print("Start: "); Serial.println(ESP.getFreeHeap()); 387 | 388 | start_request = start_request + "--" + boundry + "\r\n"; 389 | start_request = start_request + "content-disposition: form-data; name=\"chat_id\"" + "\r\n"; 390 | start_request = start_request + "\r\n"; 391 | start_request = start_request + chat_id + "\r\n"; 392 | 393 | start_request = start_request + "--" + boundry + "\r\n"; //jz caption stuff 394 | start_request = start_request + "content-disposition: form-data; name=\"caption\"" + "\r\n"; 395 | start_request = start_request + "\r\n"; 396 | start_request = start_request + caption + "\r\n"; 397 | 398 | start_request = start_request + "--" + boundry + "\r\n"; 399 | start_request = start_request + "content-disposition: form-data; name=\"" + binaryProperyName + "\"; filename=\"" + fileName + "\"" + "\r\n"; 400 | 401 | start_request = start_request + "Content-Type: " + contentType + "\r\n"; 402 | start_request = start_request + "\r\n"; 403 | 404 | end_request = end_request + "\r\n"; 405 | end_request = end_request + "--" + boundry + "--" + "\r\n"; 406 | 407 | client->print("POST /bot" + _token + "/" + command); 408 | client->println(F(" HTTP/1.1")); 409 | // Host header 410 | client->print(F("Host: ")); 411 | client->println(HOST); 412 | client->println(F("User-Agent: arduino/1.0")); 413 | Serial.print("*") ; delay(100); //jz 414 | client->println(F("Accept: */*")); 415 | Serial.print("*") ; delay(100); //jz 416 | 417 | int contentLength = fileSize + start_request.length() + end_request.length(); 418 | #ifdef _debug 419 | Serial.println("Content-Length: " + String(contentLength)); 420 | #endif 421 | client->print("Content-Length: "); 422 | client->println(String(contentLength)); 423 | client->println("Content-Type: multipart/form-data; boundary=" + boundry); 424 | Serial.print("*") ; delay(100); //jz 425 | client->println(""); 426 | Serial.print("*") ; delay(100); //jz 427 | client->print(start_request); 428 | 429 | #ifdef _debug 430 | Serial.print("Start request: " + start_request); 431 | #endif 432 | 433 | //Serial.print("End: "); Serial.println(ESP.getFreeHeap()); 434 | 435 | if (getNextByteCallback == nullptr) { 436 | while (moreDataAvailableCallback()) { 437 | client->write((const uint8_t *)getNextBufferCallback(), getNextBufferLenCallback()); 438 | #ifdef _debug 439 | Serial.println(F("Sending photo from buffer")); 440 | #endif 441 | } 442 | } else { 443 | #ifdef _debug 444 | Serial.println(F("Sending photo by binary")); 445 | #endif 446 | byte buffer[512]; 447 | int count = 0; 448 | char ch; 449 | while (moreDataAvailableCallback()) { 450 | buffer[count] = getNextByteCallback(); 451 | count++; 452 | if (count == 512) { 453 | // yield(); 454 | #ifdef _debug 455 | //Serial.println(F("Sending binary photo full buffer")); 456 | #endif 457 | client->write((const uint8_t *)buffer, 512); 458 | Serial.print("*") ; delay(100); //jz 459 | count = 0; 460 | } 461 | } 462 | 463 | if (count > 0) { 464 | #ifdef _debug 465 | Serial.println(F("Sending binary photo remaining buffer")); 466 | #endif 467 | client->write((const uint8_t *)buffer, count); 468 | Serial.print("*") ; delay(100); //jz 469 | } 470 | } 471 | 472 | client->print(end_request); 473 | #ifdef _debug 474 | Serial.print("End request: " + end_request); 475 | 476 | Serial.print("... Done Sending. Client.Available = "); Serial.println(client->available()); 477 | delay(2000); 478 | Serial.print("... 2 secs later. Client.Available = "); Serial.println(client->available()); 479 | #endif 480 | 481 | int ch_count = 0; 482 | now = millis(); 483 | 484 | while (millis() - now < waitForResponse) { 485 | while (client->available()) { 486 | char c = client->read(); 487 | responseReceived = true; 488 | 489 | if (!finishedHeaders) { 490 | if (currentLineIsBlank && c == '\n') { 491 | finishedHeaders = true; 492 | } else { 493 | headers = headers + c; 494 | } 495 | } else { 496 | if (ch_count < maxMessageLength) { 497 | body = body + c; 498 | ch_count++; 499 | } 500 | } 501 | 502 | if (c == '\n') currentLineIsBlank = true; 503 | else if (c != '\r') currentLineIsBlank = false; 504 | } 505 | 506 | if (responseReceived && ch_count > 5) { //jz && ch_count > 5 507 | #ifdef _debug 508 | Serial.println(); 509 | Serial.println(body); 510 | Serial.println(); 511 | #endif 512 | //Serial.print(millis() - now); Serial.println(" sendMultipartFormDataToTelegram - breaking"); 513 | break; 514 | } 515 | } 516 | } 517 | 518 | closeClient(); 519 | return body; 520 | } 521 | 522 | bool UniversalTelegramBot::getMe() { 523 | String command = "bot" + _token + "/getMe"; 524 | String response = sendGetToTelegram(command); // receive reply from telegram.org 525 | DynamicJsonDocument doc(maxMessageLength); 526 | DeserializationError error = deserializeJson(doc, response); 527 | JsonObject obj = doc.as(); //there is nothing better right now to use obj.containsKey("result") 528 | closeClient(); 529 | 530 | if (!error) { 531 | if (obj.containsKey("result")) { 532 | String _name = doc["result"]["first_name"]; 533 | String _username = doc["result"]["username"]; 534 | name = _name; 535 | userName = _username; 536 | return true; 537 | } 538 | } 539 | 540 | return false; 541 | } 542 | 543 | /*************************************************************** 544 | GetUpdates - function to receive messages from telegram 545 | (Argument to pass: the last+1 message to read) 546 | Returns the number of new messages 547 | ***************************************************************/ 548 | int UniversalTelegramBot::getUpdates(long offset) { 549 | 550 | #ifdef _debug 551 | Serial.println(F("GET Update Messages")); 552 | #endif 553 | String command = "bot" + _token + "/getUpdates?offset=" + String(offset) + "&limit=" + String(HANDLE_MESSAGES); 554 | if (longPoll > 0) { 555 | command = command + "&timeout=" + String(longPoll); 556 | } 557 | String response = sendGetToTelegram(command); // receive reply from telegram.org 558 | 559 | if (response == "") { 560 | #ifdef _debug 561 | Serial.println(F("Received empty string in response!")); 562 | #endif 563 | // close the client as there's nothing to do with an empty string 564 | closeClient(); 565 | return 0; 566 | } else { 567 | #ifdef _debug 568 | Serial.print(F("incoming message length ")); 569 | Serial.println(response.length()); 570 | Serial.println(F("Creating DynamicJsonBuffer")); 571 | #endif 572 | 573 | // Parse response into Json object 574 | DynamicJsonDocument doc(maxMessageLength); 575 | DeserializationError error = deserializeJson(doc, response); 576 | #ifdef _debug 577 | Serial.print(F("GetUpdates parsed jsonDoc: ")); 578 | serializeJson(doc, Serial); 579 | Serial.println(); 580 | #endif 581 | 582 | JsonObject obj = doc.as(); //there is nothing better right now 583 | if (!error) { 584 | #ifdef _debug 585 | Serial.print(F("GetUpdates parsed jsonObj: ")); 586 | serializeJson(obj, Serial); 587 | Serial.println(); 588 | #endif 589 | if (obj.containsKey("result")) { 590 | int resultArrayLength = doc["result"].size(); 591 | if (resultArrayLength > 0) { 592 | int newMessageIndex = 0; 593 | // Step through all results 594 | for (int i = 0; i < resultArrayLength; i++) { 595 | JsonObject result = doc["result"][i]; 596 | if (processResult(result, newMessageIndex)) newMessageIndex++; 597 | } 598 | // We will keep the client open because there may be a response to be 599 | // given 600 | return newMessageIndex; 601 | } else { 602 | #ifdef _debug 603 | Serial.println(F("no new messages")); 604 | #endif 605 | } 606 | } else { 607 | #ifdef _debug 608 | Serial.println(F("Response contained no 'result'")); 609 | #endif 610 | } 611 | } else { // Parsing failed 612 | if (response.length() < 2) { // Too short a message. Maybe a connection issue 613 | #ifdef _debug 614 | Serial.println(F("Parsing error: Message too short")); 615 | #endif 616 | } else { 617 | // Buffer may not be big enough, increase buffer or reduce max number of 618 | // messages 619 | #ifdef _debug 620 | Serial.print(F("Failed to parse update, the message could be too " 621 | "big for the buffer. Error code: ")); 622 | Serial.println(error.c_str()); // debug print of parsing error 623 | #endif 624 | } 625 | } 626 | // Close the client as no response is to be given 627 | closeClient(); 628 | return 0; 629 | } 630 | } 631 | 632 | bool UniversalTelegramBot::processResult(JsonObject result, int messageIndex) { 633 | int update_id = result["update_id"]; 634 | // Check have we already dealt with this message (this shouldn't happen!) 635 | if (last_message_received != update_id) { 636 | last_message_received = update_id; 637 | messages[messageIndex].update_id = update_id; 638 | messages[messageIndex].text = F(""); 639 | messages[messageIndex].from_id = F(""); 640 | messages[messageIndex].from_name = F(""); 641 | messages[messageIndex].longitude = 0; 642 | messages[messageIndex].latitude = 0; 643 | 644 | if (result.containsKey("message")) { 645 | JsonObject message = result["message"]; 646 | messages[messageIndex].type = F("message"); 647 | messages[messageIndex].from_id = message["from"]["id"].as(); 648 | messages[messageIndex].from_name = message["from"]["first_name"].as(); 649 | messages[messageIndex].date = message["date"].as(); 650 | messages[messageIndex].chat_id = message["chat"]["id"].as(); 651 | messages[messageIndex].chat_title = message["chat"]["title"].as(); 652 | 653 | if (message.containsKey("text")) { 654 | messages[messageIndex].text = message["text"].as(); 655 | 656 | } else if (message.containsKey("location")) { 657 | messages[messageIndex].longitude = message["location"]["longitude"].as(); 658 | messages[messageIndex].latitude = message["location"]["latitude"].as(); 659 | } 660 | } else if (result.containsKey("channel_post")) { 661 | JsonObject message = result["channel_post"]; 662 | messages[messageIndex].type = F("channel_post"); 663 | messages[messageIndex].text = message["text"].as(); 664 | messages[messageIndex].date = message["date"].as(); 665 | messages[messageIndex].chat_id = message["chat"]["id"].as(); 666 | messages[messageIndex].chat_title = message["chat"]["title"].as(); 667 | 668 | } else if (result.containsKey("callback_query")) { 669 | JsonObject message = result["callback_query"]; 670 | messages[messageIndex].type = F("callback_query"); 671 | messages[messageIndex].from_id = message["from"]["id"].as(); 672 | messages[messageIndex].from_name = message["from"]["first_name"].as(); 673 | messages[messageIndex].text = message["data"].as(); 674 | messages[messageIndex].date = message["date"].as(); 675 | messages[messageIndex].chat_id = message["message"]["chat"]["id"].as(); 676 | messages[messageIndex].chat_title = F(""); 677 | 678 | } else if (result.containsKey("edited_message")) { 679 | JsonObject message = result["edited_message"]; 680 | messages[messageIndex].type = F("edited_message"); 681 | messages[messageIndex].from_id = message["from"]["id"].as(); 682 | messages[messageIndex].from_name = message["from"]["first_name"].as(); 683 | messages[messageIndex].date = message["date"].as(); 684 | messages[messageIndex].chat_id = message["chat"]["id"].as(); 685 | messages[messageIndex].chat_title = message["chat"]["title"].as(); 686 | 687 | if (message.containsKey("text")) { 688 | messages[messageIndex].text = message["text"].as(); 689 | 690 | } else if (message.containsKey("location")) { 691 | messages[messageIndex].longitude = message["location"]["longitude"].as(); 692 | messages[messageIndex].latitude = message["location"]["latitude"].as(); 693 | } 694 | } 695 | return true; 696 | } 697 | return false; 698 | } 699 | 700 | /*********************************************************************** 701 | SendMessage - function to send message to telegram 702 | (Arguments to pass: chat_id, text to transmit and markup(optional)) 703 | ***********************************************************************/ 704 | bool UniversalTelegramBot::sendSimpleMessage(String chat_id, String text, 705 | String parse_mode) { 706 | 707 | bool sent = false; 708 | #ifdef _debug 709 | Serial.println(F("sendSimpleMessage: SEND Simple Message")); 710 | #endif 711 | long sttime = millis(); 712 | 713 | if (text != "") { 714 | while (millis() < sttime + 8000) { // loop for a while to send the message 715 | String command = "bot" + _token + "/sendMessage?chat_id=" + chat_id + 716 | "&text=" + text + "&parse_mode=" + parse_mode; 717 | String response = sendGetToTelegram(command); 718 | #ifdef _debug 719 | Serial.println(response); 720 | #endif 721 | sent = checkForOkResponse(response); 722 | if (sent) break; 723 | } 724 | } 725 | closeClient(); 726 | return sent; 727 | } 728 | 729 | bool UniversalTelegramBot::sendMessage(String chat_id, String text, 730 | String parse_mode) { 731 | 732 | DynamicJsonDocument payload(maxMessageLength); 733 | payload["chat_id"] = chat_id; 734 | payload["text"] = text; 735 | 736 | if (parse_mode != "") 737 | payload["parse_mode"] = parse_mode; 738 | 739 | return sendPostMessage(payload.as()); 740 | } 741 | 742 | bool UniversalTelegramBot::sendMessageWithReplyKeyboard( 743 | String chat_id, String text, String parse_mode, String keyboard, 744 | bool resize, bool oneTime, bool selective) { 745 | 746 | DynamicJsonDocument payload(maxMessageLength); 747 | payload["chat_id"] = chat_id; 748 | payload["text"] = text; 749 | 750 | if (parse_mode != "") 751 | payload["parse_mode"] = parse_mode; 752 | 753 | JsonObject replyMarkup = payload.createNestedObject("reply_markup"); 754 | 755 | // Reply keyboard is an array of arrays. 756 | // Outer array represents rows 757 | // Inner arrays represents columns 758 | // This example "ledon" and "ledoff" are two buttons on the top row 759 | // and "status is a single button on the next row" 760 | DynamicJsonDocument keyboardBuffer(maxMessageLength); // creating a buffer enough to keep keyboard string 761 | deserializeJson(keyboardBuffer, keyboard); 762 | replyMarkup["keyboard"] = keyboardBuffer.as(); 763 | 764 | // Telegram defaults these values to false, so to decrease the size of the 765 | // payload we will only send them if needed 766 | if (resize) 767 | replyMarkup["resize_keyboard"] = resize; 768 | 769 | if (oneTime) 770 | replyMarkup["one_time_keyboard"] = oneTime; 771 | 772 | if (selective) 773 | replyMarkup["selective"] = selective; 774 | 775 | return sendPostMessage(payload.as()); 776 | } 777 | 778 | bool UniversalTelegramBot::sendMessageWithInlineKeyboard(String chat_id, 779 | String text, 780 | String parse_mode, 781 | String keyboard) { 782 | 783 | DynamicJsonDocument payload(maxMessageLength); 784 | payload["chat_id"] = chat_id; 785 | payload["text"] = text; 786 | 787 | if (parse_mode != "") 788 | payload["parse_mode"] = parse_mode; 789 | 790 | JsonObject replyMarkup = payload.createNestedObject("reply_markup"); 791 | DynamicJsonDocument keyboardBuffer(maxMessageLength); // assuming keyboard buffer will alwas be limited to 1024 bytes 792 | deserializeJson(keyboardBuffer, keyboard); 793 | replyMarkup["inline_keyboard"] = keyboardBuffer.as(); 794 | return sendPostMessage(payload.as()); 795 | } 796 | 797 | /*********************************************************************** 798 | SendPostMessage - function to send message to telegram 799 | (Arguments to pass: chat_id, text to transmit and markup(optional)) 800 | ***********************************************************************/ 801 | bool UniversalTelegramBot::sendPostMessage(JsonObject payload) { 802 | 803 | bool sent = false; 804 | #ifdef _debug 805 | Serial.print(F("sendPostMessage: SEND Post Message: ")); 806 | serializeJson(payload, Serial); 807 | Serial.println(); 808 | #endif 809 | long sttime = millis(); 810 | 811 | if (payload.containsKey("text")) { 812 | while (millis() < sttime + 8000) { // loop for a while to send the message 813 | String command = "bot" + _token + "/sendMessage"; 814 | String response = sendPostToTelegram(command, payload); 815 | #ifdef _debug 816 | Serial.println(response); 817 | #endif 818 | sent = checkForOkResponse(response); 819 | if (sent) break; 820 | } 821 | } 822 | 823 | closeClient(); 824 | return sent; 825 | } 826 | 827 | String UniversalTelegramBot::sendPostPhoto(JsonObject payload) { 828 | 829 | bool sent = false; 830 | String response = ""; 831 | #ifdef _debug 832 | Serial.println(F("sendPostPhoto: SEND Post Photo")); 833 | #endif 834 | long sttime = millis(); 835 | 836 | if (payload.containsKey("photo")) { 837 | while (millis() < sttime + 8000) { // loop for a while to send the message 838 | String command = "bot" + _token + "/sendPhoto"; 839 | response = sendPostToTelegram(command, payload); 840 | #ifdef _debug 841 | Serial.println(response); 842 | #endif 843 | sent = checkForOkResponse(response); 844 | if (sent) break; 845 | 846 | } 847 | } 848 | 849 | closeClient(); 850 | return response; 851 | } 852 | 853 | String UniversalTelegramBot::sendPhotoByBinary( 854 | String chat_id, String contentType, int fileSize, 855 | MoreDataAvailable moreDataAvailableCallback, 856 | GetNextByte getNextByteCallback, GetNextBuffer getNextBufferCallback, GetNextBufferLen getNextBufferLenCallback) { 857 | 858 | #ifdef _debug 859 | Serial.println(F("sendPhotoByBinary: SEND Photo")); 860 | #endif 861 | 862 | String response = sendMultipartFormDataToTelegram("sendPhoto", "photo", "img.jpg", 863 | contentType, chat_id, fileSize, 864 | moreDataAvailableCallback, getNextByteCallback, getNextBufferCallback, getNextBufferLenCallback); 865 | 866 | #ifdef _debug 867 | Serial.println(response); 868 | #endif 869 | 870 | return response; 871 | } 872 | 873 | 874 | 875 | String UniversalTelegramBot::sendPhoto(String chat_id, String photo, 876 | String caption, 877 | bool disable_notification, 878 | int reply_to_message_id, 879 | String keyboard) { 880 | 881 | DynamicJsonDocument payload(maxMessageLength); 882 | payload["chat_id"] = chat_id; 883 | payload["photo"] = photo; 884 | 885 | if (caption) 886 | payload["caption"] = caption; 887 | 888 | if (disable_notification) 889 | payload["disable_notification"] = disable_notification; 890 | 891 | if (reply_to_message_id && reply_to_message_id != 0) 892 | payload["reply_to_message_id"] = reply_to_message_id; 893 | 894 | if (keyboard) { 895 | JsonObject replyMarkup = payload.createNestedObject("reply_markup"); 896 | DynamicJsonDocument keyboardBuffer(maxMessageLength); // assuming keyboard buffer will alwas be limited to 1024 bytes 897 | deserializeJson(keyboardBuffer, keyboard); 898 | replyMarkup["keyboard"] = keyboardBuffer.as(); 899 | } 900 | 901 | return sendPostPhoto(payload.as()); 902 | } 903 | 904 | bool UniversalTelegramBot::checkForOkResponse(String response) { 905 | int responseLength = response.length(); 906 | 907 | for (int m = 5; m < responseLength + 1; m++) { 908 | if (response.substring(m - 10, m) == 909 | "{\"ok\":true") { // Chek if message has been properly sent 910 | return true; 911 | } 912 | } 913 | 914 | return false; 915 | } 916 | 917 | bool UniversalTelegramBot::sendChatAction(String chat_id, String text) { 918 | 919 | bool sent = false; 920 | #ifdef _debug 921 | Serial.println(F("SEND Chat Action Message")); 922 | #endif 923 | long sttime = millis(); 924 | 925 | if (text != "") { 926 | while (millis() < sttime + 8000) { // loop for a while to send the message 927 | String command = "bot" + _token + "/sendChatAction?chat_id=" + chat_id + 928 | "&action=" + text; 929 | String response = sendGetToTelegram(command); 930 | 931 | #ifdef _debug 932 | Serial.println(response); 933 | #endif 934 | sent = checkForOkResponse(response); 935 | 936 | if (sent) break; 937 | 938 | } 939 | } 940 | 941 | closeClient(); 942 | return sent; 943 | } 944 | 945 | void UniversalTelegramBot::closeClient() { 946 | if (client->connected()) { 947 | #ifdef _debug 948 | Serial.println(F("Closing client")); 949 | #endif 950 | client->stop(); 951 | } 952 | } 953 | -------------------------------------------------------------------------------- /old/v86/UniversalTelegramBot.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 Brian Lough. All right reserved. 3 | 4 | UniversalTelegramBot - Library to create your own Telegram Bot using 5 | ESP8266 or ESP32 on Arduino IDE. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef UniversalTelegramBot_h 23 | #define UniversalTelegramBot_h 24 | 25 | #define ARDUINOJSON_DECODE_UNICODE 1 26 | #define ARDUINOJSON_USE_LONG_LONG 1 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define HOST "api.telegram.org" 33 | #define SSL_PORT 443 34 | #define HANDLE_MESSAGES 1 35 | 36 | //unmark following line to enable debug mode 37 | //#define _debug 38 | 39 | typedef bool (*MoreDataAvailable)(); 40 | typedef byte (*GetNextByte)(); 41 | typedef byte* (*GetNextBuffer)(); 42 | typedef int (GetNextBufferLen)(); 43 | 44 | struct telegramMessage { 45 | String text; 46 | String chat_id; 47 | String chat_title; 48 | String from_id; 49 | String from_name; 50 | String date; 51 | String type; 52 | float longitude; 53 | float latitude; 54 | int update_id; 55 | }; 56 | 57 | class UniversalTelegramBot { 58 | public: 59 | UniversalTelegramBot(String token, Client &client); 60 | String sendGetToTelegram(String command); 61 | String sendPostToTelegram(String command, JsonObject payload); 62 | String 63 | sendMultipartFormDataToTelegram(String command, String binaryProperyName, 64 | String fileName, String contentType, 65 | String chat_id, int fileSize, 66 | MoreDataAvailable moreDataAvailableCallback, 67 | GetNextByte getNextByteCallback, 68 | GetNextBuffer getNextBufferCallback, 69 | GetNextBufferLen getNextBufferLenCallback); 70 | 71 | String 72 | sendMultipartFormDataToTelegramWithCaption(String command, String binaryProperyName, 73 | String fileName, String contentType, 74 | String caption, String chat_id, int fileSize, 75 | MoreDataAvailable moreDataAvailableCallback, 76 | GetNextByte getNextByteCallback, 77 | GetNextBuffer getNextBufferCallback, 78 | GetNextBufferLen getNextBufferLenCallback); 79 | 80 | 81 | bool getMe(); 82 | 83 | bool sendSimpleMessage(String chat_id, String text, String parse_mode); 84 | bool sendMessage(String chat_id, String text, String parse_mode = ""); 85 | bool sendMessageWithReplyKeyboard(String chat_id, String text, 86 | String parse_mode, String keyboard, 87 | bool resize = false, bool oneTime = false, 88 | bool selective = false); 89 | bool sendMessageWithInlineKeyboard(String chat_id, String text, 90 | String parse_mode, String keyboard); 91 | 92 | bool sendChatAction(String chat_id, String text); 93 | 94 | bool sendPostMessage(JsonObject payload); 95 | String sendPostPhoto(JsonObject payload); 96 | String sendPhotoByBinary(String chat_id, String contentType, int fileSize, 97 | MoreDataAvailable moreDataAvailableCallback, 98 | GetNextByte getNextByteCallback, 99 | GetNextBuffer getNextBufferCallback, 100 | GetNextBufferLen getNextBufferLenCallback); 101 | String sendPhoto(String chat_id, String photo, String caption = "", 102 | bool disable_notification = false, 103 | int reply_to_message_id = 0, String keyboard = ""); 104 | 105 | int getUpdates(long offset); 106 | bool checkForOkResponse(String response); 107 | telegramMessage messages[HANDLE_MESSAGES]; 108 | long last_message_received; 109 | String name; 110 | String userName; 111 | int longPoll = 0; 112 | int waitForResponse = 10000; //jz = 1500; 113 | 114 | private: 115 | // JsonObject * parseUpdates(String response); 116 | String _token; 117 | Client *client; 118 | void closeClient(); 119 | const int maxMessageLength = 1500; //was 1500 120 | bool processResult(JsonObject result, int messageIndex); 121 | }; 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /old/v86/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /old/v86/rtc_cntl.h: -------------------------------------------------------------------------------- 1 | // ... pending inclusion in the new esp32 distribution - jz 2 | 3 | // You may have to edit rtc_cntl.h ... according to this link -- doesn't seem to be included in esp32 libraries as of Jun 2020 ... or I'll just put it here 4 | // https://github.com/espressif/esp-idf/commit/17bd6e8faba15812780d21e6e3db08fb26dd7033#diff-5e22dcf9fc6087d1585c7b2e434c0932 5 | // https://github.com/espressif/esp-idf/pull/4532 6 | // C:\Users\James\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\driver\driver -- approximate path 7 | 8 | 9 | // Copyright 2016-2017 Espressif Systems (Shanghai) PTE LTD 10 | // 11 | // Licensed under the Apache License, Version 2.0 (the "License"); 12 | // you may not use this file except in compliance with the License. 13 | // You may obtain a copy of the License at 14 | // 15 | // http://www.apache.org/licenses/LICENSE-2.0 16 | // 17 | // Unless required by applicable law or agreed to in writing, software 18 | // distributed under the License is distributed on an "AS IS" BASIS, 19 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | // See the License for the specific language governing permissions and 21 | // limitations under the License. 22 | 23 | #pragma once 24 | 25 | #include 26 | #include "esp_err.h" 27 | #include "esp_intr_alloc.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * @brief Register a handler for specific RTC_CNTL interrupts 35 | * 36 | * Multiple handlers can be registered using this function. Whenever an 37 | * RTC interrupt happens, all handlers with matching rtc_intr_mask values 38 | * will be called. 39 | * 40 | * @param handler handler function to call 41 | * @param handler_arg argument to be passed to the handler 42 | * @param rtc_intr_mask combination of RTC_CNTL_*_INT_ENA bits indicating the 43 | * sources to call the handler for 44 | * @return 45 | * - ESP_OK on success 46 | * - ESP_ERR_NO_MEM not enough memory to allocate handler structure 47 | * - other errors returned by esp_intr_alloc 48 | */ 49 | esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, 50 | uint32_t rtc_intr_mask); 51 | /** 52 | * @brief Deregister the handler previously registered using rtc_isr_register 53 | * @param handler handler function to call (as passed to rtc_isr_register) 54 | * @param handler_arg argument of the handler (as passed to rtc_isr_register) 55 | * @return 56 | * - ESP_OK on success 57 | * - ESP_ERR_INVALID_STATE if a handler matching both handler and 58 | * handler_arg isn't registered 59 | */ 60 | esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | -------------------------------------------------------------------------------- /old/v86/settings.h: -------------------------------------------------------------------------------- 1 | static const char devname[] = "desklens"; // name of your camera for mDNS, Router, and filenames 2 | 3 | // https://sites.google.com/a/usapiens.com/opnode/time-zones -- find your timezone here 4 | #define TIMEZONE "GMT0BST,M3.5.0/01,M10.5.0/02" // your timezone - this is GMT 5 | 6 | // 1 for blink red led with every sd card write, at your frame rate 7 | // 0 for blink only for skipping frames and SOS if camera or sd is broken 8 | #define BlinkWithWrite 1 9 | 10 | // EDIT ssid and password 11 | const char* ssid = "yourwifi"; 12 | const char* password = "youwifipassword"; 13 | 14 | // reboot startup parameters here 15 | 16 | int Internet_Enabled = 1; // set to 0 to shut off all internet activities - wifi, time, http, ftp, telegram 17 | int DeepSleepPir = 0; // set to 1 to deepsleep between pir videos 18 | int record_on_reboot = 1; // set to 1 to record, or 0 to NOT record on reboot 19 | int PIRpin = 13; // for active high pir or microwave etc 20 | int PIRenabled = 0; // 1 is PIR is enable on reboot, will only work if you are not recording 21 | 22 | // here are 2 sets of startup parameters 23 | 24 | // VGA 10 fps for 30 minutes, and repeat, play at real time 25 | 26 | int framesize = 6; // 10 UXGA, 7 SVGA, 6 VGA, 5 CIF 27 | int repeat = 100; // repeat same movie this many times 28 | int xspeed = 1; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames recorded at 10 second per frame ( 30 fps / 0.1 fps ) 29 | int gray = 0; // not gray 30 | int quality = 12; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 31 | int capture_interval = 100; // milli-seconds between frames 32 | volatile int total_frames = 18000; // how many frames - length of movie in ms is total_frames x capture_interval 33 | 34 | 35 | // UXGA 1 frame every 10 seconds, for 60 minutes, and repeat, play at 30 fps or 300 times speed 36 | /* 37 | int framesize = 10; // 10 UXGA, 7 SVGA, 6 VGA, 5 CIF 38 | int repeat = 300; // repaeat same movie this many times 39 | int xspeed = 300; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frames ( 30 fps / 0.1 fps ) 40 | int gray = 0; // not gray 41 | int quality = 12; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 42 | int capture_interval = 10000; // milli-seconds between frames 43 | volatile int total_frames = 360; // how many frames - length of movie is total_frames x capture_interval 44 | */ 45 | 46 | // enable the www.telegram.org BOT - it sends a snapshot to your telegram every time it starts a video 47 | // https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot for more info about esp32 telegram 48 | // I'm using the branch v1.2 from June 2020 - new master introduced late june, but not working for picture and captions, so my v1.2 mods included here 49 | // You need to create a bot, and get its number BOTtoken, and then get your telegram number -- all free at telegram.org 50 | 51 | RTC_DATA_ATTR int EnableBOT = 0; // 1 to enable 52 | #define BOTtoken "9876543210:qwertyuiopasdfghjklzxcvbnmqwertyuio" // get your own bot and id at telegram.org 53 | #define BOTme "1234567890" // these are fake 54 | -------------------------------------------------------------------------------- /old/v86/v86-Telegram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/old/v86/v86-Telegram.jpg -------------------------------------------------------------------------------- /old/v86/v86-status.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/old/v86/v86-status.jpg -------------------------------------------------------------------------------- /old/v86/v86-stop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/old/v86/v86-stop.jpg -------------------------------------------------------------------------------- /old/v86/v86.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/old/v86/v86.jpg -------------------------------------------------------------------------------- /old/v89/ESP32FtpServer.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * FTP SERVER FOR ESP8266 4 | * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) 5 | * based on Jean-Michel Gallego's work 6 | * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | // 2017: modified by @robo8080 22 | // 2019: modified by @fa1ke5 23 | 24 | /******************************************************************************* 25 | ** ** 26 | ** DEFINITIONS FOR FTP SERVER ** 27 | ** ** 28 | *******************************************************************************/ 29 | 30 | // Uncomment to print debugging info to console attached to ESP8266 31 | //#define FTP_DEBUG 32 | 33 | #ifndef FTP_SERVERESP_H 34 | #define FTP_SERVERESP_H 35 | 36 | //#include "Streaming.h" 37 | #include "SD_MMC.h" 38 | #include 39 | #include 40 | 41 | #define FTP_SERVER_VERSION "FTP-2016-01-14" 42 | 43 | #define FTP_CTRL_PORT 21 // Command port on wich server is listening 44 | #define FTP_DATA_PORT_PASV 50009 // Data port in passive mode 45 | 46 | #define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity 47 | #define FTP_CMD_SIZE 255 + 8 // max size of a command 48 | #define FTP_CWD_SIZE 255 + 8 // max size of a directory name 49 | #define FTP_FIL_SIZE 255 // max size of a file name 50 | 51 | //#define FTP_BUF_SIZE 512 //512 // size of file buffer for read/write 52 | //#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write 53 | //#define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. 54 | //#define FTP_BUF_SIZE 8192 reduce in v82 55 | //#define FTP_BUF_SIZE 2048 56 | 57 | #define FTP_BUF_SIZE 4096 58 | 59 | 60 | class FtpServer 61 | { 62 | public: 63 | void begin(String uname, String pword); 64 | void handleFTP(); 65 | 66 | private: 67 | bool haveParameter(); 68 | bool makeExistsPath( char * path, char * param = NULL ); 69 | void iniVariables(); 70 | void clientConnected(); 71 | void disconnectClient(); 72 | boolean userIdentity(); 73 | boolean userPassword(); 74 | boolean processCommand(); 75 | boolean dataConnect(); 76 | boolean doRetrieve(); 77 | boolean doStore(); 78 | void closeTransfer(); 79 | void abortTransfer(); 80 | boolean makePath( char * fullname ); 81 | boolean makePath( char * fullName, char * param ); 82 | uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, 83 | uint8_t * phour, uint8_t * pminute, uint8_t * second ); 84 | char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); 85 | int8_t readChar(); 86 | 87 | IPAddress dataIp; // IP address of client for data 88 | WiFiClient client; 89 | WiFiClient data; 90 | 91 | File file; 92 | 93 | boolean dataPassiveConn; 94 | uint16_t dataPort; 95 | char buf[ FTP_BUF_SIZE ]; // data buffer for transfers 96 | char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client 97 | char cwdName[ FTP_CWD_SIZE ]; // name of current directory 98 | char command[ 5 ]; // command sent by client 99 | boolean rnfrCmd; // previous command was RNFR 100 | char * parameters; // point to begin of parameters sent by client 101 | uint16_t iCL; // pointer to cmdLine next incoming char 102 | int8_t cmdStatus, // status of ftp command connexion 103 | transferStatus; // status of ftp data transfer 104 | uint32_t millisTimeOut, // disconnect after 5 min of inactivity 105 | millisDelay, 106 | millisEndConnection, // 107 | millisBeginTrans, // store time of beginning of a transaction 108 | bytesTransfered; // 109 | String _FTP_USER; 110 | String _FTP_PASS; 111 | 112 | 113 | 114 | }; 115 | 116 | #endif // FTP_SERVERESP_H 117 | -------------------------------------------------------------------------------- /old/v89/UniversalTelegramBot.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 Brian Lough. All right reserved. 3 | 4 | UniversalTelegramBot - Library to create your own Telegram Bot using 5 | ESP8266 or ESP32 on Arduino IDE. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef UniversalTelegramBot_h 23 | #define UniversalTelegramBot_h 24 | 25 | #define ARDUINOJSON_DECODE_UNICODE 1 26 | #define ARDUINOJSON_USE_LONG_LONG 1 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define HOST "api.telegram.org" 33 | #define SSL_PORT 443 34 | #define HANDLE_MESSAGES 1 35 | 36 | //unmark following line to enable debug mode 37 | //#define _debug 38 | 39 | typedef bool (*MoreDataAvailable)(); 40 | typedef byte (*GetNextByte)(); 41 | typedef byte* (*GetNextBuffer)(); 42 | typedef int (GetNextBufferLen)(); 43 | 44 | struct telegramMessage { 45 | String text; 46 | String chat_id; 47 | String chat_title; 48 | String from_id; 49 | String from_name; 50 | String date; 51 | String type; 52 | float longitude; 53 | float latitude; 54 | int update_id; 55 | }; 56 | 57 | class UniversalTelegramBot { 58 | public: 59 | UniversalTelegramBot(String token, Client &client); 60 | String sendGetToTelegram(String command); 61 | String sendPostToTelegram(String command, JsonObject payload); 62 | String 63 | sendMultipartFormDataToTelegram(String command, String binaryProperyName, 64 | String fileName, String contentType, 65 | String chat_id, int fileSize, 66 | MoreDataAvailable moreDataAvailableCallback, 67 | GetNextByte getNextByteCallback, 68 | GetNextBuffer getNextBufferCallback, 69 | GetNextBufferLen getNextBufferLenCallback); 70 | 71 | String 72 | sendMultipartFormDataToTelegramWithCaption(String command, String binaryProperyName, 73 | String fileName, String contentType, 74 | String caption, String chat_id, int fileSize, 75 | MoreDataAvailable moreDataAvailableCallback, 76 | GetNextByte getNextByteCallback, 77 | GetNextBuffer getNextBufferCallback, 78 | GetNextBufferLen getNextBufferLenCallback); 79 | 80 | 81 | bool getMe(); 82 | 83 | bool sendSimpleMessage(String chat_id, String text, String parse_mode); 84 | bool sendMessage(String chat_id, String text, String parse_mode = ""); 85 | bool sendMessageWithReplyKeyboard(String chat_id, String text, 86 | String parse_mode, String keyboard, 87 | bool resize = false, bool oneTime = false, 88 | bool selective = false); 89 | bool sendMessageWithInlineKeyboard(String chat_id, String text, 90 | String parse_mode, String keyboard); 91 | 92 | bool sendChatAction(String chat_id, String text); 93 | 94 | bool sendPostMessage(JsonObject payload); 95 | String sendPostPhoto(JsonObject payload); 96 | String sendPhotoByBinary(String chat_id, String contentType, int fileSize, 97 | MoreDataAvailable moreDataAvailableCallback, 98 | GetNextByte getNextByteCallback, 99 | GetNextBuffer getNextBufferCallback, 100 | GetNextBufferLen getNextBufferLenCallback); 101 | String sendPhoto(String chat_id, String photo, String caption = "", 102 | bool disable_notification = false, 103 | int reply_to_message_id = 0, String keyboard = ""); 104 | 105 | int getUpdates(long offset); 106 | bool checkForOkResponse(String response); 107 | telegramMessage messages[HANDLE_MESSAGES]; 108 | long last_message_received; 109 | String name; 110 | String userName; 111 | int longPoll = 0; 112 | int waitForResponse = 5000; //jz = 1500; 113 | int jzdelay = 60; // delay between multipart blocks 114 | int jzblocksize = 2 * 1024; // multipart block size 115 | 116 | private: 117 | // JsonObject * parseUpdates(String response); 118 | String _token; 119 | Client *client; 120 | void closeClient(); 121 | const int maxMessageLength = 1500; //was 1500 122 | bool processResult(JsonObject result, int messageIndex); 123 | }; 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /old/v89/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /old/v89/rtc_cntl.h: -------------------------------------------------------------------------------- 1 | // ... pending inclusion in the new esp32 distribution - jz 2 | 3 | // You may have to edit rtc_cntl.h ... according to this link -- doesn't seem to be included in esp32 libraries as of Jun 2020 ... or I'll just put it here 4 | // https://github.com/espressif/esp-idf/commit/17bd6e8faba15812780d21e6e3db08fb26dd7033#diff-5e22dcf9fc6087d1585c7b2e434c0932 5 | // https://github.com/espressif/esp-idf/pull/4532 6 | // C:\Users\James\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\driver\driver -- approximate path 7 | 8 | 9 | // Copyright 2016-2017 Espressif Systems (Shanghai) PTE LTD 10 | // 11 | // Licensed under the Apache License, Version 2.0 (the "License"); 12 | // you may not use this file except in compliance with the License. 13 | // You may obtain a copy of the License at 14 | // 15 | // http://www.apache.org/licenses/LICENSE-2.0 16 | // 17 | // Unless required by applicable law or agreed to in writing, software 18 | // distributed under the License is distributed on an "AS IS" BASIS, 19 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | // See the License for the specific language governing permissions and 21 | // limitations under the License. 22 | 23 | #pragma once 24 | 25 | #include 26 | #include "esp_err.h" 27 | #include "esp_intr_alloc.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * @brief Register a handler for specific RTC_CNTL interrupts 35 | * 36 | * Multiple handlers can be registered using this function. Whenever an 37 | * RTC interrupt happens, all handlers with matching rtc_intr_mask values 38 | * will be called. 39 | * 40 | * @param handler handler function to call 41 | * @param handler_arg argument to be passed to the handler 42 | * @param rtc_intr_mask combination of RTC_CNTL_*_INT_ENA bits indicating the 43 | * sources to call the handler for 44 | * @return 45 | * - ESP_OK on success 46 | * - ESP_ERR_NO_MEM not enough memory to allocate handler structure 47 | * - other errors returned by esp_intr_alloc 48 | */ 49 | esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, 50 | uint32_t rtc_intr_mask); 51 | /** 52 | * @brief Deregister the handler previously registered using rtc_isr_register 53 | * @param handler handler function to call (as passed to rtc_isr_register) 54 | * @param handler_arg argument of the handler (as passed to rtc_isr_register) 55 | * @return 56 | * - ESP_OK on success 57 | * - ESP_ERR_INVALID_STATE if a handler matching both handler and 58 | * handler_arg isn't registered 59 | */ 60 | esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | -------------------------------------------------------------------------------- /old/v89/settings.h: -------------------------------------------------------------------------------- 1 | static const char devname[] = "desklens"; // name of your camera for mDNS, Router, and filenames 2 | 3 | // https://sites.google.com/a/usapiens.com/opnode/time-zones -- find your timezone here 4 | #define TIMEZONE "GMT0BST,M3.5.0/01,M10.5.0/02" // your timezone - this is GMT 5 | 6 | // 1 for blink red led with every sd card write, at your frame rate 7 | // 0 for blink only for skipping frames and SOS if camera or sd is broken 8 | #define BlinkWithWrite 1 9 | 10 | // EDIT ssid and password 11 | const char* ssid = "jzjzjz"; 12 | const char* password = "jzjzjz"; 13 | 14 | // reboot startup parameters here 15 | 16 | int Internet_Enabled = 1; // set to 0 to shut off all internet activities - wifi, time, http, ftp, telegram 17 | int DeepSleepPir = 0; // set to 1 to deepsleep between pir videos 18 | int record_on_reboot = 1; // set to 1 to record, or 0 to NOT record on reboot 19 | int PIRpin = 13; // for active high pir or microwave etc 20 | int PIRenabled = 0; // 1 is PIR is enable on reboot, will only work if you are not recording 21 | 22 | // here are 2 sets of startup parameters -- more down in the stop and restart webpage 23 | 24 | 25 | // VGA 10 fps for 30 minutes, and repeat, play at real time 26 | /* 27 | int framesize = 6; // 10 UXGA, 7 SVGA, 6 VGA, 5 CIF 28 | int repeat_config = 100; // repaeat same movie this many times 29 | int xspeed = 1; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frame ( 30 fps / 0.1 fps ) 30 | int gray = 0; // not gray 31 | int quality = 12; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 32 | int capture_interval = 100; // milli-seconds between frames 33 | volatile int total_frames_config = 18000; // how many frames - length of movie in ms is total_frames x capture_interval 34 | */ 35 | 36 | // UXGA 1 frame every 10 seconds for 60 minutes, and repeat, play at 30 fps or 300 times speed 37 | 38 | int framesize = 10; // 10 UXGA, 7 SVGA, 6 VGA, 5 CIF 39 | int repeat_config = 300; // repaeat same movie this many times 40 | int xspeed = 300; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frames ( 30 fps / 0.1 fps ) 41 | int gray = 0; // not gray 42 | int quality = 12; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 43 | int capture_interval = 10000; // milli-seconds between frames 44 | volatile int total_frames_config = 360; // how many frames - length of movie is total_frames x capture_interval 45 | 46 | 47 | // enable the www.telegram.org BOT - it sends a text and and snapshot to you every time it starts a video 48 | // https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot 49 | // I'm using the branch v1.2 from June 2020 - new master introduced late june, but not working for picture and captions, so my v1.2 mods included here 50 | // You need to create a bot, and get its number BOTtoken, and then get your telegram number -- all free at telegram.org 51 | 52 | RTC_DATA_ATTR int EnableBOT = 0; 53 | #define BOTtoken "9876543210:qwertyuiopasdfghjklzxcvbnmqwertyuio" // get your own bot and id at telegram.org 54 | #define BOTme "1234567890" 55 | -------------------------------------------------------------------------------- /old/v94/ESP32FtpServer.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * FTP SERVER FOR ESP8266 4 | * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) 5 | * based on Jean-Michel Gallego's work 6 | * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | // 2017: modified by @robo8080 22 | // 2019: modified by @fa1ke5 23 | 24 | /******************************************************************************* 25 | ** ** 26 | ** DEFINITIONS FOR FTP SERVER ** 27 | ** ** 28 | *******************************************************************************/ 29 | 30 | // Uncomment to print debugging info to console attached to ESP8266 31 | //#define FTP_DEBUG 32 | 33 | #ifndef FTP_SERVERESP_H 34 | #define FTP_SERVERESP_H 35 | 36 | //#include "Streaming.h" 37 | #include "SD_MMC.h" 38 | #include 39 | #include 40 | 41 | #define FTP_SERVER_VERSION "FTP-2016-01-14" 42 | 43 | #define FTP_CTRL_PORT 21 // Command port on wich server is listening 44 | #define FTP_DATA_PORT_PASV 50009 // Data port in passive mode 45 | 46 | #define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity 47 | #define FTP_CMD_SIZE 255 + 8 // max size of a command 48 | #define FTP_CWD_SIZE 255 + 8 // max size of a directory name 49 | #define FTP_FIL_SIZE 255 // max size of a file name 50 | 51 | //#define FTP_BUF_SIZE 512 //512 // size of file buffer for read/write 52 | //#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write 53 | //#define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. 54 | //#define FTP_BUF_SIZE 8192 reduce in v82 55 | //#define FTP_BUF_SIZE 2048 56 | 57 | #define FTP_BUF_SIZE 4096 58 | 59 | 60 | class FtpServer 61 | { 62 | public: 63 | void begin(String uname, String pword); 64 | void handleFTP(); 65 | 66 | private: 67 | bool haveParameter(); 68 | bool makeExistsPath( char * path, char * param = NULL ); 69 | void iniVariables(); 70 | void clientConnected(); 71 | void disconnectClient(); 72 | boolean userIdentity(); 73 | boolean userPassword(); 74 | boolean processCommand(); 75 | boolean dataConnect(); 76 | boolean doRetrieve(); 77 | boolean doStore(); 78 | void closeTransfer(); 79 | void abortTransfer(); 80 | boolean makePath( char * fullname ); 81 | boolean makePath( char * fullName, char * param ); 82 | uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, 83 | uint8_t * phour, uint8_t * pminute, uint8_t * second ); 84 | char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); 85 | int8_t readChar(); 86 | 87 | IPAddress dataIp; // IP address of client for data 88 | WiFiClient client; 89 | WiFiClient data; 90 | 91 | File file; 92 | 93 | boolean dataPassiveConn; 94 | uint16_t dataPort; 95 | char buf[ FTP_BUF_SIZE ]; // data buffer for transfers 96 | char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client 97 | char cwdName[ FTP_CWD_SIZE ]; // name of current directory 98 | char command[ 5 ]; // command sent by client 99 | boolean rnfrCmd; // previous command was RNFR 100 | char * parameters; // point to begin of parameters sent by client 101 | uint16_t iCL; // pointer to cmdLine next incoming char 102 | int8_t cmdStatus, // status of ftp command connexion 103 | transferStatus; // status of ftp data transfer 104 | uint32_t millisTimeOut, // disconnect after 5 min of inactivity 105 | millisDelay, 106 | millisEndConnection, // 107 | millisBeginTrans, // store time of beginning of a transaction 108 | bytesTransfered; // 109 | String _FTP_USER; 110 | String _FTP_PASS; 111 | 112 | 113 | 114 | }; 115 | 116 | #endif // FTP_SERVERESP_H 117 | -------------------------------------------------------------------------------- /old/v94/UniversalTelegramBot.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 Brian Lough. All right reserved. 3 | 4 | UniversalTelegramBot - Library to create your own Telegram Bot using 5 | ESP8266 or ESP32 on Arduino IDE. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef UniversalTelegramBot_h 23 | #define UniversalTelegramBot_h 24 | 25 | #define ARDUINOJSON_DECODE_UNICODE 1 26 | #define ARDUINOJSON_USE_LONG_LONG 1 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define HOST "api.telegram.org" 33 | #define SSL_PORT 443 34 | #define HANDLE_MESSAGES 1 35 | 36 | //unmark following line to enable debug mode 37 | //#define _debug 38 | 39 | typedef bool (*MoreDataAvailable)(); 40 | typedef byte (*GetNextByte)(); 41 | typedef byte* (*GetNextBuffer)(); 42 | typedef int (GetNextBufferLen)(); 43 | 44 | struct telegramMessage { 45 | String text; 46 | String chat_id; 47 | String chat_title; 48 | String from_id; 49 | String from_name; 50 | String date; 51 | String type; 52 | float longitude; 53 | float latitude; 54 | int update_id; 55 | }; 56 | 57 | class UniversalTelegramBot { 58 | public: 59 | UniversalTelegramBot(String token, Client &client); 60 | String sendGetToTelegram(String command); 61 | String sendPostToTelegram(String command, JsonObject payload); 62 | String 63 | sendMultipartFormDataToTelegram(String command, String binaryProperyName, 64 | String fileName, String contentType, 65 | String chat_id, int fileSize, 66 | MoreDataAvailable moreDataAvailableCallback, 67 | GetNextByte getNextByteCallback, 68 | GetNextBuffer getNextBufferCallback, 69 | GetNextBufferLen getNextBufferLenCallback); 70 | 71 | String 72 | sendMultipartFormDataToTelegramWithCaption(String command, String binaryProperyName, 73 | String fileName, String contentType, 74 | String caption, String chat_id, int fileSize, 75 | MoreDataAvailable moreDataAvailableCallback, 76 | GetNextByte getNextByteCallback, 77 | GetNextBuffer getNextBufferCallback, 78 | GetNextBufferLen getNextBufferLenCallback); 79 | 80 | 81 | bool getMe(); 82 | 83 | bool sendSimpleMessage(String chat_id, String text, String parse_mode); 84 | bool sendMessage(String chat_id, String text, String parse_mode = ""); 85 | bool sendMessageWithReplyKeyboard(String chat_id, String text, 86 | String parse_mode, String keyboard, 87 | bool resize = false, bool oneTime = false, 88 | bool selective = false); 89 | bool sendMessageWithInlineKeyboard(String chat_id, String text, 90 | String parse_mode, String keyboard); 91 | 92 | bool sendChatAction(String chat_id, String text); 93 | 94 | bool sendPostMessage(JsonObject payload); 95 | String sendPostPhoto(JsonObject payload); 96 | String sendPhotoByBinary(String chat_id, String contentType, int fileSize, 97 | MoreDataAvailable moreDataAvailableCallback, 98 | GetNextByte getNextByteCallback, 99 | GetNextBuffer getNextBufferCallback, 100 | GetNextBufferLen getNextBufferLenCallback); 101 | String sendPhoto(String chat_id, String photo, String caption = "", 102 | bool disable_notification = false, 103 | int reply_to_message_id = 0, String keyboard = ""); 104 | 105 | int getUpdates(long offset); 106 | bool checkForOkResponse(String response); 107 | telegramMessage messages[HANDLE_MESSAGES]; 108 | long last_message_received; 109 | String name; 110 | String userName; 111 | int longPoll = 0; 112 | int waitForResponse = 5000; //jz = 1500; 113 | int jzdelay = 60; // delay between multipart blocks 114 | int jzblocksize = 2 * 1024; // multipart block size 115 | 116 | private: 117 | // JsonObject * parseUpdates(String response); 118 | String _token; 119 | Client *client; 120 | void closeClient(); 121 | const int maxMessageLength = 1500; //was 1500 122 | bool processResult(JsonObject result, int messageIndex); 123 | }; 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /old/v94/readme: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /old/v94/rtc_cntl.h: -------------------------------------------------------------------------------- 1 | // ... pending inclusion in the new esp32 distribution - jz 2 | 3 | // You may have to edit rtc_cntl.h ... according to this link -- doesn't seem to be included in esp32 libraries as of Jun 2020 ... or I'll just put it here 4 | // https://github.com/espressif/esp-idf/commit/17bd6e8faba15812780d21e6e3db08fb26dd7033#diff-5e22dcf9fc6087d1585c7b2e434c0932 5 | // https://github.com/espressif/esp-idf/pull/4532 6 | // C:\Users\James\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\driver\driver -- approximate path 7 | 8 | 9 | // Copyright 2016-2017 Espressif Systems (Shanghai) PTE LTD 10 | // 11 | // Licensed under the Apache License, Version 2.0 (the "License"); 12 | // you may not use this file except in compliance with the License. 13 | // You may obtain a copy of the License at 14 | // 15 | // http://www.apache.org/licenses/LICENSE-2.0 16 | // 17 | // Unless required by applicable law or agreed to in writing, software 18 | // distributed under the License is distributed on an "AS IS" BASIS, 19 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | // See the License for the specific language governing permissions and 21 | // limitations under the License. 22 | 23 | #pragma once 24 | 25 | #include 26 | #include "esp_err.h" 27 | #include "esp_intr_alloc.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * @brief Register a handler for specific RTC_CNTL interrupts 35 | * 36 | * Multiple handlers can be registered using this function. Whenever an 37 | * RTC interrupt happens, all handlers with matching rtc_intr_mask values 38 | * will be called. 39 | * 40 | * @param handler handler function to call 41 | * @param handler_arg argument to be passed to the handler 42 | * @param rtc_intr_mask combination of RTC_CNTL_*_INT_ENA bits indicating the 43 | * sources to call the handler for 44 | * @return 45 | * - ESP_OK on success 46 | * - ESP_ERR_NO_MEM not enough memory to allocate handler structure 47 | * - other errors returned by esp_intr_alloc 48 | */ 49 | esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, 50 | uint32_t rtc_intr_mask); 51 | /** 52 | * @brief Deregister the handler previously registered using rtc_isr_register 53 | * @param handler handler function to call (as passed to rtc_isr_register) 54 | * @param handler_arg argument of the handler (as passed to rtc_isr_register) 55 | * @return 56 | * - ESP_OK on success 57 | * - ESP_ERR_INVALID_STATE if a handler matching both handler and 58 | * handler_arg isn't registered 59 | */ 60 | esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | -------------------------------------------------------------------------------- /old/v94/settings.h: -------------------------------------------------------------------------------- 1 | static const char devname[] = "desklens"; // name of your camera for mDNS, Router, and filenames 2 | 3 | // https://sites.google.com/a/usapiens.com/opnode/time-zones -- find your timezone here 4 | #define TIMEZONE "GMT0BST,M3.5.0/01,M10.5.0/02" // your timezone - this is GMT 5 | 6 | // 1 for blink red led with every sd card write, at your frame rate 7 | // 0 for blink only for skipping frames and SOS if camera or sd is broken 8 | #define BlinkWithWrite 1 9 | 10 | // EDIT ssid and password 11 | const char* ssid = "jzjzjz"; 12 | const char* password = "jzjzjz"; 13 | 14 | // reboot startup parameters here 15 | 16 | int Internet_Enabled = 1; // set to 0 to shut off all internet activities - wifi, time, http, ftp, telegram 17 | int DeepSleepPir = 0; // set to 1 to deepsleep between pir videos 18 | int record_on_reboot = 1; // set to 1 to record, or 0 to NOT record on reboot 19 | int PIRpin = 13; // for active high pir or microwave etc 20 | int PIRenabled = 0; // 1 is PIR is enable on reboot, will only work if you are not recording 21 | 22 | int MagicNumber = 314; // change this if you are re-compiling and you dont want to use the ESPROM settings 23 | int stream_interval = 333; // milliseconds between frames delivered during the live stream - 333 is 3 fps 24 | 25 | // here are 2 sets of startup parameters -- more down in the stop and restart webpage 26 | 27 | // VGA 10 fps for 30 minutes, and repeat, play at real time 28 | 29 | int framesize = 6; // 10 UXGA, 7 SVGA, 6 VGA, 5 CIF 30 | int repeat_config = 100; // repaeat same movie this many times 31 | int xspeed = 1; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frame ( 30 fps / 0.1 fps ) 32 | int gray = 0; // not gray 33 | int quality = 12; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 34 | int capture_interval = 100; // milli-seconds between frames 35 | volatile int total_frames_config = 18000; // how many frames - length of movie in ms is total_frames x capture_interval 36 | 37 | 38 | // UXGA 1 frame every 10 seconds for 60 minutes, and repeat, play at 30 fps or 300 times speed 39 | /* 40 | int framesize = 10; // 10 UXGA, 7 SVGA, 6 VGA, 5 CIF 41 | int repeat_config = 300; // repaeat same movie this many times 42 | int xspeed = 300; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frames ( 30 fps / 0.1 fps ) 43 | int gray = 0; // not gray 44 | int quality = 6; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 45 | int capture_interval = 10000; // milli-seconds between frames 46 | volatile int total_frames_config = 360; // how many frames - length of movie is total_frames x capture_interval 47 | */ 48 | 49 | // enable the www.telegram.org BOT - it sends a text and and snapshot to you every time it starts a video 50 | // https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot 51 | // I'm using the branch v1.2 from June 2020 - new master introduced late june, but not working for picture and captions, so my v1.2 mods included here 52 | // You need to create a bot, and get its number BOTtoken, and then get your telegram number -- all free at telegram.org 53 | // detailed instructions here https://randomnerdtutorials.com/telegram-control-esp32-esp8266-nodemcu-outputs/ 54 | 55 | RTC_DATA_ATTR int EnableBOT = 0; // change to 1 for enable - must fill in your numbers below 56 | #define BOTtoken "9876543210:qwertyuiopasdfghjklzxcvbnmqwertyuio" // get your own bot and id at telegram.org 57 | #define BOTme "1234567890" 58 | -------------------------------------------------------------------------------- /old/v94/web_v94.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/old/v94/web_v94.jpg -------------------------------------------------------------------------------- /sample-output/readme.txt: -------------------------------------------------------------------------------- 1 | 2 | ... moved to https://github.com/jameszah/ESP32-CAM-Video-Recorder-samples 3 | 4 | Filenames show date and time at beginning of recording, plus framesize, quality, interval (ms), length(s), and playback speed. 5 | -------------------------------------------------------------------------------- /sample/samples.txt: -------------------------------------------------------------------------------- 1 | ... moved to https://github.com/jameszah/ESP32-CAM-Video-Recorder-samples 2 | 3 | Some samples of the files produced by this program (before I added interval to filename). 4 | 5 | File name shows the date and time of the video starts, then frame size (uxga,svga,vga,cif), 6 | jpeg quality (0..63), length (seconds), and playback speed (x realtime). 7 | 8 | 2019-08-02__13-15-16_uxga_Q10_L30_S1.avi 500 ms - 2 frames per second 9 | 2019-08-02__13-16-28_svga_Q10_L30_S1.avi 200 ms - 5 frames per second 10 | 2019-08-02__13-17-03_vga_Q10_L30_S1.avi 100 ms - 10 frames per second 11 | 2019-08-02__13-17-42_cif_Q10_L30_S1.avi 50 ms - 20 frames per second 12 | 13 | 2019-08-02__13-21-15_uxga_Q5_L120_S20.avi 1000 ms - 1 second per frame, playback 20 times faster 14 | 2019-08-02__15-29-10_uxga_Q5_L1800_S40.avi 5000 ms - 1 second per frame, playback 40 times faster (partial) 15 | 2019-08-02__18-53-29_uxga_Q40_L1800_S40.avi 5000 ms - 5 seconds per frame, playback 40 times faster 16 | -------------------------------------------------------------------------------- /telegram1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/telegram1.jpg -------------------------------------------------------------------------------- /telegram2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/telegram2.jpg -------------------------------------------------------------------------------- /telegram3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/telegram3.jpg -------------------------------------------------------------------------------- /v98-WiFiMan/ESP32FtpServer.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * FTP SERVER FOR ESP8266 4 | * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) 5 | * based on Jean-Michel Gallego's work 6 | * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | // 2017: modified by @robo8080 22 | // 2019: modified by @fa1ke5 23 | 24 | /******************************************************************************* 25 | ** ** 26 | ** DEFINITIONS FOR FTP SERVER ** 27 | ** ** 28 | *******************************************************************************/ 29 | 30 | // Uncomment to print debugging info to console attached to ESP8266 31 | //#define FTP_DEBUG 32 | 33 | #ifndef FTP_SERVERESP_H 34 | #define FTP_SERVERESP_H 35 | 36 | //#include "Streaming.h" 37 | #include "SD_MMC.h" 38 | #include 39 | #include 40 | 41 | #define FTP_SERVER_VERSION "FTP-2016-01-14" 42 | 43 | #define FTP_CTRL_PORT 21 // Command port on wich server is listening 44 | #define FTP_DATA_PORT_PASV 50009 // Data port in passive mode 45 | 46 | #define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity 47 | #define FTP_CMD_SIZE 255 + 8 // max size of a command 48 | #define FTP_CWD_SIZE 255 + 8 // max size of a directory name 49 | #define FTP_FIL_SIZE 255 // max size of a file name 50 | 51 | //#define FTP_BUF_SIZE 512 //512 // size of file buffer for read/write 52 | //#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write 53 | //#define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. 54 | //#define FTP_BUF_SIZE 8192 reduce in v82 55 | //#define FTP_BUF_SIZE 2048 56 | 57 | #define FTP_BUF_SIZE 4096 58 | 59 | 60 | class FtpServer 61 | { 62 | public: 63 | void begin(String uname, String pword); 64 | void handleFTP(); 65 | 66 | private: 67 | bool haveParameter(); 68 | bool makeExistsPath( char * path, char * param = NULL ); 69 | void iniVariables(); 70 | void clientConnected(); 71 | void disconnectClient(); 72 | boolean userIdentity(); 73 | boolean userPassword(); 74 | boolean processCommand(); 75 | boolean dataConnect(); 76 | boolean doRetrieve(); 77 | boolean doStore(); 78 | void closeTransfer(); 79 | void abortTransfer(); 80 | boolean makePath( char * fullname ); 81 | boolean makePath( char * fullName, char * param ); 82 | uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, 83 | uint8_t * phour, uint8_t * pminute, uint8_t * second ); 84 | char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); 85 | int8_t readChar(); 86 | 87 | IPAddress dataIp; // IP address of client for data 88 | WiFiClient client; 89 | WiFiClient data; 90 | 91 | File file; 92 | 93 | boolean dataPassiveConn; 94 | uint16_t dataPort; 95 | char buf[ FTP_BUF_SIZE ]; // data buffer for transfers 96 | char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client 97 | char cwdName[ FTP_CWD_SIZE ]; // name of current directory 98 | char command[ 5 ]; // command sent by client 99 | boolean rnfrCmd; // previous command was RNFR 100 | char * parameters; // point to begin of parameters sent by client 101 | uint16_t iCL; // pointer to cmdLine next incoming char 102 | int8_t cmdStatus, // status of ftp command connexion 103 | transferStatus; // status of ftp data transfer 104 | uint32_t millisTimeOut, // disconnect after 5 min of inactivity 105 | millisDelay, 106 | millisEndConnection, // 107 | millisBeginTrans, // store time of beginning of a transaction 108 | bytesTransfered; // 109 | String _FTP_USER; 110 | String _FTP_PASS; 111 | 112 | 113 | 114 | }; 115 | 116 | #endif // FTP_SERVERESP_H 117 | -------------------------------------------------------------------------------- /v98-WiFiMan/UniversalTelegramBot.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 Brian Lough. All right reserved. 3 | 4 | UniversalTelegramBot - Library to create your own Telegram Bot using 5 | ESP8266 or ESP32 on Arduino IDE. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef UniversalTelegramBot_h 23 | #define UniversalTelegramBot_h 24 | 25 | #define ARDUINOJSON_DECODE_UNICODE 1 26 | #define ARDUINOJSON_USE_LONG_LONG 1 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define HOST "api.telegram.org" 33 | #define SSL_PORT 443 34 | #define HANDLE_MESSAGES 1 35 | 36 | //unmark following line to enable debug mode 37 | //#define _debug 38 | 39 | typedef bool (*MoreDataAvailable)(); 40 | typedef byte (*GetNextByte)(); 41 | typedef byte* (*GetNextBuffer)(); 42 | typedef int (GetNextBufferLen)(); 43 | 44 | struct telegramMessage { 45 | String text; 46 | String chat_id; 47 | String chat_title; 48 | String from_id; 49 | String from_name; 50 | String date; 51 | String type; 52 | float longitude; 53 | float latitude; 54 | int update_id; 55 | }; 56 | 57 | class UniversalTelegramBot { 58 | public: 59 | UniversalTelegramBot(String token, Client &client); 60 | String sendGetToTelegram(String command); 61 | String sendPostToTelegram(String command, JsonObject payload); 62 | String 63 | sendMultipartFormDataToTelegram(String command, String binaryProperyName, 64 | String fileName, String contentType, 65 | String chat_id, int fileSize, 66 | MoreDataAvailable moreDataAvailableCallback, 67 | GetNextByte getNextByteCallback, 68 | GetNextBuffer getNextBufferCallback, 69 | GetNextBufferLen getNextBufferLenCallback); 70 | 71 | String 72 | sendMultipartFormDataToTelegramWithCaption(String command, String binaryProperyName, 73 | String fileName, String contentType, 74 | String caption, String chat_id, int fileSize, 75 | MoreDataAvailable moreDataAvailableCallback, 76 | GetNextByte getNextByteCallback, 77 | GetNextBuffer getNextBufferCallback, 78 | GetNextBufferLen getNextBufferLenCallback); 79 | 80 | 81 | bool getMe(); 82 | 83 | bool sendSimpleMessage(String chat_id, String text, String parse_mode); 84 | bool sendMessage(String chat_id, String text, String parse_mode = ""); 85 | bool sendMessageWithReplyKeyboard(String chat_id, String text, 86 | String parse_mode, String keyboard, 87 | bool resize = false, bool oneTime = false, 88 | bool selective = false); 89 | bool sendMessageWithInlineKeyboard(String chat_id, String text, 90 | String parse_mode, String keyboard); 91 | 92 | bool sendChatAction(String chat_id, String text); 93 | 94 | bool sendPostMessage(JsonObject payload); 95 | String sendPostPhoto(JsonObject payload); 96 | String sendPhotoByBinary(String chat_id, String contentType, int fileSize, 97 | MoreDataAvailable moreDataAvailableCallback, 98 | GetNextByte getNextByteCallback, 99 | GetNextBuffer getNextBufferCallback, 100 | GetNextBufferLen getNextBufferLenCallback); 101 | String sendPhoto(String chat_id, String photo, String caption = "", 102 | bool disable_notification = false, 103 | int reply_to_message_id = 0, String keyboard = ""); 104 | 105 | int getUpdates(long offset); 106 | bool checkForOkResponse(String response); 107 | telegramMessage messages[HANDLE_MESSAGES]; 108 | long last_message_received; 109 | String name; 110 | String userName; 111 | int longPoll = 0; 112 | int waitForResponse = 5000; //jz = 1500; 113 | int jzdelay = 60; // delay between multipart blocks 114 | int jzblocksize = 2 * 1024; // multipart block size 115 | 116 | private: 117 | // JsonObject * parseUpdates(String response); 118 | String _token; 119 | Client *client; 120 | void closeClient(); 121 | const int maxMessageLength = 1500; //was 1500 122 | bool processResult(JsonObject result, int messageIndex); 123 | }; 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /v98-WiFiMan/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /v98-WiFiMan/rtc_cntl.h: -------------------------------------------------------------------------------- 1 | // ... pending inclusion in the new esp32 distribution - jz 2 | 3 | // You may have to edit rtc_cntl.h ... according to this link -- doesn't seem to be included in esp32 libraries as of Jun 2020 ... or I'll just put it here 4 | // https://github.com/espressif/esp-idf/commit/17bd6e8faba15812780d21e6e3db08fb26dd7033#diff-5e22dcf9fc6087d1585c7b2e434c0932 5 | // https://github.com/espressif/esp-idf/pull/4532 6 | // C:\Users\James\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\driver\driver -- approximate path 7 | 8 | 9 | // Copyright 2016-2017 Espressif Systems (Shanghai) PTE LTD 10 | // 11 | // Licensed under the Apache License, Version 2.0 (the "License"); 12 | // you may not use this file except in compliance with the License. 13 | // You may obtain a copy of the License at 14 | // 15 | // http://www.apache.org/licenses/LICENSE-2.0 16 | // 17 | // Unless required by applicable law or agreed to in writing, software 18 | // distributed under the License is distributed on an "AS IS" BASIS, 19 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | // See the License for the specific language governing permissions and 21 | // limitations under the License. 22 | 23 | #pragma once 24 | 25 | #include 26 | #include "esp_err.h" 27 | #include "esp_intr_alloc.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * @brief Register a handler for specific RTC_CNTL interrupts 35 | * 36 | * Multiple handlers can be registered using this function. Whenever an 37 | * RTC interrupt happens, all handlers with matching rtc_intr_mask values 38 | * will be called. 39 | * 40 | * @param handler handler function to call 41 | * @param handler_arg argument to be passed to the handler 42 | * @param rtc_intr_mask combination of RTC_CNTL_*_INT_ENA bits indicating the 43 | * sources to call the handler for 44 | * @return 45 | * - ESP_OK on success 46 | * - ESP_ERR_NO_MEM not enough memory to allocate handler structure 47 | * - other errors returned by esp_intr_alloc 48 | */ 49 | esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, 50 | uint32_t rtc_intr_mask); 51 | /** 52 | * @brief Deregister the handler previously registered using rtc_isr_register 53 | * @param handler handler function to call (as passed to rtc_isr_register) 54 | * @param handler_arg argument of the handler (as passed to rtc_isr_register) 55 | * @return 56 | * - ESP_OK on success 57 | * - ESP_ERR_INVALID_STATE if a handler matching both handler and 58 | * handler_arg isn't registered 59 | */ 60 | esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | -------------------------------------------------------------------------------- /v98-WiFiMan/settings.h: -------------------------------------------------------------------------------- 1 | static const char devname[] = "desklens"; // name of your camera for mDNS, Router, and filenames 2 | 3 | #define include_telegram 4 | //#define include_pir_and_touch 5 | #define include_ftp 6 | #define include_streaming 7 | #define get_rid_of_touch 8 | 9 | int delete_old_files = 1; // set to 1 and it will delete your oldest day of files so you SD is always 10% empty 10 | 11 | // https://sites.google.com/a/usapiens.com/opnode/time-zones -- find your timezone here 12 | //#define TIMEZONE "GMT0BST,M3.5.0/01,M10.5.0/02" // your timezone - this is GMT 13 | #define TIMEZONE "MST7MDT,M3.2.0/2:00:00,M11.1.0/2:00:00" // mountain time 14 | 15 | // 1 for blink red led with every sd card write, at your frame rate 16 | // 0 for blink only for skipping frames and SOS if camera or sd is broken 17 | #define BlinkWithWrite 1 18 | 19 | // EDIT ssid and password **** with Version 98x-WiFiMan, you are using WiFiManager to set ssid and password, so these are redundant 20 | const char* ssid = "jzjzjz"; 21 | const char* password = "jzjzjz"; 22 | 23 | // reboot startup parameters here 24 | 25 | int Internet_Enabled = 1; // set to 0 to shut off all internet activities - wifi, time, http, ftp, telegram 26 | int DeepSleepPir = 0; // set to 1 to deepsleep between pir videos 27 | int record_on_reboot = 1; // set to 1 to record, or 0 to NOT record on reboot 28 | int PIRpin = 13; // for active high pir or microwave etc 29 | int PIRenabled = 0; // 1 is PIR is enable on reboot, will only work if you are not recording 30 | 31 | int MagicNumber = 011; // change this if you are re-compiling and you dont want to use the ESPROM settings 32 | int stream_interval = 333; // milliseconds between frames delivered during the live stream - 333 is 3 fps 33 | 34 | // here are 2 sets of startup parameters -- more down in the stop and restart webpage 35 | 36 | // VGA 10 fps for 30 minutes, and repeat, play at real time 37 | 38 | int framesize = 6; // 10 UXGA, 7 SVGA, 6 VGA, 5 CIF 39 | int repeat_config = 100; // repaeat same movie this many times 40 | int xspeed = 1; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frame ( 30 fps / 0.1 fps ) 41 | int gray = 0; // not gray 42 | int quality = 12; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 43 | int capture_interval = 100; // milli-seconds between frames 44 | volatile int total_frames_config = 18000; // how many frames - length of movie in ms is total_frames x capture_interval 45 | 46 | 47 | // UXGA 1 frame every 10 seconds for 60 minutes, and repeat, play at 30 fps or 300 times speed 48 | /* 49 | int framesize = 10; // 10 UXGA, 7 SVGA, 6 VGA, 5 CIF 50 | int repeat_config = 300; // repaeat same movie this many times 51 | int xspeed = 300; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frames ( 30 fps / 0.1 fps ) 52 | int gray = 0; // not gray 53 | int quality = 6; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 54 | int capture_interval = 10000; // milli-seconds between frames 55 | volatile int total_frames_config = 360; // how many frames - length of movie is total_frames x capture_interval 56 | */ 57 | 58 | // enable the www.telegram.org BOT - it sends a text and and snapshot to you every time it starts a video 59 | // https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot 60 | // I'm using the branch v1.2 from June 2020 - new master introduced late june, but not working for picture and captions, so my v1.2 mods included here 61 | // You need to create a bot, and get its number BOTtoken, and then get your telegram number -- all free at telegram.org 62 | // detailed instructions here https://randomnerdtutorials.com/telegram-control-esp32-esp8266-nodemcu-outputs/ 63 | 64 | RTC_DATA_ATTR int EnableBOT = 0; 65 | #define BOTtoken "9876543210:qwertyuiopasdfghjklzxcvbnmqwertyuio" // get your own bot and id at telegram.org 66 | #define BOTme "1234567890" 67 | -------------------------------------------------------------------------------- /v98/ESP32FtpServer.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * FTP SERVER FOR ESP8266 4 | * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) 5 | * based on Jean-Michel Gallego's work 6 | * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | // 2017: modified by @robo8080 22 | // 2019: modified by @fa1ke5 23 | 24 | /******************************************************************************* 25 | ** ** 26 | ** DEFINITIONS FOR FTP SERVER ** 27 | ** ** 28 | *******************************************************************************/ 29 | 30 | // Uncomment to print debugging info to console attached to ESP8266 31 | //#define FTP_DEBUG 32 | 33 | #ifndef FTP_SERVERESP_H 34 | #define FTP_SERVERESP_H 35 | 36 | //#include "Streaming.h" 37 | #include "SD_MMC.h" 38 | #include 39 | #include 40 | 41 | #define FTP_SERVER_VERSION "FTP-2016-01-14" 42 | 43 | #define FTP_CTRL_PORT 21 // Command port on wich server is listening 44 | #define FTP_DATA_PORT_PASV 50009 // Data port in passive mode 45 | 46 | #define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity 47 | #define FTP_CMD_SIZE 255 + 8 // max size of a command 48 | #define FTP_CWD_SIZE 255 + 8 // max size of a directory name 49 | #define FTP_FIL_SIZE 255 // max size of a file name 50 | 51 | //#define FTP_BUF_SIZE 512 //512 // size of file buffer for read/write 52 | //#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write 53 | //#define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. 54 | //#define FTP_BUF_SIZE 8192 reduce in v82 55 | //#define FTP_BUF_SIZE 2048 56 | 57 | #define FTP_BUF_SIZE 4096 58 | 59 | 60 | class FtpServer 61 | { 62 | public: 63 | void begin(String uname, String pword); 64 | void handleFTP(); 65 | 66 | private: 67 | bool haveParameter(); 68 | bool makeExistsPath( char * path, char * param = NULL ); 69 | void iniVariables(); 70 | void clientConnected(); 71 | void disconnectClient(); 72 | boolean userIdentity(); 73 | boolean userPassword(); 74 | boolean processCommand(); 75 | boolean dataConnect(); 76 | boolean doRetrieve(); 77 | boolean doStore(); 78 | void closeTransfer(); 79 | void abortTransfer(); 80 | boolean makePath( char * fullname ); 81 | boolean makePath( char * fullName, char * param ); 82 | uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, 83 | uint8_t * phour, uint8_t * pminute, uint8_t * second ); 84 | char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); 85 | int8_t readChar(); 86 | 87 | IPAddress dataIp; // IP address of client for data 88 | WiFiClient client; 89 | WiFiClient data; 90 | 91 | File file; 92 | 93 | boolean dataPassiveConn; 94 | uint16_t dataPort; 95 | char buf[ FTP_BUF_SIZE ]; // data buffer for transfers 96 | char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client 97 | char cwdName[ FTP_CWD_SIZE ]; // name of current directory 98 | char command[ 5 ]; // command sent by client 99 | boolean rnfrCmd; // previous command was RNFR 100 | char * parameters; // point to begin of parameters sent by client 101 | uint16_t iCL; // pointer to cmdLine next incoming char 102 | int8_t cmdStatus, // status of ftp command connexion 103 | transferStatus; // status of ftp data transfer 104 | uint32_t millisTimeOut, // disconnect after 5 min of inactivity 105 | millisDelay, 106 | millisEndConnection, // 107 | millisBeginTrans, // store time of beginning of a transaction 108 | bytesTransfered; // 109 | String _FTP_USER; 110 | String _FTP_PASS; 111 | 112 | 113 | 114 | }; 115 | 116 | #endif // FTP_SERVERESP_H 117 | -------------------------------------------------------------------------------- /v98/UniversalTelegramBot.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 Brian Lough. All right reserved. 3 | 4 | UniversalTelegramBot - Library to create your own Telegram Bot using 5 | ESP8266 or ESP32 on Arduino IDE. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef UniversalTelegramBot_h 23 | #define UniversalTelegramBot_h 24 | 25 | #define ARDUINOJSON_DECODE_UNICODE 1 26 | #define ARDUINOJSON_USE_LONG_LONG 1 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define HOST "api.telegram.org" 33 | #define SSL_PORT 443 34 | #define HANDLE_MESSAGES 1 35 | 36 | //unmark following line to enable debug mode 37 | //#define _debug 38 | 39 | typedef bool (*MoreDataAvailable)(); 40 | typedef byte (*GetNextByte)(); 41 | typedef byte* (*GetNextBuffer)(); 42 | typedef int (GetNextBufferLen)(); 43 | 44 | struct telegramMessage { 45 | String text; 46 | String chat_id; 47 | String chat_title; 48 | String from_id; 49 | String from_name; 50 | String date; 51 | String type; 52 | float longitude; 53 | float latitude; 54 | int update_id; 55 | }; 56 | 57 | class UniversalTelegramBot { 58 | public: 59 | UniversalTelegramBot(String token, Client &client); 60 | String sendGetToTelegram(String command); 61 | String sendPostToTelegram(String command, JsonObject payload); 62 | String 63 | sendMultipartFormDataToTelegram(String command, String binaryProperyName, 64 | String fileName, String contentType, 65 | String chat_id, int fileSize, 66 | MoreDataAvailable moreDataAvailableCallback, 67 | GetNextByte getNextByteCallback, 68 | GetNextBuffer getNextBufferCallback, 69 | GetNextBufferLen getNextBufferLenCallback); 70 | 71 | String 72 | sendMultipartFormDataToTelegramWithCaption(String command, String binaryProperyName, 73 | String fileName, String contentType, 74 | String caption, String chat_id, int fileSize, 75 | MoreDataAvailable moreDataAvailableCallback, 76 | GetNextByte getNextByteCallback, 77 | GetNextBuffer getNextBufferCallback, 78 | GetNextBufferLen getNextBufferLenCallback); 79 | 80 | 81 | bool getMe(); 82 | 83 | bool sendSimpleMessage(String chat_id, String text, String parse_mode); 84 | bool sendMessage(String chat_id, String text, String parse_mode = ""); 85 | bool sendMessageWithReplyKeyboard(String chat_id, String text, 86 | String parse_mode, String keyboard, 87 | bool resize = false, bool oneTime = false, 88 | bool selective = false); 89 | bool sendMessageWithInlineKeyboard(String chat_id, String text, 90 | String parse_mode, String keyboard); 91 | 92 | bool sendChatAction(String chat_id, String text); 93 | 94 | bool sendPostMessage(JsonObject payload); 95 | String sendPostPhoto(JsonObject payload); 96 | String sendPhotoByBinary(String chat_id, String contentType, int fileSize, 97 | MoreDataAvailable moreDataAvailableCallback, 98 | GetNextByte getNextByteCallback, 99 | GetNextBuffer getNextBufferCallback, 100 | GetNextBufferLen getNextBufferLenCallback); 101 | String sendPhoto(String chat_id, String photo, String caption = "", 102 | bool disable_notification = false, 103 | int reply_to_message_id = 0, String keyboard = ""); 104 | 105 | int getUpdates(long offset); 106 | bool checkForOkResponse(String response); 107 | telegramMessage messages[HANDLE_MESSAGES]; 108 | long last_message_received; 109 | String name; 110 | String userName; 111 | int longPoll = 0; 112 | int waitForResponse = 5000; //jz = 1500; 113 | int jzdelay = 60; // delay between multipart blocks 114 | int jzblocksize = 2 * 1024; // multipart block size 115 | 116 | private: 117 | // JsonObject * parseUpdates(String response); 118 | String _token; 119 | Client *client; 120 | void closeClient(); 121 | const int maxMessageLength = 1500; //was 1500 122 | bool processResult(JsonObject result, int messageIndex); 123 | }; 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /v98/readme.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /v98/rtc_cntl.h: -------------------------------------------------------------------------------- 1 | // ... pending inclusion in the new esp32 distribution - jz 2 | 3 | // You may have to edit rtc_cntl.h ... according to this link -- doesn't seem to be included in esp32 libraries as of Jun 2020 ... or I'll just put it here 4 | // https://github.com/espressif/esp-idf/commit/17bd6e8faba15812780d21e6e3db08fb26dd7033#diff-5e22dcf9fc6087d1585c7b2e434c0932 5 | // https://github.com/espressif/esp-idf/pull/4532 6 | // C:\Users\James\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\driver\driver -- approximate path 7 | 8 | 9 | // Copyright 2016-2017 Espressif Systems (Shanghai) PTE LTD 10 | // 11 | // Licensed under the Apache License, Version 2.0 (the "License"); 12 | // you may not use this file except in compliance with the License. 13 | // You may obtain a copy of the License at 14 | // 15 | // http://www.apache.org/licenses/LICENSE-2.0 16 | // 17 | // Unless required by applicable law or agreed to in writing, software 18 | // distributed under the License is distributed on an "AS IS" BASIS, 19 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | // See the License for the specific language governing permissions and 21 | // limitations under the License. 22 | 23 | #pragma once 24 | 25 | #include 26 | #include "esp_err.h" 27 | #include "esp_intr_alloc.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * @brief Register a handler for specific RTC_CNTL interrupts 35 | * 36 | * Multiple handlers can be registered using this function. Whenever an 37 | * RTC interrupt happens, all handlers with matching rtc_intr_mask values 38 | * will be called. 39 | * 40 | * @param handler handler function to call 41 | * @param handler_arg argument to be passed to the handler 42 | * @param rtc_intr_mask combination of RTC_CNTL_*_INT_ENA bits indicating the 43 | * sources to call the handler for 44 | * @return 45 | * - ESP_OK on success 46 | * - ESP_ERR_NO_MEM not enough memory to allocate handler structure 47 | * - other errors returned by esp_intr_alloc 48 | */ 49 | esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, 50 | uint32_t rtc_intr_mask); 51 | /** 52 | * @brief Deregister the handler previously registered using rtc_isr_register 53 | * @param handler handler function to call (as passed to rtc_isr_register) 54 | * @param handler_arg argument of the handler (as passed to rtc_isr_register) 55 | * @return 56 | * - ESP_OK on success 57 | * - ESP_ERR_INVALID_STATE if a handler matching both handler and 58 | * handler_arg isn't registered 59 | */ 60 | esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | -------------------------------------------------------------------------------- /v98/settings.h: -------------------------------------------------------------------------------- 1 | static const char devname[] = "desklens"; // name of your camera for mDNS, Router, and filenames 2 | 3 | #define include_telegram 4 | #define include_pir_and_touch 5 | #define include_ftp 6 | #define include_streaming 7 | #define get_rid_of_touch 8 | 9 | int delete_old_files = 1; // set to 1 and it will delete your oldest day of files so you SD is always 10% empty 10 | 11 | // https://sites.google.com/a/usapiens.com/opnode/time-zones -- find your timezone here 12 | #define TIMEZONE "GMT0BST,M3.5.0/01,M10.5.0/02" // your timezone - this is GMT 13 | 14 | // 1 for blink red led with every sd card write, at your frame rate 15 | // 0 for blink only for skipping frames and SOS if camera or sd is broken 16 | #define BlinkWithWrite 1 17 | 18 | // EDIT ssid and password 19 | const char* ssid = "jzjzjz"; 20 | const char* password = "jzjzjz"; 21 | 22 | // reboot startup parameters here 23 | 24 | int Internet_Enabled = 1; // set to 0 to shut off all internet activities - wifi, time, http, ftp, telegram 25 | int DeepSleepPir = 0; // set to 1 to deepsleep between pir videos 26 | int record_on_reboot = 1; // set to 1 to record, or 0 to NOT record on reboot 27 | int PIRpin = 13; // for active high pir or microwave etc 28 | int PIRenabled = 0; // 1 is PIR is enable on reboot, will only work if you are not recording 29 | 30 | int MagicNumber = 011; // change this if you are re-compiling and you dont want to use the ESPROM settings 31 | int stream_interval = 333; // milliseconds between frames delivered during the live stream - 333 is 3 fps 32 | 33 | // here are 2 sets of startup parameters -- more down in the stop and restart webpage 34 | 35 | // VGA 10 fps for 30 minutes, and repeat, play at real time 36 | 37 | int framesize = 6; // 10 UXGA, 7 SVGA, 6 VGA, 5 CIF 38 | int repeat_config = 100; // repaeat same movie this many times 39 | int xspeed = 1; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frame ( 30 fps / 0.1 fps ) 40 | int gray = 0; // not gray 41 | int quality = 12; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 42 | int capture_interval = 100; // milli-seconds between frames 43 | volatile int total_frames_config = 18000; // how many frames - length of movie in ms is total_frames x capture_interval 44 | 45 | 46 | // UXGA 1 frame every 10 seconds for 60 minutes, and repeat, play at 30 fps or 300 times speed 47 | /* 48 | int framesize = 10; // 10 UXGA, 7 SVGA, 6 VGA, 5 CIF 49 | int repeat_config = 300; // repaeat same movie this many times 50 | int xspeed = 300; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frames ( 30 fps / 0.1 fps ) 51 | int gray = 0; // not gray 52 | int quality = 6; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 53 | int capture_interval = 10000; // milli-seconds between frames 54 | volatile int total_frames_config = 360; // how many frames - length of movie is total_frames x capture_interval 55 | */ 56 | 57 | // enable the www.telegram.org BOT - it sends a text and and snapshot to you every time it starts a video 58 | // https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot 59 | // I'm using the branch v1.2 from June 2020 - new master introduced late june, but not working for picture and captions, so my v1.2 mods included here 60 | // You need to create a bot, and get its number BOTtoken, and then get your telegram number -- all free at telegram.org 61 | // detailed instructions here https://randomnerdtutorials.com/telegram-control-esp32-esp8266-nodemcu-outputs/ 62 | 63 | RTC_DATA_ATTR int EnableBOT = 0; 64 | #define BOTtoken "9876543210:qwertyuiopasdfghjklzxcvbnmqwertyuio" // get your own bot and id at telegram.org 65 | #define BOTme "1234567890" 66 | -------------------------------------------------------------------------------- /v99/ESP32FtpServer.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * FTP SERVER FOR ESP8266 4 | * based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) 5 | * based on Jean-Michel Gallego's work 6 | * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) 7 | * 8 | * This program is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation, either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program. If not, see . 20 | */ 21 | // 2017: modified by @robo8080 22 | // 2019: modified by @fa1ke5 23 | 24 | /******************************************************************************* 25 | ** ** 26 | ** DEFINITIONS FOR FTP SERVER ** 27 | ** ** 28 | *******************************************************************************/ 29 | 30 | // Uncomment to print debugging info to console attached to ESP8266 31 | //#define FTP_DEBUG 32 | 33 | #ifndef FTP_SERVERESP_H 34 | #define FTP_SERVERESP_H 35 | 36 | //#include "Streaming.h" 37 | #include "SD_MMC.h" 38 | #include 39 | #include 40 | 41 | #define FTP_SERVER_VERSION "FTP-2016-01-14" 42 | 43 | #define FTP_CTRL_PORT 21 // Command port on wich server is listening 44 | #define FTP_DATA_PORT_PASV 50009 // Data port in passive mode 45 | 46 | #define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity 47 | #define FTP_CMD_SIZE 255 + 8 // max size of a command 48 | #define FTP_CWD_SIZE 255 + 8 // max size of a directory name 49 | #define FTP_FIL_SIZE 255 // max size of a file name 50 | 51 | //#define FTP_BUF_SIZE 512 //512 // size of file buffer for read/write 52 | //#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write 53 | //#define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. 54 | //#define FTP_BUF_SIZE 8192 reduce in v82 55 | //#define FTP_BUF_SIZE 2048 56 | 57 | #define FTP_BUF_SIZE 4096 58 | 59 | 60 | class FtpServer 61 | { 62 | public: 63 | void begin(String uname, String pword); 64 | void handleFTP(); 65 | 66 | private: 67 | bool haveParameter(); 68 | bool makeExistsPath( char * path, char * param = NULL ); 69 | void iniVariables(); 70 | void clientConnected(); 71 | void disconnectClient(); 72 | boolean userIdentity(); 73 | boolean userPassword(); 74 | boolean processCommand(); 75 | boolean dataConnect(); 76 | boolean doRetrieve(); 77 | boolean doStore(); 78 | void closeTransfer(); 79 | void abortTransfer(); 80 | boolean makePath( char * fullname ); 81 | boolean makePath( char * fullName, char * param ); 82 | uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, 83 | uint8_t * phour, uint8_t * pminute, uint8_t * second ); 84 | char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time ); 85 | int8_t readChar(); 86 | 87 | IPAddress dataIp; // IP address of client for data 88 | WiFiClient client; 89 | WiFiClient data; 90 | 91 | File file; 92 | 93 | boolean dataPassiveConn; 94 | uint16_t dataPort; 95 | char buf[ FTP_BUF_SIZE ]; // data buffer for transfers 96 | char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client 97 | char cwdName[ FTP_CWD_SIZE ]; // name of current directory 98 | char command[ 5 ]; // command sent by client 99 | boolean rnfrCmd; // previous command was RNFR 100 | char * parameters; // point to begin of parameters sent by client 101 | uint16_t iCL; // pointer to cmdLine next incoming char 102 | int8_t cmdStatus, // status of ftp command connexion 103 | transferStatus; // status of ftp data transfer 104 | uint32_t millisTimeOut, // disconnect after 5 min of inactivity 105 | millisDelay, 106 | millisEndConnection, // 107 | millisBeginTrans, // store time of beginning of a transaction 108 | bytesTransfered; // 109 | String _FTP_USER; 110 | String _FTP_PASS; 111 | 112 | 113 | 114 | }; 115 | 116 | #endif // FTP_SERVERESP_H 117 | -------------------------------------------------------------------------------- /v99/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /v99/UniversalTelegramBot.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 Brian Lough. All right reserved. 3 | 4 | UniversalTelegramBot - Library to create your own Telegram Bot using 5 | ESP8266 or ESP32 on Arduino IDE. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef UniversalTelegramBot_h 23 | #define UniversalTelegramBot_h 24 | 25 | #define ARDUINOJSON_DECODE_UNICODE 1 26 | #define ARDUINOJSON_USE_LONG_LONG 1 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define HOST "api.telegram.org" 33 | #define SSL_PORT 443 34 | #define HANDLE_MESSAGES 1 35 | 36 | //unmark following line to enable debug mode 37 | //#define _debug 38 | 39 | typedef bool (*MoreDataAvailable)(); 40 | typedef byte (*GetNextByte)(); 41 | typedef byte* (*GetNextBuffer)(); 42 | typedef int (GetNextBufferLen)(); 43 | 44 | struct telegramMessage { 45 | String text; 46 | String chat_id; 47 | String chat_title; 48 | String from_id; 49 | String from_name; 50 | String date; 51 | String type; 52 | float longitude; 53 | float latitude; 54 | int update_id; 55 | }; 56 | 57 | class UniversalTelegramBot { 58 | public: 59 | UniversalTelegramBot(String token, Client &client); 60 | String sendGetToTelegram(String command); 61 | String sendPostToTelegram(String command, JsonObject payload); 62 | String 63 | sendMultipartFormDataToTelegram(String command, String binaryProperyName, 64 | String fileName, String contentType, 65 | String chat_id, int fileSize, 66 | MoreDataAvailable moreDataAvailableCallback, 67 | GetNextByte getNextByteCallback, 68 | GetNextBuffer getNextBufferCallback, 69 | GetNextBufferLen getNextBufferLenCallback); 70 | 71 | String 72 | sendMultipartFormDataToTelegramWithCaption(String command, String binaryProperyName, 73 | String fileName, String contentType, 74 | String caption, String chat_id, int fileSize, 75 | MoreDataAvailable moreDataAvailableCallback, 76 | GetNextByte getNextByteCallback, 77 | GetNextBuffer getNextBufferCallback, 78 | GetNextBufferLen getNextBufferLenCallback); 79 | 80 | 81 | bool getMe(); 82 | 83 | bool sendSimpleMessage(String chat_id, String text, String parse_mode); 84 | bool sendMessage(String chat_id, String text, String parse_mode = ""); 85 | bool sendMessageWithReplyKeyboard(String chat_id, String text, 86 | String parse_mode, String keyboard, 87 | bool resize = false, bool oneTime = false, 88 | bool selective = false); 89 | bool sendMessageWithInlineKeyboard(String chat_id, String text, 90 | String parse_mode, String keyboard); 91 | 92 | bool sendChatAction(String chat_id, String text); 93 | 94 | bool sendPostMessage(JsonObject payload); 95 | String sendPostPhoto(JsonObject payload); 96 | String sendPhotoByBinary(String chat_id, String contentType, int fileSize, 97 | MoreDataAvailable moreDataAvailableCallback, 98 | GetNextByte getNextByteCallback, 99 | GetNextBuffer getNextBufferCallback, 100 | GetNextBufferLen getNextBufferLenCallback); 101 | String sendPhoto(String chat_id, String photo, String caption = "", 102 | bool disable_notification = false, 103 | int reply_to_message_id = 0, String keyboard = ""); 104 | 105 | int getUpdates(long offset); 106 | bool checkForOkResponse(String response); 107 | telegramMessage messages[HANDLE_MESSAGES]; 108 | long last_message_received; 109 | String name; 110 | String userName; 111 | int longPoll = 0; 112 | int waitForResponse = 5000; //jz = 1500; 113 | int jzdelay = 10; //60; // delay between multipart blocks 114 | int jzblocksize = 2 * 1024; // multipart block size 115 | 116 | private: 117 | // JsonObject * parseUpdates(String response); 118 | String _token; 119 | Client *client; 120 | void closeClient(); 121 | const int maxMessageLength = 1500; //was 1500 122 | bool processResult(JsonObject result, int messageIndex); 123 | }; 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /v99/rtc_cntl.h: -------------------------------------------------------------------------------- 1 | // ... pending inclusion in the new esp32 distribution - jz 2 | 3 | // You may have to edit rtc_cntl.h ... according to this link -- doesn't seem to be included in esp32 libraries as of Jun 2020 ... or I'll just put it here 4 | // https://github.com/espressif/esp-idf/commit/17bd6e8faba15812780d21e6e3db08fb26dd7033#diff-5e22dcf9fc6087d1585c7b2e434c0932 5 | // https://github.com/espressif/esp-idf/pull/4532 6 | // C:\Users\James\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\driver\driver -- approximate path 7 | 8 | 9 | // Copyright 2016-2017 Espressif Systems (Shanghai) PTE LTD 10 | // 11 | // Licensed under the Apache License, Version 2.0 (the "License"); 12 | // you may not use this file except in compliance with the License. 13 | // You may obtain a copy of the License at 14 | // 15 | // http://www.apache.org/licenses/LICENSE-2.0 16 | // 17 | // Unless required by applicable law or agreed to in writing, software 18 | // distributed under the License is distributed on an "AS IS" BASIS, 19 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 | // See the License for the specific language governing permissions and 21 | // limitations under the License. 22 | 23 | #pragma once 24 | 25 | #include 26 | #include "esp_err.h" 27 | #include "esp_intr_alloc.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | /** 34 | * @brief Register a handler for specific RTC_CNTL interrupts 35 | * 36 | * Multiple handlers can be registered using this function. Whenever an 37 | * RTC interrupt happens, all handlers with matching rtc_intr_mask values 38 | * will be called. 39 | * 40 | * @param handler handler function to call 41 | * @param handler_arg argument to be passed to the handler 42 | * @param rtc_intr_mask combination of RTC_CNTL_*_INT_ENA bits indicating the 43 | * sources to call the handler for 44 | * @return 45 | * - ESP_OK on success 46 | * - ESP_ERR_NO_MEM not enough memory to allocate handler structure 47 | * - other errors returned by esp_intr_alloc 48 | */ 49 | esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg, 50 | uint32_t rtc_intr_mask); 51 | /** 52 | * @brief Deregister the handler previously registered using rtc_isr_register 53 | * @param handler handler function to call (as passed to rtc_isr_register) 54 | * @param handler_arg argument of the handler (as passed to rtc_isr_register) 55 | * @return 56 | * - ESP_OK on success 57 | * - ESP_ERR_INVALID_STATE if a handler matching both handler and 58 | * handler_arg isn't registered 59 | */ 60 | esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | -------------------------------------------------------------------------------- /v99/settings.h: -------------------------------------------------------------------------------- 1 | static const char devname[] = "desklens"; // name of your camera for mDNS, Router, and filenames 2 | 3 | #define include_telegram 4 | //#define include_pir_and_touch 5 | #define include_ftp 6 | #define include_streaming 7 | #define get_rid_of_touch 8 | 9 | int delete_old_files = 1; // set to 1 and it will delete your oldest day of files so you SD is always 10% empty 10 | 11 | // https://sites.google.com/a/usapiens.com/opnode/time-zones -- find your timezone here 12 | #define TIMEZONE "GMT0BST,M3.5.0/01,M10.5.0/02" // your timezone - this is GMT 13 | //#define TIMEZONE "MST7MDT,M3.2.0/2:00:00,M11.1.0/2:00:00" // mountain time 14 | 15 | // 1 for blink red led with every sd card write, at your frame rate 16 | // 0 for blink only for skipping frames and SOS if camera or sd is broken 17 | #define BlinkWithWrite 1 18 | 19 | // EDIT ssid and password **** with Version 98x-WiFiMan, you are using WiFiManager to set ssid and password, so these are redundant 20 | const char* ssid = "jzjzjz"; 21 | const char* password = "jzjzjz"; 22 | 23 | // reboot startup parameters here 24 | 25 | int Internet_Enabled = 1; // set to 0 to shut off all internet activities - wifi, time, http, ftp, telegram 26 | int DeepSleepPir = 0; // set to 1 to deepsleep between pir videos 27 | int record_on_reboot = 1; // set to 1 to record, or 0 to NOT record on reboot 28 | int PIRpin = 13; // for active high pir or microwave etc 29 | int PIRenabled = 0; // 1 is PIR is enable on reboot, will only work if you are not recording 30 | 31 | int MagicNumber = 011; // change this if you are re-compiling and you dont want to use the ESPROM settings 32 | int stream_interval = 333; // milliseconds between frames delivered during the live stream - 333 is 3 fps 33 | 34 | // here are 2 sets of startup parameters -- more down in the stop and restart webpage 35 | 36 | // VGA 10 fps for 30 minutes, and repeat, play at real time 37 | 38 | int framesize = 8; // 13 UXGA, 11 HD, 9 SVGA, 8 VGA, 6 CIF 39 | int repeat_config = 100; // repaeat same movie this many times 40 | int xspeed = 1; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frame ( 30 fps / 0.1 fps ) 41 | int gray = 0; // not gray 42 | int quality = 12; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 43 | int capture_interval = 100; // milli-seconds between frames 44 | volatile int total_frames_config = 18000; // how many frames - length of movie in ms is total_frames x capture_interval 45 | 46 | 47 | // UXGA 1 frame every 10 seconds for 60 minutes, and repeat, play at 30 fps or 300 times speed 48 | /* 49 | int framesize = 13; // 13 UXGA, 11 HD, 9 SVGA, 8 VGA, 6 CIF 50 | int repeat_config = 300; // repaeat same movie this many times 51 | int xspeed = 300; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frames ( 30 fps / 0.1 fps ) 52 | int gray = 0; // not gray 53 | int quality = 6; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 54 | int capture_interval = 10000; // milli-seconds between frames 55 | volatile int total_frames_config = 360; // how many frames - length of movie is total_frames x capture_interval 56 | */ 57 | 58 | // enable the www.telegram.org BOT - it sends a text and and snapshot to you every time it starts a video 59 | // https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot 60 | // I'm using the branch v1.2 from June 2020 - new master introduced late june, but not working for picture and captions, so my v1.2 mods included here 61 | // You need to create a bot, and get its number BOTtoken, and then get your telegram number -- all free at telegram.org 62 | // detailed instructions here https://randomnerdtutorials.com/telegram-control-esp32-esp8266-nodemcu-outputs/ 63 | 64 | RTC_DATA_ATTR int EnableBOT = 0; 65 | #define BOTtoken "9876543210:qwertyuiopasdfghjklzxcvbnmqwertyuio" // get your own bot and id at telegram.org 66 | #define BOTme "1234567890" 67 | -------------------------------------------------------------------------------- /v99/v99.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jameszah/ESP32-CAM-Video-Recorder/b6c9af8970bc2321935662286603da7ce6484271/v99/v99.jpg -------------------------------------------------------------------------------- /vA1/CRC32.cpp: -------------------------------------------------------------------------------- 1 | // mods by James Zahary Dec 28, 2021 https://github.com/jameszah/ESPxWebFlMgr 2 | // based on https://github.com/holgerlembke/ESPxWebFlMgr 3 | 4 | // 5 | // Copyright (c) 2013 Christopher Baker 6 | // 7 | // SPDX-License-Identifier: MIT 8 | // 9 | 10 | 11 | #include "CRC32.h" 12 | 13 | // Conditionally use pgm memory if it is available. 14 | 15 | #if defined(PROGMEM) 16 | #define FLASH_PROGMEM PROGMEM 17 | #define FLASH_READ_DWORD(x) (pgm_read_dword_near(x)) 18 | #else 19 | #define FLASH_PROGMEM 20 | #define FLASH_READ_DWORD(x) (*(uint32_t*)(x)) 21 | #endif 22 | 23 | 24 | static const uint32_t crc32_table[] FLASH_PROGMEM = { 25 | 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 26 | 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 27 | 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 28 | 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c 29 | }; 30 | 31 | 32 | CRC32::CRC32() 33 | { 34 | reset(); 35 | } 36 | 37 | 38 | void CRC32::reset() 39 | { 40 | _state = ~0L; 41 | } 42 | 43 | 44 | void CRC32::update(const uint8_t& data) 45 | { 46 | // via http://forum.arduino.cc/index.php?topic=91179.0 47 | uint8_t tbl_idx = 0; 48 | 49 | tbl_idx = _state ^ (data >> (0 * 4)); 50 | _state = FLASH_READ_DWORD(crc32_table + (tbl_idx & 0x0f)) ^ (_state >> 4); 51 | tbl_idx = _state ^ (data >> (1 * 4)); 52 | _state = FLASH_READ_DWORD(crc32_table + (tbl_idx & 0x0f)) ^ (_state >> 4); 53 | } 54 | 55 | 56 | uint32_t CRC32::finalize() const 57 | { 58 | return ~_state; 59 | } 60 | -------------------------------------------------------------------------------- /vA1/CRC32.h: -------------------------------------------------------------------------------- 1 | // mods by James Zahary Dec 28, 2021 https://github.com/jameszah/ESPxWebFlMgr 2 | // based on https://github.com/holgerlembke/ESPxWebFlMgr 3 | 4 | // 5 | // Copyright (c) 2013 Christopher Baker 6 | // 7 | // SPDX-License-Identifier: MIT 8 | // 9 | 10 | 11 | #pragma once 12 | 13 | 14 | #include "Arduino.h" 15 | 16 | 17 | /// \brief A class for calculating the CRC32 checksum from arbitrary data. 18 | /// \sa http://forum.arduino.cc/index.php?topic=91179.0 19 | class CRC32 20 | { 21 | public: 22 | /// \brief Initialize an empty CRC32 checksum. 23 | CRC32(); 24 | 25 | /// \brief Reset the checksum claculation. 26 | void reset(); 27 | 28 | /// \brief Update the current checksum caclulation with the given data. 29 | /// \param data The data to add to the checksum. 30 | void update(const uint8_t& data); 31 | 32 | /// \brief Update the current checksum caclulation with the given data. 33 | /// \tparam Type The data type to read. 34 | /// \param data The data to add to the checksum. 35 | template 36 | void update(const Type& data) 37 | { 38 | update(&data, 1); 39 | } 40 | 41 | /// \brief Update the current checksum caclulation with the given data. 42 | /// \tparam Type The data type to read. 43 | /// \param data The array to add to the checksum. 44 | /// \param size Size of the array to add. 45 | template 46 | void update(const Type* data, size_t size) 47 | { 48 | size_t nBytes = size * sizeof(Type); 49 | const uint8_t* pData = (const uint8_t*)data; 50 | 51 | for (size_t i = 0; i < nBytes; i++) 52 | { 53 | update(pData[i]); 54 | } 55 | } 56 | 57 | /// \returns the caclulated checksum. 58 | uint32_t finalize() const; 59 | 60 | /// \brief Calculate the checksum of an arbitrary data array. 61 | /// \tparam Type The data type to read. 62 | /// \param data A pointer to the data to add to the checksum. 63 | /// \param size The size of the data to add to the checksum. 64 | /// \returns the calculated checksum. 65 | template 66 | static uint32_t calculate(const Type* data, size_t size) 67 | { 68 | CRC32 crc; 69 | crc.update(data, size); 70 | return crc.finalize(); 71 | } 72 | 73 | private: 74 | /// \brief The internal checksum state. 75 | uint32_t _state = ~0L; 76 | 77 | }; 78 | -------------------------------------------------------------------------------- /vA1/ESPxWebFlMgr.h: -------------------------------------------------------------------------------- 1 | // mods by James Zahary Dec 28, 2021 https://github.com/jameszah/ESPxWebFlMgr 2 | // Jan 12, 2022 - adds dates/times to display 3 | // based on https://github.com/holgerlembke/ESPxWebFlMgr 4 | 5 | // inline guard. Did I mention that c/c++ is broken by design? 6 | #ifndef ESPxWebFlMgr_h 7 | #define ESPxWebFlMgr_h 8 | 9 | /* 10 | Changes 11 | V1.03 12 | x removed all SPIFFS from ESP32 version, switched fully to LittleFS 13 | x fixed rename+delete for ESP32+LittleFS (added "/") 14 | 15 | V1.02 16 | x fixed the way to select the file system by conditional defines 17 | 18 | V1.01 19 | + added file name progress while uploading 20 | x fixed error in ZIP file structure (zip.bitflags needs a flag) 21 | 22 | V1.00 23 | + out of V0.9998... 24 | + ESP8266: LittleFS is default 25 | + javascript: added "msgline();" 26 | + javascript: added "Loading..." as a not-working-hint to show that Javascript is disabled 27 | + cleaning up the "/"-stuff (from SPIFF with leading "/" to LittleFS without...) 28 | + Warning: esp8266 2.7.4 has an error in mime::getContentType(path) for .TXT. Fix line 65 is { kTxtSuffix, kTxt }, 29 | + review of "edit file", moved some stuff to ESPxWebFlMgrWpF.h 30 | */ 31 | 32 | #include 33 | #include 34 | 35 | // file system default for esp8266 is LittleFS, for ESP32 it is SPIFFS (no time to check...) 36 | 37 | #ifdef ESP8266 38 | #include 39 | #include 40 | #include 41 | // 42 | #include 43 | #define ESPxWebFlMgr_FileSystem LittleFS 44 | /* 45 | #include 46 | #define ESPxWebFlMgr_FileSystem SPIFFS 47 | */ 48 | #endif 49 | 50 | #ifdef ESP32 51 | #include 52 | #include 53 | #include 54 | #include //jz #include 55 | #define ESPxWebFlMgr_FileSystem SD_MMC //jz #define ESPxWebFlMgr_FileSystem LittleFS 56 | #endif 57 | 58 | 59 | #ifndef ESPxWebFlMgr_FileSystem 60 | #pragma message ("ESPxWebFlMgr_FileSystem not defined.") 61 | #endif 62 | 63 | /* undefine this to save about 10k code space. 64 | it requires to put the files from "/filemanager" into the FS. No free lunch. 65 | */ 66 | #define fileManagerServerStaticsInternally 67 | 68 | // will show the Edit-Button for every file type, even binary and such. 69 | //#define fileManagerEditEverything 70 | 71 | class ESPxWebFlMgr { 72 | private: 73 | word _Port ; 74 | #ifdef ESP8266 75 | ESP8266WebServer * fileManager = NULL; 76 | #endif 77 | #ifdef ESP32 78 | WebServer * fileManager = NULL; 79 | #endif 80 | bool _ViewSysFiles = false; 81 | String _SysFileStartPattern = "/."; 82 | File fsUploadFile; 83 | String _backgroundColor = "black"; 84 | 85 | void fileManagerNotFound(void); 86 | String dispIntDotted(size_t i); 87 | String dispFileString(size_t fs); 88 | String CheckFileNameLengthLimit(String fn); 89 | 90 | // the webpage 91 | void fileManagerIndexpage(void); 92 | void fileManagerJS(void); 93 | void fileManagerCSS(void); 94 | void fileManagerGetBackGround(void); 95 | 96 | // javascript xmlhttp includes 97 | String colorline(int i); 98 | String escapeHTMLcontent(String html); 99 | void fileManagerFileListInsert(void); 100 | void fileManagerFileEditorInsert(void); 101 | boolean allowAccessToThisFile(const String filename); 102 | void fileManagerCommandExecutor(void); 103 | void fileManagerReceiverOK(void); 104 | void fileManagerReceiver(void); 105 | 106 | // Zip-File uncompressed/stored 107 | void getAllFilesInOneZIP(void); 108 | int WriteChunk(const char* b, size_t l); 109 | 110 | // helper: fs.h from esp32 and esp8266 don't have a compatible solution 111 | // for getting a file list from a directory 112 | #ifdef ESP32 113 | #define Dir File 114 | #endif 115 | File nextFile(Dir &dir); 116 | File firstFile(Dir &dir); 117 | // and not to get this data about usage... 118 | size_t totalBytes(void); 119 | size_t usedBytes(void); 120 | 121 | public: 122 | ESPxWebFlMgr(word port); 123 | virtual ~ESPxWebFlMgr(); 124 | 125 | void begin(); 126 | void end(); 127 | virtual void handleClient(); 128 | 129 | // This must be called before the webpage is loaded in the browser... 130 | // must be a valid css color name, see https://en.wikipedia.org/wiki/Web_colors 131 | void setBackGroundColor(const String backgroundColor); 132 | 133 | void setViewSysFiles(bool vsf); 134 | bool getViewSysFiles(void); 135 | 136 | void setSysFileStartPattern(String sfsp); 137 | String getSysFileStartPattern(void); 138 | }; 139 | 140 | #endif 141 | 142 | /* 143 | History 144 | 145 | -- 2019-07-07 146 | + Renamed to ESPxWebFlMgr and made it work with esp32 and esp8266 147 | + separated file manager web page, "build script" to generate it 148 | 149 | -- 2019-07-06 150 | + "Download all files" creates a zip file from all files and downloads it 151 | + option to set background color 152 | - html5 fixes 153 | 154 | -- 2019-07-03 155 | + Public Release on https://github.com/holgerlembke/ESP8266WebFlMgr 156 | 157 | 158 | Things to do 159 | 160 | ?? unify file system access for SPIFFS, LittleFS and SDFS 161 | 162 | */ 163 | -------------------------------------------------------------------------------- /vA1/ESPxWebFlMgrWp.h: -------------------------------------------------------------------------------- 1 | // mods by James Zahary Dec 28, 2021 https://github.com/jameszah/ESPxWebFlMgr 2 | // Jan 12, 2022 - adds dates/times to display 3 | // based on https://github.com/holgerlembke/ESPxWebFlMgr 4 | 5 | // inline guard. Did I mention that c/c++ is broken by design? 6 | #ifndef ESPxWebFlMgrWp_h 7 | #define ESPxWebFlMgrWp_h 8 | 9 | // this file has been created by makeESPxWebFlMgrWp\do.cmd 10 | 11 | //***************************************************************************************************** 12 | static const char ESPxWebFlMgrWpindexpage[] PROGMEM = R"==x==( 13 | 14 | 15 | 16 | FileManager 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 |
 
26 |
 
27 |
 
28 |
 
29 | 30 |
31 |
 
32 |
33 |
 
34 |
35 |
36 |
37 | File
38 | Drop
39 | Zone
40 |
41 |
42 |
 
43 |
44 |
 
45 |
46 |
47 | 48 |
 
49 |
Download all files
50 |
Loading...
51 |
 
52 |
53 | File list should appear here. 54 |
55 |
56 | 57 | 58 | 59 | )==x=="; 60 | 61 | static const char ESPxWebFlMgrWpjavascript[] PROGMEM = R"==x==( 62 | 63 | function compressurlfile(source) { 64 | msgline("Fetching file..."); 65 | var request = new XMLHttpRequest(); 66 | request.onreadystatechange = function () { 67 | var DONE = this.DONE || 4; 68 | if (this.readyState === DONE) { 69 | var data = this.responseText; 70 | var gzip = require('gzip-js'), options = { level: 9, name: source, timestamp: parseInt(Date.now() / 1000, 10) }; 71 | var out = gzip.zip(data, options); 72 | var bout = new Uint8Array(out); // out is 16 bits... 73 | 74 | msgline("Sending compressed file..."); 75 | var sendback = new XMLHttpRequest(); 76 | sendback.onreadystatechange = function () { 77 | var DONE = this.DONE || 4; 78 | if (this.readyState === DONE) { 79 | getfileinsert(); 80 | } 81 | }; 82 | sendback.open('POST', '/r'); 83 | var formdata = new FormData(); 84 | var blob = new Blob([bout], { type: "application/octet-binary" }); 85 | formdata.append(source + '.gz', blob, source + '.gz'); 86 | sendback.send(formdata); 87 | } 88 | }; 89 | request.open('GET', source, true); 90 | request.send(null); 91 | } 92 | 93 | var subdir; 94 | 95 | function getfileinsert() { 96 | msgline("Fetching files infos..."); 97 | subdir = '/'; 98 | var request = new XMLHttpRequest(); 99 | request.onreadystatechange = function () { 100 | var DONE = this.DONE || 4; 101 | if (this.readyState === DONE) { 102 | var res = this.responseText.split("##"); 103 | document.getElementById('fi').innerHTML = res[0]; 104 | document.getElementById("o3").innerHTML = res[1]; 105 | msgline(""); 106 | } 107 | }; 108 | request.open('GET', '/i', true); 109 | request.send(null); 110 | } 111 | 112 | function getfileinsert2(strddd) { 113 | msgline("Fetching files infos..."); 114 | subdir = strddd; 115 | var request = new XMLHttpRequest(); 116 | request.onreadystatechange = function () { 117 | var DONE = this.DONE || 4; 118 | if (this.readyState === DONE) { 119 | var res = this.responseText.split("##"); 120 | document.getElementById('fi').innerHTML = res[0]; 121 | document.getElementById("o3").innerHTML = res[1]; 122 | msgline(""); 123 | } 124 | }; 125 | request.open('GET', '/i?subdir=' + strddd, true); // must send the subdir variable to get that folder //jz 126 | request.send(null); 127 | } 128 | function executecommand(command) { 129 | var xhr = new XMLHttpRequest(); 130 | xhr.onreadystatechange = function () { 131 | var DONE = this.DONE || 4; 132 | if (this.readyState === DONE) { 133 | getfileinsert2(subdir); 134 | } 135 | }; 136 | xhr.open('GET', '/c?' + command, true); 137 | xhr.send(null); 138 | } 139 | 140 | function downloadfile(filename) { 141 | window.location.href = "/c?dwn=" + filename; 142 | } 143 | 144 | function opendirectory(filename) { 145 | 146 | getfileinsert2(filename); 147 | } 148 | 149 | function deletefile(filename) { 150 | if (confirm("Really delete " + filename)) { 151 | msgline("Refresh when done deleting..."); //jz msgline("Please wait. Delete in progress..."); 152 | executecommand("del=" + filename); 153 | } 154 | } 155 | 156 | function renamefile(filename) { 157 | var newname = prompt("new name for " + filename, filename); 158 | if (newname != null) { 159 | msgline("Refresh when done renaming ..."); //jz msgline("Please wait. Rename in progress..."); 160 | executecommand("ren=" + filename + "&new=" + newname); 161 | } 162 | } 163 | 164 | var editxhr; 165 | 166 | function editfile(filename) { 167 | msgline("Please wait. Creating editor..."); 168 | 169 | editxhr = new XMLHttpRequest(); 170 | editxhr.onreadystatechange = function () { 171 | var DONE = this.DONE || 4; 172 | if (this.readyState === DONE) { 173 | document.getElementById('fi').innerHTML = editxhr.responseText; 174 | document.getElementById("o3").innerHTML = "Edit " + filename; 175 | msgline(""); 176 | } 177 | }; 178 | editxhr.open('GET', '/e?edit=' + filename, true); 179 | editxhr.send(null); 180 | } 181 | 182 | function sved(filename) { 183 | var content = document.getElementById('tect').value; 184 | // utf-8 185 | content = unescape(encodeURIComponent(content)); 186 | 187 | var xhr = new XMLHttpRequest(); 188 | 189 | xhr.open("POST", "/r", true); 190 | 191 | var boundary = '-----whatever'; 192 | xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary); 193 | 194 | var body = "" + 195 | '--' + boundary + '\r\n' + 196 | 'Content-Disposition: form-data; name="uploadfile"; filename="' + filename + '"' + '\r\n' + 197 | 'Content-Type: text/plain' + '\r\n' + 198 | '' + '\r\n' + 199 | content + '\r\n' + 200 | '--' + boundary + '--\r\n' + // \r\n fixes upload delay in ESP8266WebServer 201 | ''; 202 | 203 | // ajax does not do xhr.setRequestHeader("Content-length", body.length); 204 | 205 | xhr.onreadystatechange = function () { 206 | var DONE = this.DONE || 4; 207 | if (this.readyState === DONE) { 208 | getfileinsert(); 209 | } 210 | } 211 | 212 | xhr.send(body); 213 | } 214 | 215 | function abed() { 216 | getfileinsert(); 217 | } 218 | 219 | var uploaddone = true; // hlpr for multiple file uploads 220 | 221 | function uploadFile(file, islast) { 222 | uploaddone = false; 223 | var xhr = new XMLHttpRequest(); 224 | xhr.onreadystatechange = function () { 225 | // console.log(xhr.status); 226 | var DONE = this.DONE || 4; 227 | if (this.readyState === DONE) { 228 | if (islast) { 229 | getfileinsert2(subdir); 230 | console.log('last file'); 231 | } 232 | uploaddone = true; 233 | } 234 | }; 235 | xhr.open('POST', '/r'); 236 | var formdata = new FormData(); 237 | //var newname = subdir + '/' + file.name; //jz didnt work, so do it in c++ 238 | //file.name = newname; 239 | formdata.append('uploadfile', file); 240 | // not sure why, but with that the upload to esp32 is stable. 241 | formdata.append('dummy', 'dummy'); 242 | xhr.send(formdata); 243 | } 244 | 245 | var globaldropfilelisthlpr = null; // read-only-list, no shift() 246 | var transferitem = 0; 247 | var uploadFileProzessorhndlr = null; 248 | 249 | function uploadFileProzessor() { 250 | if (uploaddone) { 251 | if (transferitem==globaldropfilelisthlpr.length) { 252 | clearInterval(uploadFileProzessorhndlr); 253 | } else { 254 | var file = globaldropfilelisthlpr[transferitem]; 255 | msgline("Please wait. Transferring file "+file.name+"..."); 256 | console.log('process file ' + file.name); 257 | transferitem++; 258 | uploadFile(file,transferitem==globaldropfilelisthlpr.length); 259 | } 260 | } 261 | } 262 | 263 | /* 264 | function dropHandlerALT(ev) { 265 | console.log('File(s) dropped'); 266 | 267 | document.getElementById('msg').innerHTML = "Please wait. Transferring file..."; 268 | 269 | // Prevent default behavior (Prevent file from being opened) 270 | ev.preventDefault(); 271 | 272 | if (ev.dataTransfer.items) { 273 | // Use DataTransferItemList interface to access the file(s) 274 | for (var i = 0; i < ev.dataTransfer.items.length; i++) { 275 | // If dropped items aren't files, reject them 276 | if (ev.dataTransfer.items[i].kind === 'file') { 277 | var file = ev.dataTransfer.items[i].getAsFile(); 278 | uploadFile(file); 279 | console.log('.1. file[' + i + '].name = ' + file.name); 280 | } 281 | } 282 | } else { 283 | // Use DataTransfer interface to access the file(s) 284 | for (var i = 0; i < ev.dataTransfer.files.length; i++) { 285 | console.log('.2. file[' + i + '].name = ' + ev.dataTransfer.files[i].name); 286 | } 287 | } 288 | } 289 | */ 290 | 291 | function dropHandler(ev) { 292 | console.log('File(s) dropped'); 293 | 294 | globaldropfilelisthlpr = ev.dataTransfer; 295 | transferitem = 0; 296 | 297 | msgline("Please wait. Transferring file..."); 298 | 299 | // Prevent default behavior (Prevent file from being opened) 300 | ev.preventDefault(); 301 | 302 | if (ev.dataTransfer.items) { 303 | var data = ev.dataTransfer; 304 | globaldropfilelisthlpr = data.files; 305 | uploadFileProzessorhndlr = setInterval(uploadFileProzessor,1000); 306 | console.log('Init upload list.'); 307 | } else { 308 | // Use DataTransfer interface to access the file(s) 309 | for (var i = 0; i < ev.dataTransfer.files.length; i++) { 310 | console.log('.2. file[' + i + '].name = ' + ev.dataTransfer.files[i].name); 311 | } 312 | } 313 | } 314 | 315 | function dragOverHandler(ev) { 316 | console.log('File(s) in drop zone'); 317 | 318 | // Prevent default behavior (Prevent file from being opened) 319 | ev.preventDefault(); 320 | } 321 | 322 | function msgline(msg) { 323 | document.getElementById('msg').innerHTML = msg; 324 | } 325 | 326 | function downloadall() { 327 | msgline("Sending all files in one zip."); 328 | window.location.href = "/c?za=all"; 329 | msgline(""); 330 | } 331 | 332 | //-> 333 | window.onload = getfileinsert; 334 | 335 | )==x=="; 336 | 337 | 338 | //***************************************************************************************************** 339 | static const char ESPxWebFlMgrWpcss[] PROGMEM = R"==g==( 340 | 341 | div { 342 | margin: 1px; 343 | padding: 0px; 344 | font-family: 'Segoe UI', Verdana, sans-serif; 345 | } 346 | 347 | #gc { 348 | display: grid; 349 | grid-template-columns: 80px 25% auto 30px; 350 | grid-template-rows: 20px 30px auto 30px 20px; 351 | grid-template-areas: "o1 o2 o3 o4" "m1 c c c" "m2 c c c" "m3 c c c" "u1 u2 u3 u4"; 352 | } 353 | 354 | .o1 { 355 | grid-area: o1; 356 | background-color: #9999CC; 357 | border-top-left-radius: 20px; 358 | margin-bottom: 0px; 359 | } 360 | 361 | .o2 { 362 | grid-area: o2; 363 | background-color: #9999FF; 364 | margin-bottom: 0px; 365 | } 366 | 367 | .o3 { 368 | grid-area: o3; 369 | background-color: #CC99CC; 370 | margin-bottom: 0px; 371 | white-space: nowrap; 372 | } 373 | 374 | .o4 { 375 | grid-area: o4; 376 | background-color: #CC6699; 377 | border-radius: 0 10px 10px 0; 378 | margin-bottom: 0px; 379 | } 380 | 381 | .m1 { 382 | grid-area: m1; 383 | margin-top: 0px; 384 | background-color: #9999CC; 385 | display: grid; 386 | grid-template-columns: 60px 20px; 387 | grid-template-rows: 20px; 388 | grid-template-areas: "s11 s12"; 389 | } 390 | 391 | .s12 { 392 | margin: 0px; 393 | background-color: #9999CC; 394 | } 395 | 396 | .s13 { 397 | margin: 0px; 398 | border-top-left-radius: 20px; 399 | height: 30px; 400 | } 401 | 402 | .m2 { 403 | display: flex; 404 | justify-content: center; 405 | align-items: center; 406 | grid-area: m2; 407 | background-color: #CC6699; 408 | width: 60px; 409 | } 410 | 411 | .m3 { 412 | grid-area: m3; 413 | margin-bottom: 0px; 414 | background-color: #9999CC; 415 | display: grid; 416 | grid-template-columns: 60px 20px; 417 | grid-template-rows: 20px; 418 | grid-template-areas: "s31 s32"; 419 | } 420 | 421 | .s32 { 422 | margin: 0px; 423 | background-color: #9999CC; 424 | } 425 | 426 | .s33 { 427 | margin: 0px; 428 | border-bottom-left-radius: 20px; 429 | height: 30px; 430 | } 431 | 432 | .u1 { 433 | grid-area: u1; 434 | background-color: #9999CC; 435 | border-bottom-left-radius: 20px; 436 | margin-top: 0px; 437 | } 438 | 439 | .u2 { 440 | grid-area: u2; 441 | cursor: pointer; 442 | background-color: #CC6666; 443 | margin-top: 0px; 444 | padding-left: 10px; 445 | vertical-align: middle; 446 | font-size: 80%; 447 | } 448 | 449 | .u2:hover { 450 | background-color: #9999FF; 451 | color: white; 452 | } 453 | 454 | .u3 { 455 | grid-area: u3; 456 | padding-left: 10px; 457 | background-color: #FF9966; 458 | font-size: 80%; 459 | margin-top: 0px; 460 | } 461 | 462 | .u4 { 463 | grid-area: u4; 464 | background-color: #FF9900; 465 | border-radius: 0 10px 10px 0; 466 | margin-top: 0px; 467 | } 468 | 469 | .c { 470 | grid-area: c; 471 | } 472 | 473 | #fi .b { 474 | background-color: Transparent; 475 | border: 1px solid #9999FF; 476 | border-radius: 1px; 477 | padding: 0px; 478 | width: 30px; 479 | cursor: pointer; 480 | } 481 | 482 | #fi .b:hover { 483 | background-color: #9999FF; 484 | color: white; 485 | } 486 | 487 | .cc { 488 | width: min-content; 489 | margin: 10px 0px; 490 | } 491 | 492 | .gc div { 493 | padding: 1px; 494 | } 495 | 496 | .ccg { 497 | height: 1.5em; 498 | background-color: #A5A5FF; 499 | } 500 | 501 | .ccu { 502 | height: 1.5em; 503 | background-color: #FE9A00; 504 | } 505 | 506 | .ccd { 507 | height: 1.5em; 508 | background-color: #e8e2d8; 509 | } 510 | 511 | .ccl { 512 | border-radius: 5px 0 0 5px; 513 | cursor: pointer; 514 | } 515 | 516 | .ccl:hover { 517 | border-radius: 5px 0 0 5px; 518 | color: white; 519 | cursor: pointer; 520 | } 521 | 522 | .ccr { 523 | border-radius: 0 5px 5px 0; 524 | } 525 | 526 | .cct { 527 | text-align: right; 528 | } 529 | 530 | .ccz { 531 | text-align: right; 532 | } 533 | 534 | .gc { 535 | display: grid; 536 | grid-template-columns: repeat(4, max-content); 537 | } 538 | )==g=="; 539 | 540 | 541 | #endif 542 | -------------------------------------------------------------------------------- /vA1/ESPxWebFlMgrWpF.h: -------------------------------------------------------------------------------- 1 | // mods by James Zahary Dec 28, 2021 https://github.com/jameszah/ESPxWebFlMgr 2 | // based on https://github.com/holgerlembke/ESPxWebFlMgr 3 | 4 | // inline guard. Still broken by design? 5 | #ifndef ESPxWebFlMgrWpF_h 6 | #define ESPxWebFlMgrWpF_h 7 | 8 | static const char ESPxWebFlMgrWpFormIntro[] PROGMEM = 9 | R"==x==(
  18 | 19 | )==x=="; 20 | 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /vA1/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /vA1/UniversalTelegramBot.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2018 Brian Lough. All right reserved. 3 | 4 | UniversalTelegramBot - Library to create your own Telegram Bot using 5 | ESP8266 or ESP32 on Arduino IDE. 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef UniversalTelegramBot_h 23 | #define UniversalTelegramBot_h 24 | 25 | #define ARDUINOJSON_DECODE_UNICODE 1 26 | #define ARDUINOJSON_USE_LONG_LONG 1 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | // a1 33 | #include 34 | 35 | #define HOST "api.telegram.org" 36 | #define SSL_PORT 443 37 | #define HANDLE_MESSAGES 1 38 | 39 | //unmark following line to enable debug mode 40 | //#define _debug 41 | 42 | typedef bool (*MoreDataAvailable)(); 43 | typedef byte (*GetNextByte)(); 44 | typedef byte* (*GetNextBuffer)(); 45 | typedef int (GetNextBufferLen)(); 46 | 47 | struct telegramMessage { 48 | String text; 49 | String chat_id; 50 | String chat_title; 51 | String from_id; 52 | String from_name; 53 | String date; 54 | String type; 55 | float longitude; 56 | float latitude; 57 | int update_id; 58 | }; 59 | 60 | class UniversalTelegramBot { 61 | public: 62 | UniversalTelegramBot(String token, WiFiClientSecure &client); //UniversalTelegramBot(String token, Client &client); 63 | 64 | String sendGetToTelegram(String command); 65 | String sendPostToTelegram(String command, JsonObject payload); 66 | String 67 | sendMultipartFormDataToTelegram(String command, String binaryProperyName, 68 | String fileName, String contentType, 69 | String chat_id, int fileSize, 70 | MoreDataAvailable moreDataAvailableCallback, 71 | GetNextByte getNextByteCallback, 72 | GetNextBuffer getNextBufferCallback, 73 | GetNextBufferLen getNextBufferLenCallback); 74 | 75 | String 76 | sendMultipartFormDataToTelegramWithCaption(String command, String binaryProperyName, 77 | String fileName, String contentType, 78 | String caption, String chat_id, int fileSize, 79 | MoreDataAvailable moreDataAvailableCallback, 80 | GetNextByte getNextByteCallback, 81 | GetNextBuffer getNextBufferCallback, 82 | GetNextBufferLen getNextBufferLenCallback); 83 | 84 | 85 | bool getMe(); 86 | 87 | bool sendSimpleMessage(String chat_id, String text, String parse_mode); 88 | bool sendMessage(String chat_id, String text, String parse_mode = ""); 89 | bool sendMessageWithReplyKeyboard(String chat_id, String text, 90 | String parse_mode, String keyboard, 91 | bool resize = false, bool oneTime = false, 92 | bool selective = false); 93 | bool sendMessageWithInlineKeyboard(String chat_id, String text, 94 | String parse_mode, String keyboard); 95 | 96 | bool sendChatAction(String chat_id, String text); 97 | 98 | bool sendPostMessage(JsonObject payload); 99 | String sendPostPhoto(JsonObject payload); 100 | String sendPhotoByBinary(String chat_id, String contentType, int fileSize, 101 | MoreDataAvailable moreDataAvailableCallback, 102 | GetNextByte getNextByteCallback, 103 | GetNextBuffer getNextBufferCallback, 104 | GetNextBufferLen getNextBufferLenCallback); 105 | String sendPhoto(String chat_id, String photo, String caption = "", 106 | bool disable_notification = false, 107 | int reply_to_message_id = 0, String keyboard = ""); 108 | 109 | int getUpdates(long offset); 110 | bool checkForOkResponse(String response); 111 | telegramMessage messages[HANDLE_MESSAGES]; 112 | long last_message_received; 113 | String name; 114 | String userName; 115 | int longPoll = 0; 116 | int waitForResponse = 5000; //jz = 1500; 117 | int jzdelay = 10; //60; // delay between multipart blocks 118 | int jzblocksize = 2 * 1024; // multipart block size 119 | 120 | private: 121 | // JsonObject * parseUpdates(String response); 122 | String _token; 123 | WiFiClientSecure *client; //Client *client; //a1 2.02 esp32-arduino 124 | void closeClient(); 125 | const int maxMessageLength = 1500; //was 1500 126 | bool processResult(JsonObject result, int messageIndex); 127 | }; 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /vA1/settings.h: -------------------------------------------------------------------------------- 1 | static const char devname[] = "desklens"; // name of your camera for mDNS, Router, and filenames 2 | 3 | #define include_telegram 4 | //#define include_pir_and_touch 5 | #define include_ftp 6 | #define include_streaming 7 | #define get_rid_of_touch 8 | 9 | int delete_old_files = 1; // set to 1 and it will delete your oldest day of files so you SD is always 10% empty 10 | 11 | // https://sites.google.com/a/usapiens.com/opnode/time-zones -- find your timezone here 12 | #define TIMEZONE "GMT0BST,M3.5.0/01,M10.5.0/02" // your timezone - this is GMT 13 | 14 | // 1 for blink red led with every sd card write, at your frame rate 15 | // 0 for blink only for skipping frames and SOS if camera or sd is broken 16 | #define BlinkWithWrite 1 17 | 18 | // EDIT ssid and password **** with Version 98x-WiFiMan, you are using WiFiManager to set ssid and password, so these are redundant 19 | const char* ssid = "jzjzjzjz"; 20 | const char* password = "mrpeanut"; 21 | 22 | // reboot startup parameters here 23 | 24 | int Internet_Enabled = 1; // set to 0 to shut off all internet activities - wifi, time, http, ftp, telegram 25 | int DeepSleepPir = 0; // set to 1 to deepsleep between pir videos 26 | int record_on_reboot = 1; // set to 1 to record, or 0 to NOT record on reboot 27 | int PIRpin = 13; // for active high pir or microwave etc 28 | int PIRenabled = 0; // 1 is PIR is enable on reboot, will only work if you are not recording 29 | 30 | int MagicNumber = 011; // change this if you are re-compiling and you dont want to use the ESPROM settings 31 | int stream_interval = 333; // milliseconds between frames delivered during the live stream - 333 is 3 fps 32 | 33 | // here are 2 sets of startup parameters -- more down in the stop and restart webpage 34 | 35 | // VGA 10 fps for 30 minutes, and repeat, play at real time 36 | 37 | int framesize = 8; // 13 UXGA, 11 HD, 9 SVGA, 8 VGA, 6 CIF 38 | int repeat_config = 100; // repaeat same movie this many times 39 | int xspeed = 1; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frame ( 30 fps / 0.1 fps ) 40 | int gray = 0; // not gray 41 | int quality = 12; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 42 | int capture_interval = 100; // milli-seconds between frames 43 | volatile int total_frames_config = 18000; // how many frames - length of movie in ms is total_frames x capture_interval 44 | 45 | 46 | // UXGA 1 frame every 10 seconds for 60 minutes, and repeat, play at 30 fps or 300 times speed 47 | /* 48 | int framesize = 13; // 13 UXGA, 11 HD, 9 SVGA, 8 VGA, 6 CIF 49 | int repeat_config = 300; // repaeat same movie this many times 50 | int xspeed = 300; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frames ( 30 fps / 0.1 fps ) 51 | int gray = 0; // not gray 52 | int quality = 6; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping 53 | int capture_interval = 10000; // milli-seconds between frames 54 | volatile int total_frames_config = 360; // how many frames - length of movie is total_frames x capture_interval 55 | */ 56 | 57 | // enable the www.telegram.org BOT - it sends a text and and snapshot to you every time it starts a video 58 | // https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot 59 | // I'm using the branch v1.2 from June 2020 - new master introduced late june, but not working for picture and captions, so my v1.2 mods included here 60 | // You need to create a bot, and get its number BOTtoken, and then get your telegram number -- all free at telegram.org 61 | // detailed instructions here https://randomnerdtutorials.com/telegram-control-esp32-esp8266-nodemcu-outputs/ 62 | 63 | RTC_DATA_ATTR int EnableBOT = 0; 64 | #define BOTtoken "9876543210:qwertyuiopasdfghjklzxcvbnmqwertyuio" // get your own bot and id at telegram.org 65 | #define BOTme "1234567890" 66 | --------------------------------------------------------------------------------