刚刚放假,老爸就给了我一个任务,让我写个简易的app,用手机红外遥控他公司要用的单片机。之前在JetsonTx2小车的项目里有用过蓝牙和socket通信,还没尝试过红外,研究了一下,发现并不难。整个app两个小时就写好了,当然也没做什么界面的美化,主要还是把精力放在功能的实现上。
Android有现成的红外类ConsumerIrManager
可以用,代码都很简单,关键在于红外码的解读。
红外的编码格式一般为:引导码+用户编码低8位+用户编码高8位+数据码(8位)+数据码的反码(8位,校验用)
以我老爸的单片机为例:
9ms
的高电平+4.5ms
的低电平00000000 ffffffff
16
为例,就是0001 0110
,前4位表示1
,后4位表示6
16
为例,就是1110 1001
38KHz
最后要把1
和0
用高低电平表示,在我老爸的单片机上,560ms
的高电平+565ms
的低电平表示0
,560ms
的高电平+1690ms
的低电平表示1
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:stretchColumns="0,1,2">
<TableRow
android:layout_height="0dp"
android:layout_weight="1"
android:layout_margin="10dp">
<Button
android:id="@+id/send_button45"
android:text="总开关"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0000"
android:textColor="#ffffff"
android:textSize="25dp"/>
</TableRow>
<TableRow
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:id="@+id/send_button0d"
android:text="区号"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"/>
<Button
android:id="@+id/send_button47"
android:text="模式"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"/>
<Button
android:id="@+id/send_button44"
android:text="时间"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"/>
</TableRow>
<TableRow
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:id="@+id/send_button0c"
android:text="统一时间"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"/>
<Button
android:id="@+id/send_button18"
android:text="统一模式"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"/>
<Button
android:id="@+id/send_button16"
android:text="分段定时"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"/>
</TableRow>
<TableRow
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:id="@+id/send_button40"
android:text="+"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"/>
<Button
android:id="@+id/send_button19"
android:text="-"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="30dp"/>
<Button
android:id="@+id/send_button15"
android:text="移位"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"/>
</TableRow>
<TableRow
android:layout_height="0dp"
android:layout_weight="1">
<Button
android:id="@+id/send_button09"
android:text="开机"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"
android:background="#0000ff"
android:textColor="#ffffff"/>
<Button
android:id="@+id/send_button07"
android:text="关机"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"
android:background="#bb0000"
android:textColor="#ffffff"/>
<Button
android:id="@+id/send_button43"
android:text="确认"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"
android:background="#00aa00"
android:textColor="#ffffff"/>
</TableRow>
</TableLayout>
加上这两句:
<!-- 红外遥控 -->
<uses-permission android:name="android.permission.TRANSMIT_IR" />
<!-- 仅在支持红外的设备上运行 -->
<uses-feature android:name="android.hardware.ConsumerIrManager" android:required="true" />
package com.example.hongwai;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.hardware.ConsumerIrManager;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "ConsumerIrTest";
private ConsumerIrManager mCIR;
@SuppressLint("InlinedApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取系统的红外遥控服务
mCIR = (ConsumerIrManager) getSystemService(Context.CONSUMER_IR_SERVICE);
initViewsAndEvents();
}
private void initViewsAndEvents() {
findViewById(R.id.send_button45).setOnClickListener(mSendClickListener45);
//其余类似
}
private static int startH = 9000;
private static int startL = 4500;
private static int high8 = 560;
//0:1125
private static int low0 = 565;
//1:2250
private static int low1 = 1690;
//用户编码高八位
private static String userH = "00000000";
//用户编码低八位
private static String userL = "11111111";
//38kHz
private static int carrierFrequency = 38000;
private static int[] pattern;
private static List<Integer> list = new ArrayList<>();
public static void change(String code) {
int len = code.length();
String part;
for (int i = 0; i < len; i++) {
list.add(high8);
part = code.substring(i, i + 1);
if (part.equals("0"))
list.add(low0);
else
list.add(low1);
}
}
View.OnClickListener mSendClickListener45 = new View.OnClickListener() {
@TargetApi(Build.VERSION_CODES.KITKAT)
public void onClick(View v) {
if (!mCIR.hasIrEmitter()) {
Log.e(TAG, "未找到红外发身器!");
return;
}
list.clear();
//引导码
list.add(startH);
list.add(startL);
//用户编码
change(userH);
change(userL);
//键数据码
change("10100010");
//键数据反码
change("01011101");
//发射时数据少一位
change("1");
int size = list.size();
pattern = new int[size];
for (int i = 0; i < size; i++) {
pattern[i] = list.get(i);
}
mCIR.transmit(carrierFrequency, pattern);
}
};
//其余类似
}
代码写的不好,不同的数据我就硬编码了,没动脑子。。。这里就不全贴出来,用”其余类似“表示了
实际操作中,数据码的传送要左右颠倒,比如16
的数据码是00010110
,那你就得写成01101000
。我不知道为什么要这样,可能是我老爸的单片机接受数据的方式就是这样,开始一直不对,我也是试了几次才发现了这个规律。
还有个坑是发射时数据会少一位,所以我补了一位,这个问题也是仁者见仁,你可能压根遇不到这个问题。
这个咱也不知道是咋写的,咱也不敢问。反正老爸都写好了,用C语言写了一千多行,咱也不想看。