使用 Intel® Galileo 板的防盗报警器





0/5 (0投票)
此示例应用程序的开发旨在展示如何将接近传感器与 Intel® Galileo 开发板结合使用。
引言
此示例应用程序的开发旨在展示如何将接近传感器与 Intel® Galileo 开发板结合使用。在示例中,当任何物体进入接近传感器 3 厘米范围内时,系统会发出警报声并持续闪烁 LED 灯,直到物体移出接近传感器的探测范围。
此示例代码使用物联网 (IoT) 开发套件的 Live USB 映像来运行主机系统,该系统可以使用 Yocto 应用程序开发工具和 Eclipse* 将程序推送到 Intel® Galileo 板。
本文档假定您已满足以下条件:
- Intel® Galileo 板已使用 IoT 开发套件中提供的 SD 映像启动。
- 读者知道如何使用 Eclipse 插件构建 C 程序,以及如何将代码推送到开发板。
硬件要求
- Intel Galileo 开发板
- Intel Galileo 板的 3.3 V 和 5 V 之间有一个跳线,或者需要 5 V 外部电源。在下面的示例中,我们使用了外部电源。
- 一个能向开发板输出数字信号的接近传感器
- 蜂鸣器
- 2N2222 晶体管
- 1k 欧姆电阻
- 面包板
首先,我们将完成此应用程序的电路连接。然后,我们将查看 C 程序,该程序将控制各种 GPIO 引脚,根据接近传感器输入来切换 LED 和蜂鸣器报警。
现在,将电源连接到您的 Intel Galileo 板以及面包板。请按照下面的电路图进行连接。
开发板的引脚映射及其功能
电路
(注意:Intel Galileo 板上的端口与 Arduino 板上的端口相匹配)
- 此示例将使用 GPIO 13 和 PWM 3 作为输出,# 8 作为输入。
- 我们使用 3.3 V 电流为接近传感器供电。
- GPIO 13 用于闪烁 LED 灯。
- PWM 3 用于调节我们馈送到晶体管基极的电流大小。根据此电流,晶体管将改变流入蜂鸣器的电流大小。为了确保我们的 PWM 引脚安全,我们在 PWM 3 和晶体管基极之间放置了一个 1K 欧姆电阻。
- GPIO #8 将作为我们从接近传感器接收的数字输入。当任何物体在接近传感器的探测范围内时,传感器将输出高电平(HIGH),否则输出低电平(LOW)。
- 根据 GPIO #8 的输入,程序将设置 GPIO #13 的电压为高电平以点亮 LED。我们还将调整 PWM #3 的占空比。根据占空比的变化,蜂鸣器将发出声音(发出类似救护车的声音)。
每个 GPIO 的逻辑表示可以在 /sys/class/gpio 目录中找到,PWM 引脚可以在 /sys/class/pwm 目录中找到。Sergey 的博客“Intel Galileo - 编程 Linux 中的 GPIO”对模块和 GPIO/PWM 映射进行了精彩的介绍。在继续之前,建议您阅读此博客。
C 程序
现在是示例代码。此代码执行操作以控制 GPIO,这些操作包括:
1)将 GPIO 号导出到 /sys/class/gpio/export 文件
2)设置方向:in 表示输入,out 表示输出
这些步骤通过 openGPIO 函数实现,该函数打开相应的文件并返回文件标识符,以便将来根据声明的方向进行读取或写入。
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.
}
此代码负责操作 PWM 引脚所需的操作,这些操作包括:
1)将 PWM 号导出到 /sys/class/pwm/pwmchip0/export 文件
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)启用 PWM 引脚
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)设置 PWM 周期
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)设置占空比
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);
}
这些步骤通过 openGPIO 函数实现,该函数打开相应的文件并返回文件标识符,以便将来根据声明的方向进行读取或写入。
在 main 函数中:
1. 将 GPIO 8 打开作为输入
openGPIO(GP_PROXY, GPIO_DIRECTION_IN);
2. 将 GPIO 13 打开作为输出
openGPIO(GP_LED, GPIO_DIRECTION_OUT);
3. 打开 PWM 3,启用输入,设置周期,并初始化占空比。
//set PWM parameters
openPWM(GP_PWM);
setPWMPeriod(1000000,GP_PWM);
enablePWM(1,GP_PWM);
setPWMDutyCycle(0,GP_PWM);
现在进入一个无限循环,并持续读取接近传感器数据。如果接近传感器读数为 HIGH(程序中为 1),则更改 PWM #3 输出的占空比。在 200000 和 500000 之间切换 duty_cycle 值,以在蜂鸣器上产生类似救护车的鸣笛声。除了更改 PWM #3 的占空比外,还会切换 GPIO 13 上的 LED 灯。
GPIO 读取逻辑如下:
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;
}
GPIO 写入逻辑如下:
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);
}
主函数循环如下所示:
//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);
}
最后,关闭 GPIO 和 PWM 端口。
closeGPIO(GP_LED, fileHandleGPIO_LED);
closeGPIO(GP_PROXY, fileHandleGPIO_PROXY);
closePWM(GP_PWM);
完整代码可以在这里找到。要执行它,请打开 IoT 开发套件 Live USB 映像自带的 Hello World 示例,然后将那里的代码替换为 BurglarAlarm.c 文件中的代码。它应该可以正常运行。
Intel 和 Intel 标志是 Intel Corporation 在美国和/或其他国家/地区的商标。
版权所有 © 2014 英特尔公司。保留所有权利。
*其他名称和品牌可能被声明为他人的财产。
有关编译器优化的更完整信息,请参阅我们的优化声明。