加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

ElfBoard開源項(xiàng)目|“智慧光伏”開源項(xiàng)目技術(shù)文檔

10/12 09:41
407
閱讀需 17 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

【基于ELF 1開發(fā)板完成的“智慧光伏”項(xiàng)目】

“智慧光伏”項(xiàng)目能夠智能追蹤陽光的移動(dòng)軌跡。通過內(nèi)置的光敏傳感器和智能控制系統(tǒng),實(shí)時(shí)感知周圍光源的變化,并驅(qū)動(dòng)太陽能板精準(zhǔn)調(diào)整角度,確保每一縷陽光都能被最大化地捕捉和利用。下面就和各位小伙伴詳細(xì)介紹一下這一開源項(xiàng)目是怎樣實(shí)現(xiàn)的。

環(huán)境說明
1.開發(fā)環(huán)境操作系統(tǒng):Ubuntu18.04 64位版
2.交叉編譯工具鏈:arm-poky-linux-gnueabi-gcc5.3.0
3.開發(fā)板使用Bootloader版本:u-boot-2016.03
4.開發(fā)板內(nèi)核版本:linux-4.1.15
5.開發(fā)板移植QT版本:qt5.6.2
一、 硬件連接

1、四路光敏傳感器與板卡的連接

2、舵機(jī)與板卡的連接

二、內(nèi)核適配

1、實(shí)現(xiàn)舵機(jī)轉(zhuǎn)動(dòng)的功能

MG90S舵機(jī)采用pwm的方式來控制,該項(xiàng)目需要用到兩個(gè)舵機(jī),所以需要在設(shè)備樹中進(jìn)行pwm7、pwm8的復(fù)用。
(1)拷貝ELF1開發(fā)板資料包2-Linux 源代碼2-0 出廠內(nèi)核和uboot源碼內(nèi)核源碼linux-4.1.15-elf1.tar.bz2內(nèi)核源碼到開發(fā)環(huán)境/home/elf/work/目錄下解壓
elf@ubuntu:~/work$ tar -xvf linux-4.1.15-elf1.tar.bz2

(2)修改頂層設(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
(3)修改設(shè)備樹文件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設(shè)備節(jié)點(diǎn)

&pwm7 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm7>;
        status = "okay";
};

&pwm8 {

        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm8>;
        status = "okay";
};
在iomux節(jié)點(diǎn)下面添加pwm7、pwm8引腳復(fù)用
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已經(jīng)復(fù)用完成

2、實(shí)現(xiàn)獲取光照值的功能

四路光敏傳感器需要四路adc,需要在設(shè)備樹中進(jìn)行adc1、adc2、adc3、adc4的復(fù)用
(1)修改設(shè)備樹文件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節(jié)點(diǎn)下面添加adc1、adc2、adc3、adc4引腳復(fù)用
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已經(jīng)復(fù)用完成

?

3、編譯并替換設(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è)備樹

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盤拷貝到開發(fā)板
root@ELF1:~# cp /run/media/sda1/imx6ull-elf1-emmc.dtb /run/media/mmcblk1p1/

(4)保存并重啟開發(fā)板

root@ELF1:~# sync                                            
root@ELF1:~# reboot
三、數(shù)據(jù)采集和設(shè)備控制

1、程序設(shè)計(jì)

主函數(shù)的實(shí)現(xiàn)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: %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到開發(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
(3)編譯
elf@ubuntu:~/work$ cd sun/
elf@ubuntu:~/work/sun$ make

?

?

(4)拷貝sanapp到開發(fā)板/home/root路徑下

root@ELF1:~# cp /run/media/sda1/sunapp ./
root@ELF1:~# sync

四、項(xiàng)目測試

1、確保開發(fā)板已正確連接四路光敏傳感器和舵機(jī)

2、執(zhí)行應(yīng)用

root@ELF1:~# ./sunapp

此時(shí)可以打開手電筒模擬太陽光,調(diào)整太陽能板的角度

對于初涉嵌入式開發(fā)領(lǐng)域的小伙伴來說,“智慧光伏”無疑是一個(gè)兼具趣味與實(shí)踐的開源項(xiàng)目。通過親身參與這一開源項(xiàng)目的組裝與調(diào)試過程,可以直接接觸到真實(shí)的開發(fā)環(huán)境、工具鏈和代碼庫,從而解決實(shí)際問題,幫助初學(xué)者更快地成長為合格的嵌入式開發(fā)工程師。

相關(guān)推薦

電子產(chǎn)業(yè)圖譜