柱头ANDY 发表于 2016-8-26 11:10:43

电机控制及码盘测速

啦啦啦 要来发布测试视频啦~~~~
但仍然存在一些缺陷:1.测速精度低 2.使用时经常会出现停止测速的情况(即Processing上的测速示数停在某个值不动)如下视频所示

http://v.qq.com/x/page/l0323oql47r.html

正常情况
http://v.qq.com/x/page/a0180e8rzlu.html?ref_vid=g0323jmhrax

电机视频
http://v.qq.com/x/page/s0323c2v7i9.html

Arduino code


#include <FlexiTimer2.h>
#define IN1 3
#define IN2 4
#define IN3 5
#define IN4 6
String comdata = "";
int numdata = {0}, mark = 0,dirdata={0};
int PWMPin = {8,9};
//编码器部分
const int interruptA = 0,interruptB = 5;
//int CLK1 = 22,CLK2 = 23;
//int DT1 = 6,DT2 = 7;
int COUNT1 = 0,COUNT2 = 0;
float lastt, currentt, Speed1,Speed2;

void setup()
{   Serial.begin(9600);
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
    pinMode(PWMPin,OUTPUT);
    pinMode(PWMPin,OUTPUT);
    //编码器部分
    attachInterrupt(interruptA, RoteStateChanged1, FALLING);
    attachInterrupt(interruptB, RoteStateChanged2, FALLING);      
//    FlexiTimer2::set(1000, flash); // 500ms period
//motor1
//    pinMode(CLK1, INPUT);
//    digitalWrite (CLK1, HIGH);
//    pinMode(DT1, INPUT);
//    digitalWrite (DT1, HIGH);
//motor2
//    pinMode(CLK2, INPUT);
//    digitalWrite (CLK2, HIGH);
//    pinMode(DT2, INPUT);
//    digitalWrite (DT2, HIGH);
   
    lastt =millis();
}

//void flash()
//{
//Speed1 = 4*PI*PI*COUNT1*67/1560;
//Speed2 = 4*PI*PI*COUNT2*67/1560;
//Serial.print('h');
//Serial.print(',');
//Serial.print(Speed1);
//Serial.print(',');
//Serial.print(Speed2);
//Serial.print('\n');
//COUNT1 = 0;
//COUNT2 = 0;
//}


void loop ()
{   
   
    int j = 0;
    while (Serial.available() > 0)
    {

         comdata += char (Serial.read());
         delay (2);
         mark = 1;
      }

//            FlexiTimer2::start();
//            delay(1000);
//            FlexiTimer2::stop();
    if (mark == 1)
    {
            dirdata = comdata;
            dirdata = comdata;
            if (dirdata == 1)
            {
                digitalWrite (IN1, HIGH);
                digitalWrite (IN2, LOW);
            }
            else
            {
                digitalWrite (IN1, LOW);
                digitalWrite (IN2, HIGH);
            }
            if (dirdata == 1)
            {
                digitalWrite (IN3, HIGH);
                digitalWrite (IN4, LOW);
            }
            else
            {
                digitalWrite (IN3, LOW);
                digitalWrite (IN4, HIGH);
            }
            
            for(int i = 4; i < comdata.length(); i++)
            {
               if (comdata == ',')
               {
               j++;
               }
               else
               {
                numdata = numdata*10 + (comdata - '0');
               }
            }
               comdata = String("");
               for (int i = 0; i < 2; i++)
               {
                   analogWrite (PWMPin, numdata);
                   numdata = 0;
               }
               mark = 0;
            }
       currentt =millis();
   if ((currentt - lastt) == 500)
   {
      detachInterrupt(interruptA);
      detachInterrupt(interruptB);
      Speed1 = 4*PI*PI*COUNT1*67/1560;
      Speed2 = 4*PI*PI*COUNT2*67/1560;
      Serial.print('h');
      Serial.print(',');
      Serial.print(Speed1);
      Serial.print(',');
      Serial.print(Speed2);
      Serial.print('\n');
      COUNT1 = 0;
      COUNT2 = 0;
      lastt =millis();
      attachInterrupt(interruptA, RoteStateChanged1, FALLING);
      attachInterrupt(interruptB, RoteStateChanged2, FALLING);   
   }
         
}

void RoteStateChanged1()
{
   
//   if (digitalRead(DT1))
//    {
      COUNT1++;
//    }   
   
}

void RoteStateChanged2()
{

//   if (digitalRead(DT2))
//    {
      COUNT2++;
//    }   

}




