Wiring Forum
http://wiring.org.co/cgi-bin/yabb/YaBB.pl
Wiring Hardware >> Tangible computing >> Problems with running 3 PWMs
http://wiring.org.co/cgi-bin/yabb/YaBB.pl?num=1178521131

Message started by geiger on 05/07/07 at 06:58:51

Title: Problems with running 3 PWMs
Post by geiger on 05/07/07 at 06:58:51
Hi there,

We're trying to run a relatively large software controlling 3 PWMs (->mDC motors through drivers).
The problem is only 2 PWM work at the same time. when the 3rd "analogWrite" command is executed, it shuts off the first PWM pin.
We tested the board with a simple software running 3 PWMs and it worked fine.
We checked the pins for dual use, but it doesn't seem to be the problem (We're using port1, 3 analog input pins and 3 first pins from port3).

Can someone point on a possible reason for ther problem?

Thanks,
 Shachar.

Title: Re: Problems with running 3 PWMs
Post by barragan on 05/07/07 at 07:15:11
Please post the code you're using to have a better idea.

Title: Re: Problems with running 3 PWMs
Post by geiger on 05/07/07 at 10:14:20
Well, here it is...

It was written in origion for Atmega8, so it has no floating point and some weired tricks to overcome porblems.

[code][/code]


byte pinpwm1 = 3;
byte pinpwm2 = 4;
byte pinpwm3 = 5;

byte pindir1 = 9;
byte pindir2 = 8;
byte pindir3 = 10;

byte pinr = 13;
byte pingo = 12;
byte pinl = 11;

byte pinx = 2;
byte piny = 0;
byte pinz = 3;

byte ledpinr = 25;
byte ledping = 24;
byte ledpinb = 26;

int inputx;
int inputy;
int inputz;

int xamp;    //  Amplitude
int xmid;    //  Middle value (idle state)

int yamp;
int ymid;

int zamp;
int zmid;

long m1 = 0;     //  Individual motor velocity
long m2 = 0;
long m3 = 0;

boolean d1 = false;    //  Motor direction
boolean d2 = false;
boolean d3 = false;

long speed;   //  Motors speed factor

int sfactor = 5;  //  Speed factor - speed is devided by it.

boolean left;
boolean right;
boolean go = false;

boolean going = false ;

int alpha;   //  Forward angle
int beta;     //  Side angle

int alphaRef;   // Reference - angles as pressing "GO" button
int betaRef;

int teta;         //  Angle of desire
int tetaQ;       //  Quarter of teta in circle: 0: >^       1: <^        2: <v         3: >v

byte costoper[19] = {
 100, 100, 98, 97, 94, 91, 87, 82, 77, 71, 64, 57, 50, 42, 34, 26, 17, 9, 0 };

int atang () {
 long at;

 if (alpha == 0) {
   return 90;
 }
 else {
   at = abs(beta) * 100 / abs(alpha);
   if (at > 100) {
     if (at > 214) {
       if (at > 373) {
         if (at > 567) {
           if (at > 1143) {
             return 85;
           }
           else {
             return 80;
           }
         }
         else {
           return 75;
         }
       }
       if (at > 275) {
         return 70;
       }
       else {
         return 65;
       }
     }  
     if (at > 143) {
       if (at > 173) {
         return 60;
       }
       else {
         return 55;
       }
     }  
     if (at > 119) {
       return 50;
     }
     else {
       return 45;
     }
   }
   if (at > 36) {
     if (at > 58) {
       if (at > 70) {
         if (at > 84) {
           return 40;
         }
         else {
           return 35;
         }
       }
       else {
         return 30;
       }
     }
     if (at > 47)  {
       return 25;
     }
     else {
       return 20;
     }
   }
   if (at > 18) {
     if (at > 27) {
       return 15;
     }
     else {
       return 10;
     }
   }
   if (at > 9) {
     return 5;
   }
   else {
     return 0;
   }
 }
}


