<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://www.marcelpost.com/wiki/index.php?action=history&amp;feed=atom&amp;title=PCA9535_IO_expansion_port</id>
	<title>PCA9535 IO expansion port - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.marcelpost.com/wiki/index.php?action=history&amp;feed=atom&amp;title=PCA9535_IO_expansion_port"/>
	<link rel="alternate" type="text/html" href="https://www.marcelpost.com/wiki/index.php?title=PCA9535_IO_expansion_port&amp;action=history"/>
	<updated>2026-04-23T01:00:11Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>https://www.marcelpost.com/wiki/index.php?title=PCA9535_IO_expansion_port&amp;diff=1354&amp;oldid=prev</id>
		<title>Admin: /* Schematic */</title>
		<link rel="alternate" type="text/html" href="https://www.marcelpost.com/wiki/index.php?title=PCA9535_IO_expansion_port&amp;diff=1354&amp;oldid=prev"/>
		<updated>2014-01-27T05:24:44Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Schematic&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;The PCA9535 and PCA9535C are 24-pin CMOS devices that provide 16 bits of General&lt;br /&gt;
Purpose parallel Input/Output (GPIO) expansion for I2C-bus/SMBus applications.&lt;br /&gt;
&lt;br /&gt;
Example schematic and code for Arduino Duemilanove and UNO (and possibly others).&lt;br /&gt;
&lt;br /&gt;
==Schematic==&lt;br /&gt;
&lt;br /&gt;
[[File:PCA9535 demo circuit.png]]&lt;br /&gt;
&lt;br /&gt;
Brief explanation:&lt;br /&gt;
&lt;br /&gt;
* The Arduino provides 5V to the port expander and LEDs through the I2C header&lt;br /&gt;
* The Arduino I2C pins are on Analog In port 4(SDA) and 5(SCL) (not shown)&lt;br /&gt;
* The INT line is held high to VCC with a 10k pullup resistor&lt;br /&gt;
* A 100R current limiting resistor is in line to HDR1:3 to provide +5V for a small probe lead&lt;br /&gt;
* The I2C address is set to 0x20 (decimal 32) by pulling A0, A1 and A2 low to ground&lt;br /&gt;
* HDR1:0 to 2 and the two LEDs are all on channel 0&lt;br /&gt;
* HDR2:0 to 1 are all on channel 1&lt;br /&gt;
* 100k pulldown resistors to ground are placed on all input pins&lt;br /&gt;
* 4k7 pullup resistors to +5V for the I2C lines are added on the Arduino side of the I2C bus (not shown)&lt;br /&gt;
&lt;br /&gt;
==Demo Circuit Board==&lt;br /&gt;
&lt;br /&gt;
In order to work with the SOIC package I decided to re-route some pins and not break out all ports so I could mount it on a DIP18 socket.&lt;br /&gt;
&lt;br /&gt;
The re-mapped pins and the completed demo board are shown below:&lt;br /&gt;
&lt;br /&gt;
[[File:PCA9535-to-DIP18.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:PCA9535 demo-board component side.jpg]]&lt;br /&gt;
&lt;br /&gt;
[[File:PCA9535 demo-board copper.jpg]]&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
&lt;br /&gt;
  Arduino demo code for the PCA9535 I2C port expander.&lt;br /&gt;
  Compatible with Arduino IDE version 1.0.5&lt;br /&gt;
  Last modified: 26 January 2014  &lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;Wire.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//  I2C 9535 device address is 0 1 0 0   0 0 0 (0x20, or 0d32)&lt;br /&gt;
