My gpio expander bahaves stangly

I am using arduino uno , simple button and gpio expander aw9523B.
I need more pins for another project but first i wanted to test if it works as it should .
i2c scanner found the address, so i wrote some simple code to turn on the build in led on arduino and when the button is released the led turns off.
However for some reason sometimes when the led is turn off it will blink one or twice without pressing the button and after every release there is a delay usually 1 or 2 second before the led turns off.

Here is my code



#include <Wire.h>

#define AW9523B_ADDRESS 0x58  // I2C address of the AW9523B
#define REG_INPUT_PORT0   0x00  // Register to read input state
#define REG_CONFIG_PORT0  0x04  // Register to configure pins as input/output
#define REG_PULLUP_PORT0  0x0C  // Register to enable pull-up resistors

void setup() {
  Wire.begin();
  Serial.begin(9600);
  Serial.println("AW9523B Button with Debouncing and Arduino LED");

  pinMode(LED_BUILTIN, OUTPUT);  // Configure Arduino built-in LED as output

  // Configure P0_0 as input and enable pull-up resistor
  writeRegister(REG_CONFIG_PORT0, 0b11111111);  // Set all pins to input
  writeRegister(REG_PULLUP_PORT0, 0b00000001);  // Enable pull-up on P0_0
}

void loop() {
  static byte lastButtonState = 1;   // Button starts in released state
  static unsigned long lastDebounceTime = 0;
  const unsigned long debounceDelay = 50;  // Debounce delay in milliseconds

  // Read button state from P0_0
  byte currentButtonState = readRegister(REG_INPUT_PORT0) & 0x01;

  // Check if the button state changed
  if (currentButtonState != lastButtonState) {
    lastDebounceTime = millis();  // Reset debounce timer on state change
  }

  // If the button state has been stable for longer than debounceDelay
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (currentButtonState == 0) {  // Button pressed (active LOW)
      
      digitalWrite(LED_BUILTIN, HIGH);  // Turn LED ON
    } else {  // Button released
      
      digitalWrite(LED_BUILTIN, LOW);  // Turn LED OFF
    }
  }

  lastButtonState = currentButtonState;  // Update last button state
}

void writeRegister(byte reg, byte value) {
  Wire.beginTransmission(AW9523B_ADDRESS);
  Wire.write(reg);
  Wire.write(value);
  Wire.endTransmission();
}

byte readRegister(byte reg) {
  Wire.beginTransmission(AW9523B_ADDRESS);
  Wire.write(reg);
  Wire.endTransmission();
  Wire.requestFrom(AW9523B_ADDRESS, 1);
  return Wire.read();
}


And my conncetions

Try this:

#include <Wire.h>

#define AW9523B_ADDRESS 0x58  // I2C address of the AW9523B
#define REG_INPUT_PORT0   0x00  // Register to read input state
#define REG_CONFIG_PORT0  0x04  // Register to configure pins as input/output
#define REG_PULLUP_PORT0  0x0C  // Register to enable pull-up resistors

void setup() {
  Wire.begin();
  Serial.begin(9600);
  Serial.println("AW9523B Button with Debouncing and Arduino LED");

  // Reset the AW9523B
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  delay(10);
  digitalWrite(4, HIGH);

  pinMode(LED_BUILTIN, OUTPUT);  // Configure Arduino built-in LED as output

  // Configure P0_0 as input and enable pull-up resistor
  writeRegister(REG_CONFIG_PORT0, 0b11111111);  // Set all pins to input
  writeRegister(REG_PULLUP_PORT0, 0b00000001);  // Enable pull-up on P0_0
}

void loop() {
  static byte lastButtonState = 1;   // Button starts in released state
  static unsigned long lastDebounceTime = 0;
  const unsigned long debounceDelay = 50;  // Debounce delay in milliseconds

  // Read button state from P0_0
  byte currentButtonState = readRegister(REG_INPUT_PORT0) & 0x01;

  // Check if the button state changed
  if (currentButtonState != lastButtonState) {
    lastDebounceTime = millis();  // Reset debounce timer on state change
  }

  // If the button state has been stable for longer than debounceDelay
  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (currentButtonState == 0) {  // Button pressed (active LOW)
      
      digitalWrite(LED_BUILTIN, HIGH);  // Turn LED ON
    } else {  // Button released
      
      digitalWrite(LED_BUILTIN, LOW);  // Turn LED OFF
    }
  }

  lastButtonState = currentButtonState;  // Update last button state
}

void writeRegister(byte reg, byte value) {
  Wire.beginTransmission(AW9523B_ADDRESS);
  Wire.write(reg);
  Wire.write(value);
  Wire.endTransmission();
}

byte readRegister(byte reg) {
  Wire.beginTransmission(AW9523B_ADDRESS);
  Wire.write(reg);
  Wire.endTransmission();
  Wire.requestFrom(AW9523B_ADDRESS, 1);
  return Wire.read();
}

Thank you for this code , it solved the delay after releasing button problem , but it did not solve a problem with random blinking of led when the button is pressed.

Try increasing value of debounceDelay

Are you sure it supports internal pull-ups?
Is 0x0C valid register?

tried increasing with different numbers. did not work.

Please be more descriptive. The more detail you give, the higher the chances that someone on the forum can figure out the problem.

Was the flashing more slow with increased values?

yes of course . here are the numbers:
at 50 the button detect all clicks , there are no delays , random blinking happens,
at 100 the button detect all clicks , there are some short delays, random blinking happens,
at 200 the button ignores short clicks (which is bad cause i need fast reaction time for my project), there are some long delays,random blinking happens,

I really cant see a pattern in this random blinking they are mostly short and mosty after longer press however there are exceptions.

I am not sure if it supports internal pull-ups , checking it right now.

I'm pretty sure you need external pullups on your buttons.

From the Adafruit docs for the 9523,

Note that this chip does not support internal pull-up or pull-downs, so you will
need to add an external resistor if you need one

I have had many cases that the AI gets the order of binary reversed. Try these two and see what happens

writeRegister(REG_CONFIG_PORT0, 0b00000000);  // Set all pins to input
  writeRegister(REG_PULLUP_PORT0, 0b11111110);  // Enable pull-up on P0_0
}

or

writeRegister(REG_CONFIG_PORT0, 0b11111111);  // Set all pins to input
  writeRegister(REG_PULLUP_PORT0, 0b10000000);  // Enable pull-up on P0_0
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.