Line Sensing. QRE1113 Reflectance Sensor + Arduino

Monday, June 27 th , 2011

The QRE1113 is a common reflectance sensor often used in robotic line followers. The sensor works by shining an IR LED down and seeing how much of that light bounces back using a phototransistor. Because dark colors will bounce back less of the light, the sensor can be used to tell the difference between white and black areas. So an array of these can be used to help a robot determine where a dark line is on the ground so it can follow it. But they can also be used to determine proximity under an inch.

Both Pololu and Sparkfun sell digital and analog models of a QRE1113 breakout board. The analog version is very simple, it just outputs an analog voltage on the signal pin relative to how much light was reflected. And you might think the digital version, especially being called a line sensor by sparkfun, would just output HIGH when it sees a line, and LOW when it does not. But this is not the case.

The digital version is designed for times you do not have an analog input on your microcontroller but still need an analog reading of how much light was reflected. It does this by allowing you to charge a capacitor on the board, and then timing how long it takes to discharge. The more light that is reflected, the less time it takes to discharge the capacitor. In my tests, the times ranged between 10 microseconds (10/million) to 2.5 milliseconds, so this is all done very quickly and wont put much of a delay in your code.

Hooking Them Up

Hooking the QRE1113 to your Arduino is very simple. It just needs power (5V), ground, and an analog or digital pin depending on what version you have.


The method of reading the values from the analog and digital version is very different, so we have 2 code examples for you.

Analog Version

//Code for the QRE1113 Analog board
//Outputs via the serial terminal - Lower numbers mean more reflected
int QRE1113_Pin = 0; //connected to analog 0

