搜索
首页微信小程序小程序开发微信小程序--树莓派(raspberry pi)小车控制的代码流程

目录

1. 基本思路

2. 代码结构如下:

3. index目录

4. control目录 

5. 工程全局控制

主要练习了一下微信小程序的开发。这里简单记录一下主要代码片段。也是趟过了许多的坑,例如:微信小程序不支持完全全屏,微信小程序不能横屏展示。所以开发过程中也用了一些非常手段。可以说这只是一个很基本的demo,所以里面很多东西,比如摄像头监控ip、页面元素定位我都使用了写死的值。特别是界面,我只是在iPhone 6上面做的实验,所以换到其他手机上时,界面就会变型了。

1. 基本思路

  • 进入小程序时展示index页,可以让用户输入服务端url(模拟上一篇中在浏览器获取get请求)

  • 然后跳转到实际的小车控制界面,并可以通过点击按钮实现小车控制

  • 控制小车的移动,主要是在control.js中定义了界面按钮事件的响应,在响应事件的过程中实现http请求的发送

index页面如下: 

1.png

进去之后的页面如下(其中中间空白处会展示摄像头监控,不过我并没有启动,所以看不见):

1.png

2. 代码结构如下:

其中,index下面是首页,control是控制页面,res目录下存放的是图片资源

1.png

3. index目录

  • index.js

//index.js
//获取应用实例
const app = getApp()

Page({
  data: {
    logo: "/res/rasp-logo.png",
    welcome: "欢迎使用树莓小车",
    enterBtn: "进入",
    PromoteMsg: "Please enter the server address (eg: http://x.x.x.x:8080)",
    reqURL: ""
  },
  // 从输入框中获取用户输入的服务器地址信息
  getURL: function (e) {
    this.setData({
      reqURL: e.detail.value
    })
  },
  enterClicked: function (e) {
    /*
     * 当按下进入按钮,需要做以下事情:
     * 1. 首先判断用户是否已经在输入框中输入完整的服务器地址
     * 2. 发起一个到服务器的GET请求,并分析服务器的响应结果
     * 3. 跳转到小车控制界面
    */
    console.log(this.data.reqURL)

    if (this.data.reqURL == '') {
      wx.showModal({
        title: '提示',
        content: '请先输入正确的服务器地址!',
      })
      return
    }

    // 发起到服务器的GET请求
    wx.request({
      url: this.data.reqURL,
      success: function (res) {
        // 在这里获取POST请求地址,以及视频流地址,然后赋值给全局变量,供control页面调用
        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]

        // 跳转到control页面
        wx.navigateTo({
          url: '/pages/control/control',
        })
      },
      fail: function(res) {
        wx.showModal({
          title: '提示',
          content: '请检查输入的服务器地址!',
        })
      }
    })
  }
})
  • index.json:无数据,只有一对打括号

  • 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=&#39;1&#39; cursor=&#39;10&#39; confirm-type="done" bindinput=&#39;getURL&#39;></input>
  <button class=&#39;enter&#39; bindtap=&#39;enterClicked&#39;>{{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({

  /**
   * 页面的初始数据
   */
  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) {

      }
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  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)
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
  
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    //console.log(wx.getSystemInfoSync().windowWidth)
    //console.log(wx.getSystemInfoSync().windowHeight)
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
  
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
  
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
  
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
  
  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {
  
  }
})
  • control.json

{
  "navigationBarBackgroundColor": "#ffffff",
  "navigationBarTextStyle": "black",
  "navigationBarTitleText": "树莓小车",
  "backgroundColor": "#eeeeee",
  "backgroundTextStyle": "light",
  "enablePullDownRefresh": false,
  "navigationStyle": "custom",
  "disableScroll": true
}
  • control.wxml

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

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

  <!-- The following images control the camera move  -->
  <image class=&#39;button&#39; id=&#39;up&#39; src=&#39;{{upBtn}}&#39; style="position:absolute;z-index:2" bindtouchstart=&#39;camMove&#39; data-direction=&#39;VU&#39;></image>
  <image class=&#39;button&#39; id=&#39;camLeft&#39; src=&#39;{{camLeftBtn}}&#39; style="position:absolute;z-index:2" bindtouchstart=&#39;camMove&#39; data-direction=&#39;HL&#39;></image>
  <image class=&#39;button&#39; id=&#39;camRight&#39; src=&#39;{{camRightBtn}}&#39; style="position:absolute;z-index:2" bindtouchstart=&#39;camMove&#39; data-direction=&#39;HR&#39;></image>
  <image class=&#39;button&#39; id=&#39;down&#39; src=&#39;{{downBtn}}&#39; style="position:absolute;z-index:2" bindtouchstart=&#39;camMove&#39; data-direction=&#39;VD&#39;></image>
  <image class=&#39;button&#39; id=&#39;reset&#39; src=&#39;{{resetBtn}}&#39; style="position:absolute;z-index:2" bindtouchstart=&#39;camMove&#39; data-direction=&#39;RESET&#39;></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:实际似乎并没有用到,里面都是工程创建时的默认代码

//app.js
App({
  onLaunch: function () {
    // 展示本地存储能力
    var logs = wx.getStorageSync(&#39;logs&#39;) || []
    logs.unshift(Date.now())
    wx.setStorageSync(&#39;logs&#39;, logs)

    // 登录
    wx.login({
      success: res => {
        // 发送 res.code 到后台换取 openId, sessionKey, unionId
      }
    })
    // 获取用户信息
    wx.getSetting({
      success: res => {
        if (res.authSetting[&#39;scope.userInfo&#39;]) {
          // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
          wx.getUserInfo({
            success: res => {
              // 可以将 res 发送给后台解码出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是网络请求,可能会在 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": "树莓小车",
    "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": "项目配置文件。",
	"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": []
		}
	}
}

相关推荐:

树莓派(Raspberry Pi,RPi)的详细介绍

用树莓派实现对话机器人_PHP教程

以上是微信小程序--树莓派(raspberry pi)小车控制的代码流程的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。