Monday, 24 February 2014

LCD Interfacing - Creating Custom Characters

So you have been using an LCD for sometime and now have the need to create a custom character / symbol... How do you do it?
(Please check this before proceeding -   LCD Interfacing - Working with the Simple Labs' LCD Shield)

Before getting onto it, lets understand how an LCD displays characters. If you notice, each character on a LCD display typically is inside a small 5 Rows x 8 Columns array of dots. Depending upon the character to be displayed, the required dots are turned On / Off. Most LCD's come pre-configured to display standard characters. Each character has a definition matrix, which defines which dots are to be On and which dots are to be Off.

Here's an image that will help you understand better. Here's a Custom Smiley and its corresponding Binary definition

Here's how we will define a BYTE variable to hold the definition for the above Character. If you look at it the first row above is stored in the 0th index of the array mySmiley.

byte mySmiley[8] = {
0b00000, 
0b01010, 
0b01010, 
0b01010, 
0b00000, 
0b10001, 
0b01110,
0b00000
};

if Binary is not your game, you can use the below image, to find the decimal equivalent. (both images are using different characters - so use your common sense ;) )


So we can rewrite the definition in decimal as follows
byte mySmiley[8] = { 0, 10,10,10,0,17,14,0};

Here's a simple program to display the Smiley on your LCD

Here's the Program
/*  Induino R3 User Guide - Program 20.0 - LCD Interfacing - Creating Custom Characters on a 16x2 LCD using the Induino R3 */

/* This program uses the Simple Labs LCD Shield, 16x2 LCD from Simple Labs and the Induino R3 Board. Change the pin numbers according your own hardware */

#include <LiquidCrystal.h> //Include the LCD Header

// initialize the lcd
LiquidCrystal lcd(8, 9,10, 11, 12,13);

byte mySmiley[8] = {0,10,10,10,0,17,14,0}; // Define the Smiley Character


void setup()
{
  // add the mySmiley Character to the 0th Location of the LCD's CGRAM 
  // 0-7 are possible values here
  lcd.createChar(0, mySmiley);
  
  // set up number of columns and rows
  lcd.begin(16, 2); 
  
  // Write out Smiley Character.
 // Type casting is required as we are directly mentioning a value
  lcd.write((uint8_t)0); 
}

void loop()
{

}


Now lets play around by creating a set of 8 Characters, each representing a line at a different height (see the output to get a clear understanding)

byte line_0[8] = { 0,0,0,0,0,0,0,31};
byte line_1[8] = { 0,0,0,0,0,0,31,0};
byte line_2[8] = { 0,0,0,0,0,31,0,0};
byte line_3[8] = { 0,0,0,0,31,0,0,0};
byte line_4[8] = { 0,0,0,31,0,0,0,0};
byte line_5[8] = { 0,0,31,0,0,0,0,0};
byte line_6[8] = { 0,31,0,0,0,0,0,0};
byte line_7[8] = { 31,0,0,0,0,0,0,0};

Now the above definition can be optimized by making it an array, so we can redefine it as 

byte line[8][8]={
{ 0,0,0,0,0,0,0,31},
{ 0,0,0,0,0,0,31,0},
{ 0,0,0,0,0,31,0,0},
{ 0,0,0,0,31,0,0,0},
{ 0,0,0,31,0,0,0,0},
{ 0,0,31,0,0,0,0,0},
{ 0,31,0,0,0,0,0,0},
31,0,0,0,0,0,0,0}
};

Here's the Program
/*  Induino R3 User Guide - Program 20.1 - LCD Interfacing - Creating Custom Characters on a 16x2 LCD using the Induino R3 */

/* This program uses the Simple Labs LCD Shield, 16x2 LCD from Simple Labs and the Induino R3 Board. Change the pin numbers according your own hardware */

#include <LiquidCrystal.h> //Include the LCD Header

// initialize the lcd
LiquidCrystal lcd(8, 9,10, 11, 12,13);

byte mySmiley[8] = {0,10,10,10,0,17,14,0}; // Define the Smiley Character


void setup()
{
  // add the custom characters to the LCD's CGRAM 
  lcd.createChar(0, mySmiley);
  
  // set up number of columns and rows
  lcd.begin(16, 2); 
  
  // Write out the custom Characters
  // Type casting is required as we are directly mentioning a value
  lcd.write((uint8_t)0); 
}

void loop()
{

}

Now Lets to try to modify the above program to create a set of characters that can produce a BAR Graph with 8 different levels.

First we redefine the Character Array

