Mostrando entradas con la etiqueta microcontrollers. Mostrar todas las entradas
Mostrando entradas con la etiqueta microcontrollers. Mostrar todas las entradas

2022/10/25

Secure Boot con ESP32c3

Primero hay que leer atentamente la documentación y cuantos más clicks hagas en los links que tiene más vas a comprender todo, elegí para la v4.4. Puse ESP32c3 en el título pero probablemente aplica a Secure Boot V2, que incluye al menos ESP32s2.


El primer programa que se ejecuta es el que está en la ROM, también llamado FSB (First Stage Bootloader), que entre otras cosas se fija si el eFuse de secure boot está activado, ponele que sí. Luego busca el SSB (Second Stage Bootloader) y si tiene hasta 3 firmas agregadas. Utiliza las hasta 3 public keys que pueden haber en los eFuses y si alguna firma está ok, ejecuta el SSB.

 

Arranque normal
Arranque normal


Arranque seguro
Arranque seguro

 

Este hace lo mismo para cada imagen que haya en el resto de la memoria hasta encontrar una válida. Luego, de la aplicación, copia a memoria los datos y programa correspondientes y mapea a la memoria los datos y programas que vayan a quedar en la EEPROM. Por último ejecuta la aplicación.

Para poder llegar a esta situación, tenemos que hacer algunas cositas:

 

Generar las claves

 

En la carpeta de tu elección, pero luego el pem va en cada proyecto.

$ openssl genrsa -out secure_boot_signing_key.pem 3072

No te olvides de agregar un *.pem a tu .gitignore, si llegás a versionar esto, pensá que podrías revocar el certificado en el chip pero sólo tenés lugar para tres.

 

Toolchain


Bajar todo el entorno de esp-idf según las instrucciones del paso 4. Si ya lo tenías de antes, es conveniente que lo actualices.

$ cd ~/esp/esp-idf

$ git pull --recurse-modules

$ ./install.sh esp32,esp32c3,esp32s2

 

Tu proyecto


Para este ejemplo usé CIBS/esp32c3-secure-boot, que es lo mismo que esp32c3-pinout. De un modo u otro, activar el entorno

$ . export.sh

Ir a tu proyecto, si lo tenías ya construido, hacelo papilla con

$ rm -rf build

Para empezar de cero:

$ idf.py set-target esp32c3
$ idf.py menuconfig

# Security features
[*] Enable hardware Secure Boot in bootloader (READ DOCS FIRST)
   Select secure boot version (Enable Secure Boot version 2)  --->
   (X) Enable Secure Boot version 2
[*] Sign binaries during build (NEW)
   (secure_boot_signing_key.pem) Secure boot private signing key (NEW)

# Partition Table  --->
(0xa000) Offset of partition table

 

Ese 0xa000 en lugar del 0x8000 original podría ser opcional pero en mis pruebas dijo:


Bootloader binary size 0x8c30 bytes is too large for partition table offset 0x8000. Bootloader binary can be maximum 0x8000 (32768) bytes unless the partition table offset is increased in the Partition Table section of the project configuration menu.

La tentación es poner 0x8d00, pero tras varias iteraciones, mejor 0xa000, más que por ahí dice que debe ser múltipo de 0x1000.


$ idf.py build

En algún punto va a tirar dos mensajes, uno que gentilmente explica como agregarle firmas al bootloader:

To sign the bootloader with additional private keys.
    /home/iot/.espressif/python_env/idf4.4_py3.10_env/bin/python /home/iot/esp/esp-idf/components/esptool_py/esptool/espsecure.py sign_data -k secure_boot_signing_key2.pem -v 2 --append_signatures -o signed_bootloader.bin build/bootloader/bootloader.bin 

Y otro de cómo grabarlo, hay que hacerlo a mano, sólo cuando hay nuevas keys.


/home/iot/.espressif/python_env/idf4.4_py3.10_env/bin/python  /home/iot/esp/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32c3 --port=(PORT) --baud=(BAUD) --before=default_reset --after=no_reset --no-stub write_flash --flash_mode dio --flash_freq 80m --flash_size 2MB 0x0 /home/iot/ceiot_base/CIBS/esp32c3-secure-boot/build/bootloader/bootloader.bin


¿Qué ponemos en PORT y BAUD?

PORT = /dev/ttyUSB0

BAUD = 115200


Ambos salen de haber visto alguna vez la salida de idf.py monitor:

--- idf_monitor on /dev/ttyUSB0 115200 ---


Luego

$ idf.py flash

$ idf.py monitor

 

Resultados


La primera vez, tal como dice la documentación, sirve para activar, hace falta un reset

Último arranque inseguro

Desde la próxima vez que arranque:


Primer arranque seguro

Notá tanto la diferencia del FSB (en negro) como la del SSB (en verde).

Este proceso en dibujitos:


Setup bootloader
Setup bootloader



Setup App
Setup App



A mi no me salió de una tán fácil, no encontraba la tabla de particiones, no había nada en ésta, horas...


Una de las tantas fallas...
Una de las tantas fallas...

2022/05/04

Parte de Flisol 2022

En esta oportunidad expuse un mezcladito de varios open:

Open HW/Core/SW: SoC ICICLE con CPU RISC-V en EDU-CIAA-FPGA

A mi propuesta original que incluía el ataque mostrado en H4CK3D 2021, el Profesor Matías me recomendó podarla para que sea menos técnica. Esa poda fué insuficiente, ya el título es bastante largo y complicado, a la mayor parte de la asistencia no era un tema que le interesara, no importa, para FLISoL 2023 tengo pensado algo más apropiado.

 

Mi idea fue ir evolucionando distintas implementaciones de la luz ondulante de K.I.T.T. hasta llegar a un softcore en FPGA, aprovechando el trabajo de un montón de gente:

 

Historia
Historia

 Lo rojito a la derecha era mi objetivo, lo expuesto en H4CK3D 2021

 

La primera versión es con componentes digitales, la hice hace casi 35 años, un registro de desplazamiento con unas puertas OR animadas a continuación, con un 555 para el clock, unos OR, un flip flop y algún capacitor para  inyectar el primer bit.

Ese bit entra en la primera posición del registro de desplazamiento y en cada tick del clock se va moviendo, con la salida conectada a la entrada con un OR al flip flop que salvo en el arranque siempre está en cero, lo tenemos para siempre. Yendo hacia los leds, con los OR de la derecha transformamos el movimiento en un aparente ida y vuelta.

K.I.T.T. con compuertas digitales
K.I.T.T. con compuertas digitales

 

Comparando precios, el costo es similar a implementarlo con un microcontrolador. Ponemos un bit en uno y lo vamos desplazando para un lado hasta detectar que llegó al punto deseado, ahí invertimos el sentido del movimiento, para siempre.


K.I.T.T. con microcontrolador y lógica específica
K.I.T.T. con microcontrolador y lógica específica

El programa es corto pero complicado e inadaptable a otros patrones. Una versión mejor aunque te indigne desde el punto de vista de la programación es:

while (true) {
  gpio_A.out(1);
  delay(DELAY);
  gpio_A.out(2);
  delay(DELAY);
  gpio_A.out(4);
  delay(DELAY);
  gpio_A.out(8);
  delay(DELAY);
  gpio_A.out(16);
  delay(DELAY);
  gpio_A.out(8);
  delay(DELAY);
  gpio_A.out(4);
  delay(DELAY);
  gpio_A.out(2);
  delay(DELAY);
  gpio_A.out(1);
  delay(DELAY);
}

¿Por qué me atrevo a incluir esta manera? Pues por que es el precursor para esta version más linda, en lugar de código hardcodeado, la información está en un array:

unsigned int out[]={1,2,4,8,16,8,4,2,1};
int pos = 0;
int limit = sizeof(out)/sizeof(out[0]);

while ( true) {
  gpio_A.out(1);
  delay(DELAY);
  ++pos;
  if (pos == limit) {
    pos = 0;
  }
}

y esto se parece mucho a la implementación nuevamente con componentes digitales.

K.I.T.T. con contador y memoria
K.I.T.T. con contador y memoria
 

Ahora, tanto en hardware como en software, podemos con gran facilidad mostrar otros patrones manipulando la memoria o el array según corresponda:

 

K.I.T.T. con contador y memoria y patrones arbitrarios
K.I.T.T. con contador y memoria y patrones arbitrarios

 

En la charla acompañando a esta evolución también fui contando como funciona una computadora a un nivel más bajo, que me cuesta mucho convertir a este formato, quizás haga un video en algún momento, lamentablemente no pude grabar la sesión.


Eso llevó a la explicación de FPGA y RISC-V, desembocando en el tema que me interesaba, la implementación primero en Verilog de la versión con lógica, como dispositivo incluido en el SoC icicle:

https://github.com/cpantel/evilCodeSequence/blob/master/kitt.sv

module kitt #( parameter BASETIME) (
    input clk,
    input reset,
    output [4:0]display_out,
    /* memory bus */
    input [31:0] address_in,
    input sel_in,
    //input read_in,
    //output logic [31:0] read_value_out,
    input [3:0] write_mask_in,
    input [31:0] write_value_in,
    output logic ready_out
);

    logic [25:0]q;
    logic direction;
    logic [4:0]display;

    assign ready_out = sel_in;
    assign display_out = display;

    always_ff @(posedge clk) begin
        if (reset) begin
            display <= 1;
            direction <= 1;
        end else if ( q > ( BASETIME / 1000 * 300 ) ) begin
            q <= 0;
            if (direction ) begin
                 if ( display[4] ) begin
                     direction = ~ direction;
                     display <= display >> 1;
                 end else
                     display <= display << 1;
            end else begin
                 if ( display[0] ) begin
                     direction = ~ direction;
                     display <= display << 1;
                 end else
                     display <= display >> 1;
            end 
       end else begin
            q <= q + 1;
            display <= display;
       end
    end

endmodule

 

Y por software, de modo concurrente y absolutamente independiente, ejecutándose en la CPU:

 

/*
  This program implements a SW kitt
*/

#include <stdint.h>
#include "../memmap.h"
#include "../uart.h"
#include "../delay.h"


int main() {
    uart_init();

    uart_puts("KITT starting\r\n");
    for (;;) {
        LEDS = 1;
        delay();
        LEDS = 2;
        delay();
        LEDS = 4;
        delay();
        LEDS = 8;
        delay();
        LEDS = 4;
        delay();
        LEDS = 2;
        delay();
        uart_puts("KITT .\r\n");
    }
}

 

 

Si algo entendés de Verilog, te darás cuenta que ese dispositivo como que está en vano conectado a los buses, ya que no hay nada con lo que el programa en la CPU pueda interactuar. Es que me quedé sin tiempo, querría al menos haberle permitido cambiar la velocidad.

En una próxima entrega espero no muy lejana, mostraré la implementación de un nuevo dispositivo que he de llamar "sequencer", que consistirá en una lógica que lea un trozo de memoria y lo exponga en los leds (vía PMOD como es ahora kitt) y que desde el programa se pueda arrancar, detener, pausar, cambiar la velocidad y modificar esa memoria.


 

 



2022/03/21

ESP32 con BMP280

En el marco del mínimo sistema IoT que he preparado para la futura materia Implementación de IoT, mientras se confeccionaba la lista de materiales para la carrera completa, hubo discusión acerca de si usar DHT11 o BMP280, ambos sensores de temperatura.


  • El DHT11 es más barato, usa un solo pin, pero es menos preciso.
  • El BMP280 usa I2C, dos pines y se deduce de la frase anterior que es más caro y preciso.

 

Lo que no se deduce es que el primero mide temperatura y humedad y el segundo además presión, salvo el modelo que he conseguido que no mide humedad.

Al DHT11, dependiendo de la presentación hace falta agregarle un resistencia de entre 5 a 10 K, le he puesto unas SMD rescatadas de unas viejas placas de una central telefónica hallada en un volquete en el centro cerca del trabajo.

 

DHT11 con resistencia SMD en los pines
DHT11 con resistencia SMD en los pines

 

Había implementado todo para DHT11 pero entre que las otras materias no lo iban a usar y que para ESP32c3 no funcionó, incorporé el BMP280 al ESP32c3 y luego al ESP32, llegando al punto de poder retirar al DHT11 de la lista de materiales, discusión resuelta. De todos modos quedó en el repo disponible.


Para la adaptación no hay ningún sufrimiento, hay que tomar la implementación con DHT11, borrar lo específico y reemplazarlo con el código de ejemplo de UncleRus, que es básicamente un include, elegir los pines, armar una estructura, inicializar y leer.

 

Respecto a los pines, a diferencia de DHT11 que usa un protocolo serial OneWire por software y se puede implementar en cualquier pin GPIO, BMP280 usa I2C por hardware, supuse que debía ser un subconjunto bastante menor.


