Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
April 25, 2024, 08:11:56 20:11


Login with username, password and session length


Pages: [1] 2  All
Print
Author Topic: Motor controller with RPM count  (Read 9609 times)
0 Members and 2 Guests are viewing this topic.
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« on: December 07, 2011, 08:06:24 08:06 »

Hi,

I need to make an AC/Universal motor controller with RPM count. In the first phase I started coding for tacho part. But my tacho is very unstable.
I attached the coding and proteus file. Please help.

Code:
// CCS PCWHD Compiler 4.057
// ------------------------

#include <16F886.H>

#fuses HS               //High speed Osc (> 4mhz for PCM/PCH)
#fuses NOBROWNOUT       //No brownout reset
#fuses NOPROTECT        //Code not protected from reading
#fuses NOLVP            //No low voltage programing, B3(PIC16)
#fuses NOWDT            //No Watch Dog Timer
//#FUSES NOPUT          //No Power Up Timer

#use delay(clock=20M)    //20Mhz crystal

// #priority CCP1, TIMER1, RB // Set interrupt priority


#include <flex_LCD.c>


// Tach reading
int16 isr_ccp_delta;
#int_ccp1
void ccp1_isr(void)
{
    int16 current_ccp;
    static int16 old_ccp = 0;

    // Read the 16-bit hardware CCP1 register
    current_ccp = CCP_1;
    isr_ccp_delta = current_ccp - old_ccp;

    // Save the current ccp value for the next pass
    old_ccp = current_ccp;
}


//Main function starts here
void main(void)
{
    int16 current_ccp_delta;
    int16 rev;

    lcd_init(); //LCD start
    lcd_putc("\f");  // Clear the LCD
    delay_ms(100);

    set_timer1(0);           
    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // T1_DIV_BY_8 to reduce the lower limit on the RPM range
    setup_ccp1(CCP_CAPTURE_RE);   

    clear_interrupt(INT_CCP1);
    enable_interrupts(INT_CCP1);
    enable_interrupts(GLOBAL);

    while(1)
     {
      disable_interrupts(GLOBAL);
      current_ccp_delta = isr_ccp_delta;
      enable_interrupts(GLOBAL);
   
      rev = (int16)(5000000L / current_ccp_delta);   //period in seconds
      rev *= 60;                      // period in minutes
 
      lcd_gotoxy(1,1);    //Goto first line
      printf(lcd_putc, "%lu RPM           ", rev);  // Display RPM

      delay_ms(100);

  }

}


Logged
solutions
Hero Member
*****
Offline Offline

Posts: 1824

Thank You
-Given: 656
-Receive: 903



« Reply #1 on: December 07, 2011, 03:13:36 15:13 »

Change your display update to 1 second in the last loop, and also average at least 10 RPM computations, for starters
Logged
TomJackson69
Active Member
***
Offline Offline

Posts: 218

Thank You
-Given: 26
-Receive: 63


« Reply #2 on: December 07, 2011, 04:15:08 16:15 »

leaveme,

Please attach the HEX file, I want to take a look at your circuit in simulation.

Tom
Logged

Con Rong Chau Tien
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #3 on: December 07, 2011, 04:20:35 16:20 »

Thanks solutions.
I really need fast RPM display. Is there anything else I should look into...
Logged
Ichan
Hero Member
*****
Offline Offline

Posts: 833

Thank You
-Given: 312
-Receive: 392



WWW
« Reply #4 on: December 07, 2011, 04:34:51 16:34 »

Hi Leaveme,

Not everyone use CCS, so as Tom said including the hex file will open more chance to catch the bug.

I don't use ccs myself, my blind guess: try to move both current_ccp_delta and isr_ccp_delta as global and volatile variable.

-ichan
Logged

There is Gray, not only Black or White.
TomJackson69
Active Member
***
Offline Offline

Posts: 218

Thank You
-Given: 26
-Receive: 63


« Reply #5 on: December 07, 2011, 05:00:31 17:00 »

leaveme,

I am waiting for your HEX file.

Tom
Logged

Con Rong Chau Tien
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #6 on: December 07, 2011, 05:15:26 17:15 »

Ok buddy, I attached the HEX and LST file both. Hope it will help.

Hey Tom, how are you? After long long time...  Grin
Logged
TomJackson69
Active Member
***
Offline Offline

Posts: 218

Thank You
-Given: 26
-Receive: 63


« Reply #7 on: December 07, 2011, 05:50:15 17:50 »

leaveme,

I don't use CCS so I can not modify your code right now. I can convert it to C18 and use 18F452 to test your code, but it will take sometimes.

