Pages: [1]   Go Down
Author Topic: Motor Control With encoders. So many errors ><  (Read 1277 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

First off, I'm very sorry. This is quite a bit of code, and I'm a beginner, so the mistakes are probably quite obvious.

Background information: I have 3 motors with encoders attached around a bike wheel. Strings from these motors are attached to fingers (only one finger now). By knowing the length of these strings (from these encoders), the co-ordinates of the fingers can be calculated. By varying the torque of these motors, a force vector can be created it the motor's direction, perhaps creating the feeling of something pushing against your finger. this is known as haptics

If anyone can advise me on fixing any of the many errors this code creates I would be so grateful! To go through the formulas and things I've made for this code would take ages, but it's fairly obvious what I'm trying to do line by lane (I hope).

void setup ()
{
  pinMode(0,OUTPUT);//PWMs (3 motors)
  pinMode(1,OUTPUT);
  pinMode(2,OUTPUT);

  pinMode(22,INPUT); //encoders (2 signals for each motor)
  pinMode(23,INPUT);
  pinMode(24,INPUT);
  pinMode(25,INPUT);
  pinMode(26,INPUT);
  pinMode(27,INPUT);

  /*
  PinMode(42,OUTPUT);   //LEDs  (not necessary)
   PinMode(43,OUTPUT);
   PinMode(44,OUTPUT);
   */
}
  float length[9]={
    0.40,0.40,0.40,0.40,0.40,0.40,0.40,0.40,0.40  }; //String length from each motor (used to be 9), giving them starting values

  boolean init[6] = {
    digitalRead(22),digitalRead(23), digitalRead(24),digitalRead(25), digitalRead(26), digitalRead(27)  };// encoder values shall be kept here

  float R= 0.34 ;
  float Pi=3.14159;

  float sr3=sqrt(3);
  float g=2*R*sr3;
  
  boolean iniA;
  boolean iniB;
  boolean A;
  boolean B;   //These shall be used when working out the motor turning direction

void pos1(){
  float Lab=sq(length[0])–sq(length[1]);
  float Lac=sq(length[0])–sq(length[2]); //Why are these generating errors??

  float Xa = (Lac)/g;
  float Ya = (2*Lab – R*Lac)/(6*R);
  float Za = sqrt(length[1]*length[1]-Lac*Xa+ Ya*Ya+Ya*2*R-R*R);
  FunctionBlocks1 ();
  }
 int FunctionDir ()//Encoder direction
  {
    int C;
    if (iniA==1)
    {
      if(iniB==1)
      {
        if(B==1)
        {
          C=-1;        
        }
        else
        {
          C=1 ;       }
      }
      else
      {
        if(A==1)
        {
          C=-1;      
        }
        else
        {
          C=1 ;
        }
      }
      }
      else if (iniB==1)
      {
        if (A==1)
        {
          C==1;
        }
        else
        {
          C==-1 ;
        }
      }
      else if (A==1)
      {
        C=-1 ;
      }
      else
      {
        C=1 ;
      }
    return (C);
  }
void FunctionEnc (int m,int e) {

  //digitalwrite(m+42,HIGH);
 A=digitalRead(e);
  B=digitalRead(e+1);
  int iniA =init[m*2];
  int iniB =init[m*2+1];
  if(iniA!=A|iniB!=B)
  {
    length[m]=+FunctionDir();
      pos1();
      }

      init[m*2]=A;
  init[m*2+1]=B;


}
void FunctionBlocks1// creates virtual blocks for the user to "feel"
{
  if (Za>0.3)
  {
    if(Ya>0.07)
    {
      Fz = 1+(Za-0.3)*100;
    }
    else{
      if(x>0)
      {
        Fz = (Za-0.3)*20;
      }
      else{
        Fz = (Za-0.3)*100;
      }
    }
    FunctionForce(1,Fz)
    }

    void FunctionForce(t,f){//calculated torque pwm values for each motor
      float Fa=length[0]*f(( Ya+sr3*Xa-R)/(R*Za))/3;
      float Fb=length[1]*f(( 2*Ya+R)/(R*Za))/3;
      float Fc=length [2]*f(( Ya-sr3*Xa-R)/(R*Za))/3;
      Ta=Fa*0.07;
      Tb=Fb*0.07;
      Tc=Fc*0.07;
      float defaul = 0.01;
      if (defaul<Ta<0.1)
      {
        Wa=255*Ta/0.1      };
      else if (Ta<defaul)
      {
        Wa=255*defaul/0.1      };
      else if(Ta>0.1)
      {
        Wa=255      };
      analogWrite(0,Wa) ;
      if (defaul<Tb<0.1)
      {
        Wb=255*Tb/0.1      };
      else if (Tb<defaul)
      {
        Wb=255*defaul/0.1      };
      else if(Tb>0.1)
      {
        Wb=255      };
      analogWrite(1,Wb);
      if (defaul<Tc<0.1)
      {
        Wa=255*Tc/0.1      };
      else if (Tc<defaul)
      {
        Wc=255*defaul/0.1      };
      else if(Tc>0.1)
      {
        Wc=255      };
      analogWrite(2,Wc);



    }
  void loop ()
  {
    FunctionEnc(0,22);

    //digitalwrite(42,LOW)
    FunctionEnc(1,24);

    //digitalwrite(43,LOW)
    FunctionEnc(2,26);

    //digitalwrite(44,LOW)

  }
« Last Edit: March 26, 2012, 04:39:05 pm by MrPudding » Logged

Canada
Offline Offline
Sr. Member
****
Karma: 0
Posts: 318
Sometimes teaching, always learning,
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Go back to your post, click modify, and put your code within code tags, like this:
[code]
//your code here
...
[/code]

What exactly are your errors? It's hard to help without knowing what they are.

For starters, all the nested if statements are hard to read. This:
Code:
        if (A==1)
        {
          C==1;
        }
        else
        {
          C==-1 ;
        }
...can be changed to this:
Code:
if (A==1) C=1; else C=-1;
Logged


Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How is this meant to work?
Code:
boolean init[6] = {
  digitalRead(22),digitalRead(23), digitalRead(24),digitalRead(25), digitalRead(26), digitalRead(27)  };// encoder values shall be kept here

You need to declare the types of t and f here:
Code:
void FunctionForce(t,f)

The answer to:
Code:
 float Lab=sq(length[0])–sq(length[1]);
  float Lac=sq(length[0])–sq(length[2]); //Why are these generating errors??
Is that whatever you are typing to get '–' is not a minus sign, so the compiler doesn't know what it is.

I don't think it likes you using init as a variable name.

You have a load of variables that are local to one function, that you are trying to use in other functions.

All the semicolons after the close braces here:
Code:
      if (defaul<Ta<0.1)
      {
        Wa=255*Ta/0.1      };
      else if (Ta<defaul)
      {
        Wa=255*defaul/0.1      };
      else if(Ta>0.1)
      {
        Wa=255      };
      analogWrite(0,Wa) ;
      if (defaul<Tb<0.1)
      {
        Wb=255*Tb/0.1      };
      else if (Tb<defaul)
      {
        Wb=255*defaul/0.1      };
      else if(Tb>0.1)
      {
        Wb=255      };
      analogWrite(1,Wb);
      if (defaul<Tc<0.1)
      {
        Wa=255*Tc/0.1      };
      else if (Tc<defaul)
      {
        Wc=255*defaul/0.1      };
      else if(Tc>0.1)
      {
        Wc=255      };
are ending the if statements they are attached to, causing errors because there are else statements following. They should all be inside the braces.
« Last Edit: March 27, 2012, 02:59:43 am by dxw00d » Logged

0
Offline Offline
Shannon Member
****
Karma: 214
Posts: 12412
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset



For starters, all the nested if statements are hard to read. This:
Code:
        if (A==1)
        {
          C==1;
        }
        else
        {
          C==-1 ;
        }
...can be changed to this:
Code:
if (A==1) C=1; else C=-1;

Personally I'd advise against if and else on same line, its far to easy to see the is and not the else on a casual glance.
Code:
  if (A == 1)
    C = 1 ;
  else
    C = -1 ;
is neater and clear, but actually the neatest for such conditional assignment to my mind is a conditional expression:
Code:
  C = (A == 1) ? 1 : -1 ;
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wow... You guys have been so helpful. I've already gotten rid of most of my errors thanks to your comments. I'll let you know how it goes!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, the first half of the program is now verifying splendidly. The second half is now throwing up some errors I haven't seen before.

Code:
void setup ()
{
  pinMode(0,OUTPUT);//PWMs (3 motors)
  pinMode(1,OUTPUT);
  pinMode(2,OUTPUT);

  pinMode(22,INPUT); //encoders (2 signals for each motor)
  pinMode(23,INPUT);
  pinMode(24,INPUT);
  pinMode(25,INPUT);
  pinMode(26,INPUT);
  pinMode(27,INPUT);

  /*
  PinMode(42,OUTPUT);   //LEDs  (not necessary)
   PinMode(43,OUTPUT);
   PinMode(44,OUTPUT);
   */
};
  float length[9]={
    0.40,0.40,0.40,0.40,0.40,0.40,0.40,0.40,0.40  }; //String length from each motor (used to be 9), giving them starting values

  boolean ini[6] = {
    digitalRead(22),digitalRead(23), digitalRead(24),digitalRead(25), digitalRead(26), digitalRead(27)  };// encoder values shall be kept here

  float R= 0.34 ;
  float Pi=3.14159;

  float sr3=sqrt(3);
  float g=2*R*sr3;
 
  boolean iniA;
  boolean iniB;
  boolean A;
  boolean B;   //These shall be used when working out the motor turning direction

float Xa,Ya,Za,Fz,Wa,Wb,Wc;


void FunctionBlocks1();

void pos1(){
  float Lab=sq(length[0]) - sq(length[1]);
  float Lac=sq(length[0]) - sq(length[2]); //Why are these generating errors??

  float Xa = (Lac)/g;
  float Ya = (2*Lab - R*Lac)/(6*R);
  float Za = sqrt(length[1]*length[1] - Lac*Xa+ Ya*Ya+Ya*2*R - R*R);
  FunctionBlocks1 ();
  };
 int FunctionDir ()//Encoder direction
  {
    int C;
    if (iniA==1)
    {
      if(iniB==1)
      {
        if(B==1)
          C=-1;       
        else
          C=1;     
        };
      }
      else
      {
        if(A==1)
          C=-1;       
        else
          C=1 ;
        }
      if (iniB==1)
      {
        if (A==1)
        {
          C==1;
        }
        else
        {
          C==-1 ;
        };
      }
      else if (A==1)
      {
        C=-1 ;
      }
      else
      {
        C=1 ;
      };
    return (C);
  };
void FunctionEnc (int m,int e) {

  //digitalwrite(m+42,HIGH);
 A=digitalRead(e);
  B=digitalRead(e+1);
  int iniA =init[m*2];
  int iniB =init[m*2+1];
  if(iniA!=A|iniB!=B)
  {
    length[m]=+FunctionDir();
      pos1();
      }

      ini[m*2]=A;
  ini[m*2+1]=B;


}
void FunctionBlocks1()// creates virtual blocks for the user to "feel"
{
  if (Za>0.3)
  {
    if(Ya>0.07)
    {
      Fz = 1+(Za-0.3)*100;
    }
    else{
      if(Xa>0)
      {
        Fz = (Za-0.3)*20;
      }
      else{
        Fz = (Za-0.3)*100;
      }
    }
    FunctionForce(1,Fz);
    }
}
    void FunctionForce(int t, float f){//calculated torque pwm values for each motor
      float Fa=length[0]*f*(( Ya+sr3*Xa-R)/(R*Za))/3;
      float Fb=length[1]*f*(( 2*Ya+R)/(R*Za))/3;
      float Fc=length [2]*f*(( Ya-sr3*Xa-R)/(R*Za))/3;
      float Ta=Fa*0.07;
      float Tb=Fb*0.07;
      float Tc=Fc*0.07;
      float defaul = 0.01;
      if (defaul<Ta<0.1)
        Wa=255*Ta/0.1 ;
      else if (Ta<defaul)
        Wa=255*defaul/0.1 ;
      else if(Ta>0.1)
        Wa=255;
      analogWrite(0,Wa) ;
      if (defaul<Tb<0.1)
        Wb=255*Tb/0.1 ;
      else if (Tb<defaul)
        Wb=255*defaul/0.1;
      else if(Tb>0.1)
        {Wb=255 ;
      analogWrite(1,Wb);
        }
      if (defaul<Tc<0.1)
        Wa=255*Tc/0.1;
      else if (Tc<defaul)
        Wc=255*defaul/0.1;
      else if(Tc>0.1)
        {Wc=255;
      analogWrite(2,Wc);
        }


    }
  void loop ()
  {
    FunctionEnc(0,22);

    //digitalwrite(42,LOW)
    FunctionEnc(1,24);

    //digitalwrite(43,LOW)
    FunctionEnc(2,26);

    //digitalwrite(44,LOW)

  }

Here are some of the error messages:

motor_control_2:93: error: pointer to a function used in arithmetic
motor_control_2:93: error: invalid conversion from 'void (*)()' to 'int'

Any ideas?     {now includes whole sketch}
« Last Edit: April 01, 2012, 12:33:39 pm by MrPudding » Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You'll need to post the whole sketch. That won't compile at all, with variable and function definitions missing.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry about that, it's now all there!
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It clearly isn't. I get a load more errors than you've listed.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

As I said, they are some of the errors; the first 2.
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah, so I need to fix all the rest first then, including the missing closing brace(s). Thanks.

What are these lines doing?
Code:
 int iniA =init[m*2];
  int iniB =init[m*2+1];

I get 'init' colour-coded in the IDE, which means it is a reserved word. It's also the only two times the word 'init' appears in what you've posted.

You still have a load of variables that you have defined local to one function that you are trying to use in another function.

And you still have this line:
Code:
boolean ini[6] = {
  digitalRead(22),digitalRead(23), digitalRead(24),digitalRead(25), digitalRead(26), digitalRead(27)  };// encoder values shall be kept here

What does the 'f' mean these lines?
Code:
   float Fa=length[0]*f(( Ya+sr3*Xa-R)/(R*Za))/3;
    float Fb=length[1]*f(( 2*Ya+R)/(R*Za))/3;
    float Fc=length [2]*f(( Ya-sr3*Xa-R)/(R*Za))/3;

Edit: never mind, I see you've changed it.
« Last Edit: April 01, 2012, 02:46:28 pm by dxw00d » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What are these lines doing?
Code:
  int iniA =init[m*2];
  int iniB =init[m*2+1];

It was suggested arduino didn't like the variable name "init", so I changed it to "ini" earlier on, and I seem to have forgotten about those references you've listed.

Ini is a boolean array (I hope), and I wanted to assign iniA and iniB to values stored in that array. The particular value was to be the (m*2)th and the (m*2+1)th values.
I wouldn't be surprised if I was using the array feature above incorrectly...  smiley-confuse

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Most of the errors seem to be taken care of! This is the new code:

Code:
void setup ()
{
  pinMode(0,OUTPUT);//PWMs (3 motors)
  pinMode(1,OUTPUT);
  pinMode(2,OUTPUT);

  pinMode(22,INPUT); //encoders (2 signals for each motor)
  pinMode(23,INPUT);
  pinMode(24,INPUT);
  pinMode(25,INPUT);
  pinMode(26,INPUT);
  pinMode(27,INPUT);

  /*
  PinMode(42,OUTPUT);   //LEDs  (not necessary)
   PinMode(43,OUTPUT);
   PinMode(44,OUTPUT);
   */
};
  float length[9]={
    0.40,0.40,0.40,0.40,0.40,0.40,0.40,0.40,0.40  }; //String length from each motor (used to be 9), giving them starting values

  boolean ini[6] = {
    digitalRead(22),digitalRead(23), digitalRead(24),digitalRead(25), digitalRead(26), digitalRead(27)  };// encoder values shall be kept here

  float R= 0.34 ;
  float Pi=3.14159;

  float sr3=sqrt(3);
  float g=2*R*sr3;
 
  boolean iniA;
  boolean iniB;
  boolean A;
  boolean B;   //These shall be used when working out the motor turning direction

float Xa,Ya,Za,Fz,Wa,Wb,Wc;


void FunctionBlocks1();

void pos1(){
  float Lab=sq(length[0]) - sq(length[1]);
  float Lac=sq(length[0]) - sq(length[2]); //Why are these generating errors??

  float Xa = (Lac)/g;
  float Ya = (2*Lab - R*Lac)/(6*R);
  float Za = sqrt(length[1]*length[1] - Lac*Xa+ Ya*Ya+Ya*2*R - R*R);
  FunctionBlocks1 ();
  };
 int FunctionDir ()//Encoder direction
  {
    int C;
    if (iniA==1)
    {
      if(iniB==1)
      {
        if(B==1)
          C=-1;       
        else
          C=1;     
        };
      }
      else
      {
        if(A==1)
          C=-1;       
        else
          C=1 ;
        }
      if (iniB==1)
      {
        if (A==1)
        {
          C==1;
        }
        else
        {
          C==-1 ;
        };
      }
      else if (A==1)
      {
        C=-1 ;
      }
      else
      {
        C=1 ;
      };
    return (C);
  };
void FunctionEnc (int m,int e) {

  //digitalwrite(m+42,HIGH);
  A=digitalRead(e);
  B=digitalRead(e+1);
  iniA =init[m*2];
  iniB =init[m*2+1];
  if(iniA!=A|iniB!=B)
  {
    length[m]=+FunctionDir();
      pos1();
      }

      ini[m*2]=A;
  ini[m*2+1]=B;


}
void FunctionBlocks1()// creates virtual blocks for the user to "feel"
{
  if (Za>0.3)
  {
    if(Ya>0.07)
    {
      Fz = 1+(Za-0.3)*100;
    }
    else{
      if(Xa>0)
      {
        Fz = (Za-0.3)*20;
      }
      else{
        Fz = (Za-0.3)*100;
      }
    }
    FunctionForce(1,Fz);
    }
}
    void FunctionForce(int t, float f){//calculated torque pwm values for each motor
      float Fa=length[0]*f*(( Ya+sr3*Xa-R)/(R*Za))/3;
      float Fb=length[1]*f*(( 2*Ya+R)/(R*Za))/3;
      float Fc=length [2]*f*(( Ya-sr3*Xa-R)/(R*Za))/3;
      float Ta=Fa*0.07;
      float Tb=Fb*0.07;
      float Tc=Fc*0.07;
      float defaul = 0.01;
      if (defaul<Ta<0.1)
        Wa=255*Ta/0.1 ;
      else if (Ta<defaul)
        Wa=255*defaul/0.1 ;
      else if(Ta>0.1)
        Wa=255;
      analogWrite(0,Wa) ;
      if (defaul<Tb<0.1)
        Wb=255*Tb/0.1 ;
      else if (Tb<defaul)
        Wb=255*defaul/0.1;
      else if(Tb>0.1)
        {Wb=255 ;
      analogWrite(1,Wb);
        }
      if (defaul<Tc<0.1)
        Wa=255*Tc/0.1;
      else if (Tc<defaul)
        Wc=255*defaul/0.1;
      else if(Tc>0.1)
        {Wc=255;
      analogWrite(2,Wc);
        }


    }
  void loop ()
  {
    FunctionEnc(0,22);

    //digitalwrite(42,LOW)
    FunctionEnc(1,24);

    //digitalwrite(43,LOW)
    FunctionEnc(2,26);

    //digitalwrite(44,LOW)

  }

At the moment I'm getting this error:

motor_control_2.cpp: In function 'void FunctionEnc(int, int)':
motor_control_2:96: error: pointer to a function used in arithmetic
motor_control_2:96: error: invalid conversion from 'void (*)()' to 'boolean'
motor_control_2:97: error: pointer to a function used in arithmetic
motor_control_2:97: error: pointer to a function used in arithmetic
motor_control_2:97: error: invalid conversion from 'void (*)()' to 'boolean'

I assume I haven't fully understood arrays. These errors refer to these lines:

Code:
void FunctionEnc (int m,int e) {

  //digitalwrite(m+42,HIGH);
  A=digitalRead(e);
  B=digitalRead(e+1);
  iniA =init[m*2];
  iniB =init[m*2+1];
  if(iniA!=A|iniB!=B)
  {
    length[m]=+FunctionDir();
      pos1();
      }

      ini[m*2]=A;
  ini[m*2+1]=B;


}

Sorry I keep going on, but I can't give up ><
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I thought you'd changed this
Code:
  iniA =init[m*2];
  iniB =init[m*2+1];
to not use 'init'.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah, I thought I had aswell....
erm... it seems to be verifying now!

Thanks everyone!!!!
Logged

Pages: [1]   Go Up
Jump to: