NCD will be closed from Monday July 2nd through Friday July 6th for Independence Day. Orders placed during this time will begin processing on Monday July 9th. Dismiss

Serial to I2C Conversion

NCD has been manufacturing Serial to I2C Converters for some time now, but the most recent firmware improvements are easier to use and can save you a lot of time.  It’s now possible to talk to any I2C device with only a few commands.  Weather you are working with a PC or embedded micro, this guide will demonstrate the commands needed to read any kind of sensor or control any kind of I2C device.

This command reference guide will help get you started using AnyI2C hardware and software using our latest V3 hardware communications protocols.  If you’ve been following us on ncd.io, you will notice that all devices are now shipping with AnyI2C V3 firmware.  Here we will explain the improvements with detailed samples to help get you started quickly.

V3 Feature Overview

  • I2C Communications is now hardware, not software, Improving Reliability and Compatibility
  • I2C Communications speed has increased from 38KHz to 100KHz default
  • I2C Communications Speeds of 200, 300, and 400KHz are now possible
  • I2C Clock Stretching Functions have been Improved
  • A simplified I2C Write command has been added
  • A simplified I2C Read command has been added
  • AnyI2C Firmware V3 now Supports Wireless I2C Communications
    • Automatic Protocol Detection of Wireless vs NCD Protocols
    • Simply Wrap a Wireless API Frame Around the NCD API Frame

Please Note that AnyI2C Software has Not Been updated to the latest specifications, but we are working on this.  For now, please follow the following command samples shown below to exercise all new I2C hardware communication commands.

NCD API

Before sending ANYTHING to NCD Serial to I2C Converters, the NCD API protocol must be discussed.  The NCD API serves to protect all communication commands by wrapping them with a standardized header and checksum.  NCD devices will ignore any data that does not conform to the NCD API package standard.  As you can see, the NCD API format is essential.  

 

Transmitting Data

Before we dig too deep, it’s important to know the default communications baud rate is always 115.2K Baud.  Now let’s dig into our first I2C communications command.  The following command, 0xFE 0x21 is a simple test for 2-way communications between the device and the controller.  They are identified as Payload bytes in the packet structure shown below.  Since there are two Payload bytes, Byte 2 of the NCD API Frame must contain 0x02.  This number will always scale with the number of payload bytes in the API frame.  

 

Byte 1 0xAA NCD API Header Byte
Byte 2 0x02 NCD API Byte Count
Byte 3 0xFE Payload Byte 1 Command Header
Byte 4 0x21 Payload Byte 2 Test 2-Way Communications
Byte 5 0xCB NCD API Checksum 0xAA + 0x02 + 0xFE + 0x21 = 0xCB

Calculating the Checksum is relatively easy.  The checksum value is always truncated to the lower 8 bits and is calculated by adding Bytes 1 through 4 together.  There are a couple of easy ways to truncate the value to the lower 8 bits.  The easiest way is to define a variable that is only a byte in size.  Most programming languages will automatically truncate if the checksum is defined as a byte rather than a word or an integer.

Other programming languages may require you to accumulate the value as a integer or a word.  In this case, the lower 8 bits must be extracted using the mathematical AND function.  In the above example, 0xAA + 0x02 + 0xFE + 0x21 = 0x01CB.  

To extract the lower 8 bits, simply use the Bitwise AND function: 0x01CB AND 0xFF = 0xCB

Some programming languages also allow you to use the << function to shift bits to the left.

Receiving Data

In the previous section of this guide, we demonstrated how to send data to the Serial to I2C Converter at a baud rate of 115.2K Baud.  If you actually sent the data to a NCD controller, you should receive the following response packet (or something very similar):

Byte 10xAANCD API Header Byte 
Byte 20x01NCD API Byte Count 
Byte 30x55Payload Byte 1Response Byte
Byte 40x00NCD API Checksum0xAA + 0x01 + 0x55 = 0x00

The response packet above also includes a checksum for the 4th byte.  This checksum is calculated in the exact same way as the transmission packet.

Communicating to I2C Devices

Communicating to I2C devices over a serial connection presents some unique challenges.  We have hidden these challenges from the user to help simplify communications.  We will not go into the full depth of I2C communications here, as the topic is too far outside the scope of this guide.  Instead, we will focus on the two essential elements of communicating to I2C devices: Transmitting and Receiving.  All I2C devices have a start address.  This start address will be referenced in all transmit and receive operations.  It’s also helpful to understand that it is often necessary to send data to a I2C device then read data from a I2C device.  For instance, you will often be required to write to the I2C device to move the pointer to a specific register.  Using a second operation, you will read data from the register.  It is normal to write and then read from a I2C device using two transactions.

NCD Serial to I2C Converters use hardware interrupts for USART communications as well as hardware I2C features of the AnyI2C processor.  Hardware USARTS and I2C ports make for more stable communications in the long run.  Some I2C chips may be slow to provide a response.  In some cases, it may be necessary to send several communication queries to a given device to check flags and read data once the device is ready.  We will try to provide numerous samples for talking to many kinds of I2C devices.

As we progress through the samples shown below, it will be necessary for you to have some mechanism of communications to the AnyI2C processor via the USART.  There are many ways to do this, including Ethernet, Wireless, USB, or RS-232.  In some cases, the AnyI2C processor is installed on a hat or shield, ready to work with another microprocessor.  This guide will focus on communications through a virtual COM port USB interface operating at 115.2K Baud.  We will be using Comm Operator as we advance through the samples.  Comm Operator is our preferred tool for testing ALL controllers we manufacture. 
Comm Operator is available from SerialPortTool.com.

I2C Write: Transmitting I2C Data

Transmitting data to I2C devices will require 3 essential ingredients: Knowledge of the I2C Device (including the start address), Knowledge of the I2C Write Command and it’s structure, and Wrapping the I2C Command into a NCD API Frame (discussed earlier).  Once you have an understanding of these 3 essential components, writing I2C data is very straightforward.

The command structure for an I2C Write Operation is as follows:

0xBE, <I2C Start Address>, <Data Byte 1>, <Data Byte 2>, <Data Byte 3>, etc.  

Data bytes are optional for some I2C chips, as it all depends on the memory organization of each individual I2C device.  The data byte buffer is 25 bytes for small 8-pin AnyI2C processors and 100 bytes for larger AnyI2C processors.

Like all commands, I2C Write commands must be wrapped with a NCD API Frame.  Take a look at the sample below.

 

Byte 10xAANCD API Header Byte 
Byte 20x04NCD API Byte Count 
Byte 30xBENCD API Payload Byte 1I2C Write Command
Byte 40x41NCD API Payload Byte 2I2C Start Address
Byte 50x03NCD API Payload Byte 3I2C Data Byte
Byte 60x00NCD API Payload Byte 4I2C Data Byte
Byte 70xB0NCD API Checksum0xAA + 0x04 + 0xBE + 0x41 +0x03 + 0x00 = 0xB0

The above command works with the PCA9536 programmable GPIO chip.  If you happen to have this chip connected, you will receive the following response:

Byte 10xAANCD API Header Byte 
Byte 20x01NCD API Byte Count 
Byte 30x55Payload Byte 1Command was Successful
Byte 40x00NCD API Checksum0xAA + 0x01 + 0x55 = 0x00 

I2C Read: Receiving I2C Data

Receiving data from I2C devices is very similar to transmitting.  This operation is relatively easy, since it only requires a I2C Start Address and the total number of bytes to read from the I2C device.  Please note that a read operation typically follows a write operation.  

The command structure for an I2C Read Operation is as follows:

0xBF, <I2C Start Address>, <Number of Bytes to Read>

Read up to 25 bytes for small 8-pin AnyI2C processors and 100 bytes for larger AnyI2C processors.

This sample will be a little more complicated, as we need to do a little bit of setup before we can read from the PC9536 chip.  We will start with configuring the PCA9536 for input mode.  This only needs to be done one time to initialize the inputs for reading inputs.  Next, we will move the address pointer to location 0.  This memory address will reflect the status of the digital inputs.  Finally, we will perform a read operation and examine the result.

 

Step 1: Configure PCA9536 for Inputs

The PCA9536 include 4 programmable GPIO pins.  To read inputs, the following commands must be sent to the PCA9536 to configure the GPIO pins into Input mode.  Without this step, the inputs will never appear to change state.

Byte 10xAANCD API Header Byte 
Byte 20x04NCD API Byte Count 
Byte 30xBENCD API Payload Byte 1I2C WriteCommand
Byte 4 0x41NCD API Payload Byte 2I2C Start Address PCA9536
Byte 50x03NCD API Payload Byte 3PCA9536 Memory Location 0x03
Byte 60xFFNCD API Payload Byte 3PCA9536 Input Mode (0x00 = Out)
Byte 70xAENCD API Checksum0xAA + 0x04 + 0xBE + 0x41 + 0x03 + 0xFF = 0xAE

The controller will respond with the following bytes:

Byte 1 0xAA NCD API Header Byte
Byte 2 0x01 NCD API Byte Count
Byte 3 0x55 Payload Byte 1 Command was Successful
Byte 4 0x00 NCD API Checksum 0xAA + 0x01 + 0x55 = 0x00

Step 2: Move PCA9536 Address Pointer

The PCA9536 includes a small memory register used for various settings.  Location 0 may be used to read the inputs of all GPIO pins.  Before every read operation, the address pointer must be relocated to address location 0.

Byte 10xAANCD API Header Byte 
Byte 20x03NCD API Byte Count 
Byte 30xBENCD API Payload Byte 1I2C Write Command
Byte 4 0x41NCD API Payload Byte 2I2C Start Address PCA9536
Byte 50x00NCD API Payload Byte 3Move Pointer to Location 0
Byte 60xACNCD API Checksum0xAA + 0x03 + 0xBE + 0x41 + 0x00 = 0xB0

The controller will respond with the following bytes:

Byte 10xAANCD API Header Byte 
Byte 20x01NCD API Byte Count 
Byte 30x55Payload Byte 1Command was Successful
Byte 40x00NCD API Checksum0xAA + 0x01 + 0x55 = 0x00

Step 3: Read PCA9536 Inputs

The PCA9536 includes a small memory register used for various settings.  Location 0 may be used to read the inputs of all GPIO pins.  Before every read operation, the address pointer must be relocated to address location 0.

Byte 10xAANCD API Header Byte 
Byte 20x03NCD API Byte Count 
Byte 30xBFNCD API Payload Byte 1I2C Read Command
Byte 4 0x41NCD API Payload Byte 2I2C Start Address
Byte 50x01NCD API Payload Byte 3Read 1 Byte from I2C Chip
Byte 60xAENCD API Checksum0xAA + 0x03 + 0xBF + 0x41 + 0x01 = 0xAE

The above command works with the PCA9536 programmable GPIO chip.  If you happen to have this chip connected, you will receive the following response:

Byte 1 0xAA NCD API Header Byte
Byte 2 0x01 NCD API Byte Count
Byte 3 0x36 NCD API Payload Byte 1 Byte Returned from I2C Chip
Byte 4 0xE1 NCD API Checksum 0xAA + 0x01 + 0x36 = 0xE1

To read inputs continuously, repeat steps 2 and 3 above.

I2C Error Codes

Communicating to I2C devices is not always a successful operation.  There are several conditions that can lead to I2C error codes.  As the CPU moves through the different I2C communication routines, a error code is associated with each low-level I2C function is assigned.  The firmware is designed to immediately exit and return the first error that is detected.  This helps users identify different error conditions.  Here is a list of all possible error codes:

 

Decimal ErrorHex ErrorErrant RoutineError Description
910x5BI2C ReadTimeout Error, Chip did Not Respond, Check I2C Start Address
90/920x5A/0x5CI2C WriteTimeout Error, Chip did Not Respond, Check I2C Start Address
930x5DNot Yet ImplementedNot Yet Implemented
940x5EAcknowledgementTimeout Error, Chip did Not Acknowledge, See Below

 

Most errors are related to an incorrect I2C start address.  Make sure the correct I2C start address is indicated in all routines.  NCD Serial to I2C Converters also include full support for clock stretching.  A fixed timeout is hard-coded into the firmware.  Should a chip exceed this preset timeout, you will receive an Acknowledgement error.  NCD CPUs do not allow for blocking calls; therefore, the preset timeout value is very short, and may require you to request data in a different way (usually by checking a flag) before reading data.  

Errors are expressed in the form of a API return frame, which included both the error code and the inverse error code to help eliminate confusion regarding a return result.  Error codes are expressed in the following sequence:

 

Byte 10xAANCD API Header Byte 
Byte 20x04NCD API Byte CountErrors are Always 4 Bytes Long
Byte 30xBCNCD API Payload Byte 10xBC Indicates Error Code Header
Byte 4 0x5ANCD API Payload Byte 2Error Code 90 – Write Error
Byte 50xA5NCD API Payload Byte 30xFF – 0x5A = A5
Byte 60x43NCD API Payload Byte 40x43 Indicates Error Code Footer
Byte 70xACNCD API Checksum0xAA + 0x03 + 0xBF + 0x41 + 0x01 = 0xAE

I2C Communication Examples

Now that we have learned how to read and write data to the I2C port using serial commands, we need to simplify the context so we can move through samples at a faster pace.  From this point on, tables will not identify every single byte.  Instead, they will be referenced on a single line.  Each byte in the table row will correlate to the samples shown in “Communicating to I2C Devices” section.  Please keep in mind that NCD Serial to I2C Converters operate at 115.2K Baud by default, your software/firmware must be configured to this baud rate for proper operation.

Take a close look at the “I2C Read: Receiving I2C Data” section above.  We will re-write all tables in the following format to condense information into a smaller footprint.  These table will be re-written with communications data compress in the “Data” column as follows:

 OperationDataDescription
SendAA 04 BE 41 03 FF AFStep 1: Configure PCA9536 for Reading Inputs
ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 03 BE 41 00 ACStep 2: Move PCA9536 Address Pointer
ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 03 BF 41 01 AE

Step 3: Read PCA9536 Inputs

 ReceiveAA 01 36 E1Byte 0x36 Returned from I2C Chip

MCP23008 8-Bit GPIO

The MCP23008 is a common staple of the NCD product line.  We use this chip extensively for controlling relays and fets as well as input detection of contact closures and voltage detection applications.  The MCP23008 is one of our favorites.  It’s easy to use, expandable (supporting up to 8 devices on a single I2C bus), and very fast.  The MCP23008 also has an extensive history of reliability with our product line, making it our Go-To chip for all GPIO applications.  

The MCP23008 has a typical start address of 0x20, shown in all of the samples below.  Since 8 chips are supported per I2C port, the following I2C start addresses are possible (please keep in mind, the checksum MUST be re-calculated for each start address):

 

 Start AddressDescriptionA0 JumperA1 JumperA2 Jumper
0x20MCP23008 Chip 0RemovedRemovedRemoved
0x21MCP23008 Chip 1InstalledRemovedRemoved
0x22MCP23008 Chip 2RemovedInstalledRemoved
0x23MCP23008 Chip 3InstalledInstalledRemoved
0x24MCP23008 Chip 4

Removed

Removed

Installed

 0x25MCP23008 Chip 5InstalledRemovedInstalled
 0x26MCP23008 Chip 6RemovedInstalledInstalled
 0x27MCP23008 Chip 7InstalledInstalledInstalled

MCP23008 Initialization

