“智慧光伏”项目能够智能追踪阳光的移动轨迹。通过内置的光敏传感器和智能控制系统,实时感知周围光源的变化,并驱动太阳能板精准调整角度,确保每一缕阳光都能被最大化地捕捉和利用。下面就和各位小伙伴详细介绍一下这一开源项目是怎样实现的。
环境说明
1.开发环境操作系统:Ubuntu18.04 64位版
2.交叉编译工具链:arm-poky-linux-gnueabi-gcc5.3.0
3.开发板使用Bootloader版本:u-boot-2016.03
4.开发板内核版本:linux-4.1.15
5.开发板移植QT版本:qt5.6.2
一、 硬件连接
1、四路光敏传感器与板卡的连接
2、舵机与板卡的连接
二、内核适配
1、实现舵机转动的功能
MG90S舵机采用pwm的方式来控制,该项目需要用到两个舵机,所以需要在设备树中进行pwm7、pwm8的复用。
(1)拷贝ELF1开发板资料包\02-Linux 源代码\02-0 出厂内核和uboot源码\内核源码\linux-4.1.15-elf1.tar.bz2
内核源码到开发环境/home/elf/work/目录下解压
elf@ubuntu:~/work$ tar -xvf linux-4.1.15-elf1.tar.bz2
(2)修改顶层设备树文件arch/arm/boot/dts/imx6ull.dtsi
elf@ubuntu:~/work$ cd linux-4.1.15-elf1/ elf@ubuntu:~/work/linux-4.1.15-elf1$ vi arch/arm/boot/dts/imx6ull.dtsi
(3)修改设备树文件arch/arm/boot/dts/imx6ull-elf1-emmc.dts
elf@ubuntu:~/work/linux-4.1.15-elf1$ vi arch/arm/boot/dts/imx6ull-elf1-emmc.dts
添加pwm7、pwm8设备节点
&pwm7 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pwm7>; status = "okay"; }; &pwm8 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pwm8>; status = "okay"; };
在iomux节点下面添加pwm7、pwm8引脚复用
pinctrl_pwm7: pwm7grp { fsl,pins = < MX6UL_PAD_CSI_VSYNC__PWM7_OUT 0x110b0 >; }; pinctrl_pwm8: pwm8grp { fsl,pins = < MX6UL_PAD_CSI_HSYNC__PWM8_OUT 0x110b0 >; };
取消其它用到csi功能的地方
至此pwm7、pwm8已经复用完成
2、实现获取光照值的功能
四路光敏传感器需要四路adc,需要在设备树中进行adc1、adc2、adc3、adc4的复用
(1)修改设备树文件arch/arm/boot/dts/imx6ull-elf1-emmc.dts
elf@ubuntu:~/work$ cd linux-4.1.15-elf1/ elf@ubuntu:~/work/linux-4.1.15-elf1$ vi arch/arm/boot/dts/imx6ull-elf1-emmc.dts
在iomux节点下面添加adc1、adc2、adc3、adc4引脚复用
pinctrl_adc1: adc1grp { fsl,pins = < MX6UL_PAD_GPIO1_IO05__GPIO1_IO05 0x00b0 MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0x00b0 MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x00b0 MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x00b0 MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x00b0 >; };
注释掉其它用到GPIO1_IO01、GPIO1_IO02、GPIO1_IO03、GPIO1_IO04功能的地方
至此adc已经复用完成
3、编译并替换设备树
(1)执行环境变量
elf@ubuntu:~/work/linux-4.1.15-elf1$ . /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
(2)编译设备树
elf@ubuntu:~/work/linux-4.1.15-elf1$ make imx6ull_elf1_defconfig elf@ubuntu:~/work/linux-4.1.15-elf1$ make dtbs
(3)将arch/arm/boot/dts/路径下的imx6ull-elf1-emmc.dtb放到U盘,通过U盘拷贝到开发板
root@ELF1:~# cp /run/media/sda1/imx6ull-elf1-emmc.dtb /run/media/mmcblk1p1/
(4)保存并重启开发板
root@ELF1:~# sync root@ELF1:~# reboot
三、数据采集和设备控制
1、程序设计
主函数的实现main.cpp
int main() { int up = 0; int down = 0; int left = 0; int right = 0; int duty_cycle6 = DUTY_90_DEG; int duty_cycle7 = DUTY_90_DEG; int adcChannels[] = {1, 2, 3, 4}; int adcValues[4] = {0}; init_pwm(); write_file(PWM6_DUTY_CYCLE, duty_cycle6); write_file(PWM7_DUTY_CYCLE, duty_cycle7); while (1) { for (int i = 0; i < 4; ++i) { adcValues[i] = read_adc_value(adcChannels[i]); } up = (adcValues[3] + adcValues[0]) ; down = (adcValues[2] + adcValues[1]) ; left = (adcValues[3] + adcValues[2]) ; right = (adcValues[0] + adcValues[1]) ; printf("up: %d\n", up); printf("down: %d\n", down); printf("left: %d\n", left); printf("right: %d\n", right); if ((down - up >= 200) && (duty_cycle6 >= DUTY_0_DEG)) { duty_cycle6 -= 100000; write_file(PWM6_DUTY_CYCLE, duty_cycle6); usleep(10000); } if ((up - down >= 200) && (duty_cycle6 <= DUTY_180_DEG)) { duty_cycle6 += 100000; write_file(PWM6_DUTY_CYCLE, duty_cycle6); usleep(10000); } if ((right - left >= 200) && (duty_cycle7 >= DUTY_0_DEG)) { duty_cycle7 -= 100000; write_file(PWM7_DUTY_CYCLE, duty_cycle7); usleep(10000); } if ((left - right >= 200) && (duty_cycle7 <= DUTY_180_DEG)) { duty_cycle7 += 100000; write_file(PWM7_DUTY_CYCLE, duty_cycle7); usleep(10000); } usleep(100000); } return 0; }
配置pwm
int init_pwm() { write_file(PWM6_EXPORT, 0); if (-1 == write_file(PWM6_PERIOD, PWM_PERIOD)) return -1; if (-1 == write_file(PWM6_ENABLE, 1)) return -1; write_file(PWM7_EXPORT, 0); if (-1 == write_file(PWM7_PERIOD, PWM_PERIOD)) return -1; if (-1 == write_file(PWM7_ENABLE, 1)) return -1; return 0; }
设置舵机初始位置
write_file(PWM6_DUTY_CYCLE, duty_cycle6); write_file(PWM7_DUTY_CYCLE, duty_cycle7);
获取光照值
int read_adc_value(int adcNumber) { int adcValue = 0 ; FILE* adcFile; char adcValueFile[50]; char adcValueStr[10] = "0"; snprintf(adcValueFile, sizeof(adcValueFile), "/sys/bus/iio/devices/iio:device0/in_voltage%d_raw", adcNumber); adcFile = fopen(adcValueFile, "r"); if (adcFile) { fgets(adcValueStr, sizeof(adcValueStr), adcFile); adcValue = atoi(adcValueStr); fclose(adcFile); } else { fprintf(stderr, "Error opening ADC value file %s.\n", adcValueFile); } return adcValue; }
根据光照值调整舵机位置
if ((down - up >= 200) && (duty_cycle6 >= DUTY_0_DEG)) { duty_cycle6 -= 100000; write_file(PWM6_DUTY_CYCLE, duty_cycle6); usleep(10000); } if ((up - down >= 200) && (duty_cycle6 <= DUTY_180_DEG)) { duty_cycle6 += 100000; write_file(PWM6_DUTY_CYCLE, duty_cycle6); usleep(10000); } if ((right - left >= 200) && (duty_cycle7 >= DUTY_0_DEG)) { duty_cycle7 -= 100000; write_file(PWM7_DUTY_CYCLE, duty_cycle7); usleep(10000); } if ((left - right >= 200) && (duty_cycle7 <= DUTY_180_DEG)) { duty_cycle7 += 100000; write_file(PWM7_DUTY_CYCLE, duty_cycle7); usleep(10000); }
2、应用编译
(1)拷贝sun.tar.bz2到开发环境/home/elf/work目录下解压
elf@ubuntu:~/work$ tar xvf sun.tar.bz2
(2)执行环境变量
elf@ubuntu:~/work$ . /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
(3)编译
elf@ubuntu:~/work$ cd sun/ elf@ubuntu:~/work/sun$ make
(4)拷贝sanapp到开发板/home/root路径下
root@ELF1:~# cp /run/media/sda1/sunapp ./ root@ELF1:~# sync
四、项目测试
1、确保开发板已正确连接四路光敏传感器和舵机
2、执行应用
root@ELF1:~# ./sunapp
此时可以打开手电筒interwetten与威廉的赔率体系 太阳光,调整太阳能板的角度
对于初涉嵌入式开发领域的小伙伴来说,“智慧光伏”无疑是一个兼具趣味与实践的开源项目。通过亲身参与这一开源项目的组装与调试过程,可以直接接触到真实的开发环境、工具链和代码库,从而解决实际问题,帮助初学者更快地成长为合格的嵌入式开发工程师
-
单片机
+关注
关注
6039文章
44575浏览量
636395 -
嵌入式
+关注
关注
5086文章
19143浏览量
306095 -
开发板
+关注
关注
25文章
5081浏览量
97692 -
Linux开发
+关注
关注
0文章
34浏览量
6924 -
开源代码
+关注
关注
0文章
36浏览量
2992
发布评论请先 登录
相关推荐
评论