Busqué en esp32-wroom-32_datasheet_en.pdf y nada. Por suerte luego hallé un tutorial https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/ que decía que:

 

the SDA line may also be labeled as SDI and the SCL line as SCK.

 

y luego que se podían mapear a casi cualquier pin, supuse mal.

 

Alguna líneas interesantes del código, en estas se determina que chip es: 


bool bme280p = dev.id == BME280_CHIP_ID;
ESP_LOGI(TAG, \
    "BMP280: found %s\n", bme280p ? "BME280" : "BMP280");

 

Luego se manifiesta en los valores que se pueden completar:


if (bmp280_read_float( \
          &dev, \
          &temperature, \
          &pressure, \
          &humidity) != ESP_OK) {
  ESP_LOGI(TAG, "Temp./press. reading failed\n");
} else {
  ESP_LOGI(TAG, \
    "Press: %.2f Pa, Temp: %.2f C", pressure, temperature);
 

//if (bme280p) {
    sprintf(send_buf, REQUEST_POST, temperature , humidity );
//} else {
//    sprintf(send_buf, REQUEST_POST, temperature , 0);
//}

 

Lo dejé comantado pues la verdad es que me dá lo mismo mandar un cero hardcodeado que uno proveniente de la lectura, pero es incorrecto, debería no enviar el valor y/o agregar un campo con el tipo de sensor, para diferenciar el cero de cero humedad del cero de cero lectura.

Este sistema está todo hecho así, una reducción muy básica con múltiples oportunidades de completar y mejorar. Si te viene interesando, podés implementarlo siguiendo las instrucciones y luego:

  • Agregar campos para reportar errores.
  • Agregar timestamp, pensá donde...
  • Enviar JSON en lugar de x-www-form-urlencoded.
  • Implementar algún DNS para usar nombres en lugar de IPs. 
  • Usar https en lugar de http.
  • Envíar vía MQTT en lugar de HTTP-POST.

Truquito, en el router fijá la MAC address del servidor a una IP y te va a facilitar la vida.

Se supone que quizás viste todo esto antes de llegar hasta acá:


https://seguridad-agile.blogspot.com/2022/03/ejemplo-de-esp8266-con-lectura-de-dht11planB.html


https://seguridad-agile.blogspot.com/2022/02/ejemplo-de-esp32-con-lectura-de-dht11.html


https://seguridad-agile.blogspot.com/2022/02/primer-contacto-con-esp32.html




 



2022/03/19

Ejemplo de ESP8266 con lectura de DHT11: Plan B

Venimos de un momentáneo fracaso.

 

Plan B

 

La gente que viene de sistemas embebidos siente un cierto desprecio por ArduinoIDE debido al alto nivel de abstracción, te pasaste años estudiando como funciona una CPU, un microcontrolador, viendo como se configura bit a bit cada dispositivo y ArduinoIDE te lo reduce a un .setup() y obviamente en situaciones anormales no tenés recursos y probablemente hayas perdido el RealTime.

Se parece al desprecio que sentimos los que venimos del otro lado al ver como con cualquier gestor de Cloud cualquier iletrado puede armar cosas bastante complejas, completamente inconcientes de cómo instalar y configurar un sistema operativo, base de datos, servidor de lo que sea, optimización y hardening. No importa, no quiero ninguna flame war.


Te bajás ArduinoIDE de 

https://www.arduino.cc/en/software
 
Descomprimís:
 
tar -xf ../Downloads/arduino-1.8.19-linux64.tar.xz 

Primero no hice el install.sh pues mirándolo por encima no parecía aportar nada, luego al ver que no aparecía el programmer en tools, ejecuté arduino-linux-setup.sh, pero no era por eso, el flash se hace directamente.

Para ejecutar:

./arduino

Hay que agregar el board con 

  • File
    • Preferences
      • Additional Boars Manager URLs: 

ahí ponés

http://arduino.esp8266.com/stable/package_esp8266com_index.json

 

Luego vás a 

  • Tools 
    • Board
      • Board Manager
        • search: esp8266
          • esp8266 by ESP8266 Community
            • Install
    • Board
      • ESP8266 Boards
        • ESP Generic  Module
    • Port 
      • /dev/ttyUSB0
    • Manage Libraries
      • filtrar por dht
        • DHT Sensor Library for ESPx 
          • install


Para el DHT quise apoyarme en lo aprendido antes, pero no me sirvió, lo que hice fue incorporar DHT Sensor Library for ESPx
 
 
 
Y funcionó ok con el siguiente programa, que es una mezcla entre los ejemplos:
  • File
    • Examples
      • Examples for Generic ESP8266 Module
        • ESP8266HTTPClient
          • PostHTTPClient
      • Examples for Custom Libraries
        • DHT_sensor_library_for_ESPxDHT_ESP8266


#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

#include "DHTesp.h"
 
#define DEVICE_ID "61"
#define SERVER_IP "192.168.0.100:8080"

#define STASSID "" <- recordá no versionar
#define STAPSK  "" <- recordá no versionar
 
DHTesp dht;

float humidity = 0.0;
float temperature = 0.0;

void setup() {
  delay(10000);

  Serial.begin(115200);

  Serial.println("ESP8266 DHT HTTP POST");
 
  dht.setup(2, DHTesp::DHT11);
  delay(dht.getMinimumSamplingPeriod());

  Serial.println(dht.getStatusString());
  humidity    = dht.getHumidity();
  temperature = dht.getTemperature();
  Serial.print("Temperature : ");
  Serial.println(temperature);
  Serial.print("Humidity : ");
  Serial.println(humidity);

  WiFi.begin(STASSID, STAPSK);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // wait for WiFi connection
  if ((WiFi.status() == WL_CONNECTED)) {
    WiFiClient client;
    HTTPClient http;

    Serial.print("[HTTP] begin...\n");
    // configure traged server and url
    http.begin(client,
"http://" SERVER_IP "/measurement"); //HTTP http.addHeader("Content-Type", "application/x-www-form-urlencoded"
    );

    Serial.print("[HTTP] POST...\n");
    // start connection and send HTTP header and body
    String post("id=");
    post += DEVICE_ID;
    post += "&t=";
    post += temperature;
    post += "&h=";
    post += humidity;
    int httpCode = http.POST(post);

    // httpCode will be negative on error
    if (httpCode > 0) {
      Serial.printf("[HTTP] POST... code: %d\n", \
           httpCode);

      // file found at server
      if (httpCode == HTTP_CODE_OK) {
        const String& payload = http.getString();
        Serial.println("received payload:\n<<");
        Serial.println(payload);
        Serial.println(">>");
      }
    } else {
      Serial.printf( \
           "[HTTP] POST... failed, error: %s\n", \
           http.errorToString(httpCode).c_str());
    }

    http.end();
  }

  delay(10000);
}

 
El código bastante parecido está en github en la carpeta esp8266-arduino. En esp8266 dejé la fallada con esp-idf.
 
Nos quedó asi:
 
~/esp/
     /esp-idf
     /esp-idf-lib
     /ESP8266_RTOS_SDK
     /arduino-1.8.19
     /ceiot/
           /esp32
           /esp32c3
           /esp32s2
           /esp8266
           /esp8266-arduino 




Ejemplo de ESP8266 con lectura de DHT11

Hace ya un tiempo exploré como lidiar con el entorno de desarrollo de ESP8266. Mientras incorporaba esa arquitectura a un proyecto educativo que consiste en leer un sensor de temperatura DHT11 y transmitirlo por HTTP-POST, me encontré con que las instrucciones que tenía quizás ya no son vigentes.

El proceso es similar a cómo se hace con ESP32 y acá lo mostraré adaptado. 

 

No tomes este camino

Si no tenés curiosidad por mis desgracias, andá directo al Plan B más abajo.

Si lo tomás, tené en cuenta que te rompe la instalación de esp-idf.

 

Plan A

La estructura de archivos que es esta:

~/esp/
     /esp-idf
     /esp-idf-lib
     /ESP8266_RTOS_SDK
     /ceiot/
           /esp32
           /esp32c3
           /esp32s2
           /esp8266

Resaltado lo que vamos a agregar.

esp-idf es la SDK para ESP32, esp-idf-lib son componentes de un tal RusLand.

Vamos a suponer que al haber instalado previamente todo lo necesario para esp-idf, si siguieras los siguientes pasos en una máquina limpia quizás no alcanzaría.


$ git clone https://github.com/espressif/ESP8266_RTOS_SDK.git
$ cd ESP8266_RTOS_SDK.git
$ git checkout origin/release/v3.4
$ sudo apt install python3-pip python-setuptools libncurses5-dev
$ /usr/bin/python3 -m pip install --user -r requirements.txt
$ ./install.sh
$ . export.sh



Mirando por encima requirements.txt, que es lo que consume install.sh apreciarás que hay poca superposición.

 
export.sh te genera un entorno para que funcionen los make posteriores y se debe ejecutar en cada terminal que abrás. Si te falla por que no encuentra python, la primera tentación es ponerse a modificar las referencias a python por python2 o python3 en mi caso, primero en export.sh y luego en otras partes. Mala idea, lo mejor, recordando que tengo armada una virtual sólo para esto, es:
 

sudo ln -s /usr/bin/python3 /usr/bin/python

El problema de hacer esto es que te rompe luego lo que tengas para ESP32.

Así que tenés que estar alternando con:

sudo rm /usr/bin/python

Como no pienso hacer mucho es ESP8266, alternaré. Si luego se me ocurre algo mejor o alguien lo tiene, me lo pasa y lo pongo.
 
Si prestaste atención a cómo se hace en ESP32, habrás notado que acá no existe el paso para determinar que chip usas:
 
idf.py set-target esp8266

Esto es porque hay múltiples ESP32, como ESP32, ESP32c3, ESPs2 para mencionar algunos y sólo hay un ESP8266.

Listo para el build. Pero antes, incorporemos el proyecto, lo que hay uno tiene la tentación de hacer es (no hacer):
 
 
mkdir esp8266
cd esp32
cp CMakeLists.txt -r main/ Makefile ../esp8266
cd ../esp8266
 
 
Pero no, equivocado, lo que hay que hacer es:
 
cp -r ../ESP8266_RTOS_SDK/examples/wifi/getting_started/station .
mv station esp8266
# modificar el programa tal como con ESP32
 
 
Para la configuración de los componente, en este caso credenciales de WiFi:
 
make menuconfig

 
No te olvides de borrarlas al versionar .

Finalmente, para que funcione la parte del DHT11, hay que tocar el Makefile:

EXTRA_COMPONENT_DIRS += $(IDF_PATH)/../esp-idf-lib/components


Y ahora si

make 
make flash
make monitor


No tan fácil...

Habían varios errores simultáneos que me confundieron. Algunos relacionados con la inclusión de archivos, otros quizás relativos a los branches de cada repositorio, en una conversación en embebidos quedó registrado parte de esto, no aporta que lo repita acá.
 
Lo más significativo de esa conversación es que si hubiera leido el manual quizás hubiera detectado que hay componentes no soportados de esp-idf-lib en ESP8266 y que hay que excluirlos del proceso de compilación.

La receta resultante es, por ahora:
 
Usar los tags v3.4 y v0.8.2 (esp-idf y esp-idf-lib respectivamente)
 
En el Makefile, para que incluya esp-idf-lib:
 
EXTRA_COMPONENT_DIRS += $(IDF_PATH)/../esp-idf-lib/components
 
para que excluya los componentes no soportados:

EXCLUDE_COMPONENTS := max7219 mcp23x17 led_strip max31865 ls7366r hts221
 
 
Aún así, aunque compila no funciona:
 
 
...a ver...


Reconectando...
Reconectando...


 
Mmmh, fijate que intenta conectar a como dé lugar, habría que agregar un mensajito de log tal como he resaltado:

static void on_wifi_disconnect(void *arg, 
                        esp_event_base_t event_base,
                        int32_t event_id,
                        void *event_data){
  system_event_sta_disconnected_t *event =
     (system_event_sta_disconnected_t *)event_data;
 
  ESP_LOGI(TAG, 
            "Wi-Fi disconnected reason %d\n\r",
            event->reason);   

  ESP_LOGI(TAG,"Wi-Fi disconnected, trying to reconnect...");
  if (event->reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT){
      /*Switch to 802.11 bgn mode */

      esp_wifi_set_protocol(
         ESP_IF_WIFI_STA,
         WIFI_PROTOCOL_11B | 
         WIFI_PROTOCOL_11G |
         WIFI_PROTOCOL_11N);
  }
  ESP_ERROR_CHECK(esp_wifi_connect());
}


Si querés ver que hace esp_wifi_connect, no existe, me parece que está implementado en ROM o similar en el chip.

Ahora dice:

phy_version: 1163.0, 665d56c, Jun 24 2020, 10:00:08, RTOS new
I (415) phy_init: phy ver: 1163_0
I (426) example_connect: Connecting to thebox...
I (3217) wifi:state: 0 -> 2 (b0)
I (4217) wifi:state: 2 -> 0 (200)
I (4218) example_connect: Wi-Fi disconnected reason 2

I (4220) example_connect: Wi-Fi disconnected, trying to reconnect...
I (6286) example_connect: Wi-Fi disconnected reason 205




Las event-reasons están en components/esp8266/include/esp_wifi_types.h, son un montón y se llaman wifi_err_reason_t.

WIFI_REASON_AUTH_EXPIRE       = 2
WIFI_REASON_CONNECTION_FAIL   = 205 

 
¿Qué si probé con reiniciar el router? ¡Claro! antes de usar linux usaba windows...

Probé con
 
make menuconfig -> 
   Component config  --->
    Wi-Fi  --->
[*] Enable WiFi debug log (ESP8266_WIFI_DEBUG_LOG_ENABLE)
 
 
Pero no hallé como acceder o interactuar con ese log.
 

 
Me pasé al ejemplo más básico, station, para reducir variables, probé todo lo que sigue:
 
  • ESP8266_PHY_MAX_WIFI_TX_POWER, ya está en 20, pasé a 21Cambié de canal en el AP, del 11 al 1 y al 6 
  • Puse modo B only
  • Puse modo G only
  • Puse modo N only
  • AES en lugar de TKIP + AES
  • a 30 centímetros del AP
  • Branches v3.3 y v3.3-rc1
  • Cambié de router
  • Probé con 20 y 40 MHz de ancho

 
No encuentro más recursos, sólo esta pista:

WiFi.hostname("ESP-host"); before WiFi.begin(ssid, password);

Pero eso es con ArduinoIDE.

Me quedaría armar un Access Point para diagnosticar desde ese lado o buscar como hacer sniffing, quedará para otra vez.



2022/02/27

Ejemplo de ESP32 con lectura de DHT11

Extendiendo los pasos de primer contacto con ESP32, va tipo receta con anotaciones sin mayores explicaciones, la idea es terminar con una carpeta con el proyecto armado.

 

Instalación de dependencias

 

sudo apt install git wget flex bison gperf python3 python3-pip python3-setuptools cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0


Mi entorno suele ser una virtual, por comodidad también hago:

sudo apt install vim kdiff3 dirdiff

 

Estructura de archivos

 

mkdir esp http_request

 

~/esp/esp-idf
      esp-idf-lib
      http_request

 

Aunque he puesto el ejemplo http_request a la par de los repositorios, puede estar en cualquier lado.

 

Repositorios y setup herramientas

 

El primer repo te provee un montón de dispositivos, nos interesa el componente dht11.

git clone https://github.com/UncleRus/esp-idf-lib.git

git clone -b v4.4 --recursive https://github.com/espressif/esp-idf.git

 

El segundo es la adaptación de FreeRTOS a extensa de expresif.

 

cd esp-idf

./install.sh esp32 

 

Eso te instaló lo que haga falta para ESP32. Tanto acá como en pasos posteriores, donde dice esp32 puede ir esp32c3 o esp32s2, pero por ahora sólo probé con esp32, no debería en general pero pueden haber diferencias sutiles con los pines en estos ejemplos básicos.

 

El código


cd ../http_request

. ../esp-idf/export.sh

Esto es para que funcione el entorno de build.

 

El código es copia del ejemplo http_request:

cp -r ../esp-idf/examples/protocols/http_request/ .

Ajuste del proyecto a esp32:

idf.py set-target esp32

Sería un buen momento para hacer funcionar el ejemplo así como está, pero vamos directo al ejemplo completo.

 

Dependencias de código

 

En CMakeFiles.txt, agregá la dependencia a esp-idf-lib:

set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common $ENV{IDF_PATH}/../esp-idf-lib/components)

Menuconfig

idf.py menuconfig

Si está versionando, no te olvides de NO VERSIONAR sdkconfig una vez que hayas puesto los valores de conexión de la WiFi. Lo que hago yo es:

idf.py menuconfig -> Save

git add sdkconfig

git commit -m "xxx"

idf.py menuconfig

Example Connection Configuration --->
  [*] connect using WiFi interface
  (xxxxxxx) WiFi SSID
  (xxxxxxx) WiFi Password

Pero si tenés otros valores secretos se empieza a complicar. De un modo u otro, repito, NO VERSIONES SECRETOS.

 

Ajustes del código

 

Tomamos como base esp-idf-lib/examples/dht/main/main.c

includes

#include <stdio.h>
#include "dht.h"

constants

static const dht_sensor_type_t sensor_type = DHT_TYPE_DHT11;
static const gpio_num_t dht_gpio = 17;

La URL

#define WEB_SERVER "example.com" -> la IP que uses
#define WEB_PORT "80" -> el puerto que uses
#define WEB_PATH "/" -> según mi ejemplo "/collect.php"

static char *REQUEST_GET =
        "GET " WEB_PATH "/?t=%d&h=%d HTTP/1.0\r\n"...

La idea es reemplazar esos dos %d con sprintf(), para eso incluí <stdio.h>, con los valores leídos.

Las variables

char send_buf[256];

int16_t temperature = 0;
int16_t humidity = 0;

La lectura del sensor

