飞凌嵌入式
直播中

fsdzdzy

10年用户 260经验值
擅长:嵌入式技术 控制/MCU opencv
私信 关注
[技术]

【飞凌RK3568开发板试用体验】20-结项:基于OK3568-C的智慧家居控制器

基于OK3568-C的智慧家居控制器

本篇进行飞凌OK3568-C开发板的结项测评,通过综合前面多篇测评的各个功能,构成一个智慧家居控制器综合项目。

再来回顾一下OK3568-C开发板的功能介绍:

【飞凌RK3568开发板试用体验】1-开箱与基础功能详细测评

以及使用OK3568-C进行应用开发的软件开发环境搭建:

【飞凌RK3568开发板试用体验】2-RK3568源码编译与交叉编译环境搭建

1 智慧家居控制器功能概览

1.1 主界面介绍

先来看下此综合项目的功能概览,主要是将各个功能作为一个独立应用,然后将启动图标排列在桌面上。

智慧家居助手有以下几部分功能:

  • 天气功能
    • 网络天气:可以获取当前地区15天的天气预报信息
    • 室内温湿度:通过wifi连接ESP8266控制的温湿度节点,可以获取家中室内温湿度
  • 智能控制
    • 灯与风扇控制:通过wifi连接ESP8266控制家用电器节点,可以控制家中灯和风扇的开关
    • 氛围灯控制:设计了一个RGB灯调光的界面,后期也可通过wifi连接ESP8266节点,进行RGB灯的无线控制
  • 智能监控
    • 视频监控:目前使用USB摄像头进行视频监控,后期也可考虑使用网络摄像头进行无线视频监控
    • AI物品检测:RK3568具有AI算力,目前代码实现了物品位置检测与物品分类,后期可考虑通过人脸人形检测等,实现对监控中人物的抓拍,另外,还可考虑使用SQLite数据库,录入家人的人脸,实现人脸开门
    • 图片列表功能:目前实现了图片列表的浏览,后期实现了人物抓拍功能后,可以使用图片列表功能查看所有图片
    • 单个图片查看:此功能与图片列表浏览的区别是,可以通过目录选择查看任意目录下的图片
  • 娱乐功能
    • 音乐功能:可以实现本地音乐列表中音乐的播放,后期也可增加网络歌曲的获取与播放,作为家庭娱乐功能
    • 视频播放:可以实现本地视频的播放,后期也可增加网络视频的获取与播放,作为家庭娱乐功能
  • 时间功能
    • 时钟:可以以钟表的形式显示当前的时间
    • 秒表:这个算一个工具,可以进行计时

下面这个是主界面,左右滑动可以切换到其它界面,目前是有2个界面。

这个第2个界面的效果,第2个界面中的功能待开发中。

1.2 主界面代码实现

主界面的代码,通过自定义LauncherWidget类实现图标的布局,图标绘制的主要代码如下:

void LauncherWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
​
    if (m_bZoom)
        painter.scale(m_scaleX, m_scaleY);
    if (!m_pixmapWallpaper.isNull())
    {
        painter.drawPixmap(0, 0, m_pixmapWallpaper);
    }
    else
    {
        painter.setBrush(m_backgroundColor);
        painter.drawRect(this->rect());
    }
​
    // 绘制中心区域
    drawCenter(&painter);