Initializing the MCP23008 is a vital step before trying to utilize the GPIO capabilities.  The MCP23008 is equipped with 8 programmable digital I/O (GPIO), which may be used as 8 inputs, 8 outputs, or any combination of both inputs and outputs.  Below, we will demonstrate different ways to initialize the MCP23008 using the NCD Serial to I2C Converter operating at 115.2K Baud.  So plug in your MCP23008 relay board (or other MCP23008 powered device) and start experimenting:

 

 OperationDataDescription
SendAA 03 BE 20 FF 8AConfigure MCP23008 for 8 Digital Inputs 0xFF
SendAA 03 BE 20 FE 89Configure MCP23008 for 1 Digital Output (GPIO0) + 7 Digital Inputs (GPIO1:7) 0xFE
SendAA 03 BE 20 FC 87

Configure MCP23008 for 2 Digital Outputs (GPIO0:1) + 6 Digital Inputs (GPIO2:7) 0xFC

SendAA 03 BE 20 F0 7BConfigure MCP23008 for 4 Digital Output (GPIO0:3) + 4 Digital Inputs (GPIO4:7) 0xF0
SendAA 03 BE 20 00 8BConfigure MCP23008 for 8 Digital Outputs 0x00
ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

MCP23008 Programmable Pull-Ups

The MCP23008 includes programmable on-board pull-ups.  You may want to configure the pull-ups during initialization, depending on your application.  The pull-ups pull the GPIO inputs on NCD relay boards (if available) high.  Users may easily wire switches to the GPIO port pin when the inputs are enable.  Simply connect a switch between the input and ground.  When the switch is off, the input will be pulled high, reading a 1.  When the switch is on, the input will be grounded (over-powering the built-in pull-up resistor), and the input will read 0.

 

 OperationDataDescription
SendAA 04 BE 20 06 FF 91

Enable all 8 Pull-ups (FF Sets All Bits High, Enabling all Pull-Ups)

SendAA 04 BE 20 06 FE 90

Enable Pull-ups on GPIO1:7 (FE) for 1-Channel Relay Controllers

SendAA 04 BE 20 06 FC 8E

Enable Pull-ups on GPIO2:7 (FC) for 2-Channel Relay Controllers

SendAA 04 BE 20 06 F0 82

Enable Pull-Ups on GPIO4:7 (F0) for 4-Channel Relay Controllers

SendAA 04 BE 20 06 00 92

Disable all 8 Pull-ups for 8-Channel Relay Controllers (00 Sets All Bits Low)

 ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

Reading 8 Inputs

Reading 8 Inputs on the MCP23008 is a relatively simple operation.  The following commands will read inputs on GPIO0:7.  Please note the data returned from the MCP23008 will correspond to the binary value of all GPIO inputs.

 

 OperationDataDescription
SendAA 03 BE 20 09 94 

Move to Register 0x09 (Always Move to 0x09 Before Reading the GPIO Port)

 ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 03 BF 20 01 8D Read 1 Byte from GPIO Port
ReceiveAA 01 01 AC 0x00 Indicates All Inputs are Off
0x01 Indicates Input 1 (GPIO0) is On, All Other Inputs are Off
0xF0 Indicates Inputs 1-4 (GPIO0:3) are Off, All Other Inputs are On (GPIO4:7)
0xFF Indicates All Inputs are On

1 Relay + 7 GPIO

 

The MCP23008 can be configured to control a single relay with 7 programmable GPIO.  The following commands will control a single relay attached to GPIO0 and read inputs on GPIO1:7.

 OperationDataDescription
SendAA 04 BE 20 09 00 95Turn Off Relay 1 Connected to GPIO0 0x00
ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 04 BE 20 09 01 96 Turn On Relay 1 Connected to GPIO0 0x01
ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 03 BE 20 09 94 

Move to Register 0x09 (Always Move to 0x09 Before Reading the GPIO Port)

 ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 03 BF 20 01 8D Read 1 Byte from GPIO Port
ReceiveAA 01 01 AC 0x00 Indicates Relay 1 is Off and All other Inputs are Off
0x01 Indicates Relay 1 is On and All other Inputs are Off
0xFE Indicates Relay 1 if Off and All other Inputs are On
0xFF Indicates Relay 1 is On and All other Inputs are On

2 Relays + 6 GPIO

The MCP23008 can be configured to control 2 relays with 6 programmable GPIO.  The following commands will control Relay 1 and 2 attached to GPIO0:1 and read inputs on GPIO2:7.

 OperationDataDescription
SendAA 04 BE 20 09 00 95Turn Off Relay 1 Connected to GPIO0 0x00
ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 04 BE 20 09 01 96 Turn On Relay 1 Connected to GPIO0 0x01
ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 04 BE 20 09 02 97Turn On Relay 2 Connected to GPIO1 0x02
ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 04 BE 20 09 03 98Turn On Relays 1 and 2 Connected to GPIO0:1 0x03
ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 03 BE 20 09 94 

Move to Register 0x09 (Always Move to 0x09 Before Reading the GPIO Port)

 ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 03 BF 20 01 8D Read 1 Byte (0x01) from GPIO Port
