HTU21D & 7_segment Temp Multiplexing

Quick question:

How can I interface with a I2C device and simultaneously multiplex a 4 digit 7_Segment display?

I’m making a simple LCD temperature display project. The 7_Segment display is driven from a single shift register and I’m multiplexing through the digits. For the temperature I’m using the HTU21D I2C device. The problem is the read time for the HTU21D (Sparkfun Library) is kinda long, perhaps a 1/10th of a second. So when the code retrieves the temperature, the display goes dark for a quite noticeable amount of time. I’m not sure how I can alleviate this flickering.

I know about the MAX7219, but my display is common anode and therefor incompatible.

Any ideas?

/* 
 HTU21D Humidity Sensor Example Code
 By: Nathan Seidle
 SparkFun Electronics
 Date: September 15th, 2013
 License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
 
 Uses the HTU21D library to display the current humidity and temperature
 
 Open serial monitor at 9600 baud to see readings. Errors 998 if not sensor is detected. Error 999 if CRC is bad.
  
 Hardware Connections (Breakoutboard to Arduino):
 -VCC = 3.3V
 -GND = GND
 -SDA = A4 (use inline 330 ohm resistor if your board is 5V)
 -SCL = A5 (use inline 330 ohm resistor if your board is 5V)

 */
 
//==============================================================================================================================

#include <Wire.h>
#include "SparkFunHTU21D.h"

HTU21D myHumidity; //Create an instance of the object

const int clock = 8; //   ,,D,LC,,   pin numbers on the board
const int latch = 9; //  -[______]
const int data = 10; //   ''''''''
const int digit_pin1 = 2; 
const int digit_pin2 = 3; 
const int digit_pin3 = 4; 
const int digit_pin4 = 5; 

int digits[3]; // individul digit values to be sent to the display
int time = 100; //refresh rate
              // 0  1   2   3  4   5   6   7   8  9
byte digit[10]= {1, 79, 18, 6, 76, 36, 32, 15, 0, 12}; // Bin values for 7 segment enumeration of decimal numbers with the decimal point

char temp_char [5];   // character array contaning temerature decimal digits
int decimal_location;   // location of the decimal point in the character array

//==============================================================================================================================

void setup()
{
  myHumidity.begin();
  
  pinMode(latch, OUTPUT);//Latch
  pinMode(clock, OUTPUT);//Clock
  pinMode(data, OUTPUT);//Data
  pinMode(digit_pin1, OUTPUT);
  pinMode(digit_pin2, OUTPUT);
  pinMode(digit_pin3, OUTPUT);
  pinMode(digit_pin4, OUTPUT);
  digitalWrite(latch, LOW);
  digitalWrite(digit_pin1, LOW);
  digitalWrite(digit_pin2, LOW);
  digitalWrite(digit_pin3, LOW);
  digitalWrite(digit_pin4, LOW);
}

//==============================================================================================================================

void loop()
{
  //float humd = myHumidity.readHumidity();
  float temp = myHumidity.readTemperature();
  
  temp = (temp*1.800 + 32);
  
  dtostrf(temp, 5, 2, temp_char);            // convert temp (float) to temp_char(character array)
  
  int j = 0;                                 // index for the digit
  for (int i=0; i<=4; i++) {                 // look at the first 5 elements of the char
    if (temp_char[i+1] == '.') {             // if the next element is the decimal
      digits[i] = temp_char[i] - 48;         // convert char to decimal number
      digits[j] = digit[digits[i]];          // store the binary number correcponding to the correct segments for the display
      i++;                                   // skip over that decimal point 
    }
    else {                                   // else if the next char is not a decimal
      digits[i] = temp_char[i] - 48;         // convert char to decimal number
      digits[j] = digit[digits[i]] + 128;    // store the binary number correcponding to the correct segments for the display
    }                                        // add 128 to turn off the decimal point on the display
    j++;                                     // increment digit
  }
  writeNumber();
}

//==============================================================================================================================

void writeNumber() {
  for (int z=0; z<=time; z++) {
    
    digitalWrite(latch, LOW);
    shiftOut(data, clock, MSBFIRST, digits[0]); // shift in the digit
    digitalWrite(latch, HIGH);
    digitalWrite(digit_pin1, HIGH); // flash the digit in the correct place
    delay (4);
    digitalWrite(digit_pin1, LOW); 
    
    digitalWrite(latch, LOW);
    shiftOut(data, clock, MSBFIRST, digits[1]); // shift in the digit
    digitalWrite(latch, HIGH);
    digitalWrite(digit_pin2, HIGH); // flash the digit in the correct place
    delay (4);
    digitalWrite(digit_pin2, LOW); 
    
    digitalWrite(latch, LOW);
    shiftOut(data, clock, MSBFIRST, digits[2]); // shift in the digit
    digitalWrite(latch, HIGH);
    digitalWrite(digit_pin3, HIGH); // flash the digit in the correct place
    delay (4);
    digitalWrite(digit_pin3, LOW); 
    
    digitalWrite(latch, LOW);
    shiftOut(data, clock, MSBFIRST, digits[3]); // shift in the digit
    digitalWrite(latch, HIGH);
    digitalWrite(digit_pin4, HIGH); // flash the digit in the correct place
    delay (4);
    digitalWrite(digit_pin4, LOW); 
    }
}
int time = 100; //refresh rate

This is actually the inverse of the refresh rate, since it controls the number of iterations of display update occur when you call writeNumber(). So you aren’t checking the temperature very often. Is is possible that, and not the sensor, that is slow?

[edit] You may have to use a timer interrupt to drive the LEDs, if the temperature reading routine is a blocking type.

Yeah, that was just bad commentary. I should have called it “display on time” or something.

Increasing that value will lengthen the amount of time the display shows the current temperature value. Once the code leaves the writeNumber() function the display is black. So ideally the rest of the code needs to be really fast.

It’s definitely this line that is taking about 100ms to execute.

float temp = myHumidity.readTemperature();

I’ll see if I can implement an interrupt to basically handle the writeNumber() function.