Apiccloud + Jetson nano + websocket + OpenCV image transmission APP

catalogue

preface

1, What is apiccloud?

2, Design steps

APP Design

main.html

Wifi_Control.html

 Car_Control.html

jetson nano Python code design  

image_socket.py

  Run code

  Run APICloud APP code

summary


preface

During the summer vacation, I wanted to make a picture transmission APP myself, that is, to display the images taken by the camera on the mobile phone. After consulting the data, I found that apiccloud is very useful, so I studied for half a month and made a simple APP myself. I don't talk much nonsense. Go to the source code link:

Apiccloud + Jetson nano + websocket + OpenCV image transmission APP.rar

Friends in need can download.


1, What is apiccloud?

Apiccloud is a low code development platform for rapid development of enterprise applications with high-performance multi terminal development technology
A set of code generates Android, iOS, applet, Web and other multi terminal applications at the same time, which is very practical.

Download link on the official website: Apiccloud + Jetson nano + websocket + OpenCV image transmission APP.rar


2, Design steps

APP Design

  The designed page can be previewed in real time on the right, which I think is very good.

main.html

<!DOCTYPE html>
  <html>
  <head>
      <meta charset="utf-8">
      <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
      <title>title</title>
      <link rel="stylesheet" type="text/css" href="../css/api.css"/>
      <style>
          header{
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 80px;
                background-color: rgba(132, 134, 252, 0.867); 
          }
          
          header .left{
                position: absolute;
                bottom: 0;
                left: 0;
                width: 60px;
                height: 42px;
          }
          header .left .logo{
                position:absolute;
                bottom: 0;
                left: 0;
                width: 60px;
                height: 42px;
                background-image: url(../image/robot.png);
                background-size: 40px*33px;
                background-position: center center;
                background-repeat: no-repeat;
          }
          header .left .logo_txt{
                position:absolute;
                width: 80px;
                height: 42px;
                padding-left: 60px;
                line-height: 45px;
                font-size: 20px;

          }
          header .center{
                position:absolute;
                width: 100%;
                height: 30px;
                background-color: #000;
          }
          
          framers {
                position:absolute;
                top: 80px;
                left: 0;
                width: 100%;
                bottom: 0;
                background-color: #fff;
                text-align: center;
         }
          framers .Bluetooth_control{
                position:absolute;
                left: 20px;
                top: 20px;
                background-color: #66cbff;
                padding-left: 120px;
                line-height: 45px;
                padding-right: 120px;
                font-size: 20px;
                color: #fff;
                
          }
          framers .Wifi_control{
                  position:absolute;
                left: 20px;
                top: 85px;
                background-color: #66cbff;
                padding-left: 125px;
                line-height: 45px;
                padding-right: 120px;
                font-size: 20px;
                color: #fff;
          }
          framers .user_html{    
               
                height: 20px;   
                font-size: 20px;
                color: #000;
                line-height: 600px;
                text-align: center; 
          }
          framers .user_html_1{
                height: 20px;
                font-size: 20px;
                color: #000;
                text-align: center;
                line-height: 700px; 
          }
          framers .user_txt{
                height: 20px;
                font-size: 20px;
                color: #000;
                text-align: center;
                line-height: 800px; 
          }
          framers .user_txt_1{
                height: 20px;
                font-size: 20px;
                color: #000;
                text-align: center;
                line-height: 900px; 
          }
      </style>
  </head>
  <body>
        <header>
            <div class="left">
                <div class="logo"></div>
                <div class="logo_txt">AlphaBot</div>
            </div>
            <div class="center"></div>
        </header>
        

        <framers>
            <div class="Bluetooth_control" onclick="Bluetooth_control();">Bluetooth control</div>
            <div class="Wifi_control" onclick="Wifi_control();">Wifi control</div>
            <div class="user_html"><u>QQ:3075221401</u></div>
            <div class="user_html_1"><u>CSDN@quiet·No envy</u></div>
            <div class="user_txt"><u>AJJFirstAPP</u></div>
            <div class="user_txt_1"><s></u>my APP It's big. You have to bear it</s></div>
        </framers>
        
        <button type="submit" id="btn_submit"> submit </button>
  </body>
  <script type="text/javascript" src="../script/api.js"></script>
  <script type="text/javascript">
      apiready = function(){
            api.setScreenOrientation({
                  orientation:'auto_portrait'
            });
            api.toast({
                  msg:'Please configure the network connection first!'
            })
      };
      function Bluetooth_control(){
            api.openWin({
                  name: 'Bluetooth_control',
                  url: 'Bluetooth_control.html',
            })
            
      };
      function Wifi_control(){
            api.openWin({
                  name: 'Wifi_control',
                  url: 'Wifi_Control.html',
            })
            
      };
  </script>
  </html>

 

