Page 1 of 1

ESP32S pins 34,35,36,39 all receiving the event on one of the pins

Posted: Wed Dec 04, 2024 6:33 pm
by marcouellet
I build a circuit on a breadboard using a ESP-WROOM-32 (equivalent to a nodemcu 32S) and connected pins 34,35,36,39 to a momentary button with a 3.3k pullup resistor. A diagnose program is report that all the buttons has been pushed down at the same moment while a only click on one of then. Anybody has a idea what could case this ?

Re: ESP32S pins 34,35,36,39 all receiving the event on one of the pins

Posted: Thu Dec 05, 2024 1:56 am
by ESP_Sprite
Can you post your code?

Re: ESP32S pins 34,35,36,39 all receiving the event on one of the pins

Posted: Thu Dec 05, 2024 2:51 am
by igormoo
Once I had a similar problem, but my issue was that I had a very low value of pull-up resistors on the pins that made the pins virtually connected. Put 10k pull-ups on each one of your pins and that most-likely solves your problem

Re: ESP32S pins 34,35,36,39 all receiving the event on one of the pins

Posted: Thu Dec 05, 2024 3:57 pm
by marcouellet
Here the code (diagnostic program for the smart hand controller in project Onstep - https://onstep.groups.io/g/main/wiki/7152):

Code: Select all

/// A diagnostic exerciser and dumb handbox emulator for the OnStep Project ESP32-based Smart Hand Controller (SHC)
//
// Author: Dave Schwartz
//
// Revision history:
// 1.0 Initial version
// 1.1 Switched from interrupt-driven to input scanning - more flexible for multiple lines
// 1.2 Added use of OLED display using U8G2 library in addition to serial port output
// 1.3 Added pass-through line monitoring and user LED flash when activity detected
// 1.4 Added control of ST4 output signals to create "dumb handbox emulation" mode
// 1.5 Change RA+ output from D12 to D23
//
// Released under the GPL3 including later versions

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>

// Type of Display
// Uncomment one of the following. The SSD1306 is the 0.96" OLED and SH1106 is the 1.3" OLED

//U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // 0.96"
U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); // 1.3"

// Do not change anything below this line

#define SPLASH_LINE_1    "ESP32 SHC"
#define SPLASH_LINE_2    "Diagnostic 1.5"

#define SPLASH_MILLIS    5000
#define USER_LED_PIN     2
#define USER_LED_MILLIS  100

#define UP               0
#define DOWN             1
#define DEBOUNCING       2
#define DEBOUNCE_MILLIS  20

struct inputLine {
    uint8_t      pin;         // ESP32 GPIO for input
    const char*  lineName;    // label for display
    uint32_t     transMillis; // millisecond counter when state transition first detected
    int          state;       // UP, DOWN or DEBOUNCING
    unsigned int xPos;        // X position of label on OLED
    unsigned int yPos;        // Y position of label on OLED
    uint8_t      outPin;      // ST4 output signal GPIO if state is to be passed through to OnStep controller (0 == no passthrough)
};

inputLine inputLines[] = {
  {25, "N",     0, UP,  35, 11, 14},
  {36, "E",     0, UP,   5, 26, 23},
  {33, "SHIFT", 0, UP,  20, 26,  0},
  {34, "W",     0, UP,  60, 26, 26},
  {32, "S",     0, UP,  35, 41, 27},
  {39, "F1",    0, UP,   0, 56,  0},
  {35, "F2",    0, UP,  60, 56,  0},
  {19, "RA1+",  0, UP, 100, 11, 23},
  {18, "DE1+",  0, UP, 100, 26, 14},
  {17, "DE1-",  0, UP, 100, 41, 27},
  {5, "RA1-",   0, UP, 100, 56, 26}
};

// inputLine inputLines[] = {
//   {25, "N",     0, UP,  35, 11, 0},
//   {36, "E",     0, UP,   5, 26, 0},
//   {33, "SHIFT", 0, UP,  20, 26, 0},
//   {34, "W",     0, UP,  60, 26, 0},
//   {32, "S",     0, UP,  35, 41, 0},
//   {39, "F1",    0, UP,   0, 56, 0},
//   {35, "F2",    0, UP,  60, 56, 0},
//   {19, "RA1+",  0, UP, 100, 11, 0},
//   {18, "DE1+",  0, UP, 100, 26, 0},
//   {17, "DE1-",  0, UP, 100, 41, 0},
//   {5, "RA1-",   0, UP, 100, 56, 0}
// };
                           
int nLines = sizeof( inputLines ) / sizeof( inputLine);
boolean ledOn;
uint32_t ledOffAt;


void turnLedOn() {
  digitalWrite( USER_LED_PIN, HIGH );
  ledOn = true;
  ledOffAt = millis() + USER_LED_MILLIS;
}

void turnLedOff() {
  digitalWrite( USER_LED_PIN, LOW );
  ledOn = false;
}

