Reading Analog Values From Digital Pins Of Raspberry Pi

Unfortunately all the 17 pins of Raspberry Pi are digital which can either output HIGH or LOW. But by using a simple circuit (poor man's A/D converter) you can measure multiple level of values using a single GPIO pin. It consists of a basic “RC” charging circuit in which a Resistor in placed series with a Capacitor. The voltage across the capacitor rises when voltage is applied across the RC network. Using the formula [t = RC ] where t is the time,R is resistance in ohms,and C is capacitance in Farads and the time taken to register a HIGH on a GPIO pin we can roughly estimate the analog value.

Algorithm:-

Step 1: Set any GPIO pin as an output and set it Low.This ensures that no charge is present in capacitor and both the terminals are at 0V.

Step 2: Now set the GPIO pin as an input.This will starts a flow of current through the resistors and through the capacitor to ground. The voltage across the capacitor starts to rise. The time taken will be proportional to the input.

Step 3: Read the value from GPIO pin and keep incrementing a counter variable until the value is LOW.

Step 4:  At some point the value from GPIO will register a HIGH. When it does return the value of the counter.

Step 5: Set the GPIO pin as an output and repeat the process as required.

Python Implementation:-


#!/usr/local/bin/python
# GPIO   : RPi.GPIO v3.1.0a
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
# Define function to measure charge time
def RC_Analog (Pin):
  counter = 0
  # Discharge capacitor
  GPIO.setup(Pin, GPIO.OUT)
  GPIO.output(Pin, GPIO.LOW)
  time.sleep(0.1)
  GPIO.setup(Pin, GPIO.IN)
  # Count loops until voltage across capacitor reads high on GPIO
  while(GPIO.input(Pin)==GPIO.LOW):
        counter =counter+1
  return counter
# Main program loop
while True:
  print RC_Analog(4) # Measure timing using GPIO4

Example Circuit:-





Note:- The above technique will only work with sensors that act like resistors like photocells, thermistors, flex sensors, force-sensitive resistors, etc.

It cannot be used with sensors that have a pure analog output like IR distance sensors or analog accelerometers.


Source:- Adafruit

Read More »

Convert your Raspberry Pi into media center with XBMC

With the help of XBMC you can transform your Raspberry Pi into a full fledged media center. XBMC is an  open source media player application developed by the XBMC Foundation. Raspberry Pi is the perfect candidate for XMBC as it offers 1080p HD support along with networking capabilities and external HDD support via USB.


Getting Started:-

Software & Hardware Requirements:-

  • Rasberry Pi Model B
  • HDMI or AV cable
  • Ethernet cable (for internet viewing)
  • SD card (Class 10 preferred) 
  • Micro USB charger
  • Raspbmc Installer

raspbmc installer

The Raspbmc distribution is created and maintained by Sam Nazarko. For this post I have used the windows based installer and you can download the latest version here.Download it and extract the archive. Make sure to plug in your card reader before launching the application, and unplug any other USB storage devices besides the card you want to format.This is to make sure the only device you can select is the one you want to format. Now, launch the Raspbmc installer application and select the SD card reader from the devices list and click install.It should take around a minute or two to download & burn the image to SD card.

raspbmc installer


Once you get this message you can plug in the memory card, Ethernet cable, keyboard and power up the device.Make sure Pi has access to internet as the installer will need it to complete the installation. It will boot and the installer program will run for about 20-35 minutes depending on your connection speed.The Raspbmc will attempt to reboot the device once the installer script is ready. After the reboot you’ll be greeted with XBMC and a slightly modified light-weight version of the Confluence skin.

XBMC Confluence skin


Read More »

Interfacing 16x2 LCD with Raspberry Pi using GPIO & Python

In my previous post I had used an 8 bit i2c port expander to drive the 16x2 LCD. It saved precious GPIO pins but added complexity and cost. In this post I will be using the RPi.GPIO library and Python to control the LCD.The LCD used in this post is based on Hitachi HD44780 LCD controller.Although the LCD has 16 pins available for interfacing, using the 4 bit mode only 6 GPIO pins are required ( RS,E,D4,D5,D6,D7).                                                                               


 The wiring for the LCD is as follows:-  

    LCD Pin                       Pi Pin
       01 <-------->       GPIO-06
       02 <-------->       GPIO-02
       03 <-------->       GPIO-06
       04 <-------->       GPIO-26
       05 <-------->       GPIO-06
       06 <-------->       GPIO-24
       07
       08
       09
       10
       11 <-------->       GPIO-22
       12 <-------->       GPIO-18
       13 <-------->       GPIO-16
       14 <-------->       GPIO-12
       15    +5V via 470ohm
       16 <-------->     GPIO-06

NOTE : With the help of  RW pin the device can be set to read/write mode.Setting [R/W=0] will write to the register and setting [R/W=1] will read from the register.To display data on LCD read access is not required,so the RW in connected to GND. This ensures that there is no outbound data from HD44780 as Pi cannot tolerate 5V.

You can check the pinout of Pi from here.

Code:-

HD44780 based display can be controlled using any programming environment.Here I have used Python & RPi.GPIO library to provide access to the GPIO.


#!/usr/bin/python
import RPi.GPIO as GPIO
from time import sleep
class HD44780:
    def __init__(self, pin_rs=7, pin_e=8, pins_db=[25, 24, 23, 18]):
        self.pin_rs=pin_rs
        self.pin_e=pin_e
        self.pins_db=pins_db
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(self.pin_e, GPIO.OUT)
        GPIO.setup(self.pin_rs, GPIO.OUT)
        for pin in self.pins_db:
            GPIO.setup(pin, GPIO.OUT)
        self.clear()
    def clear(self):
        """ Blank / Reset LCD """
        self.cmd(0x33) # $33 8-bit mode
        self.cmd(0x32) # $32 8-bit mode
        self.cmd(0x28) # $28 8-bit mode
        self.cmd(0x0C) # $0C 8-bit mode
        self.cmd(0x06) # $06 8-bit mode
        self.cmd(0x01) # $01 8-bit mode
    def cmd(self, bits, char_mode=False):
        """ Send command to LCD """
        sleep(0.001)
        bits=bin(bits)[2:].zfill(8)
        GPIO.output(self.pin_rs, char_mode)
        for pin in self.pins_db:
            GPIO.output(pin, False)
        for i in range(4):
            if bits[i] == "1":
                GPIO.output(self.pins_db[::-1][i], True)
        GPIO.output(self.pin_e, True)
        GPIO.output(self.pin_e, False)
        for pin in self.pins_db:
            GPIO.output(pin, False)
        for i in range(4,8):
            if bits[i] == "1":
                GPIO.output(self.pins_db[::-1][i-4], True)
        GPIO.output(self.pin_e, True)
        GPIO.output(self.pin_e, False)
    def message(self, text):
        """ Send string to LCD. Newline wraps to second line"""
        for char in text:
            if char == '\n':
                self.cmd(0xC0) # next line
            else:
                self.cmd(ord(char),True)
if __name__ == '__main__':
    lcd = HD44780()
    lcd.message("Raspberry Pi\n  Take a byte!")
Read More »

Testing Raspberry Pi's Power Supply

Raspberry Pi requires a good power supply to function properly under full load conditions.It uses a micro B USB socket for drawing power which are used by many mobile phone chargers.It requires a DC power supply of 5V with a tolerance of +/- 0.25V and is capable of delivering atleast 0.7 Amps. Many of us get tempted to use the USB port on out PC, but that's not a good idea as USB ports can provide a maximum of 500 mA. Also you risk blowing the fuse of the USB port in your PC.(PC's and laptops uses a solid state poly-fuse which automatically resets after 2-3 hours of rest).To find out the best possible power supply for Pi, I performed a few tests:-

