[创新制造展示] 【21ic第二届设计大赛】+ 互联网信息展示器之二姨家热门贴

[复制链接]
 楼主| link8001 发表于 2018-8-4 15:37 | 显示全部楼层 |阅读模式
本帖最后由 link8001 于 2018-8-18 14:01 编辑

  韶华易逝,光阴苒冉。曲指一算,与二姨家相识已有十年。
  十年之间,由青涩小伙到步入中年,由满脸稚气到略显沧桑,时间总能在脸上留下自己的印章
  十年之间,由四处漂泊到定居一处,由心浮气噪到略显稳当,心灵总要经过岁月的洗礼才能成长
  十年之间,由孑然一身到儿女双全,由辟重就轻到敢做敢当,当了父亲才明白自已的责任与担当
  十年之前,我是二姨家的常客,每天必做的事是从论坛寻找自己喜欢的书下载,跟随T叔的脚步,我也渐渐有了自己的大书包,虽然当时真正能读懂的不多,但把硬盘里塞满电子图书总能让人乐此不疲。而我也由此步入了电子的大门。
  八年之前,初入社会的我心比天高,总以为自己能凭一已之力走上人生的巅峰,但现实与梦想的巨大落差轻易就能撕碎一颗不怎么坚强的心,唯有电子游戏能让人短暂沉迷。
  六年之前,如梦初醒,重新注册了二姨家帐号,一切重新开始。跟老欧学单片机,跟春阳学电源,成长路上当然也少不了T叔的大书包支持,发表论文,拿专利,只要能沉下心来,短短的时间就能造就一个勉强过得去的攻城狮。
  三年之前,勉强过得去的攻城狮依旧勉强过得去,微薄的收入也依旧微薄,于是攻城狮变程序猿,与二姨家也短暂离别。
  三年之间,由亲戚口中的在电子厂上班,变成了修电脑的,面子总算长了点
  三年之间,由从不加班到加班到天明,孩子奶粉钱总算有了着落
  三年之间,不常登录,甚是想念!
偶然看到【21ic第二届设计大赛】的消息,仅以此文此物,纪念与二姨家的这十年

一 项目方案的构想和实施计划
  近期在做嵌入式linux方面的工作,使用Qt开发相关嵌入式软件;便简单写了个程序,实现天气实时显示,二姨家十大热门贴实时显示

二 硬件设计过程分享
  手头有10.4寸触摸屏,LVDS接口;EM3352开发板,板载linux系统;RT3070无线wifi模块,USB接口;RGB转LVDS模块;5V升12V背光模块;几个模块组合,硬件平台基本不费力气
三 搭建平台
  需要编译嵌入式linux版Qt4.8和RT3070模块驱动,网上教程大把,不细述;

四  程序设计
    使用了Qt的network模块,包括QNetworkReply QNetworkRequest QNetworkAccessManager三个类来访问二姨家取回数据;
    Qt4.8没有json类,移植了QJson模块来解析天气信息
    代码共享在github;https://github.com/bloglink/app-ictest
五 调试过程
01 调试wifi由于没有USB转接头,用杜邦线直接焊在了背板上

  初次登录需要使用串口(此处貌似有加分),linux下的串口工具为minicom,开一个终端,使用如下命令打开minicom
  1. sudo minicom -w -c on
打开电源,一堆开机信息闪过后如下

输入下面的命令加载rt3070的驱动
  1. insmod /lib/modules/rt3070sta.ko
成功后输入
  1. ifconfig ra0 up
此时输入ifconfig会发现网口设备中多了一个名为ra0的网卡;
输入
  1. iwlist ra0 scanning
周围所有的wifi信号都会显示出来

为了便于使用,我们使用wpa工具和启动脚本来配置wifi,wpa的配置文件名为wpa_supplicant.conf,用vi命令打开,里面可以配置wifi名称和密码

配置完成后我们写一个启动脚本来实现开机自动连接wifi,脚本如下:

重启系统,加载脚本,wifi连接成功后,我们输入ifconfig查看wifi连接

至此wifi模块调试成功

注:若没有串口,也可使用telnet远程登录,登录命令为
  1. telnet 192.168.xxx.xxx
输入帐号密码后即可操作,操作方法与串口操作一致

02 调试天气
使用Qt的network模块获取本地天气信息非常简单,获取只需3行代码
  1. wether = new QNetworkAccessManager(this);
  2. connect(wether,SIGNAL(finished(QNetworkReply*)),this,SLOT(replayWether(QNetworkReply*)));
  3. wether->get(QNetworkRequest(QUrl("http://wthrcdn.etouch.cn/weather_mini?citykey=101120201")));