void setup() {
  
  // initialize the user LED and turn in on (the main loop will turn it off again)
  
  pinMode( USER_LED_PIN, OUTPUT );
  turnLedOn();
  
  // Put all input lines into INPUT mode. No need to enable internal pullups because external pullup resistors are plenty strong.
  for( int i=0; i<nLines; ++i ) {
    pinMode( inputLines[i].pin, INPUT );
    if( inputLines[i].outPin ) {    // if input has an output pass-through, initialize it HIGH
      pinMode( inputLines[i].outPin, OUTPUT );
      digitalWrite( inputLines[i].outPin, HIGH );
    }
  }

  Serial.begin( 115200 );
  Serial.print( "Monitoring " );
  Serial.print( nLines );
  Serial.println( " lines:" );

  u8g2.begin();

  // Write the splash screen
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,SPLASH_LINE_1);
    u8g2.drawStr(0,36,SPLASH_LINE_2);
  } while ( u8g2.nextPage() );

  // Go to a smaller font for the input status display
  u8g2.setFont(u8g2_font_7x13B_mf);
}
 
void loop() {
  // If LED is on, see if its time to turn it off...
  if( ledOn && ( millis() > ledOffAt ) ) {
    turnLedOff();
  }
    
  // Keep splash screen up for the a bit
  if( millis() < SPLASH_MILLIS ) {
    return;
  }
    
  // Scan the input lines...
  for( int i=0; i<nLines; ++i ) {
    // If a line is in debounce mode...
    if( inputLines[i].state == DEBOUNCING ) {
      // Pay attention to it only after the debounce timer for the line has expired...
      if( millis() > inputLines[i].transMillis + DEBOUNCE_MILLIS ) {
        // Debounce complete...
        Serial.print( "Debounce on " );
        Serial.print( inputLines[i].lineName );
        Serial.print( " complete, state is now " );
        // Set the line state, OLED label and pass-through output according to the logic level
        if( digitalRead( inputLines[i].pin ) == LOW ) {
          inputLines[i].state = DOWN;
          Serial.println( "DOWN" );
          if( inputLines[i].outPin ) {
            digitalWrite( inputLines[i].outPin, LOW );
          }
          turnLedOn();
        }
        else {
          inputLines[i].state = UP;
          Serial.println( "UP" );
          if( inputLines[i].outPin ) {
            digitalWrite( inputLines[i].outPin, HIGH );
          }
        }
      }
    }
    else {
      // Not debouncing... check if a line has changed state...
      if( ( inputLines[i].state == UP  && digitalRead( inputLines[i].pin ) == LOW ) ||
          ( inputLines[i].state == DOWN  && digitalRead( inputLines[i].pin ) == HIGH ) ) {
          // State change detected... enter debouncing state and set debounce start timer for the line
          Serial.print( "State change detected on " );
          Serial.print( inputLines[i].lineName );
          Serial.println( ", entering debounce period." );
          inputLines[i].state = DEBOUNCING;
          inputLines[i].transMillis = millis();
       }
    }
  }
  
  // Refresh the screen with the input line statuses
  u8g2.firstPage();
  do {
    for( int i=0; i<nLines; ++i ) {
      // When a line is low/button down, write label in inverse video
      if( inputLines[i].state == DOWN ) {
        u8g2.setDrawColor( 0 );
      }
      else {
        u8g2.setDrawColor( 1 );
      }
      //* position the cursor and write the label
      u8g2.drawStr( inputLines[i].xPos, inputLines[i].yPos, inputLines[i].lineName );
    }
  } while ( u8g2.nextPage() );
}

Re: ESP32S pins 34,35,36,39 all receiving the event on one of the pins

Posted: Thu Dec 05, 2024 3:59 pm
by marcouellet
I use 9.1k pullup resistor connected to 3.3 VDC for the pins 34,35,36 and 39. No change.

Re: ESP32S pins 34,35,36,39 all receiving the event on one of the pins

Posted: Fri Dec 06, 2024 2:08 am
by ESP_Sprite
Weird, I see nothing offensive in the code. Can you measure the voltage on one of the offending GPIOs when you press a button connected to another GPIO; is the line physically pulled down as well?

Re: ESP32S pins 34,35,36,39 all receiving the event on one of the pins

Posted: Tue Dec 10, 2024 3:57 pm
by MihaPeterle
I think, it is because, they are all connected to the same PORT. When any of pins on one port (for example B) are active, NVIC starts interup called EXIT as external interupt, and you need to manualy look at each pin, to see wich one is connected.

Re: ESP32S pins 34,35,36,39 all receiving the event on one of the pins

Posted: Wed Dec 11, 2024 8:35 am
by ESP_Sprite
MihaPeterle wrote:
Tue Dec 10, 2024 3:57 pm
I think, it is because, they are all connected to the same PORT. When any of pins on one port (for example B) are active, NVIC starts interup called EXIT as external interupt, and you need to manualy look at each pin, to see wich one is connected.
That makes no sense. A. it's not an ARM, so there's no NVIC, B. OPs code does not interrupts in the first place.