ARDUINO2560+ESP8266 控制小车

1.主控板是ARDUINO2560,主要控制全向轮的运动,与ESP8266交互.引脚图如下:ESP8266接的是串口三。加5V供电

三个全向轮电机使用了PWM引脚2--10,分别控制使能,方向,脉冲

主要底层函数ARDUINO

ARDUINO2560+ESP8266 控制小车

#include "motor.h"
#define DEBUG true
#define ESP8266Serail Serial3 
int LED = 13; //LED指示灯引脚
void setup() {
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);
  motor_init();
  Serial.begin(9600);
  ESP8266Serail.begin(9600); //esp8266波特率 
  sendCommand("AT+RST\r\n",2000,DEBUG); // 复位 
  setSTA("BataRobot3","3BataRobot");//连接wifi
  Serial.println("Server Ready");
  digitalWrite(LED, HIGH);//完成连接指示灯
}

void loop() {
if(ESP8266Serail.available()) // 是否接受到数据
  {
    if(ESP8266Serail.find("+IPD,"))
    {
     delay(100); // 等待接收完成 
     int connectionId = ESP8266Serail.read()-48; // subtract 48 because the read() function returns 
     ESP8266Serail.find("CMD:"); // advance cursor to "pin="
     char myCMD= ESP8266Serail.read();
     Serial.println(myCMD);
      String content;

      if(myCMD=='W'||myCMD=='w')//前进
      {
        Forward(200);delay(10);
        content = "Car Forward over ";
      }
      else if(myCMD=='S'||myCMD=='s')//后退
      {
        Back(100);   
        delay(200);
        Stop();
        content = "Car Backward over ";
      }
      else if(myCMD=='D'||myCMD=='d')//右转
      {
        Right(100);  delay(500);
        Stop();
        content = "Car Turn Right over ";
      }
      else if(myCMD=='A'||myCMD=='a')//左转
      {
        Left(100);   delay(500);
        Stop();
        content = "Car Turn Left over ";
      }
      else//停止
      {    
        Stop();
        content = "Car Stop ";
      }
      
     //sendHTTPResponse(connectionId,content);//回复
    }
  }
}
/*
* Name: sendHTTPResponse
* Description: Function that sends HTTP 200, HTML UTF-8 response
*/
void sendHTTPResponse(int connectionId, String content)
{     
     String httpResponse;// build HTTP response
     String httpHeader;
     // HTTP Header
     httpHeader = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n"; 
     httpHeader += "Content-Length: ";
     httpHeader += content.length();
     httpHeader += "\r\n";
     httpResponse = httpHeader + content + "\r\n"; // There is a bug in this code: the last character of "content" is not sent, I cheated by adding this extra space
     sendCIPData(connectionId,httpResponse);
}

/*
* Name: sendCIPDATA
* Description: sends a CIPSEND=<connectionId>,<data> command
*
*/
void sendCIPData(int connectionId, String data)
{
   String cipSend = "AT+CIPSEND=";
   cipSend += connectionId;
   cipSend += ",";
   cipSend +=data.length();
   cipSend +="\r\n";
   sendCommand(cipSend,1000,DEBUG);
   sendData(data,1000,DEBUG);
}


//AP模式
void setAP(String wifi,String passwd)
{
    sendCommand("AT+CWMODE=2\r\n",1000,DEBUG); // 开启 AP 模式
    sendCommand("AT+CWSAP=\""+wifi+"\",\""+passwd+"\",11,0\r\n",3000,DEBUG);
}

//STA模式
void setSTA(String wifi,String passwd)
{
    sendCommand("AT+CWMODE=1\r\n",1000,DEBUG); // 开启 STA 模式
    sendCommand("AT+CWJAP=\""+wifi+"\",\""+passwd+"\"\r\n",3000,DEBUG);
    delay(10000);
    sendCommand("AT+CIFSR\r\n",1000,DEBUG); //查看MAC 和ip
    sendCommand("AT+CIPMUX=1\r\n",1000,DEBUG); // 多设备连接
    sendCommand("AT+CIPSERVER=1,8080\r\n",1000,DEBUG); // 打开服务器
}

