Android手机控制ZigBee板上LED

来源:互联网 发布:电脑故障排查软件 编辑:程序博客网 时间:2024/05/11 14:59

环境:Windows

编译器:IAREW8051-8.1

硬件:CC2530

协议栈:ZStack-CC2530-2.3.0-1.4.0

手机:Android4.1.2

又重新开始学习ZigBee技术,摸索了一哈通信流程,本例程没有涉及到ZigBee组网,读者可自行扩展。

ZigBee流程如下:从串口接收指令信息,根据指令信息控制相应的LED资源,工作模式为协调器,可用GenericApp工程改编,代码如下

/**************************************************************************************************  Filename:       TESTApp.c  Revised:        $Date: 2009-03-18 15:56:27 -0700 (Wed, 18 Mar 2009) $  Revision:       $Revision: 19453 $  Description:    TEST Application (no Profile).  Copyright 2004-2009 Texas Instruments Incorporated. All rights reserved.  IMPORTANT: Your use of this Software is limited to those specific rights  granted under the terms of a software license agreement between the user  who downloaded the software, his/her employer (which must be your employer)  and Texas Instruments Incorporated (the "License").  You may not use this  Software unless you agree to abide by the terms of the License. The License  limits your use, and you acknowledge, that the Software may not be modified,  copied or distributed unless embedded on a Texas Instruments microcontroller  or used solely and exclusively in conjunction with a Texas Instruments radio  frequency transceiver, which is integrated into your product.  Other than for  the foregoing purpose, you may not use, reproduce, copy, prepare derivative  works of, modify, distribute, perform, display or sell this Software and/or  its documentation for any purpose.  YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE  PROVIDED 揂S IS?WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,   INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,   NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL  TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,  NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER  LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES  INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE  OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT  OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES  (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.  Should you have any questions regarding your right to use this Software,  contact Texas Instruments Incorporated at www.TI.com. **************************************************************************************************//*********************************************************************  This application isn't intended to do anything useful, it is  intended to be a simple example of an application's structure.  This application sends "Hello World" to another "TEST"  application every 15 seconds.  The application will also  receive "Hello World" packets.  The "Hello World" messages are sent/received as MSG type message.  This applications doesn't have a profile, so it handles everything  directly - itself.  Key control:    SW1:    SW2:  initiates end device binding    SW3:    SW4:  initiates a match description request*********************************************************************//********************************************************************* * INCLUDES */#include "OSAL.h"#include "AF.h"#include "ZDApp.h"#include "ZDObject.h"#include "ZDProfile.h"#include "Common.h"#include "DebugTrace.h"#if !defined( WIN32 )  #include "OnBoard.h"#endif/* HAL */#include "hal_lcd.h"#include "hal_led.h"#include "hal_key.h"#include "hal_uart.h"#include "OSAL_Nv.h"/********************************************************************* * MACROS *//********************************************************************* * CONSTANTS *//********************************************************************* * TYPEDEFS *//********************************************************************* * GLOBAL VARIABLES */// This list should be filled with Application specific Cluster IDs.const cId_t TESTApp_ClusterList[TESTAPP_MAX_CLUSTERS] ={  TESTAPP_CLUSTERID};const SimpleDescriptionFormat_t TestApp_SimpleDesc ={  TESTAPP_ENDPOINT,              //  int Endpoint;  TESTAPP_PROFID,                //  uint16 AppProfId[2];  TESTAPP_DEVICEID,              //  uint16 AppDeviceId[2];  TESTAPP_DEVICE_VERSION,        //  int   AppDevVer:4;  TESTAPP_FLAGS,                 //  int   AppFlags:4;  TESTAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;  (cId_t *)TESTApp_ClusterList,  //  byte *pAppInClusterList;  0,          //  byte  AppNumInClusters;  (cId_t *)NULL  //  byte *pAppInClusterList;};//用于描述一个设备节点// This is the Endpoint/Interface description.  It is defined here, but// filled-in in TESTApp_Init().  Another way to go would be to fill// in the structure here and make it a "const" (in code space).  The// way it's defined in this sample app it is define in RAM.endPointDesc_t TestApp_epDesc;//节点描述符/********************************************************************* * EXTERNAL VARIABLES *//********************************************************************* * EXTERNAL FUNCTIONS *//********************************************************************* * LOCAL VARIABLES */byte TestApp_TaskID;   // Task ID for internal task/event processing                          // This variable will be received when                          // TESTApp_Init() is called.devStates_t TestApp_NwkState;byte TestApp_TransID;  // This is the unique message ID (counter)afAddrType_t TestApp_DstAddr;static uint8 SerialApp_TxLen;static void rxCB(uint8 port, uint8 event);/********************************************************************* * LOCAL FUNCTIONS */void TestApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg );void TestApp_HandleKeys( byte shift, byte keys );void TestApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );void TestApp_SendTheMessage( void );/********************************************************************* * NETWORK LAYER CALLBACKS *//********************************************************************* * PUBLIC FUNCTIONS *//********************************************************************* * @fn      TESTApp_Init * * @brief   Initialization function for the TEST App Task. *          This is called during initialization and should contain *          any application specific initialization (ie. hardware *          initialization/setup, table initialization, power up *          notificaiton ... ). * * @param   task_id - the ID assigned by OSAL.  This ID should be *                    used to send messages and set timers. * * @return  none */void TestApp_Init( byte task_id ){  halUARTCfg_t uartConfig;  TestApp_TaskID = task_id;  TestApp_NwkState = DEV_INIT;  TestApp_TransID = 0;  // Device hardware initialization can be added here or in main() (Zmain.c).  // If the hardware is application specific - add it here.  // If the hardware is other parts of the device add it in main().  TestApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;  TestApp_DstAddr.endPoint = TESTAPP_ENDPOINT;  TestApp_DstAddr.addr.shortAddr = 0xFFFF;  // Fill out the endpoint description.  TestApp_epDesc.endPoint = TESTAPP_ENDPOINT;  TestApp_epDesc.task_id = &TestApp_TaskID;  TestApp_epDesc.simpleDesc            = (SimpleDescriptionFormat_t *)&TestApp_SimpleDesc;  TestApp_epDesc.latencyReq = noLatencyReqs;  // Register the endpoint description with the AF  afRegister( &TestApp_epDesc );    uartConfig.configured = TRUE;  uartConfig.baudRate = HAL_UART_BR_115200;  uartConfig.flowControl                    = FALSE;   uartConfig.flowControlThreshold = 64; // 2x30 don't care - see uart driver.   uartConfig.rx.maxBufSize                = 128;    // 2x30 don't care - see uart driver.   uartConfig.tx.maxBufSize                = 128;    // 2x30 don't care - see uart driver.   uartConfig.idleTimeout                    = 6;      // 2x30 don't care - see uart driver.   uartConfig.intEnable                        = TRUE;                            // 2x30 don't care - see uart driver.   uartConfig.callBackFunc                  = rxCB;   HalUARTOpen (0, &uartConfig);   // Register for all key events - This app will handle all key events  //RegisterForKeys( TestApp_TaskID );  // Update the display#if defined ( LCD_SUPPORTED )    HalLcdWriteString( "TestApp", HAL_LCD_LINE_1 );#endif      ZDO_RegisterForZDOMsg( TestApp_TaskID, End_Device_Bind_rsp );  ZDO_RegisterForZDOMsg( TestApp_TaskID, Match_Desc_rsp );}/********************************************************************* * @fn      TESTApp_ProcessEvent * * @brief   TEST Application Task event processor.  This function *          is called to process all events for the task.  Events *          include timers, messages and any other user defined events. * * @param   task_id  - The OSAL assigned task ID. * @param   events - events to process.  This is a bit map and can *                   contain more than one event. * * @return  none */UINT16 TestApp_ProcessEvent( byte task_id, UINT16 events ){  afIncomingMSGPacket_t *MSGpkt;   (void)task_id;  // Intentionally unreferenced parameter  if ( events & SYS_EVENT_MSG )  {    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( TestApp_TaskID );    while ( MSGpkt )    {      switch ( MSGpkt->hdr.event )      {                  case KEY_CHANGE:          TestApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );          break;        case AF_INCOMING_MSG_CMD:          TestApp_MessageMSGCB( MSGpkt );          break;        default:          break;      }      // Release the memory      osal_msg_deallocate( (uint8 *)MSGpkt );//释放消息所占用空间      // Next      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( TestApp_TaskID );//接着获取消息    }    // return unprocessed events    return (events ^ SYS_EVENT_MSG);  }  // Send a message out - This event is generated by a timer  //  (setup in TESTApp_Init()).  if ( events & TESTAPP_SEND_MSG_EVT )  {    // Send "the" message    TestApp_SendTheMessage();    // Setup to send message again    osal_start_timerEx( TestApp_TaskID,                        TESTAPP_SEND_MSG_EVT,                      TESTAPP_SEND_MSG_TIMEOUT );    // return unprocessed events    return (events ^ TESTAPP_SEND_MSG_EVT);  }  // Discard unknown events  return 0;}/********************************************************************* * Event Generation Functions *//********************************************************************* * @fn      TESTApp_ProcessZDOMsgs() * * @brief   Process response messages * * @param   none * * @return  none */void TestApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg ){  switch ( inMsg->clusterID )  {    case End_Device_Bind_rsp:      if ( ZDO_ParseBindRsp( inMsg ) == ZSuccess )      {        // Light LED        HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );      }#if defined(BLINK_LEDS)      else      {        // Flash LED to show failure        HalLedSet ( HAL_LED_4, HAL_LED_MODE_FLASH );      }#endif      break;    case Match_Desc_rsp:      {        ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );        if ( pRsp )        {          if ( pRsp->status == ZSuccess && pRsp->cnt )          {            TestApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;            TestApp_DstAddr.addr.shortAddr = pRsp->nwkAddr;            // Take the first endpoint, Can be changed to search through endpoints            TestApp_DstAddr.endPoint = pRsp->epList[0];            // Light LED            HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );          }          osal_mem_free( pRsp );        }      }      break;  }}/********************************************************************* * @fn      TESTApp_HandleKeys * * @brief   Handles all key events for this device. * * @param   shift - true if in shift/alt. * @param   keys - bit field for key events. Valid entries: *                 HAL_KEY_SW_4 *                 HAL_KEY_SW_3 *                 HAL_KEY_SW_2 *                 HAL_KEY_SW_1 * * @return  none */void TestApp_HandleKeys( byte shift, byte keys ){  zAddrType_t dstAddr;    // Shift is used to make each button/switch dual purpose.  if ( shift )  {    if ( keys & HAL_KEY_SW_1 )    {    }    if ( keys & HAL_KEY_SW_2 )    {    }    if ( keys & HAL_KEY_SW_3 )    {    }    if ( keys & HAL_KEY_SW_4 )    {    }  }  else  {    if ( keys & HAL_KEY_SW_1 )    {    }    if ( keys & HAL_KEY_SW_2 )    {      HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );      // Initiate an End Device Bind Request for the mandatory endpoint      dstAddr.addrMode = Addr16Bit;      dstAddr.addr.shortAddr = 0x0000; // Coordinator      ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),                             TestApp_epDesc.endPoint,                            TESTAPP_PROFID,                            TESTAPP_MAX_CLUSTERS, (cId_t *)TESTApp_ClusterList,                            TESTAPP_MAX_CLUSTERS, (cId_t *)TESTApp_ClusterList,                            FALSE );    }    if ( keys & HAL_KEY_SW_3 )    {    }    if ( keys & HAL_KEY_SW_4 )    {      HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );      // Initiate a Match Description Request (Service Discovery)      dstAddr.addrMode = AddrBroadcast;      dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;      ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,                        TESTAPP_PROFID,                        TESTAPP_MAX_CLUSTERS, (cId_t *)TESTApp_ClusterList,                        TESTAPP_MAX_CLUSTERS, (cId_t *)TESTApp_ClusterList,                        FALSE );    }  }}/********************************************************************* * LOCAL FUNCTIONS *//********************************************************************* * @fn      TESTApp_MessageMSGCB * * @brief   Data message processor callback.  This function processes *          any incoming data - probably from other devices.  So, based *          on cluster ID, perform the intended action. * * @param   none * * @return  none */void TestApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ){  unsigned char buffer;  static unsigned char LEDState[5];  switch ( pkt->clusterId )  {    case TESTAPP_CLUSTERID:      // "the" message      osal_memcpy(&buffer, pkt->cmd.Data, 1);      switch(buffer)      {        case 1:          LEDState[0]++;          if(LEDState[0] == 2)          {            LEDState[0] = 0;          }          if(LEDState[0] == 0)          {            HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);          }          else          {            HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF);          }          break;        case 2:          LEDState[1]++;          if(LEDState[1] == 2)          {            LEDState[1] = 0;          }          if(LEDState[1] == 0)          {            HalLedSet(HAL_LED_2, HAL_LED_MODE_ON);          }          else          {            HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF);          }          break;        case 3:          LEDState[2]++;          if(LEDState[2] == 2)          {            LEDState[2] = 0;          }          if(LEDState[2] == 0)          {            HalLedSet(HAL_LED_3, HAL_LED_MODE_ON);          }          else          {            HalLedSet(HAL_LED_3, HAL_LED_MODE_OFF);          }          break;        case 4:          LEDState[3]++;          if(LEDState[3] == 2)          {            LEDState[3] = 0;          }          if(LEDState[3] == 0)          {            HalLedSet(HAL_LED_4, HAL_LED_MODE_ON);          }          else          {            HalLedSet(HAL_LED_4, HAL_LED_MODE_OFF);          }          break;        case 5:          LEDState[4]++;          if(LEDState[4] == 2)          {            LEDState[4] = 0;          }          if(LEDState[4] == 0)          {            HalLedSet(HAL_LED_ALL, HAL_LED_MODE_ON);          }          else          {            HalLedSet(HAL_LED_ALL, HAL_LED_MODE_OFF);          }          break;      }#if defined( LCD_SUPPORTED )      HalLcdWriteScreen( (char*)pkt->cmd.Data, "rcvd" );#elif defined( WIN32 )      WPRINTSTR( pkt->cmd.Data );#endif      break;  }}/********************************************************************* * @fn      TESTApp_SendTheMessage * * @brief   Send "the" message. * * @param   none * * @return  none */void TestApp_SendTheMessage( void ){  char theMessageData[] = "LED";  if ( AF_DataRequest( &TestApp_DstAddr, &TestApp_epDesc,                       TESTAPP_CLUSTERID,                       3,                       theMessageData,                       &TestApp_TransID,                       AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )  {    // Successfully requested to be sent.  }  else  {    // Error occurred in request to send.  }}/******************************************************************************************************************************************/static void rxCB(uint8 port, uint8 event){  uint8 Uartbuf[80];  uint8 buffer;  static unsigned char LEDState[5];  bool result = false;  if((event &(HAL_UART_RX_FULL|HAL_UART_RX_ABOUT_FULL|HAL_UART_RX_TIMEOUT)) && #if SERIAL_APP_LOOPBACK     (SerialApp_TxLen < SERIAL_APP_TX_MAX))#else    !SerialApp_TxLen)#endif  {    SerialApp_TxLen = HalUARTRead(0, Uartbuf, 2);        osal_memcpy(&buffer, Uartbuf, 1);    buffer -=0x30;    switch(buffer)    {      case 0:        HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);        result = true;        break;      case 1:        HalLedSet(HAL_LED_2, HAL_LED_MODE_ON);        result = true;        break;      case 2:        HalLedSet(HAL_LED_3, HAL_LED_MODE_ON);        result = true;        break;      case 3:        HalLedSet(HAL_LED_ALL, HAL_LED_MODE_ON);        result = true;        break;      case 4:        HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF);        result = true;        break;      case 5:        HalLedSet(HAL_LED_2, HAL_LED_MODE_OFF);        result = true;       break;      case 6:        HalLedSet(HAL_LED_3, HAL_LED_MODE_OFF);        result = true;        break;       case 7:        HalLedSet(HAL_LED_ALL, HAL_LED_MODE_OFF);        result = true;        break;    }    if(result)    {      HalUARTWrite(0, "success\r\n", 9);     }    else    {      HalUARTWrite(0, "failed\r\n", 8);    }    SerialApp_TxLen = 0;  }}

只需查看TestApp_Init()以及rxCB()函数即可,在TestApp_Init()函数中对串口0进行配置,在rxCB()函数中对接收到的数据进行解析并对LED资源做出相应的处理。下载程序到板子上,此时可用串口工具来实现对LED资源的控制,串口信息如下所示:


此时已经完成了一半。

Android端流程:Android建立一个TCP的服务端,然后等待连接,有连接接入时即可发送控制指令到TCP的客户端,

布局文件如下

<?xml version="1.0" encoding="utf-8"?>    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:background="#eee"        android:orientation="vertical" >                <RelativeLayout   android:layout_width="fill_parent"  android:layout_height="45dp"  android:id="@+id/title"   android:background="@drawable/title_bar"  android:gravity="center_vertical"  >   <Button      android:id="@+id/back"      android:text="返回"      android:textColor="#ffffff"      android:textSize="15sp"     android:layout_alignParentLeft="true"        android:layout_centerVertical="true"      android:layout_width="80dp"      android:layout_height="wrap_content"      android:background="@drawable/title_btn_back"      android:onClick="goBack"      />        <TextView        android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_centerInParent="true"        android:text="管理"        android:textSize="20sp"android:textColor="#ffffff" />   <TextView      android:id="@+id/userName"      android:text="用户名"      android:textColor="#ffffff"      android:textSize="15sp"     android:layout_alignParentRight="true"        android:layout_centerInParent="true"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:background="@drawable/title_btn_right"      />    </RelativeLayout>      <RelativeLayout            android:id="@+id/layout_socket_name"          android:layout_below="@id/title"                    android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:layout_marginTop="14dp"            android:gravity="center_vertical"            android:clickable="true"            android:background="@drawable/preference_single_item" >            <TextView                android:id="@+id/socket_name"        android:layout_width="wrap_content"         android:layout_height="wrap_content"        android:layout_centerHorizontal="true"        android:padding="8dp"         android:text="无线插座"        android:textSize="17sp"android:textColor="#000" />       </RelativeLayout><RelativeLayout    android:layout_below="@id/layout_socket_name"            android:layout_width="fill_parent"            android:layout_height="wrap_content"            android:layout_marginTop="14dp"            android:gravity="center_horizontal"            android:background="@drawable/preference_single_item" >             <ImageViewandroid:id="@+id/socket_iv0"android:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingTop="8dp"android:paddingLeft="8dp"android:src="@drawable/jack0_close"android:clickable="true"android:onClick="Manage"/><ImageViewandroid:id="@+id/socket_iv2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toRightOf="@id/socket_iv0"android:paddingTop="8dp"    android:paddingRight="8dp"    android:src="@drawable/jack2_close"    android:clickable="true"    android:onClick="Manage"/><ImageView    android:id="@+id/socket_iv1"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_below="@id/socket_iv0"    android:paddingBottom="8dp"    android:paddingLeft="8dp"    android:src="@drawable/jack1_close"    android:clickable="true"    android:onClick="Manage"    /><ImageView    android:id="@+id/socket_iv3"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_below="@id/socket_iv2"    android:layout_toRightOf="@id/socket_iv1"    android:paddingBottom="8dp"    android:paddingRight="8dp"    android:src="@drawable/jack3_close"    android:clickable="true"    android:onClick="Manage"    />      </RelativeLayout>      <RelativeLayout             android:layout_width="fill_parent"   android:layout_height="wrap_content"   android:layout_marginTop="14dp"   android:gravity="center_vertical"   android:clickable="true"   android:layout_alignParentBottom="true"   android:background="@drawable/preference_single_item" >   <TextView       android:id="@+id/socket_id" android:layout_width="wrap_content"  android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:padding="8dp"  android:text="无线插座" android:textSize="17sp"android:textColor="#000" /> </RelativeLayout>   </RelativeLayout>

