User Tools

Site Tools


tamiwiki:users:6r1d:diymall_esp32_s3_fixture

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tamiwiki:users:6r1d:diymall_esp32_s3_fixture [2025/10/18 09:43] 6r1dtamiwiki:users:6r1d:diymall_esp32_s3_fixture [2025/10/20 05:43] (current) – [ESP-IDF (+ history and PWM debug)] 6r1d
Line 1: Line 1:
-There's something very nice about ESP32 Wroom modules: you can use fixtures to quickly debug thingsremove a module, solder it and viola, you have something working. +Theres something great about [[https://www.espressif.com/en/products/socs/esp32-s3|ESP32-WROOM]] modules: you can prototype fast, use test fixtures to debug, then pop a module off, solder it onto a board, and voilà, you’ve got a working device
-Or a bad boardMostly those options.+Or a non-working one. 
 +//Usually// it's one of those two.
  
-And I've been using a fixture by [[http://www.diymalls.com/|DIYMall]] for some time at this point. From my perspective, its main feature is the support for `ESP32-S3-WROOM-1Uand `ESP32-S3-WROOM-1([[https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf|datasheet]]).+====== Introduction ====== 
 + 
 +I've been using a fixture by [[http://www.diymalls.com/|DIYMall]] for some time at this point. From my perspective, its main feature is the support for ESP32-S3-WROOM-1U and ESP32-S3-WROOM-1 ([[https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf|datasheet]]).
  
 {{:tamiwiki:users:6r1d:signal-2025-10-18-123252_002.jpeg?400|}} {{:tamiwiki:users:6r1d:signal-2025-10-18-123334_002.jpeg?400|}} {{:tamiwiki:users:6r1d:signal-2025-10-18-123252_002.jpeg?400|}} {{:tamiwiki:users:6r1d:signal-2025-10-18-123334_002.jpeg?400|}}
  
