ESP8266_AP机械手 第三篇Uniapp遥控器
一、接口说明
以下是ardunio上需要请求ap-server的接口:
if (request.indexOf("/getLocalIp") != -1) {handleGetLocalIp(client);} else if (request.indexOf("/servoPosition") != -1) {handleServoPosition(client);} else if (request.indexOf("/servoStep") != -1) {showServoStep(client);} else if (request.indexOf("/servoControlStep") != -1) {handleServoStep(client);} else if (request.indexOf("/servo1UpMove") != -1) {handleServoUpMove(client, 0);} else if (request.indexOf("/servo2UpMove") != -1) {handleServoUpMove(client, 1);} else if (request.indexOf("/servo3UpMove") != -1) {handleServoUpMove(client, 2);} else if (request.indexOf("/servo4UpMove") != -1) {handleServoUpMove(client, 3);} else if (request.indexOf("/servo5UpMove") != -1) {handleServoUpMove(client, 4);} else if (request.indexOf("/servo1DownMove") != -1) {handleServoDownMove(client, 0);} else if (request.indexOf("/servo2DownMove") != -1) {handleServoDownMove(client, 1);} else if (request.indexOf("/servo3DownMove") != -1) {handleServoDownMove(client, 2);} else if (request.indexOf("/servo4DownMove") != -1) {handleServoDownMove(client, 3);} else if (request.indexOf("/servo5DownMove") != -1) {handleServoDownMove(client, 4);} else {handleNotFound(client);}
1.1 /getLocalIp
通过input 和 button 手动测试 uniapp 与 esp8266 连通情况。
1.2 /servoPosition和 /servoStep
获取五个机械手关节舵机的位置 和 移动步长 需要设置定时器,类似于js 的ajax异步请求 刷新特定div或view的数据
1.3 /servoControlStep
设置舵机的步长,采用button简单的请求并将请求渲染到页面
1.4 /servo1UpMove 至 /servo5DownMove
依据全局变量stepSize设置舵机的正转和反转
二、index页面
<template><view class="content"><view class="input-localIp"><view class="title">1、绑定服务</view><input v-model="serverIp" class="uni-input" focus placeholder="请输入ESP8266服务器IP" @input="saveServerIp" /></view><view><button class="btn" @click="getLocalIp">2、获取连接</button></view><view class="getlocalIpShow"><view class="line"></view><view class="title">3、连接判断</view><!-- 显示本地IP -->{{ localIp }}</view><view class="goToControlPage"><button class="btn" @click="goToControlPage">4、舵机控制</button></view></view>
</template><script setup>import {ref,onMounted} from 'vue';// 创建响应式变量来存储 IP 地址const localIp = ref('');const serverIp = ref('');// 页面加载完成后读取 uni-app 存储中的 IPonMounted(() => {uni.getStorage({key: 'serverIp',success(res) {if (res.data) {serverIp.value = res.data;}},fail() {// 如果没有存储 IP 地址,可以给出默认值serverIp.value = '';}});});// 当输入框内容变化时保存到 uni-app 存储const saveServerIp = () => {if (serverIp.value) {uni.setStorage({key: 'serverIp',data: serverIp.value,success() {console.log('IP 地址已保存');},fail() {console.error('保存失败');}});}};// 获取本地 IP 地址的请求const getLocalIp = () => {if (serverIp.value) {const requestUrl = 'http://' + serverIp.value + '/getLocalIp'; // 组装请求的 URLconsole.log('请求的 URL: ', requestUrl); // 打印 URLuni.request({url: requestUrl, // 使用已拼接的 URLmethod: 'GET',success(res) {if (res.statusCode === 200) {localIp.value = res.data; // 获取到的 IP 地址console.log('localIp: ', res)} else {localIp.value = '获取失败';}},fail() {localIp.value = '请求失败';}});} else {localIp.value = '请先输入服务器IP';}};//goToControlPageconst goToControlPage = () => {// 使用 uni.navigateTo 跳转到舵机控制页面uni.navigateTo({url: '/pages/control/control' // 这里的路径要根据实际页面路径来调整});}
</script><style lang="scss">.uni-input {border: 1rpx solid #000;/* 设置边框颜色 */width: 100%;/* 让输入框宽度占满父容器 */padding: 10rpx;border-radius: 5rpx;/* 添加圆角 */}.line {margin-bottom: 10rpx;/* 设置行间距 */border-bottom: 1rpx solid #ddd;/* 添加分隔线 */}.title {font-size: 24rpx;color: #333;margin-bottom: 5rpx;}.content {padding: 20rpx;}.btn {margin-top: 20rpx;padding: 6rpx 12rpx;/* 调整按钮的内边距使按钮更小 */background-color: white;/* 设置背景色为白色 */color: black;/* 设置文字颜色为黑色 */border: 1rpx solid #000;/* 设置边框颜色 */border-radius: 5rpx;/* 添加圆角 */width: auto;/* 设置按钮宽度为自动 */font-size: 24rpx;/* 设置字体大小 */text-align: center;}
</style>
三、control页面
<template><view class="content"><view class="goToIndexPage"><button class="btn" @click="goToIndexPage">1、回到首页</button></view><view class="servoPosition"><view class="title">2、当前各舵机位置[500,2500]</view><view class="servo1">A => {{ servoPositions[0] }}</view><view class="servo2">B => {{ servoPositions[1] }}</view><view class="servo3">C => {{ servoPositions[2] }}</view><view class="servo4">D => {{ servoPositions[3] }}</view><view class="servo5">E => {{ servoPositions[4] }}</view></view><view class="servoStep"><view class="title">3、当前控制舵机的步长</view><view v-if="servoStep !== null" class="title">{{ servoStep }}</view><view v-else class="title">加载步长数据中...</view></view><view><button class="btn" @click="handleServoStep">4、调整步长</button><view class="servoStepShow">{{ servoStepResult }}</view></view><view class="servoControls"><!-- 生成控制按钮及响应内容 --><view v-for="(servo, index) in [1, 2, 3, 4, 5]" :key="index" class="servoRow"><button class="btn" @click="moveServoUp(index)">Servo {{ index + 1}} 上升</button><button class="btn" @click="moveServoDown(index)">Servo {{ index + 1}} 下降</button><view class="response">{{ servoResponses[index - 1] }}</view></view></view></view>
</template><script setup>import { ref, onMounted } from 'vue';const serverIp = ref('');const servoPositions = ref([0, 0, 0, 0, 0]); // 存储舵机位置const servoStep = ref(null); // 存储步长const servoStepResult = ref('');const servoResponses = ref(["", "", "", "", ""]); // 存储每个舵机的响应内容// 页面加载时读取 IP 地址onMounted(() => {uni.getStorage({key: 'serverIp',success(res) {if (res.data) {serverIp.value = res.data;startRequest(); // 启动请求}},fail() {serverIp.value = '';}});});// 定时请求接口并更新舵机位置和步长const startRequest = () => {const positionUrl = 'http://' + serverIp.value + '/servoPosition';const stepUrl = 'http://' + serverIp.value + '/servoStep';// 定时获取舵机位置setInterval(() => {uni.request({url: positionUrl,method: 'GET',success(res) {if (res.data && Array.isArray(res.data)) {servoPositions.value = res.data;}},fail() {console.error('请求舵机位置失败');}});}, 500); // 每120秒请求一次舵机位置 - 500 500微秒// 定时获取步长数据setInterval(() => {uni.request({url: stepUrl,method: 'GET',success(res) {if (res.data && Array.isArray(res.data)) {servoStep.value = res.data[0]; }},fail() {console.error('请求步长失败');}});}, 10000); // 每120秒120000请求一次步长 - 10000 10秒};// 控制舵机上升const moveServoUp = (index) => {index = index + 1if (serverIp.value) {const requestUrl = 'http://' + serverIp.value + '/servo' + index + 'UpMove';console.log('requestUrl: ', requestUrl)uni.request({url: requestUrl,method: 'GET',success(res) {if (res.statusCode === 200) {servoResponses.value[index - 1] = res.data;} else {servoResponses.value[index - 1] = res.data;}clearResponse(index - 1);},fail() {servoResponses.value[index - 1] = '请求失败';clearResponse(index - 1);}});}};// 控制舵机下降const moveServoDown = (index) => {index = index + 1if (serverIp.value) {const requestUrl = 'http://' + serverIp.value + '/servo' + index + 'DownMove';console.log('requestUrl: ', requestUrl)uni.request({url: requestUrl,method: 'GET',success(res) {if (res.statusCode === 200) {servoResponses.value[index - 1] = res.data;} else {servoResponses.value[index - 1] = res.data;}clearResponse(index - 1);},fail() {servoResponses.value[index - 1] = '请求失败';clearResponse(index - 1);}});}};// 清空响应内容const clearResponse = (index) => {setTimeout(() => {servoResponses.value[index] = '';}, 200); // 5000微秒后清空响应-200 200微秒};// 调整步长const handleServoStep = () => {if (serverIp.value) {const requestUrl = 'http://' + serverIp.value + '/servoControlStep';uni.request({url: requestUrl,method: 'GET',success(res) {if (res.statusCode === 200 && res.data) {const dataString = res.data.replace(/[^\w\s=>:]/g, '').trim();servoStepResult.value = dataString;} else {servoStepResult.value = '获取失败';}},fail() {servoStepResult.value = '请求失败';}});} else {servoStepResult.value = '请先输入服务器IP';}};// 返回首页const goToIndexPage = () => {uni.navigateTo({url: '/pages/index/index'});};
</script><style lang="scss">.line {margin-bottom: 10rpx;border-bottom: 1rpx solid #ddd;}.title {font-size: 24rpx;color: #333;margin-bottom: 5rpx;}.content {padding: 20rpx;}.btn {margin-top: 20rpx;padding: 6rpx 12rpx;background-color: white;color: black;border: 1rpx solid #000;border-radius: 5rpx;width: auto;font-size: 24rpx;text-align: center;}.servoPosition {margin-top: 20rpx;}.servo1,.servo2,.servo3,.servo4,.servo5 {margin-bottom: 10rpx;font-size: 24rpx;}.servoStep {margin-top: 24rpx;}.servoStepShow {font-size: 24rpx;color: #333;}.servoControls {margin-top: 30rpx;}.servoRow {display: flex;justify-content: space-between;margin-bottom: 15rpx;}.response {margin-left: 0rpx;font-size: 20rpx;color: green;}
</style>
四、演示
-------------------------
通过网盘分享的文件:ESP8266_AP模式Uniapp代码
链接: https://pan.baidu.com/s/1R465EqLF2cMDWsRfQA3IjA?pwd=xp71 提取码: xp71
-------------------------
视频演示如何使用fiddler抓取uniapp请求包
ESP8266_AP机械手-第三篇Uniapp遥控器_哔哩哔哩_bilibili