Micropython, CardComputer - issue reading Keyboard



  • Hi, I've sucessfully installed the most recent ESP32S3 build of Micropython on my M5Stack CardComputer. Due to it being a generic build, there are no specific device drivers included with the firmware; however, I've managed to get some integrated peripherals working, ie the LCD, sdCard.
    The keyboard (schematic) in giving me some problems, its a pretty standard key matrix, the rows are provides using a 74hc138 3-8 line decoder, and the columns are 7 GPIOs. The outputs from the decoder are active low (datasheet), so I made the column pins inputs with pullups - doesnt work, needs pulldowns????
    Reading the column pins whilst iterating through the 8 rows should allow the individual key detection, but although key presses yield a pin change it doesn't work as expected and column 2 is always high???

        from time import sleep_ms
        from machine import Pin
    
        '''
         M5Stack CardComputer Keyboard 
         74HC138 3 to 8 line decoder
        
         Decoder Pin   A2, A1, A0   ----\    Y6, Y5, Y4, Y3, Y2,  Y1,  Y0       
         GPIO Pin     G11, G9, G8   ----/    G7, G6, G5, G4, G3, G15, G13     
        '''
        
        class KeyBoard():
            def __init__(self):
                keyPins = [ ('C0', 13, Pin.IN, Pin.PULL_DOWN), ('C1', 15, Pin.IN, Pin.PULL_DOWN), ('C2', 3, Pin.IN, Pin.PULL_DOWN),
                            ('C3',  4, Pin.IN, Pin.PULL_DOWN), ('C4',  5, Pin.IN, Pin.PULL_DOWN), ('C5', 6, Pin.IN, Pin.PULL_DOWN),
                            ('C6',  7, Pin.IN, Pin.PULL_DOWN),
                            ('A0',  8, Pin.OUT, None), ('A1', 9, Pin.OUT, None), ('A2', 11, Pin.OUT, None) ]
        
                ap = dict()
                for (name, pin, direction, pull) in keyPins:
                    self.pinMap[name] = Pin(pin, direction, pull) 
    
            def scan(self):
                for row in range(0,8):
                    self.pinMap['A0'].value( row & 0b001 )
                    self.pinMap['A1'].value( row & 0b010 >> 1 )
                    self.pinMap['A2'].value( row & 0b100 >> 2 )
                    sleep_ms(250)
                    print(f'{row:04b}\t',end='')
                    for col in ['C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6']:
                        sleep_ms(0)
                        val = self.pinMap[col].value()
                        print(f'{val:01b} ', end='')
                    print('')
                print('\n\n\n\n')
            
    keyboard = KeyBoard()
    while True:
        keyboard.scan()
        sleep_ms(500)
    

    Any ideas of where I'm going wrong??



  • Hello @MartynW

    I tried your code and changed two things to make it work:

    • changed the inputs to pullups (as you already thought it should be) - the output matrix then is all 1s except for the button pressed.
    • used some additional brackets for A1 and A2 to force the AND operation to happen first
                self.pinMap['A0'].value( row & 0b001 )
                self.pinMap['A1'].value( ( row & 0b010 ) >> 1 )
                self.pinMap['A2'].value( ( row & 0b100 ) >> 2 )
    
    

    Full code:

    from time import sleep_ms
    from machine import Pin
    
        
    class KeyBoard():
        def __init__(self):
          keyPins = [ ('C0', 13, Pin.IN, Pin.PULL_UP), ('C1', 15, Pin.IN, Pin.PULL_UP), ('C2', 3, Pin.IN, Pin.PULL_UP),
                      ('C3',  4, Pin.IN, Pin.PULL_UP), ('C4',  5, Pin.IN, Pin.PULL_UP), ('C5', 6, Pin.IN, Pin.PULL_UP),
                      ('C6',  7, Pin.IN, Pin.PULL_UP),
                      ('A0',  8, Pin.OUT, None), ('A1', 9, Pin.OUT, None), ('A2', 11, Pin.OUT, None) ]
        
          self.pinMap = dict()
          for (name, pin, direction, pull) in keyPins:
              self.pinMap[name] = Pin(pin, direction, pull) 
    
        def scan(self):
            for row in range(0,8):
                self.pinMap['A0'].value( row & 0b001 )
                self.pinMap['A1'].value( ( row & 0b010 ) >> 1 )
                self.pinMap['A2'].value( ( row & 0b100 ) >> 2 )
                sleep_ms(250)
                print(f'{row:04b}\t',end='')
                for col in ['C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6']:
                    sleep_ms(0)
                    val = self.pinMap[col].value()
                    print(f'{val:01b} ', end='')
                print('')
            print('\n\n\n\n')
    
        def scan2(self):
            for row in (7, 3, 6, 2, 5, 1, 4, 0):
                self.pinMap['A0'].value( row & 0b001 )
                self.pinMap['A1'].value( ( row & 0b010 ) >> 1 )
                self.pinMap['A2'].value( ( row & 0b100 ) >> 2 )
                sleep_ms(250)
                print(f'{row:04b}\t',end='')
                for col in ['C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6']:
                    sleep_ms(0)
                    val = self.pinMap[col].value()
                    print(f'{val:01b} ', end='')
                print('')
            print('\n\n\n\n')
    
    
    keyboard = KeyBoard()
    while True:
        keyboard.scan()
    #    keyboard.scan2()
        sleep_ms(500)
    

    BTW: I like your coding style with the pinMap etc. (Note: I am not very familiar with Micropython.)

    Thanks
    Felix



  • Felix,

    Thank you for the extra pair of eyes much appreciated, I got so obsessed with the PULL_UP/PULL_DOWN issue, I didn't even consider the processing order of the bitwise logic!! Many thanks.

    Martyn



  • Hello @martynw, I've been trying for a while to get my CardComputer's screen to work with Micropython code. I want to display a simple "hello world," but I'm having trouble. Could you help me? Could you show your code for activating the screen and writing anything on it?



  • Hello MartynW

    how do you use just the machine library. When I try this the m5stack gives an error.
    When I use the m5stack lib I don't have any problems with this



  • @felipeparaizo said in Micropython, CardComputer - issue reading Keyboard:

    Hello @martynw, I've been trying for a while to get my CardComputer's screen to work with Micropython code. I want to display a simple "hello world," but I'm having trouble. Could you help me? Could you show your code for activating the screen and writing anything on it?

    Have you added a driver to control the screen?

    @thijsnl said in Micropython, CardComputer - issue reading Keyboard:

    Hello MartynW

    how do you use just the machine library. When I try this the m5stack gives an error.
    When I use the m5stack lib I don't have any problems with this

    What's is the error?



  • @ajb2k3 said in Micropython, CardComputer - issue reading Keyboard:

    Você adicionou um driver para controlar a tela?

    Não, qual seria esse driver ? como posso adicionar ?



  • @felipeparaizo said in Micropython, CardComputer - issue reading Keyboard:

    Não, qual seria esse driver ? como posso adicionar ?

    Você precisa fazer upload do driver Micropython para a tela ST7789V2 no micropython usando thonny.