布局效果图如下所示:


代码中用了Apache-Mina库文件,当然也可以不使用。MainActivity.java代码如下

package com.anobodykey.remotecontrol;import java.io.IOException;import java.net.InetSocketAddress;import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;import org.apache.mina.core.session.IoSession;import org.apache.mina.filter.codec.ProtocolCodecFilter;import org.apache.mina.filter.codec.textline.TextLineCodecFactory;import org.apache.mina.transport.socket.SocketAcceptor;import org.apache.mina.transport.socket.nio.NioSocketAcceptor;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.os.Bundle;import android.view.KeyEvent;import android.view.Menu;import android.view.View;import android.widget.ImageView;import android.widget.Toast;public class MainActivity extends Activity {private static final int JACK_NUMBER = 4;SocketAcceptor acceptor;private int[] jacks_id = {R.id.socket_iv0, R.id.socket_iv1, R.id.socket_iv2, R.id.socket_iv3,};//插孔控件idprivate int[] jacks_status = {R.drawable.jack0_close, R.drawable.jack0_open,R.drawable.jack1_close, R.drawable.jack1_open,R.drawable.jack2_close, R.drawable.jack2_open,R.drawable.jack3_close, R.drawable.jack3_open,};//插孔状态图片资源private ImageView[] jackViews = null;static public int iterator = 0;//插孔遍历器static public boolean[] status = null;//插座状态@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.remote_manager);jackViews = new ImageView[JACK_NUMBER];status = new boolean[JACK_NUMBER + 1];for(int i = 0; i < JACK_NUMBER; i++){jackViews[i] = (ImageView)findViewById(jacks_id[i]);status[i] = false;if(status[i]){jackViews[i].setImageResource(jacks_status[2*i + 1]);}else{jackViews[i].setImageResource(jacks_status[2*i]);}}status[JACK_NUMBER] = false;acceptor = new NioSocketAcceptor();DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();chain.addLast("mychain", new ProtocolCodecFilter(new TextLineCodecFactory()));acceptor.setHandler(new SimpleMinaServerHandler());int port = 5555;try {acceptor.bind(new InetSocketAddress(port));Toast.makeText(MainActivity.this, "服务器启动完毕", Toast.LENGTH_SHORT).show();}catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}public void Manage(View v){for(iterator = 0; iterator < 4; iterator++){if(jacks_id[iterator] == v.getId()){break;}}new AlertDialog.Builder(this)   .setTitle("确认对话框")  .setMessage("确定要修改该插孔状态吗?")  .setPositiveButton("是", new OnClickListener() {public void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubif(iterator < 3){if(status[iterator]){jackViews[iterator].setImageResource(jacks_status[2*iterator]);}else{jackViews[iterator].setImageResource(jacks_status[2*iterator + 1]);}status[iterator] = !status[iterator];}else if (iterator == 3){if(status[iterator]){for(int i = 0; i <=iterator; i++){jackViews[i].setImageResource(jacks_status[2*i]);}}else{for(int j = 0; j <=iterator; j++){jackViews[j].setImageResource(jacks_status[2*j + 1]);}}for(int k = 0; k <=iterator; k++)status[k] = !status[k];}SendMessage();}})  .setNegativeButton("否", null)  .show();}public void SendMessage(){if(status[iterator]){SimpleMinaServerHandler.ioSession.write(iterator);}else{SimpleMinaServerHandler.ioSession.write(iterator+4);}}public void goBack(View v){acceptor.unbind();acceptor.dispose();this.finish();}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {// TODO Auto-generated method stubif(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0){goBack(null);}return false;}}

SimpleMinaServerHandler.java代码如下

package com.anobodykey.remotecontrol;import org.apache.mina.core.service.IoHandlerAdapter;import org.apache.mina.core.session.IdleStatus;import org.apache.mina.core.session.IoSession;public class SimpleMinaServerHandler extends IoHandlerAdapter{static public IoSession ioSession; @Overridepublic void exceptionCaught(IoSession session, Throwable cause)throws Exception {// TODO Auto-generated method stubsuper.exceptionCaught(session, cause);}@Overridepublic void messageReceived(IoSession session, Object message)throws Exception {// TODO Auto-generated method stubString s = (String)message;System.out.println("message:"+s);}@Overridepublic void messageSent(IoSession session, Object message) throws Exception {// TODO Auto-generated method stubSystem.out.println("Sent");}@Overridepublic void sessionClosed(IoSession session) throws Exception {// TODO Auto-generated method stubSystem.out.println("closed");;}@Overridepublic void sessionCreated(IoSession session) throws Exception {// TODO Auto-generated method stubsuper.sessionCreated(session);}@Overridepublic void sessionIdle(IoSession session, IdleStatus status)throws Exception {// TODO Auto-generated method stubsuper.sessionIdle(session, status);}@Overridepublic void sessionOpened(IoSession session) throws Exception {// TODO Auto-generated method stubSystem.out.println("opend!");ioSession = session;}}

此外,还需要一个TcpComm的工具,该工具可以将接收的TCP数据转换成串口数据发出,同时也可以将接收到的串口数据转换成TCP数据发出,我们用作中转,此时,就可以实现用手机来控制ZigBee板子上的LED资源啦。。。

PS:Android程序还有待完善,读者可自行设计。。。

原创粉丝点击