Meanwhile, you can modify your code so that TMR1 will interrupt every 1/10 second or 1/20 seconds (or whatever you like, but even number is better).

Like ichan said "try to move both current_ccp_delta and isr_ccp_delta as global and volatile variable". They should be global variables. Also, the "static int16 old_ccp = 0;" line in the interrupt routine could be Huh.

The "old_ccp" should be reset to zero the new count.

The interrupt routine seem like not very good. I would suggest to read "CCP_1" 10 or 20 times than take an average of the reading. That average is a reading of 1 second or 1/2 second or whatever time base you set for interrupt.

Let say every 1/2 second you get the average reading than set a flag to 1 indicate that a half second has occured and a reading is ready for you to display.

In main, a while loop is waiting for that flag to set. After display, clear the flag and it keep repeating.

Hope I have time to modify your code.

Tom
Logged

Con Rong Chau Tien
solutions
Hero Member
*****
Offline Offline

Posts: 1824

Thank You
-Given: 656
-Receive: 903



« Reply #8 on: December 08, 2011, 12:08:34 00:08 »

Thanks solutions.
I really need fast RPM display. Is there anything else I should look into...
A fast display is useless if you cannot read it.

Tom seems to have agreed with what I originally posted, but he apparently like Ichan more than me  Cry  : "I would suggest to read "CCP_1" 10 or 20 times than take an average of the reading. That average is a reading of 1 second or 1/2 second or whatever time base you set for interrupt."  Grin

Motors jump from pole to pole. You cannot infer an RPM reading if you measure on a short time interval. There's too much mechanical jitter, aka vibration.

In other words, what you want, a "fast readout", you cannot get. IMPOSSIBLE.  You can average, but that average is not the "instantaneous" RPM, it's a historical one.

You also did not explain why you need this fast readout.  Do you have Superman on the motor speed control?
Logged
TomJackson69
Active Member
***
Offline Offline

Posts: 218

Thank You
-Given: 26
-Receive: 63


« Reply #9 on: December 08, 2011, 12:50:01 00:50 »

Like solutions has said "what you want, a "fast readout", you cannot get. IMPOSSIBLE. ". Also WHY??? You are wasting the uP time by displaying the reading more than twice/second; unless you want to animate somethings.

I have a question: What is the MAX SPEED of your motor? in other word, what is MAX FREQUENCY of the pulse output of the motor and single phase or three phases???

Tom
Logged

Con Rong Chau Tien
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #10 on: December 08, 2011, 05:31:07 05:31 »

@solutions:
I'll use the tach readout for speed feedback. So, fast is better. Slow readout will give a wobble effect in the motor speed.

@Tom:
Speed range of the motor will be 5K - 30K RPM. It is a single phase (brussed) AC/Universal motor.

The motor is rated for 220v/30K RPM. My main goal is building a speed controller with speed feedback. I'll use a reflective sensor for the rotation count. RPM data then will be used to maintain a constant speed. 2-3% speed variation is ok. Zero crossing need to be used for triac firing though I never worked with it before.  Huh

Say, I referenced the motor to run at 5K RPM and it will do so but without load. The speed will decrease as soon as there is a (side) load since the motor has a cutter attached to it. Speed controller counts the RPM and immediately increase necessary power until the speed reaches to the referenced value.