从中国天气网获取天气数据,青岛的代码为101120201
然后在replayWether函数中解析返回的天气数据,天气数据为json类型,我们已提前移植了QJson模块,将返回值导入QJson类即可解析
  1. void AppWindow::replayWether(QNetworkReply *reply)
  2. {
  3.     if(reply->error() == QNetworkReply::NoError)
  4.     {
  5.         QByteArray bytes = reply->readAll();

  6.         QString result = QString::fromLocal8Bit(bytes);

  7.         QJsonObject info = QJsonDocument::fromJson(result.toUtf8()).object();

  8.         QJsonObject data = info.take("data").toObject();
  9.         QJsonValue forecast1 = data.take("forecast");
  10.         QJsonArray forecast2 = forecast1.toArray();
  11.         QJsonObject today = forecast2.at(0).toObject();
  12.         wethershow.at(3)->setText(today.value("fengli").toString().mid(9, 4));
  13.         wethershow.at(5)->setText(today.value("fengxiang").toString());
  14.         wethershow.at(7)->setText(data.value("wendu").toString());
  15.         wethershow.at(9)->setText(today.value("type").toString());
  16.     }
  17. }
03 调试热门贴二姨家热门贴的获取方式与获取天气相同
  1. icblog = new QNetworkAccessManager(this);
  2. connect(icblog,SIGNAL(finished(QNetworkReply*)),this,SLOT(replayIcblog(QNetworkReply*)));
  3. icblog->get(QNetworkRequest(QUrl("https://bbs.21ic.com")));
然后在replayIcblog函数中解析返回的帖子数据,返回的数据为xml类型,直接使用Qt的xml模块解析总是出错,估计是Qt4.8版本过低,没办法,直接字符串解析提取数据
  1. void AppWindow::replayIcblog(QNetworkReply *reply)
  2. {
  3.     if(reply->error() == QNetworkReply::NoError)
  4.     {
  5.         techo->clear();
  6.         QByteArray bytes = reply->readAll();
  7.         QString result = QString::fromLocal8Bit(bytes);
  8.         qDebug() << result;
  9.         QStringList tmp = result.split("\n");
  10.         int k = 0;
  11.         int g = 0;
  12.         for (int i=0; i < tmp.size(); i++) {

  13.             if (tmp.at(i).contains(tr("十大热门-技术贴"))) {
  14.                 techo->insertHtml(tr("十大热门-技术贴") + "<br><br/>");
  15.                 for (int t=0; t < 50; t++) {
  16.                     if (QString(tmp.at(i+t)).contains("<a href=")) {
  17.                         QString str = tmp.at(i+t);

  18.                         QStringList tt = str.split(""");
  19.                         int x = tt.indexOf(" title=");
  20.                         QString dat = "<a style='font-size:19px;color:cyan;' href="0">";
  21.                         dat += tr("%1  ").arg(k, 2, 10, QChar('0'));
  22.                         dat += tt.at(x+1);
  23.                         techo->insertHtml(dat + "<br><br/>");
  24.                         k++;
  25.                         if (k >= 10) {
  26.                             techo->insertHtml("<br><br/>");
  27.                             break;
  28.                         }
  29.                     }
  30.                 }
  31.             }
  32.             if (tmp.at(i).contains(tr("十大热门-生活贴"))) {
  33.                 techo->insertHtml(tr("十大热门-生活贴") + "<br><br/>");
  34.                 for (int t=0; t < 50; t++) {
  35.                     if (QString(tmp.at(i+t)).contains("<a href=")) {
  36.                         QString str = tmp.at(i+t);
  37.                         QStringList tt = str.split(""");
  38.                         int x = tt.indexOf(" title=");
  39.                         QString dat = "<a style='font-size:19px;color:cyan;' href="0">";
  40.                         dat += tr("%1  ").arg(g, 2, 10, QChar('0'));
  41.                         dat += tt.at(x+1);
  42.                         techo->insertHtml(dat + "<br><br/>");
  43.                         g++;
  44.                         if (g>= 10)
  45.                             break;
  46.                     }
  47.                 }
  48.             }
  49.         }
  50.     }
  51. }

六 作品展示


总结:基本都是学嵌入式必会的知识点,没什么核心技术,当作练手还是极好的.
后续升级方案:
1 理论上可实现触摸屏查看和输入wifi连接信息,类似手机或笔记本的wifi连接方式,功能开发中
2 电池供电和低功耗模式,板块本身使用5V电源,一个充电宝即可搞定电池供电,低功耗可通过PWM控制屏幕亮度来实现
3 显示内容可配置,参数配置Qt有QSetting模块,很容易实现
4 语音播报,只有一个蜂鸣器,估计只能播放音乐,音频不熟,时间太紧,有时间就加上,没时间就算了






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评论