Wifi_Control.html

<!DOCTYPE html>
  <html>
  <head>
      <meta charset="utf-8">
      <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
      <title>title</title>
      <link rel="stylesheet" type="text/css" href="../css/api.css"/>
      <style>
          header{
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 80px;
                background-color: rgba(132, 134, 252, 0.867); 
          }
          
          header .left{
                position: absolute;
                bottom: 0;
                left: 0;
                width: 60px;
                height: 42px;
          }
          header .left .logo{
                position:absolute;
                bottom: 0;
                left: 0;
                width: 60px;
                height: 42px;
                background-image: url(../image/robot.png);
                background-size: 40px*33px;
                background-position: center center;
                background-repeat: no-repeat;
                
          }
          header .left .logo_txt{
                position:absolute;
                width: 80px;
                height: 42px;
                padding-left: 60px;
                line-height: 45px;
                font-size: 20px;
                
                  
          }
          header .center{
                position:absolute;
                width: 100%;
                height: 30px;
                background-color: #000;
          }
          framers {
                position:absolute;
                top: 80px;
                left: 0;
                width: 100%;
                bottom: 0;
                background-color: #fff;
                
         }
          framers .IP_adrress{
                position: absolute;
                left: 20px;
                line-height: 45px;
                font-size: 14px;
                color: #000;
                
          }
          
          framers .control_port{
                position: absolute;
                left: 20px;
                line-height: 205px;
                font-size: 14px;
                color: #000;
          }

          framers .connection{
                position:absolute;
                left: 20px;
                right: 20px;
                top: 200px;
                background-color: #66cbff;
                padding-left: auto;
                line-height: 45px;
                padding-right: auto;
                font-size: 20px;
                text-align: center; 
                color: #fff;
          }
          framers .user_html{    
                height: 20px;   
                font-size: 20px;
                color: #000;
                line-height: 600px;
                text-align: center; 
          }
          framers .user_html_1{
                height: 20px;
                font-size: 20px;
                color: #000;
                text-align: center;
                line-height: 700px; 
          }
          framers .user_txt{
                height: 20px;
                font-size: 20px;
                color: #000;
                text-align: center;
                line-height: 800px; 
          }
          framers .user_txt_1{
                height: 20px;
                font-size: 20px;
                color: #000;
                text-align: center;
                line-height: 900px; 
          }
          
      </style>
  </head>
  <body>
        <header>
            <div class="left">
                <div class="logo"></div>
                <div class="logo_txt">AlphaBot</div>
            </div>
            <div class="center"></div>
        </header>
        
        <style type="text/css">
            framers .IP_adrress input{
                  position: absolute;
                  left: 0px;
                  top: 40px;
                  font-size: 14px;
                  width: 300px;
                  height: 30px;
            }
            framers .control_port input{
                  position: absolute;
                  left: 0px;
                  top: 120px;
                  font-size: 14px;
                  width: 300px;
                  height: 30px;
            }
            </style>
        <framers>
            <div class="IP_adrress" >IP address: <input id="IP" type ="text"  value="192.168.0.102" maxlength="13"></div>
            <div class="control_port">Control port: <input id="port" type ="text" value="8080" maxlength="4"></div>
            <div class="connection" onclick="Connection(host_value,port_value);">connect</div>
            <div class="user_html"><u>QQ:3075221401</u></div>
            <div class="user_html_1"><u>CSDN@quiet·No envy</u></div>
            <div class="user_txt"><u>AJJFirstAPP</u></div>
            <div class="user_txt_1"><s></u>my APP It's big. You have to bear it</s></div>
        </framers>
     
  </body>
  <script type="text/javascript" src="../script/api.js" src="../html/Car_Control.html"></script>
  <script type="text/javascript">
      apiready = function(){
            api.setScreenOrientation({
                  orientation:'portrait_up'
            });
            api.require('socketManager');
      }; 
      var host_value=document.getElementById("IP").value;
      var port_value=document.getElementById("port").value;
      function Connection(host,port)
      {
            ws = new WebSocket("ws://"+host+":"+port);
            ws.onopen =  function (msg) {
                  console.log('webSocket opened');
                  Send('ok');
                  api.setGlobalData({key: 'host',value: host});
                  api.setGlobalData({key: 'port',value: port});
                  ws.close();
                  api.openWin({name: 'Car_Control',url: 'Car_Control.html'})
            };
            ws.onerror = function (error) {
                        console.log('error :' + error.name + error.number);
                        api.toast({msg:'Connection error!'}) 
            };
            ws.onclose =  function () {
                        console.log('webSocket closed');
                        api.toast({msg:'Connection closed!'})  
            };
            // ws.onmessage = function (event) {
            //       let data = JSON.parse(event.data);
            //       if (data.command == "getplans") {f
            //             var planData = data.data;// Returned data
            //             console.log(planData);
            //       } else if (data.command == "getscenes") {
            //                   //Other commands
            //       }
            // }

      
      }
      function Send(content){
            ws.send(content);
      }
      // window.onunload = function(){
      //       ws.close();
      // };
  </script>
  </html>

 

 Car_Control.html

