ESP12F自动配网并连接服务器实现舵机控制(解决速度问题)

5 篇文章 0 订阅
2 篇文章 0 订阅

废话不多说,直接上代码,这里调用的包是需要提前引入(见后文)的,否则会报错。
网盘链接:WIFImaneger
提取码:wifi

/**********************************************************************
项目:WIFI开关(终端)
功能:自动配网,接受命令/发送数据
@author mansuosuo
***********************************************************************/
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> 
#include <Servo.h>

// 建立WiFi客户端对象,对象名称client
WiFiClient client; 
//连接服务器参数
const String HOST = "192.168.2.136";
const int PORT = 8000;
//舵机参数
Servo myservo;  //创建一个舵机控制对象
const int SERVO_PIN = 4; //对应D2
int pos = 0;    // 该变量用与存储舵机角度位置
//串口接受数据
String inputString;

 
void setup() {
  
  // 初始化串口设置
  Serial.begin(9600);
 
  // 建立WiFiManager对象
  WiFiManager wifiManager;

  // 自身WiFi。以下语句的参数是连接ESP8266时的WiFi名称,供首次设置连接
  // wifiManager.autoConnect("^_^WIFI UPDATE01", "12345678");
  wifiManager.autoConnect("^_^WIFI UPDATE01");
   
}
 
void loop() {  
  // 调用函数
  wifiClientRequest();  
  delay(60000);
}

// 请求并连接到服务器
void wifiClientRequest(){   
 
  // 建立字符串,用于HTTP请求
  String httpRequest =  "ADD::CL001";
  
 
  // 连接网络服务器
  if (client.connect(HOST, PORT)){ 
   
    client.print(httpRequest);          // 向服务器发送HTTP请求
       
    // 通过串口输出网络服务器响应信息  
    while (client.connected() || client.available()){ 
      readDataFromServer();
    }
    
    client.stop();                      // 断开与服务器的连接
    Serial.print("Disconnected from "); // 并且通过串口输出断开连接信息
    Serial.print(HOST);
    
  } else{    // 如果连接不成功则通过串口输出“连接失败”信息
    Serial.println(" connection failed!");
    client.stop();
  }  
}

//接受服务器数据并响应
void readDataFromServer(){
  while(client.available()){
    if (client.read()=='G'){
  
      char a = client.read();
      Serial.print(a);
  
      int inNum = (a-48)*20;
//      String s = client.readString();
//      Serial.print(s);
//      int inNum = s.toInt();
//      int inNum = client.parseInt();  
      Serial.print("inNum = ");Serial.println(inNum);
      servoGo(inNum);
      client.print("OK");
    }
    delayMicroseconds(5000);  //延时等待下一个数据接收到(单位1ms)
  }
}

//get缓冲区事件
void readDataFromSerial(){
  inputString=""; //清空接收的数据
  while(Serial.available()>0){
    char inChar = (char)Serial.read();  //每次读取一个字节
    if(inChar=='G'){
      int inNum = Serial.parseInt();  //每次读取一个字节
      servoGo(inNum);
    }
    delayMicroseconds(5000);  //延时等待下一个数据接收到(单位1ms)
    inputString +=inChar;  //将接收的字节拼接到字符串
  }
}


//舵机运行到指定位置
void servoGo(int n){
  myservo.attach(SERVO_PIN);
  int lastNum = myservo.read();
  if(lastNum<n){
    for(pos=lastNum; pos<=n; pos+=1){
      myservo.write(pos);         // 指定舵机转向的角度
      delay(5);                       // 等待15ms让舵机到达指定位置
    }
  }else{
    for(pos=lastNum; pos>=n; pos-=1){
      myservo.write(pos);         // 指定舵机转向的角度
      delay(5);                       // 等待15ms让舵机到达指定位置
    }
  }
  myservo.detach();
}

配网部分的代码不多说了,这里说说接收服务器的数据问题,我尝试使用readString()方法接入数据,这样读取一个字符串String,也方便我们转换类型,但是问题来了,这个读取速度及其低效,根本实现不了实时控制,几乎收到一条数据需要1.5秒以上。原因就是这里读取的时候是按位读取的ASC码,那么怎末读取比较快呢,当然是直接用read()方法读取,读到的是ASCII码,我这里控制的是9g小舵机,其灵敏度比较低,我在控制的时候间隔为20度就行了,所以直接使用ASCII码做乘法,如果是复杂数据,其实这里可以自己写一个方法:循环按位读取,再将char数组转字符串,也比原来的读取快的多,至于如何类型转换,看下这个不要太简单,主要是两个方法:
1.String类的toCharArray()方法,将字符串转为字符(char)数组

String ss=“abc”;
char[] cc;
cc=ss.toCharArray();

这时cc={‘a’,‘b’,‘c’};

2.String类的valueOf()方法,将字符(char)数组转换为字符串

char[] cc={‘a’,‘b’,‘c’};
ss=String.valueOf(cc);

这时ss=“abc”;

3.字符串转为int使用toInt()方法:

String my_str = "123";
int my_int = my_str.toInt();

如果你看不懂部分代码,那么你需要先了解一下WIFIClient下面的库函数,他们有不同的作用;
我这里放一张图(不是我做的,推荐:https://www.cnblogs.com/liming19680104/p/11227742.html)
在这里插入图片描述

最后,把ASC码表也发一下:
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值