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 存储中的 IP
	onMounted(() => {
		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'; // 组装请求的 URL
			console.log('请求的 URL: ', requestUrl); // 打印 URL
			uni.request({
				url: requestUrl, // 使用已拼接的 URL
				method: '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';
		}
	};

	//goToControlPage
	const 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 + 1
		if (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 + 1
		if (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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值