Main Content

Esta página se ha traducido mediante traducción automática. Haga clic aquí para ver la última versión en inglés.

Escribir imagen en ThingSpeak desde la placa de cámara ESP32

Este ejemplo muestra cómo capturar una imagen desde una placa de cámara ESP32 y escribirla en un canal de imágenes ThingsSpeak®.

Este ejemplo utiliza una placa de cámara ESP32 que es compatible con la placa A.I.Thinker. Se pueden utilizar otros tipos ajustando los pines definidos. El ejemplo Creación de prototipos con sensor de proximidad de sonda le muestra cómo utilizar un sensor de proximidad para mantener segura su grapadora. En este ejemplo, puede conservar una imagen de su grapadora para ayudar a disuadir y capturar a posibles ladrones.

Configuración

1) Cree un nuevo canal de imágenes de ThingSpeak como se describe en Crear un canal de imágenes.

2) Cree un nuevo canal de datos ThingSpeak como se describe en Recopilar datos en un nuevo canal.

3) Agregue un widget de visualización de imágenes a la vista de su canal de datos, como se describe en Visualización de imagen.

Programar el ESP32

Utilice el IDE de Arduino para crear una aplicación para su dispositivo.

1) Conecte el ESP32 a su computadora usando un cable micro-USB y espere a que se conecte correctamente.

stapler_images_esp32Cam.jpg

2) En el IDE de Arduino, seleccione la placa del módulo de desarrollo ESP32 y el puerto COM correcto.

3) Crea la aplicación. Abra una nueva ventana en el IDE de Arduino y guarde el archivo. Agregue el código proporcionado en la sección Código. Edite el SSID de la red inalámbrica, la contraseña y la clave API de escritura para su canal de imágenes.

Código

1) Incluir las bibliotecas necesarias y definir los parámetros de conexión. Asegúrese de editar los parámetros del canal de imagen y Wi-Fi para que coincidan con su configuración.

#include "esp_camera.h"
#include <WiFiClientSecure.h>

#define PWDN     32
#define RESET    -1
#define XCLK      0
#define SIOD     26
#define SIOC     27
#define Y9       35
#define Y8       34
#define Y7       39
#define Y6       36
#define Y5       21
#define Y4       19
#define Y3       18
#define Y2        5
#define VSYNC    25
#define HREF     23
#define PCLK     22
// Network information.
#define WIFI_SSID "WIFI_NAME"
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"

// ThingSpeak information.
#define IMAGE_CHANNEL_ID "YOUR_THINGSPEAK_IMAGE_CHANNEL_ID"
#define IMAGE_CHANNEL_API_KEY "YOUR_THINGSPEAK_IMAGE_CHANNEL_API_KEY"

#define THINGSPEAK_ADDRESS "data.thingspeak.com"

#define RESPONSE_TIMEOUT 5000
#define MAX_BLOCK_SIZE 16384
#define SNAPSHOT_PERIOD 50000

WiFiClientSecure client = NULL;
unsigned long previousSnapshotTime = 0;
bool cameraAvailable = false;

2) Conéctese a la red wifi local.

void connectWifi()
{
    while (WiFi.status() != WL_CONNECTED) {
        WiFi.begin( WIFI_SSID, WIFI_PASSWORD );
        Serial.println( "Connecting to Wi-Fi" );
        delay( 5000 );
    }
    // Skip checking of server certs.
    client.setInsecure();
    Serial.println( "WiFi Connected" );
}

3) Inicialice la cámara.

bool initCamera() {
  static camera_config_t config  = {
    .pin_pwdn = PWDN,
    .pin_reset = RESET,
    .pin_xclk = XCLK,
    .pin_sscb_sda = SIOD,
    .pin_sscb_scl = SIOC,
    .pin_d7 = Y9,
    .pin_d6 = Y8,
    .pin_d5 = Y7,
    .pin_d4 = Y6,
    .pin_d3 = Y5,
    .pin_d2 = Y4,
    .pin_d1 = Y3,
    .pin_d0 = Y2,
    .pin_vsync = VSYNC,
    .pin_href = HREF,
    .pin_pclk = PCLK,
    .xclk_freq_hz = 20000000,
    .ledc_timer = LEDC_TIMER_0,
    .ledc_channel = LEDC_CHANNEL_0,
    .pixel_format = PIXFORMAT_JPEG,
    .frame_size = FRAMESIZE_QSXGA,
    .jpeg_quality = 10,
    .fb_count = 1,
  };

  if (esp_camera_init(&config) != ESP_OK) {
    Serial.println("Camera initialization failed");
    return false;
  }

  sensor_t * s = esp_camera_sensor_get();
  s->set_brightness(s, 0); // -2 to 2
  s->set_contrast(s, 2); // -2 to 2
  s->set_saturation(s, -2); // -2 to 2
  s->set_whitebal(s, 1); // 0 = disable , 1 = enable
  s->set_awb_gain(s, 1); // 0 = disable , 1 = enable
  s->set_wb_mode(s, 0); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
  s->set_exposure_ctrl(s, 1); // 0 = disable , 1 = enable
  s->set_aec2(s, 1); // 0 = disable , 1 = enable
  s->set_gain_ctrl(s, 0); // 0 = disable , 1 = enable
  s->set_agc_gain(s, 0); // 0 to 30
  s->set_gainceiling(s, (gainceiling_t)6); // 0 to 6
  s->set_bpc(s, 1); // 0 = disable , 1 = enable
  s->set_wpc(s, 1); // 0 = disable , 1 = enable
  s->set_raw_gma(s, 1); // 0 = disable , 1 = enable (makes much lighter and noisy)
  s->set_lenc(s, 1); // 0 = disable , 1 = enable
  s->set_hmirror(s, 0); // 0 = disable , 1 = enable
  s->set_vflip(s, 0); // 0 = disable , 1 = enable
  s->set_dcw(s, 0); // 0 = disable , 1 = enable
  return true;
}

4) Imprima la respuesta del servidor ThingSpeak al puerto serie.

void printResponse(){

  unsigned long startTime = millis();
  // Wait a few hundred milliseconds for server to process the request
  delay( 100 );
  while ( client.available() < 1 && (( millis() - startTime ) < RESPONSE_TIMEOUT ) ){
    delay( 10 );
  }
    
  // Read server response and print it to serial port
  if( client.available() > 0 ){ 
    do {
      Serial.write(client.read());
    } while ( client.available() > 0 );
    Serial.println(' ');    
  }
}

5) Tome una fotografía y envíe la imagen al canal ThingSpeak indicado arriba. Haga eco de cada impresión del cliente en el monitor serie para su depuración.

bool snapshotToThingSpeak() {
  bool result = false;
  // Only send image to ThingSpeak if sufficient time has passed since previous send.
  if ( cameraAvailable && ( millis() > previousSnapshotTime + SNAPSHOT_PERIOD) ) {
    // Capture a new image from the camera.
    camera_fb_t *frame = esp_camera_fb_get();
    if (!frame) return result;
    // Connect to ThingSpeak and send image
    // Echo client commands to serial port for debugging 
    if (client.connect(THINGSPEAK_ADDRESS, 443)) {
      Serial.println("Writing image to ThingSpeak");
      client.print( "POST /channels/");
      Serial.print( "POST /channels/");
      client.print( IMAGE_CHANNEL_ID );
      Serial.print( IMAGE_CHANNEL_ID );
      client.println( "/images HTTP/1.1" );
      Serial.print( IMAGE_CHANNEL_ID );
      client.println( "Connection: close" );
      Serial.println( "Connection: close" );
      client.print( "Host: " );
      Serial.print( "Host: " );
      client.println(THINGSPEAK_ADDRESS);
      Serial.println(THINGSPEAK_ADDRESS);
      client.print( "Thingspeak-image-channel-api-key: ");
      Serial.print( "Thingspeak-image-channel-api-key: ");
      client.println( IMAGE_CHANNEL_API_KEY );
      Serial.println( IMAGE_CHANNEL_API_KEY );
      client.println( "Content-Type: image/jpeg" );
      Serial.println( "Content-Type: image/jpeg" );
      client.print( "Content-Length: ");
      Serial.print( "Content-Length: ");
      client.println(frame->len);
      Serial.println(frame->len);
      client.println(  );
      Serial.println(  );  
      uint8_t *fbBuf = frame->buf;
      long int fbLen = frame->len;   
      do {
        client.write(fbBuf, ( (fbLen > MAX_BLOCK_SIZE) ? MAX_BLOCK_SIZE : fbLen) );
        fbLen -= MAX_BLOCK_SIZE;
        fbBuf += MAX_BLOCK_SIZE;
      } while (fbLen > 0);
      client.flush();
      // Print out server response to serial port.
      printResponse();
      client.stop();
      result = true;   
    } else {
      Serial.print("Unable to connect to ");
      Serial.println(THINGSPEAK_ADDRESS);
    }
    // Update the stored time when the last image was written.
    previousSnapshotTime = millis();    
    // Free the memory buffer for the image so we don't leak memory and segmentation fault.
    esp_camera_fb_return(frame);
    return result;
  }
}

6) Ejecutar rutinas de inicialización.

void setup() {
   // Open serial port for printing debug messages.
   Serial.begin( 115200 );   

   // Connect to WiFi
   connectWifi();
   
   // Initialize the camera
   if (initCamera()){
    Serial.println("Camera initialized");
    cameraAvailable = true;
   }
}

7) Realizar un bucle continuo y enviar una imagen a ThingSpeak.

void loop() {
// If the connection is lost, recconnect.
  if (WiFi.status() != WL_CONNECTED) {
    connectWifi();
  }
  snapshotToThingSpeak();
  delay(30);
}

Escribe la imagen

Ejecute el código mientras monitorea el widget de visualización de imágenes en la vista de su página.

stapler_image_widget.jpg