单片机发送数据到android_android蓝牙接收单片机回传数据 - CSDN
精华内容
参与话题
  • 先把源码和资料链接放这里 链接:https://pan.baidu.com/s/10MxI8-Q33-M_R2WEHqEi1A密码:j1sz 先说一下那天的bug 所有的任务在启动时都是新建 ...

    https://yq.aliyun.com/users/article?spm=a2c4e.11155435.0.0.34723312MRbahT


    先把源码和资料链接放到这里

    链接:https://pan.baidu.com/s/10MxI8-Q33-M_R2WEHqEi1A 密码:j1sz

     

    先说一下那天的bug

    所有的任务在启动时都是新建

     

     

    否则就会有问题

    但是每次新建可能会产生有好几个同样的任务

     

    列如上面的连接任务

    咱们用一个全局的变量去记录咱的连接任务

     

    销毁的时候

    复制代码
    try {
           mthreadConnectService.interrupt();
        } catch (Exception e) {
           
        }
    复制代码

     

     发送数据的任务也是用一个全局变亮记录

    出现问题需要销毁的时候

    因为有好几个地方要添加这几句话,本来想.....算了,后期再说

    现在做显示部分,先给自己说一下,,,,下一篇一定要用Handle,如果还是这样写..都感觉无人子弟....唉......写的有点害怕了,,,,应该先介绍

    通常怎么操作控件的....这样操作控件懂行的人不知道会不会....唉

    现在界面再拖一个TextView用来显示温湿度数据

     

     

     再看一下规定的

     

     

     然后其实就是在接收数据里面

    复制代码
    /**
         * 接收数据的任务
         * @author yang
         *
         */
        class ThreadReadData extends Thread
        {
            public void run()
            {
                while (threadReadDataFlage)
                {
                    try 
                    {
                        ReadBufferLengh = inputStream.read(ReadBuffer);//服务器断开会返回-1
                        if (ReadBufferLengh == -1) 
                        {
                            threadSendDataFlage = false;//关掉发送任务,预防产生多的任务
                            threadReadDataFlage = false;//关掉接收任务,预防产生多的任务
                            try {mthreadReadData.interrupt();} catch (Exception e) {}
                            try {mthreadSendData.interrupt();} catch (Exception e) {}
                            SendDataCnt = 0;//清零发送的个数
                            ConnectFlage = true;
                            
                            
                            buttonConnect.post(new Runnable() {
                                @Override
                                public void run() {
                                    buttonConnect.setText("连接");
                                    Toast.makeText(getApplicationContext(), "与服务器断开连接", 500).show();
                                }
                            });
                        }
                        
                        try //防止数据有其它错误
                        {
                            if ((ReadBuffer[0]&0xff) == 0xaa && (ReadBuffer[1]&0xff) == 0x55) 
                            {
                                if ((ReadBuffer[2]&0xff) == 0x01) {
                                    textViewShowData.post(new Runnable() {//稍微写一个靠谱点的操作UI控件
                                        public void run() {
                                            textViewShowData.setText("温度:"+(ReadBuffer[3]&0xff)+"湿度"+(ReadBuffer[4]&0xff));
                                        }
                                    });
                                }
                            }
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                        
                        
                    } 
                    catch (Exception e) 
                    {
                        // TODO Auto-generated catch block
                        Log.e("error", ReadBufferLengh+"");
                        e.printStackTrace();
                        runOnUiThread(new Runnable() {//修改界面的UI最好用Handle,这里力求简单,下几节再用
                            public void run() {
                                buttonConnect.setText("连接");
                                Toast.makeText(getApplicationContext(), "与服务器断开连接", 500).show();
                            }
                        });
                        ConnectFlage = true;
                        threadSendDataFlage = false;//关掉发送任务,预防产生多的任务
                        threadReadDataFlage = false;//关掉接收任务,预防产生多的任务
                        try {mthreadReadData.interrupt();} catch (Exception e1) {}
                        try {mthreadSendData.interrupt();} catch (Exception e2) {}
                        SendDataCnt = 0;//清零发送的个数
                    }
                }
            }
        }
    复制代码

    其实就一点有用的,其余的大多数是重复的程序,下一篇优化一下....

    现在咱先用调试助手测试

    APP可在百度手机助手,安卓市场,91助手,下载安装(搜索"小五物联")

     

     

    我是用的两个手机哈,因为我做的那个调试助手,一关闭就会全都关闭了,,后期再优化下哈,,,,

    亲们可以用电脑的调试助手,资料里面有

     

    好现在咱们用板子试一下

    不对不对...咱是做的先发给板子指令然后板子收到命令再回复.....忘了,现在做每隔1S发送一次0xaa,0x55,0x01

     

     

    这样板子收到信息就回咱

    实现定时器呢有多种实现方法,说一种最简单的

    复制代码
    /**
         * 每间隔1S发送一次采集数据的命令
         */
        private CountDownTimer editDeleteTimer = new CountDownTimer(1000,100) {
            @Override
            public void onTick(long millisUntilFinished) {
                
            }
            
            @Override
            public void onFinish() 
            {
                SendBuffer[0] = (byte) 0xaa;
                SendBuffer[1] = 0x55;
                SendBuffer[2] = 0x01;
                SendDataCnt = 3;//控制发送数据的个数
                editDeleteTimer.start();
            }
        };
    复制代码

    启动和停止呢

     

     现在试一下

    板子上电正常运行哈...

     

     

    刚才板子放在了我电脑的散热口附近,所以才会30度哈,我没有在非洲和赤道哈....,,电脑两天没有关机了,,有点小热.....

    现在控制一下灯

     

     下一篇一定要优化程序,不能这样子了,,,,,,额嗯,做TCP服务的时候再优化也行,重新写一切按照常规写

     

    单片机程序还是上一篇的...

    对了

    数据&0xff

    参考链接

    https://blog.csdn.net/wwzuizz/article/details/77649358

    亲们自己百度哈


    展开全文
  • 51单片机是市面上比较普及的单片机种类,同时也深受广大电子爱好者的青睐。在51单片机的众多功能中串口通信占据了重要的地位,通过串口通信,我们可以实现51单片机与其他设备的... 要完成单片机Android手机的无...

      51单片机是市面上比较普及的单片机种类,同时也深受广大电子爱好者的青睐。在51单片机的众多功能中串口通信占据了重要的地位,通过串口通信,我们可以实现51单片机与其他设备的互联,增加了学习的趣味性。

      HC-05蓝牙模块为主从一体的蓝牙模块,并可与手机实现实时的通信。将单片机的串口通信通过HC-05进行扩展从而实现无线通信,更可使用手机来控制单片机完成工作。

     要完成单片机与Android手机的无线通信,首先我们要在写好单片机的控制程序,因为HC-05只是对串口通信功能进行延伸, 并不能独立完成通信。

     编写串口通信的程序中首先我们要对串口的配置进行初始化

    void UartConfigurationInit()
    {
        TMOD=0x20;  //设置定时器1工作方式为方式2   
        TH1=0xfd;  	  //波特率9600
        TL1=0xfd;  
        TR1=1;      //启动定时器1     
        SM0=0;SM1=1;      //串口方式1         
        REN=1;      //允许接收   
        PCON=0x00;  //关倍频   
        ES=1;       //开串口中断   
        EA=1;       //开总中断
    }

    配置好串口后,在编写发送函数前我们需要对串口发送数据的原理有个了解:

    转码过程:

    发送十进制数:查询ASCII码表后发送相应的字符 ,如SBUF=65;则会收到字符‘A’;

    发送字符:原样输出

    发送字符串:强行对SBUF传递字符串会造成输出乱码,得不到想要的结果。想要发送字符串则需要运用指针,每次发送时发送指针指向的那个字符,因为发送频率很快,最后输出时组合起来还是一条字符串。

    实现整数转为字符串发送:

       0x30对应的字符‘0’,当我们要发送一个整数时,需要将该整数按最高位到最低位得到顺序依次发送,发送时需要在原始数据上加上0x30或者48,则会输出相应的数字字符。


    字符发送函数:

    void PostChar(uchar character)  
    {     
    	    SBUF=character;   //发送单个字符
    	    while(!TI);TI=0; //发送完成标志 
    }

    字符串的发送需要依靠字符发送函数来实现:

      这里加了一个延时函数delay(),因为在实际与手机通信中我发现发送速度过快会产生严重的数据丢失,因此加上一个延时可以较好的保证数据的准确度,具体延时数据根据大家实际需要调整。

    void  PostString(uchar *p)  
    {  
    	    while(*p)  	   //若指针指向的地址为空,则跳出循环
    	    {  
    	        PostChar(*p); //指针第一次默认指向首地址
    			delay(20);  //延时,作用为提高发送准确度
    	        p++;  
    	    }	  
    }

    十进制数据发送:

     因为十进制数据不能直接发送,所以要先加上0x30或者48后再转为字符型。

    void IntConversionChar(uint number)
    {
           uint model;	//模
           uint numberByte; //十进制数据不同位上的值
    
         for(model=1000;model>=1;model=model/10) //model的取值根据实际需要选择,选择过大会浪费资源
    
          {
                numberByte = number/model;	//相除取整
    			//当取到整数数据的最高位时,将其加上0x30或者48并转为字符型后发送
                if(numberByte >=1 ) PostChar((uchar)(numberByte%10+0x30));
          		//if(numberByte >=1 ) PostChar((unsigned char)(numberByte%10+48));
    	  }	
    }

    以上就是51单片机使用HC-05蓝牙模块与Android手机通信的程序的要点和原理。

    完整程序:

    https://download.csdn.net/download/qq_41570228/10398277



    展开全文
  • 最近一个项目是android和MCU之间的串口指令数据通信,捣鼓了很久,也找了很多网上的资料。最后将实现的总结记录下来。 使用的是GitHub中的一个项目,下载地址:https://github.com/cepr/android-serialport-api ...

     最近一个项目是android和MCU之间的串口指令数据通信,捣鼓了很久,也找了很多网上的资料。最后将实现的总结记录下来。

    使用的是GitHub中的一个项目,下载地址:https://github.com/cepr/android-serialport-api

    下载解压后会出现两个文件夹,我们使用的是这个,如图:

    复制整个文件夹到项目的java目录下,不要变更名字,名字是跟里面的东西相关的,变更后会报错,如图:

    再将android_serialport_api下的除了drawable下的其他资源文件复制粘贴到项目中对应的文件下,如图:

    再将jni和lib下的文件也都复制到项目中,如图:

    接下来配置model的build.gradle

    在android下的defaultConfig 添加ndk,如图:

     

    ndk{
        abiFilters "armeabi-v7a"
    }
    ndk{
        moduleName "serial_port"
        abiFilters "armeabi", "armeabi-v7a", "x86"
    }
    ndk{
        ldLibs "log"
    }
    

    在android下添加,引用jni:

    sourceSets{
        main{
            jni.srcDirs = []
        }
    }注:targetSdkVersion版本要22以下,22以上会报错奔溃

    至此,配置完成。接下来就是打开和使用串口通信了

    串口使用到的数据定义:

    /**
     * 标记当前串口状态(true:打开,false:关闭)
     **/
    public static boolean isFlagSerial = false;
    public static SerialPort serialPort = null;
    public static InputStream inputStream = null;
    public static OutputStream outputStream = null;
    public static Thread receiveThread = null;
    public static String strData = "";
    

    打开串口,在oncreate()中调用open(),可根据返回值来确认串口是否打开成功,需要注意的是

    serialPort = new SerialPort(new File("/dev/ttyS2"), 9600, 0);

    /dev/ttyS2 : 表示串口号,根据自身设备更换,一般为ttyS2,ttyS3

    9600 : 波特率,根据模块设定而更换

    0 : 校验位,固定为0即可

    /**
     * 打开串口
     */
    public boolean open() {
        boolean isopen = false;
        if (isFlagSerial) {
            Log.i("1111111", "串口已经打开,打开失败");
            return false;
        }
        try {
            serialPort = new SerialPort(new File("/dev/ttyS2"), 9600, 0);
            inputStream = serialPort.getInputStream();
            outputStream = serialPort.getOutputStream();
            receive();
            isopen = true;
            isFlagSerial = true;
        } catch (IOException e) {
            e.printStackTrace();
            isopen = false;
        }
        return isopen;
    }
    

    关闭串口没什么好说明的,顾名思义,在退出应用时调用

    /**
     * 关闭串口
     */
    public boolean close() {
        if (isFlagSerial) {
            Log.i("1111111", "串口关闭失败");
            return false;
        }
        boolean isClose = false;
        Log.i("1111111", "关闭串口");
        try {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
            isClose = true;
            isFlagSerial = false;//关闭串口时,连接状态标记为false
        } catch (IOException e) {
            e.printStackTrace();
            isClose = false;
        }
        return isClose;
    }
    

    发送串口指令,这个是android下发数据到mcu时调用,一般用于mcu上发数据给android端,android发特定指令回应指令发送给mcu。

    data : 为string类型,定义下发指令时为byte[]类型,需要转换成string

    十进制指令:byte data[] = new byte[]{104, 81, 03, 00, 00, 25, 85};

    十六进制指令:byte data[] = new byte[]{0x68, 0x51, 0x03, 0x00, 0x00, 0x19, 0x55};

    sendString(ByteUtil.getSum16(ms, ms.length));    //发送指令

    我一般使用的是十进制指令,因为十六进制指令有时是0xBA这种两个字母时,会出错。使用十进制指令要将mcu给的指令转成

    十进制,因为mcu给的都会是十六进制的数值。byte[]转string的工具类会在文章末贴出,网上也很容易找到

    /**
     * 发送串口指令
     */
    public void sendString(String data) {
        Toast.makeText(MainActivity.this, "发送串口指令 : " + data, Toast.LENGTH_SHORT).show();
        if (!isFlagSerial) {
            Log.i("1111111", "串口未打开,发送失败" + data);
            return;
        }
        try {
            outputStream.write(ByteUtil.hex2byte(data));
            outputStream.flush();
            Log.i("1111111", "sendSerialData:" + data);
        } catch (IOException e) {
            e.printStackTrace();
            Log.i("1111111", "发送指令出现异常");
        }
    }
    

    接收串口数据,此方法为接收mcu上发给android的指令数据方法。

    strData  : 上发的数据,根据数据进行处理,实现各需功能

    /**
     * 接收串口数据的方法
     */
    public void receive() {
        if (receiveThread != null && !isFlagSerial) {
            return;
        }
        receiveThread = new Thread() {
            @Override
            public void run() {
                while (isFlagSerial) {
                    try {
                        byte[] readData = new byte[32];
                        if (inputStream == null) {
                            return;
                        }
                        int size = inputStream.read(readData);
                        if (size > 0 && isFlagSerial) {
                            strData = ByteUtil.byteToStr(readData, size);
                            Message msg = new Message();
                            msg.what = 0x10;
                            msg.obj = strData;
                            handler.sendMessage(msg);
                            Log.i("1111111", "readSerialData:" + strData);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        receiveThread.start();
    }

    串口通信类,复制粘贴即可使用,我这里是将这些方法写在MainActivity下,也可以写成一个工具类调用,由你们决定。下面将byte[]和string的转换工具类贴一下出来

    public class ByteUtil {
    
        /**
         * 字符串转化成为16进制字符串
         *
         * @param s
         * @return
         */
        public static String strTo16(String s) {
            String str = "";
            for (int i = 0; i < s.length(); i++) {
                int ch = (int) s.charAt(i);
                String s4 = Integer.toHexString(ch);
                str = str + s4;
            }
            return str;
        }
        /**
         * 16进制转换成为string类型字符串
         *
         * @param s
         * @return
         */
        public static String hexStringToString(String s) {
            if (s == null || s.equals("")) {
                return null;
            }
            s = s.replace(" ", "");
            byte[] baKeyword = new byte[s.length() / 2];
            for (int i = 0; i < baKeyword.length; i++) {
                try {
                    baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            try {
                s = new String(baKeyword, "UTF-8");
                new String();
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            return s;
        }
        /**
         * 向串口发送数据转为字节数组
         */
        public static byte[] hex2byte(String hex) {
            String digital = "0123456789ABCDEF";
            String hex1 = hex.replace(" ", "");
            char[] hex2char = hex1.toCharArray();
            byte[] bytes = new byte[hex1.length() / 2];
            byte temp;
            for (int p = 0; p < bytes.length; p++) {
                temp = (byte) (digital.indexOf(hex2char[2 * p]) * 16);
                temp += digital.indexOf(hex2char[2 * p + 1]);
                bytes[p] = (byte) (temp & 0xff);
            }
            return bytes;
        }
        /**
         * 接收到的字节数组转换16进制字符串
         */
        public static String bytes2HexString(byte[] b, int size) {
            String ret = "";
            for (int i = 0; i < size; i++) {
                String hex = Integer.toHexString(b[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                ret += hex.toUpperCase();
            }
            return ret;
        }
        public static String bytesToHexString(byte[] src) {
            StringBuilder stringBuilder = new StringBuilder("");
            if (src == null || src.length <= 0) {
                return null;
            }
            for (int i = 0; i < src.length; i++) {
                int v = src[i] & 0xFF;
                String hv = Integer.toHexString(v);
                if (hv.length() < 2) {
                    stringBuilder.append(0);
                }
                stringBuilder.append(hv);
            }
            return stringBuilder.toString();
        }
        /**
         * 接收到的字节数组转换16进制字符串
         */
        public static String byteToStr(byte[] b, int size) {
            String ret = "";
            for (int i = 0; i < size; i++) {
                String hex = Integer.toHexString(b[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                ret += hex.toUpperCase();
            }
            return ret;
        }
    
        /**
         * 计算CRC16校验码
         * 逐个求和
         *
         * @param bytes 字节数组
         * @return {@link String} 校验码
         * @since 1.0
         */
        public static String getCRC_16(byte[] bytes) {
            int CRC = 0x0000ffff;
            int POLYNOMIAL = 0x0000a001;
            int i, j;
            for (i = 0; i < bytes.length; i++) {
                CRC ^= ((int) bytes[i] & 0x000000ff);
                for (j = 0; j < 8; j++) {
                    if ((CRC & 0x00000001) != 0) {
                        CRC >>= 1;
                        CRC ^= POLYNOMIAL;
                    } else {
                        CRC >>= 1;
                    }
                }
            }
            if (Integer.toHexString(CRC).toUpperCase().length() == 2) {
                return byteToStr(bytes, bytes.length) + "00" + Integer.toHexString(CRC).toUpperCase();
            } else if (Integer.toHexString(CRC).toUpperCase().length() == 3) {
                return byteToStr(bytes, bytes.length) + "0" + Integer.toHexString(CRC).toUpperCase();
            }
            return byteToStr(bytes, bytes.length) + Integer.toHexString(CRC).toUpperCase();
        }
    
        /**
         * 指令校验和,并取出后两位字节
         * */
        public static String getSum16(byte[] msg, int length) {
            long mSum = 0;
            byte[] mByte = new byte[length];
    
            /** 逐Byte添加位数和 */
            for (byte byteMsg : msg) {
                long mNum = ((long) byteMsg >= 0) ? (long) byteMsg : ((long) byteMsg + 256);
                mSum += mNum;
            } /** end of for (byte byteMsg : msg) */
    
            /** 位数和转化为Byte数组 */
            for (int liv_Count = 0; liv_Count < length; liv_Count++) {
                mByte[length - liv_Count - 1] = (byte) (mSum >> (liv_Count * 8) & 0xff);
            } /** end of for (int liv_Count = 0; liv_Count < length; liv_Count++) */
            return byteToStr(msg, length) + byteToStr(mByte, mByte.length).substring(byteToStr(mByte,       mByte.length).length() - 4, byteToStr(mByte, mByte.length).length());
        }
    
    }

    至此,END。

     

     

     

    展开全文
  • socket实现TCP通信_android

    最近做了一个TCP连接android与单片机的项目。记录一下。

    TCP连接对象

    首先是TCP连接,以前没有做过,摘抄的同事项目中TCP连接对象。
    public class TCPChannel {
        private SocketChannel myChannel = null;
        private boolean isConnecting = true;
        private boolean isConnected = false;
        // 发送心跳包的线程是否已经关闭
        private boolean isSendHeartBreak = false;
        private Selector selector = null;
        private Iterator<SelectionKey> iterator;
        private SelectionKey key;
        private String mac = "";
        private SocketAddress address;
        private int timeOut;
        private Thread heartbeat;

        private int heartCunt = 0;
        private boolean isWaitHeart = false;

        public TCPChannel(SocketChannel socketChannel, SocketAddress address,
                int timeOut) {
            // TODO Auto-generated constructor stub
            myChannel = socketChannel;
            this.address = address;
            this.timeOut = timeOut;
            try {
                LogUtil.e("selector open is will run open!!");
                selector = Selector.open();
            } catch (IOException e) {
                LogUtil.e("Selector.open() is wrong XXXX");
                e.printStackTrace();
            }
        }

        public void connect() throws IOException, NullPointerException {
            LogUtil.e("connect is be runned!!");

            isConnecting = true;
            isConnected = false;
            System.out.println(myChannel.toString());
            myChannel.configureBlocking(false);
            if (selector == null)
                throw new NullPointerException(mac);
            myChannel.register(selector, SelectionKey.OP_CONNECT
                    | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
            myChannel.connect(address);

            // System.out.println("检查TCP连接:" + checkConnect());
            if (checkConnect()) {
                LogUtil.e("checkConnect return true");
            } else {
                this.close();
                LogUtil.e("checkConnect return false");

            }
        }

        public void reConnect() {
            Log.w("重练空调", "准备开始");
            if (!isConnected) {
                return;
            }
            isConnecting = true;
            isConnected = false;
            if (heartbeat != null) {
                heartbeat.interrupt();
            } else {
                System.out.println("重连接时候心跳为空");
                // sendHeartbeat();
            }
            try {
                Log.w("重练空调", "关闭连接");
                myChannel.socket().close();
                myChannel.close();
                selector.close();
                myChannel = SocketChannel.open();
                try {
                    selector = Selector.open();
                } catch (IOException e) {
                    Log.e("----->", "Selector.open()错误2");
                    e.printStackTrace();
                }
                Log.w("重练空调", "正在重连");
                try {
                    connect();
                } catch (NullPointerException e) {
                    isConnected = true;
                    Log.e("----->", e + "抛出空指针异常33");
                }

                if (!isConnected) {
                    Log.w("重练空调", "没有连上");

                    close();
                } else {
                    Log.w("重练空调", "重连成功");
                    Log.i("----->12.4", "重连成功?" + heartCunt + " "
                            + isSendHeartBreak);

                    // 在断开wifi的情况下,心跳线程异常会从而终止,此判断是如果心跳因为异常而终止则重新开启心跳
                    if (heartCunt < 3) {
                        if (isSendHeartBreak) {
                            // sendHeartbeat();
                        }
                    } else {
                        close();
                    }
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ConcurrentModificationException e) {
                e.printStackTrace();
                close();
            }
        }

        public boolean checkConnect() {
            isConnected = false;
            try {
                Thread.sleep(timeOut * 1000);

            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            try {
                LogUtil.e("check TCP connection is:::-->" + myChannel
                        + "                   " + myChannel.finishConnect()
                        + "            " + myChannel.isConnected());
                if (myChannel != null && myChannel.finishConnect()
                        && myChannel.isConnected()) {

                    LogUtil.e(" not null 重连的时候?");
                    isConnected = true;
                }
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            isConnecting = false;
            return isConnected;
        }

        public void send(byte[] bytes) {
            // TODO Auto-generated method stub
            if (!isConnected || isConnecting) {
                return;
            }
            System.out.println("bytes  " + bytes + "myChannel  " + myChannel);
            try {
                ByteBuffer buf = ByteBuffer.wrap(bytes);
                myChannel.write(buf);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        public int sendUpdateDate(byte[] bytes) {
            // TODO Auto-generated method stub
            if (!isConnected || isConnecting) {
                return -1;
            }
            System.out.println("bytes  " + bytes + "myChannel  " + myChannel);
            try {
                ByteBuffer buf = ByteBuffer.wrap(bytes);
                myChannel.write(buf);
                return 0;
            } catch (IOException e) {

                e.printStackTrace();
                return -2;
            }
        }

        public void receive(Handler mainHandler) throws ParseException {

            // LogUtil.e("in receive ...");
            if (!isConnected || isConnecting) {
                return;
            }
            // LogUtil.e("in receive 校验之后 ");
            try {
                selector.select(100);
                if (selector != null && selector.isOpen()) {
                    // LogUtil.e("selector校验  selector != null && selector.isOpen()");
                    iterator = selector.selectedKeys().iterator();
                } else {
                    return;
                }
                while (iterator.hasNext()) {
                    // LogUtil.e("进入while循环内, iterator.hasNext()");
                    key = iterator.next();
                    // LogUtil.e("key == "+key.toString());
                    // 删除正在处理的SelectionKey
                    iterator.remove();
                    // 如果该SelectionKey对应的Channel中有可读的数据
                    // 测试此键的通道是否已准备好接受新的套接字连接。
                    ServerSocketChannel server = null;
                    SocketChannel client = null;
                    if (key.isReadable()) {
                        LogUtil.e("key.isReadable() 为true了  有可读数据");
                        // 使用NIO读取Channel中的数据
                        SocketChannel sc = (SocketChannel) key.channel();
                        // ByteArrayOutputStream buff = new
                        // ByteArrayOutputStream(1024 );//缓冲
                        // ByteArrayOutputStream有toByteArray()方法 直接得到数据
                        ByteBuffer buff = ByteBuffer.allocate(256);
                        String content = "";
                        int i = 0;
                        // //161 23.97
                        while ((i = sc.read(buff)) > 0) {
                            sc.read(buff);
                            buff.flip();
                            byte[] bytes = new byte[i];
                            buff.get(bytes);
                            switch (i) {
                            case 97:// 1-46
                                BatteryInfo batteryInfo = SaveUtil
                                        .saveBatteryInfo(bytes);
                                if(batteryInfo!=null){
                                    Message msg = new Message();
                                    Bundle b = new Bundle();// 存放数据
                                    b.putSerializable("BatteryInfo",
                                            (Serializable) batteryInfo);
                                    msg.setData(b);
                                    msg.what= 2;
                                    LogUtil.e("发送数据97的、、、");
                                    mainHandler.sendMessage(msg);
                                }
                                // 1.bytes,先截取前三个,后二个。留中间数据.返回三个数组
                                // 2。数据分开保存至bean中
                                // 2.1前三个直接把无符号byte转为int存储。
                                // 2.2中间数组两个合并一个,合并后,获取到short的无符号int值存储bean
                                // 2.2.1 数据格38-43四个合成一个转成long存储bean中。
                                // 2.3后两个变成16进制存储到CRC高低字节中。
    //                            LogUtil.e(batteryInfo.toString());
                                break;
                            case 161:// 80-158

                                break;
                            case 25:// 60-69
                                BatteryWarmInfo saveBatteryWarmInfo = SaveUtil
                                        .saveBatteryWarmInfo(bytes);
    //                            LogUtil.e(saveBatteryWarmInfo.toString());
                                // 判断saveBatteryWarmInfo.警告信息集合长度,如果有数据,更新界面
                                if (saveBatteryWarmInfo.WarmInfos.size() > 0) {
                                    // TODO发送消息到 MainUIThread 线程更新界面??
                                    // mainHandler.
                                    Message msg = new Message();
                                    Bundle b = new Bundle();// 存放数据
                                    b.putSerializable("warmInfos",
                                            (Serializable) saveBatteryWarmInfo);
                                    msg.setData(b);
                                    msg.what= 1;
                                    LogUtil.e("发送数据 25的、、、");
                                    mainHandler.sendMessage(msg);
                                    
                                }
                                break;

                            default:
                                LogUtil.e("获取到未知长度数据!请复查代码");
                                break;
                            }

                            // for (int x = 0; x < i; x++) {
                            // LogUtil.e(Byte.toString(bytes[x]));
                            // }
                            buff.clear();
                        }

                        key.interestOps(SelectionKey.OP_READ);
                        if (i == -1) {
                            reConnect();
                        }
                    }

                }
                // LogUtil.e("跳出while循环, iterator.hasNext()");
            } catch (IOException e1) {
                e1.printStackTrace();
            }

        }

        public void close() {
            isConnecting = true;
            isConnected = false;
            selector = null;
            mac = null;
            try {
                myChannel.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NullPointerException e) {
                Log.w("TCP关闭", "空指针");
            }
            myChannel = null;
        }

        public String getMac() {
            return mac;
        }

        public boolean isConnected() {
            return isConnected;
        }

        // private void ProcessReply(String id, List<String> strs) {
        // JsonParser parser = new JsonParser();
        // for (String str : strs) {
        //
        // System.out.println("str====:" + str);
        // // 改用正则匹配
        // if (str.matches("\\{.*\\}")) {
        //
        // System.out.println("没有问题啊!!!!!!!!!!!!!!!!");
        //
        // JsonElement jsonEl = parser.parse(str);
        // JsonObject jsonObj = null;
        // jsonObj = jsonEl.getAsJsonObject();
        // JsonElement je;
        // if ((je = jsonObj.get("response_type")) != null
        // && je.getAsInt() == 2) {
        // heartCunt = 0;
        // isWaitHeart = false;
        // } else {
        // Control.receivedPackets(gApp, jsonObj, TCPChannel.this);
        // }
        // } else {
        // System.out.println(id + "回码有问题啊!!!!!!!!!!!!!!!!" + str);
        // GreeApplication.baseActivity.showToast(id + "局域网回码错误");
        // }
        // }
        // }

        // public void sendHeartbeat() {
        // isSendHeartBreak = false;
        // heartbeat = new Thread(mac + "心跳") {
        // public void run() {
        // while (isConnected && !isConnecting) {
        // try {
        // Log.i("心跳包",
        // "心跳包发送"
        // + mac
        // + "       "
        // + JsonUtil.toJsonString(new Heartbeat(
        // GreeTime.getTimestamp())));
        //
        // String heartPacket = JsonUtil
        // .toJsonString(new Heartbeat(GreeTime
        // .getTimestamp())); // 加密
        //
        // String key = GreeApplication.LANKeymap.get(mac);
        // if (key == null) {
        //
        // key = "fbaef480";
        // }
        //
        // try {
        // heartPacket = Des.encryptDES(heartPacket, key,
        // false);
        // } catch (Exception e1) {
        // // TODO Auto-generated catch block
        // e1.printStackTrace();
        // }
        //
        // System.out.println("=================心跳des加密:" + key);
        // send(HeadUtil.addHead(heartPacket));
        // isWaitHeart = true;
        // sleep(10 * 1000);
        // if (isWaitHeart && heartCunt++ > 1) {
        // // 网络断开操作
        // Log.i("心跳包", "心跳包检测到网络断开" + mac);
        // reConnect();
        // }
        // } catch (UnsupportedEncodingException e) {
        // Log.i("----->12.4", "1:heart  error " + e.toString());
        // isSendHeartBreak = true;
        // e.printStackTrace();
        // } catch (InterruptedException e) {
        // Log.i("----->12.4", "2:heart  error " + "num is "
        // + heartCunt + "   " + e.toString());
        // isSendHeartBreak = true;
        // e.printStackTrace();
        // }
        // }
        // }
        // };
        // // ScheduledThreadPoolExecutor scheduler = new
        // // ScheduledThreadPoolExecutor(1);
        // // scheduler.schedule(heartbeat, 1,TimeUnit.SECONDS);
        // heartbeat.start();
        // }

        // private void checkTiming() throws ParseException {
        // // TODO Auto-generated method stub
        // DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
        // Locale.getDefault());
        // Date _date = new Date();
        //
        // String time_str = df.format(_date);
        //
        // System.out.println("定时现在时间:" + time_str);
        // if (AirCtrlDB.mPowerOnTimer != null) {
        // if (AirCtrlDB.mPowerOnTimer.bTimerOn) {
        // // System.out.println("//ON ");
        // time_str = time_str.substring(0, 11)
        // + AirCtrlDB.mPowerOnTimer.mHours + ":"
        // + AirCtrlDB.mPowerOnTimer.mMin + ":00";
        // long timeInterval = GreeTime.getInstance().timeIntervalNow(
        // time_str);
        // //
        // Log.i("----->12.4","在定时开机的循环中:"+AirCtrlDB.mPowerOnTimer.mfireMode+"   "+Math.abs(timeInterval));
        // if (Math.abs(timeInterval) < 4000) {
        //
        // System.out.println("//on < 36 ");
        // boolean _Execution = true;
        // switch (AirCtrlDB.mPowerOnTimer.mfireMode) {
        // case Timer_Mode_Once:
        // AirCtrlDB.mPowerOnTimer.bTimerOn = false;
        // break;
        // case Timer_Mode_WorkDay:
        // if (ByteOrder.getDay(_date) < 6) {
        //
        // } else {
        // _Execution = false;
        // }
        // break;
        // }
        // if (_Execution) {
        // // 开机
        // Log.i("----->12.4", "开机");
        // System.out.println("//on //开机 ");
        // ByteOrder.setpoweronView();
        // }
        //
        // }
        //
        // }
        // }
        //
        // if (AirCtrlDB.mPowerOffTimer != null) {
        // if (AirCtrlDB.mPowerOffTimer.bTimerOn) {
        // // System.out.println("//Off ");
        // /*
        // * DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // * Date _date = new Date(); String time_str = df.format(_date);
        // */
        // time_str = time_str.substring(0, 11)
        // + AirCtrlDB.mPowerOffTimer.mHours + ":"
        // + AirCtrlDB.mPowerOffTimer.mMin + ":00";
        // long timeInterval = GreeTime.getInstance().timeIntervalNow(
        // time_str);
        // //
        // Log.i("----->12.4","在定时关机的循环中:"+AirCtrlDB.mPowerOffTimer.mfireMode+"   "+Math.abs(timeInterval));
        // if (Math.abs(timeInterval) < 4000) {
        // System.out.println("//off < 36 ");
        // boolean _Execution = true;
        // switch (AirCtrlDB.mPowerOffTimer.mfireMode) {
        // case Timer_Mode_Once:
        // AirCtrlDB.mPowerOffTimer.bTimerOn = false;
        // break;
        // case Timer_Mode_WorkDay:
        // if (ByteOrder.getDay(_date) < 6) {
        //
        // } else {
        // _Execution = false;
        // }
        // break;
        // }
        //
        // if (_Execution) {
        // // 关机
        // System.out.println("//off //关机 ");
        // ByteOrder.setpowerOffView();
        // }
        // }
        // }
        // }
        //
        // }

    }
    此类的几个主要方法简单说明下:

    1.TCPChannel(SocketChannel socketChannel, SocketAddress address,int timeOut)

    初始化对象,SocketChannel,SocketAddress  java api对象。

    2.connect()

    连接方法.内部调用了SocketChannel的register(selector, SelectionKey.OP_CONNECT| SelectionKey.OP_READ | SelectionKey.OP_WRITE);和connect(address);

    3.reConnect()

    重连socket,

    4.send(byte[] bytes)

    发送byte数组数据。

    5.receiver();

    数据接收。

    调用方式:

    先执行,接收数据的循环,接收到数据,就发送给主线程的handler

    jieshou = new jieshou("TCP循环检测接收");
            jieshou.start();


    private class jieshou extends Thread {
            public jieshou(String string) {
                this.setName(string);
            }

            @Override
            public void run() {
                super.run();
                LogUtil.e("接收线程run方法中 ");

                while (true) {
                    try {
                        if (tcpChannel != null) {

                            tcpChannel.receive(mainHandler);

                        }
                        sleep(100);
                    } catch (Exception exception) {
                        exception.printStackTrace();
                    }
                }
            }
        }

    然后,连接通道,发送数据。

    address = new InetSocketAddress(ipAddress, 8088);
                flag = true;
                // 建立TCP连接通道

                thread = new Thread() {

                    public void run() {
                        try {
                            tcpChannel = new TCPChannel(SocketChannel.open(),
                                    address, 2);
                            tcpChannel.connect();
                            while (flag) {
                                LogUtil.e("while true循环着  去请求数据。。。。");
                                try {
                                    tcpChannel.send(getSendData(1, 46));
                                    sleep(500);
                                    tcpChannel.send(getSendData(60, 10));

                                    sleep(2500);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                    LogUtil.e("while 里抛出异常。");
                                }
                            }

                            LogUtil.e("tcp 请求数据,循环结束了。。。。。");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                };
                thread.start();

    断网后,重新连接:

    if (tcpChannel != null)
         tcpChannel.reConnect();

    TCP连接就完毕了。之后是CRC16校验和byte数据处理。

    展开全文
  • Android单片机的信息传输方案

    千次阅读 2019-03-18 08:29:39
    前言 本篇文章将围绕App与单片机的蓝牙通信来说说lz最近...单片机Android App的通信方案 环境 单片机 单片机:STC89C52 c语言 编写环境:Keil uVision4 烧录:stc-isp-15xx-v6.82 Android android sdk 16+
  • android开发之手机与单片机蓝牙模块通信

    万次阅读 多人点赞 2014-01-07 10:08:35
    下面是目前为止尝试的与单片机的通信方法,没有成功,但是从思路上来说没有问题,最大的问题是与单片机配对的时候,单片机的蓝牙模块的PIN配对码是写死的,固定为1234, 而手机这边连接配对都是自动生成的PIN配对...
  • Android手机wifi连接控制单片机发送数据简单测试demo(Socket通信简单应用测试)。
  • Android Studio 创建Socket客户端向单片机发送数据功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、...
  • Android通过串口向单片机发送一条16进制的指令,单片机收到以后会返回一条相同格式的命令。Android与PC上的串口助手调试,可以正确收发数据;单片机与串口助手调试,也可以正确收发数据。但是Android直接与单片机...
  • 先说明一下粘包的概念: 发送时是两个单独的包、两次发送,但接收时两个包连在一起被一次接收。在以前 WinCE 下 Socket 编程,确实也要处理粘包的问题,没想到在 Android 下也遇到了。首先想从发送端能否避免这样的...
  • Android通过蓝牙接收单片机发来的数据
  • #求助 Android 通过wifi控制单片机 ##问题:在写wifi传输文件时做好了wifi一系列的东西,但是现在要在Main离发送控制信号,不知道怎么调用 最近在做一个wifi控制单片机,用的Android studi程序参考了网上的大佬,在...
  • 其实使用调试助手,或者别人开的的APP同样能够实现接受单片机数据,但想学习的,我还是建议能够自己写一个Android软件,这样从底层上层都能学很多东西。 APP页面如图: 硬件连接如图: 单片机的硬件代码...
  • android蓝牙接收单片机数据并绘制波形
  • android手机接收并波形图显示单片机通过蓝牙传输的传感器数据
  • 使用Socket和ServerSocket在局网使用二台电脑 创建服务器和客户端连接,发送数据 第一步创 建服务器 在台试电脑 AbdroidStudro,MainActivity类创建 ServerSocket服务器,发送数据给笔记本电脑客户端 在电脑打开...
  • 这次期末的课程设计做了一个智能灯光控制系统,系统整体的功能不在此赘述,系统主要是要实现下位机同上位机的通信,上位机选用的是Android手机端,下位机是52单片机,通过蓝牙模块实现通信。虽然系统很简单,但还是...
  • DatagramSocket使用的UDP连接,客户端不需要先连接数据,可以直接发送给指定服务端。;DatagramPacket 用来发送和接收数据; /** * * */ public class Client2 { private static DatagramSocket client; /** .....
  • 请教一下各位大佬,51单片机按一下按钮之后,怎么通过esp8266发送一个字符串手机app啊。 现在我可以用手机控制单片机了,但不会从单片机数据到手机上。
  • 工作中经常遇到需要Android程序与各式各样的板子、智能设备进行交互,通信的方式也基本上都是Ble或者Socket tcp/udp等等…其中最重要的一点就是通信的协议、协议、协议重要的是说三遍;通信协议就是用来定义与设备...
1 2 3 4 5 ... 20
收藏数 1,516
精华内容 606
关键字:

单片机发送数据到android