Testing at Full Power:-

testing raspberry pi with full power
For testing at full power I connected 1A power supply from my HTC mobile charger. In order to measure the voltage across the Raspberry Pi, two probing terminals- TP1 and TP2 are provided on the device.Next I used my DMM to get the readings without connecting any external load.As expected the reading was 5.12 V which is considered within the specified range.I was quite confident that using the same power supply the Pi could be powered with full load, seeing how as I have already done so to use the device.I got a reading of 4.96 V after attaching all the loads via USB Hub.




Testing at Low Power:-

testing raspberry pi with low power
For testing at low power I used a 5 V 450 mA USB supply from my MP3 player charger.This is well below the specified 700 mA that Raspberry Pi requires to function properly.Still I went forward with the test and results were a little shocking to say the least.Without any external load the reading from DMM was 5.02!. As the voltage was within the specified tolerance of 0.25 V, I tested the voltage with full load, and the reading came out to be 4.88 V!. As anticipated,even with all the peripherals under full load the Pi booted successfully.But the joy lasted only for a brief moment.When I tried to use my keyboard and mouse they were not responding.


The final verdict? Well if you are planning to run the Raspberry Pi headless, you might be able to skimp on the current, but if you are planning on running a full fledged Linux box you should consider getting a decent power supply with a rating of 1A or greater.
Read More »

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
















Read More »

Interfacing ADC with Raspberry Pi


In this post I will demonstrate how you can utilize a modest PICAXE micro-controller as a multi channel ADC.We would be utilizing I2C bus to access the PICAXE, which will dump the values to memory registers.Your Pi must be configured to use the I2C bus.You can refer to this post for setting up I2C.

Very few PICAXEs can act as an I2C slave.One of them is 28X1. I have collected some fundamental information about PICAXEs, but in the event that you have never utilized one before, I suggest you to get basic knowledge about PICAXE's (Google is your friend ;) ).

You will require a minimum working circuit for PICAXe with power,reset and download socket to proceed.Here I am connecting 4 potentiometer with the ADC channel of PICAXE to demonstrate the working.

