Go Down

### Topic: Motor Control With encoders. So many errors >< (Read 2916 times)previous topic - next topic

#### MrPudding

##### Mar 26, 2012, 11:37 pmLast 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] = {

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

#1
##### Mar 27, 2012, 12:32 am
Go back to your post, click modify, and put your code within code tags, like this:
[code]
...
[/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;`

#### dxw00d

#2
##### Mar 27, 2012, 09:39 amLast 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)`

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

#3
##### Mar 27, 2012, 06:26 pm

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 will NOT respond to personal messages, I WILL delete them, use the forum please ]

#### MrPudding

#4
##### Apr 01, 2012, 01:16 pm
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 pmLast 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 directionfloat 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

#6
##### Apr 01, 2012, 05:48 pm
You'll need to post the whole sketch. That won't compile at all, with variable and function definitions missing.

#### MrPudding

#7
##### Apr 01, 2012, 06:41 pm
Sorry about that, it's now all there!

#### dxw00d

#8
##### Apr 01, 2012, 06:55 pm
It clearly isn't. I get a load more errors than you've listed.

#### MrPudding

#9
##### Apr 01, 2012, 07:04 pm
As I said, they are some of the errors; the first 2.

#### dxw00d

#10
##### Apr 01, 2012, 08:34 pmLast 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

#11
##### Apr 02, 2012, 01:41 pm

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

#12
##### Apr 03, 2012, 08:09 pm
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 directionfloat 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

#13
##### Apr 03, 2012, 08:21 pm
I thought you'd changed this
Code: [Select]
`  iniA =init[m*2];  iniB =init[m*2+1];`
to not use 'init'.

#### MrPudding

#14
##### Apr 04, 2012, 02:30 pm
Yeah, I thought I had aswell....
erm... it seems to be verifying now!

Thanks everyone!!!!

Go Up