byte line[8][8]={
{ 0,0,0,0,0,0,0,31}, // Level 1
{ 0,0,0,0,0,0,31,31}// Level 2
{ 0,0,0,0,0,31,31,31}// Level 3
{ 0,0,0,0,31,31,31,31}// Level 4
{ 0,0,0,31,31,31,31,31}// Level 5
{ 0,0,31,31,31,31,31,31}// Level 6
{ 0,31,31,31,31,31,31,31}// Level 7
31,31,31,31,31,31,31,31// Level 8
};

Here's the Program
/*  Induino R3 User Guide - Program 20.2 - LCD Interfacing - Creating Custom Characters on a 16x2 LCD using the Induino R3 */

/* This program creates a series of Bar Graph Characters- an experimentation with custom characters */

#include <LiquidCrystal.h> //Include the LCD Header

// initialize the lcd
LiquidCrystal lcd(8, 9,10, 11, 12,13);

// Define the Characters for creating a Bar Graph with Various Levels
byte line[8][8]={
{ 0,0,0,0,0,0,0,31}, // Level 1
{ 0,0,0,0,0,0,31,31}, // Level 2
{ 0,0,0,0,0,31,31,31}, // Level 3
{ 0,0,0,0,31,31,31,31}, // Level 4
{ 0,0,0,31,31,31,31,31}, // Level 5
{ 0,0,31,31,31,31,31,31}, // Level 6
{ 0,31,31,31,31,31,31,31}, // Level 7
{ 31,31,31,31,31,31,31,31} // Level 8
};

void setup()
{
  // add the custom characters to the LCD's CGRAM 
  for(int i =0; i <8; i++)
  {
    lcd.createChar(i, line[i]);
  }
  // set up number of columns and rows
  lcd.begin(16, 2); 
}

void loop()
{
  // Show the Bar Graph Characters as increasing
  for(int i =0; i <8; i++)
  {
   // Print the Bar Graph Character on the First Line
   lcd.setCursor(i,0);   
   lcd.write(i);
   
   // Print the Corresponding value on the Second Line
   lcd.setCursor(i,1);   
   lcd.print(i);
   delay(1000); 
  }
  delay(1000); 
  // Clear the display
  lcd.clear();
}

Now lets use the bar graph characters to indicate sensor value. We shall use the value of the LDR on the Induino R3 board and try to represent it using the Bar Graph.

Here's the Program
/*  Induino R3 User Guide - Program 20.3 - LCD Interfacing Custom Characters- Displaying the LDR Value as a Single Bar Graph Character Induino R3 */

/* This program creates a series of Bar Graph Characters- an experimentation with custom characters */

#include <LiquidCrystal.h> //Include the LCD Header

// initialize the lcd
LiquidCrystal lcd(8, 9,10, 11, 12,13);

// Define the Characters for creating a Bar Graph with Various Levels
byte line[8][8]={
{ 0,0,0,0,0,0,0,31}, // Level 1
{ 0,0,0,0,0,0,31,31}, // Level 2
{ 0,0,0,0,0,31,31,31}, // Level 3
{ 0,0,0,0,31,31,31,31}, // Level 4
{ 0,0,0,31,31,31,31,31}, // Level 5
{ 0,0,31,31,31,31,31,31}, // Level 6
{ 0,31,31,31,31,31,31,31}, // Level 7
{ 31,31,31,31,31,31,31,31} // Level 8
};

void setup()
{
  // add the custom characters to the LCD's CGRAM 
  for(int i =0; i <8; i++)
  {
    lcd.createChar(i, line[i]);
  }
  // set up number of columns and rows
  lcd.begin(16, 2); 
}

void loop()
{
 // Read the LDR Value and store it in a variable
 int val = analogRead(3);
 // Map the analog value from the sensor to a scale of 0 to 7 (8 Levels)
 val = map(val, 0, 1023, 0, 7);
 
 // Print the numerical value to the LCD
 lcd.setCursor(0,1);
 lcd.print(val);
 
 //set the cursor
 lcd.setCursor(0,0);
 
  // Write the Bar Graph Level Value corresponding to the Value of the LDR

 lcd.write(val);
 
 delay(100);  
 lcd.clear(); 
}

Now Having a static Bar is not much fun, lets convert this into a realtime BAR graph. A Running Bar Graph based on the last 16 values of the sensor. 16 Values as we can display only 16 characters per line.

/*  Induino R3 User Guide - Program 20.4 - LCD Interfacing Custom Characters- Displaying the LDR Value as a Running Bar Graph using the Induino R3 */

/* This program creates a series of Bar Graph Characters- an experimentation with custom characters */

#include <LiquidCrystal.h> //Include the LCD Header

// initialize the lcd
LiquidCrystal lcd(8, 9,10, 11, 12,13);

