Android手机控制ZigBee板上LED

2023-05-16

环境: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" >
            			 
			<ImageView
				android: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"
			/>
			<ImageView
				android: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,
		};//插孔控件id
	private 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;//插座状态
	@Override
	protected 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 block
			e.printStackTrace();
		}
		
		
	}

	@Override
	public 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 stub
				if(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();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if(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; 
	@Override
	public void exceptionCaught(IoSession session, Throwable cause)
			throws Exception {
		// TODO Auto-generated method stub
		super.exceptionCaught(session, cause);
	}

	@Override
	public void messageReceived(IoSession session, Object message)
			throws Exception {
		// TODO Auto-generated method stub
		String s = (String)message;
		System.out.println("message:"+s);
	}

	@Override
	public void messageSent(IoSession session, Object message) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("Sent");
	}

	@Override
	public void sessionClosed(IoSession session) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("closed");;
	}

	@Override
	public void sessionCreated(IoSession session) throws Exception {
		// TODO Auto-generated method stub
		super.sessionCreated(session);
	}

	@Override
	public void sessionIdle(IoSession session, IdleStatus status)
			throws Exception {
		// TODO Auto-generated method stub
		super.sessionIdle(session, status);
	}

	@Override
	public void sessionOpened(IoSession session) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("opend!");
		ioSession = session;
	}
	
}

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android手机控制ZigBee板上LED 的相关文章

随机推荐

  • window平台搭建服务器

    在windows如何搭建服务器 xff1a 1 先打开控制面板 xff0c 然后打开程序和功能 xff0c 点击启用或者关闭windows功能 xff0c 找到Internet information services xff0c 选中后点
  • CycleGAN的基本原理以及Pytorch框架实现

    目录 1 了解CycleGAN xff08 1 xff09 什么是CycleGAN xff08 2 xff09 CycleGAN的应用场景 2 CycleGAN原理 xff08 1 xff09 整个模型 xff08 2 xff09 优化目标
  • OpenCV下的图形交互和媒体接口HighGUI

    目录 1 OpenCV下的GUI接口 xff08 1 xff09 回调函数 xff08 1 xff09 滑杆控件trackbars xff08 2 xff09 鼠标操作回调函数 xff08 3 xff09 键盘响应函数 Windows下的C
  • WGAN基本原理及Pytorch实现WGAN

    目录 1 WGAN产生背景 xff08 1 xff09 超参数敏感 xff08 2 xff09 模型崩塌 2 WGAN主要解决的问题 3 不同距离的度量方式 xff08 1 xff09 方式一 xff08 2 xff09 方式二 xff08
  • Pytorch框架实现WGAN-GP

    目录 1 WGAN GP产生背景 2 WGAN GP的主要成就 3 权重限制的困难 Difficulties with weight constraints xff08 1 xff09 WGAN GP算法流程 xff08 2 xff09 梯
  • Pytorch框架实现Pix2Pix(Image-to-image)

    目录 1 pix2pix研究背景 2 Pix2Pix基本原理 xff08 1 xff09 原理图 xff08 2 xff09 条件GAN cGAN xff08 3 xff09 公式原理 3 Pix2Pix网络模型 xff08 1 xff09
  • 【Microsoft COCO数据集介绍以及简单使用】

    Microsoft COCO数据集介绍以及简单使用 文前白话1 MSCOCO数据集介绍2 COCO数据集格式说明3 数据集下载4 COCO API pycocotools 其它的COCO API Reference 文前白话 本文介绍Mic
  • linux装SSH服务以及防止SSH暴力破解

    需要安装的包 xff1a openssh clients 6 6 1p1 22 el7 x86 64 openssh server 6 6 1p1 22 el7 x86 64 配置文件中常用参数的介绍 xff1a vim etc ssh s
  • 【Linux 切换 ES(elasticsearch)用户】

    Linux服务器里面有些操作不能用root用户操作ES xff0c 需要切换用户操作启动 1 切换用户命令 su 用户名 或者 ssh 用户名 64 服务器ip地址 su span class token operator span es
  • [DSA] 数字血管造影系统-硬件篇

    根据一下资料整理和增删 xff1a http www china radiology com showtopic 6451 aspx 2008年的资料 xff0c 但可以作为入门资料 xff0c 讲述了很多基本概念 http blog cs
  • QT修改QPushButton的背景色和文字颜色

    Qt中QPushButton背景颜色设置方法 不管我设置不是画笔颜色 xff0c 依然不管用 xff0c 一查才知道自己错了 因为在windows中QPushButton的颜色涉及到样式表 xff0c 所以应该设置样式表才可以 xff0c
  • anaconda释放空间

    学习内容 xff1a conda clean 后面可以跟很多超参 xff0c 不同超参有不同的功能 xff1a 可选参数 xff1a span class token operator span h span class token ope
  • Qt线程:QThread

    一 描述 一个QThread对象管理程序内的一个线程 xff0c QThreads在run 中开始执行 默认情况下 xff0c run 通过调用exec 启动事件循环 xff0c 并在线程内部运行一个Qt事件循环 可以通过使用 QObjec
  • 论文精讲 | CVPR 2022|RHFL-对抗噪声的联邦学习

    模型异构的联邦学习 xff0c 是一种每个client拥有互不相同模型的联邦学习任务 xff0c 其能够解决联邦学习中每个成员希望独立设计自己模型的需求 xff0c 但目前同样面临着来自数据层面和成员层面的各种挑战 xff0c 比如数据标记
  • Android音频简介

    1 基本概念 1 1 播放模式 xff1a Deep buffer playback Android开发中最常用的播放模式 xff0c 音乐等对时延要求不高的声音输出采用该模式 边加载边播放 xff0c 由AP进行解码 Low latenc
  • vnc显示远程桌面

    搜了很多教程 xff0c 大部分都试了还是不能正常显示Ubuntu18 04的桌面 xff0c 最后找到了一篇文章 xff1a 使用 VNC 显示 Ubuntu Server 的图形化界面 可以让我的vnc正常显示的配置 首先 在服务器终端
  • 面试中常被提到的最左前缀匹配原则

    最左前缀匹配原则 xff1a 在MySQL建立联合索引时会遵守最左前缀匹配原则 xff0c 即最左优先 xff0c 在检索数据时从联合索引的最左边开始匹配 要想理解联合索引的最左匹配原则 xff0c 先来理解下索引的底层原理 索引的底层是一
  • njupt 字典序最大的出栈序列

    题意 xff1a 给出入栈序列 A xff0c 保证 A 各个元素值各不相等 xff0c 输出字典序最大的出栈序列 如入栈序列 A 61 1 2 9 4 6 5 则字典序最大的出栈序列为9 6 5 4 2 1 栈的性质就是先进后出 xff0
  • SD-WAN设备白盒刷机

    1 启动U盘插入盒子USB接口 2 PC与盒子通过串口线连接 xff0c 波特率为115200 3 加电 4 WAN接口接入网络 xff0c 保证可以访问外网 5 cd var 6 scp 64 122 96 93 166 root Fle
  • Android手机控制ZigBee板上LED

    环境 xff1a Windows 编译器 xff1a IAREW8051 8 1 硬件 xff1a CC2530 协议栈 xff1a ZStack CC2530 2 3 0 1 4 0 手机 xff1a Android4 1 2 又重新开始