External Links

Creative Science Centre



This is a popular bus and protocol and there are many devices that now use it. I2C uses a master / slave type of arrangement where there is only one device (master) that controls the bus and one or many other devices that sit on the bus (slave)

Most of the time the ByPic microcontroller will be the master device. Reading and writing the I2C bus requires start and stop conditions the following generic examples may be useful.

Writing Example

i2c_putc(data) .... etc.

Open is only required once per reset. The address given for the start is the device (8 bit) address and must be an even number. An even number ensures that the read write bit is set to write (0).

Reading Example


In this example the address will be an odd number, e.g. 0x31,0x33 etc.. as this will set the read/write bit to 1 to tell the I2C bus that the slave should send out information. I2C uses an ACK (acknowledge) and NAK (not - acknowledge) system for checking when the bytes are sent correctly. In the case of reading a byte from the slave, the last read should include '1' as shown above in the i2c_getc() parameter.

I2C Terminal

// #include "http://www.byvac.com/mBlib/flb/Library/2016/lib_i2cterm.bas"

This is useful for debugging I2C devices and only has two commands but can address ANY I2C device. It does require that rookie is installed.

  • i2cf() // this will return a list of all of the I2C devices on the bus
  • i2c(<address>,"list of bytes to send",<bytes to return>)

Where: <address> is the 8 bit I2C address of the device
"list of bytes to send": Is a string with bytes separated by a space, e.g. "12 45 2", this can be "" but numbers must be in decimal.
<bytes to return>: Number of bytes that the slave will return, this can be 0


Most BV42nn devices will return the device ID which is 2 bytes when 0xa1 is sent. Assume the address is 70 then


This will return the device ID

I2C Slave

This is a more unusual configuration but is useful for when the microcontroller acts as the slave. It is normally used for intercommunication between microcontrollers.

// #include "http://www.byvac.com/mBlib/flb/Library/2016/lib_i2slave.bas"

The above code is specific to the MX1 or the MX3 device. Currently it is set up for MX1 as you will see that the MX3 code is commented out. To use with MX3, simply comment out the MX1 block. The code should be copied to a local file for use, to do this click on the above link and copy to PSPad.

Common Devices

DS1307 Real Time Clock, Data sheet pdf

// #include "http://www.byvac.com/mBlib/flb/Library/2016/lib_ds1307.bas"

This is a common RTC used with many devices. This is used with a time array, see also the date and time library which will work with this device via the array.

// 0 year full 2016
// 1 month 1 to 12
// 2 day of month 1 to 31
// 3 day of week 1 to 7 (Monday = 1)
// 4 hours
// 5 minutes
// 6 seconds


dim time(7) // must supply the array
rtc.get(*time()) // fills array with data

print time(rtc.YEAR)

constant RTCADR 0xd0 // DS1307 address

  • rtc.init()   // initialise i2c bus
  • rtc.get(*time())  // fills array with current time
  • rtc.set(*time())  // writes time array to DS1307
  • web.dt$(*time()) // returns "Mon, 16 Aug 2016 09:07:44" HTTP format
  • rtc.dt$() // returns current date and time in correct format

In addition to the above there is BCD conversions and functions to convert between 3 letter month day and back.

24C32  EEPROM, Data sheet pdf

// #include "http://www.byvac.com/mBlib/flb/Library/2016/lib_24c32.bas"

  • eeprom.init(i2caddress) // initialise i2c bus and sets address
  • eeprom.read(*buf(),start,bytes) // reads eeprom into a buffer - see code
  • eeprom.byteWrite(adr,byte) // writes a single byte to any address
  • eeprom.bufWrite(*buf(),start,bytes) // writes buffer to eeprom without needing to worry about page boundaries, slow about 200 bytes per second
  • eeprom.pageWrite(*buf(),start,bytes) // see code, only single pages (32 bytes) or part pages, must not go over a boundary.

AM2320/AM2321 Temperature and Humidity

// #include "http://www.byvac.com/mBlib/flb/Library/2016/lib_am3230.bas"

Data sheet for the AM2321

This is a more accurate version of the DHT11 and it is physically much smaller but quite complex to understand. The code provided by Ross (thanks) will read the temperature and humidity. There are two versions, the default that will work with rookie3 and below that and commented out is a version that will work with rookie 2. The only difference is that the prior version uses a global array to pass the data.

PCF8574 8 bit I/O Expnder

There is a 20x2 LCD driver example here.

LCD Display

This uses the ST703 type controller and is associated with the COG type displays