/*
 * esp8266发送数据
 * command:AT命令
 * timeout:超时时间
 * debug:是否接受回复
 */
String sendData(String command, const int timeout, boolean debug)
{
    String response = "";
    int dataSize = command.length();
    char data[dataSize];
    command.toCharArray(data,dataSize);
    ESP8266Serail.write(data,dataSize); // send the read character to the esp8266
    if(debug)
    {
      Serial.println("\r\n====== HTTP Response From Arduino ======");
      Serial.write(data,dataSize);
      Serial.println("\r\n========================================");
    }

    long int time = millis();
    while( (time+timeout) > millis())
    {
      while(ESP8266Serail.available())
      {
        char c = ESP8266Serail.read(); // 读取回复
        response+=c;
      }  
    }
    if(debug)
    {
      Serial.print(response);
    }
    return response;
}
/*
 * esp8266发送命令
 * command:AT命令
 * timeout:超时时间
 * debug:是否接受回复
 */
String sendCommand(String command, const int timeout, boolean debug)
{
    String response = "";
    ESP8266Serail.print(command); // send the read character to the esp8266

    long int time = millis();
    while( (time+timeout) > millis())
    {
      while(ESP8266Serail.available())
      {        
        char c = ESP8266Serail.read(); // read the next character.
        response+=c;
      }  
    }

    if(debug)
    {
      Serial.print(response+"\r\n");
    }
    return response;
}

电机控制函数:

#include "motor.h"
#include <Arduino.h>
// MD01电机驱动引脚定义
int M1SLP = 2;
int M1PWM = 3;
int M1DIR = 4;
//MD02电机驱动引脚定义
int M2SLP = 5;
int M2PWM = 6;
int M2DIR = 7;
//MD03电机驱动引脚定义
int M3SLP = 8;
int M3PWM = 9;
int M3DIR = 10;
float Vx, Vy;     //定义正交分解之后的速度
float V1, V2, V3;
void motor_init()
{
    pinMode(M1SLP, OUTPUT);
    pinMode(M1PWM, OUTPUT);
    pinMode(M1DIR, OUTPUT);

    pinMode(M2SLP, OUTPUT);
    pinMode(M2PWM, OUTPUT);
    pinMode(M2DIR, OUTPUT);

    pinMode(M3SLP, OUTPUT);
    pinMode(M3PWM, OUTPUT);
    pinMode(M3DIR, OUTPUT);
}

void Forward(float speed)      //前进,Y轴上下移动
{
    Vy = -speed;

    V1 = -sqrt(3) / 2 * Vy;
    V2 = sqrt(3) / 2 * Vy;
    V3 = 0;
    enableM1();
    digitalWrite(M1DIR, HIGH);
    analogWrite(M1PWM, V1);

    enableM2();
    digitalWrite(M2DIR, LOW);
    analogWrite(M2PWM, -V2);

    analogWrite(M3PWM, V3);
}
void Back(float speed)          //后退,Y轴上下移动
{
    Vy = -speed;
    V1 = -sqrt(3) / 2 * Vy;
    V2 = sqrt(3) / 2 * Vy;
    V3 = 0;
    enableM1();
    digitalWrite(M1DIR, LOW);
    analogWrite(M1PWM, V1);

    enableM2();
    digitalWrite(M2DIR, HIGH);
    analogWrite(M2PWM, -V2);

    analogWrite(M3PWM, V3);
}
void Right(float speed)        //右平移,X轴移动
{
    Vx = speed;
    V1 = -0.5 * Vx;
    V2 = -0.5 * Vx;
    V3 = Vx;
    enableM1();
    digitalWrite(M1DIR, HIGH);
    analogWrite(M1PWM, V1);

    enableM2();
    digitalWrite(M2DIR, HIGH);
    analogWrite(M2PWM, -V2);

    enableM3();
    digitalWrite(M3DIR, LOW);
    analogWrite(M3PWM, V3);
}

