View previous topic :: View next topic |
Author |
Message |
tomal
Joined: 20 Nov 2011 Posts: 9
|
Need support for Closed loop motor speed controller |
Posted: Sun Nov 20, 2011 1:26 am |
|
|
Hi,
At first I express my apology to post it here. But I'm learning CCS C and going to buy it due to its easiness so I thought I would post it here.
Anyway, my interest is actually to build a closed loop (AC/Universal) motor speed controller. Since I'm new to PIC, I need help from the PIC/CCS expert.
I'm ready to pay for your help and support. Please PM me if you can help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Nov 21, 2011 5:25 pm |
|
|
??
110v ??
how much current at 110v - unrestricted I input?
re servo -
attempting to go sensor less ?
or do you have hall/opto interrupters? |
|
|
tomal
Joined: 20 Nov 2011 Posts: 9
|
|
Posted: Mon Nov 21, 2011 11:12 pm |
|
|
It is not a servo but a single phase brushed AC (110/220V) motor and some people calls it universal AC motor.
I have drawn a basic schematic of the speed controller. Pls take a look.
Few words about the schematic:
1. I plan to use (28 pin) PIC18F2420 or 2520 and the circuit will be opto isolated from AC mains.
2. PS2505 multi-photocoupler will be used for zero cross detection. I might be used a selector for 50Hz/60Hz selection.
3. Output will be driven by the MOC3021/23, which will then trigger the triac.
4. The motor usually rotates at 25K RPM with full power. A pot will be used to control the speed between 5k to 25K. Reference voltage (for speed pot) will be 0v - 5v.
5. A reflective sensor (HOA1397) will be used in the motor for rotation count and RPM will be displayed. The same sensor will be used as feedback loop to maintain a constant speed. May be some PID algorithm need to be used. 2-5% speed variation is ok for the application.
Just an illustration:
The (220v/5A) motor is referenced for 5k RPM so it is rotating in the same speed at without load. But the speed will reduce as soon as I put some load on it. MCU will recalculate the revolution at this point and provide more power to maintain the referenced speed.
Hope above explanation will help. |
|
|
tomal
Joined: 20 Nov 2011 Posts: 9
|
Tachometer |
Posted: Fri Dec 09, 2011 2:21 am |
|
|
Here is the tacho part.
Would you pls check if the calculations are right...do you think I'll get right RPM?
Code: |
// Compiler: CCS PCWHD 4.120
#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
//#FUSES PUT //Power Up Timer
#use delay(clock=20M) //20Mhz crystal
#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
// Tacho_PORT = PIN_C2
#include <flex_LCD.c>
#define START_TACH 0
#define RUN_TACH 1
#define DONE_TACH 2
// Global variables
static char cState;
static long iCount;
// Tach reading
#int_ccp1
void ccp1_isr(void)
{
if ( cState == RUN_TACH ) // second edge
{
iCount = CCP_1; // get capture value
cState = DONE_TACH; // prevent further processing during this interrupt
}
if ( cState == START_TACH ) // first edge
{
set_timer1 (0); // restart timer on this edge
cState = RUN_TACH;
}
}
//*****************************************************************
// MAIN FUNCTION
void main (void)
{
int cCnt;
float fRpm;
int32 int32Count;
// INITIAL MESSAGE
lcd_init(); //LCD start
lcd_putc("\f"); // Clear the LCD
delay_ms(100);
lcd_putc("TACHOMETER\n");
// SETUP TIMER 1
setup_timer_1(T1_INTERNAL);
// SETUP CCP1
setup_ccp1(CCP_CAPTURE_RE); // capture every rising edge
// ENABLE INTERRUPTS
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1); // CCP1 interrupt
enable_interrupts(GLOBAL); // enable all interrupts
cState = DONE_TACH;
while (1)
{
int32Count = 0;
for ( cCnt = 0; cCnt < 20; cCnt++ ) // accumulate 20 readings
{
cState = START_TACH; // allow interrupt to start
while ( cState != DONE_TACH ) // wait for timing to complete
{
if ( get_timer1() > 60000 ) // timeout counter
{
iCount = 0; // zero everything out
int32Count = 0;
break; // don't wait any longer
}
}
int32Count += iCount; // otherwise accumulate
}
int32Count /= 20; // get average of those 20 readings
fRpm = 1 / ((float)int32Count); // period in uS
fRpm *= 1000000; // period in seconds
fRpm *= 60; // period in minutes
//DISPLAY RPM
lcd_gotoxy(1,2); //Goto second line
printf(lcd_putc, "%0.0f RPM ", fRpm); //Show RPM
delay_ms(500);
}
}
|
|
|
|
|