Showing posts with label 7 segment. Show all posts
Showing posts with label 7 segment. Show all posts

Monday, December 31, 2012

on Leave a Comment

Interfacing MAX7219 with Raspberry Pi

The MAX7219 is extraordinary IC from Maxim which allows us to control many LEDs utilizing only a couple Raspberry Pi pin-outs. It removes all the hassles related with multiplexing, latching, refreshing common with 7 segments. Just by sending commands  via its SPI interfaceto the MAX7219 can control 64 LEDs or eight 7 segment displays.

Even though Rpi supports hardware SPI I couldn't get it to work with MAX7219. So I abandoned the SPI and connected 3 normal digital GPIO pins to the MAX7219 directly.I connected pin 1 (data), 12 (load) and 13 (clock) to the RPi GPIO pins 17, 23 and 22. Pins 4 and 9 to RPi Ground. Pin 19 to RPi’s 5V along with pin 18 via a resistor of your choice depending on your LED.



















Now it was only a matter of sending commands to the MAX7219 via the data in, clock and load line.

For instance, to display the number 4 on digit 1 we would send the command 0×104 (0×01 : use digit 1, 0×04 : display the number 4). Which might look something like this :

Set LOAD to 1.
Send 16 bits command and data (0×104 = 0000000100000100), and for each binary digit we : set CLOCK to 0; send the binary digit, 0 or 1; set CLOCK to 1.
To finish, set LOAD to 0 then set LOAD to 1.

At this point it might be worth mentioning that the MAX7219 can work in two modes, BCD decode on or BCD off. With BCD on we can just send the number we want to appear on the 7 segment display to the MAX7219 and it will display it, as shown above. As well as digits 0 to 9, 10 to 15 correspond to -, E, H, L, P and ‘ ‘ / blank.

With BCD set to off we can control each segment directly. We’d use this mode if we were controlling a bunch of LEDs

bit  -  segment
0  -  g
1  -  f
2  -  e
3  -  d
4  -  c
5  -  b
6  -  a
7  -  dp

So binary 1110111, 0×77, would display a letter A on a 7 segment display.

Below is the code for MAX7219, using Gordon’s excellent wiringPi library to control the GPIO pins :-

/*
 max7219.c
 to compile : gcc max7219.c -o max7219 -lwiringPi
*/
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// define our pins :
#define DATA        0 // GPIO 17 (WiringPi pin num 0)  header pin 11
#define CLOCK       3 // GPIO 22 (WiringPi pin num 3)   header pin 15
#define LOAD        4 // GPIO 23 (WiringPi pin num 4)   header pin 16
// The Max7219 Registers :
#define DECODE_MODE   0x09                       
#define INTENSITY     0x0a                        
#define SCAN_LIMIT    0x0b                        
#define SHUTDOWN      0x0c                        
#define DISPLAY_TEST  0x0f                         
static void Send16bits (unsigned short output)
{
  unsigned char i;
  for(i=16;i>0;i--) 
  {
    unsigned short mask=1<<(i-1); // calculate bitmask
    digitalWrite(CLOCK,0);  // set clock to 0
    // Send one bit on the data pin
    if (output & mask)   
      digitalWrite(DATA,1);          
    else                              
      digitalWrite(DATA,0);        
    digitalWrite(CLOCK,1);  // set clock to 1 	 
  }
}
// Take a reg numer and data and send to the max7219
static void MAX7219Send(unsigned char reg_number,unsigned char dataout)
{
  digitalWrite(LOAD,1);  // set LOAD 1 to start
  Send16bits((reg_number << 8) + dataout);   // send 16 bits ( reg number + dataout )
  digitalWrite(LOAD,0);  // LOAD 0 to latch
  digitalWrite(LOAD,1);  // set LOAD 1 to finish
}
int main(void)
{
  printf("\n\nRaspberry Pi Max7219 Test using WiringPi\n\n");
  if(wiringPiSetup()==-1) exit(1) ;
  //We need 3 output pins to control the Max7219: Data, Clock and Load
  pinMode(DATA,OUTPUT);  
  pinMode(CLOCK,OUTPUT);
  pinMode(LOAD,OUTPUT);  
  MAX7219Send(SCAN_LIMIT,7);     // set up to scan all eight digits
/* 
 BCD decode mode off : data bits correspond to the segments (A-G and DP) of the seven segment display.
 BCD mode on :  0 to 15 =  0 to 9, -, E, H, L, P, and ' '	
*/
  MAX7219Send(DECODE_MODE,1);   // Set BCD decode mode on
  MAX7219Send(DISPLAY_TEST,0);  // Disable test mode
  MAX7219Send(INTENSITY,1);     // set brightness 0 to 15	
  MAX7219Send(SHUTDOWN,1);      // come out of shutdown mode
  MAX7219Send(1,6); 		 // displays the number 6 on digit 1
  return 0;
}

Wednesday, November 14, 2012

on Leave a Comment

7 Segment Multiplexing With Raspberry Pi

7 segments can be driven using many different techniques in conjunction with software and hardware. Multiplexing is one of the most popular methods used to drive a 7 segment display when there are limited no of I/O pins.It uses the concept of POV(persistence of vision) where the human brain cannot detect the flickering of display when the refresh rate is very high(~50Hz).In this method the fundamental logic is to enable or disable the segment blocks at a very high speed at  precise time slices.


7 segment multiplexing with raspberry pi
 In case of Raspberry Pi there are limited no of I/O pins, hence we will use multiplexing. WiringPi is perfect for this job as it uses Arduino like code and the code executes at a higher priority. Display used in this example is of common cathode type.Make sure you have the right 7 segment display,else you will end up getting random segments turned on.For pin mapping check the code below:-


Code:-

#include <wiringPi.h>
#include <stdio.h>
#define DISPLAY_BRIGHTNESS  500
#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW
#define SEGMENT_ON  LOW
#define SEGMENT_OFF HIGH
int SEGMENT_1=7; 
int SEGMENT_2=11;
int SEGMENT_3=13;
int SEGMENT_4=15;
int SEGMENT_A=3; 
int SEGMENT_B=5; 
int SEGMENT_C=18; 
int SEGMENT_D=19; 
int SEGMENT_E=23; 
int SEGMENT_F=24; 
int SEGMENT_G=25; 
void display_number(int num)
{
  pinMode(SEGMENT_1,OUTPUT);
  pinMode(SEGMENT_2,OUTPUT);
  pinMode(SEGMENT_3,OUTPUT);
  pinMode(SEGMENT_4,OUTPUT);
  long start=millis();
  for(int i=4;i>0;i--)
  {
    switch(i)
    {
    case 1:
      digitalWrite(SEGMENT_1,DIGIT_ON);
      break;
    case 2:
      digitalWrite(SEGMENT_2,DIGIT_ON);
      break;
    case 3:
      digitalWrite(SEGMENT_3,DIGIT_ON);
      break;
    case 4:
      digitalWrite(SEGMENT_4,DIGIT_ON);
      break;
    }
    print_number(num%10);
    num/=10;
    delayMicroseconds(DISPLAY_BRIGHTNESS); 
    print_number(10); 
    digitalWrite(SEGMENT_1,DIGIT_OFF);
    digitalWrite(SEGMENT_2,DIGIT_OFF);
    digitalWrite(SEGMENT_3,DIGIT_OFF);
    digitalWrite(SEGMENT_4,DIGIT_OFF);
  }
  while((millis()-start)<10);
}
void print_number(int num)
{
  pinMode(SEGMENT_A,OUTPUT);
  pinMode(SEGMENT_B,OUTPUT);
  pinMode(SEGMENT_C,OUTPUT);
  pinMode(SEGMENT_D,OUTPUT);
  pinMode(SEGMENT_E,OUTPUT);
  pinMode(SEGMENT_F,OUTPUT);
  pinMode(SEGMENT_G,OUTPUT);
  switch(num)
  {
  case 0:
    digitalWrite(SEGMENT_A,SEGMENT_ON);
    digitalWrite(SEGMENT_B,SEGMENT_ON);
    digitalWrite(SEGMENT_C,SEGMENT_ON);
    digitalWrite(SEGMENT_D,SEGMENT_ON);
    digitalWrite(SEGMENT_E,SEGMENT_ON);
    digitalWrite(SEGMENT_F,SEGMENT_ON);
    digitalWrite(SEGMENT_G,SEGMENT_OFF);
    break;
  case 1:
    digitalWrite(SEGMENT_A,SEGMENT_OFF);
    digitalWrite(SEGMENT_B,SEGMENT_ON);
    digitalWrite(SEGMENT_C,SEGMENT_ON);
    digitalWrite(SEGMENT_D,SEGMENT_OFF);
    digitalWrite(SEGMENT_E,SEGMENT_OFF);
    digitalWrite(SEGMENT_F,SEGMENT_OFF);
    digitalWrite(SEGMENT_G,SEGMENT_OFF);
    break;
  case 2:
    digitalWrite(SEGMENT_A,SEGMENT_ON);
    digitalWrite(SEGMENT_B,SEGMENT_ON);
    digitalWrite(SEGMENT_C,SEGMENT_OFF);
    digitalWrite(SEGMENT_D,SEGMENT_ON);
    digitalWrite(SEGMENT_E,SEGMENT_ON);
    digitalWrite(SEGMENT_F,SEGMENT_OFF);
    digitalWrite(SEGMENT_G,SEGMENT_ON);
    break;
  case 3:
    digitalWrite(SEGMENT_A,SEGMENT_ON);
    digitalWrite(SEGMENT_B,SEGMENT_ON);
    digitalWrite(SEGMENT_C,SEGMENT_ON);
    digitalWrite(SEGMENT_D,SEGMENT_ON);
    digitalWrite(SEGMENT_E,SEGMENT_OFF);
    digitalWrite(SEGMENT_F,SEGMENT_OFF);
    digitalWrite(SEGMENT_G,SEGMENT_ON);
    break;
  case 4:
    digitalWrite(SEGMENT_A,SEGMENT_OFF);
    digitalWrite(SEGMENT_B,SEGMENT_ON);
    digitalWrite(SEGMENT_C,SEGMENT_ON);
    digitalWrite(SEGMENT_D,SEGMENT_OFF);
    digitalWrite(SEGMENT_E,SEGMENT_OFF);
    digitalWrite(SEGMENT_F,SEGMENT_ON);
    digitalWrite(SEGMENT_G,SEGMENT_ON);
    break;
  case 5:
    digitalWrite(SEGMENT_A,SEGMENT_ON);
    digitalWrite(SEGMENT_B,SEGMENT_OFF);
    digitalWrite(SEGMENT_C,SEGMENT_ON);
    digitalWrite(SEGMENT_D,SEGMENT_ON);
    digitalWrite(SEGMENT_E,SEGMENT_OFF);
    digitalWrite(SEGMENT_F,SEGMENT_ON);
    digitalWrite(SEGMENT_G,SEGMENT_ON);
    break;
  case 6:
    digitalWrite(SEGMENT_A,SEGMENT_ON);
    digitalWrite(SEGMENT_B,SEGMENT_OFF);
    digitalWrite(SEGMENT_C,SEGMENT_ON);
    digitalWrite(SEGMENT_D,SEGMENT_ON);
    digitalWrite(SEGMENT_E,SEGMENT_ON);
    digitalWrite(SEGMENT_F,SEGMENT_ON);
    digitalWrite(SEGMENT_G,SEGMENT_ON);
    break;
  case 7:
    digitalWrite(SEGMENT_A,SEGMENT_ON);
    digitalWrite(SEGMENT_B,SEGMENT_ON);
    digitalWrite(SEGMENT_C,SEGMENT_ON);
    digitalWrite(SEGMENT_D,SEGMENT_OFF);
    digitalWrite(SEGMENT_E,SEGMENT_OFF);
    digitalWrite(SEGMENT_F,SEGMENT_OFF);
    digitalWrite(SEGMENT_G,SEGMENT_OFF);
    break;
  case 8:
    digitalWrite(SEGMENT_A,SEGMENT_ON);
    digitalWrite(SEGMENT_B,SEGMENT_ON);
    digitalWrite(SEGMENT_C,SEGMENT_ON);
    digitalWrite(SEGMENT_D,SEGMENT_ON);
    digitalWrite(SEGMENT_E,SEGMENT_ON);
    digitalWrite(SEGMENT_F,SEGMENT_ON);
    digitalWrite(SEGMENT_G,SEGMENT_ON);
    break;
  case 9:
    digitalWrite(SEGMENT_A,SEGMENT_ON);
    digitalWrite(SEGMENT_B,SEGMENT_ON);
    digitalWrite(SEGMENT_C,SEGMENT_ON);
    digitalWrite(SEGMENT_D,SEGMENT_ON);
    digitalWrite(SEGMENT_E,SEGMENT_OFF);
    digitalWrite(SEGMENT_F,SEGMENT_ON);
    digitalWrite(SEGMENT_G,SEGMENT_ON);
    break;
  case 10:
    digitalWrite(SEGMENT_A,SEGMENT_OFF);
    digitalWrite(SEGMENT_B,SEGMENT_OFF);
    digitalWrite(SEGMENT_C,SEGMENT_OFF);
    digitalWrite(SEGMENT_D,SEGMENT_OFF);
    digitalWrite(SEGMENT_E,SEGMENT_OFF);
    digitalWrite(SEGMENT_F,SEGMENT_OFF);
    digitalWrite(SEGMENT_G,SEGMENT_OFF);
    break;
  }
}
int main(void)
{
 printf("7 Segment Multiplexing using Raspberry Pi\n") ;
 if(getuid()!=0) //wiringPi requires root privileges  
 {  
  printf("Error:wiringPi must be run as root.\n");  
  return 1;  
 }  
 if(wiringPiSetup()==-1)  
 {  
  printf("Error:wiringPi setup failed!\n");  
  return 1;  
 }
 int counter=0;
 for(;;)
 {
  display_number(counter++);
                delay(1000);
  if(counter>9999)
   counter=0;
 }
  return 0;
}

Compile the code as...
gcc -o display segment.c -L/usr/local/lib -lwiringPi 
 Now execute it...
 sudo ./display