​
    // 绘制底部广告标语
    painter.drawPixmap(m_rectAbout, QPixmap(":/images/mainwindow/statusbar_bg.png"));
}
​
void LauncherWidget::drawCenter(QPainter *painter)
{
    painter->save();
    painter->setClipRect(m_rectPage);
    painter->setPen(Qt::NoPen);
    if (None == m_nDirection)
    {
        drawAppItem(painter, m_nCurrentPage, m_rectPage.left());
    }
    else
    {
        int nXoffset = m_rectPage.left() + m_nStartPos;
        drawAppItem(painter, m_nCurrentPage, nXoffset);
        if (m_nStartPos < 0)
        {
            drawAppItem(painter, m_nCurrentPage + 1, m_rectPage.width() + nXoffset);
        }
        else
        {
            drawAppItem(painter, m_nCurrentPage - 1, -m_rectPage.width() + nXoffset);
        }
    }
    //  绘制底部的点
    drawItemSpot(painter);
    painter->restore();
}
​
// 绘制item
void LauncherWidget::drawAppItem(QPainter *painter, int page, int xOffset)
{
    //printf("===page:%d, xOffset:%d\n", page, xOffset);
    QRect rect;
    int nIndex = 0;
    foreach (LauncherItem *item, m_itemApps)
    {
        item->m_rect = QRect(m_rectPage.left(), m_rectPage.top(), 0, 0);
        //printf("nIndex:%d, l:%d, r:%d, m_nPageIndex:%d\n", nIndex, m_rectPage.left(), m_rectPage.top(), item->m_nPageIndex);
        if (page == item->m_nPageIndex) //是否是当前页面中的图标
        {
            if (0 == (nIndex % m_nLayoutColumns)) //每行的第一个
            {
                rect = QRect(xOffset, (nIndex / m_nLayoutColumns) * (m_nItemHeight + ITEM_SPACE) + ITEM_SPACE, 0, 0);
                //printf("---rect:%d, %d, %d, %d\n", rect.left(), rect.right(), rect.top(), rect.bottom());
            }
​
            rect = QRect(rect.right() + ITEM_SPACE, rect.top(), m_nItemWidth, m_nItemHeight);
            //printf("-----rect:%d, %d, %d, %d\n", rect.left(), rect.right(), rect.top(), rect.bottom());
            item->m_rect = rect;
            nIndex++;
            // 绘制app信息
            drawAppInfo(painter, rect, item);
        }
    }
}
​
// 绘制底部小圆圈
void LauncherWidget::drawItemSpot(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);
    foreach (QRect rect, m_rectPageSpot)
    {
        int nKey = m_rectPageSpot.key(rect);
        painter->setBrush(nKey == m_nCurrentPage ? QColor("#182e3a") : QColor("#ffffff"));
        painter->drawEllipse(rect.left(), rect.top(), SPOT_WIDTH, SPOT_WIDTH);
    }
    painter->restore();
}

在主界面中, 通过在指定位置插入对应图标,以及在对应的索引触发后,启动对应的独立应用即可:

