BLOG > Tutorial 7 for Arduino: I2C and Processing

This tutorial was featured on the official Arduino blog on 3/9/2011

As promised, this week brings another communications tutorial! In this video, we’ll use both the serial and processing knowledge that we gained last week, plus an I2C enabled temperature-sensing IC. We’ll use processing to generate a pretty room temperature display on your computer screen.  If you are new to processing, they have an excellent set of tutorials to help you get started.

You can download the files associated with this episode here:

GNU GPL License Distributed under the GNU General Public (Open-Source) License.
Please Attribute and Share-Alike.


  1. I just finished with putting together my first temperature display from this tutorial. I created the background art in Inkscape. I would like to show it to you. What is the best way to do that?


      1. Does that mean that it is the same for each unit of this device? What if I wanted to read the temperature in two different rooms? In other words, could I change the address to get two or more of these sensors on the same I2C bus?


  2. Just how accurate is the I2C temperature sensor at getting room temperature? Are there other temperature sensors? The readout with my build is consistently 70-72°F and the temperature feels much warmer. I can see the temperature change when I pinch the sensor between my fingers.

  3. Just tried using an HH10D humidity sensor. I keep getting nothing but zeroes back from the sensor. I used this code:

    * Read HH10D humidity sensor (
    * It contains a M24C02BN6 Eeprom with calibration values.
    * Author: Patrik Hermansson,
    * Date: 110309
    * Connections:
    * Vss – Gnd
    * Vdd – +3.3V
    * Fout – D5 (Mega168 pin 11)
    * SDA – A4 (pin 27)
    * SCL – A5 (pin 28)


    int rv = 0;

    void setup() {

    void loop() {
    Serial.print(“Sensitivity: “);
    Serial.print(“Offset: “);

    int readCalib( int deviceaddress, int calibAddress ) // deviceaddress is 1 according to datasheet
    // Set address

    // Request return value
    Wire.requestFrom(deviceaddress, 2);
    // Collect return value
    for (int c = 0; c < 2; c++ )
    if (Wire.available()) rv = rv * 256 + Wire.receive();
    return rv;

    Not sure what I am doing wrong. It says the device has an EEPROM and that in order to read out the correct humidity, 4 calibration factors need to be read out from the EEPROM at address of 10 and 11,12 and 13 for sensitivity, offset.

    This one blew me away a bit.

  4. This is a great video and series! Very informative and easy to follow. I have two quick questions;

    1) How many of these temperature sensors can you connect to each bus? I’m looking to connect about 10 if possible.

    2) If I had multiple sensors on one SDA and SCL line, would I need to connect pull up resistors for each sensor, or would all the sensors share two resistors at the start of the SD and SCL line?

    Thanks Sciguy!!

  5. Jeremy:
    I replicated your schematic using a T 74a7 with an ID of 79 and it worked fine except the temperature reads about 10F higher than it should accross the range frm 20-100F. Is there a means of inserting a calibrating resistor to compensate?
    I tried replacing one of the 10k pull up resistor with a variable pot with no change across the 10k range, and in the process found out tha the 10k pull up resistors had no effect at all on the readout.
    Would appreciate your comments.

    1. The pullup won’t affect the value – that’s just for setting the default digital values of the I2C lines. If it is consistently 10 degrees to high, why not just subtract 10 in software from whatever value you are reading?

      1. Thanks Jeremy:

        I adjusted as follows:

        int c=Wire.receive()-5;

        Still playing with the correction. But for now -5F seems to work well

        Thanks a lot

  6. Hi Jeremy,

    Great demo.

    It’s not the same components, but I have a SRF10 ultra sonic range sensor connected to an Arduino Pro Mini, and I’m trying to get the I2C protocol to work but it’s not happening. Based on my testing (println to check for code progression), I found that when the code gets to the “endTransmission” instruction, it freezes, and nothing else happens. It looks like this has been a problem, but I don’t know how to get around it. Any idea?


  7. Hi Jeremy,

    Your tutorials are the best. Thanks for all your effort. As with others above, I’m interested in using more than one sensor on the bus, but am aware that I will need to change the address of the other sensors so that there isn’t a data crash.

    How would I
    a) write a new address to a device and
    b) poll each sensor individually to recover the temperature at each sensor?

    I must admit that my biggest difficulty is understanding how to use library functions. I don’t know what each one holds or how to use them correctly.

    What resources are there that will explain how to use libraries?

    1. Most I2C devices cannot have new ID’s assigned to them, so you need to find ones with different ID’s. An alternative is to bit-bang two I2C devices with the same ID on different bus lines.

      The best way to understand libraries is to check out the source code and see how the functions are written.

  8. Hi,
    Very good tutorial. I have two questions, so far:
    1. The serial communication to the computer, is in fact an emulation of an RS232 via the USB right ? You are not really doing an RS232 link betwen the Arduino and your PC…
    2. If I got it right, the Arduino, here, is a development tool. After you do your programing and testing, would you be able to “burn” a microcontroler in orther to have it embeded in a circuit?
    Thank you,

  9. Hello Jeremy!
    After your lessons I fill power in my hands and begin to wire different parts to my “clock”
    And I was success with LCD (COG 2×16 LCD board from
    But with I2C RTClock board (PCF8583 chip)I meet some difficulties.
    I’ve connected Vss and Ground to the board, pullup with 10kom SDA(5 to A4) & SCL(6 to A5) and …
    nothing else. (may be I have to wire 3 & 7 pin on chip to Vcc?)
    I was try to read time & date but it is fail.
    Help me< where I am wrong?

    thank you a lot!

  10. hi

    guys, help me in this error as i m new to arduino

    wire.send () has been renamed wire.write().

    what does that mean ???

    i copied the code and paste it in ardiuno window!!


  11. // New code for Arduino 1.0, library has changed slightly from older versions

    //Program by Jeremy Blum
    //Reads Temp in Celsius and Shows it on Computer

    //Include Wire I2C Library
    int temp_address = 72;

    void setup()
    //Create Serial Object (9600 Baud)

    //Create a Wire Object

    void loop()
    //Send Request
    Wire.beginTransmission(temp_address); //Start talking
    Wire.write(8); //Changed command send to write (8 bit device)
    Wire.endTransmission(); //Complete Transmission
    Wire.requestFrom(temp_address, 1); //Request 1 Byte
    while(Wire.available() == 0); //wait for response
    int c =; // Changed command from receive to read, Get the temp

    //do some math…
    int f = round(c*9.0/5.0 +32.0);




  12. I am trying to use PIC18f46j50 as a master and an uno as a slave. I have no problem using the Uno with another Uno. But when I try to use the PIC, even after several approaches to voltage level shifting, etc., I still get no ACK. Has anyone you know ever tried this and is there a protocol trick or other hidden issue here?

  13. Hi.
    I think I must be using a differnt version of developer to you? I have no font option in my tools?
    Mine was recently downloaded from the arduino site.
    What developer software are you using?

    1. I’ve found the proccessing site and downloaded the proccessor, it is similar to the one Iam using but I can’t see any way of uploading programs to the arduino?
      what am I missing

  14. Hi.!!
    I have a sht71 sensor. I’m training to using with arduino but it doesn’t show any number

    #include “Sensirion.h”

    const uint8_t dataPin = 9;
    const uint8_t clockPin = 8;

    float temperature;
    float humidity;
    float dewpoint;

    Sensirion tempSensor = Sensirion(dataPin, clockPin);

    void setup()

    void loop()
    tempSensor.measure(&temperature, &humidity, &dewpoint);

    Serial.print(“Temperature: “);
    Serial.print(” C, Humidity: “);
    Serial.print(” %, Dewpoint: “);
    Serial.println(” C”);


    void serialPrintFloat(float f){
    int decplace = (f – (int)f) * 100;

  15. Hi Jeremy,
    Great demo.
    It’s not the same components, but I have multiple sensors connected to an Arduino Uno, and I’m trying to get the I2C protocol to work but it’s not happening. Based on my testing (println to check for code progression), I found that when the code gets to the “endTransmission” instruction, it freezes, and nothing else happens. This has been a problem, and I don’t know how to get around it. Here are the links to the data sheets: ( and ( Any idea?

  16. Hello, Jeremy, Thank you for your work.
    When I read the sensor datasheet, it tells me the default address is 1001101(b). when i work that out in binary, I get 77. I don’t know whats up with the “b”. What am I doing wrong? Thank you for your time.

      1. Thank you, but that begs the question, if the datasheet states the address is 77, why do you declare the “temp_address=72”? in the sketch?

  17. Hello.
    I am writing the same program as you on Arduino. For some reason, the Wire.requestFrom is freezing the program. I used the Serial.println() to make sure. I used a link that you posted to try to find a way around it. But it still doesn’t work. What do you think I should do??

    1. That might mean it can’t communicate with the device. Do you have the ID correct? It could also be a result of which version of the IDE you are using.

  18. could you please help me to give a processing arduino program the can be using for reading DC/AC voltage from 0-700V, Resistor from 0 Ohm to 2 Mega Ohm and 0-10 Ampere current meter.

  19. Hey Jeremy!I have some doubts here.
    In the following processing program
    void serialEvent (Serial port)
    data = port.readStringUntil(‘.’);
    Here “serialEvent” and “readStringUnit” are not marked in orange which means they are not class and method in Processing. So why can they be ran here in the Processing development environment. Also I want to know where are they from?

    Thank you for your kind help!!
    Waiting for your reply!!

  20. I’ve seen most of your tutorials, and enjoy them all. Haven’t had anything that’s implements i2c until I got myself an RTC from st micro and have been having some issues. My troubles lie, I think, in the clock and data lines. I have pull up resistors in place, but after watching this video again, I noticed what will hopefully be my resolution. You mentioned connecting SDA to A4, and SCL to A5. I’ve been connecting to a couple of pins on the AREF side of my uno (they’re labeled SDA and SCL underneath). Am I not wiring my device to the correct pins? Or is there potentially another issue I should look for?

  21. Hi Jeremy,
    thank you for the tutorials.
    I was fighting also with hte address of the device as i could not find the value in the (online) datasheet.
    So i tweaked s.o. sketch to increase the address value until it can read a temperature.
    you can see the valid address in the serial Monitor.

    #include “Wire.h”
    //wire library

    #define address 0x01 + l
    //address of the temperature sensor

    #define delayC 10
    //delay count in ms

    #define baudrate 9600
    //baudrate for communication
    int l;
    void setup()


    void loop()
    Serial.print(“temperature in Celsius: “);
    //let’s signal we’re about to do something

    int temperature;
    //temperature in a byte

    //start the transmission


    Wire.requestFrom(address, 1);
    if (Wire.available()) {
    temperature =;
    Serial.println(” address”);
    } else {

    Serial.println(“Increasing address”);

    //end the transmission


    Maybe it is usefull to s.o. else.
    But i still wonder how you can handle more davices with the sam address on the bus,
    as i can not find ‘adjustable’ sensores out there

  22. Thanks for the videos , can you please do a video of an eeprom maybe AT24C11, ateml I2C eeprom, that only read the content of the eeprom.
    My eeprom already have some calibration data, that i am trying to download.

  23. thanks for the videos dude… i was using an accelerometer…..ADXL345…and the data sheet says ” With the ALT ADDRESS pin high, the 7-bit I2C address for the device is 0x1D, followed by the R/Figure 40Table 11Table 12Figure 41W bit. This translates to 0x3A for a write and 0x3B for a read ” …so how do i set the device address and read and write to it??
    thanks in advance

  24. I have replicated the circuit exactly on a prototype shield, but when I run the processing code the window pops up with nothing written on it, just a black screen. Can u please help me?

  25. import processing.serial.*;
    Serial port;
    int inp = 0;
    int wdt=800, ht=600;
    void setup()
    port= new Serial(this,Serial.list()[0],9600);
    void serialEvent (Serial port)
    void draw()
    text(inp, 400,300);

    Please help me the text is over lapping rather than refreshing and its my arduino code

    //declare variables
    float tempC;
    int tempPin = A0;

    void setup()
    Serial.begin(9600); //opens serial port, sets data rate to 9600 bps

    void loop()
    tempC = analogRead(tempPin); //read the value from the sensor
    tempC = (5.0 * tempC * 100.0)/1024.0;//convert the analog data to temperature
    int f = round(tempC*9.0/5.0 +32.0);
    Serial.print((byte)tempC);//send the data to the computer
    delay(500); //wait one second before sending new data


  26. It’s a great lesson. Can your help me, how to connect together BMP085 on 3.3V and DS1307 on 5V?

  27. I liked the processing but I am more hardware focused. I think that seeing several I2C devices on the bus would be useful. To demonstrate this I am thinking maybe adding two separately addressable 16bit IO expanders, like TI 9555s. One of them could be used to output temperature on a 2×7-segment LED display. The other 9555 could be used to get inputs and outputs, controlling various equipment and verifying it is running like a couple of fans, a heater, and some duct dampers. A nice bonus might be to have several temperature sensors and a multiplexer that selects which one is being read, (powered up).

  28. I have this code using atmega1281… I am using tcs3471 color sensor my projects is still not working and I don’t know why… I’m a beginner in using arduino…

    * The I2C library code is from DSSCircuits

    const int PIN_MODE_LED = 13;
    const int BACK_LED = 7;

    const byte COMMAND = 0x80; //(W) Specifies register address
    const byte REPEATED_BYTE = 0x00;
    const byte AUTO_INC = 0x20;
    const byte SPECIAL_FUNC = 0x60;
    const byte RGBC_INT_CLR = 0x06;

    const byte REG_ENABLE = 0x00; //(R/W) Enables states and interrupts
    const byte REG_ATIME = 0x01; //(R/W) RGBC ADC time
    const byte REG_WTIME = 0x03; //(R/W) Wait time
    const byte REG_AILTL = 0x04; //(R/W) RGBC interrupt low threshold low byte
    const byte REG_AILTH = 0x05; //(R/W) RGBC interrupt low threshold high byte
    const byte REG_AIHTL = 0x06; //(R/W) RGBC interrupt high threshold low byte
    const byte REG_AIHTH = 0x07; //(R/W) RGBC interrupt high threshold high byte
    const byte REG_PERS = 0x0C; //(R/W) Interrupt persistence filters
    const byte REG_CONFIG = 0x0D; //(R/W) Configuration
    const byte REG_CONTROL = 0x0F; //(R/W) Gain control register
    const byte REG_ID = 0x12; //(R) Device ID
    const byte REG_STATUS = 0x13; //(R) R Device status
    const byte REG_CDATA = 0x14; //(R) Clear ADC low data register
    const byte REG_CDATAH = 0x15; //(R) Clear ADC high data register
    const byte REG_RDATA = 0x16; //(R) Red ADC low data register
    const byte REG_RDATAH = 0x17; //(R) Red ADC high data register
    const byte REG_GDATA = 0x18; //(R) Green ADC low data register
    const byte REG_GDATAH = 0x19; //(R) Green ADC high data register
    const byte REG_BDATA = 0x1A; //(R) Blue ADC low data register
    const byte REG_BDATAH = 0x1B; //(R) Blue ADC high data register

    const byte I2C_ADDR = 0x29;

    const byte FULL_SCALE_RANGE_2g = 0x0;
    const byte FULL_SCALE_RANGE_4g = 0x1;
    const byte FULL_SCALE_RANGE_8g = 0x2;

    unsigned int CDATA = 0, RDATA = 0, GDATA = 0, BDATA = 0;
    byte STAT;
    byte ID;

    Read register content into buffer.
    The default count is 1 byte.

    The buffer needs to be pre-allocated
    if count > 1
    void regRead(byte reg, byte *buf, byte count = 1) {
    byte command;
    command = COMMAND | AUTO_INC | reg;
    I2c.write(I2C_ADDR, command);, reg, count);

    for (int i = 0; i < count; i++)
    *(buf + i) = I2c.receive();

    Write a byte value into a register
    void regWrite(byte reg, byte val) {
    byte command;
    command = COMMAND | AUTO_INC | reg;
    I2c.write(I2C_ADDR, command, val);

    void getColor(unsigned int *C, unsigned int *R, unsigned int *G, unsigned int *B) {
    byte buf[8];

    digitalWrite(PIN_MODE_LED, HIGH);
    regRead(REG_STATUS, buf, 1);
    STAT = buf[0];
    regRead(REG_ID, buf, 1);
    ID = buf[0];
    regRead(REG_CDATA, buf, 8);
    *C = buf[0] << 8 | buf[1];
    *R = buf[2] << 8 | buf[3];
    *G = buf[4] << 8 | buf[5];
    *B = buf[6] << 8 | buf[7];

    digitalWrite(PIN_MODE_LED, LOW);

    void setup() {

    regWrite(REG_ENABLE, 0x03);

    pinMode(PIN_MODE_LED, OUTPUT);
    pinMode(BACK_LED, OUTPUT);

    digitalWrite(BACK_LED, HIGH);

    void loop() {
    getColor(&CDATA, &RDATA, &GDATA, &BDATA);

    Serial.print("\tID = ");
    Serial.print("\tSTATUS = ");
    Serial.print("\tC_DATA = ");
    Serial.print("\tR_DATA = ");
    Serial.print("\tG_DATA = ");
    Serial.print("\tB_DATA = ");

  29. Hi
    Great tutorial
    I need several temperatue sensors for a project but all the TC74A0’s have the same address of 72.
    How do I change there addesses so they are all different or is there away around the problem
    many thanks

  30. Jeremy, in the following code (taken from another website) it is bringing in data from the serial port and printing in the processing monitor screen values such as 2,123,175. I am trying to figure out how to take the string coming in and assign descriptions to the values like pitch = 2, roll = 123, and yaw = 175. Can you please help? Thanks for your help in advance.

    import processing.serial.*;

    Serial myPort; // Create object from Serial class
    char HEADER = ‘H’; // character to identify the start of a message
    short LF = 10; // ASCII linefeed
    short portIndex = 0; // select the com port, 0 is the first port
    int c;
    void setup() {
    size(200, 200);

    // WARNING!
    // If necessary, change the definition of portIndex at the top of this
    // sketch to the desired serial port.
    println(” Connecting to -> ” + Serial.list()[portIndex]);
    myPort = new Serial(this,Serial.list()[portIndex], 9600);

    void draw() {

    void serialEvent(Serial p)
    String message = myPort.readStringUntil(LF); // read serial data

    if(message != null)
    String [] data = message.split(“,”); // Split the comma-separated message

    if(data[0].charAt(0) == HEADER) // check for header character in the first field
    for( int i = 1; i < data.length-1; i++) // skip the header and terminating cr and lf
    int[] value = int(splitTokens(message, ",*"));
    //int value = Integer.parseInt(data[i]);
    println("Value" + i + " = " + value); //Print the value for each field



      1. Thanks for your response. I could do that but I would like to split it up in processing so I can use each value in other parts of the program that I will add once I get this resolved.

        1. String s1 = “Chernenko”;
          String s2 = “Brezhnev”;
          String sc1 = s1 + s2;
          String sc2 = s1 + “, Andropov, ” + s2;
          println(sc1); // Prints “ChernenkoBrezhnev”
          println(sc2); // Prints “Chernenko, Andropov, Brezhnev”

          String s1 = “Gorbachev”;
          int i = 1987;
          String sc1 = s1 + i;
          println(sc1); // Prints “Gorbachev1987”

          1. Thanks for the reply. I was wondering if it was Better to send separate strings from arduino to processing. I’m just thinking it would be easier to extract the data from multiple strings then from one serial string. My problem now is by using the “split” command with a comma as the delimiter it reads to the first comma and pulls that data but it scraps the rest of the data.

  31. Hey there.. nice tutorials! :)
    Well.. I’m making a color sensor and I’ve got the arduino program running just fine. I want to display the color using tutorial 6 and tutorial 7. My problem is that I don’t know how should I send them three variables I’m using to store the color values for red, green and blue on arduino. And how do I fetch this values in the string and use them as integers to change de backbround color.

    I wish my question has been specific enough.

  32. hi, i’ve read the datasheets from arduino nano, uno and mega, and realised that there’s only 1 SDA and 1 SCL for each micro, do you know if it is possible to connect 2 or more sensors using I2C protocol on one arduino?

      1. I replicated your schematic using a 74a0(id72) and 74a3(id75). it worked fine when connected one of them. Both do not work together. Do they can work together.
        Do Arduino can power more then one of these sensors.

        Would appreciate your comments.

        1. Which arduino you have and how you powered your devices?

          By spec., each arduino pin can supply pin up to 40mA (that is actually from ATMega328 spec). Thus, if I2C device is powered from 3.3V arduino pin, max current can be drawn is 50mA.

  33. Appreciate you Jeremy.. So what about DHT11 temp sensor? Is it applicable for I2C.. I have searched web for it but couldn’t get accurate info… I can’t find a way to indicate sensor data in Processing.. Also it requires a special library to work on an arduino sketch… How can I deal with that?

  34. Actually, there is no need to use floating point library and enlarge used memory and slow speed of FP arithmetic.

    The following:
    int f = round(c*9.0/5.0 +32.0);

    Can be simply used integer arithmetic:
    int f = (c * 9) / 5 +32;

    Compiler should follow the arithmetic priority rule, however brackets can be used to force that.

  35. Hi. I really like ur tutorials, very instructive. I’m working with a md25 controller, with I2C communication with an Arduino UNO. I would like to know if it is possible to command the md25 from “Processing” with I2C connection. I saw ur video, but i noticed that u run the program from arduino IDE, and “processing” just displays the information, not command.

    i have a problem, because i don’t find a “wire” library in “Processing” that let me stablish a I2C connection, so i could command the md25 with the notebook keyboard for example.

    the other solution is to get a Arduino Leonardo, that allows to command from mouse or keyboard, but i want to know if it is possible via “Processing”

    Thx for ur patience.

  36. Hi jeremy
    I want to send the values of Ultrasonic Sensor and Accelerometer Sensor to another Arduino UNO by using I2C

  37. Hello Jeremy. I’m really enjoying working through the projects in your book. You have a fantastic knack for teaching. Well done! I’m sure you have moved on to new projects since you published Exploring Arduino but I have a question. I’m working through Chapter 8. I think it’s great that you’ve included Processing in your tutorial. One problem. The new Processing 2.1.1. Version just doesn’t seem to work with the code you published. I think that the folks who have been working on Processing have really fallen short with their updates. Unlike the Arduino IDE, they really have not done a good job ensuring that newer versions are compatible with the old. I’ve tried to figure out how to modify your example processing sketch to be compatible with the new version but as a rank amateur I’ve just not been able to figure it out. Do you have a revised version of the Processing sketch for “display_temp.pde” that’s compatible with version 2.1.1? I’m really curious to know what needs to be changed to work with the newest version.

  38. Pingback: Ellentriek » Blog Archive » Arduino, Processing and sensors Part 2

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.