牛逼了  发表于 2018-8-15 19:20
这个厉害了  发表于 2018-8-6 20:09
 楼主| link8001 发表于 2018-8-4 15:38 | 显示全部楼层
本帖最后由 link8001 于 2018-8-18 13:21 编辑

低功耗:
使用板载PWM功能实现背光控制和低功耗板上载有四路PWM输出端口

我们选取PWM1作为背光控制口
控制代码如下
  1. void AppScreen::openfd()
  2. {
  3.     fd = open("/dev/em335x_pwm1", O_RDWR);  // 打开蜂鸣器
  4.     if (fd < 0) {
  5.         qWarning() << "pwm show:" << "open fail";
  6.     }
  7. }

  8. void AppScreen::setDuty(int duty)
  9. {
  10.     QList<int> rates;
  11.     rates << 0 << 1 << 2 << 3 << 5 << 8 << 12 << 17 << 23 << 30 << 100;
  12.     duty = qMin(rates.size()-1, duty);

  13.     struct pwm_config_info conf;

  14.     conf.freq = 20000;
  15.     conf.duty = rates.at(duty);
  16.     conf.polarity = 0;
  17.     conf.count = 0;

  18.     if (duty == 0)
  19.         memset(&conf, 0, sizeof(struct pwm_config_info));

  20.     int ret = write(fd, &conf, sizeof(struct pwm_config_info));
  21.     if (ret < 0) {
  22.         qWarning() << "pwm show:" << "send fail";
  23.     }
  24. }
设置占空比为0可以关闭背光,根据屏幕亮度设置了10级背光,小占空比时屏幕亮度变化时显,超过30%基本无变化
在主类中添加如下代码实现早8点亮屏,晚8点关屏
  1. void AppWindow::updateWether()
  2. {
  3.     QTime from(8, 0, 0);
  4.     QTime stop(20, 0, 0);
  5.     if (QTime::currentTime() > stop || QTime::currentTime() < from)
  6.         pwm.setDuty(0);
  7.     else
  8.         pwm.setDuty(9);
  9.     wether->get(QNetworkRequest(QUrl("http://wthrcdn.etouch.cn/weather_mini?citykey=101120201")));
  10.     icblog->get(QNetworkRequest(QUrl("https://bbs.21ic.com")));
  11.     newmsg->get(QNetworkRequest(QUrl("http://news.baidu.com")));
  12. }

电池供电:
掏出多年前的充电宝,5000mAh,加一根USB线实现电池供电,效果如下

屏幕不是很亮,果然1.5A的输出还是有点不够,查下手册

主板耗电300~450mA,屏幕大体记得是1000mA,充电宝容量已不足,估记正常开启3小时内电池耗光,晚上屏幕关闭,待机电流300mA,可以**到第二天上班

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| link8001 发表于 2018-8-4 15:38 | 显示全部楼层
本帖最后由 link8001 于 2018-8-18 14:05 编辑

配置WIFI:为实现wifi可配置,增加了一个网络配置界面,效果如下