ReceiveAA 01 01 AC 0x00 Indicates Relay 1 is Off and Relays 2 is Off, and All other Inputs are Off
0x01 Indicates Relay 1 is On and Relay 2 is Off, and All other Inputs are Off
0x02 Indicates Relay 1 if Off and Relays 2 is On, and All other Inputs are Off
0x03 Indicates Relay 1 if On and Relay 2 is On, and All other Inputs are Off
0xFE Indicates Relay 1 if Off and Relay 2 is On, and All other Inputs are On
0xFF Indicates Relay 1 is On and Relay 2 is On, and All other Inputs are On

4 Relays + 4 GPIO

The MCP23008 can be configured to control 4 relays with 4 programmable GPIO.  The following commands will control Relay 1 through 4 attached to GPIO0:3 and read inputs on GPIO4:7.

 OperationDataRelay 1Relay 2Relay 3Relay 4
SendAA 04 BE 20 09 00 95OffOffOffOff
SendAA 04 BE 20 09 01 96OnOffOffOff
SendAA 04 BE 20 09 02 97OffOnOffOff
SendAA 04 BE 20 09 03 98OnOnOffOff
SendAA 04 BE 20 09 04 99OffOffOnOff
SendAA 04 BE 20 09 05 9AOnOffOnOff
SendAA 04 BE 20 09 06 9BOffOnOnOff
SendAA 04 BE 20 09 07 9COnOnOnOff
SendAA 04 BE 20 09 08 9DOffOffOffOn
SendAA 04 BE 20 09 09 9EOnOffOffOn
SendAA 04 BE 20 09 0A 9FOffOnOffOn
SendAA 04 BE 20 09 0B A0OnOnOffOn
SendAA 04 BE 20 09 0C A1OffOffOnOn
SendAA 04 BE 20 09 0D A2OnOffOnOn
SendAA 04 BE 20 09 0E A3OffOnOnOn
SendAA 04 BE 20 09 0F A4OnOnOnOn
ReceiveAA 01 55 00 (Returned by All Commands Above)    

Reading data works the same way as shown before, keep in mind, the data received indicates the status of all inputs and relays in a binary pattern:

 OperationDataDescription
SendAA 03 BE 20 09 94 

Move to Register 0x09 (Always Move to 0x09 Before Reading the GPIO Port)

 ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 03 BF 20 01 8D Read 1 Byte (0x01) from GPIO Port
ReceiveAA 01 01 AC The Value Returned Represents the Binary Pattern of all Relays

8 Relays

The MCP23008 can be configured to control 8 relays.  The following commands will control Relay 1 through 8 in a Binary Pattern Corresponding to GPIO0:7.

 

 OperationDataRelay 1Relay 2Relay 3Relay 4Relay 5Relay 6Relay 7Relay 8
SendAA 04 BE 20 09 00 95OffOffOffOffOffOffOffOff
SendAA 04 BE 20 09 01 96OnOffOffOffOffOffOffOff
SendAA 04 BE 20 09 02 97OffOnOffOffOffOffOffOff
SendAA 04 BE 20 09 03 98OnOnOffOffOffOffOffOff
SendAA 04 BE 20 09 04 99OffOffOnOffOffOffOffOff
SendAA 04 BE 20 09 05 9AOnOffOnOffOffOffOffOff
SendAA 04 BE 20 09 06 9BOffOnOnOffOffOffOffOff
SendAA 04 BE 20 09 07 9COnOnOnOffOffOffOffOff
SendAA 04 BE 20 09 08 9DOffOffOffOnOffOffOffOff
SendAA 04 BE 20 09 09 9EOnOffOffOnOffOffOffOff
SendAA 04 BE 20 09 0A 9FOffOnOffOnOffOffOffOff
SendAA 04 BE 20 09 0B A0OnOnOffOnOffOffOffOff
SendAA 04 BE 20 09 0C A1OffOffOnOnOffOffOffOff
SendAA 04 BE 20 09 0D A2OnOffOnOnOffOffOffOff
SendAA 04 BE 20 09 0E A3OffOnOnOnOffOffOffOff
SendAA 04 BE 20 09 0F A4OnOnOnOnOffOffOffOff
SendAA 04 BE 20 09 10 A5OffOffOffOffOnOffOffOff
SendAA 04 BE 20 09 20 B5OffOffOffOffOffOnOffOff
Send AA 04 BE 20 09 30 C5OffOffOffOffOnOnOffOff
Send AA 04 BE 20 09 40 D5OffOffOffOffOffOffOnOff
Send AA 04 BE 20 09 50 E5OffOffOffOffOnOffOnOff
SendAA 04 BE 20 09 60 F6OffOffOffOffOffOnOnOff
SendAA 04 BE 20 09 70 05OffOffOffOffOnOnOnOff
Send AA 04 BE 20 09 80 15OffOffOffOffOffOffOffOn
Send AA 04 BE 20 09 90 25OffOffOffOffOnOffOffOn
Send AA 04 BE 20 09 A0 35OffOffOffOffOffOnOffOn
SendAA 04 BE 20 09 B0 45OffOffOffOffOnOnOffOn
Send AA 04 BE 20 09 C0 55OffOffOffOffOffOffOnOn
Send AA 04 BE 20 09 D0 65OffOffOffOffOnOffOnOn
Send AA 04 BE 20 09 E0 75OffOffOffOffOffOnOnOn
Send AA 04 BE 20 09 F0 85OffOffOffOffOnOnOnOn
Send AA 04 BE 20 09 FF 94 OnOn  OnOn On  OnOn  On
ReceiveAA 01 55 00
Returned by All Commands Above
        

Reading data works the same way as shown before, keep in mind, the data received indicates the status of all relays in a binary pattern:

 OperationDataDescription
SendAA 03 BE 20 09 94 

Move to Register 0x09 (Always Move to 0x09 Before Reading the GPIO Port)

 ReceiveAA 01 55 00Command Confirmed Successfully
SendAA 03 BF 20 01 8D Read 1 Byte (0x01) from GPIO Port
ReceiveAA 01 01 AC The Value Returned Represents the Binary Pattern of all Relays

MCP23017 16-Bit GPIO

The MCP230017 is another common staple of the NCD product line.  We use this chip extensively for controlling relays and fets as well as input detection of contact closures and voltage detection applications.  The MCP23017 (like the MCP23008) is another one of our favorites.  It’s easy to use, expandable (supporting up to 8 devices on a single I2C bus), and very fast.  The MCP23017 (like the MCP23008) also has an extensive history of reliability with our product line, making it our Go-To chip for all GPIO applications.  

The MCP23008 and MCP23017 both have a typical start address of 0x20, shown in all of the samples below.  Since 8 chips are supported per I2C port, the following I2C start addresses are possible (please keep in mind, the checksum MUST be re-calculated for each start address):

 

 Start AddressDescriptionA0 JumperA1 JumperA2 Jumper
0x20MCP23017 Chip 0RemovedRemovedRemoved
0x21MCP23017 Chip 1InstalledRemovedRemoved
0x22MCP23017 Chip 2RemovedInstalledRemoved
0x23MCP23017 Chip 3InstalledInstalledRemoved
0x24MCP23017 Chip 4

Removed

Removed

Installed

 0x25MCP23017 Chip 5InstalledRemovedInstalled
 0x26MCP23017 Chip 6RemovedInstalledInstalled
 0x27MCP23017 Chip 7InstalledInstalledInstalled

The MCP230017 is sometimes found in pairs on a single controller.  For instance, 24 and 32-Channel relay controller are equipped with 2 chips that are permanently hard-wired to avoid address conflicts.  Since there are 2 chips on these controllers, there are two possible start addresses for each controller.  The table below explains the start addresses and address jumper settings for these types of controllers.

 

 Start Address Chip 0
Channel 1-16
Start Address Chip 1
Channels 17-32
A0 JumperA1 Jumper
0x200x21RemovedRemoved
0x220x23InstalledRemoved
0x240x25RemovedInstalled
0x26 0x27InstalledInstalled

MCP23017 Initialization

Initializing the MCP23017 must be initialized for proper operation.  The MCP23017 consists of two 8-bit ports, each of which is configured separately for inputs outputs, or a mix of both.  NCD controllers typically allocate 8 bits as inputs or outputs.  Though the MCP23017 does support any combination of inputs and outputs on a single port, these configuration scenarios are outside the scope for use with most NCD controllers; therefore, we will focus on configuration examples applicable to NCD controllers.

 OperationDataDescription
SendAA 04 BE 20 00 00 8CInitialize Port A of MCP23017 at Address 0x20 as Outputs
SendAA 04 BE 20 01 00 8DInitialize Port B of MCP23017 at Address 0x20 as Outputs
SendAA 04 BE 21 00 00 8D

Initialize Port A of MCP23017 at Address 0x21 as Outputs

SendAA 04 BE 21 01 00 8EInitialize Port B of MCP23017 at Address 0x21 as Outputs
 SendAA 04 BE 20 00 FF 8BInitialize Port A of MCP23017 at Address 0x20 as Inputs
 SendAA 04 BE 20 01 FF 8DInitialize Port B of MCP23017 at Address 0x20 as Inputs
 SendAA 04 BE 21 00 FF 8CInitialize Port A of MCP23017 at Address 0x21 as Inputs
 SendAA 04 BE 21 01 FF 8DInitialize Port B of MCP23017 at Address 0x21 as Inputs
ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

MCP23017 Programmable Pull-Ups

Like the MCP23008, the MCP23017 also includes programmable pull-up resistors.  When pull-ups are enabled, the digital inputs are pulled high using a 100K resistor on each input.  This prevents the input from “floating”.  This also has the added benefit of making the inputs directly compatible with contact closure applications.  For instance, when pull-ups are enabled, the input will read high.  Simply connect a  switch between the input and ground.  When the switch is closed, the input will read low (0) and when the switch is opened, the input will pull up to a high (1) state.  Use the command below to control programmable pull-ups on the MCP23017.  Note that each input may be configured with pull-up resistors by simply providing a value from 00 to FF.  A value of 00 will disable the pull-ups on all inputs.  A value of FF will enable the pull-ups on all inputs.  Any value in between will control the pull-ups in the equivalent binary pattern.

 OperationDataDescription
SendAA 04 BE 20 0C FF 97Enable Pull-Ups on Port A of Address 0x20 (Equal to Relay Bank 1)
SendAA 04 BE 20 0D FF 98Enable Pull-Ups on Port B of Address 0x20 (Equal to Relay Bank 2)
SendAA 04 BE 21 0C FF 98

Enable Pull-Ups on Port A of Address 0x21 (Equal to Relay Bank 3)

