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.
MCP23016
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- lnino
- Posts: 9
- Joined: Mon Dec 17, 2012 11:22 am
MCP23016
- Attachments
-
- ioexpander.c
- (719 Bytes) Downloaded 193 times
- adafruit_support_mike
- Posts: 67446
- Joined: Thu Feb 11, 2010 2:51 pm
Re: MCP23016
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.
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.
- lnino
- Posts: 9
- Joined: Mon Dec 17, 2012 11:22 am
Re: MCP23016
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.
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.
- adafruit_support_mike
- Posts: 67446
- Joined: Thu Feb 11, 2010 2:51 pm
Re: MCP23016
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:I thought the adafruit library for MCP23017 and the wire library is only for arduino.
I didn't know the Fleury library existed until yesterday, but it would probably look something like this:lnino wrote:Maybe you can give me a code example according to the MCP23016, the fleury lib and my present code.
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();
- lnino
- Posts: 9
- Joined: Mon Dec 17, 2012 11:22 am
Re: MCP23016
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:
Additional Function:
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?
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();
}
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();
}
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
}
- lnino
- Posts: 9
- Joined: Mon Dec 17, 2012 11:22 am
Re: MCP23016
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?
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();
}
- adafruit_support_mike
- Posts: 67446
- Joined: Thu Feb 11, 2010 2:51 pm
Re: MCP23016
That looks like the right sequence. The real test will be on the board though.
- soerena
- Posts: 57
- Joined: Fri Nov 16, 2012 7:00 am
Re: MCP23016
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
- zener
- Posts: 4567
- Joined: Sat Feb 21, 2009 2:38 am
Re: MCP23016
That would make 30pF which should be close enough to 33pF.
Please be positive and constructive with your questions and comments.