界面代码在github,不再贴出,wifi的查询使用iwlist来实现,关键代码如下
  1.     QProcess w;
  2.     w.start("iwlist ra0 scanning");
  3.     w.waitForFinished();
  4.     QByteArray msg = w.readAll();
  5.     QStringList wires = QString(msg).split("Cell");
  6.     wires.removeFirst();
  7.     wifis.clear();
  8.     for (int i=0; i < qMin(MAXNET, wires.size()); i++) {
  9.         QStringList less = wires.at(i).split("\n");
  10.         for (int t=0; t < less.size(); t++) {
  11.             QString text = less.at(t);
  12.             text = text.remove("\t");
  13.             if (text.contains("ESSID:")) {
  14.                 names.at(i)->setText(titleOK.arg(text));
  15.                 int t = text.indexOf(":");
  16.                 QString str = text.mid(t+1, 200);
  17.                 str.remove(""");
  18.                 wifis.insert(QString::number(i), str);
  19.             }
  20.             if (text.contains("Mode:")) {
  21.                 texts.at(i)->setText(strWifi.arg(i).arg(text.remove(" ")));
  22.             }
  23.             if (text.contains("Quality=")) {
  24.                 int index = text.indexOf("/");
  25.                 int p = (text.mid(0, index)).remove("Quality=").toInt();
  26.                 if (p / 20 == 0)
  27.                     icons.at(i)->setPixmap(QPixmap(":/wifi1.png"));
  28.                 if (p / 20 == 1)
  29.                     icons.at(i)->setPixmap(QPixmap(":/wifi2.png"));
  30.                 if (p / 20 == 2)
  31.                     icons.at(i)->setPixmap(QPixmap(":/wifi3.png"));
  32.                 if (p / 20 >= 3)
  33.                     icons.at(i)->setPixmap(QPixmap(":/wifi4.png"));
  34.             }
  35.         }
  36.     }
使用iwlist ra0 scanning命令后读取命令返回值,将wifi名称和强度显示在界面上
wifi的连接如下
首先保存wifi名称和密码到wpa_supplicant.conf
  1.     QFile file(path);
  2.     file.open(QFile::ReadWrite);
  3.     file.write("# WPA-PSK/TKIP\n\n");
  4.     file.write("ctrl_interface=/var/run/wpa_supplicant\n\n");
  5.     file.write("network={\n");
  6.     file.write(tr("\tssid="%1"\n").arg(ssid->text()).toUtf8());
  7.     file.write("\tscan_ssid=1\n");
  8.     file.write("\tkey_mgmt=WPA-EAP WPA-PSK IEEE8021X NONE\n");
  9.     file.write("\tpairwise=TKIP CCMP\n");
  10.     file.write("\tgroup=CCMP TKIP WEP104 WEP40\n");
  11.     file.write(tr("\tpsk="%1"\n").arg(pswd->text()).toUtf8());
  12.     file.write("}\n");
  13.     file.close();
然后使用wpa_supplicant命令连接wifi
  1.     QProcess w;
  2.     w.start("ifconfig ra0 down");
  3.     w.waitForFinished();
  4.     w.start("ifconfig ra0 up");
  5.     w.waitForFinished();
  6.     w.start("wpa_supplicant -B -D wext -i ra0 -c /etc/wpa_supplicant.conf");
  7.     w.waitForFinished();
  8.     w.start("udhcpc -i ra0");
  9.     w.waitForFinished();
顺便做了wifi名称,密码,和刷新频率的自动保存,以及输入字母和数字使用的虚拟键盘
操作视频见下楼

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| link8001 发表于 2018-8-4 15:39 | 显示全部楼层
本帖最后由 link8001 于 2018-8-18 15:06 编辑





蜂鸣器提示就不做了,加了只兔斯基当更新提示

caijie001 发表于 2018-8-5 00:29 | 显示全部楼层
mark,等着更新完@ 我啊
 楼主| link8001 发表于 2018-8-6 18:43 | 显示全部楼层
caijie001 发表于 2018-8-5 00:29
mark,等着更新完@ 我啊

一楼已更新,欢迎点评指正
Andrew55 发表于 2018-8-13 08:22 | 显示全部楼层
大佬啊。
小小电子爱好者 发表于 2018-8-13 13:05 | 显示全部楼层
都姓高   支持支持!!!
 楼主| link8001 发表于 2018-8-15 16:18 | 显示全部楼层

刚入门,共同进步
慕鱼 发表于 2018-8-15 19:19 | 显示全部楼层
奋斗小范 发表于 2018-8-15 19:26 | 显示全部楼层
厉害厉害
21ic小喇叭 发表于 2018-8-17 15:44 | 显示全部楼层
比赛还有三天就结束啦,还请及时更新哦,这样才不会影响到时候的评委打分~
 楼主| link8001 发表于 2018-8-17 16:57 | 显示全部楼层
21ic小喇叭 发表于 2018-8-17 15:44
比赛还有三天就结束啦,还请及时更新哦,这样才不会影响到时候的评委打分~ ...

嗯嗯,最后一个周末了,拼了
 楼主| link8001 发表于 2018-8-18 15:07 | 显示全部楼层
caijie001 发表于 2018-8-5 00:29
mark,等着更新完@ 我啊

全部更新完成
 楼主| link8001 发表于 2018-8-18 15:08 | 显示全部楼层
小小电子爱好者 发表于 2018-8-13 13:05
都姓高   支持支持!!!

请高手多多支持
 楼主| link8001 发表于 2018-8-18 15:09 | 显示全部楼层
21ic小喇叭 发表于 2018-8-17 15:44
比赛还有三天就结束啦,还请及时更新哦,这样才不会影响到时候的评委打分~ ...

已全部完成,请检阅
慕鱼 发表于 2018-8-18 16:12 | 显示全部楼层
支持
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

434

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部