Actions

Kamod ESP32-C3 (PL)

From Kamamilabs.com - Wiki

Opis

Kamod ESP32-C3 - Płytka rozwojowa z układem ESP32-C3 Mini-1
Kamod ESP32-C3 jest układem opartym na zintegrowanym module mikrokontrolera ESP32-C3 Mini-1 firmy Espressif. ESP32-C3 Mini-1 zawiera 32-bitowy jednordzeniowy mikrokontroler SoC o architekturze RISC-V i maksymalnej częstotliwości taktowania 160 MHz. Dzięki 22 konfigurowalnym wejściom GPIO, 400 KB wewnętrznej pamięci RAM i obsłudze trybu niskiego zużycia energii, może być stosowany w różnych zastosowaniach związanych na przykład z układami IoT, systemami nadzoru lub sterowania. MCU jest dostępny w wielu wariantach ze zintegrowaną i zewnętrzną pamięcią flash. Wysoka maksymalna temperatura pracy sprawia, że idealnie nadaje się do zastosowań przemysłowych. Możliwości stosowania ESP32- C3 znacznie poszerzają wbudowane radiowe interfejsy Wi-Fi i Bluetooth 5 (LE) z obsługą dalekiego zasięgu (LR). Bezpieczeństwo aplikacji zapewniają funkcje bezpiecznego rozruchu oparty na RSA-3072 i szyfrowanie flash z AES-128/256-XTS.

Moduł Kamod ESP32 C3 jest przeznaczony do uruchomiania i testowania własnych aplikacji na przykład w środowisku Arduino, lub w języku Rust . Pomocne w tym mogą być umieszczone na płytce modułu układy peryferyjne: dokładny czujnik temperatury i wilgotności SHTC3, oraz czujnik MEMS typu ICM42670 zawierający 3-osiowy żyroskop i 3-osiowy akcelerometr. Dodatkowo do testów można wykorzystać diodę LED podłączoną do jednego z portów mikrokontrolera i programowaną 3-kolorową diodę WS28212.

Moduł jest zasilany napięciem +5V dostarczanym przez złącze USB-C, lub napięciem z baterii Li-Jon. Napięcie +3,3V zasilające mikrokontroler i układy peryferyjne wytwarza przetwornica Buck DC/DC typu SY8088 o napięciu wejściowym z zakresu 2.5….5V. Po zaniku napięcia ze złącza USB-C zasilanie przełącza się automatycznie na baterię (jeżeli jest podłączona). Układ zasilania bateryjnego jest uzupełniony o ładowarkę baterii Li-Jon opartą o układ MCP7383 zasilany z napięcia VBUS +5V pochodzącego ze złącza USB-C.



