會(huì)C/C++就可以開發(fā)Linux/Android應(yīng)用程序?替代傳統(tǒng)串口屏的Yoxios了解一下!
1、UI軟件邏輯開發(fā)痛點(diǎn)
串口屏相信各位開發(fā)者都不陌生了,它解決了大多數(shù)開發(fā)者在嵌入式UI應(yīng)用方向的痛點(diǎn),常見的痛點(diǎn)主要有以下幾個(gè)方面:
1、市面上的UI框架層出不窮,不知道如何選擇,常見的有UCGUI,EMWIN,MINIGUI,AWTK,QT等等。
2、需要花時(shí)間去熟悉一個(gè)成熟的UI框架,并將它集成到自己的程序上去,例如emWin,隨便找一個(gè)這方面的開發(fā)文檔,動(dòng)則上千頁,讓眾多開發(fā)者聞風(fēng)喪膽。
3、不使用GUI框架,大數(shù)組讓你感受一下。
這還只是單色圖,如果是選擇16位真彩色呢?這個(gè)數(shù)組得有多大?不得自己加FLASH進(jìn)行存儲(chǔ)嗎?
近年來,市面上出現(xiàn)了許多優(yōu)秀的串口屏廠家,例如迪文、淘晶馳、大彩、中顯、尚視界等等,串口屏的出現(xiàn)簡直就是眾多開發(fā)者和創(chuàng)業(yè)公司的福音呀!
從曾經(jīng)的項(xiàng)目開發(fā)周期很長,縮短到了一周甚至是一兩天,即可輕松完成項(xiàng)目研發(fā),減少了企業(yè)硬件研發(fā)方面的費(fèi)用支出,提高了軟件開發(fā)效率,同時(shí)產(chǎn)品也能夠快速更新迭代。
2、Yoxios是什么?
接下來介紹一款在我最近入手的全新的類串口屏,它的功能比傳統(tǒng)串口屏要強(qiáng)大得多,為什么說它強(qiáng)大,因?yàn)樗С侄伍_發(fā),隨便一個(gè)模塊,只要板子上有接口,都可以通過Yoxios HMI去操控它。當(dāng)你使用Yoxios的時(shí)候,也順便將Linux應(yīng)用開發(fā)一起學(xué)習(xí)并且掌握了,不得不說這是一個(gè)利器,不單是開發(fā)簡單,也能讓一直從事單片機(jī)開發(fā)的小伙伴們輕輕松松入門Linux應(yīng)用。
話不多說,一分鐘了解一下Yoxios:
Yoxios 提供了可供用戶開發(fā)的硬件和軟件接口,官網(wǎng)上也提供了完善的開發(fā)文檔和不少樣例,如果有興趣可以去了解一下。
3、Yoxios實(shí)戰(zhàn)之Yoxios+ESP8266控制小車
3、Yoxios實(shí)戰(zhàn)之Yoxios+ESP8266控制小車
3.1 硬件配置
3.1 硬件配置
參考:
http://bbs.yoxios.com/forum.php?mod=viewthread&tid=6&extra=page%3D1
ESP8266引腳和接線(官方論壇提供的接口)
X3開發(fā)板 | ESP8266模塊 |
VCC3.3 | VCC |
GND |
GND |
U2TX | RX |
U2RX | TX |
普通IO / 懸空 | RST |
SPICS | CH_PD/EN |
這里我做的唯一和論壇的區(qū)別是在硬件上將WIFI使能管腳(CH_PD/EN)直接接到3.3V,這樣軟件上不需要使能該管腳,上電即使能。
3.2 UI布局
3.2 UI布局
3.3 代碼邏輯
3.3 代碼邏輯
這個(gè)項(xiàng)目的核心代碼主要是在jni/logic/mainlogic.cc這個(gè)文件下編寫,參考官網(wǎng)及論壇demo后修改程序如下:
mainLogic.cc
#include
#include#include "string"
#include "uart/ProtocolSender.h"
#include "uart/UartContext.h"
string sendMsg, showMsg;
bool WifiConnet = false;
struct {
string name;
string password;
string IP;
string port;
} WifiConFig;
/**
* 串口數(shù)據(jù)回調(diào)接口
*/
static void onProtocolDataUpdate(BYTE *key, int readNum) {
// 串口數(shù)據(jù)回調(diào)接口
char* p = new char[readNum];
memcpy(p, key, readNum);
p[readNum] = 0;
if (strstr(p, "ready") != NULL) {
showMsg = "";
mTextView3Ptr->setText(showMsg);
return;
}
showMsg += p;
mTextView3Ptr->setText(showMsg);
}
static void WifiReset() {
string s = "AT+CWMODE=1\r\n";
UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
s = "AT+RST\r\n";
UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
mTextView3Ptr->setText("wifi 初始化");
}
static void WifiConnect() {
WifiConFig.name = "Smart_Car";
WifiConFig.password = "12345678";
string s = "AT+CWJAP=\"" + WifiConFig.name + "\",\"" + WifiConFig.password
+ "\"\r\n";
UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
mTextView3Ptr->setText("wifi 連接");
}
static void WifiTCPConnect() {
string s = "AT+CIPMUX=0\r\n";
UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
usleep(500000);
s = "AT+CIPMODE=1\r\n";
UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
usleep(500000);
//連接服務(wù)器
WifiConFig.IP = "192.168.4.1";
WifiConFig.port = "8080";
s = "AT+CIPSTART=\"TCP\",\"" + WifiConFig.IP + "\"," + WifiConFig.port
+ "\r\n";
UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
usleep(100000);
//進(jìn)入透傳模式
s = "AT+CIPMODE=1\r\n";
UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
usleep(100000);
//開始透傳數(shù)據(jù)
s = "AT+CIPSEND\r\n";
UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
usleep(100000);
mTextView3Ptr->setText("TCP 連接");
mTextView5Ptr->setText("Smart_Car 192.168.4.1 8080");
}
/**
* 定時(shí)器觸發(fā)函數(shù)
* 不建議在此函數(shù)中寫耗時(shí)操作,否則將影響UI刷新
* 參數(shù):id
* 當(dāng)前所觸發(fā)定時(shí)器的id,與注冊時(shí)的id相同
* 返回值: true
* 繼續(xù)運(yùn)行當(dāng)前定時(shí)器
* false
* 停止運(yùn)行當(dāng)前定時(shí)器
*/
static bool onUI_Timer(int id) {
//Tips:添加定時(shí)器響應(yīng)的代碼到這里,但是需要在本文件的 REGISTER_ACTIVITY_TIMER_TAB 數(shù)組中 注冊
//id 是定時(shí)器設(shè)置時(shí)候的標(biāo)簽,這里不要寫耗時(shí)的操作,否則影響UI刷新,ruturn:[true] 繼續(xù)運(yùn)行定時(shí)器;[false] 停止運(yùn)行當(dāng)前定時(shí)器
switch (id) {
case 0:
WifiConnect();
return false;
break;
case 1:
WifiTCPConnect();
return false;
break;
default:
break;
}
return true;
}
/**
* 有新的觸摸事件時(shí)觸發(fā)
* 參數(shù):ev
* 新的觸摸事件
* 返回值:true
* 表示該觸摸事件在此被攔截,系統(tǒng)不再將此觸摸事件傳遞到控件上
* false
* 觸摸事件將繼續(xù)傳遞到控件上
*/
static bool onmainActivityTouchEvent(const MotionEvent &ev) {
switch (ev.mActionStatus) {
case MotionEvent::E_ACTION_DOWN: //觸摸按下
LOGD("時(shí)刻 = %ld 坐標(biāo) x = %d, y = %d", ev.mEventTime, ev.mX, ev.mY);
//前進(jìn)
if (ev.mX > 180 && ev.mX < 290 && ev.mY > 70 && ev.mY < 106) { string s = "GO\r\n"; UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
}
//后退
if(ev.mX > 180 && ev.mX < 290 && ev.mY > 180 && ev.mY < 208) { string s = "BACK\r\n"; UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
}
//左
if(ev.mX > 65 && ev.mX < 131 && ev.mY > 128 && ev.mY < 165) { string s = "LEFT\r\n"; UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
}
//右
if(ev.mX > 298 && ev.mX < 400 && ev.mY > 131 && ev.mY < 166) { string s = "RIGHT\r\n"; UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
}
break;
case MotionEvent::E_ACTION_MOVE: //觸摸滑動(dòng)
break;
case MotionEvent::E_ACTION_UP://觸摸抬起
LOGD("按鍵抬起");
string s = "STOP\r\n";
UARTCONTEXT->send((BYTE *)s.c_str(),s.length());
break;
default:
break;
}
return false;
}
//連接小車
static bool onButtonClick_Button5(ZKButton *pButton) {
LOGD(" ButtonClick Button5 !!!\n");
WifiReset();
mActivityPtr->registerUserTimer(0, 3000);
mActivityPtr->registerUserTimer(1, 8000);
return false;
}
其中小車部分控制邏輯參考:
圓曾經(jīng)的小車夢,造一臺(tái)智能小車(四)之QT上位機(jī)控制小車
圓曾經(jīng)的小車夢,造一臺(tái)智能小車(三)之小車前進(jìn)后退左右轉(zhuǎn)基本框架
3.4運(yùn)行結(jié)果
4、Demo案例下載
公眾號后臺(tái)回復(fù):yoxi 即可獲取所有案例及參考demo的下載鏈接。
往期精彩
【編譯器玄學(xué)研究報(bào)告】第一期——位域和volatile
移植一個(gè)實(shí)時(shí)OS很難?那就手把手教你如何快速移植一個(gè)RT-Thread Nano吧!
覺得本次分享的文章對您有幫助,隨手點(diǎn)[在看]并轉(zhuǎn)發(fā)分享,也是對我的支持。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場,如有問題,請聯(lián)系我們,謝謝!