Go Down

Topic: Motor Control With encoders. So many errors >< (Read 1 time) previous topic - next topic

MrPudding

Mar 26, 2012, 11:37 pm Last Edit: Mar 26, 2012, 11:39 pm by MrPudding Reason: 1
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)

 }

John_S

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: [Select]
        if (A==1)
        {
          C==1;
        }
        else
        {
          C==-1 ;
        }

...can be changed to this:
Code: [Select]
if (A==1) C=1; else C=-1;
http://jsrintervalometers.blogspot.ca

dxw00d

#2
Mar 27, 2012, 09:39 am Last Edit: Mar 27, 2012, 09:59 am by dxw00d Reason: 1
How is this meant to work?
Code: [Select]
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: [Select]
void FunctionForce(t,f)

The answer to:
Code: [Select]
 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: [Select]
      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.

MarkT




For starters, all the nested if statements are hard to read. This:
Code: [Select]
        if (A==1)
        {
          C==1;
        }
        else
        {
          C==-1 ;
        }

...can be changed to this:
Code: [Select]
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: [Select]

  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: [Select]

  C = (A == 1) ? 1 : -1 ;
[ I won't respond to messages, use the forum please ]

MrPudding

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!

MrPudding

#5
Apr 01, 2012, 05:15 pm Last Edit: Apr 01, 2012, 07:33 pm by MrPudding Reason: 1
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: [Select]

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}

dxw00d

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

MrPudding


dxw00d

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

MrPudding

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

dxw00d

#10
Apr 01, 2012, 08:34 pm Last Edit: Apr 01, 2012, 09:46 pm by dxw00d Reason: 1
Ah, so I need to fix all the rest first then, including the missing closing brace(s). Thanks.

What are these lines doing?
Code: [Select]
 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: [Select]
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: [Select]
   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.

MrPudding


What are these lines doing?
Code: [Select]
  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...  :~


MrPudding

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

Code: [Select]

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: [Select]

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 ><

dxw00d

I thought you'd changed this
Code: [Select]
  iniA =init[m*2];
  iniB =init[m*2+1];

to not use 'init'.

MrPudding

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

Thanks everyone!!!!

Go Up