Podstawowe cechy i parametry

  • Moduł ESP32C3 Mini-1
  • IEEE 802.11 b/g/n-compliant
  • Bluetooth 5, Bluetooth
  • 32-bit RISC-V jednordzeniowy taktowanie do160MHz
  • 384 KB ROM
  • 400 KB SRAM (16 KB pamięć cache)
  • 8 KB SRAM dla modułu RTC
  • 22 × programowanych linii GPIO
  • 3 × SPI
  • 2 × UART
  • 1 × I2C
  • 1 × I2S
  • 2 × 54-bit uniwersalnych timerów
  • 3 × watchdog timers
  • 1 × 52-bit system timer
  • Remote Control Peripheral (RMT)
  • LED PWM controller (LEDC)
  • Full-speed USB Serial/JTAG controller
  • General DMA controller (GDMA)
  • 1 × TWAI®
  • 2 × przetwornik 12-bit SAR ADCs, do 6 kanałów
  • 1 × sensor temperatury
  • Akcelerometr ICM42670
    • Trójosiowy żyroskop MEMS Czujniki prędkości kątowej osi X, Y i Z z wyjściem cyfrowym (z programowalnym zakresem pełnej skali ±250, ±500, ±1000 i ±2000 stopni/sek.
    • Trójosiowy akcelerometr MEMS osi X, Y i Z z wyjściem cyfrowym i programowalnym zakresem pełnej skali ±2 g, ±4 g, ±8 g i +16 g
    • Zasilanie od+1.7V do +3,3V
    • Interfejs komunikacyjny I3C, I2C, SPI
  • Termometr/higometr SHTC3
    • Zakres pomiaru wilgotności 0…100%RH z dokładnością +/- 2%
    • Zakres pomiaru temperatury -40 do +125 °C. Dokładność pomiaru +/-0.2°C w zakresie od 0°C do +60°C
    • Napięcie zasilania od+1.6V do +3,6V
    • Interfejs komunikacyjny I2C
  • Przetwornica DC/DC SY8088
  • Układ ładowarki baterii Li-JON MCP73831
  • Programowana dioda WS2812
  • Złącze USB-C
    • Zasilanie modułu napięciem +5V
    • Interfejs programujący pamięć Flash mikrokontrolera
    • Interfejs JTAG
  • Przyciski Reset i Boot

Wyposażenie standardowe

Kod Opis
KAmod ESP32-C3

Zmontowany i uruchomiony moduł
1 x prosta listwa goldpin 12-pin raster 2,54 mm 1 x prosta listwa goldpin 16-pin raster 2,54 mm


Schemat elektryczny


Opis wyprowadzeń



Zasilanie układu

Standardowo moduł jest zasilany napięciem VBUS o wartości +5V ze złącza USB-C. To napięcie jest również wykorzystywane do ładowania pojedynczej celi baterii Li-Jon podłączonej do wyjścia Charger. Ładowaniem zajmuje się układ MCP7381 wykorzystujący algorytm ładowania o stałym natężeniu prądu/stałym napięciu z możliwością wyboru wstępnego kondycjonowania i zakończenia ładowania. Stała regulacja napięcia jest ustalona za pomocą czterech dostępnych opcji: 4,20 V, 4,35 V, 4,40 V lub 4,50. Stała wartość prądu jest ustawiana za pomocą jednego zewnętrznego rezystora. W naszym przypadku prąd ładowania to 100mA, a napięcie wyjściowe 4,20V.


Konfiguracja środowiska Arduino i program testowy


Czynności wstępne

Podłączany moduł Kamod ESP-C3 do komputera z zainstalowanym środowiskiem Arduino IDE. W oknie wyboru modułu wybieramy moduł ESP32C3 Dev Module i wirtualny port szeregowy COMx z którym moduł jest połączony.

W naszej procedurze testowej będziemy używali okna terminala, w którym będą wyświetlanie wyniki działania programu. Żeby to było możliwe trzeba odblokować domyślnie zablokowaną opcję USB CDC On Boot


Konfiguracja okna preferences

Otwieramy okno preferencji File->Preferences. W polu Additional boards manager ULRs zakładki Settings wpisujemy adres https://dl.espressif.com/dl/package_esp32_index.json



Wybór typu procesora dla programowanego modułu

Wybieramy kolejno zakładkę Tools, następnie Board, rodzinę procesorów esp32 i moduł z procesorem ESP32C3. Każda zmiana modułu podłączonego do komputera przez USB będzie wymagała powtórzenia tego kroku. Jeżeli nie wykonamy go na początku, to można go wykonać przed kompilacją. W przeciwnym razie projekt nie zostanie prawidłowo skompilowany.

Instalowanie bibliotek

Program testowy wymaga zainstalowania bibliotek obsługujących układy peryferyjne: akcelerometr ICM42670P, termometr/higrometr SHTC3 i 3-kolorową diodę LED typu WS2812B.

Instalowanie biblioteki do obsługi układu ICM42670P

Klikamy na pionowym pasku narzędzi ikonę bibliotek. W oknie wyszukiwanie wpisujemy ICM42670, wybieramy ICM42670P by TDK/Invensense i klikamy Install.


Instalowanie biblioteki do obsługi układu SHTC3

Wybieramy bibliotekę Adafruit SHTC3 Library dostarczaną przez Adafruit. Ta biblioteka wymaga doinstalowania koniecznych współpracujących z nią innych bibliotek. Aby to zrobić w wyskakującym dodatkowym oknie Install library dependencies klikamy Install All.


Instalowanie biblioteki obsługującej 3-kolorową diodę RGB typu WS2812

Do sterowania 3-kolorowej diody RGB wykorzystamy bibliotekę dostarczana przez Adafruit - Adafruit NeoPixel


Obsługa akcelerometru ICM42670P

ICM42670P jest połączony z mikrokontrolerem za pomocą magistrali I2C. Do jej obsługi jest przeznaczona biblioteka Wire. Do inicjowania interfejsu I2S jest używana metoda begin z argumentami określającymi linie portów przypisane do sygnałów SDA i SCL

#define I2C_SDA 10              //SDA IO10
#define I2C_SCL 8               //SCL IO8
Wire.begin(I2C_SDA, I2C_SCL);


Obsługa termometru/higrometru SHTC3

Układ SHTC3 łączy się z mikrokontrolerem również za pomocą interfejsu I2C. Konfiguracja i inicjacja tego interfejsu została pokazana powyżej. Inicjalizacja biblioteki układu SHTC3 jest wykonywana standardowo przez metodę begin.

shtc3.begin();

Odczytywanie i konwersję wartości temperatury wykonuje metoda htc3.getEvent

htc3.getEvent(&humidity, &temp); // read temp and humidity

Dane wyjściowe są umieszczane w zmiennych temp.temperature i humidity.relative_humidity i można je bezpośrednio wyświetlić.

Przykładowy wydruk odczytanych danych z czujnika SHTC3 na konsoli znakowej Arduino IDE


Obsługa diody RGB WS2812B

Tworzymy instancję WS2812B, w której określamy: ilość diod WS2812 połączonych w łańcuchu (NUM_PIXELS), oraz numer portu linii danych (PIN_WS2812B). Pozostałe parametry można zostawić domyślnie. U nas jest jedna dioda (NUM_PIXELS = 1) podłączona do linii poru DO2 (PIN_WS2812B =2)

#define PIN_WS2812B  2          // ESP32 pin that connects to WS2812B
#define NUM_PIXELS     1        // The number of LEDs (pixels) on WS2812B
Adafruit_NeoPixel WS2812B(NUM_PIXELS, PIN_WS2812B, NEO_GRB + NEO_KHZ800);

Inicjalizacja drivera jest standardowo wykonywana przez metodę begin:

WS2812B.begin();              //WS2812 driver config

Metoda setBrightness służy do ustawiania jasności świecenia wszystkich diod

WS2812B.setBrightness(50);    //WS8212 brightness

Metoda clear wygasza wszystkie diody, a metoda setPixelColor określa składowe koloru dla każdej z diod.

WS2812B.setPixelColor(0, WS2812B.Color(255, 0, 0)); //kolor czerwony

Skutki działania metod clear i setPixelColor są widoczne po wywołaniu metody show:

WS2812B.show();

Sprawdzanie działania modułu WiFi

Procedura testowa sprawdzająca działanie modułu WiFi polega na skanowaniu radiowej sieci WiFi i wyświetlaniu znalezionych identyfikatorów SSID lokalnych sieci wraz z poziomem sygnału radiowego, kanałem radiowym oraz rodzajami szyfrowania danych.
Najpierw jest ustawiany tryb WIFI_STA, czyli tryb stacji. W tym trybie moduł ESP32 może się łączyć z sieciami WIFI. Po połączeniu z ruterem moduł może żądać informacji z Internetu (jeżeli ruter jest połączony z Internetem), lub z urządzeń z lokalnej sieci rutera. Po ustawieniu tego trybu wykonujemy ewentualne rozłączenie z siecią (jeżeli moduł był wcześniej połączony):

WiFi.mode(WIFI_STA); //station mode

WiFi.disconnect();         //disconnect WIFI network


Możemy teraz skanować identyfikatory sieci WIFI za pomocą metody scanNetworks
Metoda zwraca ilość wykrytych sieci wspomniane już parametry: poziom sygnału radiowego, kanał radiowy oraz rodzaj szyfrowania danych.

numNetworks = WiFi.scanNetworks(); //scan WIFI networks </nowiki>
  Serial.println("Scan done");
  if (numNetworks == 0)
  {
    Serial.println("no networks found");
  }

Po wykonaniu skanowania można wyświetlić odczytane dane w konsoli i wykorzystać do w naszej aplikacji na przykład w celu połączenia z wybraną siecią.

for (int i = 0; i < numNetworks; ++i) {
      // Print SSID and RSSI for each network found
      Serial.printf("%2d", i + 1);
      Serial.print(" | ");
      Serial.printf("%-32.32s", WiFi.SSID(i).c_str());
      Serial.print(" | ");
      Serial.printf("%4ld", WiFi.RSSI(i));
      Serial.print(" | ");
      Serial.printf("%2ld", WiFi.channel(i));
      Serial.print(" | ");
      switch (WiFi.encryptionType(i)) {
        case WIFI_AUTH_OPEN:            Serial.print("open"); break;
        case WIFI_AUTH_WEP:             Serial.print("WEP"); break;
        case WIFI_AUTH_WPA_PSK:         Serial.print("WPA"); break;
        case WIFI_AUTH_WPA2_PSK:        Serial.print("WPA2"); break;
        case WIFI_AUTH_WPA_WPA2_PSK:    Serial.print("WPA+WPA2"); break;
        case WIFI_AUTH_WPA2_ENTERPRISE: Serial.print("WPA2-EAP"); break;
        case WIFI_AUTH_WPA3_PSK:        Serial.print("WPA3"); break;
        case WIFI_AUTH_WPA2_WPA3_PSK:   Serial.print("WPA2+WPA3"); break;
        case WIFI_AUTH_WAPI_PSK:        Serial.print("WAPI"); break;
        default:                        Serial.print("unknown");
      }
      Serial.println();
      delay(10);
    }
  }