void readHandle() {
 inputx = analogRead(pinx);
 inputy = analogRead(piny);
 inputz = analogRead(pinz);

 left = digitalRead(pinl);
 right = digitalRead(pinr);
 go = digitalRead(pingo);
 if (!go) {
   going = false;
 };
}


void startup() {
 digitalWrite(ledpinr, HIGH);
 while (!go) {
   readHandle();
 };
 xmid = inputx;
 ymid = inputy;
 zamp = inputz;
 digitalWrite(ledpinr, LOW);
 while (go) {
   readHandle();
 };
 delay(1000);

 digitalWrite(ledping, HIGH);
 while (!go) {
   readHandle();
 };
 yamp = inputy;
 zmid = inputz;
 digitalWrite(ledping, LOW);
 while (go) {
   readHandle();
 };
 delay(1000);

 digitalWrite(ledpinb, HIGH);
 while (!go) {
   readHandle();
 };
 xamp = inputx;
 digitalWrite(ledpinb, LOW);
 while (go) {
   readHandle();
 };
 delay(2000);

 zamp = zmid - zamp;
 yamp = yamp - ymid;
 xamp = xmid - xamp;
}


void gomotorsgo (int mot1, int mot2, int mot3, boolean dr1, boolean dr2, boolean dr3) {
 digitalWrite (pindir1, dr1);
 digitalWrite (pindir2, dr2);
 digitalWrite (pindir3, dr3);

 analogWrite (pinpwm1, mot1);
 analogWrite (pinpwm2, mot2);
 analogWrite (pinpwm3, mot3);
}


void drive() {

 teta = atang ();

 // Figue out which quarter of the circle we are in
 if (beta >= 0) {
   if (alpha >= 0) {
     tetaQ = 0;
   }
   else {
     tetaQ = 3;
   }
 }
 else {
   if (alpha >= 0) {
     tetaQ = 1;
   }
   else {
     tetaQ = 2;
   }
 }

 //  Calculating speed factor
 speed = (alpha * alpha) + (beta * beta);

 switch (tetaQ) {

 case 0:

   // motor 1
   if (teta > 30) {
     d1 = false;
     m1 = costoper [(teta - 30) / 5];
   }
   else {
     d1 = false;
     m1 = costoper [(30 - teta) / 5];
   }

   // motor 2:
   if (teta > 60) {
     d2 = false;
     m2 = costoper [(150 - teta) / 5];
   }
   else {
     d2 = true;
     m2 = costoper [(teta + 30) / 5];
   }

   // motor 3:
   d3 = true;
   m3 = costoper[(90 - teta) / 5];

   break;

 case 1:

   // motor 1
   if (teta > 60) {
     d1 = true;
     m1 = costoper [(150 - teta) / 5];
   }
   else {
     d1 = false;
     m1 = costoper [(teta + 30) / 5];
   }

   // motor 2:
   if (teta > 30) {
     d2 = true;
     m2 = costoper [(teta - 30) / 5];
   }
   else {
     d2 = true;
     m2 = costoper [(30 - teta) / 5];
   }

   // motor 3:
   d3 = false;
   m3 = costoper[(90 - teta) / 5];

   break;



contd...

Title: Re: Problems with running 3 PWMs
Post by geiger on 05/07/07 at 10:15:13
Rest of code:



[code][/code]
 case 2:

   // motor 1:
   if (teta > 30) {
     d1 = true;
     m1 = costoper [(teta - 30) / 5];  //  was 30 - teta
   }
   else {
     d1 = true;
     m1 = costoper [(30 - teta) / 5];  // was teta - 30
   }

   // motor 2:
   if (teta > 60) {
     d2 = true;
     m2 = costoper [(150 - teta) / 5];
   }
   else {
     d2 = false;
     m2 = costoper [(teta + 30) / 5];
   }

   // motor 3:
   d3 = false;
   m3 = costoper[(90 - teta) / 5];

   break;

 case 3:

   // motor 1:
   if (teta > 60) {
     d1 = false;
     m1 = costoper [(150 - teta) / 5];
   }
   else {
     d1 = true;
     m1 = costoper [(teta + 30) / 5];
   }

   // motor 2:
   if (teta > 30) {
     d2 = false;
     m2 = costoper [(teta - 30) / 5];
   }
   else {
     d2 = false;
     m2 = costoper [(30 - teta) / 5];
   }  

   // motor 3:
   d3 = true;
   m3 = costoper[(90 - teta) / 5];

 }

 m1 = ((m1 * speed) / 51000) / sfactor;
 m2 = ((m2 * speed) / 51000) / sfactor;
 m3 = ((m3 * speed) / 51000) / sfactor;  

 gomotorsgo (m1, m2, m3, d1, d2, d3);
}


int alphaRead() {
 long y;
 y = (ymid - inputy) * 255 / yamp;
 return y;
}


int betaRead() {
 long x;
 x = (xmid - inputx) * 255 / xamp;
 return x;
}


void setup() {

 pinMode (pindir1, OUTPUT);
 pinMode (pindir2, OUTPUT);
 pinMode (pindir3, OUTPUT);

 pinMode (pinr, INPUT);
 pinMode (pinl, INPUT);
 pinMode (pingo, INPUT);

 pinMode (ledpinr, OUTPUT);
 pinMode (ledping, OUTPUT);
 pinMode (ledpinb, OUTPUT);
 
 pinMode (pinsoftwareswitch, INPUT);

 startup();
};

void loop() {
 readHandle();
 if (go) {
   if (going) {
     alpha = alphaRead() - alphaRef;
     beta = betaRead() - betaRef;
     drive();
   }
   else {
     alphaRef = alphaRead();
     betaRef = betaRead();
     going = true;
   };
 }
 else {
   gomotorsgo (0, 0, 0, d1, d2, d3);
 };  
}


Title: Re: Problems with running 3 PWMs
Post by barragan on 05/07/07 at 15:09:20
Which version of the Wiring software are you using?

Title: Re: Problems with running 3 PWMs
Post by geiger on 05/07/07 at 15:21:14
the newest (0012).
And I also checked it on new board revision an on an older one.
The software worked on the Atmega8 MC (on an Arduino) almost without any changes, and we're upgrading to the Wiring board for extra capabilities.

Title: Re: Problems with running 3 PWMs
Post by barragan on 05/07/07 at 15:42:54
hi, ok, in Wiring PWM pins are numbered 0, 1, 2, 3, 4, and 5
they are available in a separate section.
if PWM is in use you shouldn't be using digital pins 29, 30, 31 and 35, 36, 37 since they are the same. Also the servo library might conflict with 3 of the PWM pins, check this: http://wiring.org.co/cgi-bin/yabb/YaBB.pl?num=1175200666
Please check this and let me know.

Title: Re: Problems with running 3 PWMs
Post by geiger on 05/07/07 at 16:28:32
Well, we've checked almost any possible combination of PWM pins, including using of only 3,4 and 5 and using only 0,1 and 2. Anyhow, we're not using the servo library (is it loaded anyway?)

We also don't use pins that are cross-connected to the PWM pins.

Title: Re: Problems with running 3 PWMs
Post by geiger on 05/09/07 at 07:25:30
Hi,

We checked the porgram with Wiring 0011 and it worked!

I don't know what the bug is, but it's definitely in the 0012 version.  [smiley=shocked.gif]

...

Thanks anyway...

Title: Re: Problems with running 3 PWMs
Post by barragan on 05/09/07 at 21:45:50
hi, could you please post the smallest code possible to reproduce the error?
thanks for your help,
H.

Wiring Forum » Powered by YaBB 2.5 AE!
YaBB Forum Software © 2000-2010. All Rights Reserved.