// Define the Characters for creating a Bar Graph with Various Levels
byte line[8][8]={
{ 0,0,0,0,0,0,0,31}, // Level 1
{ 0,0,0,0,0,0,31,31}, // Level 2
{ 0,0,0,0,0,31,31,31}, // Level 3
{ 0,0,0,0,31,31,31,31}, // Level 4
{ 0,0,0,31,31,31,31,31}, // Level 5
{ 0,0,31,31,31,31,31,31}, // Level 6
{ 0,31,31,31,31,31,31,31}, // Level 7
{ 31,31,31,31,31,31,31,31} // Level 8
};

// a variable array to store the last 16 values of the sensor
int hist_val[16];

// to count the first 16 values
int cnt = 0;

void setup()
{
  // add the custom characters to the LCD's CGRAM 
  for(int i =0; i <8; i++)
  {
    lcd.createChar(i, line[i]);
  }
  // set up number of columns and rows
  lcd.begin(16, 2); 
}

void loop()
{
 // Read the LDR Value and store it in a variable
 int val = analogRead(3);
 // Map the analog value from the sensor to a scale of 0 to 7 (8 Levels)
 val = map(val, 0, 1023, 0, 7);
 
 lcd.setCursor(0,0);
 lcd.print(val);
 
 // Check if cnt is less than 16, if it is less than 16, we need to increment it
// we also need to store the values of the sensor for the first 16 counts
 if(cnt<16)
 {
   hist_val[cnt] = val;
   // Increment cnt  
   cnt++;
 }
 else
 // if count is greater than 16, we need to push out the oldest of the values and add the latest value to the set of 16 values.
 // the oldest value will be stored in the 0th array index and the latest value in the 15th array index
 // in addition, we also need to move up all other historic values by one position
 {
   // do the moving up of the historic values
   for(int j=0; j<15;j++) 
     hist_val[j] = hist_val[j+1];
     
   // store the latest value in the last position
   hist_val[15] = val; 
 }
 // Displaying the Values as a Running Bar Graph
 for(int i=0; i<cnt; i++)
 {
    lcd.setCursor(i,0);
                  lcd.write(hist_val[i]);
                 /* lcd.setCursor(i,1);
                  lcd.print(hist_val[i]); */
                  delay(10);
 }

}

Thats It For This Part! Enjoy... and feel free to drop us an email with questions you might have -> info@simplelabs.co.in

Visit www.simplelabs.co.in for more interesting products

Monday, 17 February 2014

Interfacing Sensors - Microphone Sound Detection Sensor

Microphone Sound Detection Sensor

The Microphone Sound Detection Sensor is a simple sensor that detects sound using a Condenser Mike. It can give either a RAW analog output or a Comparator based Digital Output. The Analog Output is the Output from a Potential Divider constructed between the Microphone and the Trimpot. The Digital Output is that of a Comparator that takes in the potential divider as one Input and a fixed resistance as the other. 



Connections

If you are using the Induino R3 Board, You can plug the sensor directly onto the Sensor Interface on the Board. Like in the Image Below.



  1. Connect '+' pin of the Sensor module to +5V on the Induino R3 / Arduino Board
  2. Connect the 'G' pin of the Sensor module to the GND pin on the Induino R3 / Arduino Board
  3. Connect the 'DO' pin of the Sensor module to Digital Pin 16 (A2) on the Induino R3 / Arduino Board
Adjusting the Sound Sensor Sensitivity

The Trimpot on the Sensor, lets you adjust the Sound Sensor Sensitivity. The LED marked L2 (below the Trimpot) indicates the digital output of the sensor. To adjust the sensitivity, Adjust the Trimpot using a Screw Driver. Clock Wise Rotation, Decreases the Sensitivity and Anti-Clock Wise Rotation Increases it. Once the sensitivity is set,  Verify by making a sound and checking if the LED L2 Turns On when you make the desired sound. 


Programming for the Microphone Sound Detection Sensor

Here's a Simple Program that toggles On / Off the LED on the 13th Pin everytime a clap is detected.


Here's the Program
/*  Induino R3 User Guide - Program 19.0 - Interfacing Microphone Sound Detection Sensor with the Induino R3 */

#define mic 16 // The Microphone Sound Detection Sensor's Digital Output Pin is Connected to Pin 16 / A2 of Induino R3

boolean state = 0;

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
  // Setup the 13the pin LED for OUTPUT
  pinMode(13, OUTPUT);
  
  // Setup the sensor input pin
  pinMode(mic, INPUT);
  
}

void loop()
{
  if(digitalRead(mic)) // Check if the Sensor Input is HIGH
  {
   state = !state; // Toggle the State Variable
   digitalWrite(13, state); // Set the Current State to the OUTPUT LED
   delay(1000); // Wait for the INPUT to become stable
  }
}

Thats It For This Part! Enjoy... and feel free to drop us an email with questions you might have -> info@simplelabs.co.in

Visit www.simplelabs.co.in for more interesting products