interfacing ADC with raspberry pi


Code for PICAXE:-
You will need to download the below code into your PICAXE. Values from ADC is dumped into the micro-controller's scratchpad memory which can be accessed via I2C bus.

#no_data
#no_table
hi2csetup i2cslave, 100000
main:
readadc 0,b1
readadc 1, b2
readadc 2, b3
readadc 3, b4
put 1, b1
put 2, b2
put 3, b3
put 4, b4
goto main

Code for Raspberry Pi:-
I have created a python script to access the PICAXE's scratchpad memory over I2C bus.It reads and displays the values.Save the script as read_adc.py.


import smbus
import time
bus=smbus.SMBus(0)
add=0x10

def read(reg):
        value=bus.read_byte_data(add, reg)
        return value

adc_channel1=0
adc_channel2=0
adc_channel3=0
adc_channel4=0
while True:
        adc_channel1=read(1)
        adc_channel2=read(2)
        adc_channel3=read(3)
        adc_channel4=read(4)
        print adc_channel1
        print adc_channel2
        print adc_channel3
        print adc_channel4
        time.sleep(0.3)

Testing:-
Run the script on your pi as-
root@raspberrypi:~# sudo python read_adc.py
It should now display the ADC values in your screen!

Warning:- Use a voltage level shifter ( 5V <----> 3.3V ) when interfacing the PICAXE with Raspberry Pi, as Pi cannot tolerate 5V!.


Read More »

PWM on Raspberry Pi

generating PWM on raspberry pi
With only one hardware PWM pin on Raspberry Pi it can be quite a problem with Arduino users like me.There are various hardware solutions available to overcome this problem.Many ADC(analog to digital converters) IC are available which can be interfaced via I2C bus.In this post I will be using WiringPi library which can bit-bang any GPIO pins and generate PWM signal. Even though the PWM signals are generated by individual threads with high priority using a real-time scheduler, there may be instances where it may get  temporarily descheduled for a fraction of a second and cause jitters.

Installing the Library:-
WiringPi is maintained under GIT for ease of change tracking.If you do not have GIT installed, then under any of the Debian releases, you can install it with-
sudo apt-get install git-core

To obtain WiringPi using GIT:
git clone git://git.drogon.net/wiringPi

If you have already used the clone operation for the first time, then

cd wiringPi
git pull origin
Will fetch an updated version then you can re-run the build script below.

To build/install there is a new simplified script:
cd wiringPi
./build

The new build script will compile and install it all for you - it does use the sudo command at one point, so you may wish to inspect the script before running it.

Example Code:-
This code uses both the hardware and software PWM functions.

//////---------------------------------------------------------------------------
////// Name:                   pwm.c
////// Compiled with:      gcc pwm.c -I/usr/local/include -L/usr/local/lib -lwiringPi -lpthread -o pwm
////// Schematic:              .------.
//////                         | o  o |
//////                     RPi | o  o |12
//////                         | o  o-|-----(->|)-----\/\/\/\--o GND
//////                         | o  o |11    LED1       220
//////                         | o  o-|-----(->|)-----\/\/\/\--o GND
//////                         | o  o |      LED2       220
//////                         | o  o-|
//////
////// Notes:
//////---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <wiringPi.h>
#include <softPwm.h>
void control_event(int sig);
int HARD_PWM_PIN=1; //Hardware PWM Pin(GPIO18-12)
int SOFT_PWM_PIN=0; //Software PWM Pin(GPIO0-11)
int DELAY_MS=10;
int main(void)
{
  (void)signal(SIGINT,control_event);
  (void)signal (SIGQUIT,control_event);
  printf("Hardware and software based PWM test on LED\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;
  }
  pinMode(HARD_PWM_PIN,PWM_OUTPUT); //setup hardware pwm
  softPwmCreate(SOFT_PWM_PIN,0,100); //setup software pwm pin
  int up;
  int down;
  while(1)
  {
    for(up=1;up=5;down--)
    {
      pwmWrite(HARD_PWM_PIN,down);
      softPwmWrite(SOFT_PWM_PIN,down);
      delay(DELAY_MS*2);
    }
    delay(DELAY_MS*5);
  }
}
void control_event(int sig)
{
  printf("\b\bExiting...\n");
  pwmWrite(HARD_PWM_PIN,0);
  softPwmWrite(SOFT_PWM_PIN,0);
  delay(100); //wait a little for the pwm to finish write
  exit(0);
}
Limitations:- To minimize CPU usage the minimum default pulse width is set to 100μs thereby generating a PWM of 100 Hz. Lowering the range can give you a higher frequency at an expense of resolution and vice versa. Delays less than 100μs will dramatically increase the CPU usage and controlling other pins would be impossible.However, within these limitations controlling an LED or Motor is quite practical.
Read More »

Interfacing Temperature and Humidity Sensor (DHT11) With Raspberry Pi