#define PCA9535_ADDR 32&lt;br /&gt;
&lt;br /&gt;
int ch0=0;&lt;br /&gt;
int ch1=0;&lt;br /&gt;
&lt;br /&gt;
void setup() &lt;br /&gt;
{&lt;br /&gt;
  &lt;br /&gt;
  Wire.begin();&lt;br /&gt;
&lt;br /&gt;
  // setup channel 0 and 1&lt;br /&gt;
  Wire.beginTransmission(PCA9535_ADDR);&lt;br /&gt;
  Wire.write(6); // configure port 0 registers&lt;br /&gt;
  Wire.write(B00111111); // set bit 6+7 as output, the rest input&lt;br /&gt;
  Wire.write(B11111111); // set all as input&lt;br /&gt;
  Wire.endTransmission();&lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void loop() &lt;br /&gt;
{&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
  PCA_ReadBytes(); // read the values of channel 0 and 1&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
  // channel 0&lt;br /&gt;
  &lt;br /&gt;
  if (bitRead(ch0,0))&lt;br /&gt;
  {&lt;br /&gt;
    // bit 0 of channel 0 is set high&lt;br /&gt;
    blinkLed(0,1);  // blink one time&lt;br /&gt;
  }&lt;br /&gt;
  if (bitRead(ch0,1))&lt;br /&gt;
  {&lt;br /&gt;
    // bit 1 of channel 0 is set high&lt;br /&gt;
    blinkLed(0,2);  // blink two times&lt;br /&gt;
  }&lt;br /&gt;
  if (bitRead(ch0,2))&lt;br /&gt;
  {&lt;br /&gt;
    // bit 2 of channel 0 is set high&lt;br /&gt;
    blinkLed(0,3);  // blink three times&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // channel 1&lt;br /&gt;
&lt;br /&gt;
  if (bitRead(ch1,0))&lt;br /&gt;
  {&lt;br /&gt;
    // bit 0 of channel 0 is set high&lt;br /&gt;
    blinkLed(1,1);  // blink one time&lt;br /&gt;
  }&lt;br /&gt;
  if (bitRead(ch1,1))&lt;br /&gt;
  {&lt;br /&gt;
    // bit 1 of channel 0 is set high&lt;br /&gt;
    blinkLed(1,2);  // blink two times&lt;br /&gt;
  }&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  delay(1000);&lt;br /&gt;
  delay(1000);&lt;br /&gt;
  &lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void blinkLed(int lednr, int times)&lt;br /&gt;
{&lt;br /&gt;
  if (lednr==0)&lt;br /&gt;
  {&lt;br /&gt;
    lednr=B01000000; // bit 6 goes to the RED led &lt;br /&gt;
  } else {&lt;br /&gt;
    lednr=B10000000; // bit 7 goes to the GREEN led&lt;br /&gt;
  }&lt;br /&gt;
    &lt;br /&gt;
  while (times&amp;gt;0)&lt;br /&gt;
  {&lt;br /&gt;
    &lt;br /&gt;
    // turn led on I/O 0, pin 6 or 7&lt;br /&gt;
    Wire.beginTransmission(PCA9535_ADDR);&lt;br /&gt;
    Wire.write(2); // select IO channel 0&lt;br /&gt;
    Wire.write(lednr); // turn on port on bit 6 or 7&lt;br /&gt;
    Wire.endTransmission();&lt;br /&gt;
    delay(100);&lt;br /&gt;
    all_off();&lt;br /&gt;
    delay(300);&lt;br /&gt;
   &lt;br /&gt;
    times--;&lt;br /&gt;
    &lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void all_off()&lt;br /&gt;
{&lt;br /&gt;
    // turn off all outputs&lt;br /&gt;
    Wire.beginTransmission(PCA9535_ADDR);&lt;br /&gt;
    Wire.write(2); // select IO channel 0 output registers&lt;br /&gt;
    Wire.write(B00000000); // turn off all ports on channel 0&lt;br /&gt;
    Wire.endTransmission();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void PCA_ReadBytes()&lt;br /&gt;
{&lt;br /&gt;
  // reads the input registers of the PCA9535 device&lt;br /&gt;
  &lt;br /&gt;
  // read channel 0 first&lt;br /&gt;
  Wire.beginTransmission(PCA9535_ADDR);&lt;br /&gt;
  Wire.write(0); // we want to read channel 0 first&lt;br /&gt;
  Wire.endTransmission();&lt;br /&gt;
  Wire.requestFrom(PCA9535_ADDR,2); // read two bytes&lt;br /&gt;
  if(Wire.available())&lt;br /&gt;
  {&lt;br /&gt;
    ch0 = Wire.read(); // read channel 0&lt;br /&gt;
    ch1 = Wire.read(); // read other channel (channel 1)&lt;br /&gt;
  }&lt;br /&gt;
  Wire.endTransmission();  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Download the above code as a .zip file here.&lt;br /&gt;
&lt;br /&gt;
Arduino source code: [[File:PCA9535 Arduino demo.zip]]&lt;br /&gt;
&lt;br /&gt;
==Something on I2C bus speed for the Arduino==&lt;br /&gt;
&lt;br /&gt;
The following blurb on I2C speeds is not relevant in order to get the PCA9535 to work, because it works just fine with the standard Arduino. However, for debugging purposes it is very handy to know that the I2C bus speed can be modified. I didn&amp;#039;t have a better place to put this info, so here it is..&lt;br /&gt;
&lt;br /&gt;
The default prescaler is 1, and the default value for TWBR (on the Uno etc.) is 72. Thus:&lt;br /&gt;
&lt;br /&gt;
freq = 16000000 / (16 + 144) = 100000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  TWBR   prescaler   Frequency&lt;br /&gt;
 &lt;br /&gt;
  12       1       400   kHz  (the maximum supported frequency)&lt;br /&gt;
  32       1       200   kHz&lt;br /&gt;
  72       1       100   kHz  (the default)&lt;br /&gt;
 152       1        50   kHz&lt;br /&gt;
  78       4        25   kHz&lt;br /&gt;
 158       4        12.5 kHz&lt;br /&gt;
&lt;br /&gt;
To set the prescaler to 4 you need to set the bit TWPS0 in TWSR, so for example to have a clock of 12.5 kHz:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  Wire.begin ();&lt;br /&gt;
  TWBR = 158;  &lt;br /&gt;
  TWSR |= _BV (TWPS0);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
The internal buffer used for I2C communications is 32 bytes. That means you can transfer a maximum of 32 bytes in one transaction.&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
It also isn&amp;#039;t particularly clear, but the functions Wire.beginTransmission and Wire.write don&amp;#039;t actually send anything. They simply prepare an internal buffer (with a maximum length of 32 bytes) for the transmission. This is so that the hardware can then clock out the data at a high rate. For example:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  Wire.beginTransmission (SLAVE_ADDRESS);  // prepare internal buffer&lt;br /&gt;
  Wire.write (&amp;quot;hello world&amp;quot;);              // put data into buffer&lt;br /&gt;
  byte result = Wire.endTransmission ();   // transmission occurs here&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Source: http://www.gammon.com.au/forum/?id=10896&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>