while(1) {
  if (dht_read_data(sensor_type, dht_gpio, &humidity, &temperature) == ESP_OK) {
    ESP_LOGI(TAG,"Humidity: %d%% Temp: %dC\n", humidity, temperature);
    sprintf(send_buf, REQUEST_GET, temperature, humidity);
    ESP_LOGI(TAG,"sending: \n%s\n",send_buf);
 } else {
    ESP_LOGE(TAG,"Could not read data from sensor\n");
 }

y la escritura, al buffer lo preparamos con el sprintf() anterior.

if (write(s, send_buf, strlen(send_buf)) < 0) {...



Acá el código entero resultante con propuestas de ejercicios intercalados, no deberías necesitarlo, pero no molesta. El proyecto completo en github

 

#include <string.h>
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"

#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
#include "dht.h"


/* Constants that aren't configurable in menuconfig */
#define WEB_SERVER "192.168.1.102"
#define WEB_PORT "8080"
#define WEB_PATH "/collect.php"

static const dht_sensor_type_t sensor_type = DHT_TYPE_DHT11;
static const gpio_num_t dht_gpio = 17;


static const char *TAG = "temp_collector";

static char *REQUEST_GET = "GET " WEB_PATH "/?t=%d&h=%d HTTP/1.0\r\n"
    "Host: "WEB_SERVER":"WEB_PORT"\r\n"
    "User-Agent: esp-idf/1.0 esp32\r\n"
    "\r\n";

// Ejercicio: enviar POST    
// Ejercicio: enviar json

static void http_get_task(void *pvParameters)
{
    const struct addrinfo hints = {
        .ai_family = AF_INET,
        .ai_socktype = SOCK_STREAM,
    };
    struct addrinfo *res;
    struct in_addr *addr;
    int s, r;
    char recv_buf[64];

    char send_buf[256];

    int16_t temperature = 0;
    int16_t humidity = 0;
 
    while(1) {
        if (dht_read_data(sensor_type, dht_gpio,
                &humidity, &temperature) == ESP_OK) {
            ESP_LOGI(TAG,
    "Humidity: %d%% Temp: %dC\n", humidity / 10, temperature / 10);
            sprintf(send_buf, REQUEST_GET, temperature / 10, humidity / 10);
        ESP_LOGI(TAG,"sending: \n%s\n",send_buf);
        } else {
            ESP_LOGE(TAG,"Could not read data from sensor\n");
        // Ejercicio: enviar mensaje
        }

        int err = getaddrinfo(WEB_SERVER, WEB_PORT, &hints, &res);

        if(err != 0 || res == NULL) {
            ESP_LOGE(TAG, "DNS lookup failed err=%d res=%p",
                      err, res);
            vTaskDelay(1000 / portTICK_PERIOD_MS);
            continue;
        }

        addr = &((struct sockaddr_in *)res->ai_addr)->sin_addr;
        ESP_LOGI(TAG, "DNS lookup succeeded. IP=%s",
                        inet_ntoa(*addr));

        s = socket(res->ai_family, res->ai_socktype, 0);
        if(s < 0) {
            ESP_LOGE(TAG, "... Failed to allocate socket.");
            freeaddrinfo(res);
            vTaskDelay(1000 / portTICK_PERIOD_MS);
            continue;
        }
        ESP_LOGI(TAG, "... allocated socket");

        if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
            ESP_LOGE(TAG,
                 "... socket connect failed errno=%d", errno);
            close(s);
            freeaddrinfo(res);
            vTaskDelay(4000 / portTICK_PERIOD_MS);
            continue;
        }

        ESP_LOGI(TAG, "... connected");
        freeaddrinfo(res);

        if (write(s, send_buf, strlen(send_buf)) < 0) {
            ESP_LOGE(TAG, "... socket send failed");
            close(s);
            vTaskDelay(4000 / portTICK_PERIOD_MS);
            continue;
        }
        ESP_LOGI(TAG, "... socket send success");

        struct timeval receiving_timeout;
        receiving_timeout.tv_sec = 5;
        receiving_timeout.tv_usec = 0;
        if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,
           &receiving_timeout, sizeof(receiving_timeout)) < 0) {
            ESP_LOGE(TAG,
              "... failed to set socket receiving timeout");
            close(s);
            vTaskDelay(4000 / portTICK_PERIOD_MS);
            continue;
        }
        ESP_LOGI(TAG, "... set socket receiving timeout success");

        /* Read HTTP response */
        do {
            bzero(recv_buf, sizeof(recv_buf));
            r = read(s, recv_buf, sizeof(recv_buf)-1);
            for(int i = 0; i < r; i++) {
                putchar(recv_buf[i]);
            }
        } while(r > 0);

        ESP_LOGI(TAG, "... done reading from socket. Last read return=%d errno=%d.", r, errno);
        close(s);

        for(int countdown = 10; countdown >= 0; countdown--) {
            ESP_LOGI(TAG, "%d... ", countdown);
            vTaskDelay(1000 / portTICK_PERIOD_MS);
        }
        ESP_LOGI(TAG, "Starting again!");
    }
}

void app_main(void)
{
    ESP_ERROR_CHECK( nvs_flash_init() );
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    ESP_ERROR_CHECK(example_connect());

    xTaskCreate(&http_get_task, "http_get_task", 4096, NULL, 5, NULL);
}


Si hubieras usado el ejemplo http_request sin tocar y vez esa basura no te preocupes, es que el servidor te ha dado la respuesta comprimida, observá el Content-Encoding: gzip, no tenés error.


example.org
example.org


Errata


Me faltó mencionar que hay que conectar el sensor a algún pin, en este caso usé el 17

static const gpio_num_t dht_gpio = 17;

y no olvides poner la resistencia entre el positivo (3.3v) y el cable de datos.

2022/02/21

Primer contacto real con PIC16

Tras haber asistido a un seminario introductorio a PIC16, debido a que los kits fueron entregados tras éste, me quedaron pendientes dos actividades: el blinky y ver si unas instrucciones muy específicas bcf y bsf, no serían reemplazables por unos ingeniosos ands y ors.

 

El blinky

 

Hasta donde entendí, a diferencia de los AVR, estos PIC siempre necesitan una referencia externa para el clock, hay que ponerle un cristal y unos capacitores... no tan fácil, en el curso no hay ningún diagrama de conexión, como que está asumido que vos ya sabés electrónica digital y lo que no conocés es PIC. Menciona por un lado que sólo se van a usar dos pines para programar (TX y RX) y luego dice "Comparte el control del pin MCLR", ¿mmh, qué querrá decir? Obviamente pedí el diagrama pero para hacer más interesante esta experiencia lo voy a recibir cuando haya tenido éxito o fracaso.

Entonces, al buscar diagramas relacionados a cosas como "pic16f tiny bootloader circuit diagram and usb uart adapter" lo segundo mejor que encontré fué un proyecto donde muestra que se usa RTS para pegarle a MCLR (a.k.a. RESET), pero eso es a la salida de un MAX232, la idea es usar el adaptador USB-UART provisto en el kit (dicho sea de paso, ese kit debería haber traido el cristal, los capacitores...)

 

Usando RTS para el RESET
Usando RTS para el RESET


Finalmente, llegúe a un tutorial que al final dice:

 

Download the complete project folder from the below link:
Hardware design Files and Code Library 

 

Sin RTS
Sin RTS


perfecto, es lo más sencillo posible que parecería funcionar, al reset habría que darle con el dedo.

 

Ahora, a tomar posesión del chip, lo primero es identificar las patitas:

 

Pinout colorizado por función
Pinout colorizado por función

Cada color es un puerto, en grís los mínimos necesarios para programarlo.


A pensar un poco, muy poco, el diagrama del tutorial es lo que hay que hacer.


Circuito armado
Circuito armado

A la derecha Tx y Rx al USB-TTL. Lo alimento con una fuente externa.


Antes de investigar nada más, a ver si funciona. Hay que bajar el tinybootloader para linux y probar...

 

En la versión 0.6 al bajar el .deb falla por dependencia imposible de satisfacer, python-gtk2,buscando, hallamos https://osdn.net/projects/sfnet_tinybldlin/releases/ que dice tener la versión 0.8.1, veamos... nop, tambien necesita python-gtk2

              Depends: python-gtk2 but it is not installable
              Depends: python-cairo but it is not installed
              Depends: python-gobject but it is not installed
              Depends: python-serial but it is not installable

Veamos de instalarlo basándonos en https://techviewleo.com/install-python-with-virtualenv-on-linux-mint/

sudo apt-get update

sudo apt-get upgrade

sudo add-apt-repository universe

sudo apt-get update

con algunos

apt-cache search python 

determinamos que python-cairo y python-gobject estan disponibles, hay que usar pip para el resto

curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py

sudo python2 get-pip.py

ok, pero luego no puedo hallar los paquetes faltantes con pip


Hay varios caminos: 

  • resolver las dependencias
    • es en lo que vengo fallando
  • buscar otro programa
    • no está apareciendo
  • instanciar una virtual con una distro antigua que soporte python2
    • quizás tampoco pueda resolver las dependencias
    • puede ser que mplab no funcione ahí
      • no importa, sólo la usaría para flashear
  • usar wine
    • seguramente se me complique el acceso al puerto serial
    • chicken
  • instanciar una virtual con windows
    • se me puede complicar el acceso al puerto serial
    • chicken
  • actualizar el programa a python3
    • y hacer un aporte a la humanidad...
    • pero puede ser mucho tiempo
  • evitar el bootloader
    • esto significa faltar al espíritu de la experiencia original
    • tendría que armar o comprar el programador
      • no me interesa volver a hacer nada con PIC, quizás programar otro que tengo en un cajón

o mucho mejor aun, buscar un poco más hasta encontrar que 


https://github.com/lcgamboa/tinybldlin

y un

sudo apt install python3-serial


abre el programa, pero... siempre hay un pero, dice que:


Tiny PIC BootLoader
Tiny PIC BootLoader

...no lo encuentra. Mirá fijo la captura y vas a ver que en la terminal desde donde lo abriste, dice que aprietes el reset. Esta captura no es sobre la primera iteración, donde esa terminal había quedado oculta.

Lo aprieto y nada...

Siguiento mi método de armar un mail para no mandarlo, donde fuí documentando todo lo hecho para solicitar ayuda, descubrí que había conectado mal Rx, así que a desoldar... y anda.

Situación: hay que apretar el reset ante cada operación, ok, razonable.

Puede hacer falta por única vez:

  •  Tools -> Options -> Embedded -> Build Tools -> Scan for Build Tools 

Luego, para cada proyecto:

  • New project -> Microchip Embedded -> Standalone project
  • family -> Baseline 8-bit MCUs (PIC10/12/16)
  • device -> PIC16F874A
  • tool -> simulator
  • header -> none
  • compiler -> XC8 (v2.32) o similar
  • new file -> main.c

#include <xc.h>
#include <pic16f877a.h>
#include <stdio.h>

#define _XTAL_FREQ 4000000

void main(void) {
    TRISB = 0;
    PORTB=0;
    while(1) {
        PORTBbits.RB0=0;
        PORTBbits.RB1=0;
        PORTBbits.RB7=0;
        __delay_ms(500);
        PORTBbits.RB0=1;
        PORTBbits.RB1=1;
        PORTBbits.RB7=1;
        __delay_ms(500);
    }
    return;
}

  • Build
  • copiar a tinypicbootloader la ruta tipo:

/home/carlos/Desktop/blinky.X/dist/default/production/blinky.X.production.hex

  • write flash
  • reset
Listo, el blinky funciona.

La parte ingeniosa del análisis bcf -> andwf queda para otro día,


2022/02/17

Primer contacto con ESP32

Paso a relatar los pasos que he seguido para instanciar los hello world en distintos ESP32 en el marco de colaborar en los criterios de elección de hardware para la carrera de especialización de IoT, siendo mi foco de interés sus características de seguridad, pero antes hay hacerlos andar.

Para comenzar, me ha costado comprender la taxonomía de los ESP32, en algún momento medio que lo había logrado pero por falta de refrescarlo lo perdí. En esta oportunidad no sé si he tenido mejor suerte o ha mejorado la información de espressif. Como sea, a partir de una comparativa pude hacerme el siguiente resumen.

Si ves en github podés ver con blame que existe desde hace 15 meses, yo había tenido mi primer contacto con ESP8266 hace 20 meses e intenté entender poco despues así que quizás me la perdí.

Desde ahí te bajás la datasheet de cada familia o serie y te queda algo como esto:
 

  • ESP32
    • ESP32-D0WD-V3
    • ESP32-D0WDQ6-V3
    • ESP32-D0WD
    • ESP32-D0WDQ6
    • ESP32-D2WD
    • ESP32-S0WD
    • ESP32-U4WDH
    • ESP-WROOM-32
  • ESP32-S2
    • ESP32-S2
      • WROVER-1
      • MINI-1
    • ESP32-S2FH2
    • ESP32-S2FH4
  • ESP32-S3
    • ESP32-S3
    • ESP32-S3FN8
    • ESP32-S3R2
    • ESP32-S3R8
    • ESP32-S3R8V
  • ESP32-C3
    • ESP32-C3
      • ESP32-C3-WROOM-02
    • ESP32-C3FN4
    • ESP32-C3FH4

En negrita marqué los que tengo, en el primer caso lo dejé colgando, eso es lo que me confunde un poco. Lo que me importa es dada una plaquita, poder identificar que tiene, a ver si me sirve en particular para el dictado de la materia Ciberseguridad de IoT para mostrar secure boot. Ese safer than ESP32 significa que ESP32 es vulnerable a algunos ataques, no importa, es un tanto irrelevante al mostrar como funciona.

 

Compartiva familias ESP32
Compartiva familias ESP32

Bien, ¿qué hay que hacer? Pues bajar la SDK, evitando sufrir todo lo sufrido con ESP8266.

Curioseás un rato por Libraries and Frameworks, Resources, ponés freertos en el buscador, nada. Recordás que existe https://github.com/espressif/ESP8266_RTOS_SDK y suponés que existe algo tipo ESP32_RTOS_SDK, pero no, no existe. Buscás en los repos y aparece uno que dice:


ESP31B SDK based on FreeRTOS.
For ESP32 please see http://github.com/espressif/esp-idf

 

Ok, pese a que acá relaciona FreeRTOS con el SDK luego... no importa, no fue tan difícil.

Lo primero que te dice es que si querés soporte para todas las familias, elijas la versión apropiada. Luego dice que hay documentación para cada release combinando para cada serie, vamos por la V4.4. que cubre todo, la que me falta, ESP32-S3, ya vendrá.

 

Pasos


Abrimos en tres ventanas esp32, esp32s2 y esp32c3 y los operamos en simultáneo a ver las diferencias.

Voy a usar un VirtualBox con Linux Mint 20.3 xfce, 8GB RAM, 2 cores, guest additions para poder copiar y pegar.

 

Step 1: Install prerequisites, linux only

Sin misterios, es lo mismo para cualquier serie.

sudo apt-get install git wget flex bison gperf python3 python3-pip python3-setuptools cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0


Step 2: Get ESP-IDF

Sin misterios, son 1.2 GB, el v4.4 corresponde al release que habíamos elegido antes.

git clone -b v4.4 --recursive https://github.com/espressif/esp-idf.git


Step 3: Set up the tools, linux only

./install.sh esp32,esp32s2,esp32c3

Dice que

Selected targets are: esp32c3, esp32s2, esp32
Installing tools: xtensa-esp32-elf, xtensa-esp32s2-elf, riscv32-esp-elf, esp32ulp-elf, esp32s2ulp-elf, openocd-esp32

 

Ese riscv32-esp-elf debe ser para el esp32c3.

 

Step 4: Set up the environment variables


. ./export.sh

Te dice con buen criterio que no lo incluyas en el .bashrc para que no se active en cada terminal, es razonable pues no vas a tener 20 terminales en la que estés compilando.

 

Step 5: Start a project

Te dice que te ubiques afuera de ~/esp/esp-idf, copies el hello world, nada misterioso.


Step 7: Configure


idf.py set-target [esp32|esp32s2|eps32c3]
idf.py menuconfig

Con set-target le decís a cada proyecto en que familia será desplegado.

En este punto te recomiendo un:

sudo apt install kdiff3 dirdiff

Luego  te hacés algo como esto mediante copias sucesivas:

hello_world
hello_world_esp32
hello_world_esp32c3
hello_world_esp32s2

Entrás en cada  *_esp32* y ejecutás el set-target correspondiente.

Te genera una carpeta build y el archivo sdkconfig. En éste, podés ver las opciones de configuración para menuconfig y con kdiff3 podrás apreciar las diferencias, muy divertido e ilustrativo:

kdiff3 hello_world_esp32s2/sdkconfig \
    hello_world_esp32c3/sdkconfig

 

Comparación sdkconfig
Comparación sdkconfig

 

Para comparar los archivos de build la tentación es usar esto:

dirdiff hello_world_esp32s2/build/ \
   hello_world_esp32c3/build/

Usalo, pero tené en cuenta que en la carpeta esp-idf hay varias carpetas con nombres correspondientes a la familia, lo cual mete ruido. Igual no me fijé si amerita mirar mucho por este lado.

Cuando llegues al menuconfig, esta bueno tomar nota del baud rate:

Serial Flasher Config ->
'idf.py monitor' baud rate (115200 bps)

Pese a que dice: "set up project specific variables, e.g. Wi-Fi network name and password, the processor speed,..." y habiendo aprendido que con "/" te muestra todas las variables, no lo puedo encontrar. Luego, tras explorar un ratito y quizás recordar de la experiencia anterior, hay variables que son locales a cada proyecto, eso lo ves en main/Kconfig.projbuild. Lo de la clave de Wi-Fi está en el ejemplo ./esp-idf/examples/wifi/getting_started/station.

 

Step 6: Connect device


Esta bueno decirle a virtualbox que siempre conecte la placa a la virtual, asi no tenés que estar recordando hacerlo cada vez que reconectás o se resetea:


Conexión USB con filtro
Conexión USB con filtro

No domino esta funcionalidad, me parece que hay que hacerlo con cada dispositivo, no alcanza cada tipo, tampoco es tan importante.

 

Step 8: Build the project


idf.py build

Paciencia...


Mientras podés saltarte unos pasos y ejecutar 

idf.py -p /dev/ttyUSB0 monitor

para ver que trae la placa ya flasheado.

 

Step 9: Flash onto the device


idf.py -p /dev/ttyUSB0 flash


Step 10: Monitor 

 

Ya te lo había dicho:

idf.py -p /dev/ttyUSB0 monitor

Te agrego que se sale con control ]

 

Resultados

 

El ESP-WROOM-32 dijo que:

Failed to connect to ESP32: Wrong boot mode detected (0x13)!

Se corrije apretando el botón que dice "100" o parecido mientras 

Serial port /dev/ttyUSB0
Connecting.........

Los otros, de una.

 

Remapeo

 

Mirando la traza al fashear cada plaquita, puedo identificar mejor qué es qué, verde significa que le había acertado, amarillo que estaba cerca:

 

  • ESP32
    • ESP32-D0WD-V3
    • ESP32-D0WDQ6-V3
    • ESP32-D0WD
    • ESP32-D0WDQ6
      • ESP-WROOM-32
    • ESP32-D2WD
    • ESP32-S0WD
    • ESP32-U4WDH
  • ESP32-S2
    • ESP32-S2
      • WROVER-1
    • ESP32-S2FH2
    • ESP32-S2FH4
      • MINI-1
  • ESP32-S3
    • ESP32-S3
    • ESP32-S3FN8
    • ESP32-S3R2
    • ESP32-S3R8
    • ESP32-S3R8V
  • ESP32-C3
    • ESP32-C3
        • ESP32-C3-WROOM-02 
    • ESP32-C3FN4
    • ESP32-C3FH4

 

No te prometo que en breve publique la parte de seguridad, mientras, le pego un sensor de temperatura y lo mando por Internet.