<!DOCTYPE html>
  <html>
  <head>
      <meta charset="utf-8">
      <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/>
      <title>title</title>
      <link rel="stylesheet" type="text/css" href="../css/api.css"/>
      <style>
            
            header{
                        position: absolute;
                        top: 0;
                        left: 0;
                        width: 100%;
                        height: 30px;
                        background-color: #000; 
            }
          
            header .car_state{
                        line-height: 120px;
                        font-size: 20px;
                        text-align:center;
                        color: #66cbff;  
            }
         
            body { 
                  /* transform: rotate(90deg);
                  height: 100vw;
                  width: 100vh;
                  transform-origin: 0% 100%;
                  top: -100vw; */
                  background-color: #fff;
                  
                  }
            lefter{
                  position: absolute;
                  top: 0;
                  left: 0;
                  width: 30px;
                  height: 100%;
                  transform: rotateZ(90);
                  background-color: #000; 
            }
            control{
                  position: absolute;
                  top: 30px;
                  left: 30px;
                  bottom: 0px;
                  width: 345px; 
            }
            control .Forward{
                  position: absolute;
                  top: 80px;
                  left: 120px;
                  width: 70px;
                  height: 70px;
                  background-image: url(../image/106.png);
            }
            control .Backward{
                  position: absolute;
                  top: 220px;
                  left: 120px;
                  width: 70px;
                  height: 70px;
                  background-image: url(../image/109.png);
            }
            control .TurnLeft{
                  position: absolute;
                  top: 150px;
                  left: 30px;
                  width: 70px;
                  height: 70px;
                  background-image: url(../image/102.png);
            }
            control .TurnRight{
                  position: absolute;
                  top: 150px;
                  left: 210px;
                  width: 70px;
                  height: 70px;
                  background-image: url(../image/105.png);
            }
            control .Up{
                  position: absolute;
                  top: 80px;
                  left: 560px;
                  width: 70px;
                  height: 70px;
                  background-image: url(../image/106.png);
            }
            control .Down{
                  position: absolute;
                  top: 220px;
                  left: 560px;
                  width: 70px;
                  height: 70px;
                  background-image: url(../image/109.png);
            }
            control .Left{
                  position: absolute;
                  top: 150px;
                  left: 470px;
                  width: 70px;
                  height: 70px;
                  background-image: url(../image/102.png);
            }
            control .Right{
                  position: absolute;
                  top: 150px;
                  left: 650px;
                  width: 70px;
                  height: 70px;
                  background-image: url(../image/105.png);
            }
         
      </style>
  </head>
  <body>
      
      <header>
            <div class="car_state"id="direction">Stop</div>
            <div class="center"></div>
      </header>
      <lefter></lefter>
      <control>
            <div class="Forward"  id="F"></div>
            <div class="Backward" id="B"></div>
            <div class="TurnLeft" id="TL"></div>
            <div class="TurnRight"id="TR"></div>
            <div class="Up"  id="U"></div>
            <div class="Down" id="D"></div>
            <div class="Left" id="L"></div>
            <div class="Right"id="R"></div>
            <img id="resImg" src="" width="640" height="480"/> <!--Picture display-->
            <iframe id="inner1" src="../html/Wifi_Control.html"></iframe>
      </control>
      

            

        
  </body>
  
  <script type="text/javascript"  src="../script/api.js" src="../html/Wifi_Control.html" ></script>
  <script type="text/javascript">
      apiready = function(){
            api.setScreenOrientation({
                  orientation:'landscape_left'
            });
            api.toast({
                  msg:'Connection succeeded!'
            })           
            api.addEventListener({
            name:'keyback'
            }, function(ret,err){   
            api.setScreenOrientation({
                  orientation:'portrait_up'
                  });
                  api.closeWin();
            });
            host = api.getGlobalData({key: 'host'});
            port = api.getGlobalData({key: 'port'});
            Connection(host,port);

      };
      var Img =  document.getElementById('resImg');
      function Connection(host,port)
      {
            ws = new WebSocket("ws://"+host+":"+port);
            ws.onopen =  function (msg) {
                  console.log('webSocket opened');
                  Send('ok');                 
            };
            ws.onerror = function (error) {
                        console.log('error :' + error.name + error.number);
                        api.toast({msg:'Connection error!'}) 
            };
            ws.onclose =  function () {
                        console.log('webSocket closed');
                        api.toast({msg:'Connection closed!'})  
            };
            ws.onmessage = function (event) {
                  Img.src=event.data;
            }

      
      }
      function Send(content){
            ws.send(content);
      }
      var F =  document.getElementById('F'); 
      F.addEventListener("touchstart",function()
      {
            F.style.backgroundImage='url(../image/107.png)';
            Send('Forward');
      })
      F.addEventListener("touchend",function()
      {
            F.style.backgroundImage='url(../image/106.png)';
            Send('Stop');
      }
      )

      var B =  document.getElementById('B'); 
      B.addEventListener("touchstart",function()
      {
            B.style.backgroundImage='url(../image/108.png)';
            Send('Backward');
      })
      B.addEventListener("touchend",function()
      {
            B.style.backgroundImage='url(../image/109.png)';
            Send('Stop');
      }
      )

      var TL =  document.getElementById('TL'); 
      TL.addEventListener("touchstart",function()
      {
            TL.style.backgroundImage='url(../image/103.png)';
            Send('TurnLeft');
      })
      TL.addEventListener("touchend",function()
      {
            TL.style.backgroundImage='url(../image/102.png)';
            Send('Stop');
      }
      )

      var TR =  document.getElementById('TR'); 
      TR.addEventListener("touchstart",function()
      {
            TR.style.backgroundImage='url(../image/104.png)';
            Send('TurnRight');
      })
      TR.addEventListener("touchend",function()
      {
            TR.style.backgroundImage='url(../image/105.png)';
            Send('Stop');
      }
      )

      var U =  document.getElementById('U'); 
      U.addEventListener("touchstart",function()
      {
            U.style.backgroundImage='url(../image/107.png)';
            Send('Up');
      })
      U.addEventListener("touchend",function()
      {
            U.style.backgroundImage='url(../image/106.png)';
            Send('Stop');
      }
      )

      var D =  document.getElementById('D'); 
      D.addEventListener("touchstart",function()
      {
            D.style.backgroundImage='url(../image/108.png)';
            Send('Down');
      })
      D.addEventListener("touchend",function()
      {
            D.style.backgroundImage='url(../image/109.png)';
            Send('Stop');
      }
      )

      var L =  document.getElementById('L'); 
      L.addEventListener("touchstart",function()
      {
            L.style.backgroundImage='url(../image/103.png)';
            Send('Left');
      })
      L.addEventListener("touchend",function()
      {
            L.style.backgroundImage='url(../image/102.png)';
            Send('Stop');
      }
      )

      var R =  document.getElementById('R'); 
      R.addEventListener("touchstart",function()
      {
            R.style.backgroundImage='url(../image/104.png)';
            Send('Right');
      })
      R.addEventListener("touchend",function()
      {
            R.style.backgroundImage='url(../image/105.png)';
            Send('Stop');
      }
      )
      
      
  </script>
  </html>

 

jetson nano Python code design  

image_socket.py

#! /usr/bin/env python3
# -*- coding: utf-8 -*-

from websocket_server import WebsocketServer
import threading
import cv2
import base64
import time
import subprocess
    
time.sleep(5)
cmd = "hostname -I | cut -d\' \' -f1"
host = subprocess.check_output(cmd,shell = True )
print(host)
              
# Called for every client connecting (after handshake)
def new_client(client, server):
	print("got connection from ",client['address'] )
	# Send to all connections
	server.send_message_to_all("Hey all, a new client has joined us")

# Called for every client disconnecting
def client_left(client, server):
	print("Client disconnected!" )

# Called when a client sends a message
def message_received(client, server, message):
	if len(message) > 200:
		message = message[:200]+'..'
	print("Client(%d) said: %s" % (client['id'], message))
	
	# Send to all connections
	#server.send_message_to_all(message)


def vedio_thread2(n):
    cap = cv2.VideoCapture(0)
    width = 640
    height = 480
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
    while(True):
    	ret, img_bgr = cap.read()
    	if img_bgr is None:
    		print('lose image_value')
    	else:
    		frame = cv2.flip(img_bgr, 1)
    		image = cv2.imencode('.jpg', frame)[1]
    		base64_data = base64.b64encode(image)
    		s = base64_data.decode()
    		#cv2.imshow("video", frame)
    		server.send_message_to_all('data:image/jpeg;base64,%s'%s)
    		cv2.waitKey(50)
    	time.sleep(0.05)


