0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

ElfBoard开源项目|“智慧教室”开源项目技术文档

ElfBoard 2024-09-11 10:51 次阅读

“智慧教室”项目的目标是实现实时采集环境中的温度、湿度及光照信息,并将这些数据可视化地呈现在Qt图形界面上。用户既可以选择手动控制风扇与窗帘的开关,也可以设置系统根据所采集的环境参数自动调节,以达到舒适的室内环境。接下来,将和各位小伙伴深入探讨这一项目的具体实现方式。

一、 功能特性

1、数据监测与显示:实时监测室内温度、湿度和光照强度,并直观地显示在Qt界面上。

2、手动/感应控制:用户可以通过切换界面按钮选择手动控制风扇和窗帘的状态,或者根据实时监测到的环境数据,自动的调节风扇和窗帘的状态,以提供最佳的舒适度和能源利用效率。

3、节能优化:自动调节功能可实时调整设备状态,以减少能源消耗并提高设备寿命。

二、 环境说明

1、开发环境操作系统:Ubuntu18.04 64位版

2、交叉编译工具链:arm-poky-linux-gnueabi-gcc 5.3.0

3、开发板使用Bootloader版本:u-boot-2016.03

4、开发板内核版本:linux-4.1.15

5、开发板移植QT版本:qt5.6.2

三、 硬件连接

1、风扇与板卡的连接

wKgaombg_OCACyXdAAJECmwSncQ098.png

2、步进电机与板卡的连接

wKgZombg_MqAMZdKAANO_8WH06Y162.png

四、 内核适配

ELF 1开发板已集成温湿度传感器与光线传感器,实现环境温度、湿度和光照强度的采集。为支持智慧教室系统的其它功能,需要对内核源码进行以下适配步骤。

1、实现风扇转动的功能

风扇采用pwm的方式来控制,需要在设备树中进行pwm7的复用。

