溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

微信小程序之樹(shù)莓派raspberry pi控制的示例分析

發(fā)布時(shí)間:2021-01-30 09:48:22 來(lái)源:億速云 閱讀:390 作者:小新 欄目:移動(dòng)開(kāi)發(fā)

小編給大家分享一下微信小程序之樹(shù)莓派raspberry pi控制的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

1. 基本思路

  • 進(jìn)入小程序時(shí)展示index頁(yè),可以讓用戶輸入服務(wù)端url(模擬上一篇中在瀏覽器獲取get請(qǐng)求)

  • 然后跳轉(zhuǎn)到實(shí)際的小車控制界面,并可以通過(guò)點(diǎn)擊按鈕實(shí)現(xiàn)小車控制

  • 控制小車的移動(dòng),主要是在control.js中定義了界面按鈕事件的響應(yīng),在響應(yīng)事件的過(guò)程中實(shí)現(xiàn)http請(qǐng)求的發(fā)送

index頁(yè)面如下:

微信小程序之樹(shù)莓派raspberry pi控制的示例分析

進(jìn)去之后的頁(yè)面如下(其中中間空白處會(huì)展示攝像頭監(jiān)控,不過(guò)我并沒(méi)有啟動(dòng),所以看不見(jiàn)):

微信小程序之樹(shù)莓派raspberry pi控制的示例分析

2. 代碼結(jié)構(gòu)如下:

其中,index下面是首頁(yè),control是控制頁(yè)面,res目錄下存放的是圖片資源

微信小程序之樹(shù)莓派raspberry pi控制的示例分析

3. index目錄

  • index.js

//index.js
//獲取應(yīng)用實(shí)例
const app = getApp()

