由聲網 Agora 舉辦的首屆AI in RTC 大賽,已在10 月 24 日圓滿落幕。其中,參與創意編程賽道的 100 多支參賽隊伍在 3 個多月裏揮灑創意與熱情,帶來了許多用心的項目。咱們邀請了獲獎的參賽隊伍們,逐一分享了他們的開發實踐。html
buggy 團隊基於 Android 手機、開發板、傳感組件等,開發了一個可經過手機遠程控制,支持視頻的小車。android
如下內容由 buggy 團隊撰寫:編程
在消費電子設備的迅猛發展趨勢下,智能手機的價格變低、配置卻變高,愈來愈多的人選擇更換配置更高的智能手機。舊手機若是沒有被回收利用,其中的重金屬和塑料將會對環境形成不可逆轉的嚴重污染,使人可惜的是絕大部分的舊智能手機還能正常使用。目前,對舊手機的主流處理辦法是回收提煉貴金屬,但提煉過程當中仍是會產生有毒有害氣體。數組
智能手機的攝像頭已經知足通常的圖像採集要求。將舊智能手機攝像頭利用起來,開發視頻監控應用,成爲舊手機從新利用的一大趨勢[1],能夠節省大量的視頻採集設備成本,還能減小環境污染和資源浪費。bash
印度Mindhelix初創團隊開發的智能安防產品Rico將舊智能手機利用起來,作出了一種有創意的安防產品。Rico主要由舊智能手機、智能插座,Rico內置的各類環境傳感器及手機應用程序等軟硬件組成。將舊智能手機裝上應用程序,插入Rico中,本來要報廢的智能手機就承擔起視頻攝像、人臉識別、語音控制、麥克風通話、行程提醒和音樂播放等功能。Rico內置的各類環境傳感器能夠監測一氧化碳、煤氣、煙霧濃度、溫度、溼度、燈光強度和運動;智能插座能夠鏈接到家裏的各類家用電器和電燈,控制其開啓和閉合;全部監測到的數據經過API接口上傳至雲端,在手機應用程序上能夠查看家庭環境的各項指標。例如溫度、溼度等。若是出門忘記關燈,能夠經過手機遠程控制電燈關閉[2]。網絡
在北美比較受歡迎的阿福管家(Alfred),是由臺北初創團隊研發的一款把舊手機變爲監控攝影機的APP,提供動態偵測、推播通知、即時錄影、夜視功能。用戶只須要在兩個智能手機上安裝APP,一個設定爲相機端,另外一個爲監控端,兩端登入同一個Google賬號,即可以經過WIFI或3G/4G實現遠程監控[3][4]。併發
當今在安防監控領域,大多數民用監控設備有幾大弊端:app
此設計要求實現一個手機能夠遠程經過WIFI查看小車上的手機攝像頭拍攝的畫面並控制小車移動。利用淘汰的智能手機的攝像頭,實時採集視頻圖像信號並經過無線WIFI網絡將視頻信號實時傳輸到手機端觀看,再經過小車上的手機的紅外遙控功能對小車進行移動方向、速度的控制。使用C語言開發單片機程序,用Java語言開發安卓程序。ide
此小節圍繞安卓端視頻傳輸方案的選擇、單片機的選擇、車身的選擇、馬達驅動的選擇和遙控控制模塊的選擇展開討論。函數
安卓端視頻傳輸方案的選擇
查閱相關文獻和資料後對Android的實時圖像傳輸的圖像數據處理方式進行了彙總,總結出下表中的五套Android實時圖像網絡傳輸方案[5]。
在因特網環境下,方案1不可取。方案2中MediaRecorder有很強的硬件依賴性,所以不一樣的手機表現是不同的,有的手機數據傳輸的時候會出現阻塞現象,實時性就下降了。方案3和方案4實時性低。方案5平均流量消耗高,也不可取。
這裏採用另外一種方案,使用聲網Agora的視頻通話 SDK進行二次開發。既保證了實時性,又下降了開發難度。
單片機的選擇:單片機用於接收紅外信號並控制馬達驅動,根據在網上教程比較多的單片機是STC89CXX系列,STC89C52RC單片機是STC89C52的升級版,不斷髮展的半導體工藝也讓該單片機的功耗不斷下降。不只僅是作到了能耗上的升級,也進一步增強了單片機的處理性能。因此選擇STC89C52RC型號。
車身的選擇:第一種方案,淘寶上購買用於此設計的車身。小車底盤和頂面採用3mm厚亞克力板經激光切割總體成形,並預留了多組安裝孔,擴展能力強。利用小車的圓形底盤特性,在底面左右兩邊直流馬達和橡膠防滑車輪,先後兩個萬向輪起平衡小車做用。直流馬達更是容易控制及調速,並且這種玩具車架通常都價格便宜;第二種方案,本身作一個車身。採用鋁合金板製做,須要切割板鑽孔。此過程很是耗時,應該將時間用在程序開發上。因此採用第一種方案從淘寶上購買車身。
馬達驅動的選擇:方案1,經過繼電器控制馬達的運動狀態。好處是結構簡單,但工做原理爲機械結構,因此壞處是反應慢,並且佔用的空間大;方案2,採用TI公司的馬達專業驅動芯片L293D。電壓最大36V,峯值電流最大1.2A,0.6A連續額定電流。採用TTL電平信號控制。具備兩個使能控制器,可作PWM信號輸入端,用來調整馬達速度[5]。綜上選擇方案2。
遙控控制模塊的選擇:方案1,使用紅外遙控。雖然紅外的遙控的控制距離只有10m左右,沒法繞過障礙物進行遙控。但發射紅外遙控信號的手機就架在小車上,能夠將手機的紅外發射器和紅外接收器放在一塊固定住。雖然並非全部的安卓手機都有紅外發射器,但都有3.5mm的耳機接口,紅外信號的38kHz頻率在音頻範圍內,能夠用耳機接口外接的紅外發光二極管發射紅外遙控信號[6];方案2,能夠用藍牙來完成對小車的控制,小車上須要配備藍牙模塊與手機進行配對通訊。但並非全部的手機都支持藍牙,早期的一些安卓智能手機就不支持藍牙。相比藍牙模塊,紅外模塊成本更低。因此採用方案1。
本設計是以安卓手機爲控制核心,在手機控制端實時查看小車上的手機攝像頭採集到的圖像,併發送控制命令發給小車上的手機,再經過手機被控制端紅外發送動做指令。VS1838B爲紅外接收模塊,接收手機端的紅外遙控信號,再交給STC89C52RC單片機判斷紅外遙控的碼值,對應控制L293D馬達驅動,從而實現小車的先後左右移動。電源採用2節18650鋰電池串聯供電。
3.4系統框圖 本系統的系統框圖如圖所示。
整個小車的硬件設計能夠分爲四個模塊:電源電路、單片機最小系統、馬達驅動模塊、紅外接收模塊。電源電路爲單片機最小系統、紅外接收模塊、馬達驅動和兩個車輪馬達供電。
單片機最小系統
單片機的最小系統就是讓單片機能正常工做併發揮其功能時所必須的組成部分,也可理解爲是用最少的元件組成的單片機能夠工做的系統[7]。單片機最小系統的系統框圖和電路原理圖如圖所示。
STC89C52RC單片機可謂是國產單片機發展歷程上的一塊里程碑,初步作到了國內量產。而52單片機則是51的升級版,不斷髮展的半導體工藝也讓該單片機的功耗不斷下降。不只僅是作到了能耗上的升級,也進一步增強了單片機的處理性能。在保持原有的8位處理器不變的大方針下,採用了CMOS的生產工藝STC89S52RC單片機片內集成512字節RAM、8K字節ROM。在燒寫次數方面達到了1000次左右的優良性能,低功耗模式狀況下時鐘系統雖然會中止工做,可是內部的寄存器仍是可以進行正常的處理。爲了適應不一樣的使用場合,這款單片機提供了多種封裝,本次設計根據最小系統有時須要更換單片機的具體狀況,使用雙列直插DIP-40的封裝,配合縮緊底座。
馬達驅動模塊
L293D是TI公司的產品,比較常見的是16腳PDIP封裝。L293D經過TTL電平信號控制,由OUTPUT1,OUTPUT2和OUTPUT3,OUTPUT4驅動2個馬達。INPUT一、INPUT二、INPUT三、INPUT4腳鏈接STC89C52RC的P0. 0、P0. 一、P0. 二、P0. 3口,控制馬達的運動狀態。ENABLE1,ENABLE2爲控制使能端,對應與單片機的P0. 四、P0. 5口相連,控制馬達的停轉和PWM調速[8]。P0. 四、P0. 5口經過輸出不一樣佔空比的PWM波形來改變馬達的快慢。佔空比是指高電平持續時間在一個週期時間內的百分比。單片機輸出PWM信號可採用軟件延時或定時器兩種方法,在此用的是軟件延時的方法。當高電平延時時間到時,電平取反變成低電平,而後再延時;當低電平延時時間到時,電平取反變高電平,一直這樣反覆就能獲得PWM波形[9]。VSS可接4.5~7V電壓,給芯片的邏輯電路提供電壓。VS電壓範圍爲4.5~36 V,給輸出端提供電壓。L293D的真值邏輯和功能的對應如表4-1所示。 表L293D真值邏輯和功能對應表
紅外遙控模塊
紅外遙控模塊主要由遙控發射器、紅外接收頭、接口電路組成。紅外遙控器用來產生遙控編碼脈衝,驅動紅外發射管輸出紅外遙控信號,這裏使用的使手機自帶的紅外發射功能。遙控接收頭完成對遙控信號的放大、檢波、整形、解調出遙控編碼脈衝,這裏使用一體化紅外接收頭來完成這一系列操做。遙控編碼脈衝是一組串行二進制碼,此串行碼輸入到單片機,由其內部CPU完成對遙控指令解碼,並執行相應的遙控功能[9]。
紅外遙控的實現原理
本次紅外遙控採用的是NEC協議,調製方式爲PPM脈衝位置調製,載波38kHz。位0和位1所不一樣之處就是在高電平脈衝後的低電平脈寬不同,邏輯1爲2.25ms,脈衝時間560us;邏輯0爲1.125ms,脈衝時間560us。其波形如圖所示。
下圖是NEC的協議格式。首先是引導碼,9ms的高電平脈衝和4.5ms的低電平,接下來是8位的地址碼和8位的地址反碼,用於校驗地址碼, 而後是8位的命令碼和8位的命令反碼,用於校驗碼[10]。
紅外接收模塊
本次採用的是VS1838B 一體化紅外接收頭有三個引腳,其外觀和引腳排列如圖4-6所示。OUT端即解調信號的輸出端,鏈接單片機的P3. 2口。
此次設計能夠用C語言編程序,也能夠用匯編語言編程序,如今的單片機內部容量已經比較大了,可使用C語言編寫程序,沒必要使用晦澀難懂的彙編語言[11]。因此本次設計中系統程序用C語言編寫程序,用軟件Keil C51編譯。
主程序設計
在本設計中,單片機主要是在主程序的控制下,定時對紅外一體化接收頭VS1838B接收的紅外信號進行識別分析,讀出的數據若是爲0x十二、0x1八、0x1四、0x16則分別對應控制小車的前進、後退、左轉、右轉。小車硬件系統軟件設計的流程圖如圖4-7所示。
主要代碼以下。
void main(){
IrInit();//初始化
ENA=0;
ENB=0;
T=2048;
speed=400;//數字越大速度越快
ENA=1;
ENB=1;
while(1){
detectorIR();//判斷紅外信號
motorRun();//控制電機狀態
if(speed!=T){
ENA=0;
ENB=0;
delay(T-speed);
ENA=1;
ENB=1;
delay(speed);
}
}
}
複製代碼
紅外遙控接收程序設計
紅外遙控接收程序的重心在於解碼的方式,解碼方法以下:
主要代碼以下。
void ReadIr() interrupt 0
{
u8 j,k;
u16 err;
Time=0;
delay(700); //7ms
if(IRIN==0) //確認是否真的接收到正確的信號
{
err=1000; //1000*10us=10ms,超過說明接收到錯誤的信號
/*當兩個條件都爲真是循環,若是有一個條件爲假的時候跳出循環,省得程序出錯的時
侯,程序死在這裏*/
while((IRIN==0)&&(err>0)) //等待前面9ms的低電平過去
{
delay(1);
err--;
}
if(IRIN==1) //若是正確等到9ms低電平
{
err=500;
while((IRIN==1)&&(err>0)) //等待4.5ms的起始高電平過去
{
delay(1);
err--;
}
for(k=0;k<4;k++) //共有4組數據
{
for(j=0;j<8;j++) //接收一組數據
{
err=60;
while((IRIN==0)&&(err>0))//等待信號前面的560us低電平過去
{
delay(1);
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //計算高電平的時間長度。
{
delay(10); //0.1ms
Time++;
err--;
if(Time>30)
{
return;
}
}
IrValue[k]>>=1; //k表示第幾組數據
if(Time>=8) //若是高電平出現大於565us,那麼是1
{
IrValue[k]|=0x80;
}
Time=0; //用完時間要從新賦值
}
}
}
if(IrValue[2]!=~IrValue[3])
{
return;
}
}
}
複製代碼
本設計的安卓程序可以使用手機攝像頭實時地將手機拍到的圖像傳送到手機端或電腦端,同時接收手機端或電腦端發出的指令。根據指令小車上的手機再發送相應的紅外遙控信號給小車,手機安卓程序是小車端和控制端二合一的,在初始界面進行選擇,主要是實現接收和發送信令、實時音視頻傳輸和紅外信號傳輸等功能。
Android開發包及其工具的安裝和配置 本次開發使用聲網(Agora)的視頻通話和信令的SDK進行二次開發。下面介紹在正式使用 Agora SDK for Android進行通話/直播和信令控制前,須要準備的開發環境,包含前提條件及SDK集成方法等內容[12]。 請確保知足如下開發環境要求:
在編譯和啓動實例程序前,須要首先獲取一個可用的App ID:
集成Agora視頻SDK:
完成以上步驟後,用Android Studio打開該項目,連上設備,就能夠編譯並運行程序了。
手機端程序的設計
由於Android4.4及以上纔有ConsumerIrManager類用來操控紅外設備,因此本程序是基於Android 5.1系統的OPPO A51手機開發和測試的。用Android Studio開發,在此開發環境下完成Android手機終端的相關應用開發很是的方便[13]。 手機控制端實時視頻功能的程序流程圖如圖所示。
具體使用方法見聲網官網文檔中心的參考[12],這裏就不進行詳盡描述了。下面來對主要步驟進行簡單介紹。
(1)初始化
進入頻道以前,調用create建立一個實例。
import io.agora.rtc.Constants;
import io.agora.rtc.IRtcEngineEventHandler;
import io.agora.rtc.RtcEngine;
import io.agora.rtc.video.VideoCanvas;//初始化前先導入這4個包
...
private void initializeAgoraEngine() {
try {
mRtcEngine = RtcEngine.create(getBaseContext(),
getString(R.string.agora_app_id),
mRtcEventHandler);
} catch (Exception e) {
Log.e(LOG_TAG, Log.getStackTraceString(e));
throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
}
}
複製代碼
(2)加入頻道
App在加入頻道前,須要先設置頻道模式,再加入頻道。 建立實例後,調用setChannelProfile方法設置頻道模式。
mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_COMMUNICATION);
複製代碼
以後調用joinChannel方法加入頻道。
private void joinChannel() {
mRtcEngine.joinChannel("token", "demoChannel1", "Extra Optional Data", 0);
}
複製代碼
(3)離開頻道
調用leaveChannel方法離開頻道,結束或退出通話或直播。
private void leaveChannel() {
mRtcEngine.leaveChannel();
}
複製代碼
(4)信令的實現
信令的具體使用方法見聲網官網文檔中心的參考[14],這裏就不進行詳盡描述了。主要使用的函數以下:
// 初始化信令 SDK
m_agoraAPI = AgoraAPIOnlySignal.getInstance(context, appID);
// 登陸 Agora 信令系統
m_agoraAPI.login2(appId, account, token, uid, deviceID, retry_time_in_s, retry_count)
/////////////頻道測試///////////////
// 加入頻道
m_agoraAPI.channelJoin(channelName)
// 發送頻道消息
m_agoraAPI.messageChannelSend(channelName, msg, msgID)
// 設置對端接收到頻道消息回調
m_agoraAPI.onMessageChannelReceive(channelID, account, uid, msg) {
// code there
}
// 退出 Agora 信令系統
m_agoraAPI.logout()
複製代碼
小車上的手機實時視頻功能的程序流程圖如圖所示。
手機端紅外線發射功能的程序流程圖如圖所示。
由於Android4.4及以上纔有ConsumerIrManager類用來操控紅外設備,因此如下程序是基於Android 5.1系統的OPPO A51手機開發和測試的。
首先從系統服務中獲取到ConsumerIrManager服務。
IR=(ConsumerIrManager)getSystemService(CONSUMER_IR_SERVICE);
複製代碼
而後將要發送的紅外碼存入數組中。
//0x73
int[] pattern2 = { 9000, 4500,
560, 560, 560, 560, 560, 560, 560, 560, 560,560, 560, 560, 560, 560, 560, 560,
560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690, 560, 1690,
560, 560, 560, 560, 560, 560, 560, 1690, 560, 1690, 560, 560, 560, 560, 560, 560,
560, 1690, 560, 1690, 560, 1690, 560, 560, 560, 560, 560, 1690, 560, 1690,560, 1690,
560, 42020, 9000, 2250, 560, 98190 };
複製代碼
數組中存放的是數值表明的是一種交替的載波序列模式,經過毫秒測量。這6行數據依次表示引導碼,地址碼,地址碼,數據碼,數據反碼,連續碼,具體原理詳見4.1.3節紅外遙控原理。
第三行數據碼反置,好比0x12=0001 0010反置爲 0100 1000,只有反置了以後才能接收正常。最後經過以下方法最終發送紅外信號。
mCIR.transmit(hz, pattern2);//後退
複製代碼
transmit(int carrierFrequency, int[] pattern) :此方法控制手機產生 carrierFrequency爲頻率的,以pattern爲紅外開關的時間數組,發送紅外信號。(例如:transmit(38000,{100,200,300,400}) 將會產生一個頻率爲38KHz的紅外信號,信號的電平高低爲 100us高電平,200us低電平,300us高電平,400us低電平。注意pattern的數據個數要爲偶數個,否則報錯。)[15]。
你們能夠訪問buggy 團隊的博客,與他們交流。同時,歡迎訪問 RTC 開發者社區。