interfacing DHT11 with raspberry pi
DHT11 is a 4 pin sensor which can measure temperatures ranging from 0-50°C & relative humidity ranging from 20-95%.The sensor uses its own proprietary 1-wire protocol to communicate with Raspberry Pi and runs from 3.3V-5V. The timings must be precise and according to the datasheet of the sensor.

Raspberry Pi initiates the data transmission process by pulling the data bus low for about 18 ms and keeps it HIGH for about 20-40 μs before releasing it.Subsequently, the sensor responds to the Pi's data transfer request by  pulling the data bus LOW for 80 μs followed by 80 μs of HIGH.At this point Pi is ready to receive data from the sensor.Data is sent in packet of 40 bits (5 bytes) via the data line with the most significant bit at the beginning.

Data is transmitted in the following order:- Integer Part of Relative Humidity--->Decimal Part of Relative Humidity--->Integer Part of Temperature--->Decimal Part of Temperature---> Checksum. Checksum consists the last 8 bits of each part. Transmission of '0' & '1' is done by varying the width of the pulse.For transmitting '0' the data bus is held HIGH for 26-28μs, and 70μs for transmitting '1'.A delay of 50μs(LOW) is introduced before any new data bit is transmitted.After the transmission of last data-bit the data line is held LOW for 50μs and released.

DHT11 sensor timing states

Circuit:-

Holding the DHT11 towards you (the one with grid), the left pin is connected to VCC (pin 1).The data pin is next  after VCC and is connected to pin 7.Next pin is NC(no connection).Finally the last pin is connected to GND(pin 25).To prevent random data connect a 10K resistor between data and VCC pin of DHT11.

Software:-
WiringPi which uses C like Arduino language is used to read the sensor value. WiringPi is maintained under GIT for ease of change tracking.If you do not have GIT installed, then under any of the Debian releases, you can install it with-
sudo apt-get install git-core

To obtain WiringPi using GIT:
git clone git://git.drogon.net/wiringPi

If you have already used the clone operation for the first time, then

cd wiringPi
git pull origin
Will fetch an updated version then you can re-run the build script below.

To build/install there is a new simplified script:
cd wiringPi
./build

Save the below code as temp_rh_sensor.c...

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MAX_TIME 85
#define DHT11PIN 7
int dht11_val[5]={0,0,0,0,0};
void dht11_read_val()
{
  uint8_t lststate=HIGH;
  uint8_t counter=0;
  uint8_t j=0,i;
  float farenheit;
  for(i=0;i<5;i++)
     dht11_val[i]=0;
  pinMode(DHT11PIN,OUTPUT);
  digitalWrite(DHT11PIN,LOW);
  delay(18);
  digitalWrite(DHT11PIN,HIGH);
  delayMicroseconds(40);
  pinMode(DHT11PIN,INPUT);
  for(i=0;i<MAX_TIME;i++)
  {
    counter=0;
    while(digitalRead(DHT11PIN)==lststate){
      counter++;
      delayMicroseconds(1);
      if(counter==255)
        break;
    }
    lststate=digitalRead(DHT11PIN);
    if(counter==255)
       break;
    // top 3 transistions are ignored
    if((i>=4)&&(i%2==0)){
      dht11_val[j/8]<<=1;
      if(counter>16)
        dht11_val[j/8]|=1;
      j++;
    }
  }
  // verify cheksum and print the verified data
  if((j>=40)&&(dht11_val[4]==((dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])& 0xFF)))
  {
    farenheit=dht11_val[2]*9./5.+32;
    printf("Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)\n",dht11_val[0],dht11_val[1],dht11_val[2],dht11_val[3],farenheit);
  }
  else
    printf("Invalid Data!!\n");
}
int main(void)
{
  printf("Interfacing Temperature and Humidity Sensor (DHT11) With Raspberry Pi\n");
  if(wiringPiSetup()==-1)
    exit(1);
  while(1)
  {
     dht11_read_val();
     delay(3000);
  }
  return 0;
}

Compile the code as...
gcc -o sensor temp_rh_sensor.c -L/usr/local/lib -lwiringPi

Now execute it...
sudo ./sensor

[ Humidity = 87.0 % Temperature = 32.2 *C (90.0 *F) ]
Read More »

Running Pi Headless - with GUI part3


In this tutorial, I will demonstrate how to use the pi with remote GUI. It involves the following steps given below:-

1. Install VNC server on pi:

$ sudo apt-get install tightvncserver


2. Setup VNC client on remote system:

$ sudo apt-get install xtightvncviewer

3. Start VNC server on pi:

$ /user/bin/tightvncserver

4. Open VNC viewer on remote system:

$ xvncviewer 192.168.1.5:1





5. Kill VNC server

$ vncserver -kill :1





Download notes


Read More »

Running Pi headless - SSH tunneling part2

In this tutorial, I will demonstrate the following:-



1. Login through ssh
2. Changing pi's password
3. Navigating  through file-system
4. Copying files on network
5. Shutdown, Reboot pi
6. Writing, compiling a C program










