• RSSRSS
  • TwitterTwitter
  • FacebookFacebook
  • About
  • Privacy Policy
  • Contact Us

Raspberry Pi Blog

Get Guides,Tips,Tricks And Information Related To Raspberry Pi

Powered by Blogger.
  • Home
  • GPIO
  • I2C
  • SSH
  • LCD
  • Hardware
    • I2C
    • ADC
    • PWM
    • LED
    • LCD
  • Software
    • Python
    • C
    • Programming
    • SSH

convert raspberry pi into a wireless access point
In this post I will demonstrate how to transform the Raspberry Pi into a Wireless Access Point. The majority of this post accompanies what is portrayed here yet I have included a couple more steps.


The process may look a little bit lengthy but it can be finished under 10 minutes. Each time you need to alter or make new record, case in point -[ /etc/udhcpd.conf ] you can utilize "sudo nano /etc/udhcpd.conf".

1. The very first thing to do is to check if the dongle is being detected.Fire up the terminal and type :-
lsusb
If any adapter is detected you should get a message like this:-
Bus 001 Device 005: ID 07d1:3c09 D-Link System DWA-140 RangeBooster N Adapter(rev.B1) [Ralink RT2870]

2.Now you'll need to install the "iw" tool to check which modes are supported by your wireless dongle. Open the terminal and type:-
sudo apt-get install iw
After installation enter iw list. At this point you will see a bunch of specs being printed and some place in the middle you might find something similar to this (the modes beneath are the ones of my dongle that I am utilizing):-

Supported interface modes:
   * IBSS
   * managed
   * AP
   * AP/VLAN
   * WDS
   * monitor
   * mesh point
Depending on the support of AP option you can continue going.

3. Next step is to install "hostapd" and "udhcpd" :-
sudo apt-get install hostapd udhcpd

4. Next we need to configure DHCP so that the Raspberry Pi can distribute IP to the clients. Edit the file /etc/udhcpd.conf with following information:-

start 192.168.42.2 # This is the range of IPs that the hostspot will give to client devices.
end 192.168.42.20
interface wlan0 # The device uDHCP listens on.
remaining yes
opt dns 8.8.8.8 4.2.2.2 # The DNS servers client devices will use.
opt subnet 255.255.255.0
opt router 192.168.42.1 # The Pi's IP address on wlan0 which we will set up shortly.
opt lease 864000 # 10 day DHCP lease time in seconds.

5. Next step is to edit the file /etc/default/udchpd and change the line DHCPD_ENABLED="no" to DHCPD_ENABLED="yes"

6. Assign a static IP by entering the following command: sudo ifconfig wlan0 192.168.42.1
To set this up automatically you must edit the file /etc/network/interfaces and replace the line "iface wlan0 inet dhcp" to:
iface wlan0 inet static
address 192.168.42.1
netmask 255.255.255.0
If the line "iface wlan0 inet dhcp" does not exist, include the below lines at thebottom part of the file. You will additionally need to update the lines-

allow-hotplug wlan0
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet manual
to
allow-hotplug wlan0
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet manual

7. In order to create network we need to configure hostapd. It can be either an open network or a WPA- secured network for authorized access only.You need to create or edit some files accordingly. The first file that needs to be edited/created is "/etc/hostapd/hostapd.conf". For a WPA-secured network make it look like this:-

interface=wlan0
driver=nl80211
ssid=My_AP
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=My_Passphrase
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

To create an open network enter the following text in the file instead:-

interface=wlan0
ssid=My_AP
hw_mode=g
channel=6
auth_algs=1
wmm_enabled=0

8. Next  step is to change a variable inside the file /etc/default/hostapd so that it points to the file that has been just created/edited. Change this line: DAEMON_CONF="" to DAEMON_CONF="/etc/hostapd/hostapd.conf"

9. The next thing to do is to configure NAT (Network Address Translation) which is a technique that allows several devices to use a single connection to the internet. Edit the file /etc/sysctl.conf and add the following line to the end of the file:
net.ipv4.ip_forward=1
It will enable NAT in the kernel. Now, run the following commands:
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
And this concludes the NAT configuration. To make it permanent so you don't have to run the commands after each reboot, run the command
sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
and edit the file /etc/network/interfaces and add the following lines to the end of the file:
up iptables-restore < /etc/iptables.ipv4.nat

10. Almost done! Run the following commands to start the Access Point:-
sudo service hostapd start
sudo service udhcpd start
And your Pi should finally be hosting a wireless hotspot!  To get it to start on boot everytime, run these two last commands:
sudo update-rc.d hostapd enable
sudo update-rc.d udhcpd enable
And you're done! If you followed every step correctly everything should be working as expected :-)

led status infi
There are 5 status LED's on the Raspberry Pi board namely [OK, PWR, FDX, LNK, 10M]. FDX, LNK, 10M are connected to the LAN IC- LAN9512. So those 3 LED's will be present only on model B.

According to http://elinux.org/RPi_Hardware

D5(Green) - OK - SDCard Access (via GPIO16)
D6(Red) - PWR - 3.3 V Power
D7(Green) - FDX - Full Duplex (LAN) (Model B)
                                                      D8(Green) - LNK - Link/Activity (LAN) (Model B)
                                                      D9(Yellow) - 10M - 10/100Mbit (LAN) (Model B)

According to the datasheet the pins can also be programmed as GPIO, so these three LEDs could potentially be under software control, but I have not checked if the Linux drivers support this.

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

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


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).                                                                               


  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    
     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!")

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.

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

















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!.

(Update):- If you have a Raspberry Pi with a revision 2.0 board, you need to use I²C bus 1, not bus 0, so you will need to change the bus number used. In this case, the line bus=smbus.SMBus(0) would become bus=smbus.SMBus(1). 

You can check that the device is present on the bus by using the i2cdetect program from the i2ctools package-
i2cdetect 0 -y  or i2cdetect 1 -y 


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.

Recent Posts


Recent Comments

Copyright 2013 RPiBlog. All Rights Reserved.

Site Developed By Rahul Kar