def vedio_thread1(n):
	print('send')
	while True:
		if len(server.clients)>0:
			image = cv2.imencode('.jpg', frame)[1]
			base64_data = base64.b64encode(image)
			s = base64_data.decode()
			#print('data:image/jpeg;base64,%s'%s)
			#server.send_message_to_all('data:image/jpeg;base64,%s'%s)
		time.sleep(0.05)

def from_camera():
	thread1 = threading.Thread(target=vedio_thread1, args=(1,))
	thread1.setDaemon(True)
	thread1.start()
	thread2 = threading.Thread(target=vedio_thread2, args=(1,))
	thread2.setDaemon(True)
	thread2.start()
	print('start')

print('server is running....')
# Server Port
port=8080
# Create Websocket Server
server = WebsocketServer(port,host)
from_camera()
# A device is connected
server.set_fn_new_client(new_client)
# Disconnect
server.set_fn_client_left(client_left)
# Message received
server.set_fn_message_received(message_received)
# Start listening
server.run_forever()



  Run code

  Run APICloud APP code

Download the AppLoader from the mobile phone. The official download link is: AppLoader , connect to the computer through the data cable and start the debugging mode, right-click the project and click USB synchronization

After the project is compiled, the connectable devices will be displayed:

  Click to select a mobile device, and the mobile phone will automatically open AppLoader to enter the APP interface:

Make sure that the nano and the mobile phone are connected to the same network and run image on the nano_ socket.py:

  As can be seen from the figure, the IP address of the nano is 192.168.0.102, and the port in the code is set to 8080

APP click WIFI control, enter the IP address and port, and then click Connect to see the images collected by the nano camera on the mobile APP.

 


summary

Although it took half a month to finish it, I learned a lot this time. Hey hey, the source code has been uploaded to CSDN. Those who have money can hold a money field. Of course, those who want to go whoring can leave an email in the comment area. I'll send it when I'm free.

Tags: Python Linux websocket

Posted on Mon, 18 Oct 2021 13:00:33 -0400 by dink87522