void MainWindow::InitDesktop()
{
    // 第一页
    int nPage = 0;
    m_launchItems.insert(0, new LauncherItem(0, nPage, tr("天气"), QPixmap(":/images/mainwindow/ic_weather.png")));
    m_launchItems.insert(1, new LauncherItem(1, nPage, tr("温湿度"), QPixmap(":/images/mainwindow/ic_dht11.png")));
    m_launchItems.insert(2, new LauncherItem(2, nPage, tr("家电控制"), QPixmap(":/images/mainwindow/ic_ledfan.jpg")));
    m_launchItems.insert(3, new LauncherItem(3, nPage, tr("RGB氛围灯"), QPixmap(":/images/mainwindow/ic_rgb.png")));
​
    m_launchItems.insert(4, new LauncherItem(4, nPage, tr("视频监控"), QPixmap(":/images/mainwindow/ic_camera.png")));
    m_launchItems.insert(5, new LauncherItem(5, nPage, tr("AI物品检测"), QPixmap(":/images/mainwindow/ic_ai.png")));
    m_launchItems.insert(6, new LauncherItem(6, nPage, tr("图库"), QPixmap(":/images/mainwindow/ic_photos.png")));
    m_launchItems.insert(7, new LauncherItem(7, nPage, tr("图片查看"), QPixmap(":/images/mainwindow/ic_picview.png")));
​
    m_launchItems.insert(8, new LauncherItem(8, nPage, tr("音乐"), QPixmap(":/images/mainwindow/ic_music.jpg")));
    m_launchItems.insert(9, new LauncherItem(9, nPage, tr("视频"), QPixmap(":/images/mainwindow/ic_video.png")));
    m_launchItems.insert(10, new LauncherItem(10, nPage, tr("时钟"), QPixmap(":/images/mainwindow/ic_clock.png")));
    m_launchItems.insert(11, new LauncherItem(11, nPage, tr("秒表"), QPixmap(":/images/mainwindow/ic_stopwatch.png")));
​
    // 第二页
    nPage++;
    m_launchItems.insert(15, new LauncherItem(15, nPage, tr("汽车仪表"), QPixmap(":/images/mainwindow/ic_car.png")));
    m_launchItems.insert(16, new LauncherItem(16, nPage, tr("开发中"), QPixmap(":/images/mainwindow/ic_todo.png")));
    m_launchItems.insert(17, new LauncherItem(17, nPage, tr("开发中"), QPixmap(":/images/mainwindow/ic_todo.png")));
    m_launchItems.insert(18, new LauncherItem(18, nPage, tr("开发中"), QPixmap(":/images/mainwindow/ic_todo.png")));
    m_launchItems.insert(16, new LauncherItem(19, nPage, tr("开发中"), QPixmap(":/images/mainwindow/ic_todo.png")));
    m_launchItems.insert(20, new LauncherItem(20, nPage, tr("开发中"), QPixmap(":/images/mainwindow/ic_todo.png")));
​
    m_launcherWidget->SetItems(m_launchItems);
}
​
void MainWindow::SltCurrentAppChanged(int index)
{
    if (m_bStartApp)
        return;
​
    if (!(index >= 0 && index <= 11))
        return;
​
    m_launcherWidget->setEnabled(false);
    m_bStartApp = true;
​
    if (NULL != m_widgetWorkSpace)
    {
        if (m_nCurrentIndex != index)
        {
            disconnect(m_widgetWorkSpace, SIGNAL(signalBackHome()), this, SLOT(SltBackHome()));
            delete m_widgetWorkSpace;
            m_widgetWorkSpace = NULL;
        }
        else
        {
            m_widgetWorkSpace->setVisible(true);
            m_widgetWorkSpace->StartAnimation(QPoint(this->width(), this->height()), QPoint(0, 0), 300, true);
            return;
        }
    }
​
    switch (index)
    {
    case 0:
        m_widgetWorkSpace = new WeatherWidget(this);
        break;
    case 1:
        m_widgetWorkSpace = new DhtCollection(this);
        break;
    case 2:
        m_widgetWorkSpace = new LEDFanWidget(this);
        break;
    case 3:
        m_widgetWorkSpace = new LedWidget(this);
        break;
​
    case 4:
        m_widgetWorkSpace = new USBCameraWidget(this);
        break;
    case 5:
        m_widgetWorkSpace = new qtCameraSSD(this);
        break;
    case 6:
        m_widgetWorkSpace = new PhotosView(this);
        break;
    case 7:
        m_widgetWorkSpace = new PicViewWidget(this);
        break;
​
    case 8:
        m_widgetWorkSpace = new MusicPlayer(this);
        break;
    case 9:
        m_widgetWorkSpace = new VideoPlayer(this);
        break;
    case 10:
        m_widgetWorkSpace = new ClockWidget(this);
        break;
    case 11:
        m_widgetWorkSpace = new StopWatchWidget(this);
        break;
​
    default:
        m_nCurrentIndex = -1;
        break;
    }
​
    if (NULL != m_widgetWorkSpace)
    {
        m_widgetWorkSpace->resize(this->size());
        connect(m_widgetWorkSpace, SIGNAL(signalBackHome()), this, SLOT(SltBackHome()));
        connect(m_widgetWorkSpace, SIGNAL(signalAnimationFinished()), this, SLOT(SltAppStartOk()));
​
        m_nCurrentIndex = index;
        m_widgetWorkSpace->setVisible(true);
        m_widgetWorkSpace->StartAnimation(QPoint(this->width(), this->height()), QPoint(0, 0), 300, true);
    }
}

下面再来介绍具体的各个功能。

2 天气功能

2.1 网络天气

通过连网,使用一个免费的API接口,进行网络天气的获取,可以得到最近15天的天气信息,信息的格式是josn形式的,需要使用cJson进行数据解析,然后将天气数据显示在设计的Qt界面上:

网络天气的具体实现,可看这篇测评报告:【飞凌RK3568开发板试用体验】19-网络天气信息

2.2 室内温湿度

温湿度传感器采用DHT11数字温湿度传感器,通过单总线与ESP8266控制器相连。ESP8266采集到温湿度数据后,通过WIFI传送给OK3568开发板,然后在设计的Qt界面上显示温湿度。

OK3568与ESP8266直接采用TCP连接,OK3568作为TCP服务端,ESP8266作为客户端。

温湿度功能的具体实现,可看两篇这篇测评报告:

【飞凌RK3568开发板试用体验】13-与ESP8266进行TCP通信测试

【飞凌RK3568开发板试用体验】15-家中温湿度监测

3 智能控制

3.1 灯与风扇控制

仍然是利用TCP无线通信,实现家中电器的控制,家中的电器开关通过与ESP8266相连,作为一个无线节点,接受OK3568-C板子的控制。

家电控制的具体实现,可看这篇测评报告:【飞凌RK3568开发板试用体验】14-WIFI控制家用电器

3.2 氛围灯控制

利用Qt设计一个RGB氛围灯的调光控制界面,目前只设计了界面,未控制实际的灯,后期可考虑也通过TCP无线连接来控制RGB氛围灯。

