MCP23016

General project help for Adafruit customers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
lnino
 
Posts: 9
Joined: Mon Dec 17, 2012 11:22 am

MCP23016

Post by lnino »

Hi at all.

I am working on my MCP23016 to get a button input working.

At now I am able to say if a pin is Output or Input.
I can also set them to High or Low.
In case of that I can turn on a LED. (see my code)

But I want to wire a button on f.i. GP1.1 and I want to be able to check if this button is either pressed or not.

I already set GP1.1 to Input, but I don't know how to check the button status. Pressed or not.

Did someone realised this or can help me?

I use the fleury i2cmaster library for this. (http://homepage.hispeed.ch/peterfleury/ ... tware.html)

Thanks for the help.
Attachments
ioexpander.c
(719 Bytes) Downloaded 193 times

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: MCP23016

Post by adafruit_support_mike »

The chip Adafruit sells is the MCP23017, which is slightly different from the MCP23016. They're both 16-channel I2C expanders, but some of the options are different.

If you do have the '17, Adafruit has a library made especially for that chip: https://github.com/adafruit/Adafruit-MC ... no-Library

If you're using the '16, or just prefer to stick with the Fleury code, the MCP23016 datasheet (http://ww1.microchip.com/downloads/en/D ... 20090C.pdf) tells you how to read the chip's registers in section 1.9.3 (page 15). It looks like the master sends a 'read' command (a zero bit on the end of the address byte) then a byte that identifies the register it wants to read. The list of 'command bytes' is Table 1-3 (page 4), and according to that, you send the byte '0' to get GP0 and the byte '1' to get GP1.

User avatar
lnino
 
Posts: 9
Joined: Mon Dec 17, 2012 11:22 am

Re: MCP23016

Post by lnino »

Thanks for your reply and the explanation.

I made some evaluation boards fitting for MCP23016 therefore I would really like to go ahead with this IC.
But when I've done with it I will definately try another project with the MCP23017. The 17' is much faster. :-)

At the moment I will go forward with the fleury library.

I thought the adafruit library for MCP23017 and the wire library is only for arduino.

I am using a breadboard with ATmega168 and do code in ANSI C.

But now to the center of my question.

I tried to understand the section you highlighted in the manual, but was not able to write a code.
I think I could not interprete it the right way.

Maybe you can give me a code example according to the MCP23016, the fleury lib and my present code.

Thanks for your help.

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: MCP23016

Post by adafruit_support_mike »

lnino wrote:I thought the adafruit library for MCP23017 and the wire library is only for arduino.
Not really. The Arduino library is basically a set of utility routines for ATmega168 programming, mostly written in C. I think the Wire library is written in C++ for the sake of modularity, but aside from that, it's just a set of wrappers around I2C operations.
lnino wrote:Maybe you can give me a code example according to the MCP23016, the fleury lib and my present code.
I didn't know the Fleury library existed until yesterday, but it would probably look something like this:

Code: Select all

#define MCP23016    0x40
#define GP0         (unsigned char) 0
#define GP1         (unsigned char) 1

#   send the address:
i2c_start_wait( MCP23016 + I2C_WRITE );
i2c_write( GP1 );
i2c_stop();

#   read the data:
i2c_start_wait( MCP23016 + I2C_READ );
unsigned char gp1 = i2c_read_ack();
unsigned char gp2 = i2c_read_nak();
I was mistaken about the read process. You start by issuing a WRITE command and the address, then create the stop condition before sending any data. Then you issue a READ command and collect the data that's in the registers.

User avatar
lnino
 
Posts: 9
Joined: Mon Dec 17, 2012 11:22 am

Re: MCP23016

Post by lnino »

Thanks for your reply.

Hmm, I am not sure If I understood this right.

Regarding to my code would it look like this? (At the moment I am not at my evaluatin board to test it)

Original Code:

Code: Select all

int main(void)
	
	{	
	i2c_init();                             // initialize I2C library
	 
	SendData(0x06,0x00);					// Sets all Ports on GP0(0x06) to Output
	SendData(0x07,0xFF);					// Sets all Ports on GP1(0x07) to Input

		 while(1)
		 {
			Senddata(0x00,0x04); 				//Sets GP0.2 to High, Rest to Low --> LED turns on  (0x00=GP0)
		 }
	}
	
void SendData(uint8_t command, uint8_t port)
{
	i2c_start_wait(0x40);			// set device address and write mode
	i2c_write(command);
	i2c_write(port);
	i2c_stop();
}
Additional Function:

Code: Select all

void ReadData()
{
      i2c_start_wait(0x40 + ??);
      i2c_write(0x07);             //GP1
      i2c_stop();

      i2c_start_wait(0x40 + ??);
      unsigned char gp1 = i2c_read_ack();
      unsigned char gp2 = i2c_read_nak();
}
I used a question mark where I don't know which value I should use.
Did I get that right? Or this completely wrong?

And how do I check If the button is pressed?

Code: Select all

If (??? == ???)
{
   // Button is pressed - LED lights up
}

User avatar
lnino
 
Posts: 9
Joined: Mon Dec 17, 2012 11:22 am

Re: MCP23016

Post by lnino »

I studied the datasheet and some sample codes.

Now I think I understood.

Because I am right now not at my evaluation board, this is an untested code:

Might this work?

Code: Select all

#define F_CPU 14745600
#include <stdio.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include <util/delay.h>

#include "../libnerdkits/i2cmaster.h"

#define MCP23016	0x40

voaltile uint8_t inputregister;

void SendData(uint8_t, uint8_t);
uint8_t ReadData(uint8_t);

int main(void)
	
   {	
    i2c_init();                             // initialize I2C library
	 
	SendData(0x06,0x00);					// Sets all Ports on GP0 to Output
	SendData(0x07,0xFF);					// Sets all Ports on GP1 to Input
 
		 while(1)
		 {
		     inputregister = ReadData(0x06);                 // Reads Input on GP1
		 
		 	if(inputregister == 0b00000010 ) // When Button GP1.1 is pressed
			  { 
                    // Do something			
			  }

		 	elseif(inputregister == 0b00000100 ) // When Button GP1.2 is pressed
			  { 
                     // Do something			
			  }

		 	elseif(inputregister == 0b00001000 ) // When Button GP1.3 is pressed
			  { 
                      // Do something			
			  }
		 }
	}	

uint8_t ReadData(uint8_t command)
{ 
  uint8_t  data;

  i2c_start_wait(MCP23016 | 0x00);		// Write
  i2c_write(command);					// GP0 or GP1
  i2c_stop();
				
  i2c_rep_start(MCP23016 | 0x01);		// Read
  data = i2c_readNak();
  i2c_stop();

  return data;
}

void SendData(uint8_t command, uint8_t port)
{
	i2c_start_wait(MCP23016);			// set device address and write mode
	i2c_write(command);
	i2c_write(port);
	i2c_stop();
}

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: MCP23016

Post by adafruit_support_mike »

That looks like the right sequence. The real test will be on the board though.

User avatar
soerena
 
Posts: 57
Joined: Fri Nov 16, 2012 7:00 am

Re: MCP23016

Post by soerena »

MCP23016
by lnino » 26 Feb 2013 19:07

Hi at all.

I am working on my MCP23016 to get a button input working.

At now I am able to say if a pin is Output or Input.
I can also set them to High or Low.
In case of that I can turn on a LED. (see my code)

But I want to wire a button on f.i. GP1.1 and I want to be able to check if this button is either pressed or not.

I already set GP1.1 to Input, but I don't know how to check the button status. Pressed or not.

Did someone realised this or can help me?

I use the fleury i2cmaster library for this. (http://homepage.hispeed.ch/peterfleury/ ... tware.html)

Thanks for the help.

Hi, I'm using 3 10pf caps in parallel (instead of 1 33pf) on the clock pin 9 to GND. I was wondering if you have any idea if this would work? Obviously I can't get it working, but I don't know if it has anything to do with the cap value.

Søren

User avatar
zener
 
Posts: 4567
Joined: Sat Feb 21, 2009 2:38 am

Re: MCP23016

Post by zener »

That would make 30pF which should be close enough to 33pF.

Locked
Please be positive and constructive with your questions and comments.

Return to “General Project help”