### Initialize M5CoreS3 Hardware Source: https://context7.com/m5stack/m5cores3/llms.txt Call CoreS3.begin() in the Arduino setup() function to initialize all hardware peripherals. It can be called with default configuration or a custom configuration object. ```cpp #include void setup() { // Basic initialization with default configuration CoreS3.begin(); // Or with custom configuration auto cfg = M5.config(); // Customize configuration options here // cfg.output_power = false; // Disable power output on Grove port CoreS3.begin(cfg); } void loop() { // Call update() in each loop iteration to handle touch, buttons, etc. CoreS3.update(); } ``` -------------------------------- ### M5CoreS3 Touch Input Handling Source: https://context7.com/m5stack/m5cores3/llms.txt The CoreS3.Touch object manages capacitive touch input, including multi-touch and gestures. Call CoreS3.update() to refresh touch states. This example detects touch state changes and displays coordinates and a touch point indicator. ```cpp #include static m5::touch_state_t prev_state; void setup() { auto cfg = M5.config(); CoreS3.begin(cfg); CoreS3.Display.setTextColor(GREEN); CoreS3.Display.setTextDatum(middle_center); CoreS3.Display.setFont(&fonts::Orbitron_Light_24); CoreS3.Display.drawString("Touch Test", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2); } void loop() { CoreS3.update(); auto t = CoreS3.Touch.getDetail(); // Detect touch state changes if (prev_state != t.state) { prev_state = t.state; // Touch state names for debugging static constexpr const char* state_name[16] = { "none", "touch", "touch_end", "touch_begin", "___", "hold", "hold_end", "hold_begin", "___", "flick", "flick_end", "flick_begin", "___", "drag", "drag_end", "drag_begin" }; CoreS3.Display.fillRect(0, 0, CoreS3.Display.width(), 140, BLACK); CoreS3.Display.drawString(state_name[t.state], CoreS3.Display.width() / 2, CoreS3.Display.height() / 2 - 30); } // Display touch coordinates CoreS3.Display.drawString( "X:" + String(t.x) + " / Y:" + String(t.y), CoreS3.Display.width() / 2, 200); // Draw touch point indicator CoreS3.Display.fillCircle(t.x, t.y, 4, GREEN); } ``` -------------------------------- ### Configure and Use Speaker Source: https://context7.com/m5stack/m5cores3/llms.txt Configures the AW88298 speaker with a high sample rate and sets master and channel volumes. Demonstrates playing simple tones, continuous tones with fade-in, and chords using multiple channels. Includes an example of playing a tone on touch input. ```cpp #include void setup() { auto cfg = M5.config(); CoreS3.begin(cfg); // Configure speaker (optional) auto spk_cfg = CoreS3.Speaker.config(); spk_cfg.sample_rate = 192000; // Higher sample rate for better quality CoreS3.Speaker.config(spk_cfg); CoreS3.Speaker.begin(); if (!CoreS3.Speaker.isEnabled()) { CoreS3.Display.print("Speaker not found..."); while (1) CoreS3.delay(1); } // Set master volume (0-255, default: 64) CoreS3.Speaker.setVolume(64); // Set channel volume (0-255, default: 255) CoreS3.Speaker.setAllChannelVolume(255); CoreS3.Speaker.setChannelVolume(0, 255); // Play simple tones CoreS3.Speaker.tone(2000, 100); // 2000Hz for 100ms CoreS3.delay(100); CoreS3.Speaker.tone(1000, 100); // 1000Hz for 100ms CoreS3.delay(100); CoreS3.Speaker.stop(); CoreS3.delay(500); // Play continuous tone (until stop() is called) CoreS3.Speaker.tone(880); for (int i = 0; i <= 64; i++) { CoreS3.Speaker.setVolume(i); // Fade in CoreS3.delay(25); } CoreS3.Speaker.stop(); CoreS3.delay(500); // Play chord using multiple channels CoreS3.Speaker.tone(261.626, 1000, 1); // C4 on channel 1 CoreS3.delay(200); CoreS3.Speaker.tone(329.628, 1000, 2); // E4 on channel 2 CoreS3.delay(200); CoreS3.Speaker.tone(391.995, 1000, 3); // G4 on channel 3 while (CoreS3.Speaker.isPlaying()) { CoreS3.delay(1); } } void loop() { CoreS3.update(); // Example: Play tone on touch if (CoreS3.Touch.getCount() && CoreS3.Touch.getDetail(0).wasClicked()) { CoreS3.Speaker.tone(440, 200); // A4 for 200ms } } ``` -------------------------------- ### Add M5CoreS3 BSP to Project Source: https://github.com/m5stack/m5cores3/blob/main/README.md Use this command to add the M5CoreS3 Board Support Package to your PlatformIO project. This simplifies hardware initialization. ```bash idf.py add-dependency m5stack_core_s3 ``` -------------------------------- ### Initialize RTC and Synchronize with NTP Source: https://context7.com/m5stack/m5cores3/llms.txt Initializes the RTC module, connects to WiFi, synchronizes the time with NTP servers, and sets the RTC. Requires valid WiFi credentials and timezone configuration. ```cpp #include #include #define WIFI_SSID "YOUR_SSID" #define WIFI_PASSWORD "YOUR_PASSWORD" #define NTP_TIMEZONE "UTC-8" #define NTP_SERVER1 "0.pool.ntp.org" #define NTP_SERVER2 "1.pool.ntp.org" #define NTP_SERVER3 "2.pool.ntp.org" void setup() { CoreS3.begin(); // Check if RTC is available if (!CoreS3.Rtc.isEnabled()) { Serial.println("RTC not found."); while (1) delay(500); } // Manual RTC setting // CoreS3.Rtc.setDateTime({ { 2024, 12, 31 }, { 12, 34, 56 } }); // NTP synchronization CoreS3.Display.println("WiFi Connecting..."); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { delay(500); } CoreS3.Display.println("WiFi Connected."); // Configure timezone and NTP servers configTzTime(NTP_TIMEZONE, NTP_SERVER1, NTP_SERVER2, NTP_SERVER3); // Wait for NTP sync and set RTC delay(2000); time_t t = time(nullptr) + 1; while (t > time(nullptr)); CoreS3.Rtc.setDateTime(gmtime(&t)); CoreS3.Display.clear(); } void loop() { static constexpr const char* const wd[7] = { "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat" }; delay(500); // Read RTC time auto dt = CoreS3.Rtc.getDateTime(); CoreS3.Display.setCursor(0, 0); CoreS3.Display.printf("RTC UTC: %04d/%02d/%02d (%s) %02d:%02d:%02d", dt.date.year, dt.date.month, dt.date.date, wd[dt.date.weekDay], dt.time.hours, dt.time.minutes, dt.time.seconds); // Compare with ESP32 internal clock auto t = time(nullptr); auto tm = localtime(&t); CoreS3.Display.setCursor(0, 40); CoreS3.Display.printf("Local: %04d/%02d/%02d (%s) %02d:%02d:%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, wd[tm->tm_wday], tm->tm_hour, tm->tm_min, tm->tm_sec); } ``` -------------------------------- ### Initialize and Capture Frames with GC0308 Camera Source: https://context7.com/m5stack/m5cores3/llms.txt Initializes the camera sensor and demonstrates how to push raw RGB565 frames to the display. ```cpp #include #include "esp_camera.h" void setup() { auto cfg = M5.config(); CoreS3.begin(cfg); CoreS3.Display.setTextColor(GREEN); CoreS3.Display.setTextDatum(middle_center); CoreS3.Display.setFont(&fonts::Orbitron_Light_24); // Initialize camera if (!CoreS3.Camera.begin()) { CoreS3.Display.drawString("Camera Init Fail", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2); while (1) delay(100); } CoreS3.Display.drawString("Camera Init Success", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2); } void loop() { // Capture frame if (CoreS3.Camera.get()) { // Display raw RGB565 frame directly CoreS3.Display.pushImage(0, 0, CoreS3.Display.width(), CoreS3.Display.height(), (uint16_t *)CoreS3.Camera.fb->buf); // Alternative: Convert to JPEG and display // uint8_t *out_jpg = NULL; // size_t out_jpg_len = 0; // frame2jpg(CoreS3.Camera.fb, 255, &out_jpg, &out_jpg_len); // CoreS3.Display.drawJpg(out_jpg, out_jpg_len, 0, 0, // CoreS3.Display.width(), // CoreS3.Display.height()); // free(out_jpg); // Release frame buffer CoreS3.Camera.free(); } } ``` -------------------------------- ### Implement Deep Sleep and Wake-up on M5CoreS3 Source: https://context7.com/m5stack/m5cores3/llms.txt Uses the Power API to enter a low-power state with a timer-based wake-up trigger. ```cpp #include void setup() { auto cfg = M5.config(); CoreS3.begin(cfg); CoreS3.Display.setTextColor(GREEN); CoreS3.Display.setTextDatum(middle_center); CoreS3.Display.setFont(&fonts::FreeSerifItalic18pt7b); CoreS3.Display.drawString("Touch to sleep", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2 - 40); CoreS3.Display.drawString("Wake after 5s", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2 + 40); } void loop() { CoreS3.update(); if (CoreS3.Touch.getCount() && CoreS3.Touch.getDetail(0).wasClicked()) { // Sleep for 5 seconds then wake up CoreS3.Power.timerSleep(5); // Alternative: Sleep until specific time // rtc_time_t wake_time = { 7, 30, 0 }; // 07:30:00 // CoreS3.Power.timerSleep(wake_time); // Alternative: Sleep until specific date and time // rtc_date_t wake_date = { 2024, 12, 25 }; // rtc_time_t wake_time = { 8, 0, 0 }; // CoreS3.Power.timerSleep(wake_date, wake_time); // Alternative: Power off completely (no wake-up) // CoreS3.Power.powerOff(); } } ``` -------------------------------- ### Record and Play Audio with ES7210 Source: https://context7.com/m5stack/m5cores3/llms.txt Demonstrates recording audio to a buffer and playing it back. Note that the microphone and speaker cannot be active simultaneously. ```cpp #include static constexpr size_t record_length = 320; static constexpr size_t record_samplerate = 17000; static int16_t *rec_data; void setup() { auto cfg = M5.config(); CoreS3.begin(cfg); CoreS3.Display.setRotation(1); CoreS3.Display.setTextDatum(top_center); CoreS3.Display.setTextColor(WHITE); // Allocate recording buffer rec_data = (int16_t*)heap_caps_malloc( record_length * sizeof(int16_t), MALLOC_CAP_8BIT); // Microphone and speaker cannot work simultaneously CoreS3.Speaker.end(); CoreS3.Mic.begin(); CoreS3.Display.fillCircle(130, 15, 8, RED); CoreS3.Display.drawString("REC", 180, 3); } void loop() { CoreS3.update(); if (CoreS3.Mic.isEnabled()) { // Record audio samples if (CoreS3.Mic.record(rec_data, record_length, record_samplerate)) { // Process or display audio waveform int32_t w = min((int32_t)CoreS3.Display.width(), (int32_t)(record_length - 1)); for (int32_t x = 0; x < w; ++x) { int32_t y1 = rec_data[x] >> 6; int32_t y = (CoreS3.Display.height() >> 1) + y1; CoreS3.Display.drawPixel(x, y, WHITE); } } } // Toggle playback on touch if (CoreS3.Touch.getCount() && CoreS3.Touch.getDetail(0).wasClicked()) { if (CoreS3.Mic.isEnabled()) { // Switch to playback mode CoreS3.Mic.end(); CoreS3.Speaker.begin(); CoreS3.Speaker.setVolume(255); // Play recorded audio CoreS3.Speaker.playRaw(rec_data, record_length, record_samplerate, false, 1, 0); while (CoreS3.Speaker.isPlaying()) { CoreS3.delay(1); } // Switch back to recording mode CoreS3.Speaker.end(); CoreS3.Mic.begin(); } } // Adjust noise filter with PWR button if (M5.BtnPWR.wasClicked()) { auto cfg = CoreS3.Mic.config(); cfg.noise_filter_level = (cfg.noise_filter_level + 8) & 255; CoreS3.Mic.config(cfg); CoreS3.Display.printf("Noise Filter: %d", cfg.noise_filter_level); } } ``` -------------------------------- ### Initialize and Scan I2C Buses on M5CoreS3 Source: https://context7.com/m5stack/m5cores3/llms.txt Initializes the M5CoreS3 and its I2C buses, then continuously scans for devices on both the external (Grove Port A) and internal I2C buses, displaying results on the screen and serial monitor. Requires the M5CoreS3 library. ```cpp #include void setup() { CoreS3.begin(); CoreS3.Display.setTextColor(YELLOW); CoreS3.Display.setTextSize(2); CoreS3.Display.println("M5CoreS3 I2C Scanner"); // Initialize I2C buses CoreS3.Ex_I2C.begin(); // External (Grove Port A) CoreS3.In_I2C.begin(); // Internal peripherals } void scanI2C(m5::I2C_Class &i2c, const char* busName) { CoreS3.Display.printf("\n%s:\n", busName); for (int addr = 8; addr < 0x78; addr++) { if (i2c.start(addr, false, 400000) && i2c.stop()) { CoreS3.Display.printf("0x%02X ", addr); Serial.printf("Found device at 0x%02X\n", addr); } delay(10); } } void loop() { CoreS3.Display.clear(); CoreS3.Display.setCursor(0, 0); // Scan external I2C bus (Grove Port A) scanI2C(CoreS3.Ex_I2C, "External I2C"); delay(2000); CoreS3.Display.clear(); CoreS3.Display.setCursor(0, 0); // Scan internal I2C bus scanI2C(CoreS3.In_I2C, "Internal I2C"); delay(2000); } ``` -------------------------------- ### Implement Virtual Touch Buttons and Power Button Monitoring Source: https://context7.com/m5stack/m5cores3/llms.txt Uses screen coordinates to define touch regions for virtual buttons and monitors the hardware power button state. ```cpp #include static m5::touch_state_t prev_state; void setup() { auto cfg = M5.config(); CoreS3.begin(cfg); CoreS3.Display.setTextColor(RED); CoreS3.Display.setTextDatum(middle_center); CoreS3.Display.setFont(&fonts::Orbitron_Light_24); // Draw virtual touch buttons at bottom of screen CoreS3.Display.fillRect(0, CoreS3.Display.height() - 40, CoreS3.Display.width() / 3, 40, WHITE); CoreS3.Display.fillRect(CoreS3.Display.width() / 3, CoreS3.Display.height() - 40, CoreS3.Display.width() / 3, 40, GREEN); CoreS3.Display.fillRect((CoreS3.Display.width() / 3) * 2, CoreS3.Display.height() - 40, CoreS3.Display.width() / 3, 40, YELLOW); CoreS3.Display.drawString("Btn A Btn B Btn C", CoreS3.Display.width() / 2, CoreS3.Display.height() - 20); } void loop() { CoreS3.update(); auto touchPoint = CoreS3.Touch.getDetail(); // Check for touch in button region if ((touchPoint.y > CoreS3.Display.height() - 40) && touchPoint.state == m5::touch_state_t::touch_begin) { CoreS3.Display.fillRect(0, 40, CoreS3.Display.width(), 70, BLACK); if (touchPoint.x < CoreS3.Display.width() / 3) { CoreS3.Display.drawString("Btn A", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2 - 30); } else if (touchPoint.x < (CoreS3.Display.width() / 3) * 2) { CoreS3.Display.drawString("Btn B", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2 - 30); } else { CoreS3.Display.drawString("Btn C", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2 - 30); } } // Check hardware power button if (CoreS3.BtnPWR.wasClicked()) { CoreS3.Display.fillRect(0, 40, CoreS3.Display.width(), 70, BLACK); CoreS3.Display.drawString("Btn PWR", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2 - 30); } } ``` -------------------------------- ### Initialize and Access SD Card Storage Source: https://context7.com/m5stack/m5cores3/llms.txt Configures SPI pins for the microSD card slot and performs basic file read/write operations. ```cpp #include #include #include // SD Card SPI pins for M5CoreS3 #define SD_SPI_SCK_PIN 36 #define SD_SPI_MISO_PIN 35 #define SD_SPI_MOSI_PIN 37 #define SD_SPI_CS_PIN 4 void setup() { CoreS3.begin(); // Initialize SPI for SD card SPI.begin(SD_SPI_SCK_PIN, SD_SPI_MISO_PIN, SD_SPI_MOSI_PIN, SD_SPI_CS_PIN); if (!SD.begin(SD_SPI_CS_PIN, SPI, 25000000)) { CoreS3.Display.println("SD Card failed!"); while (1); } // Get card info uint8_t cardType = SD.cardType(); if (cardType == CARD_NONE) { CoreS3.Display.println("No SD card"); return; } const char* typeStr = (cardType == CARD_MMC) ? "MMC" : (cardType == CARD_SD) ? "SDSC" : (cardType == CARD_SDHC) ? "SDHC" : "UNKNOWN"; CoreS3.Display.printf("Card Type: %s\n", typeStr); uint64_t cardSize = SD.cardSize() / (1024 * 1024); CoreS3.Display.printf("Card Size: %lluMB\n", cardSize); // Write file File file = SD.open("/hello.txt", FILE_WRITE); if (file) { file.println("Hello from M5CoreS3!"); file.close(); CoreS3.Display.println("File written"); } // Read file file = SD.open("/hello.txt"); if (file) { CoreS3.Display.println("File contents:"); while (file.available()) { CoreS3.Display.write(file.read()); } file.close(); } // Show storage usage CoreS3.Display.printf("\nTotal: %lluMB\n", SD.totalBytes() / (1024 * 1024)); CoreS3.Display.printf("Used: %lluMB\n", SD.usedBytes() / (1024 * 1024)); } void loop() { } ``` -------------------------------- ### Initialize and Use LTR-553 Sensor Source: https://context7.com/m5stack/m5cores3/llms.txt Initializes the LTR-553 sensor with custom parameters for proximity and ambient light sensing. Activate proximity and ambient light sensors after initialization. Reads proximity and ambient light values in the loop. ```cpp #include // Initialize with default parameters Ltr5xx_Init_Basic_Para device_init_base_para = LTR5XX_BASE_PARA_CONFIG_DEFAULT; void setup() { auto cfg = M5.config(); CoreS3.begin(cfg); CoreS3.Display.setTextColor(GREEN); CoreS3.Display.setTextDatum(middle_center); CoreS3.Display.setFont(&fonts::Orbitron_Light_24); // Customize sensor parameters device_init_base_para.ps_led_pulse_freq = LTR5XX_LED_PULSE_FREQ_40KHZ; device_init_base_para.ps_measurement_rate = LTR5XX_PS_MEASUREMENT_RATE_50MS; device_init_base_para.als_gain = LTR5XX_ALS_GAIN_48X; // Initialize sensor if (!CoreS3.Ltr553.begin(&device_init_base_para)) { CoreS3.Display.drawString("Ltr553 Init Fail", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2); while (1) delay(10); } CoreS3.Display.drawString("Ltr553 Init Success", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2); // Activate proximity sensor CoreS3.Ltr553.setPsMode(LTR5XX_PS_ACTIVE_MODE); // Activate ambient light sensor CoreS3.Ltr553.setAlsMode(LTR5XX_ALS_ACTIVE_MODE); } void loop() { CoreS3.Display.clear(); // Read proximity value (higher = closer object) uint16_t ps_value = CoreS3.Ltr553.getPsValue(); // Read ambient light value (lux) uint16_t als_value = CoreS3.Ltr553.getAlsValue(); CoreS3.Display.drawString( "PS:" + String(ps_value) + " / ALS:" + String(als_value), CoreS3.Display.width() / 2, CoreS3.Display.height() / 2); Serial.printf("Proximity: %d, Ambient Light: %d\n", ps_value, als_value); delay(100); } ``` -------------------------------- ### Initialize and Read IMU Data Source: https://context7.com/m5stack/m5cores3/llms.txt Initializes the IMU and continuously reads and displays gyroscope, accelerometer, and magnetometer data. Ensure the IMU module is connected and initialized before use. ```cpp #include void setup() { auto cfg = M5.config(); CoreS3.begin(cfg); CoreS3.Display.setTextSize(2); CoreS3.Display.setCursor(0, 0); delay(200); // Initialize IMU CoreS3.Imu.begin(); } void loop() { auto imu_update = M5.Imu.update(); if (imu_update) { auto data = M5.Imu.getImuData(); // Access accelerometer data (m/s^2) float accel_x = data.accel.x; float accel_y = data.accel.y; float accel_z = data.accel.z; // Or as array: data.accel.value[0], [1], [2] // Access gyroscope data (degrees/s) float gyro_x = data.gyro.x; float gyro_y = data.gyro.y; float gyro_z = data.gyro.z; // Access magnetometer data float mag_x = data.mag.x; float mag_y = data.mag.y; float mag_z = data.mag.z; // Display gyroscope values CoreS3.Display.setCursor(0, 20); CoreS3.Display.printf("gyroX, gyroY, gyroZ"); CoreS3.Display.setCursor(0, 42); CoreS3.Display.fillRect(0, 42, 320, 20, BLACK); CoreS3.Display.printf("%2.2f\t %2.2f\t %2.2f", gyro_x, gyro_y, gyro_z); // Display accelerometer values CoreS3.Display.setCursor(0, 70); CoreS3.Display.printf("accX, accY, accZ"); CoreS3.Display.setCursor(0, 92); CoreS3.Display.fillRect(0, 92, 320, 20, BLACK); CoreS3.Display.printf("%2.2f\t %2.2f\t %2.2f", accel_x, accel_y, accel_z); // Display magnetometer values CoreS3.Display.setCursor(0, 120); CoreS3.Display.printf("magX, magY, magZ"); CoreS3.Display.setCursor(0, 142); CoreS3.Display.fillRect(0, 142, 320, 20, BLACK); CoreS3.Display.printf("%2.1f %2.1f %2.1f", mag_x, mag_y, mag_z); delay(10); } } ``` -------------------------------- ### M5CoreS3 Display API Usage Source: https://context7.com/m5stack/m5cores3/llms.txt Utilize the CoreS3.Display object for graphics operations on the 320x240 IPS touchscreen. Configure text settings, clear the screen, draw text, and render shapes. The loop function demonstrates drawing random shapes for animation. ```cpp #include void setup() { auto cfg = M5.config(); CoreS3.begin(cfg); // Configure text settings CoreS3.Display.setTextSize(2); CoreS3.Display.setTextColor(GREEN); CoreS3.Display.setTextDatum(middle_center); CoreS3.Display.setFont(&fonts::Orbitron_Light_24); // Clear screen and draw text CoreS3.Display.clear(); CoreS3.Display.drawString("Hello M5CoreS3", CoreS3.Display.width() / 2, CoreS3.Display.height() / 2); // Draw shapes CoreS3.Display.fillCircle(50, 50, 20, RED); CoreS3.Display.fillRect(100, 30, 40, 40, BLUE); CoreS3.Display.drawLine(0, 0, 320, 240, WHITE); } void loop() { // Random shapes animation int x = rand() % CoreS3.Display.width(); int y = rand() % CoreS3.Display.height(); int r = (CoreS3.Display.width() >> 4) + 2; uint16_t color = rand(); CoreS3.Display.fillCircle(x, y, r, color); } ``` -------------------------------- ### Monitor Battery and Power with AXP2101 Source: https://context7.com/m5stack/m5cores3/llms.txt Shows how to read battery voltage, charge level, and VBUS status using the PMIC. ```cpp #include void setup() { auto cfg = M5.config(); // For external power (Grove or DC), disable output power // cfg.output_power = false; CoreS3.begin(cfg); CoreS3.Display.setTextSize(2); // Set charging current (mA): 100, 200, 300, 400, 500, ... CoreS3.Power.setChargeCurrent(200); } void loop() { CoreS3.Display.clear(); // Check charging status bool is_charging = CoreS3.Power.isCharging(); CoreS3.Display.setCursor(10, 30); CoreS3.Display.printf("Charging: %s", is_charging ? "Yes" : "No"); // Read battery voltage (mV) int bat_voltage = CoreS3.Power.getBatteryVoltage(); CoreS3.Display.setCursor(10, 50); CoreS3.Display.printf("Battery: %dmV", bat_voltage); // Read battery level (0-100%) int bat_level = CoreS3.Power.getBatteryLevel(); CoreS3.Display.setCursor(10, 70); CoreS3.Display.printf("Level: %d%%", bat_level); // Read USB voltage (mV) int vbus_voltage = CoreS3.Power.getVBUSVoltage(); CoreS3.Display.setCursor(10, 90); CoreS3.Display.printf("VBUS: %dmV", vbus_voltage); delay(1000); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.