氛围灯的具体实现,可看这篇测评报告:【飞凌RK3568开发板试用体验】18-RGB氛围灯

4 智能监控

4.1 视频监控

视频监控功能,也是智能家居中重要的一部分,这里使用USB摄像头组为视频监控的来源,后期可考虑使用网络摄像头作为视频监控。

视频监控(USB摄像头的使用)的具体实现,可看这篇测评报告:【飞凌RK3568开发板试用体验】7-Qt摄像头程序精简与分析

4.2 AI物品检测

在实时视频监控中,可加入AI检测功能,实现物品的识别,目前使用的是SSD模型来识别物品,后期可考虑使用人脸识别和人形识别,来识别人物,以及人物的抓拍。

AI物品检测的具体实现,可看这些测评报告:

【飞凌RK3568开发板试用体验】8-USB摄像头实时AI物品识别初体验

【飞凌RK3568开发板试用体验】9-USB摄像头实时AI物品识别代码实现

另外,除了对物品位置进行检测,还可以对物品种类进行识别分类:

【飞凌RK3568开发板试用体验】11-USB摄像头AI物品识别分类测试

【飞凌RK3568开发板试用体验】12-USB摄像头AI物品识别分类代码实现

4.3 图片列表浏览

目前可以实现图片列表的浏览,后期实现了人物抓拍功能后,可以使用图片列表功能查看所有图片

图片浏览器的具体实现,可看这篇测评报告:【飞凌RK3568开发板试用体验】5-Qt开发一个相册浏览器

4.4 单个图片查看

此功能与图片列表浏览的区别是,可以通过目录选择查看任意目录下的图片

图片查看器的具体实现,可看这篇测评报告:【飞凌RK3568开发板试用体验】6-Qt图片查看器

5 娱乐功能

5.1 音乐播放

可以实现本地音乐列表中音乐的播放,可以暂停继续,切换歌曲,显示歌词瞪。

后期也可增加网络歌曲的获取与播放,作为家庭娱乐功能

音乐播放器的具体实现,可看这篇测评报告:【飞凌RK3568开发板试用体验】3-Qt开发一个音乐播放器

5.2 视频播放

目前可以实现本地视频的播放,可以暂停继续,切换视频,后期也可增加网络视频的获取与播放,作为家庭娱乐功能

视频播放器的具体实现,可看这篇测评报告:【飞凌RK3568开发板试用体验】4-Qt开发一个视频播放器

6 时间功能

6.1 时钟

可以以钟表的形式显示当前的时间

时钟的具体实现,可看这篇测评报告:【飞凌RK3568开发板试用体验】16-Qt时钟测试

6.2 秒表

这个算一个工具,可以进行计时

秒表的具体实现,可看这篇测评报告:【飞凌RK3568开发板试用体验】17-Qt秒表测试

7 总结

本篇进行了OK3568-C开发板的结项测评,通过综合之前实现的各部分功能,实现了一个智慧家居控制器。

附:测评汇总

【飞凌RK3568开发板试用体验】1-开箱与基础功能详细测评

【飞凌RK3568开发板试用体验】2-RK3568源码编译与交叉编译环境搭建

【飞凌RK3568开发板试用体验】3-Qt开发一个音乐播放器

【飞凌RK3568开发板试用体验】4-Qt开发一个视频播放器

【飞凌RK3568开发板试用体验】5-Qt开发一个相册浏览器

【飞凌RK3568开发板试用体验】6-Qt图片查看器

【飞凌RK3568开发板试用体验】7-Qt摄像头程序精简与分析

【飞凌RK3568开发板试用体验】8-USB摄像头实时AI物品识别初体验

【飞凌RK3568开发板试用体验】9-USB摄像头实时AI物品识别代码实现

【飞凌RK3568开发板试用体验】10-蓝牙收发文件测试

【飞凌RK3568开发板试用体验】11-USB摄像头AI物品识别分类测试

【飞凌RK3568开发板试用体验】12-USB摄像头AI物品识别分类代码实现

【飞凌RK3568开发板试用体验】13-与ESP8266进行TCP通信测试

【飞凌RK3568开发板试用体验】14-WIFI控制家用电器

【飞凌RK3568开发板试用体验】15-家中温湿度监测

【飞凌RK3568开发板试用体验】16-Qt时钟测试

【飞凌RK3568开发板试用体验】17-Qt秒表测试

【飞凌RK3568开发板试用体验】18-RGB氛围灯

【飞凌RK3568开发板试用体验】19-网络天气信息

更多回帖

发帖
×
20
完善资料,
赚取积分