Pages: [1]   Go Down
Author Topic: Universal motor pid controll  (Read 1342 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 5
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hello ppl
first sorry for bad english smiley-sad

i need some little help.
im making pid motor controller for 1800W universal motor.
i have problems with triac missing needed delay and im getting spikes on output
code is simple
im using pid_v1 library
and two interrupts one for rpm reading and on for zero cross.
pid output limits are set as delay for triac
potentiometer is for speed control

i cant figure out whare is problem.
pid works ok( tested in front end)
but im still getting spikes, because triac is getting unwanted delay someware and missing.
i dont want to put the triac fiering part in interrupt rutine because i want it to be short as possible.
if i put triac fiering code in interrupt rutine im spending to much time in routine and have no time to calculate pid and do rest of the code.
dont know if rpm interrupt is messing thing up. but i did some crude calculation and in max speed im getting about 7 microseconds of delay more, that is to low to interfire much .
Code:

// TRIAC
    #define triac_control 5 // Triac control - pin
   
//RPM control   
    #define sensorPin A0 // potentiometer or MACH3 - pin
   
//Power
    #define powerOn 4 // Power switch - pin
    #define powerIndicator 6 // indicator GREEN LED -pin
   
//Zero Detect   
    #define zero_detect 2 //Zero detect - pin
    // when using values in the main routine and IRQ routine must be volatile value
    volatile byte zero_bit = LOW; // declare IRQ flag
    // HIGH = 1, LOW = 0
 
// HALL SENSOR
    #define  hallsensor 3 //- pin
 
//LCD
    //LiquidCrystal::LiquidCrystal(rs, enable, d0, d1, d2, d3)
    #include <Wire.h>
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(13, 11, 7, 8, 9, 10);

// PID
    #include <PID_v1.h>

    //Define Variables we'll be connecting to
    double Setpoint, Input, Output;

    //Define the aggressive and conservative Tuning Parameters
    //double consKp=4, consKi=0.2, consKd=1;
    //double consKp=0.4, consKi=0.001, consKd=1;
    //double consKp=4, consKi=0.2, consKd=1;
    //double consKp=1, consKi=0.4, consKd=0.01; //100% work
    //double consKp=0.4, consKi=0.001, consKd=1;
    double consKp=0.0821, consKi=0.725, consKd=0.028;

    //Specify the links and initial tuning parameters
    PID myPID(&Input, &Output, &Setpoint, consKp, consKi, consKd, DIRECT);
    unsigned int analogValue;
    float kDev = 38; // rpm to analog - exp: max rpm = 22000 , analogmax = 920 : rpm/analogmax = kDev = 25
 
   volatile byte rpmcount;
   unsigned int rpm;
   unsigned long timeold;
   unsigned long timenow;

void setup() 
{
 
 
//Triac control setup 
  pinMode(triac_control, OUTPUT); 
  digitalWrite(triac_control, 0); // LED off
//Power switch 
  pinMode(powerIndicator, OUTPUT);
  digitalWrite(powerIndicator, 0); // LED off
  pinMode(powerOn, INPUT);
  digitalWrite(powerOn, 1); // pull up on
//Zero detect 
  pinMode(zero_detect, INPUT);
//  digitalWrite(zero_detect, 1); // pull up on
  attachInterrupt(0, zero_fun, RISING);  // interrupt 0 digital pin 2 connected ZC circuit
// Hall sensor 
  pinMode(hallsensor, INPUT);
//  digitalWrite(hallsensor, 1); // pull up on
  attachInterrupt(1, rpm_fun, RISING);  // interrupt 1 digital pin 3 connected hall sensor
 
  rpmcount = 0;
  rpm = 0;
  timeold = 0;
  timenow = 0; 
 
// LCD detect
  lcd.begin(16,2);               // initialize the lcd
  lcd.home ();                   // go home
  lcd.print("Hello, ARDUINO "); 
  lcd.setCursor ( 0, 1 );        // go to the next line
  lcd.print (" vSpindel-2.0   ");   
  delay(1000);
  lcd.clear();
 
//PID
  analogValue =0;
  Input = rpm;
  Setpoint = analogValue;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  myPID.SetOutputLimits(1000, 9999); 
 

 
 
}

void loop()
{
 
//Power switch and indicator = ON/OFF 
  if (!digitalRead(powerOn))
    {
         digitalWrite(powerIndicator, 1);       
    }
  else
    {   
         digitalWrite(powerIndicator, 0);
    }
   

//RPM counter and show on LCD
if (rpmcount >= 100)
    {
       //Update RPM every 20 counts, increase this for better RPM resolution,
       //decrease for faster update
     timenow =micros();
     rpm = 30000000.0/(float)(timenow-timeold)*(float)rpmcount;
     rpmcount = 0; //reset
     timeold  = timenow; //set time
    }
       lcd.setCursor ( 0, 0 );
       lcd.print ("RPM:");
       lcd.setCursor ( 5, 0 );
       lcd.print (rpm);   
   
//PID
  analogValue = analogRead(sensorPin);
  Input = rpm;
  Setpoint    = analogValue*kDev; 
  myPID.Compute();
 //TRIAC delay control     
  if ((zero_bit == 1) && (digitalRead(powerOn)== 0))
    {
      if (analogRead(sensorPin) > 200)
        {
          delayMicroseconds(10000-Output); // set value between 4 and 14
          digitalWrite(triac_control, 1); //triac on
          delayMicroseconds(10);         //triac propogotional delay
          digitalWrite(triac_control, 0);  //triac off
          zero_bit = 0; // clear flag           
        }   
 
    }
       
}

void zero_fun() // set bit
  {
    zero_bit = 1;
    // if zero detect set bit == 1
  }

void rpm_fun()
 {
   rpmcount++;
   //Each rotation, this interrupt function is run twice
 }
please help
and agin sorry for my english

* Vspindle_V6.pde (4.08 KB - downloaded 19 times.)
Logged

Dubuque, Iowa, USA
Offline Offline
Edison Member
*
Karma: 45
Posts: 2474
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've looked over your code quite a few times and I can't find any problems.
Logged

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

i know. me neither.
that is main reason i asking for help here smiley-sad
Logged

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

What do you mean by spikes on the output?
The motor will create spikes - but maybe you mean the arduino output.

Have you determined whether you have a firmware or hardware problem?
Logged

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

it is frimware problem.
im getting spikes on triac output becouse triac miss on low speed
Logged

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

To understand the nature of your problem it would be helpful to know how it is suppose to work. I don't know what you have tried before.
Secondly, I don't have a schematic of your circuit.

I am assuming that you are starting from scratch.
Have you started your design with a potentiometer connected to Arduino for a manual control of the motor speed? This method would eliminate the basic circuit problems. If you can get a low speed control this way then you have confirmed both hardware and the simple Arduino test software.

Slow speed control will need a closed loop circuit for good speed control.
Logged

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

ofc i tested first with simple pot. controll, hardware is ok. problem was lcd,print, and lcdsetcursor.
lcd generating to much delay in code.
i tried serial print also but nothing.
it is working fine now, but i cant get speed displayed smiley-sad
« Last Edit: January 12, 2013, 04:39:46 pm by mrendu43 » Logged

Pages: [1]   Go Up
Jump to: