Wer dem Autor auf Twitter [1] folgt, wird bereits gesehen haben, dass bei ihm ein paar ESP32-C3-DevKits auf dem Tisch liegen. Und diejenigen Leser, welche unsere Lab Notes vom Juni [2] gelesen haben, werden bereits wissen, dass der ESP32-C3 softwareseitig noch stetige Verbesserungen erfährt.

Vorab ein paar Hinweise zu diesem Artikel: Unsere DevKits haben noch einen ESP32-C3 Chip in der Revision 2 verbaut. Die DevKits werden noch mit einer beidseitig bedrucken A4-Seite geliefert, die auf die Probleme dieser Revision hinweist. Unter anderem sind das eine hohe Stromaufnahme in Deep-Sleep-Mode und ein Totalausfall des USB/JTAG-Adapters im Chip. Die kommende Revision 3 soll dieses beheben, wie aus dem Tweet unter [3] ersichtlich ist.

Auch die IDF wird laufend für den ESP32-C3 angepasst und kann noch Bugs enthalten. Da die Arduino-Unterstützung drauf aufbaut, können diese Bugs auch dort wiedergefunden werden. Zum Zeitpunkt, an dem dieser Artikel geschrieben wurde, musste der Development Release des Arduino Support Packages installiert werden.

Dazu muss der folgende Link unter Preference in die Additional Boards Manager URLs eingetragen werden: https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json. Damit wird momentan die Version 2.0.0-rc1 installiert.

Wer nun ein ESP32-C3 basiertes Kit kauft, sollte eine Revision 3 des Chips erhalten, wie aus dem Forumseintrag von ESP32.com [4] zu sehen ist. Die Revision 2 wurde nur in geringen Stückzahlen für die ersten DevKits verwendet.

 

Das ESP32-C3-DevKitC-02

Zuerst sollen der ESP32-C3 und das DevKitC-02 (Bild 1) vorgestellt werden. Bei dem ESP32-C3 handelt es sich um einen Nachfolger für den ESP8266. Auch hier wird ein einzelner Prozessorkern verwendet, der mit bis zu 160 MHz getaktet werden kann und WiFi im 2,4-GHz-Band nach BGN beherrscht. An der Stelle hören die Gemeinsamkeiten mit dem ESP8266 auch schon auf. Der ESP32-C3 hat von seinem größeren Verwandten, dem ESP32, einen Großteil der Peripherie bekommen. Damit beherrscht der Chip neben WiFi auch BLE 5.0 und Bluetooth Mesh. Zusätzlich bringt er die liebgewonnene IO-Matrix mit, so dass wir fast jede Funktion mit fast jedem Pin nutzen können. Bild 2 zeigt das Blockdiagramm des ESP32-C3, inklusive des USB-Seriell/JTAG-Adapters.

Bild 1. ESP32-C3-DevKitC-02.
Bild 2. ESP32-C3 Blockdiagramm.

Auch bei den anderen Funktionen im Chip ist klar zu erkennen, dass diese aus dem ESP32 stammen. Tabelle 1 zeigt eine Übersicht der Funktionen. Mit seinen 384 kB an RAM bietet der ESP32-C3 etwa fünf Mal mehr RAM als der ESP8266 (80 kB). Etwas was den ESP32-C3 von allen anderen ESP32- oder ESP8266-Chips unterscheidet ist der verwendete Prozessorkern. Während alle Vorgänger auf einem Tensilica L106 oder LX6/LX7 [5] basieren, steckt im ESP32-C3 ein Prozessorkern mit RISC-V Befehlssatz. Das bedeutet, dass für diesen Kern bestehende Compiler aus dem RISC-V-Ökosystem verwendet werden können. Verbesserungen dieser Compiler und der entsprechenden Tools stehen damit dem ESP32-C3 offen. Es muss nicht erst wie beim ESP8266 eine Toolchain durch die Community geschaffen werden.
 

Auf dem DevKitC-02 selbst ist gezwungenenmaßen ein USB-Seriell-Wandler verbaut, sowie eine WS2812-kompatible RGB-LED. Eine genaue Übersicht der Komponenten kann dem Schaltplan [6] für das Board entnommen werden. Bild 3 zeigt das ESP32-C3-DevKitC-02 von der Oberseite und der Unterseite.

Bild 3. Ober- und Unterseite des ESP32-C3-DevKitC-02.

Das etwas andere Blinky-Beispiel

Wie schon erwähnt ist eine WS2812-kompatible RGB-LED verbaut, so dass es mit dem Setzen eines IO-Pins nicht getan ist, um die LED zum Leuchten zu bringen. In Verbindung mit der Arduino IDE kann aber der NeoPixel-Bibliothek von Adafruit verwendet werden. Der Code in Listing 1 lässt die RGB-LED rot blinken, besondere Anpassungen für den ESP32-C3 scheinen nicht nötig zu sein. Auch der Upload erfolgt genauso einfach wie bei einem ESP32. Durch die IO-Matrix können auch an anderen Pins WS2812-LEDs betrieben werden.

 

Chip-Typ und Version auslesen

Bei den ESP32-Chips lassen sich grundlegende Eigenschaften des Chips auslesen. Das Listing 2 gibt die Informationen auf der seriellen Schnittstelle bei 115200 Baud aus (mit 9600 Baud hat der Chip in Revision 2 und mit dem verbauten USB-Seriell-Wandler verstümmelte Zeichen ausgegeben). Wer sich ein ESP32-C3 Kit zulegt, kann so sehen, welche Chiprevision vorliegt. Vor allem wer einen Blick in die Errata eines Chips wirft, wird froh sein, wenn er sein Exemplar klar den Bugs zuordnen kann.

 

Portierung von ESP32-Projekten

Mit die interessantesten Funktionen des ESP32-C3 sind sicherlich WiFi und BLE. Viele werden bei ihren WiFi-Projekten auch SPIFFS oder littlefs verwenden, um Webseiten oder andere Daten auf dem ESP32 zu verwalten. Wer mit der Arduino IDE 1.X unterwegs ist, sollte sich eine gepatchte Version [7] für den Uploader installieren, da die Originalversion von me-no-dev [8] nicht mit dem ESP32-C3 zusammenarbeitet.

Als Beispiel haben wir den Code [9] des ESP32 Mini-NTP-Servers [10] verwendet. Dieser kann im eigenen Netzwerk die Uhrzeit per NTP bereitstellen und ist für das Arduino-Framework geschrieben. Nach ein paar Anpassungen der Pins lässt sich der Code ohne Probleme kompilieren und auf den ESP32-C3 hochladen. Damit lässt sich viel Code und Wissen vom ESP32 auf dem ESP32-C3 transportieren, und auch Neulinge brauchen vor diesem Chip keine Angst haben. Die meisten Beispiele für den ESP32 laufen auch auf dem ESP32-C3; und da auch hier ein FreeRTOS im Hintergrund werkelt, kann wie bei einem ESP32 mit allen Vor- und Nachteilen des FreeRTOS gearbeitet werden.

Da der ESP32-C3 im Moment nur durch den Developer-Zweig des Arduino-Frameworks für die ESP32-Chips unterstützt wird, haben noch nicht alle IDEs eine volle Unterstützung für den Chip. Mit dem Fortschreiten des Frameworks für den ESP32 wird diese aber früher oder später Einzug halten.

 

Zusammenfassung

Mit dem ESP32-C3 steht eine kostengünstige Alternative zum ESP8266 bereit, die einen Großteil an Peripherie des ESP32 erhalten hat. Mit dem integrierten USB/Seriell- und JTAG-Adapter kann der Chip über USB Daten austauchen. Es lässt sich sogar das Debuggen von Code starten (sollten in der Revision 3 nicht noch unvorhergesehene Dinge auftreten...).

Bestehenden Code kann man dank des Arduino-Frameworks mit dem ESP32-C3 verwenden und die Menge an RAM und Flash erlaubt es auch, größere Projekte mit dem Chip umzusetzen. Wir sind gespannt, wann die ersten ESP32-C3 Boards von Drittanbietern in den europäischen Shops erscheinen und welche Funktionen diese bieten werden. Wer schon ein ESP32-DevKitC-02 zuhause hat, kann bis dahin schon einmal anfangen, Code zu schreiben und zu testen. Die Arduino-Sketche zu den Listings finden Sie auf unserer GitHub-Seite [11].

 

Tabelle 1. Spezifikationen des ESP32-C3.

  • RISC-V CPU mit 160 MHz
  • 400 KB SRAM ( 16 KB als Flash Cache )
  • Integriertes 2,4-GHz-WLAN (BGN)
  • Bluetooth LE 5.0
  • Kryptographische Hardware-Beschleunigung
  • 22 programmierbare GPIOs
  • 2 x 12-Bit-SAR ADC
  • 3 x SPI (unterstützt SPI, Dual SPI, Quad SPI und QPI)
  • 2 x UART (unterstützt RS232, RS485 IrDA mit bis zu 5 MBd)
  • 1 x I2C (bis zu 800 kbit/s)
  • 1 x I2S
  • RMT (Fernsteuerungs-Peripheriegeräte)
  • TWAI (CAN 2.0 b kompatibel / ISO 11898-1)
  • PWM
  • Interner USB/JTAG-Adapter
 

Listing 1. Blinky.

/* This sample needs the Adafruit NeoPixel library */

#include <Adafruit_NeoPixel.h>
#define PIN        8
#define NUMPIXELS  1

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

 

void setup() {
    pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
    pixels.clear(); // Set all pixel colors to 'off'
}

 

void loop() {
    delay(1000);                       // wait for a second
        pixels.setPixelColor(0, pixels.Color(255, 0, 0));
        pixels.show();   
    delay(1000);                       // wait for a second
        pixels.setPixelColor(0, pixels.Color(0, 0, 0));
        pixels.show();   
}

 

Listing 2. Auslesen der Chiprevision.


/* From the IDF documentation at https://github.com/espressif/esp-idf/components/esp_hw_support/include/esp_chip_info.h */
/*  
 typedef enum {
    CHIP_ESP32  = 1, //!< ESP32
    CHIP_ESP32S2 = 2, //!< ESP32-S2
    CHIP_ESP32S3 = 4, //!< ESP32-S3
    CHIP_ESP32C3 = 5, //!< ESP32-C3
    CHIP_ESP32H2 = 6, //!< ESP32-H2
} esp_chip_model_t;

// Chip feature flags, used in esp_chip_info_t
#define CHIP_FEATURE_EMB_FLASH      BIT(0)      //!< Chip has embedded flash memory
#define CHIP_FEATURE_WIFI_BGN       BIT(1)      //!< Chip has 2.4GHz WiFi
#define CHIP_FEATURE_BLE            BIT(4)      //!< Chip has Bluetooth LE
#define CHIP_FEATURE_BT             BIT(5)      //!< Chip has Bluetooth Classic
#define CHIP_FEATURE_IEEE802154     BIT(6)      //!< Chip has IEEE 802.15.4

typedef struct {
    esp_chip_model_t model;  //!< chip model, one of esp_chip_model_t
    uint32_t features;       //!< bit mask of CHIP_FEATURE_x feature flags
    uint8_t cores;           //!< number of CPU cores
    uint8_t revision;        //!< chip revision number
} esp_chip_info_t;

*/

 

void setup() {
    Serial.begin(115200);
}

 

void loop() {
    delay(5000);
    Serial.println("esp_chip_info()");
    Serial.println("-------------------------------------------------------------");
    esp_chip_info_t info;
    esp_chip_info(&info);
    Serial.print("Chip Model: ");
    switch(info.model){
        case 1:{
            Serial.println("ESP32");
        }break;

        case 2:{
            Serial.println("ESP32-S2");
        }break;

        case 4:{
            Serial.println("ESP32-S3");
        }break;

        case 5:{
            Serial.println("ESP32-C3");
        }break;

        case 6:{
            Serial.println("ESP32-H2");
        } break;

        default:{
            Serial.print("Unknown Chipmodel");
            Serial.println(info.model);
        }   
    }
 

    Serial.print("Featues :");
    if(info.features&CHIP_FEATURE_EMB_FLASH){
        Serial.print(" Embedded Flash ");
    }
    if(info.features&CHIP_FEATURE_WIFI_BGN){
        Serial.print(" WiFi(BGN) ");
    }
    if(info.features&CHIP_FEATURE_BLE){
        Serial.print(" BLE ");
    }
 
    if(info.features&CHIP_FEATURE_BT){
        Serial.print(" BT CLassic ");
    }

    if(info.features&CHIP_FEATURE_IEEE802154){
        Serial.print(" IEEE802.155.4 ");
    }
    Serial.println("");
    Serial.print("Cores: ");
    Serial.println(info.cores);
    Serial.print("Chip Revision: ");
    Serial.println(info.revision);
    Serial.println("-------------------------------------------------------------");
    Serial.println();

}

 

Sie haben Fragen oder Kommentare?

Haben Sie technische Fragen oder Kommentare zu diesem Artikel? Schicken Sie eine E-Mail an den Autor unter mathias.claussen@elektor.com oder kontaktieren Sie Elektor unter editor@elektor.com.