Download Notes


Read More »

Running Pi headless - SSH tunneling part1


Pi normally needs hardware support like keyboard, mouse, display( HDMI compatible monitors). But we can run pi without these hardware too, using another PC by SSH tunneling. Before getting started, we need to install ssh client in the system from which we are tunneling in to the pi. In Ubuntu (or other linux distros), we install ssh client as follows:

$ sudo apt-get install ssh
$ sudo apt-get install openssh-client




Default login for pi running Wheezy:


usrname: pi
passwd: raspberry

Follow the video below which explains what is SSH and how to log in to pi by SSH tunneling step by step:





Dowload notes/hints


Read More »

Arduino vs Raspberry Pi

difference between arduino and raspberry pi
Ever since the Raspberry Pi was announced, it has been a topic of much debate online.Starting from profoundly diverse naming plans- masculine Italian name vs sweet fruit pie- Arduino and Raspberry Pi boards are significantly different in a lot of things. For one Arduino is an Open Source single-board micro-controller,  while Raspberry Pi is a single-board computer.

Ask any electronics enthusiastic and he will tell you why it is preferable to get the Arduino if this is your first time venturing into the world of embedded systems.On the other hand, if you have already dipped your toes in this field you could go ahead with the Raspberry Pi.

The table compares the two boards. It should help you make a good decision if you are new to this field.

Arduino
Raspberry Pi
Extremely simple to get working.
Less simpler to get working
A typical embedded system with easy-to-develop software.
Fully fledged computer running Linux.
Support is available virtually everywhere.
Limited support is available at present but should increase over time.
Perfect for controlling hardware(robotics).
Features an extremely powerful GPU and can handle HD content.
Umpteen, different  kits and shield’s are available.
Very few kits are available presently.
Low power consumption(<0.5 W), capable of even running micro amps with very low clock.
Power consumption(~3.5 W) is comparatively higher than Arduino.

Verdict: While the Raspberry Pi is a great high-performance option, Arduino is a good general-purpose board.
Read More »

Using GPIO on Raspberry Pi to blink an LED

One of the few things that separates the Pi from other SBC (Single Board Computer)  is the ability to use the GPIO (General Purpose Input/Output) pins which can be set as HIGH or LOW to control any external devices. All you need is a female to male jumper wire to get started. Here I have used a HDD IDE connector to get the job done.

In this post pin 9 is used for GND and pin 11 for GPIO17. The LED was connected using a 470 ohm register in series with pin 9 and 11 to limit the current.

GPIO of raspberry pi
Software Implementation:-

The fastest way to get started is to use python which comes pre-installed with all images. Download the RPi.GPIO library and copy the gz tar ball to the RPi wheezy raspbian. Open the terminal and navigate to the extracted folder containing the RPi.GPIO library. Then type:  $ sudo python setup.py install to install the module. Imp: As the OS is multitasking  and not Real-time unlike Arduino there may be jitters depending on CPU priority.

Based on the library I have written a simple code to turn ON and turn OFF the LED after a delay of 1 sec (1000ms) each.The LED blinks 50 times.
import RPi.GPIO as GPIO
import time
# blinking function
def blink(pin):
        GPIO.output(pin,GPIO.HIGH)
        time.sleep(1)
        GPIO.output(pin,GPIO.LOW)
        time.sleep(1)
        return
# to use Raspberry Pi board pin numbers
GPIO.setmode(GPIO.BOARD)
# set up GPIO output channel
GPIO.setup(11, GPIO.OUT)
# blink GPIO17 50 times
for i in range(0,50):
        blink(11)
GPIO.cleanup() 

led blinking with raspberry pi           
Read More »

Bluetooth pairing on Raspberry Pi with smartphone


Follow the steps below to pair your Raspberry Pi with your smartphone:-

1. Load a new wheezy raspbian image on SD card via the MAC, from a terminal window enter:
sudo umount /dev/disk1s1
sudo dd bs=1m if=2012-09-18-wheezy-raspbian.img of=/dev/rdisk1
sudo umount /dev/disk1s1
2. Boot Raspbian, perform the initial configuration and increase the size of SD to maximum (4GB), & Reboot.
3. Perform a ssh login to Raspbian from MAC, username pi pw raspberry and enter commands:
su
(enter root password)
apt-get update
apt-get install -y bluetooth bluez-utils blueman
lsusb
/etc/init.d/bluetooth status
4. Enable tightvncserver  and remote connect to Raspbian to see its GUI.
5. From Raspbian's GUI select Preferences->Bluetooth Manager, a Bluetooth Devices window will pop up.
Click 'Search' on the Bluetooth Devices, go to the phone, turn on Bluetooth and enable discovery.
6. When Raspberry Pi detects the smartphone, click + on the Bluetooth Devices window. Click Setup, specify password 0000 on the Bluetooth Assistant window.
7. On the smartphone, enter 0000 to pair with Raspberry Pi, the phone should display "raspberry3-14" as a paired device.

setting up Bluetooth with raspberry pi

















The Raspberry Pi Bluetooth name can be changed using : Adapter->Preferences and change the Friendly Name.
Read More »

Setting up webcam on Raspberry Pi

I wanted to find out if the Raspberry Pi supports webcam or not. So I pulled an old Microsoft LifeCam NX-3000 to test with the Pi.The packages were talking a long time to load so I had to perform most of my installation on the emulator instead.
Since my MAC has single hard disk drive, the USB drive for the SD card would always be on /dev/disk1s1 when plugged in. To overcome the problem I created a shell script to write any Raspberry Pi  images on the SD card.

#!/bin/bash
sudo diskutil umount /dev/disk1s1
sudo dd bs=1m if=$1 of=/dev/rdisk1
sudo diskutil umount /dev/disk1s1

Through Qemu you can quickly install debian packages on SD card.The image can be loaded on the SD card using the script above.Follow the steps below to test webcam packages on the Raspberry Pi:

1. Remotely access your Linux box using ssh, then mount the folder containing wheezy raspbian image.
2. Create a raw 3GB raw image disk and copy wheezy raspbian onto it:
qemu-img info 2012-09-18-wheezy-raspbian.img
qemu-img create -f raw newwheezy.img 3G
dd if=2012-09-18-wheezy-raspbian.img of=newwheezy.img
3. Start qemu without graphic, and specify 512MB memory (or replace the flag to -m 1024 to use 1GB memory), command:
sudo qemu-system-arm -kernel kernel-qemu -cpu arm1176 -M versatilepb -m 512 -no-reboot -append "root=/dev/sda2" -hda newwheezy.img -net nic -net user -nographic
4. Within qemu emulating Raspbian:
sudo passwd root
(enter new root password: root, twice)
su
(enter root)
aptitude update
aptitude install -y camorama
aptitude show camorama (to make sure it's installed).
shutdown -h now
(enter Ctrl-a x to exit qemu, then quit ssh session to go back to the MAC).
5. From the MAC, use sftp or scp to copy the new wheezy raspbian image loaded with camorama, command:
./loadsd.sh newwheezy.img
6. Now boot your Raspberry Pi with new wheezy raspbian. Enter command: startx to start the GUI & click LXTerminal, enter:
lsub (a list of USB devices is displayed, one of those lines listed the LifeCam)
camorama (command to start camorama, or command cheese to start cheese)


Read More »

Interfacing a 16x2 LCD with Raspberry Pi

I2C and 16x2 LCD

Hitachi HD44780 based 16x2 character LCD are very cheap and widely available, and is a essential part for any  projects that displays information. Using the I2C bus on Raspberry Pi ,PCF8574 IC, and Python characters/strings can be displayed on the LCD. The PCF8574 is an general purpose bidirectional 8 bit I/O port expander that uses the I2C protocol.



The LCD(HD44780) is connected in 4 bit mode as follows to the PCF8574:-

expandin I/O ports with PCF8574
            P0 - D4
              P1 - D5
              P2 - D6
              P3 - D7
              P4 - RS
              P5 - R/W
              P6 - E

Port A0 is connected to VCC(5V) with a 10k resistor so that it will be addressed at 0x21.

Connecting 16x2 LCD with PCF8574

PCF8574 Slave Address Map


Coming to the software part, Python is used to drive the logic.I have written a simple library to communicate with the LCD using the I2C bus.For this code to work python-smbus package must be installed(sudo apt-get install python-smbus).Save the below code as pylcdlib.py

import smbus
from time import *
# General i2c device class so that other devices can be added easily
class i2c_device:
 def __init__(self, addr, port):
  self.addr = addr
  self.bus = smbus.SMBus(port)
 def write(self, byte):
  self.bus.write_byte(self.addr, byte)
 def read(self):
  return self.bus.read_byte(self.addr)
 def read_nbytes_data(self, data, n): # For sequential reads > 1 byte
  return self.bus.read_i2c_block_data(self.addr, data, n)
class lcd:
 #initializes objects and lcd
 '''
 Reverse Codes:
 0: lower 4 bits of expander are commands bits
 1: top 4 bits of expander are commands bits AND P0-4 P1-5 P2-6
 2: top 4 bits of expander are commands bits AND P0-6 P1-5 P2-4
 '''
 def __init__(self, addr, port, reverse=0):
  self.reverse = reverse
  self.lcd_device = i2c_device(addr, port)
  if self.reverse:
   self.lcd_device.write(0x30)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_device.write(0x20)
   self.lcd_strobe()
   sleep(0.0005)
  else:
   self.lcd_device.write(0x03)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_strobe()
   sleep(0.0005)
   self.lcd_device.write(0x02)
   self.lcd_strobe()
   sleep(0.0005)
  self.lcd_write(0x28)
  self.lcd_write(0x08)
  self.lcd_write(0x01)
  self.lcd_write(0x06)
  self.lcd_write(0x0C)
  self.lcd_write(0x0F)
 # clocks EN to latch command
 def lcd_strobe(self):
  if self.reverse == 1:
   self.lcd_device.write((self.lcd_device.read() | 0x04))
   self.lcd_device.write((self.lcd_device.read() & 0xFB))
  if self.reverse == 2:
   self.lcd_device.write((self.lcd_device.read() | 0x01))
   self.lcd_device.write((self.lcd_device.read() & 0xFE))
  else:
   self.lcd_device.write((self.lcd_device.read() | 0x10))
   self.lcd_device.write((self.lcd_device.read() & 0xEF))
 # write a command to lcd
 def lcd_write(self, cmd):
  if self.reverse:
   self.lcd_device.write((cmd >> 4)<<4)
   self.lcd_strobe()
   self.lcd_device.write((cmd & 0x0F)<<4)
   self.lcd_strobe()
   self.lcd_device.write(0x0)
  else:
   self.lcd_device.write((cmd >> 4))
   self.lcd_strobe()
   self.lcd_device.write((cmd & 0x0F))
   self.lcd_strobe()
   self.lcd_device.write(0x0)
 # write a character to lcd (or character rom)
 def lcd_write_char(self, charvalue):
  if self.reverse == 1:
   self.lcd_device.write((0x01 | (charvalue >> 4)<<4))
   self.lcd_strobe()
   self.lcd_device.write((0x01 | (charvalue & 0x0F)<<4))
   self.lcd_strobe()
   self.lcd_device.write(0x0)
  if self.reverse == 2:
   self.lcd_device.write((0x04 | (charvalue >> 4)<<4))
   self.lcd_strobe()
   self.lcd_device.write((0x04 | (charvalue & 0x0F)<<4))
   self.lcd_strobe()
   self.lcd_device.write(0x0)
  else:
   self.lcd_device.write((0x40 | (charvalue >> 4)))
   self.lcd_strobe()
   self.lcd_device.write((0x40 | (charvalue & 0x0F)))
   self.lcd_strobe()
   self.lcd_device.write(0x0)
 # put char function
 def lcd_putc(self, char):
  self.lcd_write_char(ord(char))
 # put string function
 def lcd_puts(self, string, line):
  if line == 1:
   self.lcd_write(0x80)
  if line == 2:
   self.lcd_write(0xC0)
  if line == 3:
   self.lcd_write(0x94)
  if line == 4:
   self.lcd_write(0xD4)
  for char in string:
   self.lcd_putc(char)
 # clear lcd and set to home
 def lcd_clear(self):
  self.lcd_write(0x1)
  self.lcd_write(0x2)
 # add custom characters (0 - 7)
 def lcd_load_custon_chars(self, fontdata):
  self.lcd_device.bus.write(0x40);
  for char in fontdata:
   for line in char:
    self.lcd_write_char(line)
Main Program:-
import pylcdlib
lcd = pylcdlib.lcd(0x21,0)
lcd.lcd_puts("Raspberry Pi",1)  #display "Raspberry Pi" on line 1
lcd.lcd_puts("  Take a byte!",2)  #display "Take a byte!" on line 2

 Save the above code as test_lcd.py and enter sudo python test_lcd.py
My code assumes that the first 4 bits of the LCD(11,12,13,14) are connected to P0,P1,P2,P3 ports on PCF8574. The next 3 ports on PCF8574(P4,P5,P6) should be connected to 4-RS, 5-R/W, 6-E.However there are other serial backpack lcd's with different pinouts. According to the wiring of your serial backpack LCD you can override the default mapping during initialization.There are 3 modes available-
lcd = pylcdlib.lcd(0x21,0)   lower 4 bits of expander are commands bits
lcd = pylcdlib.lcd(0x21,0,1)   top 4 bits of expander are commands bits AND   P0-4   P1-5   P2-6
lcd = pylcdlib.lcd(0x21,0,2)   top 4 bits of expander are commands bits AND   P0-6   P1-5   P2-4
Read More »

Overclocking the Raspberry Pi


Raspberry Pi uses the Broadcom BCM2835 system-on-chip (SoC) processor which was originally developed to be used with applications that involved heavy graphics and multimedia handling. This led to the design of architecture that pairs a relatively weak and outdated CPU with a massively powerful graphics processor.The CPU instruction set is based on an outdated ARM v6  architecture.


Overclocking the Raspberry Pi is quite different from that of the desktop processors, where if you overclock it and crank up the voltage a few notch you can sustain a higher clock rate with increased power consumption.But the problem with Raspberry Pi is that it uses a mobile phone chip and over-volting can significantly lower the overall chip lifetime.


Even though, since launch Raspberry Pi supported over-volting and overclocking by modifying the "config.txt". The Raspberry Pi can be safely overclocked to 1 GHz without voiding the warranty. Over-volting  is not recommended as it will permanently set a fuse in your SoC and void your warranty.


The latest version of the Raspbian operating system has inbuilt overclock method built into it.With the help of cpufreq driver it offers a “turbo mode”, which can dynamically overclock and over-volt the chip without voiding your warranty.To overclock enter "sudo raspi-config"  in Terminal. Select "overclock" and reboot the system. This will enables dynamic overclocking. If your Raspberry Pi gets too hot(85°C) it will automatically drop back down to 700MHz.


In case the Pi fails to boot due to higher clock, hold the shift key to disable the overclock for that boot session. Link for default clock: http://elinux.org/RPi_config.txt#Overclocking_configuration. Also make sure that you have a decent quality power supply capable of handling the extra load due to overclocking.





Read More »

Raspberry Pi temperature sensor using TMP102

The TMP102 is an I2C temperature sensor from Texas Instruments.It's a perfect sensor for Raspberry Pi as it lacks any onboard ADC and TMP102 eliminates the requirement for analyzing the analog signals.When compared with the analog sensors TMP102 is very accurate and capable of measuring 0.0625ºC changes between -25°C and +85°C.

TMP102 pinout

If you have more than one device on the I2C bus you can modify the address of the sensor using the address pin (ADD0).The sensor's address will be 72(0×48 in hex) when the address pin is grounded.It will be set to 73 (0×49 in hex) if the address pin is tied to VCC.

Pi GPI0        Function
---------------------------
Pin 2            SDA
Pin 3            SCL
Pin 26          5V  

Make sure your system has the latest version of Linux 3.2 kernel and a proper I2C driver.Also you will be requiring two utilities:-
1) "lm-sensors" package, enter "apt-get install lm-sensors"
2) "I2C tools" package, enter "apt-get install i2c-tools"