Przykładowy wydruk działania programu skanującego sieć WIFI na konsoli znakowej Arduino IDE


Po wykonaniu skanowania i wyświetleniu danych trzeba wyczyścić dane, żeby przygotować moduł WiFi do kolejnego skanowania – metoda scanDelete

WiFi.scanDelete();

Program testowy

Program testowy ma zadanie przetestować wszystkie komponenty umieszczone na płytce modułu. Test składa się z kolejnych kroków:

  • Zapaleniu diody czerwonej LED podłączonej do linii portu IO7
  • Odczytaniu i wyświetleniu w konsoli Arduino IDE odczytanych danych z ICM42670P
  • Odczytaniu i wyświetleniu w konsoli Arduino IDE odczytanych danych z SHTC3
  • Skanowaniu sieci WIFI i wyświetleniu w konsoli Arduino IDE identyfikatorów SSID siłę sygnału radiowego, numer kanału WIFI i rodzaj kodowania danych w sieci dla każdej ze znalezionych sieci
  • Zgaszeniu czerwonej diody LED
  • Zapaleniu co 0,5 sekundy kolejnych diod WS2812B czerwonej, zielonej i niebieskiej
  • Zgaszeniu wszystkich diod WS2812B i rozpoczęciu testu od nowa


Poniżej pokazany jest fragment ekranu konsoli znakowej Arduino IDE wyświetlający jeden przebieg programu testowego.


Kod programu testowego znajduje się poniżej, można go skompilować w środowisku Arduino.

#include "WiFi.h"
#include<Wire.h>               //I2s DRIVER
#include <Adafruit_NeoPixel.h>//RGB diode WS2812
#include "Adafruit_SHTC3.h"
#include "ICM42670P.h"          //ICM42670P driver

#define LED_BUILTIN 7           //LED IO7 to flash 

#define I2C_SDA 10              //SDA IO10 
#define I2C_SCL 8               //SCL IO8
#define PIN_WS2812B  2          // ESP32 pin that connects to WS2812B
#define NUM_PIXELS     1        // The number of LEDs (pixels) on WS2812B

Adafruit_NeoPixel WS2812B(NUM_PIXELS, PIN_WS2812B, NEO_GRB + NEO_KHZ800);
ICM42670 IMU(Wire,0);           //I2S addres 0x68
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();


void setup() {

    //WS28212 setup   
    WS2812B.begin();              //WS2812 driver config
    WS2812B.setBrightness(50);    //WS8212 brightness
    //LED flash setup 
    pinMode(LED_BUILTIN, OUTPUT);  //IO7 output 
    //serial setup
     Serial.begin(115200);
     delay(2000);
     while(!Serial);                 //wait to serial ready  
    //I2S line setup 
    Wire.begin(I2C_SDA, I2C_SCL);                    //setup I2S driver
    IMU.begin();                                      //setup ICM42670P driver
    // Start accelerometer and gyroscope
    IMU.startAccel(100, 16); // 100 Hz, ±16g
    IMU.startGyro(100, 2000); // 100 Hz, ±2000 dps
    shtc3.begin();
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);
    
}
void loop()
 {
  int numNetworks;
  sensors_event_t humidity, temp;
  inv_imu_sensor_event_t imu_event;
   digitalWrite (LED_BUILTIN, HIGH);
  //ICM42670P register read, convert and 
  Serial.print("\n");
   Serial.print("********************************");
   Serial.print("\n");
  int ret = IMU.getDataFromRegisters(imu_event);   //ICM42670P register read 
  Serial.println(ret);
  if (ret == 0) {
// Convert acceleration to g
  float accelX = imu_event.accel[0] / 2048.0;
  float accelY = imu_event.accel[1] / 2048.0;
  float accelZ = imu_event.accel[2] / 2048.0;

// Convert gyroscope to dps
  float gyroX = imu_event.gyro[0] / 16.4;
  float gyroY = imu_event.gyro[1] / 16.4;
  float gyroZ = imu_event.gyro[2] / 16.4;
//print converted result
  Serial.print("ICM42670P AccelX:");
  Serial.println(accelX);
  Serial.print("ICM42670P AccelY:");
  Serial.println(accelY);
  Serial.print("ICM42670P AccelZ:");
  Serial.println(accelZ);
  Serial.print("********************************");
  Serial.print("\n"); 
  Serial.print("ICM42670P GyroX:");
  Serial.println(gyroX);
  Serial.print("ICM42670P GyroY:");
  Serial.println(gyroY);
  Serial.print("ICM42670P GyroZ:");
  Serial.println(gyroZ);
  Serial.print("********************************");
   Serial.print("\n");
  Serial.print("ICM42670PTemperature:");
  Serial.println((imu_event.temperature/128.0)+25.0);
  Serial.print("********************************");
  Serial.print("\n");
}
  Serial.print("SHTC3P register read.........:");
  Serial.print("\n");
  Serial.print("********************************");
  Serial.print("\n");
  shtc3.getEvent(&humidity, &temp);// read temp and humidity 
  
  Serial.print("SHTC3 Temperature: "); Serial.print(temp.temperature); Serial.println(" deg C");
  Serial.print("SHTC3 Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");
  Serial.print("********************************");
  Serial.print("\n");
      numNetworks = WiFi.scanNetworks();
  
    Serial.println("Scan done");
  if (numNetworks == 0) {
    Serial.println("no networks found");
  } else {
    Serial.print(numNetworks);
    Serial.println(" networks found");
    Serial.println("Nr | SSID                             | RSSI | CH | Encryption");
    for (int i = 0; i < numNetworks; ++i) {
      // Print SSID and RSSI for each network found
      Serial.printf("%2d", i + 1);
      Serial.print(" | ");
      Serial.printf("%-32.32s", WiFi.SSID(i).c_str());
      Serial.print(" | ");
      Serial.printf("%4ld", WiFi.RSSI(i));
      Serial.print(" | ");
      Serial.printf("%2ld", WiFi.channel(i));
      Serial.print(" | ");
      switch (WiFi.encryptionType(i)) {
        case WIFI_AUTH_OPEN:            Serial.print("open"); break;
        case WIFI_AUTH_WEP:             Serial.print("WEP"); break;
        case WIFI_AUTH_WPA_PSK:         Serial.print("WPA"); break;
        case WIFI_AUTH_WPA2_PSK:        Serial.print("WPA2"); break;
        case WIFI_AUTH_WPA_WPA2_PSK:    Serial.print("WPA+WPA2"); break;
        case WIFI_AUTH_WPA2_ENTERPRISE: Serial.print("WPA2-EAP"); break;
        case WIFI_AUTH_WPA3_PSK:        Serial.print("WPA3"); break;
        case WIFI_AUTH_WPA2_WPA3_PSK:   Serial.print("WPA2+WPA3"); break;
        case WIFI_AUTH_WAPI_PSK:        Serial.print("WAPI"); break;
        default:                        Serial.print("unknown");
      }
      Serial.println();
      delay(10);
    }
  }
    WiFi.scanDelete();
    digitalWrite (LED_BUILTIN, LOW);
    WS2812B.clear();  // set all pixel colors to 'off'. It only takes effect if pixels.show() is called
    WS2812B.setPixelColor(0, WS2812B.Color(255, 0, 0));  // it only takes effect if pixels.show() is called
    WS2812B.show();    
    delay(500); 
    WS2812B.setPixelColor(0, WS2812B.Color(0, 255, 0));  // it only takes effect if pixels.show() is called
    WS2812B.show(); 
    delay(500); 
    WS2812B.setPixelColor(0, WS2812B.Color(0, 0, 255));  // it only takes effect if pixels.show() is called
    WS2812B.show(); 
    delay(500); 
     WS2812B.clear();  // set all pixel colors to 'off'. It only takes effect if pixels.show() is called
     WS2812B.show(); 
    delay(100);  // 500ms pause between each pixel
  //}
}

Konfiguracja środowiska do programowania w języku Rust i programy testowe

Najpierw pokażemy, jak szybko pobrać i skonfigurować niezbędne komponenty i narzędzia programowe do wygenerowania prostego projektu w języku Rust. Po skonfigurowaniu narzędzi będzie można projekt skompilować i przesłać do pamięci flash. Wszystkie czynności są wykonywane w systemie operacyjnym Linux Ubuntu wersja 24.04.2 LTS. Komputer musi być podłączony do Internetu.

Włączenie repozytorium Universe

"Universe" to standardowe repozytorium dla Ubuntu. Repozytorium jest utrzymywane przez społeczność i zapewnia bezpłatne oprogramowanie typu open source. Domyślnie jest włączone w najnowszych wersjach Ubuntu. Jednak, gdyby tak nie było to możemy go włączyć za pomocą wiersza poleceń:


Instalacja pakietów libssl-dev, libudev, kompilatora C/C++ clang i interpretera Python 3

Pakiet libssl-dev zawiera protokoły kryptograficzne SSL i TLS do bezpiecznej komunikacji przez Internet. Pakiet libudev udostępnia interfejs API do introspekcji i wyliczania urządzeń na poziomie lokalnym system. Clang jest kompilatorem języków programowania C, C++ i Objective-C i jest częścią projektu LLVM. Znany z szybkiego czasu kompilacji i doskonałej diagnostyki, Clang może również działać jako zamiennik GCC. W projekcie jest używany linker Clang. Python3-pip jest pakietem instalacyjnym języka Python ver3, a python3-venv instaluje środowisko wirtualne.


Instalacja pakietów Rust i menadżera Cargo

Rust to język programowania ogólnego przeznaczenia, kładący nacisk na wydajność, bezpieczeństwo typów i współbieżność. Cargo to menedżer pakietów Rust. Cargo pobiera zależności pakietu Rust, kompiluje pakiety, tworzy pakiety dystrybucyjne i przesyła je do crates.io, rejestru pakietów społeczności Rust.


Instalacja niezbędnych modułów Cargo:

  • espflash potrzebny do programowania pamięci Flash mikrokontrolera
  • ldproxy  przekazanie argumentów konsolidatora
  • cargo-generate do generowania projektów według szablonu


Tworzenie projektu


Wykonanie tego polecenia otwiera okno uproszczonego menadżera projektu. Menadżer poprosi nas o:

  • wpisanie nazwy projektu na przykład test-modulu-esp32c3
  • wybranie z listy typu MCU – w naszym przypadku będzie to ESP32C3
  • wybranie wersji ESP-IDF wybieramy v5.3


Pozostałe opcje można wybrać tak jak na rysunku poniżej


Po wybraniu wszystkich opcji menadżer projektu utworzy katalog o nazwie projektu, w którym umieści niezbędne pliki. W katalogu src projektu menadżer umieści plik źródłowy main.rs ze szkieletem wczytanym poleceniem cargo generate.

W tym momencie mamy już wszystko, żeby wyedytowany plik main.rs kompilować, przesyłać swój program do pamięci flash i uruchamiać jego działanie. Wszystkie te czynności są wykonywane automatycznie po wykonaniu polecenie.


Jeżeli wykonujemy to pierwszy raz to polecenie będzie pobierało z sieci szereg niezbędnych komponentów i może to trochę potrwać.

Testowanie modułu – miganie diody D2 podłączonej do portu IO7

Na poniższym listingu jest wersja źródłowa programu cyklicznie zapalającego i gaszącego diodę LED co 500msek. Należy go umieścić w pliku main.rd (katalog src) i wykonać polecenie cargo run.

use esp_idf_svc::hal::{delay::FreeRtos, gpio::PinDriver, peripherals::Peripherals};
//use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
fn main() {
	// It is necessary to call this function once. Otherwise some patches to the runtime
	// implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
	esp_idf_svc::sys::link_patches();
let peripherals = Peripherals::take().expect("Failed to take peripherals");
	let mut led = PinDriver::output(peripherals.pins.gpio7).expect("Failed to create led driver");
	loop {
		led.toggle().expect("Failed to toggle LED");
		FreeRtos::delay_ms(500);
	}
}


Testowanie modułu – odczyt danych z termometru SHTC3 i akceleratora ICM42670

Podobnie jak w poprzednim przykładzie należy wpisać do pliku poniższa wersję źródłową i wykonać polecenia cargo run.

use esp_idf_svc::hal::{
	delay::FreeRtos,
	i2c::{I2cConfig, I2cDriver},
	prelude::*,
};
//use esp_idf_sys as _;
use icm42670::{accelerometer::vector::F32x3, prelude::_accelerometer_Accelerometer, Address};
use shtcx::{Measurement, PowerMode::*};

fn main() {
	esp_idf_svc::sys::link_patches();

	let peripherals = Peripherals::take().expect("Failed to take peripherals");

	let i2c_config = I2cConfig::new()
		.baudrate(100.kHz().into())
		.sda_enable_pullup(true)
		.scl_enable_pullup(true);

	let shared_bus = shared_bus::BusManagerSimple::new(
		I2cDriver::new(
			peripherals.i2c0,
			peripherals.pins.gpio10,
			peripherals.pins.gpio8,
			&i2c_config,
		)
		.expect("Failed to create i2c driver"),
	);

	let mut shtc3 = shtcx::shtc3(shared_bus.acquire_i2c());
	let mut icm42670 = icm42670::Icm42670::new(shared_bus.acquire_i2c(), Address::Primary)
		.expect("Failed to instantiate icm42670");

	loop {
		let Measurement {
			temperature,
			humidity,
		} = shtc3
			.measure(NormalMode, &mut FreeRtos)
			.expect("Failed to read SHTC3 temp/hum");

		println!(
			"SHTC3:\n\t- temp: {}\n\t- hum: {}",
			temperature.as_degrees_celsius(),
			humidity.as_percent()
		);

		let temp = icm42670
			.temperature()
			.expect("Failed to read ICM42670 temp");

		let F32x3 {
			x: ax,
			y: ay,
			z: az,
		} = icm42670
			.accel_norm()
			.expect("Failed to read ICM42670 accel data");

		let F32x3 {
			x: gx,
			y: gy,
			z: gz,
		} = icm42670
			.gyro_norm()
			.expect("Failed to read ICM42670 gyro data");

		println!(
			"ICM42670:\n\t- temp: {}\n\t- accel: {}, {}, {}\n\t- gyro: {}, {}, {}",
			temp, ax, ay, az, gx, gy, gz
		);
		
		FreeRtos::delay_ms(1000);
	}
}


Po wykonaniu komendy cargo run po skompilowaniu i zapisaniu pamięci flash na ekranie terminala będą co sekundę wyświetlane odczytane po magistrali I2C dane z termometru i akceleratora.



Wymiary


Linki zewnętrzne