Edit:
Anybody used T1G (pin # 26) of 16F886 before? Someone suggested me to use T1G for precise RPM count.
« Last Edit: December 08, 2011, 05:53:31 05:53 by leaveme » Logged
solutions
Hero Member
*****
Offline Offline

Posts: 1824

Thank You
-Given: 656
-Receive: 903



« Reply #11 on: December 08, 2011, 10:01:14 22:01 »

@solutions:
I'll use the tach readout for speed feedback. So, fast is better. Slow readout will give a wobble effect in the motor speed.

@Tom:
Speed range of the motor will be 5K - 30K RPM. It is a single phase (brussed) AC/Universal motor.

The motor is rated for 220v/30K RPM. My main goal is building a speed controller with speed feedback. I'll use a reflective sensor for the rotation count. RPM data then will be used to maintain a constant speed. 2-3% speed variation is ok. Zero crossing need to be used for triac firing though I never worked with it before.  Huh

Say, I referenced the motor to run at 5K RPM and it will do so but without load. The speed will decrease as soon as there is a (side) load since the motor has a cutter attached to it. Speed controller counts the RPM and immediately increase necessary power until the speed reaches to the referenced value.

Edit:
Anybody used T1G (pin # 26) of 16F886 before? Someone suggested me to use T1G for precise RPM count.

You sure are knocking yourself out when all you need is an opamp.....
Logged
TomJackson69
Active Member
***
Offline Offline

Posts: 218

Thank You
-Given: 26
-Receive: 63


« Reply #12 on: December 09, 2011, 03:56:09 15:56 »

leaveme,

Try solution suggestions to see how it works.

But, if you still want to use software than a PID control is a sure way to control the motor. Without PID, you will have hard time to maintain the speed of the motor. Try to manually control the fan speed with a knob to see how hard it is.

Tom
Logged

Con Rong Chau Tien
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #13 on: December 09, 2011, 04:35:02 16:35 »

Thanx Tom.
At the end it will be a PID controller. But I'm experimenting each part individually so that I'll be sure that I'm in the right direction.

I'll modify the coding as per you guys earlier suggestion. Let's see what happens...
I'll keep you posted. Smiley
Logged
TomJackson69
Active Member
***
Offline Offline

Posts: 218

Thank You
-Given: 26
-Receive: 63


« Reply #14 on: December 10, 2011, 01:01:47 01:01 »

Leaveme,

I don’t have CSS installed on my computer so I can not modify your program. Here is what I would do if I am going to modify it.

Global variables:
Pulse_Counter, Total_P_Counter and Int_Counter,

1.   Use TMR1 as a timer for interrupts every 10mS (or whatever time you want).
2.   Use RB0 (any free pin on port B) as Pin Change Interrupt and set as Hi-Priority Int. (edge level H/L not mater).
3.   Each Pin Change Interrupt on RB0, increase Pulse_Counter by one (make sure Pulse_Counte big enough).
4.   Each TMR1 int, add Pulse_Counter to Total_P_Counter, set Pulse_Counter = 0 and increase Int_Counter by one. When Int_Counter = 10, set Int_Counter = 0 (in TMR1 int). Calculate RPM base on Total_P_Counter and TMR1 period than reset Total_P_Counter = 0 (remember Total_P_Counter is for 10 reading).

This should works and will have some error on very slow speed. For RPM = 25,000 should be OK. Display your RPM reading every 1/3 or ½ or 1 second is up to you in the main loop.

Tom
« Last Edit: December 10, 2011, 03:12:37 03:12 by TomJackson69 » Logged

Con Rong Chau Tien
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #15 on: December 10, 2011, 04:39:22 04:39 »

Thanx Tom once again.

UPDATE:
I got the Tacho working and it is perfect now.  Grin

2nd phase is Speed Controller. Anybody knows a good DIMMER in C, which will help me a lot.
« Last Edit: December 10, 2011, 08:54:55 08:54 by leaveme » Logged
iphone
Active Member
***
Offline Offline

Posts: 168

Thank You
-Given: 115
-Receive: 10


« Reply #16 on: December 10, 2011, 09:02:39 09:02 »

Thanx Tom once again.

UPDATE:
I got the Tacho working and it is perfect now.  Grin

2nd phase is Speed Controller. Anybody knows a good DIMMER in C, which will help me a lot.

In my experience, to control speed, I'm using PWM with variable Duty %.
Logged
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #17 on: December 10, 2011, 09:07:46 09:07 »

In my experience, to control speed, I'm using PWM with variable Duty %.
It is an AC/Universal single phase motor. PWM will not work. I need phase control method.
Logged
TomJackson69
Active Member
***
Offline Offline

Posts: 218

Thank You
-Given: 26
-Receive: 63


« Reply #18 on: December 10, 2011, 06:17:23 18:17 »

leaveme,

Try U208B Phase Control to see if it works.

Tom
Logged

Con Rong Chau Tien
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #19 on: December 11, 2011, 04:36:09 04:36 »

leaveme,

Try U208B Phase Control to see if it works.

Tom
Thanks buddy.
Since it will be a PID controller so I can't move to U208B. I have a MCU for tacho and I need to use the same unit for phase control too. If you know anything PIC based, please share.
Logged
TomJackson69
Active Member
***
Offline Offline

Posts: 218

Thank You
-Given: 26
-Receive: 63


« Reply #20 on: December 11, 2011, 05:55:54 05:55 »

The U208B is a phase control that will directly control the phase angle for the load. I forget how it really works but, I think it has a pin that you can control by varry the voltage. That in turn, you can use PWM to control the phase angle.

The PID control will fit nicely to the U208B. Since PWM can be convert to voltage and this voltage can control the U208B. That way you don't have to worry about detecting zero crossing and when to turn on the TRIAC (or SCRs) and so on...

You can take a look at the dat sheet to really undrestand.

Tom
Logged

Con Rong Chau Tien
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #21 on: December 11, 2011, 09:50:14 09:50 »

I just checked the datasheet. It seems to me better for independant application. But in my case, I prefer to avoide external components as much as possible. Besides, my mcu is un-utilized.
Logged
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #22 on: December 13, 2011, 07:23:52 07:23 »

Hi,

Anybody here knows CCS C?
Pls help me for a dimmer/motor speed control. I also attached the simulation file. I can't really get the zero crossing synchronization implemented.

Code:
#include <16F886.H>
// #include <16F88.H>

#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#use delay(clock=20M)

//#use fast_io(A)
//#use fast_io(B)

//#byte PORTA                = 0x05
//#byte PORTB                = 0x06
//#byte ANSEL                = 0x9B
//#byte OPTIONREG            = 0x81



#define LCD_DB4    PIN_B1
#define LCD_DB5    PIN_B2
#define LCD_DB6    PIN_B3
#define LCD_DB7    PIN_B4

#define LCD_E      PIN_C5
#define LCD_RS     PIN_C4
#define LCD_RW     PIN_C6

#include <flex_LCD.c>


#define HZ         50

#define PORT_adc   sAN0    // PIN_A0
#define PORT_zero  PIN_B0
#define TRIAC      PIN_B7
#define ON         output_high
#define OFF        output_low

#define Int_Min            50   // 50
#define Int_Max            80   // 80
#define period             85   // 85

int8 dim_pos;
int8 intensity;               


#INT_EXT
void zerocross()
{
   dim_pos=0;
   if (PORT_zero)
       ext_int_edge(H_TO_L);
   else   
       ext_int_edge(L_TO_H);
}


#INT_TIMER0
void triggure(){
   set_timer0(period);
   dim_pos++;
   if (dim_pos==intensity){     
      ON(TRIAC);                                   
      delay_us(20);
      OFF(TRIAC);                               
    }           
 }


void main(void)
{
   // Port directions: 1=input, 0=output
   set_tris_a( 0b00000001 );   
   set_tris_b( 0b00000001 );   

   // Setup the ADC so we can read a value from 0 to 1023
   // as we turn a trimpot which is connected to pin A0.
   setup_comparator(NC_NC_NC_NC);
   setup_adc_ports(PORT_adc);
   setup_adc(ADC_CLOCK_DIV_32);    // Divisor for 20 MHz oscillator
   set_adc_channel(0);
   delay_us(15);

   lcd_init(); //LCD start
   lcd_putc("\f");  // Clear the LCD
   delay_ms(100);
   lcd_gotoxy(1,1);    //Goto first line
   printf(lcd_putc, "Intensity");

   // ANSEL=0;
   // OPTIONREG=OPTIONREG & 0x7F;     

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_2);
   // setup_timer_0( T0_INTERNAL| T0_DIV_64 | T0_8_BIT );

   enable_interrupts(INT_TIMER0);
   enable_interrupts(INT_EXT);
   ext_int_edge(L_TO_H);
   enable_interrupts(GLOBAL);
   set_timer0(period);
   intensity = Int_Max ;
   while(1) {
    // intensity = read_adc();       // Read speed set value from the ADC

    // lcd_gotoxy(1,2);    //Goto second line
    // printf(lcd_putc, "%lu   ", intensity);  //Show intensity for test perpose
   
     // delay_ms(10);
   }
  }
 
 
Logged
solutions
Hero Member
*****
Offline Offline

Posts: 1824

Thank You
-Given: 656
-Receive: 903



« Reply #23 on: December 13, 2011, 05:57:31 17:57 »

What is the maximum desired RPM of your lamp?

Seriously - why are you saying "dimmer/motor" control.  I thought you were doing an AC MOTOR control.  A dimmer is a totally different approach - you can't just cut and paste dimmer code....you yourself said you need phase control. A phase controlled dimmer is NOT the same as phase controlled motor speed.

I suggest you look at app notes from TI, ATMEL and others on AC motor speed control. Most have example code.  It's NOT, however, the same as a dimmer.
Logged
leaveme
Junior Member
**
Offline Offline

Posts: 93

Thank You
-Given: 38
-Receive: 15


« Reply #24 on: December 13, 2011, 06:10:46 18:10 »

If it is a dimmer then I can at least understand the phase control concept, i.e. how zero cross synchronized...
Logged
Pages: [1] 2  All
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC