【基于ELF 1開(kāi)發(fā)板完成的“智慧光伏”項(xiàng)目】
“智慧光伏”項(xiàng)目能夠智能追蹤陽(yáng)光的移動(dòng)軌跡。通過(guò)內(nèi)置的光敏傳感器和智能控制系統(tǒng),實(shí)時(shí)感知周?chē)庠吹淖兓?,并?qū)動(dòng)太陽(yáng)能板精準(zhǔn)調(diào)整角度,確保每一縷陽(yáng)光都能被最大化地捕捉和利用。下面就和各位小伙伴詳細(xì)介紹一下這一開(kāi)源項(xiàng)目是怎樣實(shí)現(xiàn)的。
1、四路光敏傳感器與板卡的連接
2、舵機(jī)與板卡的連接
1、實(shí)現(xiàn)舵機(jī)轉(zhuǎn)動(dòng)的功能
elf@ubuntu:~/work$ tar -xvf linux-4.1.15-elf1.tar.bz2
(2)修改頂層設(shè)備樹(shù)文件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
elf@ubuntu:~/work/linux-4.1.15-elf1$ vi arch/arm/boot/dts/imx6ull-elf1-emmc.dts
添加pwm7、pwm8設(shè)備節(jié)點(diǎn)
&pwm7 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm7>;
status = "okay";
};
&pwm8 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm8>;
status = "okay";
};
pinctrl_pwm7: pwm7grp {
fsl,pins = <
MX6UL_PAD_CSI_VSYNC__PWM7_OUT 0x110b0
>;
};
pinctrl_pwm8: pwm8grp {
fsl,pins = <
MX6UL_PAD_CSI_HSYNC__PWM8_OUT 0x110b0
>;
};
2、實(shí)現(xiàn)獲取光照值的功能
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
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
>;
};
?
3、編譯并替換設(shè)備樹(shù)
(1)執(zhí)行環(huán)境變量
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)編譯設(shè)備樹(shù)
elf@ubuntu:~/work/linux-4.1.15-elf1$ make imx6ull_elf1_defconfig
elf@ubuntu:~/work/linux-4.1.15-elf1$ make dtbs
root@ELF1:~# cp /run/media/sda1/imx6ull-elf1-emmc.dtb /run/media/mmcblk1p1/
(4)保存并重啟開(kāi)發(fā)板
root@ELF1:~# sync
root@ELF1:~# reboot
1、程序設(shè)計(jì)
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: %dn", up);
printf("down: %dn", down);
printf("left: %dn", left);
printf("right: %dn", 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;
}
設(shè)置舵機(jī)初始位置
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;
}
根據(jù)光照值調(diào)整舵機(jī)位置
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、應(yīng)用編譯
(1)拷貝sun.tar.bz2到開(kāi)發(fā)環(huán)境/home/elf/work目錄下解壓
elf@ubuntu:~/work$ tar xvf sun.tar.bz2
(2)執(zhí)行環(huán)境變量
elf@ubuntu:~/work$ . /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
elf@ubuntu:~/work$ cd sun/
elf@ubuntu:~/work/sun$ make
?
?
(4)拷貝sanapp到開(kāi)發(fā)板/home/root路徑下
root@ELF1:~# cp /run/media/sda1/sunapp ./
root@ELF1:~# sync
四、項(xiàng)目測(cè)試
1、確保開(kāi)發(fā)板已正確連接四路光敏傳感器和舵機(jī)
2、執(zhí)行應(yīng)用
root@ELF1:~# ./sunapp
此時(shí)可以打開(kāi)手電筒模擬太陽(yáng)光,調(diào)整太陽(yáng)能板的角度
對(duì)于初涉嵌入式開(kāi)發(fā)領(lǐng)域的小伙伴來(lái)說(shuō),“智慧光伏”無(wú)疑是一個(gè)兼具趣味與實(shí)踐的開(kāi)源項(xiàng)目。通過(guò)親身參與這一開(kāi)源項(xiàng)目的組裝與調(diào)試過(guò)程,可以直接接觸到真實(shí)的開(kāi)發(fā)環(huán)境、工具鏈和代碼庫(kù),從而解決實(shí)際問(wèn)題,幫助初學(xué)者更快地成長(zhǎng)為合格的嵌入式開(kāi)發(fā)工程師。