Page({
  data: {
    logo: "/res/rasp-logo.png",
    welcome: "歡迎使用樹(shù)莓小車",
    enterBtn: "進(jìn)入",
    PromoteMsg: "Please enter the server address (eg: http://x.x.x.x:8080)",
    reqURL: ""
  },
  // 從輸入框中獲取用戶輸入的服務(wù)器地址信息
  getURL: function (e) {
    this.setData({
      reqURL: e.detail.value
    })
  },
  enterClicked: function (e) {
    /*
     * 當(dāng)按下進(jìn)入按鈕,需要做以下事情:
     * 1. 首先判斷用戶是否已經(jīng)在輸入框中輸入完整的服務(wù)器地址
     * 2. 發(fā)起一個(gè)到服務(wù)器的GET請(qǐng)求,并分析服務(wù)器的響應(yīng)結(jié)果
     * 3. 跳轉(zhuǎn)到小車控制界面
    */
    console.log(this.data.reqURL)

    if (this.data.reqURL == '') {
      wx.showModal({
        title: '提示',
        content: '請(qǐng)先輸入正確的服務(wù)器地址!',
      })
      return
    }

    // 發(fā)起到服務(wù)器的GET請(qǐng)求
    wx.request({
      url: this.data.reqURL,
      success: function (res) {
        // 在這里獲取POST請(qǐng)求地址,以及視頻流地址,然后賦值給全局變量,供control頁(yè)面調(diào)用
        console.log(res.data.match(/url = \"(\S*)\"/)[1])
        console.log(res.data.match(/src=\"(\S*)\"/)[1])
        app.globalData.postURL = res.data.match(/url = \"(\S*)\"/)[1]
        app.globalData.cameraURL = res.data.match(/src=\"(\S*)\"/)[1]

        // 跳轉(zhuǎn)到control頁(yè)面
        wx.navigateTo({
          url: '/pages/control/control',
        })
      },
      fail: function(res) {
        wx.showModal({
          title: '提示',
          content: '請(qǐng)檢查輸入的服務(wù)器地址!',
        })
      }
    })
  }
})
  • index.json:無(wú)數(shù)據(jù),只有一對(duì)打括號(hào)

  • index.wxml

<!--index.wxml-->
<view>
  <view class="welcome">
    <view class="logo">
      <image style="width: 250rpx; height: 250rpx" src="{{logo}}"></image>
    </view>
    <view>
      <text class="words">{{welcome}}</text>
    </view>
  </view>

  <input class="requestURL" type="text" placeholder="{{PromoteMsg}}" focus='1' cursor='10' confirm-type="done" bindinput='getURL'></input>
  <button class='enter' bindtap='enterClicked'>{{enterBtn}}</button>
</view>
  • index.wxss

/**index.wxss**/
.welcome{
  display: flex;
  margin-top: 50rpx;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
}

.requestURL{
  margin: 50rpx 10rpx 30rpx 10rpx;
  border: 1px solid gray;
  font-style: italic;
  font-size: small
}

.enter{
  margin-right: 10rpx;
  width: 150rpx;
  height: 60rpx;
  font-size: small
}

4. control目錄

  • control.js

// pages/control/control.js
const app = getApp()

Page({

  /**
   * 頁(yè)面的初始數(shù)據(jù)
   */
  data: {
    // Car control images
    "forwardBtn": "/res/forward.png",
    "leftBtn": "/res/left.png",
    "rightBtn": "/res/right.png",
    "backLeftBtn": "/res/back-left.png",
    "backRightBtn": "/res/back-right.png",
    "backBtn": "/res/backward.png",

    // Camera control images
    "upBtn": "/res/forward.png",
    "camLeftBtn": "/res/camLeft.png",
    "camRightBtn": "/res/camRight.png",
    "downBtn": "/res/backward.png",
    "resetBtn": "/res/reset.png"
  },

  carMove: function(event) {
    wx.request({
      url: this.data.postURL,
      data: event.currentTarget.dataset.direction,
      method: "POST",
      success: function(res){

      },
      fail: function(res){
        
      }
    })
  },

  carStop: function(event) {
    wx.request({
      url: this.data.postURL,
      data: "S",
      method: "POST",
      success: function (res) {

      },
      fail: function (res) {

      }
    })
  },

  camMove: function(event) {
    wx.request({
      url: this.data.postURL,
      data: event.currentTarget.dataset.direction,
      method: "POST",
      success: function (res) {

      },
      fail: function (res) {

      }
    })
  },

  /**
   * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面加載
   */
  onLoad: function (options) {
    //this.data.cameraURL = app.globalData.cameraURL
    this.setData({
      cameraURL: app.globalData.cameraURL,
      postURL: app.globalData.postURL
    })
    console.log(this.data.cameraURL)
    console.log("post url in control page: " + app.globalData.postURL)
  },

  /**
   * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面初次渲染完成
   */
  onReady: function () {
  
  },

  /**
   * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面顯示
   */
  onShow: function () {
    //console.log(wx.getSystemInfoSync().windowWidth)
    //console.log(wx.getSystemInfoSync().windowHeight)
  },

  /**
   * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面隱藏
   */
  onHide: function () {
  
  },

  /**
   * 生命周期函數(shù)--監(jiān)聽(tīng)頁(yè)面卸載
   */
  onUnload: function () {
  
  },

  /**
   * 頁(yè)面相關(guān)事件處理函數(shù)--監(jiān)聽(tīng)用戶下拉動(dòng)作
   */
  onPullDownRefresh: function () {
  
  },

  /**
   * 頁(yè)面上拉觸底事件的處理函數(shù)
   */
  onReachBottom: function () {
  
  },

  /**
   * 用戶點(diǎn)擊右上角分享
   */
  onShareAppMessage: function () {
  
  }
})
  • control.json

{
  "navigationBarBackgroundColor": "#ffffff",
  "navigationBarTextStyle": "black",
  "navigationBarTitleText": "樹(shù)莓小車",
  "backgroundColor": "#eeeeee",
  "backgroundTextStyle": "light",
  "enablePullDownRefresh": false,
  "navigationStyle": "custom",
  "disableScroll": true
}
  • control.wxml

<!--pages/control/control.wxml-->
<view class='control'>
  <!-- This image shows the camera view -->
  <image class='cameraView' src='http://192.168.1.104:8080/?action=stream' style="z-index:1"></image>

  <!-- The following six images control the car move  -->
  <image class='button' id='forward' src='{{forwardBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='F' bindtouchend='carStop'></image>
  <image class='button' id='left' src='{{leftBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='L' bindtouchend='carStop'></image>
  <image class='button' id='right' src='{{rightBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='R' bindtouchend='carStop'></image>
  <image class='button' id='backLeft' src='{{backLeftBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='BL' bindtouchend='carStop'></image>
  <image class='button' id='backRight' src='{{backRightBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='BR' bindtouchend='carStop'></image>
  <image class='button' id='back' src='{{backBtn}}' style="position:absolute;z-index:2" bindtouchstart='carMove' data-direction='B' bindtouchend='carStop'></image>

  <!-- The following images control the camera move  -->
  <image class='button' id='up' src='{{upBtn}}' style="position:absolute;z-index:2" bindtouchstart='camMove' data-direction='VU'></image>
  <image class='button' id='camLeft' src='{{camLeftBtn}}' style="position:absolute;z-index:2" bindtouchstart='camMove' data-direction='HL'></image>
  <image class='button' id='camRight' src='{{camRightBtn}}' style="position:absolute;z-index:2" bindtouchstart='camMove' data-direction='HR'></image>
  <image class='button' id='down' src='{{downBtn}}' style="position:absolute;z-index:2" bindtouchstart='camMove' data-direction='VD'></image>
  <image class='button' id='reset' src='{{resetBtn}}' style="position:absolute;z-index:2" bindtouchstart='camMove' data-direction='RESET'></image>
</view>
  • control.wxss

/* pages/control/control.wxss */

.control {
  width: 100%;
  height: 100%;
  transform: rotate(90deg);
  background-color: #eee;
  justify-content: center;
}

.cameraView {
  margin-left: 0px;
  width: 603px;
  height: 375px;
  background-color: #eee;
  justify-content: center;
}

.button {
  height: 60px;
  width: 60px;
  opacity: 0.3;
}

#forward {
  left: 60px;
  top: 135px;
}

#left {
  left: 0px;
  top: 195px;
}

#right {
  left: 120px;
  top: 195px;
}

#backLeft {
  left: 0px;
  top: 255px;
}

#backRight {
  left: 120px;
  top: 255px;
}

#back {
  left: 60px;
  top: 315px;
}