Processing code
class Button
{
   int x, y, r;
   int dir = 1;
      Button(int xp, int yp, int rp)
   {
            x = xp;
            y = yp;
            r = rp;
         
   }
   void display()
   {   
         
         fill(255);
         rect(x,y,r,r);
         if (dir == 1)
         {
             text("Foward",x-90,y+10);
         }
         else
         {
             text("Back",x-90,y+10);
         }
   }
   void press(int mx, int my)
   {
      
         if ((mx > (x))&&(mx < (x + r))&&(my > (y))&&(my < (y + r)))
         {
            
             dir = -dir;
         }
      
   }
   int Output()
   {
      return dir;
   }
}
class Scrollbar
{
   int x, y;
   float Scrollbar_Width, Scrollbar_Height;
   float pos;
   float position_Min, position_Max;
   boolean rollover;
   boolean locked;
   float minVal, maxVal;
   Scrollbar (int xp, int yp, int w ,int h, float miv, float mav)
   {
            x = xp;
            y = yp;
            Scrollbar_Width = w;
            Scrollbar_Height = h;
            minVal = miv;
            maxVal = mav;
            pos = x;
            position_Min = x;
            position_Max = x + Scrollbar_Width - Scrollbar_Height;   
   }
   void update (int mx, int my)
   {
         if (over (mx, my) == true)
         {
         rollover = true;
         }
         else
         {
         rollover = false;
         }
         if (locked == true)
         {
         pos = constrain(mx-Scrollbar_Height/2,position_Min,position_Max);
         }
   }
   void press(int mx, int my)
   {
         if (rollover == true)
         {
          locked = true;
         }
         else
         {
         locked = false;
         }
   }
   void release()
   {
         locked = false;
   }
   boolean over (int mx, int my)
   {
            if ((mx > x)&&(mx < x+Scrollbar_Width)&&(my > y)&&(my < y + Scrollbar_Height))
            {
                return true;
            }
            else
            {
                return false;
            }
            
            
   }
   void display()
   {
         fill(255);
         rect(x,y,Scrollbar_Width, Scrollbar_Height);
         if ((rollover == true)||(locked == true))
         {
             fill(#FFD700);
         }
         else
         {
             fill(102);
         }
         rect(pos, y, Scrollbar_Height, Scrollbar_Height);
   }
   float getPos()
   {
          float scallar = Scrollbar_Width/(Scrollbar_Width-Scrollbar_Height);
          float ratio = (pos - x)*scallar;
          float offset = minVal + (ratio/Scrollbar_Width*(maxVal-minVal));
          return offset;
   }
}

Scrollbar Motor1_bar, Motor2_bar;
Button But1, But2;
PFont font;
int pos1, pos2;
import processing.serial.*;
Serial myPort;
float Speed1 = 0,Speed2 = 0;
PImage img;


void setup()
{
    img = requestImage("image1.jpg");
    size (600 , 600);
    noStroke();
    textSize(20);
    Motor1_bar = new Scrollbar(100, 50, 255, 20, 0, 255);
    Motor2_bar = new Scrollbar(100, 150, 255, 20, 0, 255);
    But1 = new Button(110,110,10);
    But2 = new Button(110,210,10);
    font = loadFont("David-30.vlw");
    textFont(font);
    textAlign(LEFT);
    myPort = new Serial(this, "COM4", 9600);
    myPort.bufferUntil('\n');
    myPort.clear();
   
}

void draw()
{   
    background(0);
    img.resize(352,220);
    image(img,120,350);


    fill(255);
    text("Motor1", 20, 68);
    text("Motor2", 20, 168);
    pos1 = int (Motor1_bar.getPos());
    textSize(25);
    text(pos1, 525, 68);
    text("PWM:", 365, 68);
    text("Speed1(mm/s):", 365, 120);
    text(Speed1, 520, 120);
    pos2 = int (Motor2_bar.getPos());
    text(pos2, 525, 168);
    text("PWM:", 365, 168);
    text("Speed2(mm/s):", 365, 220);
    text(Speed2, 520, 220);
    Motor1_bar.update(mouseX, mouseY);
    Motor2_bar.update(mouseX, mouseY);
    Motor1_bar.display();
    Motor2_bar.display();
    But1.display();
    But2.display();
}

void mousePressed()
{
    Motor1_bar.press(mouseX, mouseY);
    Motor2_bar.press(mouseX, mouseY);
    But1.press(mouseX, mouseY);
    But2.press(mouseX, mouseY);
}

void mouseReleased()
{
    String s1 = Integer.toString(pos1);
    String s2 = Integer.toString(pos2);
    int s3 = But1.Output();
    int s4 = But2.Output();
    myPort.write(s3);
    myPort.write(",");
    myPort.write(s4);
    myPort.write(",");
    myPort.write(s1);
    myPort.write(",");
    myPort.write(s2);
    Motor1_bar.release();
    Motor2_bar.release();
}

void serialEvent(Serial p)
{
    String [] str;
    String inString = p.readString();
    if (inString != null)
    {
      str = inString.split(",");
      if(str.charAt(0) == 'h')
      {
            Speed1 = Float.parseFloat(str);
            Speed2 = Float.parseFloat(str);
      }
    }
}
   

柱头ANDY 发表于 2016-8-26 11:12:20

活见鬼了 真是每每发Arduino代码都发不出去:@:@:@#include <FlexiTimer2.h>
#define IN1 3
#define IN2 4
#define IN3 5
#define IN4 6
String comdata = "";
int numdata = {0}, mark = 0,dirdata={0};
int PWMPin = {8,9};
//编码器部分
const int interruptA = 0,interruptB = 5;
//int CLK1 = 22,CLK2 = 23;
//int DT1 = 6,DT2 = 7;
int COUNT1 = 0,COUNT2 = 0;
float lastt, currentt, Speed1,Speed2;

void setup()
{   Serial.begin(9600);
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
    pinMode(PWMPin,OUTPUT);
    pinMode(PWMPin,OUTPUT);
    //编码器部分
    attachInterrupt(interruptA, RoteStateChanged1, FALLING);
    attachInterrupt(interruptB, RoteStateChanged2, FALLING);      
//    FlexiTimer2::set(1000, flash); // 500ms period
//motor1
//    pinMode(CLK1, INPUT);
//    digitalWrite (CLK1, HIGH);
//    pinMode(DT1, INPUT);
//    digitalWrite (DT1, HIGH);
//motor2
//    pinMode(CLK2, INPUT);
//    digitalWrite (CLK2, HIGH);
//    pinMode(DT2, INPUT);
//    digitalWrite (DT2, HIGH);
   
    lastt =millis();
}

//void flash()
//{
//Speed1 = 4*PI*PI*COUNT1*67/1560;
//Speed2 = 4*PI*PI*COUNT2*67/1560;
//Serial.print('h');
//Serial.print(',');
//Serial.print(Speed1);
//Serial.print(',');
//Serial.print(Speed2);
//Serial.print('\n');
//COUNT1 = 0;
//COUNT2 = 0;
//}


void loop ()
{   
   
    int j = 0;
    while (Serial.available() > 0)
    {

         comdata += char (Serial.read());
         delay (2);
         mark = 1;
      }

//            FlexiTimer2::start();
//            delay(1000);
//            FlexiTimer2::stop();
    if (mark == 1)
    {
            dirdata = comdata;
            dirdata = comdata;
            if (dirdata == 1)
            {
                digitalWrite (IN1, HIGH);
                digitalWrite (IN2, LOW);
            }
            else
            {
                digitalWrite (IN1, LOW);
                digitalWrite (IN2, HIGH);
            }
            if (dirdata == 1)
            {
                digitalWrite (IN3, HIGH);
                digitalWrite (IN4, LOW);
            }
            else
            {
                digitalWrite (IN3, LOW);
                digitalWrite (IN4, HIGH);
            }
            
            for(int i = 4; i < comdata.length(); i++)
            {
               if (comdata == ',')
               {
               j++;
               }
               else
               {
                numdata = numdata*10 + (comdata - '0');
               }
            }
               comdata = String("");
               for (int i = 0; i < 2; i++)
               {
                   analogWrite (PWMPin, numdata);
                   numdata = 0;
               }
               mark = 0;
            }
       currentt =millis();
   if ((currentt - lastt) == 500)
   {
      detachInterrupt(interruptA);
      detachInterrupt(interruptB);
      Speed1 = 4*PI*PI*COUNT1*67/1560;
      Speed2 = 4*PI*PI*COUNT2*67/1560;
      Serial.print('h');
      Serial.print(',');
      Serial.print(Speed1);
      Serial.print(',');
      Serial.print(Speed2);
      Serial.print('\n');
      COUNT1 = 0;
      COUNT2 = 0;
      lastt =millis();
      attachInterrupt(interruptA, RoteStateChanged1, FALLING);
      attachInterrupt(interruptB, RoteStateChanged2, FALLING);   
   }
         
}

void RoteStateChanged1()
{
   
//   if (digitalRead(DT1))
//    {
      COUNT1++;
//    }   
   
}

void RoteStateChanged2()
{

//   if (digitalRead(DT2))
//    {
      COUNT2++;
//    }   

}

柱头ANDY 发表于 2016-8-26 11:45:13

用定时器测速 可能精度会高一点#include <FlexiTimer2.h>
#define IN1 3
#define IN2 4
#define IN3 5
#define IN4 6
String comdata = "";
int numdata = {0}, mark = 0,dirdata={0};
int PWMPin = {8,13};
//编码器部分
const int interruptA = 0,interruptB = 5;
//int CLK1 = 22,CLK2 = 23;
//int DT1 = 6,DT2 = 7;
int COUNT1 = 0,COUNT2 = 0;
float lastt, currentt, Speed1,Speed2;

void setup()
{   Serial.begin(9600);
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
    pinMode(PWMPin,OUTPUT);
    pinMode(PWMPin,OUTPUT);
    //编码器部分
    attachInterrupt(interruptA, RoteStateChanged1, FALLING);
    attachInterrupt(interruptB, RoteStateChanged2, FALLING);      
    FlexiTimer2::set(500, flash); // 500ms period
    FlexiTimer2::start();
//motor1
//    pinMode(CLK1, INPUT);
//    digitalWrite (CLK1, HIGH);
//    pinMode(DT1, INPUT);
//    digitalWrite (DT1, HIGH);
//motor2
//    pinMode(CLK2, INPUT);
//    digitalWrite (CLK2, HIGH);
//    pinMode(DT2, INPUT);
//    digitalWrite (DT2, HIGH);
   
//    lastt =millis();
}

void flash()
{
Speed1 = 8*PI*PI*COUNT1*67/1560;
Speed2 = 8*PI*PI*COUNT2*67/1560;
Serial.print('h');
Serial.print(',');
Serial.print(Speed1);
Serial.print(',');
Serial.print(Speed2);
Serial.print('\n');
COUNT1 = 0;
COUNT2 = 0;
}


void loop ()
{   
   
    int j = 0;
    while (Serial.available() > 0)
    {

         comdata += char (Serial.read());
         delay (2);
         mark = 1;
      }

//            FlexiTimer2::start();
//            delay(1000);
//            FlexiTimer2::stop();
    if (mark == 1)
    {
            dirdata = comdata;
            dirdata = comdata;
            if (dirdata == 1)
            {
                digitalWrite (IN1, HIGH);
                digitalWrite (IN2, LOW);
            }
            else
            {
                digitalWrite (IN1, LOW);
                digitalWrite (IN2, HIGH);
            }
            if (dirdata == 1)
            {
                digitalWrite (IN3, HIGH);
                digitalWrite (IN4, LOW);
            }
            else
            {
                digitalWrite (IN3, LOW);
                digitalWrite (IN4, HIGH);
            }
            
            for(int i = 4; i < comdata.length(); i++)
            {
               if (comdata == ',')
               {
               j++;
               }
               else
               {
                numdata = numdata*10 + (comdata - '0');
               }
            }
               comdata = String("");
               for (int i = 0; i < 2; i++)
               {
                   analogWrite (PWMPin, numdata);
                   numdata = 0;
               }
               mark = 0;
            }
//       currentt =millis();
//   if ((currentt - lastt) == 500)
//   {
//      detachInterrupt(interruptA);
//      detachInterrupt(interruptB);
//      Speed1 = 4*PI*PI*COUNT1*67/1560;
//      Speed2 = 4*PI*PI*COUNT2*67/1560;
//      Serial.print('h');
//      Serial.print(',');
//      Serial.print(Speed1);
//      Serial.print(',');
//      Serial.print(Speed2);
//      Serial.print('\n');
//      COUNT1 = 0;
//      COUNT2 = 0;
//      lastt =millis();
//      attachInterrupt(interruptA, RoteStateChanged1, FALLING);
//      attachInterrupt(interruptB, RoteStateChanged2, FALLING);   
//   }
         
}

void RoteStateChanged1()
{
   
//   if (digitalRead(DT1))
//    {
      COUNT1++;
//    }   
   
}

void RoteStateChanged2()
{

//   if (digitalRead(DT2))
//    {
      COUNT2++;
//    }   

}

164335413 发表于 2016-8-27 10:51:21

mills也可以的,编码器的精度多少?340线的?还是11线的?

Frankwxd 发表于 2016-10-25 16:38:22

柱头ANDY 发表于 2016-8-26 11:45
用定时器测速 可能精度会高一点

你好,我是初学的,麻烦大神能不能把电机驱动部分去掉只剩下测速部分,我最近在学习编写测速程序,想学习一下。拜托拜托
页: [1]
查看完整版本: 电机控制及码盘测速