void setup(){

void loop(){

  int QRE_Value = analogRead(QRE1113_Pin);


Digital Version

//Code for the QRE1113 Digital board
//3000 or more means nothing was reflected.

int QRE1113_Pin = 2; //connected to digital 2

void setup(){

void loop(){

  int QRE_Value = readQD();


int readQD(){
  //Returns value from the QRE1113 
  //Lower numbers mean more refleacive
  //More than 3000 means nothing was reflected.
  pinMode( QRE1113_Pin, OUTPUT );
  digitalWrite( QRE1113_Pin, HIGH );  
  pinMode( QRE1113_Pin, INPUT );

  long time = micros();

  //time how long the input is HIGH, but quit after 3ms as nothing happens after that
  while (digitalRead(QRE1113_Pin) == HIGH && micros() - time < 3000); 
  int diff = micros() - time;

  return diff;

A Slow Display… E-Paper + Arduino

Monday, June 20 th , 2011

Most notable for its inclusion in the Kindel and other E-Readers, E-Paper has recently become very popular. But until very recently been out of reach to being used in personal projects. Luckily for us, SparkFun started selling and E-Paper display, and breakout board finally bringing this great technology to a place where we can slap it on the back of our Arduinos.

If you are wondering, E-Ink is a brand of E-Paper, and this display is not of that brand so we will be calling it E-Paper.

E-paper has some properties that make it unlike almost any other display. Unlike a typical LCD screen, E-paper only needs power when it is changing what is being displayed. Think of it as an electrical etch-a-sketch – The image is there until you change it.

The E-paper actually does this by drawing the image by flipping over tiny balls in the display that are black on one side, and white on the other. When an electrical charge is applied to portions of the display it forces the balls in that area to all flip to one side, changing the color of that part of the display. Once these balls have been set into place, they stay there until a new instruction takes place.

E-paper also is not backlit like many LCDs and is more like actual paper where reading it is dependent on available light where you are. And, many people report E-Paper as being easier on the eyes and more like reading actual paper than a screen.

This particular display is a 20 character, 2 line, 16-segment display. So you wont be able to display graphics on it, and the type size is set as well. But… it is still very cool.

Hooking It Up

I wouldn’t try hooking up this display without the breakout board, so im not going to cover that at all (the break outboard bumps the 3.3 or 5[v] source to the 35V needed for the display) and there are like 400 connections on the 2 ribbon cables. Also, even with the breakout board it can be a little tricky.

The ribbon cables of the display need to slide into the connectors of the breakout board, and I have read some people having issue with this. To do this you need to slide out the sides of the connector, then slide the ribbon cable into it, and slide the sides back in, locking it into place.

You also need to make sure you are plugging the right cable into the right connector. – Look at the illustration. In the top left of the back of the display are some square / line shapes. This side needs to plug into “input 2″ of the breakout-board. Im not 100% that it MUST be orientated this way, but this is how I did it, and how it is shown on SparkFun, and it worked for us. It is possible that it would just be upside-down if reversed.

Now just hook everything up as shown in the illustration.


This code is based on the code example on SparkFun’s site written by Jim Lindblom. With his permission, we started a library for this display that makes it very easy to write anything to the display. It has some bugs, but works quite well.

All you need to do after the library is initiated, is this:

To display a number up to 2147483647

Or for text
epaper.writeTop(” bildr “);
epaper.writeBottom(” example “);

To make this code work, before you load the code, or even open the Arduino program, we need to place both the “ePaper” folder into your Arduino Library. If you don’t know where that is by default, Look to the right.


Default Library Folder Location


Help expand the library

We would love help expanding the library if you are interested. We would like to add to support for other characters, capital and non capitol letters, left and right justify etc. The screen may also support black on white as well as black on white (not 100% sure). If you are interested in helping, let us know in the forum.


Sensing Barometric Pressure | BMP085 + Arduino

Thursday, June 16 th , 2011



The reading differs from my weather report


Hooking it up





//Arduino 1.0+ Only
//Arduino 1.0+ Only

/*Based largely on code by  Jim Lindblom

 Get pressure, altitude, and temperature from the BMP085.
 Serial.print it out at 9600 baud to serial monitor.

#include <Wire.h>

#define BMP085_ADDRESS 0x77  // I2C address of BMP085

const unsigned char OSS = 0;  // Oversampling Setting

// Calibration values
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;

long b5; 

void setup(){


void loop()
  float pressure = bmp085GetPressure(bmp085ReadUP());

  Serial.print("Temperature: ");
  Serial.println("deg C");

  Serial.print("Pressure: ");
  Serial.println(" Pa");

  Serial.print("Standard Atmosphere: ");

  Serial.print("Altitude: ");
  Serial.println(" M");

  Serial.println();//line break


// Calibration values are required to calculate temp and pressure
void bmp085Calibration()
  ac1 = bmp085ReadInt(0xAA);
  ac2 = bmp085ReadInt(0xAC);
  ac3 = bmp085ReadInt(0xAE);
  ac4 = bmp085ReadInt(0xB0);
  ac5 = bmp085ReadInt(0xB2);
  ac6 = bmp085ReadInt(0xB4);
  b1 = bmp085ReadInt(0xB6);
  b2 = bmp085ReadInt(0xB8);
  mb = bmp085ReadInt(0xBA);
  mc = bmp085ReadInt(0xBC);
  md = bmp085ReadInt(0xBE);

// Calculate temperature in deg C
float bmp085GetTemperature(unsigned int ut){
  long x1, x2;

  b5 = x1 + x2;

  temp = temp /10;

  return temp;

// Calculate pressure given up
// calibration values must be known
// Value returned will be pressure in units of Pa.
long bmp085GetPressure(unsigned long up){
  unsigned long b4, b7;

  b6 = b5 - 4000;
  // Calculate B3
  x2 = (ac2 * b6)>>11;
  x3 = x1 + x2;

  // Calculate B4
  x1 = (ac3 * b6)>>13;

  if (b7 < 0x80000000)
    p = (b7<<1)/b4;
    p = (b7/b4)<<1;

  x1 = (x1 * 3038)>>16;
  x2 = (-7357 * p)>>16;

  long temp = p;
  return temp;

// Read 1 byte from the BMP085 at 'address'
char bmp085Read(unsigned char address)
  unsigned char data;


  Wire.requestFrom(BMP085_ADDRESS, 1);


// Read 2 bytes from the BMP085
// First byte will be from 'address'
// Second byte will be from 'address'+1
int bmp085ReadInt(unsigned char address)
  unsigned char msb, lsb;


  Wire.requestFrom(BMP085_ADDRESS, 2);
  msb =;
  lsb =;

  return (int) msb<<8 | lsb;

// Read the uncompensated temperature value
unsigned int bmp085ReadUT(){
  unsigned int ut;

  // Write 0x2E into Register 0xF4
  // This requests a temperature reading

  // Wait at least 4.5ms

  // Read two bytes from registers 0xF6 and 0xF7
  ut = bmp085ReadInt(0xF6);
  return ut;

// Read the uncompensated pressure value
unsigned long bmp085ReadUP(){

  unsigned char msb, lsb, xlsb;
  unsigned long up = 0;

  // Request a pressure reading w/ oversampling setting
  Wire.write(0x34 + (OSS<<6));

  // Wait for conversion, delay time dependent on OSS
  delay(2 + (3<<OSS));

  msb = bmp085Read(0xF6);
  lsb = bmp085Read(0xF7);
  xlsb = bmp085Read(0xF8);


  return up;

  Wire.beginTransmission(deviceAddress); // start transmission to device 
  Wire.write(address);       // send register address
  Wire.write(val);         // send value to write
  Wire.endTransmission();     // end transmission

int readRegister(int deviceAddress, byte address){

  int v;
  Wire.write(address); // register to read

  Wire.requestFrom(deviceAddress, 1); // read a byte

  while(!Wire.available()) {
    // waiting

  v =;
  return v;

float calcAltitude(float pressure){

  float A = pressure/101325;
  float B = 1/5.25588;
  float C = pow(A,B);
  C = 1 - C;
  C = C /0.0000225577;

  return C;

« Older Entries