#up {
  left: 480px;
  top: 195px;
}

#camLeft {
  left: 420px;
  top: 255px;
}

#camRight {
  left: 540px;
  top: 255px;
}

#down {
  left: 480px;
  top: 315px;
}

#reset{
  left: 480px;
  top: 135px
}

5. 工程全局控制

  • app.js:實(shí)際似乎并沒(méi)有用到,里面都是工程創(chuàng)建時(shí)的默認(rèn)代碼

//app.js
App({
  onLaunch: function () {
    // 展示本地存儲(chǔ)能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    // 登錄
    wx.login({
      success: res => {
        // 發(fā)送 res.code 到后臺(tái)換取 openId, sessionKey, unionId
      }
    })
    // 獲取用戶信息
    wx.getSetting({
      success: res => {
        if (res.authSetting['scope.userInfo']) {
          // 已經(jīng)授權(quán),可以直接調(diào)用 getUserInfo 獲取頭像昵稱,不會(huì)彈框
          wx.getUserInfo({
            success: res => {
              // 可以將 res 發(fā)送給后臺(tái)解碼出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是網(wǎng)絡(luò)請(qǐng)求,可能會(huì)在 Page.onLoad 之后才返回
              // 所以此處加入 callback 以防止這種情況
              if (this.userInfoReadyCallback) {
                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  globalData: {
    userInfo: null,
    postURL: null,
    cameraURL: null
  }
})
  • app.json:

{
  "pages": [
    "pages/index/index",
    "pages/control/control"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "樹(shù)莓小車",
    "navigationBarTextStyle": "black",
    "showStatusBar": false
  }
}
  • app.wxss:

/**app.wxss**/
.container {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 200rpx 0;
  box-sizing: border-box;
}
  • project.control.json:

{
	"description": "項(xiàng)目配置文件。",
	"packOptions": {
		"ignore": []
	},
	"setting": {
		"urlCheck": false,
		"es6": true,
		"postcss": true,
		"minified": true,
		"newFeature": true
	},
	"compileType": "miniprogram",
	"libVersion": "2.0.4",
	"appid": "wx18414b9f85bfc895",
	"projectname": "wechat-control",
	"isGameTourist": false,
	"condition": {
		"search": {
			"current": -1,
			"list": []
		},
		"conversation": {
			"current": -1,
			"list": []
		},
		"game": {
			"currentL": -1,
			"list": []
		},
		"miniprogram": {
			"current": -1,
			"list": []
		}
	}
}

看完了這篇文章,相信你對(duì)“微信小程序之樹(shù)莓派raspberry pi控制的示例分析”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI