跳转到主要内容

BURGLAR ALARM 使用英特尔® GALILEO 开发板

editor 提交于


开发该范例应用的目的是为了如何针对英特尔® Galileo 开发板使用近距离传感器。 在示例中,如果任意物体出现在距近距离传感器 3 厘米的范围内,系统将发出警报且 LED 持续闪烁,直到物体离开该范围。

该示例代码使用物联网 (IoT) 开发套件的 Live USB 映像运行主机系统,后者可以借助 Yocto 应用开发工具和 Eclipse* 将草图推送至英特尔® Galileo 开发板。

本文将做出以下假设:

英特尔® Galileo 开发板借助 SD 映像启动,并可用于 IoT 开发套件。

读者了解如何借助 Eclipse 插件构建 C 程序,以及如何将代码推送至开发板。

硬件要求:

英特尔 Galileo 开发板

英特尔 Galileo 开发板 3.3 V 或 5 V 跳线器,或 5 V 外部电源。 在下列示例中,我们使用外部电源。

将数字输出传给开发板的近距离传感器

蜂鸣器

2N2222 晶体管

1k 电阻器

电路试验板(Breadboard)

首先,我们接通该应用的电路。 然后我们对 C 程序进行观察,该程序可控制不同 GPIO pin 以根据距离输入切换 LED 和蜂鸣报警器。

现在,接通英特尔 Galileo 开发板和电路试验板的电源。 电路如下图所示:

基于开发板的 PIN 映射及其功能:


电路:

(注: 英特尔 Galileo 开发板上的端口与 Arduino 开发板上的端口相匹配)


1、本示例中,GPIO 13 和 PWM 3 用作输出端口, # 8 用作输入端口。

2、采用 3.3 V 电流为近距离传感器供电。

3、GPIO 13 用于使 LED 灯闪烁。

4、PWM 3 用于调节通过晶体管基区的电流。 晶体管根据电流改变通过蜂鸣器的电流。 为保证 PWM pin 的安全,我们在 PWM 3 和晶体管基区之间放置一个 1000 欧姆电阻器。

5、GPIO #8 作为数字输入端口与近距离传感器通信。 对象进入近距离传感器范围时,传感器将返回高电压,否则,返回的是低电压。

6、程序将根据 GPIO #8 的输入信息调高 GPIO #13 的电压以点亮 LED。 我们也将调整 PWM #3 的占空比(duty cycle)。 蜂鸣器将根据不同的占空比发出警报(发出类似救护车的声音)。

各 GPIO 的逻辑表示位于 /sys/class/gpio 目录,PWM pins 位于 /sys/class/pwm 目录。 Sergey 的博客“英特尔 Galileo - 通过 Linux 编程 GPIO” 全面介绍了 GPIO 和 PWM 的模块和映射。 进行下一步操作前阅读这篇博客将对您大有帮助。

C 程序:

现在来看一下示例代码。 下列代码执行操控 GPIO 所需的步骤,包括:

(1)向 /sys/class/gpio/export 文件输出 GPIO 数量

(2))设置方向:in 为输入,out 为输出

上述步骤借助 openGPIO 函数得以完成,该函数打开相应的文件并返回文件标识符,以支持后续读取或写入(取决于设置的方向)。

01 int openGPIO(int gpio, int direction )
02 {
03 char buffer[256];
04 int fileHandle;
05 int fileMode;
06
07 //Export GPIO
08 fileHandle = open("/sys/class/gpio/export", O_WRONLY);
09 if(ERROR == fileHandle)
10 {
11 puts("Error: Unable to opening /sys/class/gpio/export");
12 return(-1);
13 }
14 sprintf(buffer, "%d", gpio);
15 write(fileHandle, buffer, strlen(buffer));
16 close(fileHandle);
17
18 //Direction GPIO
19 sprintf(buffer, "/sys/class/gpio/gpio%d/direction", gpio);
20 fileHandle = open(buffer, O_WRONLY);
21 if(ERROR == fileHandle)
22 {
23 puts("Unable to open file:");
24 puts(buffer);
25 return(-1);
26 }
27
28 if (direction == GPIO_DIRECTION_OUT)
29 {
30 // Set out direction
31 write(fileHandle, "out", 3);
32 fileMode = O_WRONLY;
33 }
34 else
35 {
36 // Set in direction
37 write(fileHandle, "in", 2);
38 fileMode = O_RDONLY;
39 }
40 close(fileHandle);
41
42
43 //Open GPIO for Read / Write
44 sprintf(buffer, "/sys/class/gpio/gpio%d/value", gpio);
45 fileHandle = open(buffer, fileMode);
46 if(ERROR == fileHandle)
47 {
48 puts("Unable to open file:");
49 puts(buffer);
50 return(-1);
51 }
52
53 return(fileHandle); //This file handle will be used in read/write and close operations.
54 }

以下代码执行操控 PWM pin 所需的步骤,包括:

(1)向 /sys/class/pwm/pwmchip0/export 文件输出 PWM 数量

01 int openPWM(int port)
02 {
03 char buffer[256];
04 int fileHandle;
05 int fileMode;
06
07 //Export GPIO
08 fileHandle = open("/sys/class/pwm/pwmchip0/export", O_WRONLY);
09
10 if(ERROR == fileHandle)
11
12 {
13 puts("Error: Unable to opening /sys/class/pwm/pwmchip0/export");
14 return(-1);
15 }
16 sprintf(buffer, "%d", port);
17 write(fileHandle, buffer, strlen(buffer));
18 close(fileHandle);
19 sleep(1);
20 return 0;
21 }

(2))启用 PWM pin

01 int enablePWM(int enable,int port)
02 {
03 char buffer[256];
04
05 int fileHandle;
06
07
08 //Enable PWM
09 sprintf(buffer, "/sys/class/pwm/pwmchip0/pwm%d/enable", port);
10 fileHandle = open(buffer, O_WRONLY);
11 if(ERROR == fileHandle)
12 {
13 puts("Unable to open file:");
14
15 puts(buffer);
16
17 return(-1);
18
19 }
20
21 sprintf(buffer, "%d", enable);
22 write(fileHandle, buffer, strlen(buffer));
23 return 0;
24 }

(3)设置 PWM 周期

01 int setPWMPeriod(int period, int port)
02 {
03 //Open GPIO for Read / Write
04 char buffer[256];
05 int fileHandle;
06
07
08 sprintf(buffer, "/sys/class/pwm/pwmchip0/pwm%d/period", port);
09
10 fileHandle = open(buffer, O_WRONLY);
11 if(ERROR == fileHandle)
12 {
13 puts("Unable to open file:");
14
15 puts(buffer);
16
17 return(-1);
18 }
19 sprintf(buffer, "%d", period);
20 write(fileHandle, buffer, strlen(buffer));
21
22 close(fileHandle);
23 return(0);
24
25 }

(4) 设置占空比

01 int setPWMDutyCycle(int dutycycle, int port)
02 {
03 //Open GPIO for Read / Write
04 char buffer[256];
05 int fileHandle;
06
07
08 sprintf(buffer, "/sys/class/pwm/pwmchip0/pwm%d/duty_cycle", port);
09
10 fileHandle = open(buffer, O_WRONLY);
11 if(ERROR == fileHandle)
12 {
13 puts("Unable to open file:");
14
15 puts(buffer);
16
17 return(-1);
18 }
19 sprintf(buffer, "%d", dutycycle);
20 write(fileHandle, buffer, strlen(buffer));
21 close(fileHandle);
22 return(0);
23
24 }

上述步骤借助 openGPIO 函数得以完成,该函数打开相应的文件夹并返回文件夹标识符,以支持后续读取或写入(取决于设置的方向)。

在主函数中:

1.、打开 GPIO 8(输入)

1 openGPIO(GP_PROXY, GPIO_DIRECTION_IN);

2、打开 GPIO 13(输出)

1 openGPIO(GP_LED, GPIO_DIRECTION_OUT);

3、 打开 PWM 3、启用输入、设置周期,并初始化占空比。

1 //set PWM parameters
2 openPWM(GP_PWM);
3 setPWMPeriod(1000000,GP_PWM);
4 enablePWM(1,GP_PWM);
5 setPWMDutyCycle(0,GP_PWM);

现在打开无限循环,并连续读取近距离传感器数据。 如果距离值较高(程序中的 1),请调整 PWM #3 输出的占空比。 将占空比值在 200000 至 500000 之间切换,确保蜂鸣器发出类似救护车的声音。 同时改变 PWM #3 的占空比,切换 GPIO 13 的 LED 灯。

GPIO 读取逻辑如下所示。

int readGPIO(int fileHandle,int gpio)

01 {
02 int value;
03 //Reopening the file again in read mode, since data was not refreshing.
04 fileHandle = openFileForReading(gpio);
05 read(fileHandle, &value, 1);
06
07 if('0' == value)
08 {
09 // Current GPIO status low
10 value = 0;
11 }
12 else
13 {
14 // Current GPIO status high
15 value = 1;
16 }
17 close(fileHandle);
18 return value;
19 }

GPIO 写入逻辑如下所示。

int writeGPIO(int fHandle, int val)

01 {
02 if(val == 0)
03
04 {
05 // Set GPIO low status
06 write(fHandle, "0", 1);
07 }
08 else
09
10 {
11 // Set GPIO high status
12 write(fHandle, "1", 1);
13
14 }
15 return(0);
16
17 }

主函数循环如下所示。

01 //Start an infinite loop to keep polling for proximity info
02 int proxyValue = 0;
03 while(1==1)
04 {
05 proxyValue = readGPIO(fileHandleGPIO_PROXY,GP_PROXY);
06 if(proxyValue == 1)
07 {
08 if(duty_cycle == 500000)
09 {
10 duty_cycle = 200000;
11 writeGPIO(fileHandleGPIO_LED, 0);
12 }
13 else
14 {
15 duty_cycle = 500000;
16 writeGPIO(fileHandleGPIO_LED, 1);
17 }
18 setPWMDutyCycle(duty_cycle,GP_PWM);
19 }
20 else
21 {
22 duty_cycle = 50000;
23 setPWMDutyCycle(0,GP_PWM);
24 writeGPIO(fileHandleGPIO_LED, 0);
25 }
26 usleep(1000*400);
27 }

最后关闭 GPIO 和 PWM 端口。

1 closeGPIO(GP_LED, fileHandleGPIO_LED);

2 closeGPIO(GP_PROXY, fileHandleGPIO_PROXY);

3 closePWM(GP_PWM);

文章来源:英特尔开发人员专区