Home \ Help \ Search \ Login RSS

Welcome, Guest. Please Login

This forum is now READ-ONLY! Please visit http://forum.wiring.co/ for the new forum.

Wiring ForumWiring HardwareTangible computing › Problems with running 3 PWMs

Page Index Toggle Pages: 1
Problems with running 3 PWMs (Read 10429 times)
05/07/07 at 06:58:51

geiger   Offline
YaBB Newbies
Israel

Posts: 13
*
 
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.
 
IP Logged
 
Reply #1 - 05/07/07 at 07:15:11

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
Please post the code you're using to have a better idea.
 
IP Logged
 
Reply #2 - 05/07/07 at 10:14:20

geiger   Offline
YaBB Newbies
Israel

Posts: 13
*
 
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...
 
IP Logged
 
Reply #3 - 05/07/07 at 10:15:13

geiger   Offline
YaBB Newbies
Israel

Posts: 13
*
 
Rest of 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);
  }; 
}

 
IP Logged
 
Reply #4 - 05/07/07 at 15:09:20

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
Which version of the Wiring software are you using?
 
IP Logged
 
Reply #5 - 05/07/07 at 15:21:14

geiger   Offline
YaBB Newbies
Israel

Posts: 13
*
 
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.
 
IP Logged
 
Reply #6 - 05/07/07 at 15:42:54

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
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.
 
IP Logged
 
Reply #7 - 05/07/07 at 16:28:32

geiger   Offline
YaBB Newbies
Israel

Posts: 13
*
 
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.
 
IP Logged
 
Reply #8 - 05/09/07 at 07:25:30

geiger   Offline
YaBB Newbies
Israel

Posts: 13
*
 
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

...

Thanks anyway...
 
IP Logged
 
Reply #9 - 05/09/07 at 21:45:50

barragan   Offline
YaBB Administrator

Posts: 939
*****
 
hi, could you please post the smallest code possible to reproduce the error?
thanks for your help,
H.
 
IP Logged
 
Page Index Toggle Pages: 1