Waqar Ahmad
Waqar Ahmad

Reputation: 3730

TypeError: function takes 1 positional arguments but 2 were given

I am trying to interface multiple buttons with Esp8266 and display it on a 16x2 LCD. I am using micropython. Here is my code

import time
from machine import I2C, Pin, Timer
from i2c_lcd import I2cLcd

DEFAULT_I2C_ADDR = 0x27


class Button:
    def __init__(self, pin, callback):
        self.pin = Pin(pin, Pin.IN, Pin.PULL_UP)
        self.callback = callback
        self.debounce_timer = Timer(-1)
        self.state = False

    def init(self):
        self.pin.irq(trigger=Pin.IRQ_FALLING, handler=self.interrupt_handler)
        print('Button initialized')

    def interrupt_handler(self):
        if not self.state:
            self.debounce_timer.init(period=50, mode=Timer.ONE_SHOT, callback=self.debounce_callback)       

    def debounce_callback(self):
        if not self.state and self.pin.value() == 0:
            self.callback()
        self.state = False


class Counter:
    def __init__(self, lcd):
        self.lcd = lcd
        self.count = 0

    def increment(self):
        print('Increament start')
        self.count += 1
        print('About to call update display')
        self.update_display()
        

    def decrement(self):
        self.count -= 1
        self.update_display()

    def update_display(self):
        print('Update display')
        self.lcd.move_to(11, 1)
        self.lcd.putstr("     ")
        self.lcd.move_to(11, 1)
        self.lcd.putstr(str(self.count))

i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16)

# Initialize counter
counter = Counter(lcd)

# Create a list of buttons
buttons = []


    
# Initialize buttons with their pins and callback functions (if any)
buttons.append(Button(13, counter.increment))  # Increment button
buttons.append(Button(14, counter.decrement))  # Decrement button


# Start all buttons
for button in buttons:
    button.init()
    
lcd.clear()
lcd.move_to(11, 0)
lcd.putstr("COUNT")

The code compiles fine buton as soon as I press an interrupt button, I get error

TypeError: function takes 1 positional arguments but 2 were given

I have been trying to debug for about an hour but not successful yet. I am not sure what is wrong.

Upvotes: -2

Views: 27

Answers (1)

Waqar Ahmad
Waqar Ahmad

Reputation: 3730

As per the micropython docs, interrupt handler expects Pin object. Here is my modified code which works fine.

import time
from machine import I2C, Pin, Timer
from i2c_lcd import I2cLcd

DEFAULT_I2C_ADDR = 0x27


class Button:
    def __init__(self, pin, callback):
        self.pin = Pin(pin, Pin.IN, Pin.PULL_UP)
        self.callback = callback
        self.debounce_timer = Timer(-1)
        self.state = False

    def init(self):
        self.pin.irq(trigger=Pin.IRQ_FALLING, handler=self.interrupt_handler)

    def interrupt_handler(self, pin):
        if not self.state:
            self.debounce_timer.init(period=50, mode=Timer.ONE_SHOT, callback=self.debounce_callback)       

    def debounce_callback(self, pin):
        if not self.state and self.pin.value() == 0:            
            self.callback()
            self.state = False        


class Counter:
    def __init__(self, lcd):
        self.lcd = lcd
        self.count = 0

    def increment(self):
        print("Incrementing counter")
        self.count += 1
        self.update_display()
        

    def decrement(self):
        print("Decrementing counter")
        self.count -= 1
        self.update_display()

    def update_display(self):
        self.lcd.move_to(11, 1)
        self.lcd.putstr("     ")
        self.lcd.move_to(11, 1)
        self.lcd.putstr(str(self.count))

i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16)

# Initialize counter
counter = Counter(lcd)

# Create a list of buttons
buttons = []


    
# Initialize buttons with their pins and callback functions (if any)
buttons.append(Button(13, counter.increment))  # Increment button
#buttons.append(Button(14, counter.decrement))  # Decrement button


# Start all buttons
for button in buttons:
    button.init()
    
lcd.clear()
lcd.move_to(11, 0)
lcd.putstr("COUNT")

Upvotes: 0

Related Questions