单片机/MCU论坛
直播中

阿飞

11年用户 124经验值
擅长:控制/MCU RF/无线
私信 关注
[文章]

【钛极小龟试用体验】钛极小龟阿里云物联网云端通讯及Android APP控制

``-----------------------------防吞分隔线-----------------------------
拿到钛极小龟开发板将近三周,陆陆续续做了一些实验,现在对这块板子了解的也比较全面了,在此非常感谢电子发烧友网提供的试用机会。
今天做一下结项实验,总结展示这段时间的学习成果。
实验名称:钛极小龟阿里云物联网云端通讯及Android APP控制
实验目的:使用Android App,通过阿里云物联网,实现与钛极小龟开发板的云端通讯及控制。
实验效果:Android App实时显示开发板环境参数, 且可点击按钮远程通过继电器控制外设台灯的亮灭. 效果演示如下(不太清晰,可看文末视频):

1.jpg
1. 实验概述
1.1 数据传输
以阿里云端做为数据中转,通过规则引擎转发, 实现控制端(安卓APP)与开发板的数据交互。数据传输流程如图:
2.png
1.2 云端设置
因上一篇贴子已有对阿里云端设置进行详细说明,此处仅作简要介绍。
1.2.1 创建产品及设备
在阿里云控制台物联网模块下创建一个产品,并在此产品下创建两个设备tikit-demo(开发板)和controller(安卓控制端), 同时记录相关参数(ProductKey,DeviceName,DeviceSecret)
3.jpg
1.2.2 创建转发规则
阿里物联网限制同一台设备同时只可存在一个连接, 因此APP控制端与开发板端无法使用同一个MQQT账号. 为实现开发板与安卓APP数据交互的目的,需要在规则引擎创建两条转发规则,分别是数据从开发板转发至APP及指令从APP转发至开发板。
4.png
1.3 数据格式
数据与指令因转发需要,采用Json格式。Json结构参数说明如下:
5.png
2. 实验材料
本次实验用到的工具材料有:钛极小龟开发板,安卓手机,USB充电头,USB小台灯(也可换为其他外设如小风扇),遥控器,USB线及杜邦线。如下图(洞洞板是为了方便与开发板继电器连接而焊接的引脚,仅用于连接中转,上面的两个模块请无视):
6.jpg
3. 实验步骤
3.1 模块连接
开发板继电器一端连接电源端,一端连接USB小台灯,以便于进行控制。连接方式如图:
6.5.jpg
3.2 APP连接
打开APP,输入controller设备的参数(ProductKey,DeviceName,DeviceSecret),并点击连接按钮。APP内部会根据相应算法,计算出MQQT用户名与密码, 网络正常的话会连接阿里云服务端并跳转至主界面,此时因开发板离线,故参数均为空。
7.jpg
3.3 开发板通讯
开发板上电,LED闪烁表示正在连接WiFi,连接成功后LED长亮,并将相关参数显示在LED并通过网络上传至云端。APP实时获取参数并显示,如图:
9.jpg
3.4 数据传输
用手掌遮盖开发板,传感器接收到的光照大大减少,APP端显示当前亮度为4流明。
10.jpg
手指按在开发板触摸按钮上,APP实时显示触摸状态为“有”,手指移开后状态消失。
11.jpg
按下开发板Key/F键,APP显示按钮为“有”,弹起后状态消失
12.jpg
用红外遥控器对准开发板按下按钮,APP实时显示遥控器所按下的键码。
13.jpg
3.5 云端远程控制
点击APP端按钮,按钮状态变更为“已开启”,此时开发板继电器发出咔嗒声吸合,USB小台灯通电开启,APP端显示的亮度增加至177流明。
14.jpg
再次点击APP控制按钮,状态变更为“已关闭”,此时继电器发出咔嗒声断开,台灯断电关闭,APP端显示的亮度恢复之前的45流明。
注意事项:
1.继电器应连接NO(常开)与GND
2.开发板多线程受性能影响,有时不那么准确,可能会出现红外接收线程抢占主线程情况,导致结果不准确
3.开发板本身有一定发热,导致DHT11测量到的温度不是准确室温
实验完毕,本次实验实现了通过云端将开发板检测到的环境参数显示在手机APP中,同时可用手机APP控制开发板连接的外部设备。达到实验目的。
实验过程视频:
[media]http://v.youku.com/v_show/id_XMzkzNjc4MDYzNg==.html?spm=a2h3j.8428770.3416059.1[/media]
关键代码(Android):
  1. public class MainActivity extends Activity implements MonitorService.ChangedListener {

  2.     public MonitorService monitorService;

  3.     private ToggleButton toggleSwitch;

  4.     private TextView txtViewLumen = null, txtParaTemp, txtParaHumi, txtParaVice, txtParaTouch, txtParaKey, txtParaRed;

  5.     @Override
  6.     protected void onCreate(Bundle savedInstanceState) {
  7.         super.onCreate(savedInstanceState);
  8.         setContentView(R.layout.activity_main);

  9.         System.err.println("onCreate");

  10.         toggleSwitch = (ToggleButton) findViewById(R.id.toggleButtonLED);
  11.         txtViewLumen = (TextView)findViewById(R.id.lighting);
  12.         txtParaTemp = (TextView)findViewById(R.id.txtParaTemp);
  13.         txtParaHumi = (TextView)findViewById(R.id.txtParaHumi);
  14.         txtParaVice = (TextView)findViewById(R.id.txtParaVice);
  15.         txtParaTouch = (TextView)findViewById(R.id.txtParaTouch);
  16.         txtParaKey = (TextView)findViewById(R.id.txtParaKey);
  17.         txtParaRed = (TextView)findViewById(R.id.txtParaRed);

  18.         MyApplication app = (MyApplication) getApplication();
  19.         monitorService = app.getMonitorService();
  20.         monitorService.registerChangedListener(this);

  21.         /**
  22.         * 开关控制事件
  23.         */
  24.         toggleSwitch.setOnClickListener(new View.OnClickListener() {
  25.             @Override
  26.             public void onClick(View view) {
  27.                 try {
  28.                     monitorService.switchControl();
  29.                 }
  30.                 catch (Exception ex){
  31.                     ex.printStackTrace();
  32.                 }
  33.             }
  34.         });

  35.     }

  36.     /**
  37.     *  退出时断开连接
  38.     */
  39.     @Override
  40.     protected void onDestroy() {
  41.         System.err.println("onDestroy");

  42.         monitorService.unregisterChangedListener(this);

  43.         monitorService.disconnect();

  44.         super.onDestroy();
  45.     }

  46.     /**
  47.     * 收到数据消息
  48.     * 更新界面
  49.     */
  50.     @Override
  51.     public void onDataChange(final int state, final int lumen, final String other) {
  52.         runOnUiThread(new Runnable() {
  53.             @Override
  54.             public void run() {
  55.                 if(state == 0)
  56.                     toggleSwitch.setChecked(false);
  57.                 else
  58.                     toggleSwitch.setChecked(true);
  59.                 //Log.d("Tipos", "State: " + state);

  60.                 txtViewLumen.setText(Integer.toString(lumen) + " 流明");

  61.                 if(other.length() > 10) {
  62.                     String[] arys = other.split(";");
  63.                     if(arys.length >= 6) {
  64.                         txtParaTemp.setText(arys[0] + "  ℃");
  65.                         txtParaHumi.setText(arys[1] + "  %");
  66.                         txtParaVice.setText(arys[2]);
  67.                         txtParaTouch.setText("0".equals(arys[3]) ? "-" : "有");
  68.                         txtParaKey.setText("0".equals(arys[4]) ? "-" : "有");
  69.                         txtParaRed.setText("N".equals(arys[5]) ? "-" : arys[5]);
  70.                     }
  71.                 }
  72.             }
  73.         });
  74.     }
  75. }

关键代码(开发板):
  1. public static void main(String[] args) {
  2.                 try {
  3.                         TiWiFi obj = TiWiFi.getInstance();
  4.                         obj.startup(30);
  5.                         TiDNS.getInstance().startup();
  6.                         System.out.println("Wi-Fi Connect. IP: " + obj.getAddress());
  7.                 } catch (IOException ex) {
  8.                         System.out.println("Wi-Fi Connect Failed.");
  9.                         ex.printStackTrace();
  10.                         return;
  11.                 }
  12.                 try {
  13.                         // GPIO资源分配,GPIO0的PIN2/3/4/5脚
  14.                         TiGPIO gpio0 = TiGPIO.open(0, 2, 3, 4, 5);
  15.                         // I2C主机总线资源分配,I2CM0
  16.                         TiI2CMaster i2cm0 = TiI2CMaster.open(0);
  17.                         // ADC资源分配,ADC0的CH0通道
  18.                         TiADC adc0 = TiADC.open(0, 0);
  19.                         /* ---资源绑定--- */
  20.                         // I2C主机总线资源PORT0与屏幕对象绑定,屏幕地址:0x3C
  21.                         TiOLED_UG2864 oled = new TiOLED_UG2864(i2cm0, 0x3c);
  22.                         // I2C主机总线资源PORT0与照度计BH1750对象绑定,默认地址:0x23
  23.                         TiBH1750 bh1750 = new TiBH1750(i2cm0);
  24.                         // GPIO总线资源PIN2与继电器对象绑定
  25.                         TiRelay1CH relay = new TiRelay1CH(gpio0, 2);
  26.                         // GPIO总线资源PIN3与温湿度传感器DHT11绑定
  27.                         TiDHT dht11 = new TiDHT(gpio0, 3);
  28.                         // GPIO总线资源PIN4与触摸按钮对象绑定,触发电平:高电平
  29.                         TiButton touch = new TiButton(gpio0, 4, true);
  30.                         // GPIO总线资源PIN5与红外解码对象绑定
  31.                         TiVS1838BNEC vs1838b = new TiVS1838BNEC(gpio0, 5);
  32.                         // 获取键盘实例并设置键盘事件监听对象
  33.                         TiKeyboard keyboard = TiKeyboard.getInstance();
  34.                         keyboard.setEventListener(new KeyboardListener());
  35.                         // 设置ADC参考电压及分压倍数
  36.                         adc0.setRefVoltageValue(1.0, 2);
  37.         
  38.                         /* ---资源使用--- */
  39.                         // 屏幕开启并清屏
  40.                         oled.turnOn();
  41.                         oled.clear();
  42.                         oled.print(0, 0, "AliYun&Android APP!");
  43.                         touch.setEventListener(new TouchListener(relay));
  44.                         vs1838b.setEventListener(new IRDecodeListener());
  45.                         Thread.sleep(2000);
  46.                         
  47.                         MqttConnectOptions connOpts = new MqttConnectOptions();
  48.                         connOpts.setCleanSession(true);
  49.                         connOpts.setKeepAliveInterval(80);
  50.                 connOpts.setUserName(USER_NAME);
  51.                 connOpts.setPassword(USER_PASS);               
  52.                 connOpts.setAutomaticReconnect(true);
  53.                
  54.                 MqttClient mqttClient = new MqttClient(BROKER, CLIENT_ID);
  55.                         mqttClient.SetMqttClientListener(new MqttClientListener() {
  56.                                 
  57.                                 @Override
  58.                                 public void unsubscribeCompleted(Object arg0, int arg1, String arg2, int arg3) {
  59.                                         //System.err.println("unsubscribeCompleted");
  60.                                 }
  61.                                 
  62.                                 @Override
  63.                                 public void subscribeCompleted(Object arg0, int arg1, String arg2, int arg3) {
  64.                                         //System.err.println("subscribeCompleted: " + arg2);
  65.                                 }
  66.                                 
  67.                                 @Override
  68.                                 public void publishCompleted(Object arg0, int arg1, String arg2, int arg3) {
  69.                                         //System.err.println("publishCompleted: " + arg2);
  70.                                 }
  71.                                 
  72.                                 @Override
  73.                                 public void onMqttConnectSuccess(Object arg0) {
  74.                                         //System.err.println("onMqttConnectSuccess");
  75.                                 }
  76.                                 
  77.                                 @Override
  78.                                 public void onMqttConnectFailure(Object arg0, int arg1) {
  79.                                         //System.err.println("onMqttConnectFailure");
  80.                                 }
  81.                                 
  82.                                 @Override
  83.                                 public void messageArrived(Object arg0, String arg1, byte[] payload) {
  84.                                         if("cmd".equals(arg1.substring(arg1.length() - 3))) {
  85.                                                 String cmd = new String(payload);
  86.                                                 cmd = cmd.substring(11, cmd.length() - 2);
  87.                                                 //System.err.println("Received Cmd: " + cmd);
  88.                                                 try {
  89.                                                         if("OPEN".equals(cmd)) {
  90.                                                                 relay.turnOn();
  91.                                                                 System.err.println("Relay Turn On.");
  92.                                                         } else if("CLOSE".equals(cmd)) {
  93.                                                                 relay.turnOff();
  94.                                                                 System.err.println("Relay Turn Off.");
  95.                                                         }
  96.                                                 }catch(Exception e) {}
  97.                                         }
  98.                                        
  99.                                 }
  100.                                 
  101.                                 @Override
  102.                                 public void connectionLost(Object arg0) {
  103.                                         //System.err.println("connectionLost");
  104.                                 }
  105.                                 
  106.                                 @Override
  107.                                 public void connectComplete(Object arg0, boolean arg1) {
  108.                                         //System.err.println("connectComplete");
  109.                                        
  110.                                 }
  111.                         });

  112.                         try {
  113.                                 mqttClient.connect(connOpts, mqttClient);
  114.                         } catch (Exception e) {
  115.                                 e.printStackTrace();
  116.                                 System.err.println("Connect failed.");
  117.                         }
  118.                         
  119.                 mqttClient.subscribe(TOPIC_CMD, 1);
  120.                         
  121.                 while(true) {
  122.                                 // 启动温湿度测量
  123.                                 dht11.measure();
  124.                                 // 获取温湿度值
  125.                                 double temp = dht11.getTemperature();
  126.                                 double humi = dht11.getHumidity();
  127.                                 int lux = bh1750.readLightLevel();
  128.                                 int val = adc0.getRawValue(0);
  129.                                 String sensorState = "{ switch: " + (relay.isTurnedOn() ? "1" : "0") + ",lumen: " + lux + ",other: '" + temp + ";" + humi + ";" + val + ";" + touchState + ";" + keyState + ";" + vs1838State + "' }";
  130.                                 
  131.                                 oled.print(1, 0, "Temp:" + temp + " C    ");
  132.                                 oled.print(2, 0, "Humi:" + humi + " %    ");
  133.                                 oled.print(3, 0, "Light:" + lux + "    ");
  134.                                 vs1838State = "N";
  135.                                 try {
  136.                                         System.out.println("Send to Cloud: " + sensorState);
  137.                                         mqttClient.publish(Main.TOPIC_DATA, sensorState.getBytes(), 0, false);
  138.                                         Thread.sleep(1200);
  139.                                 } catch (Exception e) {}
  140.                         }
  141.                         
  142.                 } catch (Exception ex) {
  143.                         ex.printStackTrace();
  144.                 } finally {
  145.                         try {
  146.                                 
  147.                         } catch (Exception e) {
  148.                                 e.printStackTrace();
  149.                         }
  150.                 }
  151.         }


`` 8.jpg a.gif

更多回帖

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