Menu

Is there any MCP23017 example code for keypads?

2022-12-22
2023-01-08
  • David Briscoe

    David Briscoe - 2022-12-22

    Hi,
    I'd like to use GCB to read from a 39 key keypad and write to upto 10 led's. This would use an MCP23017 port expander and a 4532 8 to 3 priority encoder (see attached example schematic-the MCP23017 replaces the SAA1061 chip). Is there any example code that uses a MCP23017 with a keypad and LED's? Thanks.

     
    • Anobium

      Anobium - 2022-12-22

      Not a solution I have come across over the years I have been here. :-)

       
  • mmotte

    mmotte - 2022-12-22

    There is a library file for MCP23017. That would be a good starting spot.

     
  • David Briscoe

    David Briscoe - 2022-12-22

    Thanks. I'm a beginner with GCB. Where can I find (which directory?) this library file and how do I include it in a listing? I can probably start with turning an LED on and OFF. Is there an example of this anywhere? I've seen a few posts in the forum about the MCP23017 but nothing that is a clear working example. I'm mostly going to writing/polling to port pins.

     
    • Anobium

      Anobium - 2022-12-22

      I have working examples of the MPC23xxx functions. Let me dig them out and post here.

       
  • Anobium

    Anobium - 2022-12-22

    These are two subroutines that are used to test I2C communications of Great Cow BASIC. So, this code segment is part of a much larger test program.

    Search for //!Here In GCStudio the calls will show up in RED.

    This code segment shows how to setup, write and read.

    The library is will documented but have you used I2C before ? What chip are you using ?
    Do you have communications with the MCP ?

    Evan

      #include <MCP23008.h>    //!Here
      #include <MCP23017.h>    //!Here
    
    
    dim ug_stateofmcp23008
    sub Showmcp23008
    
          //!Here
          #DEFINE MCP23008_DEVICE_1 0X48
    
          ANSI (  2, 40)
          ' BOLD OFF
    
          HSerSend 27
          HSerPrint "[1m"
          HSerSend 27
          HSerPrint "[37m"
    
          HSerPrint "MCP 23008 Device  "
          ' BOLD OFF
          HSerSend 27
          HSerPrint "[0m"
    
          ANSI (  3, 40)
    
          //!Here
          ' Is device present?
          I2CStart
          I2CSend ( MCP23008_DEVICE_1 )
          i2cstop
          //!Here
    
          if I2CSendState = False  then
            HSerSend 27
            HSerPrint "[1"
            HSerSend 0x3b
            HSerPrint     "31m"
            HSerPrint "Device Missing"
            HSerSend 27
            HSerPrint "[1"
            HSerSend 0x3b
            HSerPrint "32m"
            exit sub
          end if
    
    
          HSerPrint "All Ports to Output"
          ANSI (  4, 40)
          HSerPrint "Device Ports = 0x"
    
          //!Here
          ' setup MCP23008
          mcp23008_sendbyte(MCP23008_DEVICE_1, MCP23008_IODIR  , 0x00)' turn all pins output
    
          if ug_stateofmcp23008 = 0 then
             portsetvalue0 = 0xAA
             HSerPrint hex(portsetvalue0)
    
              //!Here
              ' set ports status on MCP23008
              mcp23008_sendbyte(MCP23008_DEVICE_1, MCP23008_GPIO, portsetvalue0 )' turn all pins off
              ug_stateofmcp23008 = 1
            else
              portsetvalue1 = 0x55
              HSerPrint hex(portsetvalue1)
    
              //!Here  
              ' set ports status on MCP23008
              mcp23008_sendbyte(MCP23008_DEVICE_1, MCP23008_GPIO, portsetvalue1 )' turn all pins on to state
              ug_stateofmcp23008 = 0
            end if
            HSerPrint "  "
    
    
    
          ANSI (  5, 40)
          HSerPrint "Read Device  = "
          //!Here
          ' read ports status on MCP23008
          mcp23008_readbyte(MCP23008_DEVICE_1, MCP23008_GPIO, ug_data )' read state
    
    
          if ug_stateofmcp23008 = 1 then
             HSerSend 27
             if ug_data <>  portsetvalue0  then
                 HSerPrint "[1"
                 HSerSend 0x3b
                 HSerPrint     "31m"
    
              else
                 HSerPrint "[1"
                 HSerSend 0x3b
                 HSerPrint "32m"
    
              end if
          end if
    
          if ug_stateofmcp23008 = 0 then
             HSerSend 27
             if ug_data <> portsetvalue1  then
               HSerPrint "[1"
               HSerSend 0x3b
               HSerPrint "31m"
            else
               HSerPrint "[1"
               HSerSend 0x3b
               HSerPrint "32m"
            end if
          end if
    
          HSerPrint "0x"
          HSerPrint hex(ug_data)
          HSerPrint "    "
          HSerSend 27
          HSerPrint "[0m"
    
    end sub
    
    dim ug_stateofmcp23017
    sub Showmcp23017
    
          //!Here   
          #DEFINE MCP23017_DEVICE_1 0X40
    
          ddelay = 1
          //!Here
          mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_IODIRA  , 0x00)' turn all pins output
          mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_GPIOA, 0x00 )
    
          mcp23017_status = 1
    
    
          ANSI (  7, 40 )
          ' BOLD OFF
          HSerSend 27
          HSerPrint "[1m"
          HSerSend 27
          HSerPrint "[37m"
          HSerPrint "MCP 23017 Device  "
          ' BOLD OFF
    
          HSerSend 27
          HSerPrint "[0m"
    
          ANSI (  8, 40 )
          ' Is device present?
          I2CStart
          I2CSend ( MCP23017_DEVICE_1 )
          I2CStop
    
          if I2CSendState = False  then
            HSerSend 27
            HSerPrint "[1"
            HSerSend 0x3b
            HSerPrint     "31m"
            HSerPrint "Device Missing"
            HSerSend 27
            HSerPrint "[1"
            HSerSend 0x3b
            HSerPrint "32m"
            exit sub
          end if
    
    
        Set C off
        repeat 7                      ' Repeat this loop 7 times
               Rotate mcp23017_status Left      ' Rotate the portD to the left, shifting Carry Bit (equals 0 to first port)
               //!Here 
               ' set ports status on MCP23008
               mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_GPIOA, mcp23017_status )
               wait ddelay ms         ' wait
    '           Axe033cmd ( 254, 192 )
    '           Axe033String ( BYTETOBIN( mcp23017_status)  )
               set c off
        end Repeat                    ' Loop
        wait ddelay ms
    
    
        repeat 7                      ' Repeat this loop 7 times, 7 prevents a double flash of one of the LEDs
             Rotate mcp23017_status Right
             //!Here
            ' set ports status on MCP23008
            mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_GPIOA, mcp23017_status )
    '        Axe033cmd ( 254, 192 )
    '        Axe033String ( BYTETOBIN( mcp23017_status)  )
            wait ddelay ms           ' wait
            set c off
        end Repeat                    ' loop
    
        set mcp23017_status = 1               ' reinitialise the port
        //!Here
        mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_GPIOA, mcp23017_status )' turn all pins off
    
          ANSI (  8, 40 )
          HSerPrint "All Ports to Output"
          ANSI (  9, 40 )
          HSerPrint "Device Ports = 0x"
    
          ' setup MCP23017
          //!Here
          mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_IODIRA  , 0x00)' turn all pins output
    
          if ug_stateofmcp23017 = 0 then
             portsetvalue0 = 0x00
             HSerPrint hex(portsetvalue0)
    
              ' set ports status on MCP23017
              //!Here
              mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_GPIOA, portsetvalue0 )' turn all pins off
              ug_stateofmcp23017 = 1
            else
              portsetvalue1 = 0x55
              HSerPrint hex(portsetvalue1)
    
              ' set ports status on MCP23017
              //!Here
              mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_GPIOA, portsetvalue1 )' turn all pins on to state
              ug_stateofmcp23017 = 0
            end if
            HSerPrint "  "
    
          ANSI (  10, 40 )
          HSerPrint "Read Device  = "
          //!Here
                ' read ports status on MCP23008
          mcp23017_readbyte(MCP23017_DEVICE_1, MCP23017_GPIOA, ug_data )' read state
    
    
          if ug_stateofmcp23017 = 1 then
             HSerSend 27
             if ug_data <>  portsetvalue0  then
                 HSerPrint "[1"
                 HSerSend 0x3b
                 HSerPrint "31m"
    
              else
                 HSerPrint "[1"
                 HSerSend 0x3b
                 HSerPrint "32m"
    
              end if
          end if
    
          if ug_stateofmcp23017 = 0 then
             HSerSend 27
             if ug_data <> portsetvalue1  then
               HSerPrint "[1"
               HSerSend 0x3b
               HSerPrint "31m"
            else
               HSerPrint "[1"
               HSerSend 0x3b
               HSerPrint "32m"
            end if
          end if
    
          HSerPrint "0x"
          Hserprint hex(ug_data)
          Hserprint "    "
          HSerSend 27
          HSerPrint "[0m"
    
    
    end sub
    
     
  • mmotte

    mmotte - 2022-12-22

    David,

    The library is in the include directory ..... GreatcowBasic/Include/mcp23017.h
    GCB libraries end with '.h' but are the library not a header file.
    It can be used by an include statement at the beginning of you code.

    #include <mcp23017.h>
    

    There is a demo file for another I2C expander under greatCowBasic/demos/I2C_solutions/I2C_serial_expanders/I2C_pcf8574_serial_expander..... .gcb

    What processor will you be using? Just change the chip statement.

    #chip mega328p, 16
    

    GreatCowBasic has a very good Help page.
    And use this forum to ask question. We are not usually grumpy like this past month.

    GL
    mike

     
  • David Briscoe

    David Briscoe - 2022-12-22

    I'm agnostic about the chip at this stage (I'm using 16F819 or 16F1847 at the moment), but may choose a 18f series later on for the USB capability). I mainly use C (CCS C compiler) or assembly, but I've never used GCB. I've never used a MCP20317 or I2C either. I just want to start very simply with lighting 1 LED and then moving on to several LEDs and at the same time getting familiar with GCB. I guess reading the MCP23017.h file would help, but where does this header live?

     
  • Anobium

    Anobium - 2022-12-22

    This is a really good read for someone new to Great Cow BASIC. https://sourceforge.net/p/gcbasic/discussion/579126/thread/d648215933/#825c


    The headers are loaded into the include folder. So, you do not need to worry when you start.

    #chip 16F1847
    #include <mcp23017.h>
    
    #DEFINE MCP23017_DEVICE_1 0X40   // address 0x40 the 8 bit address
    
     ; ----- Define I2C Hardware settings
    
       #define HI2C_BAUD_RATE 100
       #define HI2C_DATA PORTB.4    // required pullup 4k
       #define HI2C_CLOCK PORTB.6   // required pullup 4k
    
       Dir HI2C_DATA in
       Dir HI2C_CLOCK in
    
       HI2CMode Master
    ; ----- end of I2C Hardware settings
    
    ;main program
    mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_IODIRA  , 0x00)' turn all pins output
    
    mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_GPIOA, 0x00 )  //set all off
    wait 1 s
    mcp23017_sendbyte(MCP23017_DEVICE_1, MCP23017_GPIOA, 0xFF ) //set all on
    

    This compiles. But, has not been tested.

    However, does try to compile. You will get an error in the library there is a typo on line 191. All very obvious as HII2CStop should be HI2CStop(remove the II for I).


    If this does work on the real hardware - you must try I2C discovery. This will confirm your setup. There are many I2C discover programs in your demos installation folder..

     
  • David Briscoe

    David Briscoe - 2023-01-08

    Thanks everyone,
    I'll give this a try over the next few weeks. If I come across any snags, I'll come back here for help.

    David

     

Log in to post a comment.