SendAA 04 BE 21 0D FF 99Enable Pull-Ups on Port B of Address 0x21 (Equal to Relay Bank 4)
 SendAA 04 BE 20 0C 00 98Disable Pull-Ups on Port A of Address 0x20 (Equal to Relay Bank 1)
 SendAA 04 BE 20 0D 00 99Disable Pull-Ups on Port B of Address 0x20 (Equal to Relay Bank 2)
 SendAA 04 BE 21 0C 00 99Disable Pull-Ups on Port A of Address 0x21 (Equal to Relay Bank 3)
 SendAA 04 BE 21 0D 00 9ADisable Pull-Ups on Port B of Address 0x21 (Equal to Relay Bank 4)
ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

Reading Inputs

The MCP23017 consists of several registers that may be used for read/write operations.  In the examples shown below, we will show you how to move to the important registers for read and write functions.  The registers we will be demonstrating will allow you to read the inputs of any port.  If individual port pins (or entire ports) are set to output mode, these registers will allow you to read the status of the outputs along with the status of the inputs, effectively merging the output and input data together.  In the samples shown below, simply move the data pointer to the selected input, then execute the read operation.  Be sure to use the Read Operation the corresponds to the selected address.  For instance, if you move to Address 0x21, be sure to read the status using the 0x21 sample shown below.

 OperationDataDescription
SendAA 03 BE 20 12 9D Move Pointer to Relays in Bank 1 (Port A) Address 0x20
SendAA 03 BE 20 13 9EMove Pointer to Relays in Bank 2 (Port B) Address 0x20
SendAA 03 BE 21 12 9E

Move Pointer to Relays in Bank 3 (Port A) Address 0x21

SendAA 03 BE 21 13 9FMove Pointer to Relays in Bank 4 (Port B) Address 0x21
ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully
OperationDataDescription
 SendAA 03 BF 20 01 8DRead Inputs from Selected Memory Location of a Device with a Start Address of 0x20
ReceiveAA 01 FF AA0xFF Indicates All Inputs are High and All Relays are On at Start Address 0x20
 SendAA 03 BF 21 01 8E Read Inputs from Selected Memory Location of a Device with a Start Address of 0x21
ReceiveAA 01 FF AA0xFF Indicates All Inputs are High and All Relays are On at Start Address 0x21

Controlling Relays

The MCP23017 may be used for both input our output operations.  The functions shown below are intended for relay control, but are equally as effective for GPIO Port Output operations.  To control relays (or set the state of GPIO outputs), data must be stored in the correct register.  A single data byte is used to set the state of all outputs (or control up to 8 relays per port).  The data sent to the port is interpreted as a binary value, and the corresponding GPIO lines are set accordingly.

 OperationDataDescription
SendAA 04 BE 20 12 00 9ETurn Off All Relays in Bank 1 (Port A at Address 0x20)
SendAA 04 BE 20 12 FF 9DTurn On All Relays in Bank 1 (Port A at Address 0x20)
SendAA 04 BE 20 13 00 9F

Turn Off All Relays in Bank 2 (Port B at Address 0x20)

SendAA 04 BE 20 13 FF 9ETurn On All Relays in Bank 2 (Port B at Address 0x20)
SendAA 04 BE 21 12 00 9FTurn Off All Relays in Bank 3 (Port A at Address 0x21)
SendAA 04 BE 21 12 FF 9ETurn On All Relays in Bank 3 (Port A at Address 0x21)
SendAA 04 BE 21 13 00 A0Turn Off All Relays in Bank 4 (Port B at Address 0x21)
SendAA 04 BE 21 13 FF 9FTurn On All Relays in Bank 4 (Port B at Address 0x21)
ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

PCA9685 Pulse Width Modulation

The PCA9685 is a very versatile 16-Channel Pulse Width Modulation (PWM) controller, ideally suited for LED Dimming, servo motor control, motor speed control, proportional valve control, and much more.  The PCA9685 is a complex I2C interface device, so here, we will focus on very basic initialization and control applications.

PCA9685 Initialization

To initialize the PCA9685, send each of the commands shown below in the order shown.  Because of the complexity of the PCA9685, we strongly advise reviewing the datasheet, here will focus on getting it running.

 OperationDataDescription
SendAA 04 BE 40 00 00 AC Initialization Step 1
SendAA 04 BE 40 00 10 BC Initialization Step 2
SendAA 04 BE 40 FE 05 AF 

Initialization Step 3

SendAA 04 BE 40 00 00 AC Initialization Step 4
 SendAA 04 BE 40 00 A1 4D Initialization Step 5
ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

Controlling PWM Channels

The following samples will show you how to progressively increase the PWM value of each individual channel.  Note that PWM data is stored in LSB MSB format, please see below for examples.

 OperationDataDescription
SendAA 07 BE 40 06 00 00 00 01 B6Set Channel 1 to 256 Decimal LSB=0x00 MSB=0x01
SendAA 07 BE 40 0A 00 00 00 02 BBSet Channel 2 to 512 Decimal LSB=0x00 MSB=0x02
SendAA 07 BE 40 0E 00 00 00 03 C0

Set Channel 3 to 768 Decimal LSB=0x00 MSB=0x03

SendAA 07 BE 40 12 00 00 00 04 C5Set Channel 4 to 1024 Decimal LSB=0x00 MSB=0x04
SendAA 07 BE 40 16 00 00 00 05 CASet Channel 5 to 1280 Decimal LSB=0x00 MSB=0x05
SendAA 07 BE 40 1A 00 00 00 06 CFSet Channel 6 to 1536 Decimal LSB=0x00 MSB=0x06
SendAA 07 BE 40 1E 00 00 00 07 D4Set Channel 7 to 1792 Decimal LSB=0x00 MSB=0x07
SendAA 07 BE 40 22 00 00 00 08 D9Set Channel 8 to 2048 Decimal LSB=0x00 MSB=0x08
SendAA 07 BE 40 26 00 00 00 09 DESet Channel 9 to 2304 Decimal LSB=0x00 MSB=0x09
SendAA 07 BE 40 2A 00 00 00 0A E3Set Channel 10 to 2560 Decimal LSB=0x00 MSB=0x0A
SendAA 07 BE 40 2E 00 00 00 0B E8Set Channel 11 to 2816 Decimal LSB=0x00 MSB=0x0B
SendAA 07 BE 40 32 00 00 00 0C EDSet Channel 12 to 3072 Decimal LSB=0x00 MSB=0x0C
SendAA 07 BE 40 36 00 00 00 0D F2Set Channel 13 to 3328 Decimal LSB=0x00 MSB=0x0D
SendAA 07 BE 40 3A 00 00 00 0E F7Set Channel 14 to 3584 Decimal LSB=0x00 MSB=0x0E
SendAA 07 BE 40 3E 00 00 00 0F FCSet Channel 15 to 3840 Decimal LSB=0x00 MSB=0x0F
SendAA 07 BE 40 42 00 00 FF 0F FF Set Channel 16 to 4095 Decimal LSB=0xFF MSB=0x0F
ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

AS1115 LED Display Driver

The AS1115 is a I2C chip capable of controlling up to eight 7-Segment LED displays.  The examples shown below will help you initialize the display, set the brightness, and write digits to the LEDs.

AS1115 Initialization

The AS1115 is initialized by following the steps below.

 OperationDataDescription
SendAA 04 BE 00 09 07 7C Initialization Step 1
SendAA 04 BE 00 0A FF 75Initialization Step 2
SendAA 04 BE 00 0C 01 79

Initialization Step 3

SendAA 04 BE 00 0E 00 7AInitialization Step 4
 SendAA 04 BE 00 0B 03 7AInitialization Step 5
ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

Setting the Brightness

The following commands will control the brightness of the LED display.  While the examples shown below only show three levels of brightness, the display controller supports up 16 levels of brightness from F0 to FF.

 OperationDataDescription
SendAA 04 BE 00 0A F0 66 Set Brightness to Lowest Setting
SendAA 04 BE 00 0A F9 6FSet Brightness to Medium Setting
SendAA 04 BE 00 0A FF 75 

Set Brightness to Highest Setting

ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

Writing to the Display

The following commands will demonstrate writing digits to the display.  Note that select special characters may also be written to the display.

 OperationDataDescription
Send AA 04 BE 00 01 01 6E Write the Number 1 to Display Segment 1
Send AA 04 BE 00 02 02 70 Write the Number 2 to Display Segment 2
Send AA 04 BE 00 03 03 72

Write the Number 3 to Display Segment 3

Send AA 04 BE 00 01 04 71Write the Number 4 to Display Segment 1
Send AA 04 BE 00 02 05 73Write the Number 5 to Display Segment 2
Send AA 04 BE 00 03 06 75Write the Number 6 to Display Segment 3
Send AA 04 BE 00 01 0A 77Write “-” to Display Segment 1
Send AA 04 BE 00 02 0B 79Write “E” to Display Segment 2
Send AA 04 BE 00 03 0C 7BWrite “H” to Display Segment 3
Send AA 04 BE 00 01 0D 7AWrite “L” to Display Segment 1
Send AA 04 BE 00 02 0E 7CWrite “P” to Display Segment 2
Send AA 04 BE 00 03 0F 7E Write ” ” to Display Segment 3 (Turns Off Segment)
ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

Controlling the Decimal Point

Users have complete control of every decimal point, allowing every segment to have a decimal simultaneously if desired.  The decimal point is controlled by the most significant nibble of the display value byte.  For instance, if you want to write the number 1, you will send 0x01.  But if you want the number 1 followed by a decimal point, you will send 0xF1.  Sending all sample codes below will result in displaying 1.2.3. 

 OperationDataDescription
SendAA 04 BE 00 01 F1 5ETurn On the 1nd Decimal Point
SendAA 04 BE 00 02 F2 60Turn On the 2nd Decimal Point
SendAA 04 BE 00 03 F3 62

Turn On the 3rd Decimal Point

ReceiveAA 01 55 00
Returned by All Commands Above
Command Confirmed Successfully

ControlAnything.com and ControlEverything Site Migration Notes

©2018 National Control Devices, LLC

ncd.io

Made in the USA
5 Year Warranty
Free Shipping on orders over $100
Free Shipping on orders over $100

To learn something new, take the path that you took yesterday. ~John Burroughs

Log in with your credentials

or    

Forgot your details?

Create Account