void Left(float speed)         //左平移,X轴移动
{
    Vx = speed;
    V1 = -0.5 * Vx;
    V2 = -0.5 * Vx;
    V3 = Vx;

    enableM1();
    digitalWrite(M1DIR, LOW);
    analogWrite(M1PWM, V1);

    enableM2();
    digitalWrite(M2DIR, LOW);
    analogWrite(M2PWM, -V2);

    enableM3();
    digitalWrite(M3DIR, HIGH);
    analogWrite(M3PWM, V3);
}

void Stop()            //停止
{
    disableM1();
    analogWrite(M1PWM, 0);
    disableM2();
    analogWrite(M2PWM, 0);
    disableM3();
    analogWrite(M3PWM, 0);
}

void enableM1() {    //MD01电机驱动使能控制
    digitalWrite(M1SLP, HIGH);
}
void disableM1() {    //MD01电机驱动禁用控制
    digitalWrite(M1SLP, LOW);
}
void enableM2() {    //MD02电机驱动使能控制
    digitalWrite(M2SLP, HIGH);
}
void disableM2() {    //MD02电机驱动禁用控制
    digitalWrite(M2SLP, LOW);
}
void enableM3() {    //MD03电机驱动使能控制
    digitalWrite(M3SLP, HIGH);
}
void disableM3() {    //MD03电机驱动禁用控制
    digitalWrite(M3SLP, LOW);
}

上位机控制程序:TCP 通讯:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;
namespace client
{
    public partial class Form1 : Form
    {
        private Socket clientsocket;
        public string ipaddress = "192.168.0.187";
        public int port = 8080;
        private byte[] data = new byte[1024];//数据容器
        private Thread my_thread;
        public Form1()
        {
            InitializeComponent();
            connecttoserver();
        }
        void OnDestory(object sender, FormClosingEventArgs e)
        {
            //Environment.Exit(0);
            clientsocket.Shutdown(SocketShutdown.Both);
            clientsocket.Close();//关闭连接
        }
        void connecttoserver()
        {
            clientsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //跟服务器连接
            clientsocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress), port));
            my_thread = new Thread(Receivemessage);//开启线程接收消息
            my_thread.Start();
        }
        void snedmessage(string message)
        {
            byte[] data = Encoding.UTF8.GetBytes(message);
            clientsocket.Send(data);
        }
        private void Receivemessage()
        {
            while (true)
            {
                //在接收前判断socket是否断开
                if (clientsocket.Connected ==false)
                {
                    clientsocket.Close();
                    break;
                }
                try
                {
                    int lenght = clientsocket.Receive(data);
                    string message = Encoding.UTF8.GetString(data, 0, lenght);

                    textBox1.BeginInvoke(new Action(() =>
                    {
                        if (textBox1.Lines.Length > 15) textBox1.Text = "";
                        textBox1.Text += "\r\n" + message;//显示消息

                    }));
                }
                catch 
                {
                    clientsocket.Close();
                    break;
                }

            }
        }
        private void button1_Click(object sender, EventArgs e)//发送
        {
            string value = textBox2.Text;
            snedmessage("xjh:"+value);
            textBox2.Text = "";
        }

        private void ForwardBtn_Click(object sender, EventArgs e)//前进
        {
            snedmessage("+IPD,CMD:W" );
        }

        private void BackBtn_Click(object sender, EventArgs e)//后退
        {
            snedmessage("+IPD,CMD:S");
        }

        private void RightBtn_Click(object sender, EventArgs e)//向右
        {
            snedmessage("+IPD,CMD:D");
        }

        private void LeftBtn_Click(object sender, EventArgs e)//向左
        {
            snedmessage("+IPD,CMD:A");
        }
    }
}

 

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chilian12321

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值