After installation we can now use the modprobe i2c-tools.Run "i2cdetect" to check whether TMP102 is connected.

root@raspberrypi:~# i2cdetect -y 0

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --


As we have received the address from i2cdetect, the system has to be updated to get new drivers.

rahul@raspberrypi:~# echo tmp102 0x48 > /sys/class/i2c-adapter/i2c-0/new_device

Run the "sensors" command to get the temperature:-

rahul@raspberrypi:~# sensors
tmp102-i2c-0-48
Adapter: bcm2708_i2c.0
temp1:        +35.7°C  (high = +70.0°C, hyst = +55.0°C)




Read More »

Safely Shutting Down / Rebooting your Raspberry Pi


Well the most easiest way to shut down any computer is by pulling the plug or to switch it off directly. As with most of the PCs they can be switched off forcibly even when the system has crashed by holding the power switch for 3 secs. But this method isn't quite healthy for your system as it can damage the HDD or BIOS. For the Raspberry Pi, it can cause problems or corrupt the SD card.

So now let’s talk about how to shut down your Raspberry Pi when it hasn't frozen.

sudo shutdown -h now (or sudo halt)  [-h means halt the system] [now means to shutdown immediately]

You can also use the shorthand's:- `halt` and `reboot`.


Remember that you will need sudo privileges to  use shutdown (or halt)

