Wire | |
---|---|
Quick Look | |
Hardware | (External hardware) |
Include | Wire.h |
The Wire library provides methods for I2C / TWI communication.
This library allows you to commicate with I2C devices which are sometimes also called Two Wire Interface (TWI). I2C requires 2 signal lines for data transfer called SDA(Data) and SCL(Clock). To remain compatible with Arduino boards these lines are shared with Analong Pins A4 and A5 on chipKIT boards. It may be necessary to select the behavior of thse pins using a Jumper. Be sure to read the manual on your chipKIT board for proper setup.
Note that many of the chipKIT boards have multiple I2C ports. The Wire library only works with the default port. If you want to access the other ports you should forgo the Wire library and use the DTWI library instead.
A typical I2C bus will require one set of Pull-Up resistors shown as Rp in the diagram. Refer to the documentation of your devices for an idea of what to make these values. Typically you'll see resistors from 1K Ohm to 5K Ohm depending on the speed and number of devices on your bus.
Not shown in the diagram are the power and ground wires. At a minumum all devices must share a common ground in order to communicate with each other. I know right! They call it two wire but it takes 4 wires. The two wire refers to the signal lines only.
It's also important to note that the default SDA and SDC lines used by the Wire library are called out in the Board Def file for whatever board you are using. These are defined as DTWI0_SCL_PIN and DTWI0_SCA_PIN in the Board_Def.h file. DTWI0 is the only port uses by the Wire library. All other ports would only be accessible byt the DTWI library.
Label | chipKIT Pin | Definition | Notes |
---|---|---|---|
Serial Data (SDA) | A4 | Used for sending bi-directional data. | Often Jumper Selectable |
Serial Clock (SCL) | A5 | Used for sycronizing the data being transmitted | Often Jumper Selectable |
This example shows how to write to a AD5171 digital potentiometer. It will sweep it's value from 0 to 64 continuously.
// I2C Digital Potentiometer
// by Nicholas Zambetti <http://www.zambetti.com>
// and Shawn Bonkowski <http://people.interaction-ivrea.it/s.bonkowski/>
// Demonstrates use of the Wire library
// Controls AD5171 digital potentiometer via I2C/TWI
// Created 31 March 2006
// This example code is in the public domain.
// This example code is in the public domain.
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
}
byte val = 0;
void loop()
{
Wire.beginTransmission(44); // transmit to device #44 (0x2c)
// device address is specified in datasheet
Wire.send(0x00); // sends instruction byte
Wire.send(val); // sends potentiometer value byte
Wire.endTransmission(); // stop transmitting
val++; // increment value
if(val == 64) // if reached 64th position (max)
{
val = 0; // start over from lowest value
}
delay(500);
}
This example shows how to read and write to the SFR08 Ultrasonic Ranger Finder.
// I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder
// by Nicholas Zambetti <http://www.zambetti.com>
// and James Tichenor <http://www.jamestichenor.net>
// Demonstrates use of the Wire library reading data from the
// Devantech Utrasonic Rangers SFR08 and SFR10
// Created 29 April 2006
// This example code is in the public domain.
#include <Wire.h>
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial communication at 9600bps
}
int reading = 0;
void loop()
{
// step 1: instruct sensor to read echoes
Wire.beginTransmission(112); // transmit to device #112 (0x70)
// the address specified in the datasheet is 224 (0xE0)
// but i2c adressing uses the high 7 bits so it's 112
Wire.send(0x00); // sets register pointer to the command register (0x00)
Wire.send(0x50); // command sensor to measure in "inches" (0x50)
// use 0x51 for centimeters
// use 0x52 for ping microseconds
Wire.endTransmission(); // stop transmitting
// step 2: wait for readings to happen
delay(70); // datasheet suggests at least 65 milliseconds
// step 3: instruct sensor to return a particular echo reading
Wire.beginTransmission(112); // transmit to device #112
Wire.send(0x02); // sets register pointer to echo #1 register (0x02)
Wire.endTransmission(); // stop transmitting
// step 4: request reading from sensor
Wire.requestFrom(112, 2); // request 2 bytes from slave device #112
// step 5: receive reading from sensor
if(2 <= Wire.available()) // if two bytes were received
{
reading = Wire.receive(); // receive high byte (overwrites previous reading)
reading = reading << 8; // shift high byte to be high 8 bits
reading |= Wire.receive(); // receive low byte as lower 8 bits
Serial.println(reading); // print the reading
}
delay(250); // wait a bit since people have to read the output :)
}
/*
// The following code changes the address of a Devantech Ultrasonic Range Finder (SRF10 or SRF08)
// usage: changeAddress(0x70, 0xE6);
void changeAddress(byte oldAddress, byte newAddress)
{
Wire.beginTransmission(oldAddress);
Wire.send(0x00);
Wire.send(0xA0);
Wire.endTransmission();
Wire.beginTransmission(oldAddress);
Wire.send(0x00);
Wire.send(0xAA);
Wire.endTransmission();
Wire.beginTransmission(oldAddress);
Wire.send(0x00);
Wire.send(0xA5);
Wire.endTransmission();
Wire.beginTransmission(oldAddress);
Wire.send(0x00);
Wire.send(newAddress);
Wire.endTransmission();
}
*/
The Wire library includes underlying code from Digilent called DTWI. This library is essentially a wrapper for that code.
void begin(void);
Initialize the I2C port and join the bus as a master.
void begin(uint8_t address);
Initialize the I2C port and join the bus as a slave. Takes a 7bit slave address in the form of unit8_t.
void begin(int address);
Initialize the I2C port and join the bus as a slave. Takes a 7bit slave address in the form of an int.
void beginTransmission(uint8_t address);
Begin a trasmission with the given slave device address. Follow this command with subsequent write() commands and finish with the endTransmission() command. Takes a 7bit slave address.
void beginTransmission(int address);
Begin a trasmission with the given slave device address. Follow this command with subsequent write() commands. write() commands are queued up and transmitted with the endTransmission() command. Takes a 7bit slave address.
uint8_t endTransmission(void);
Transmits all bytes that were put in the queue by write().
uint8_t endTransmission(uint8_t fStopBit);
Transmits all bytes that were put in the queue by write(). Set the paramenter to 1 to send a stop bit. This indicates that you do not wish to attempt a repeated start.
uint8_t requestFrom(uint8_t address, uint8_t quantity);
uint8_t requestFrom(int address, int quantity);
Used by the master to request bytes from a slave device. The bytes can be retrieved using the available() and read() methods.
int write(uint8_t);
Places a byte in a queue to written to a slave device. Used after a beginTransmission() and before an endTransmission() call.
int write(uint8_t* data, uint8_t quantity);
Places a array of bytes in the queue to written to a slave device. Used after a beginTransmission() and before an endTransmission() call. Takes an array of bytes as data and the number of bytes to transmit as quantity.
int write(int data);
Places a byte in a queue to written to a slave device. Used after a beginTransmission() and before an endTransmission() call.
int write(char* data);
Places a string in the queue to written to a slave device. Used after a beginTransmission() and before an endTransmission() call.
uint8_t available(void);
Return the number of bytes ready to be retrieved with read(). Used after a call to requestFrom().
uint8_t read(void);
Reads a byte that was transmitted from a slave device to a master. Used after a call to requestFrom().
void onReceive( void (*)(int) );
Registers a function to be called when a slave device receives a transmission from a master. Useful for processing data.
void onRequest( void (*)(void) );
Register a function to be called when a master requests data from this slave device.