This sample application was developed to showcase the use of a proximity sensor with the Intel® Galileo development board. In the sample whenever any object is found within 3 centimeter from the proximity sensor, the system makes an alarm sound and blinks an LED continuously until the object is out of range of the proximity sensor.
This sample code uses the Internet of Things (IoT) Development Kit’s Live USB image to run a host system that can push sketches to an Intel® Galileo board using Yocto Application Development Tools and Eclipse*.
This article makes the following assumptions:
- The Intel® Galileo board is booted using the SD Image also available in the IoT Development Kit.
- Readers know how to build C programs using the Eclipse plugin and how to push their code to the board.
Hardware requirements:
- Intel Galileo development board
- Either a jumper between 3.3 V and 5 V of the Intel Galileo board or 5 V external supply. In the example below, we used an external power supply.
- Proximity sensor that gives digital output to the board
- Buzzer
- 2N2222 transistor
- 1k resister
- Breadboard
First, we’ll start by completing the circuit for this application. After that we’ll look at the C program that controls the various GPIO pins to toggle the LED and the buzzer alarms based on proximity input.
Now connect the power supply to your Intel Galileo board and also to the breadboard. Follow the circuits as shown below:
PIN mapping on the board and its functionality:
Circuit:
(Note: Ports on the Intel Galileo board match with those on the Arduino board)
- This sample will use GPIO 13 and PWM 3 as outputs and # 8 as input.
- We use 3.3 V current to power the proximity sensor.
- GPIO 13 is used to blink the LED light.
- PWM 3 is used to modulate the amount of current that we pass into the base of transistors. Depending on this current, the transistor will vary the amount of current that goes into the buzzer. Just to make sure our PWM pin is safe, we put a 1K ohm resistor in between PWM 3 and the transistor base.
- GPIO #8 will be our digital input from the proximity sensor. When any object is in range of the proximity sensor, sensor will return HIGH voltage, otherwise it will be LOW.
- Depending on the input on GPIO #8, the program will set the GPIO #13 voltage to HIGH to light the LED. We will also modulate the duty cycle of PWM #3. Based on the variations in the duty cycle, the buzzer will sound (make an ambulance kind of noise).
The logical representation of each GPIO is available in the /sys/class/gpio directory, and PWM pins are in the /sys/class/pwm directory. Sergey’s Blog “Intel Galileo - Programming GPIO From Linux“ has excellent coverage of the modules and mapping of the GPIOs and PWMs. It would be good if you read this blog before proceeding further.
C Program:
Now the sample code. This code performs the steps needed to manipulate the GPIOs, which are:
1) Export the GPIO number to the /sys/class/gpio/export file
2) Set the direction: in for input, out for output
These steps are implemented using the openGPIO function, which opens the corresponding file and returns this file identifier for future reading or writing, depending on the direction declared.
int openGPIO(int gpio, int direction ) { char buffer[256]; int fileHandle; int fileMode; //Export GPIO fileHandle = open("/sys/class/gpio/export", O_WRONLY); if(ERROR == fileHandle) { puts("Error: Unable to opening /sys/class/gpio/export"); return(-1); } sprintf(buffer, "%d", gpio); write(fileHandle, buffer, strlen(buffer)); close(fileHandle); //Direction GPIO sprintf(buffer, "/sys/class/gpio/gpio%d/direction", gpio); fileHandle = open(buffer, O_WRONLY); if(ERROR == fileHandle) { puts("Unable to open file:"); puts(buffer); return(-1); } if (direction == GPIO_DIRECTION_OUT) { // Set out direction write(fileHandle, "out", 3); fileMode = O_WRONLY; } else { // Set in direction write(fileHandle, "in", 2); fileMode = O_RDONLY; } close(fileHandle); //Open GPIO for Read / Write sprintf(buffer, "/sys/class/gpio/gpio%d/value", gpio); fileHandle = open(buffer, fileMode); if(ERROR == fileHandle) { puts("Unable to open file:"); puts(buffer); return(-1); } return(fileHandle); //This file handle will be used in read/write and close operations. }
This code takes care of the steps needed to manipulate the PWM pins, which are:
1) Export the PWM number to the /sys/class/pwm/pwmchip0/export file
int openPWM(int port) { char buffer[256]; int fileHandle; int fileMode; //Export GPIO fileHandle = open("/sys/class/pwm/pwmchip0/export", O_WRONLY); if(ERROR == fileHandle) { puts("Error: Unable to opening /sys/class/pwm/pwmchip0/export"); return(-1); } sprintf(buffer, "%d", port); write(fileHandle, buffer, strlen(buffer)); close(fileHandle); sleep(1); return 0; }
2) Enable the PWM pin
int enablePWM(int enable,int port) { char buffer[256]; int fileHandle; //Enable PWM sprintf(buffer, "/sys/class/pwm/pwmchip0/pwm%d/enable", port); fileHandle = open(buffer, O_WRONLY); if(ERROR == fileHandle) { puts("Unable to open file:"); puts(buffer); return(-1); } sprintf(buffer, "%d", enable); write(fileHandle, buffer, strlen(buffer)); return 0; }
3) Set the PWM period
int setPWMPeriod(int period, int port) { //Open GPIO for Read / Write char buffer[256]; int fileHandle; sprintf(buffer, "/sys/class/pwm/pwmchip0/pwm%d/period", port); fileHandle = open(buffer, O_WRONLY); if(ERROR == fileHandle) { puts("Unable to open file:"); puts(buffer); return(-1); } sprintf(buffer, "%d", period); write(fileHandle, buffer, strlen(buffer)); close(fileHandle); return(0); }
4) Set the duty cycle
int setPWMDutyCycle(int dutycycle, int port) { //Open GPIO for Read / Write char buffer[256]; int fileHandle; sprintf(buffer, "/sys/class/pwm/pwmchip0/pwm%d/duty_cycle", port); fileHandle = open(buffer, O_WRONLY); if(ERROR == fileHandle) { puts("Unable to open file:"); puts(buffer); return(-1); } sprintf(buffer, "%d", dutycycle); write(fileHandle, buffer, strlen(buffer)); close(fileHandle); return(0); }
These steps are implemented using the openGPIO function, which opens the corresponding file and returns this file identifier for future reading or writing, depending on the direction declared.
In the main function:
1. Open GPIO 8 as input
openGPIO(GP_PROXY, GPIO_DIRECTION_IN);
2. Open GPIO 13 as output
openGPIO(GP_LED, GPIO_DIRECTION_OUT);
3. Open PWM 3, enable for input, set period, and initialize duty cycle.
//set PWM parameters openPWM(GP_PWM); setPWMPeriod(1000000,GP_PWM); enablePWM(1,GP_PWM); setPWMDutyCycle(0,GP_PWM);
Now open an infinite loop and continuously read proximity sensor data. If the proximity value is HIGH (1 in the program), change the duty cycle of the PWM #3 output. Toggle between 200000 and 500000 duty_cycle values to make an ambulance type of sound in the buzzer. Along with changing the duty cycle on PWM #3, toggle the LED light on GPIO 13.
The GPIO reading logic is as follows.
int readGPIO(int fileHandle,int gpio)
{ int value; //Reopening the file again in read mode, since data was not refreshing. fileHandle = openFileForReading(gpio); read(fileHandle, &value, 1); if('0' == value) { // Current GPIO status low value = 0; } else { // Current GPIO status high value = 1; } close(fileHandle); return value; }
The GPIO writing logic is as follows.
int writeGPIO(int fHandle, int val)
{ if(val == 0) { // Set GPIO low status write(fHandle, "0", 1); } else { // Set GPIO high status write(fHandle, "1", 1); } return(0); }
The main function loop is shown below.
//Start an infinite loop to keep polling for proximity info int proxyValue = 0; while(1==1) { proxyValue = readGPIO(fileHandleGPIO_PROXY,GP_PROXY); if(proxyValue == 1) { if(duty_cycle == 500000) { duty_cycle = 200000; writeGPIO(fileHandleGPIO_LED, 0); } else { duty_cycle = 500000; writeGPIO(fileHandleGPIO_LED, 1); } setPWMDutyCycle(duty_cycle,GP_PWM); } else { duty_cycle = 50000; setPWMDutyCycle(0,GP_PWM); writeGPIO(fileHandleGPIO_LED, 0); } usleep(1000*400); }
Finally close the GPIO and PWM ports.
closeGPIO(GP_LED, fileHandleGPIO_LED); closeGPIO(GP_PROXY, fileHandleGPIO_PROXY); closePWM(GP_PWM);
The full code can be found here. To execute it, open the Hello World sample that comes with the IoT Development Kit’s Live USB image and replace the code there with the code in the BurglarAlarm.c file. It should run without any problems.
Intel and the Intel logo are trademarks of Intel Corporation in the U.S. and/or other countries.
Copyright © 2014 Intel Corporation. All rights reserved.
*Other names and brands may be claimed as the property of others.