Notes About Working with Various Arduino & Netduino Microcontroller Boards

Tuesday, January 15, 2013

Using a Digital Pot & IR Remote to Control Contrast of an LCD with an Arduino Uno

This post shows how to use a digital potentiometer and an infra-red remote to control the contrast of an LCD display. In this case, the LCD is a 16 x 2 LCD with a parallel interface driven by the Arduino LiquidCrystal library
The digital potentiometer allows control via the code rather than by way of a physical control. This example uses an MCP4131 10k pot from Sparkfun. The Arduino and digital MCP4131 communicate via SPI. (This means you have to avoid using Uno's digital pins 11, 12,  & 13 for other purposes, even you run the SPI connections to the SPI header on the Arduino.) 

The IR remote is from the CuteDigi Infrared Remote Control Kit for Arduino. I posted the IR codes for this remote control here. The IR receiver is the Sparkfun IR receiver (TSOP85) used with the IRremote library for Arduino. Pressing the VOL+ key increases the LCD's contrast, while pressing the VOL- key decreases it. 

LCD Connections:
LCD Disp.  Arduino Uno 
1  (VSS)   GND
2  (VDD)   5V
3  (V0)    [Dig. Pot Pin 6 (P0W)]
4  (RS)    D7
5  (RW)    GND
6  (E)     D8
11 (D4)    D9
12 (D5)    D10
13 (D6)    D3
14 (D7)    D6
15 (A)     5V  (backlight)
16 (K)     GND (w/ 330 Ohm resistor)

MCP4131 Digital Pot. Connections:

Dot marks pin 1. Pins counted counterclockwise from pin 1.

MCP4131      Arduino Uno
1 (CS)       D4
2 (SCK)      D13
3 (SDI/SDO)  D11
4 (VSS)      GND
5 (P0A)      GND
6 (P0W)      [LCD Pin 3 (V0)]
7 (P0B)      5V
8 (VDD)      5V

TSOP85 IR Receiver Connections:
TSOP85     Arduino Uno 
VCC        5V
OUT        D5
GND        GND

Code:

#include <LiquidCrystal.h>
#include <SPI.h>
#include <IRremote.h>

LiquidCrystal lcd(7, 8, 9, 10, 3, 6);

// Set digital pin 4 as slave select for digital pot:
const int POT_PIN = 4;
// Set digital pin 5 for IR data:
const int RECV_PIN = 5;

// IR codes for VOL- & VOL+ keys
const long VOL_DOWN = 0x40BFA05F;
const long VOL_UP = 0x40BF609F;

IRrecv irrecv(RECV_PIN);
decode_results results;

// Starting level for digital pot
int level = 80;

void setup()
{
  lcd.begin(16, 2);
  // The usual msg. for demo
  lcd.print("Hello, world!");
  // set the POT_PIN as an output:
  pinMode(POT_PIN, OUTPUT);
  // initialize SPI:
  SPI.begin(); 
  Serial.begin(9600);
  irrecv.enableIRIn(); 
}
void loop()
{
  lcd.setCursor(0, 1);
  // Print the number of seconds since reset as part of demo:
  lcd.print(millis()/1000);
  // Check if IR data received 
  if(irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    // 80 defined as minimum contrast
    if((results.value == VOL_DOWN) && level > 80) {
      level--;
    }
    // 127 is maximum contrast
    if((results.value == VOL_UP) && level < 127) {
      level++;
    }
    digitalPotWrite(level);
    irrecv.resume();
  }
}
int digitalPotWrite(int value)
{
  // Take the SS/CS pin low to select the chip:
  digitalWrite(POT_PIN, LOW);
  // Send in the address and value via SPI:
  SPI.transfer(0);
  SPI.transfer(value);
  // Take the SS/CS pin high to de-select the chip:
  digitalWrite(POT_PIN, HIGH); 

No comments:

Post a Comment