(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

wKgZombg_S2AQLlfAAXVGkRy0_s628.png

(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设备节点

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

wKgZombg_WWAPSD4AAN9HPriB70074.png

在iomux节点下面添加pwm7引脚复用

pinctrl_pwm7: pwm7grp { fsl,pins = < MX6UL_PAD_CSI_VSYNC__PWM7_OUT 0x110b0 >; };

wKgaombg_h2AMQC5AASICkuEBUU451.png

取消其它用到csi功能的地方

wKgZombg_kSAFRXUAAOZ4JatwUs726.pngwKgaombg_lqAewehAAQSkZ0lfVo466.png

至此pwm7已经复用完成。

2、实现控制窗帘开合的功能

该项目选用28BYJ-48步进电机实现窗帘的开合操作,28BYJ-48电机需要4个GPIO来控制,需要在设备树中进行GPIO的复用并在内核中添加电机驱动。(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

添加设备节点

mymotor { compatible = "motor"; pinctrl-names = "default"; pinctrl-0 = <&mymotor>; status = "okay"; motorA-gpios = <&gpio4 21 GPIO_ACTIVE_HIGH>; motorB-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>; motorC-gpios = <&gpio4 23 GPIO_ACTIVE_HIGH>; motorD-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>; };

wKgaombg_qOAZJOaAATRxK0wbnY310.png

在iomux节点下面添加引脚复用

mymotor: mymotorgrp { fsl,pins = < MX6UL_PAD_CSI_DATA00__GPIO4_IO21 0x10b0 MX6UL_PAD_CSI_DATA01__GPIO4_IO22 0x10b0 MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x10b0 MX6UL_PAD_CSI_DATA03__GPIO4_IO24 0x10b0 >; };

wKgaombg_saAUrGWAATV-6ALB6k044.png

(2)添加电机驱动

拷贝motor.c到内核源码的drivers/gpio目录下,修改drivers/gpio目录下的Makefile文件,添加如下内容:

obj-y += motor.o

wKgZombg_veAfTYvAAmxUaLDuDg818.png

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 elf@ubuntu:~/work/linux-4.1.15-elf1$ make zImage

(3)将arch/arm/boot/路径下的zImage和arch/arm/boot/dts/路径下的imx6ull-elf1-emmc.dtb放到U盘,通过U盘拷贝到开发板。

root@ELF1:~# cp /run/media/sda1/imx6ull-elf1-emmc.dtb /run/media/mmcblk1p1/ root@ELF1:~# cp /run/media/sda1/zImage /run/media/mmcblk1p1/

(4)保存并重启开发板

root@ELF1:~# sync root@ELF1:~# reboot

五、基于Qt界面的数据采集和控制

1、程序设计

wKgZombhAlaAMEpfAAKabUVYMOU641.png

主函数的实现main.cpp

int main(int argc, char* argv[]) { QApplication a(argc, argv); if(!ControllerHandler::instance()->startController()) { return 0; } a.setStyle("Fusion"); QFont f = a.font(); f.setPointSize(20); f.setPixelSize(16); a.setFont(f); MWainWindow w; w.setWindowFlags(Qt::FramelessWindowHint); if(a.primaryScreen()) { w.resize(a.primaryScreen()->size()); } w.show(); int ret = a.exec(); return ret; }

设置显示的时间的样式和位置

void MWainWindow::showtime() { /* 实例化与设置显示的位置大小*/ lcdNumber = new QLCDNumber(this); QScreen *screen = QGuiApplication::primaryScreen(); // 获取屏幕分辨率的大小 QSize screenSize = screen->size(); int screenWidth = screenSize.width(); int screenHeight = screenSize.height(); // 根据屏幕分辨率的大小执行不同的操作 if (screenWidth == 1024 && screenHeight == 600) { lcdNumber->setGeometry( 850, 9, 100, 40); } else if (screenWidth == 800 && screenHeight == 480) { lcdNumber->setGeometry( 650, 9, 100, 40); } else { qDebug() << "Performing other operation";} /* 设置显示的位数 8 位 */ lcdNumber->setDigitCount(8); /* 设置样式 */ lcdNumber->setFrameStyle(QFrame::NoFrame); /* 设置 lcd 显示为当前系统时间 */ QTime time = QTime::currentTime(); /* 设置显示的样式 */ lcdNumber->display(time.toString("hh:mm:ss")); lcdNumber->setStyleSheet("color: black"); }

设置显示的图片的大小和位置

void MWainWindow::showphoto() { /* 设置大小与位置 */ this->setGeometry(0, 0, 1024, 600); /* 使用资源里的文件时格式是 :+前缀+文件路径 */ QPixmap pixmap(":images/res.png"); labelImage = new QLabel(this); QScreen *screen = QGuiApplication::primaryScreen(); // 获取屏幕分辨率的大小 QSize screenSize = screen->size(); int screenWidth = screenSize.width(); int screenHeight = screenSize.height(); // 根据屏幕分辨率的大小执行不同的操作 if (screenWidth == 1024 && screenHeight == 600) { labelImage->setGeometry(14, 61, 343, 524); } else if (screenWidth == 800 && screenHeight == 480) { labelImage->setGeometry(14, 61, 343, 403); } else { qDebug() << "Performing other operation"; } /* 设置图像 */ labelImage->setPixmap(pixmap); /* 开启允许缩放填充 */ labelImage->setScaledContents(true); }

获取设备的状态

void MWainWindow::readData() { /* 当定时器计时 1000 毫秒后,刷新 lcd 显示当前系统时间 */ QTime time = QTime::currentTime(); /* 设置显示的样式 */ lcdNumber->display(time.toString("hh:mm:ss")); ControllerHandler* pInstance =ControllerHandler::instance(); float value=-100; int curtainstate = targetCurtainState; pInstance->getValue(TEMPERATURE_SENSOR,value); ui->widget_temp->setData("温度", QString::number(value) +"°"); if(bOpen==1) { if(value > 31) { ControllerHandler::instance()->setValue(FAN, 10, ' ', ' '); } else { ControllerHandler::instance()->setValue(FAN, 0, ' ', ' '); } } pInstance->getValue(HUMIDITY_SENSOR,value); ui->widget_hum->setData("湿度", QString::number(value) +"%"); pInstance->getValue(LIGHT_SENSOR,value); ui->widget_light->setData("亮度", QString::number(value) +" lt"); if(bOpen==1) { if (value >= 0 && value < 100) { if (curtainstate == 0) { printf("Automatic curtain opening!!!\n"); //ControllerHandler::instance()->setValue(MYMOTOR, ' ', 'R', 2048); targetCurtainState = 1; } } else if (value >= 100 && value < 500) { if (curtainstate == 1) { printf("Automatic curtain closing!!!\n"); //ControllerHandler::instance()->setValue(MYMOTOR, ' ', 'L', 2048); targetCurtainState = 0; } } } if(bOpen==0) { if(bOpen2==1) { //printf("Fan open!!!\n"); ControllerHandler::instance()->setValue(FAN, 10, ' ', ' '); } if(bOpen2==0) { //printf("Fan close!!!\n"); ControllerHandler::instance()->setValue(FAN, 0, ' ', ' '); } } if(bOpen == 0){ if (isFirstCheck) { lastbOpen3 = bOpen3; isFirstCheck = false; } else if (bOpen3 != lastbOpen3) { if(bOpen3 == 1){ printf("Curtain open!!!\n"); //ControllerHandler::instance()->setValue(MYMOTOR, ' ', 'R', 2048); } else { printf("Curtain close!!!\n"); //ControllerHandler::instance()->setValue(MYMOTOR, ' ', 'L', 2048); } lastbOpen3 = bOpen3; } } }

设置界面样式

void MWainWindow::Style() { QString qssFileName; qssFileName = ":/green.qss"; QFile file(qssFileName); if(file.open(QFile::ReadOnly| QFile::Text)){ QString qss =file.readAll(); QApplication *app = dynamic_cast(qApp); if(!qss.isEmpty()){ app->setStyleSheet(qss); } file.close(); } }

2、应用编译

(1)拷贝smartclassroom.tar.bz2到开发环境/home/elf/work目录下解压

elf@ubuntu:~/work$ tar xvf smartclassroom.tar.bz2

(2)执行环境变量

elf@ubuntu:~/work/adc$ . /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi

(3)编译

elf@ubuntu:~/work$ cd smartclassroom/ elf@ubuntu:~/work/smartclassroom$ qmake elf@ubuntu:~/work/smartclassroom$ make

(4)压缩

elf@ubuntu:~/work/smartclassroom$ cd ../smartclassroom_output/release/ elf@ubuntu:~/work/smartclassroom_output/release$ tar -cjvf smartclassroom.tar.bz2 *

(5)拷贝smartclassroom.tar.bz2压缩包到开发板/home/root路径下解压

root@ELF1:~# cp /run/media/sda1/smartclassroom.tar.bz2 ./ root@ELF1:~# tar xvf smartclassroom.tar.bz2 root@ELF1:~# chmod 777 * root@ELF1:~# cp lib* /usr/lib root@ELF1:~# sync

六、项目测试

1、确保开发板已正确连接风扇、步进电机和屏幕

2、执行应用

root@ELF1:~# export DISPLAY=:0.0 root@ELF1:~# ./app

应用执行成功后,Qt界面显示如下,此时可以通过切换按钮选择手动控制或者感应控制风扇开关以及窗帘开合。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6020

    文章

    44351

    浏览量

    628192
  • 嵌入式
    +关注

    关注

    5043

    文章

    18801

    浏览量

    298361
  • 开源代码
    +关注

    关注

    0

    文章

    30

    浏览量

    2891
  • 学习开发板
    +关注

    关注

    0

    文章

    10

    浏览量

    182
收藏 人收藏

    评论

    相关推荐

    Matepad pro12.2 已上市半个月,但是还没有在开源网站看到该项目开源信息,违背开源精神

    Matepad pro12.2 已上市半个月,本人自己也购买了同款12+256的pad,想要同步学习下这款pad的一些体验还不错的功能点,但是目前为止还没有在开源网站看到该项目开源信息,也查询不到
    发表于 08-27 17:25

    嵌入式学习-飞凌嵌入式ElfBoard-项目分享|基于ELF 1S开发板完成的物联网开源项目

    工程师借助ELF 1S开发板完成的嵌入式物联网项目,见证智慧技术的火花。 关于这个项目的思维导图,如下图所示: 接下来,将会从云-网-边-端的物联网体系架构出发,描述整个
    发表于 05-16 09:19

    飞凌嵌入式-ElfBoard-项目分享|基于ELF 1S开发板完成的物联网开源项目

    工程师借助ELF 1S开发板完成的嵌入式物联网项目,见证智慧技术的火花。 关于这个项目的思维导图,如下图所示: 接下来,将会从云-网-边-端的物联网体系架构出发,描述整个
    发表于 05-16 09:12

    项目分享|基于ELF 1S开发板完成的物联网开源项目

    ElfBoard作为飞凌嵌入式旗下教育品牌,自成立以来,持续吸引着各界的瞩目,其中也赢得了一些工程师的青睐。今天,就和各位小伙伴分享一位杰出工程师借助ELF1S开发板完成的嵌入式物联网项目,见证智慧
    的头像 发表于 05-14 09:03 1220次阅读
    <b class='flag-5'>项目</b>分享|基于ELF 1S开发板完成的物联网<b class='flag-5'>开源</b><b class='flag-5'>项目</b>

    项目分享|基于ElfBoard的远程监测系统

    技术领域的专业素养。值得一提的是,社群内部已经涌现出许多富有创意的产品设计理念与技术解决方案,今天就跟大家分享一名共创官完成的项目报告“基于ElfBoard的远程监测系
    的头像 发表于 01-17 11:14 406次阅读
    <b class='flag-5'>项目</b>分享|基于<b class='flag-5'>ElfBoard</b>的远程监测系统

    关于FPGA的开源项目介绍

    Hello,大家好,之前给大家分享了大约一百多个关于FPGA的开源项目,涉及PCIe、网络、RISC-V、视频编码等等,这次给大家带来的是不枯燥的娱乐项目,主要偏向老的游戏内核使用FPGA进行硬解,涉及的内核数不胜数,主要目标是
    的头像 发表于 01-10 10:54 1179次阅读
    关于FPGA的<b class='flag-5'>开源</b><b class='flag-5'>项目</b>介绍

    开源FPGA项目有哪些

    请问开源FPGA项目有哪些?
    发表于 12-26 12:09

    开源项目维护者分论坛圆满举办

    开源维护者——一个被严重误解的群体,在一个开源项目中,开源维护者 往往拥有很高的权限,比如合并其他人的代码,又或者是无须经过他人review就可以提交,当这些人的心态炸裂,就会发生诸如
    的头像 发表于 12-22 18:20 450次阅读
    <b class='flag-5'>开源</b><b class='flag-5'>项目</b>维护者分论坛圆满举办

    书写开源之魂|2023 年活力开源贡献者、开源项目揭晓

    开源事业的蓬勃发展,离不开持之以恒的开源贡献者。他们用一行行代码孕育出无数独具特色的产品,凝聚成了源远流长、代代相传的开源精神。集众智、采众长,他们以坚定的信念和满腔的热情传播开源文化
    的头像 发表于 12-22 09:26 510次阅读
    书写<b class='flag-5'>开源</b>之魂|2023 年活力<b class='flag-5'>开源</b>贡献者、<b class='flag-5'>开源</b><b class='flag-5'>项目</b>揭晓

    开放原子开源基金会与 9 个开源项目举行捐赠签约仪式

    软件、OpenTenBase、MetaToC、crowdos、NXROS、Dorothy SSR、onps 开源网络协议共 9 个开源项目捐赠方代表共同签约。 开源
    的头像 发表于 12-21 17:30 699次阅读
    开放原子<b class='flag-5'>开源</b>基金会与 9 个<b class='flag-5'>开源</b><b class='flag-5'>项目</b>举行捐赠签约仪式

    书写开源之魂|2023年活力开源贡献者、开源项目揭晓

    开源事业的蓬勃发展,离不开持之以恒的开源贡献者。他们用一行行代码孕育出无数独具特色的产品,凝聚成了源远流长、代代相传的开源精神。集众智、采众长,他们以坚定的信念和满腔的热情传播开源文化
    的头像 发表于 12-18 15:55 381次阅读

    开放原子开源基金会与9个开源项目举行捐赠签约仪式

    软件、OpenTenBase、MetaToC、crowdos、NXROS、Dorothy SSR、onps开源网络协议共9个开源项目捐赠方代表共同签约。 开源
    的头像 发表于 12-17 15:55 652次阅读

    2023贡献者、开源项目评选正式启动!

    开源倡导开放、平等、协作、共享理念,是推动技术创新的重要手段,也是促进全球协同发展的源动力。为了进一步汇聚开发者力量、繁荣开源生态,开放原子开源基金会特发起 2023贡献者、
    的头像 发表于 11-09 21:40 536次阅读
    2023贡献者、<b class='flag-5'>开源</b><b class='flag-5'>项目</b>评选正式启动!

    开源项目专访 | XuperCore——让信任的链接更加便捷

    开源基金会,通过基金会快速推动开源项目的健康成熟发展。 在数字经济蓬勃发展、数据成为重要生产要素的时代,区块链已经不仅仅是一项技术、一种工具,更是一种思维方式和一类商业模式。区块链作
    的头像 发表于 09-25 14:48 389次阅读
    <b class='flag-5'>开源</b><b class='flag-5'>项目</b>专访 | XuperCore——让信任的链接更加便捷

    开源项目专访 | XuperCore——让信任的链接更加便捷

    开源基金会,通过基金会快速推动开源项目的健康成熟发展。 在数字经济蓬勃发展、数据成为重要生产要素的时代,区块链已经不仅仅是一项技术、一种工具,更是一种思维方式和一类商业模式。区块链作
    的头像 发表于 09-20 18:40 474次阅读