Το έπος της αναζητήσης τρόπου περιμετρικού οπτικού ελέγχου παραμένει - τα καθρεφτάκια δοκιμάστηκαν αλλά απορίφθηκαν μετ' επαίνων αφού είναι κουραστικά έως ακατάλληλα για εκτός δρόμου χρήση. Το είδωλο στα καθρεφτάκια μικρό και η θέση του κρανίου κρίσιμη για την ακριβή εκτίμηση της κατάστασης συνεπώς κουραστικό/ακατάλληλο για περιπτώσεις τραμπάλας του κεφαλιού στις κακοτοπιές - πέραν του ότι δεν καλύπτουν το θέμα της προγναθικής μουράκλας των NV. Οι λύσεις "βγάζω το κεφάλι έξω από το παράθυρο", "τα πατάω όλα", "κατεβάζω πεζή την/τον συνοδηγό να καθοδηγεί" δυστυχώς δεν παίζει πάντα για προφανείς λόγους (πχ οπισθοπορεία 300 μέτρων μεταξύ γκρεμού και χαντακιών λόγω κατολίσθησης στον παγωμένο αυχένα της Νιάλας, μόνος, σούρωπο με ημίφως και -2 βαθμούς κελσίου - τα ήθελε ο κώλος μου δεν λέω).
Σε mode παλιμπαιδισμού, πρόσφατα έκανα και κατά τις δύο φορές της την κοντινή, στους αθηναίους, διαδρομή
Άγιος Μερκούρης - Αυλώνα με το NV δοκιμάζοντας τις δυνατότητες του-και-μου με τα μαμά καλοκαιρινά λάστιχα πλήν όμως κατεβάζοντας καντήλια για τις φορές που αναγκάστηκα να ανεβοκατέβω από το αμάξι για να δω αν-περνάει-και-από-πού (ναι ΟΚ σκόπιμα περνούσα από τις κακοτοπιές για να καταλάβω που και πως πατάει όμως αυτό είναι απλά μια καλή εξομοίωση του τι μπορεί να συμβεί υπό πραγματικές συνθήκες).
Έτσι ξεκίνησα διερευνητικά να κάνω δοκιμές με μια WiFi κάμερα του φτωχού που μπορεί να προσαρμοστεί (προσωρινά με βεντούζα/μαγνητάκια ή μόνιμα) σε εκείνο/εκείνα τα σημεία του οχήματος που βολεύει και να καλύψει κάποιες από τις τυφλές γωνίες, προβάλλοντας ασύρματα το βίντεο στον web-browser ενός οποιουδήποτε tablet ή κινητού. Θεωρητικά περισσότερες από μια τέτοια κάμερες θα μπορούσαν να συνδεθούν στο ίδιο φορητό Wi-Fi Access Point του αυτοκινήτου και μέσω μιας multi cam εφαρμογής στο κινητό να εναλλάσει κανείς το τί βλέπει ή να βλέπει βίντεο από πολλές βιντεοκάμερες μαζί.
Πρόκειται για Καντο-Μόνος-Σου-Προτζεκτάκι με κόστος γύρω στα 20 ευρώ ανά κάμερα (συμπεριλαμβανομένης της μπαταρίας με αυτονομία συνεχούς λειτουργίας περίπου 10 ωρών σε φως ημέρας και περίπου 2 ωρών την νύχτα με μια φτηνιάρικη 18650) για του οποίου την χρησιμότητα δεν έχω καταλήξει ακόμα. Αρχικά βλέπω ικανοποιητική εμβέλεια με το ενσωματωμένο στην πλακέτα κεραιάκι, ένα σχετικά χαμηλό frame rate γύρω στα 12fps σε streaming με ένα lag/latency της τάξης των 200ms χωρίς όμως προβλήματα υπερθέρμανσης σε θερμοκρασίες 25 κελσίου περίπου - τιμές όχι απαγορευτικές - θα ενημερώσω εδώ εάν και εφόσον το προτζεκτάκι τελεσφορήσει.
Eνδεικτικά βασικά υλικά εδώ (κουτάκια, διακοπτάκια, φρού φρού και αρώματα εξαιρούνται) :
https://www.banggood.com/Geekcreit-FT23 ... rehouse=CNhttps://www.banggood.com/ESP32-CAM-WiFi ... rehouse=CNhttps://www.banggood.com/3pcs-ESP32S-ES ... rehouse=CNhttps://www.banggood.com/30cm-40pcs-Fem ... rehouse=CNhttps://www.skroutz.gr/c/1631/Epanafort ... ml?o=18650Τα προαιρετικά εδώ :
https://www.banggood.com/LILYGO-TTGO-Ca ... rehouse=CNhttps://www.banggood.com/3W-LED-Driver- ... rehouse=CNΒασικές οδηγίες εδώ :
https://randomnerdtutorials.com/esp32-c ... duino-ide/O κανιβαλισμένος από ετοιματζίδικα παραδείγματα .ino κώδικας εδώ :
- Κώδικας: Επιλογή όλων
//ESP32-CAM-softAP-Streamer-01
#include "esp_camera.h"
#include <WiFi.h>
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "fb_gfx.h"
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include "esp_http_server.h"
//Replace with Wi-Fi softAP Credentials
const char* ssid = "ESP32-CAM-AP";
const char* password = "12345678";
#define PART_BOUNDARY "123456789000000000000987654321"
#define CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22
static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY;
static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";
static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n";
httpd_handle_t stream_httpd = NULL;
static esp_err_t stream_handler(httpd_req_t *req){
camera_fb_t * fb = NULL;
esp_err_t res = ESP_OK;
size_t _jpg_buf_len = 0;
uint8_t * _jpg_buf = NULL;
char * part_buf[64];
res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);
if(res != ESP_OK){
return res;
}
while(true){
fb = esp_camera_fb_get();
if (!fb) {
Serial.println("Camera capture failed");
res = ESP_FAIL;
} else {
if(fb->width > 400){
if(fb->format != PIXFORMAT_JPEG){
bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);
esp_camera_fb_return(fb);
fb = NULL;
if(!jpeg_converted){
Serial.println("JPEG compression failed");
res = ESP_FAIL;
}
} else {
_jpg_buf_len = fb->len;
_jpg_buf = fb->buf;
}
}
}
if(res == ESP_OK){
size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);
res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);
}
if(res == ESP_OK){
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY));
}
if(fb){
esp_camera_fb_return(fb);
fb = NULL;
_jpg_buf = NULL;
} else if(_jpg_buf){
free(_jpg_buf);
_jpg_buf = NULL;
}
if(res != ESP_OK){
break;
}
//Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len));
}
return res;
}
void startCameraServer(){
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.server_port = 80;
httpd_uri_t index_uri = {
.uri = "/",
.method = HTTP_GET,
.handler = stream_handler,
.user_ctx = NULL
};
//Serial.printf("Starting web server on port: '%d'\n", config.server_port);
if (httpd_start(&stream_httpd, &config) == ESP_OK) {
httpd_register_uri_handler(stream_httpd, &index_uri);
}
}
void setup() {
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
Serial.begin(115200);
Serial.setDebugOutput(false);
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;
if(psramFound()){
config.frame_size = FRAMESIZE_UXGA;
config.jpeg_quality = 10;
config.fb_count = 2;
} else {
config.frame_size = FRAMESIZE_SVGA;
config.jpeg_quality = 12;
config.fb_count = 1;
}
// Camera init
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
Serial.printf("Camera init failed with error 0x%x", err);
return;
}
// Wi-Fi softAP Connection
WiFi.softAP(ssid, password);
Serial.println();
Serial.print("Camera ready to stream on http://");
Serial.println(WiFi.softAPIP());
// Start streaming web server
startCameraServer();
}
void loop() {
delay(1);
}
Άσχετο: Ένα βαθύ σκίσιμο στο μάγουλο του μπροστινού αριστερού μαμά Conti λάστιχου χωρίς απώλεια αέρα ευτυχώς, η ψυχανωμαλία μου με τα πειράγματα που υποτροπίασε και το επερχόμενο λοκντάουν με κάνει να σκέφτομαι σοβαρά - ενάντια σε κάθε ασφάλτινη λογική - τα Yoko G015 ή τα Cooper ATT σε 215/60-R17 σε συνδυασμό με τα
Gatoz® E30-80-013-01-22 (και ας πάει για βρούβες η εγγύηση - είπαμε πρώτα βγαίνει η ψυχή και μετά το χούι).