When the shutdown command is entered it sends out a message to all logged in users
“The system is going down for system halt NOW!”
If you want to reebot your system simply replace the -h with -r 
sudo shutdown -r now (or sudo reboot) [-r means reboot the system] [now means to shutdown immediately]

Now for cases when your system is not responding or frozen,ssh comes in handy.By using a ssh client on another computer within the same network start an Xterm console window and enter the given commands..
sudo shutdown -h now (or sudo halt) OR
sudo shutdown -r now (or sudo reboot)
Your ssh session will terminate as the system is shutting down.
Read More »

Preparing your SD card for Raspberry Pi



As with all computers, your Raspberry Pi requires a boot-loader and a suitable Operating System to boot. Some Raspberry Pi's comes with  pre-installed SD card, but if you didn't receive one you will need to prepare your own.

You can use the BerryBoot installer if your Pi is connected to the Internet.A small zip file containing the BerryBoot system files is required to be extracted to an empty SD card .Then boot up your Pi with the SD card inserted  and follow the on-screen prompts to complete the installation. BerryBoot allows you to install more than one Operating System.

To prepare your SD card you have to download the SD image (the data you will write to the card) from a mirror or a torrent . It is recommended that you verify the image with the SHA-1 checksum provided in the download page. After successfully downloading the image extract the image file to a folder of your choice.Now insert the SD card and note the drive letter assigned.Format the SD card to avoid any troubles.You will need an utility (Win32ImageWriter) to make your SD card bootable. Locate the image file that you have extracted and select the drive letter in device box of Win32DiskImager .



Then you need to hit on 'Write' followed by ‘Yes’ when confirmation box appears . The burn process takes around 3 minutes and upon completion you will get a pop up ‘Write Successful’.  Now remove the SD card from your computer put it in your Raspberry Pi .You can expand the partitions using configure script to use all of the SD card if you have used SD card of capacity greater than 4 G.B.


Read More »