-It is very helpful as a fixture. It is not helpful whatsoever in terms of having a proper documentation. If you open the DIYMalls site, it shows 403 and doesn't give you anything.+It is very helpful as a fixture. It is not helpful whatsoever when it comes to proper documentation. If you open the [[http://diymalls.com/|DIYMalls site]], it shows 403 and gives you nothing.
  
 So, the fixture is easy to buy on AliExpress, for example, [[https://aliexpress.com/item/1005008525778779.html|here]], it works without hassle, and it will also require you trace all pins unless you have a reference. So, the fixture is easy to buy on AliExpress, for example, [[https://aliexpress.com/item/1005008525778779.html|here]], it works without hassle, and it will also require you trace all pins unless you have a reference.
Line 12: Line 15:
 Thus, I've traced everything I found so you don't have to. Thus, I've traced everything I found so you don't have to.
  
-^ ESP32-S3-Wroom contact pad ^ DS REF ^ Arduino pin ^ Board pin ^ +====== Pin assignments ====== 
-| 39                         | IO1    | 1           | D36       | + 
-| 38                         | IO2    | 2           | D35       | +^ ESP32-S3-Wroom contact pad ^ Datasheet reference ^ Arduino pin ^ Board pin ^ 
-| 4                          | IO4    | 4           | D1        | +| 39                         | IO1                 | 1           | D36       | 
-| 5                          | IO5    | 5           | D2        | +| 38                         | IO2                 | 2           | D35       | 
-| 6                          | IO6    | 6           | D3        | +| 4                          | IO4                 | 4           | D1        | 
-| 7                          | IO7    | 7           | D4        | +| 5                          | IO5                 | 5           | D2        | 
-| 12                         | IO8    | 8           | D9        | +| 6                          | IO6                 | 6           | D3        | 
-| 17                         | IO9    | 9           | D14       | +| 7                          | IO7                 | 7           | D4        | 
-| 18                         | IO10   | 10          | D15       | +| 12                         | IO8                 | 8           | D9        | 
-| 19                         | IO11   | 11          | D16       | +| 17                         | IO9                 | 9           | D14       | 
-| 20                         | IO12   | 12          | D17       | +| 18                         | IO10                | 10          | D15       | 
-| 21                         | IO13   | 13          | D18       | +| 19                         | IO11                | 11          | D16       | 
-| 22                         | IO14   | 14          | D19       | +| 20                         | IO12                | 12          | D17       | 
-| 8                          | IO15   | 15          | D5        | +| 21                         | IO13                | 13          | D18       | 
-| 9                          | IO16   | 16          | D6        | +| 22                         | IO14                | 14          | D19       | 
-| 10                         | IO17   | 17          | D7        | +| 8                          | IO15                | 15          | D5        | 
-| 11                         | IO18   | 18          | D8        | +| 9                          | IO16                | 16          | D6        | 
-| 23                         | IO21   | 21          | D20       | +| 10                         | IO17                | 17          | D7        | 
-| 31                         | IO38   | 38          | D28       | +| 11                         | IO18                | 18          | D8        | 
-| 32                         | IO39   | 39          | D29       | +| 23                         | IO21                | 21          | D20       | 
-| 33                         | IO40   | 40          | D30       | +| 31                         | IO38                | 38          | D28       | 
-| 34                         | IO41   | 41          | D31       | +| 32                         | IO39                | 39          | D29       | 
-| 35                         | IO42   | 42          | D32       | +| 33                         | IO40                | 40          | D30       | 
-| 24                         | IO47   | 47          | D21       | +| 34                         | IO41                | 41          | D31       | 
-| 25                         | IO48   | 48          | D22       | +| 35                         | IO42                | 42          | D32       | 
-| 36                         | RXD0   | 36          | D33       | +| 24                         | IO47                | 47          | D21       | 
-| 37                         | TXD0   | 37          | D34       |+| 25                         | IO48                | 48          | D22       | 
 +| 36                         | RXD0                | 36          | D33       | 
 +| 37                         | TXD0                | 37          | D34       | 
 + 
 +===== Notes ===== 
 + 
 +  * GPIO pin 48 is the onboard LED, usually blue. 
 +  * Initially, I thought that onboard USB-UART is connected to something else than RXD0 / TXD0. It was not. It is the main UART. 
 +  
 +====== Tracing code ====== 
 + 
 +You might disagree with me and want to double-check. Excellent! More eyes (and feedback) mean better information. 
 + 
 +Grab your trusty 30-year-old LED soldered to a pair of DuPont sockets and start tracing. If you don’t have one handy (like me), grab your scope instead.((Marie Antoinette reference unintended.)) 
 + 
 +For convenience, here’s the code to do the job. I didn’t bother writing it from scratch, but I tested it, and it worked just fine for me. 
 +===== ESP-IDF (+ history and PWM debug) ===== 
 + 
 +This code gives you a predictable interactive workflow with history. 
 + 
 +<code> 
 +> help 
 +Commands: 
 +  list                          -> show test-safe GPIOs 
 +  status                        -> show current pin/mode 
 +  pin <gpio>                    -> start blinking GPIO 
 +  <gpio>                        -> same as 'pin <gpio>' 
 +  delay <ms>                    -> set blink delay 
 +  pwm <pin> [brightness]        -> start PWM (0-99, current: 50%) 
 +  brightness <level>            -> set PWM brightness (0-99) 
 +  freq <frequency>              -> set PWM frequency (Hz) 
 +  stop                          -> stop and release pin 
 + 
 +> 48 
 +Stopped. Pin released to INPUT. 
 +Blinking GPIO 48 at 100 ms. 
 + 
 +> 42 
 +Stopped. Pin released to INPUT. 
 +Blinking GPIO 42 at 100 ms. 
 + 
 +> 47 
 +Stopped. Pin released to INPUT. 
 +Blinking GPIO 47 at 100 ms. 
 + 
 +> 46 
 +Restricted: GPIO 46 is not in the test-safe set. 
 + 
 +> delay 40 
 +Set blink delay to 40 ms. 
 + 
 +> delay 10 
 +Set blink delay to 10 ms. 
 +</code> 
 + 
 +As for using it, you should know the gist at this point. 
 + 
 +<code bash> 
 +mkdir pin_tracer && cd pin_tracer 
 +idf.py create-project . && idf.py reconfigure && idf.py set-target esp32s3 
 +# fill the code 
 +# update the CMake configs 
 +idf.py build 
 +idf.py flash monitor 
 +</code> 
 + 
 +For your convenience, I have shared the whole [[https://git.telavivmakers.space/6r1d/esp32_s3_pin_tracer_espidf|repository]] at TAMI Gitea. 
 + 
 +Clone it like that: 
 + 
 +<code bash> 
 +git clone https://git.telavivmakers.space/6r1d/esp32_s3_pin_tracer_espidf.git esp32_s3_pin_tracer 
 +</code> 
 + 
 +Also, you can use Minicom to interact with the tracing code if you'd like. It's just one of the default baudrates, 115200. 
 + 
 +<code bash> 
 +minicom -D /dev/ttyUSB0 -b 115200 -o 
 +</code> 
 +===== Arduino (basic version) ===== 
 + 
 +Flash from Arduino IDE. Use the ESP32 board package by Espressif, pick ESP32S3 Dev Module, pick 115200 baud in Serial Monitor. 
 + 
 +<file cpp esp32_s3_pin_tracer.ino> 
 +#include <Arduino.h> 
 + 
 +// ====== CONFIG ====== 
 +// Blink timing (change at runtime with: delay <ms>
 +static uint32_t BLINK_DELAY_MS = 100; 
 + 
 +// Conservative "test-safe GPIO" set for ESP32-S3 modules. 
 +// Excludes pins that commonly serve boot strapping, USB D-/D+, PSRAM/flash, UART0 console, or JTAG, 
 +// which can interfere with programming, boot, or board-level functions during quick tests. 
 +// 
 +// Notes (summarized from the ESP32-S3 module/chip docs): 
 +// - 0, 3, 45, 46 are strapping/boot-related or JTAG-related; driving them can change boot modes or disable debug. 
 +// - 19, 20 are the on-chip USB D-/D+ differential pair; toggling them breaks USB comms. 
 +// - 35, 36, 37 are wired to Octal PSRAM on some variants; not available as GPIO there. 
 +// - 43 (U0TXD), 44 (U0RXD) are UART0 console pins used by Serial; poking them disrupts logs/flashing. 
 +// - 47, 48 form a differential SPI clock pair; safe as GPIO but mind 1.8 V I/O level on some R16V variants. 
 +const uint8_t TEST_SAFE_GPIO[] = { 
 +  1, 2,                      // ADC/Touch-capable, OK for digital use 
 +  4, 5, 6, 7,                // " 
 +  8, 9, 10, 11, 12, 13, 14,  // " 
 +  15, 16, 17, 18,            // " 
 +  // 19,20 excluded (USB D-/D+) 
 +  21,  // plain GPIO 
 +  // 22..34 don't exist on S3 modules 
 +  // 35,36,37 excluded (PSRAM on some variants) 
 +  38, 39, 40, 41, 42,  // JTAG-capable if configured, but OK as GPIO when JTAG is not in use 
 +  // 43,44 excluded (UART0 TX/RX used by Serial) 
 +  47, 48  // differential clock pair; OK as GPIO (watch 1.8 V I/O on some R16V variants) 
 +}; 
 +const size_t TEST_SAFE_GPIO_COUNT = sizeof(TEST_SAFE_GPIO) / sizeof(TEST_SAFE_GPIO[0]); 
 + 
 +// ====== RUNTIME STATE ====== 
 +static int currentPin = -1; 
 +static bool blinking = false; 
 + 
 +// ====== HELPERS ====== 
 +bool isTestSafe(int gpio) { 
 +  for (size_t i = 0; i < TEST_SAFE_GPIO_COUNT; ++i) { 
 +    if ((int)TEST_SAFE_GPIO[i] == gpio) return true; 
 +  } 
 +  return false; 
 +
 + 
 +void printTestSafePins() { 
 +  Serial.println(F("\nTest-safe GPIOs (ESP32-S3):")); 
 +  for (size_t i = 0; i < TEST_SAFE_GPIO_COUNT; ++i) { 
 +    Serial.print(F(i ? ", " : "  ")); 
 +    Serial.print(TEST_SAFE_GPIO[i]); 
 +  } 
 +  Serial.println(); 
 +  Serial.println(F("Excluded (reason): 0,3,45,46 (boot/strap/JTAG) | 19,20 (USB D-/D+) | 35-37 (PSRAM on some) | 43,44 (UART0 console)")); 
 +
 + 
 +void stopBlink() { 
 +  if (currentPin >= 0) { 
 +    digitalWrite(currentPin, LOW); 
 +    pinMode(currentPin, INPUT);  // leave safe 
 +  } 
 +  blinking = false; 
 +  currentPin = -1; 
 +  Serial.println(F("Stopped. Pin released to INPUT.")); 
 +
 + 
 +void startBlink(int gpio) { 
 +  if (!isTestSafe(gpio)) { 
 +    Serial.print(F("Restricted: GPIO ")); 
 +    Serial.print(gpio); 
 +    Serial.println(F(" is not in the test-safe set.")); 
 +    return; 
 +  } 
 +  if (blinking && currentPin == gpio) { 
 +    Serial.print(F("Already blinking GPIO ")); 
 +    Serial.println(gpio); 
 +    return; 
 +  } 
 +  // switch pin if needed 
 +  if (blinking && currentPin != gpio) stopBlink(); 
 + 
 +  currentPin = gpio; 
 +  pinMode(currentPin, OUTPUT); 
 +  digitalWrite(currentPin, LOW); 
 +  blinking = true; 
 + 
 +  Serial.print(F("Blinking GPIO ")); 
 +  Serial.print(currentPin); 
 +  Serial.print(F(" at ")); 
 +  Serial.print(BLINK_DELAY_MS); 
 +  Serial.println(F(" ms.")); 
 +
 + 
 +// Parse commands like: 
 +//   list 
 +//   pin 10 
 +//   delay 250 
 +//   stop 
 +void handleCommand(String line) { 
 +  line.trim(); 
 +  if (line.length() == 0) return; 
 + 
 +  line.toLowerCase(); 
 +  if (line == "list") { 
 +    printTestSafePins(); 
 +    return; 
 +  } 
 +  if (line == "stop") { 
 +    stopBlink(); 
 +    return; 
 +  } 
 +  if (line.startsWith("pin ")) { 
 +    int gpio = line.substring(4).toInt(); 
 +    startBlink(gpio); 
 +    return; 
 +  } 
 +  if (line.startsWith("delay ")) { 
 +    int v = line.substring(6).toInt(); 
 +    if (v < 10) v = 10;  // clamp a bit 
 +    BLINK_DELAY_MS = (uint32_t)v; 
 +    Serial.print(F("Set blink delay to ")); 
 +    Serial.print(BLINK_DELAY_MS); 
 +    Serial.println(F(" ms.")); 
 +    return; 
 +  } 
 + 
 +  // Single-number shortcut: just type the GPIO number 
 +  bool allDigits = true; 
 +  for (size_t i = 0; i < (size_t)line.length(); ++i) { 
 +    if (!isDigit(line[i])) { 
 +      allDigits = false; 
 +      break; 
 +    } 
 +  } 
 +  if (allDigits) { 
 +    startBlink(line.toInt()); 
 +    return; 
 +  } 
 + 
 +  Serial.println(F("Commands:")); 
 +  Serial.println(F("  list               -> show test-safe GPIOs")); 
 +  Serial.println(F("  pin <gpio>         -> start blinking that GPIO")); 
 +  Serial.println(F("  <gpio>             -> same as 'pin <gpio>'")); 
 +  Serial.println(F("  delay <ms>         -> set blink delay")); 
 +  Serial.println(F("  stop               -> stop and release pin")); 
 +
 + 
 +void setup() { 
 +  Serial.begin(115200); 
 +  // give USB-Serial/JTAG a moment 
 +  delay(400); 
 +  Serial.println(F("\nESP32-S3 GPIO Quick Tester")); 
 +  Serial.println(F("Type 'list' to see test-safe pins, 'pin <gpio>' to blink, 'delay <ms>' to change speed, 'stop' to release.\n")); 
 +  printTestSafePins(); 
 +
 + 
 +void loop() { 
 +  // Process serial line input 
 +  static String line; 
 +  while (Serial.available()) { 
 +    char c = (char)Serial.read(); 
 +    if (c == '\r') continue; 
 +    if (c == '\n') { 
 +      handleCommand(line); 
 +      line = ""; 
 +    } else { 
 +      line += c; 
 +    } 
 +  } 
 + 
 +  // Blink the selected pin 
 +  if (blinking && currentPin >= 0) { 
 +    digitalWrite(currentPin, HIGH); 
 +    delay(BLINK_DELAY_MS); 
 +    digitalWrite(currentPin, LOW); 
 +    delay(BLINK_DELAY_MS); 
 +  } else { 
 +    delay(5); 
 +  } 
 +
 +</file> 
 + 
 + 
 +====== Feedback ====== 
  
-If you'd like to make corrections or are unhappy with how I wrote this tiny article, ping me in Telegram.+If youd like to suggest corrections or aren’t satisfied with how I wrote this short article, feel free to ping me on [[https://t.me/I_am_6r1d|Telegram]].
  
-This topic possibly deserves to be a more widely shown form of a doc. Then again, IDK if anyone uses S3 that much around.+This topic might deserve to be expanded into document outside of my personal page. 
 +Then again, I’m not sure how many people around here actually use ESP32-S3.
tamiwiki/users/6r1d/diymall_esp32_s3_fixture.1760780628.txt.gz · Last modified: by 6r1d