通过手机端APP实现对树莓派控制摄像头的转动以及画面回传

本文详细描述了如何通过手机应用程序与树莓派进行网络连接,以及通过触控事件控制摄像头的移动,包括发送指令和接收摄像头画面的实时传输过程。
摘要由CSDN通过智能技术生成
通过手机端APP建立网络连接
public void Connect(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    s = new Socket(ip, port); //手机的IP地址和通信的端口号
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
在手机端APP给树莓派发送指令
public void SendCommand(String command){
        new Thread(new Runnable() {
            @Override
            public void run() {
//                showToast("!!!!!!!!!!");
                try{
//                    s.connect(new InetSocketAddress(ip, port), 6000);
                    while(flag == 1) {
                        s.setSendBufferSize(1000);
                        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
                        out.write(command);
                        out.flush();
                        Thread.sleep(100);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();
    }
通过按动手机APP上的按键来实现对摄像头的转动
public void onClick(View v) {
        int id = v.getId();
        switch(id){
            case R.id.buttonCamUp:
                up.setOnTouchListener(new View.OnTouchListener(){
                    @Override
                    public boolean onTouch(View view, MotionEvent motionEvent) {
                    //按住向上的按键,就控制摄像头向上转动
                        if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
                            flag = 1;
                            SendCommand("up");
                        }
                        if(motionEvent.getAction() == MotionEvent.ACTION_UP){
                            flag = 0;
                        }
                        return false;
                    }
                });
                break;
            case R.id.buttonCamDown:
                down.setOnTouchListener(new View.OnTouchListener(){
                    @Override
                    public boolean onTouch(View view, MotionEvent motionEvent) {
                        //按住向下的按键,就控制摄像头向下转动
                        if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
                            flag = 1;
                            SendCommand("down");
                        }
                        if(motionEvent.getAction() == MotionEvent.ACTION_UP){
                            flag = 0;
                        }
                        return false;
                    }
                });
                break;
            case R.id.buttonCamRight:
                right.setOnTouchListener(new View.OnTouchListener(){
                    @Override
                    public boolean onTouch(View view, MotionEvent motionEvent) {
                        //按住向右的按键,就控制摄像头向右转动
                        if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
                            flag = 1;
                            SendCommand("right");
                        }
                        if(motionEvent.getAction() == MotionEvent.ACTION_UP){
                            flag = 0;
                        }
                        return false;
                    }
                });
                break;
            case R.id.buttonCamLeft:
                left.setOnTouchListener(new View.OnTouchListener(){
                    @Override
                    public boolean onTouch(View view, MotionEvent motionEvent) {
                        //按住向左的按键,就控制摄像头向左转动
                        if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
                            flag = 1;
                            SendCommand("left");
                        }
                        if(motionEvent.getAction() == MotionEvent.ACTION_UP){
                            flag = 0;
                        }
                        return false;
                    }
                });
                break;
            case R.id.buttonOpen:
            //按下连接按钮与树莓派进行网络连接
                Connect();
                startReceiveThread();
                break;
            case R.id.buttonClose:
            //关闭网络连接
                try {
                    s.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                ss.close();
                finish();
                break;
            case R.id.buttonSure:

                buttonSure.setOnTouchListener(new View.OnTouchListener(){
                    @Override
                    public boolean onTouch(View view, MotionEvent motionEvent) {
                        if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){
                            flag = 1;
                            SendCommand("sure");
//                            imgView.setImageResource(R.drawable.touxiang);
                        }
                        if(motionEvent.getAction() == MotionEvent.ACTION_UP){
                            flag = 0;
                        }
                        return false;
                    }
                });
                break;
        }
    }
树莓派接收手机端的指令
def tcpCon():
    host = "192.168.43.114"
    port = 2025
    print('localhost ip :' + host)
    tcpServer = socket.socket()
    tcpServer.bind((host, port))
    # tcpServer.setblocking(0)  # Set unblock mode
    tcpServer.listen(5)
    (client, addr) = tcpServer.accept() 
    print('accept the client!')
    print(addr)
    while True:
        # client.setblocking(0)
        data = client.recv(1024)  //接收指令
        data = bytes.decode(data) //将接收到的指令进行解码
        cameraAction(data)        //通过接收指令让摄像头转动
        print(data)               //打印接收的指令
判断接收的指令并让摄像头转动
def cameraAction(command):
    global servo1_face_track, servo2_face_track, key
    if command == "sure":
        key = 1
    elif command == "up" and servo1_face_track >= 520://如果是up命令并且在限位角度区间内
        key = 0                                       //让舵机进行转动,带动摄像头向上转动
        servo1_face_track = servo1_face_track - 20    //底层封装的控制舵机工作的函数
        PWMServo.setServo(1, servo1_face_track, 20)      
        PWMServo.setServo(2, servo2_face_track, 20)
    elif command == "down" and servo1_face_track <= 1780: //向下转动
        key = 0
        servo1_face_track = servo1_face_track + 20
        PWMServo.setServo(1, servo1_face_track, 20)
        PWMServo.setServo(2, servo2_face_track, 20)
    elif command == "left" and servo2_face_track <= 2480: //向左转动
        key = 0
        servo2_face_track = servo2_face_track + 20
        PWMServo.setServo(1, servo1_face_track, 20)
        PWMServo.setServo(2, servo2_face_track, 20)
    elif command == "right" and servo2_face_track >= 520: //向右转动
        key = 0
        servo2_face_track = servo2_face_track - 20
        PWMServo.setServo(1, servo1_face_track, 20)
        PWMServo.setServo(2, servo2_face_track, 20)
将摄像头捕捉到的画面回传给手机端APP
    HOST = '10.134.184.98'
    PORT = 5051
    WIDTH = 320
    HEIGHT = 240
    server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)  # enable broadcast
    server.connect((HOST, PORT))
    print('now starting to send frames...')
    try:
        image = frame
        frameOpencvDnn = cv2.resize(frame, (160, 120), interpolation=cv2.INTER_CUBIC)

        frameHeight = frameOpencvDnn.shape[0]
        frameWidth = frameOpencvDnn.shape[1]

        blob = cv2.dnn.blobFromImage(frameOpencvDnn, 1, (150, 150), [104, 117, 123], False,                 False)
        result, imgencode = cv2.imencode('.jpg', image, [cv2.IMWRITE_JPEG_QUALITY, 60])
        # print(len(imgencode))
        print(key)
        server.sendall(imgencode)
手机端接收回传的画面
public void startReceiveThread(){
        new Thread(){
            @Override
            public void run() {
                try{
                    ss=new DatagramSocket(5051);
//                    ss.setSoTimeout(1);
                    while(true) {
//                        Message message=new Message();
//                        message.what=1;
//                        message.obj=R.drawable.touxiang;
//                        updateUIHandler.sendMessage(message);
                        byte[] data = new byte[65536];
                        DatagramPacket packet = new DatagramPacket(data, data.length);

                        ss.receive(packet);
                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, packet.getLength());
                        Message message=new Message();
                        message.what=1;
                        message.obj=bitmap;
                        updateUIHandler.sendMessage(message);
//                        sendFrameToActivity(bitmap);
                    }
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    public static final int TOAST_TEXT=1;
    public static final int CLOSE_OR_SHUTDOWN=2;
    public static final int UPDATE_IMAGEVIEW=3;
    @SuppressLint("HandlerLeak")
    public static Handler updateUIHandler= new Handler(Looper.myLooper()){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case 1:
                    ((OpenActivity)context).imgView.setImageBitmap((Bitmap)msg.obj);
                    break;

                default:
                    break;
            }
        }
    };
    public void sendFrameToActivity(Bitmap bitmap){
        Message message=new Message();
        message.what=OpenActivity.UPDATE_IMAGEVIEW;
        message.obj=bitmap;
        updateUIHandler.sendMessage(message);
    }

实现效果

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值