@grobasoz I think I require your help again. Your code works great with the C3 but when I port it to the S3 no luck. Very frustrating. I thought I fully understood your code and it would require a few simple changes for it to work with the S3. This has not been the case. The S3 goes into deep sleep but then immediately wakes up. It repeats this cycle.
The reason I want to use the S3 is for production reasons. The S3 allows the board to be directly connected/soldered to the back of the keypad (see picture) significantly reducing time to fabricate.
However, in order for this to work with the keypad I have to change the pin mappings which in turn means I need to use the row pins to wake-up the S3 since the D6 pin (GPIO 43) on the S3 is not an RTC pin (all others on that side of the XIAO ESP32S3 are).
Here is the code (I have tried lots of variations, but this version most closely matches your original code):
/***********************************************************************************************
Any Key Wake-up Test Code
v1.0
date: 08-Apr-2025
hardware: XIAO_ESP32S3
3x4 Matrix Keypad
This code is based on code developed by Gary Robas to have the XIAO_ESP32S3 wake-up when any
key is pressed.
************************************************************************************************/
#include <Keypad.h>
#define USE_DEEP_SLEEP
#define SLEEP_TIMEOUT 6000 // 10mS intervals
// Define pin mapping - must use RTC pins for rows
#define COL_PIN_1 GPIO_NUM_5 // D4 - P3
#define COL_PIN_2 GPIO_NUM_43 // D6 - P1
#define COL_PIN_3 GPIO_NUM_3 // D2 - P5
#define ROW_PIN_1 GPIO_NUM_6 // D5 - P2
#define ROW_PIN_2 GPIO_NUM_1 // D0 - P7
#define ROW_PIN_3 GPIO_NUM_2 // D1 - P6
#define ROW_PIN_4 GPIO_NUM_4 // D3 - P4
#define ROW_PIN_MASK ((1 << ROW_PIN_1) + (1 << ROW_PIN_2) + (1 << ROW_PIN_3) + (1 << ROW_PIN_4))
const byte ROWS = 4; // Rows
const byte COLS = 3; // Columns
// Define the symbols on the buttons of the keypads
char keys[ROWS][COLS] = {
{ '1', '2', '3' },
{ '4', '5', '6' },
{ '7', '8', '9' },
{ '*', '0', '#' }
};
byte colPins[COLS] = { COL_PIN_1, COL_PIN_2, COL_PIN_3 }; // Connect to the column pinouts of the keypad
byte rowPins[ROWS] = { ROW_PIN_1, ROW_PIN_2, ROW_PIN_3, ROW_PIN_4 }; // Connect to the row pinouts of the keypad
// Initialize an instance of class NewKeypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
static uint16_t sleep_count = 0; // Sleep after x seconds
#ifdef USE_DEEP_SLEEP
static bool sleep_permitted = true; // False if error with sleep setup
// Prepare GPIOs for wake
void prep_for_wake(void) {
// Allow rows to be pulled low when in deep sleep
digitalWrite(COL_PIN_1, HIGH);
digitalWrite(COL_PIN_2, HIGH);
digitalWrite(COL_PIN_3, HIGH);
// Release outputs held during deep sleep
gpio_hold_dis(COL_PIN_1);
gpio_hold_dis(COL_PIN_2);
gpio_hold_dis(COL_PIN_3);
}
// Prepare GPIOs for sleep
void prep_for_sleep(void) {
pinMode(ROW_PIN_1, INPUT);
pinMode(ROW_PIN_2, INPUT);
pinMode(ROW_PIN_3, INPUT);
pinMode(ROW_PIN_4, INPUT);
// Sleep - Cols are outputs
pinMode(COL_PIN_1, OUTPUT);
pinMode(COL_PIN_2, OUTPUT);
pinMode(COL_PIN_3, OUTPUT);
// Allow rows to be pulled low when in deep sleep
digitalWrite(COL_PIN_1, LOW);
digitalWrite(COL_PIN_2, LOW);
digitalWrite(COL_PIN_3, LOW);
// Maintain outputs during deep sleep
gpio_hold_en(COL_PIN_1);
gpio_hold_en(COL_PIN_2);
gpio_hold_en(COL_PIN_3);
if (esp_sleep_enable_ext1_wakeup_io(ROW_PIN_MASK, ESP_EXT1_WAKEUP_ANY_LOW) == ESP_OK) {
Serial.println("Keypad Wake Mask : 0x" + String(ROW_PIN_MASK, HEX));
} else {
Serial.println("Keypad Wake Error");
sleep_permitted = false;
}
Serial.println("Deep Sleep!");
}
void do_deep_sleep() {
prep_for_sleep();
Serial.println("Going to sleep now");
Serial.flush();
delay(100);
gpio_deep_sleep_hold_en();
esp_deep_sleep_start();
}
#endif // USE_DEEP_SLEEP
void setup() {
Serial.begin(115200);
#ifdef USE_DEEP_SLEEP
// Before starting the keypad, release held rows.
prep_for_wake();
#endif //USE_DEEP_SLEEP
Serial.println("Starting!");
}
void loop() {
char key = keypad.getKey();
if (key) {
Serial.print("Key pressed: ");
Serial.println(key);
}
if (sleep_count++ > SLEEP_TIMEOUT) {
#ifdef USE_DEEP_SLEEP
if (sleep_permitted) {
do_deep_sleep();
}
#endif
Serial.println("Sleep!");
delay(5000); // Testing
sleep_count = 0;
}
delay(10);
}