View previous topic :: View next topic |
Author |
Message |
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
PWM with changing frequency |
Posted: Thu Dec 03, 2015 6:33 am |
|
|
Hi everybody.
I'm have a problem when tried to create a PWM signal with frequency change like as an image.
I'm using PIC16F877A and CCS C ver 5.021
Can give me a solution to make it because I only create a PWM signal with fixed frequency.
Thanks you.
https://drive.google.com/file/d/0Bz215_lkn4g-SUg1WVE1M0NobGs/view?usp=sharing _________________ Begin Begin Begin !!! |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Thu Dec 03, 2015 7:28 am |
|
|
You've been here a while now, so should know the form.
You must show us short complete compilable code we can copy and paste to test.
Also, I can't tell what it is you are trying to achieve.
Do you want (say) a constant 60% duty ratio over a range of frequencies?
As it stands you are not giving us enough to work on. Please be more specific.
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Thu Dec 03, 2015 8:50 am |
|
|
Also try searching the forum.
This has been discussed before.
The PWM, is not very suitable for variable frequencies. Low resolution, and limited range. Some chips offer a better range. The CCP can be used to do this, but still quite 'code heavy'. However some PIC's have the NCO module, and this is much more suitable for this |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Thu Dec 03, 2015 9:00 am |
|
|
OK, I have to ask what your application is that requires both PWM and VF ?
I'm thinking the algorithm needed to do BOTH functions could be 'intensive' and the 877 wouldn't be the correct PIC for the job.
Jay |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Fri Dec 04, 2015 2:40 am |
|
|
Thanks for your solutions.
Sorry because I'm used PWM phrase to introduce for the signal.
I think it a PWM signal but not sure.
Can you check it again?
About this circuit, I'm want to make a pulse generator circuit with output same the waveform in a picture using PIC ( a current version using AT89S51 IC).
So that, now i'm looking a solutions to make it with a PIC MCU.
I need helping from all you.
Thanks you.
https://drive.google.com/file/d/0Bz215_lkn4g-S1ZmVllYcG1NSzA/view?usp=sharing _________________ Begin Begin Begin !!! |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Fri Dec 04, 2015 5:47 am |
|
|
OK.
I can see your waveform trace.
You've got a sort of gated pulse generator.
You've still not told us what it's for.
Which properties of the waveform are you wanting to change/control?
Mike |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Fri Dec 04, 2015 6:25 am |
|
|
Mike's right ! We need more information.That waveform you showed us doesn't vary the frequency,just a simple gated pulse genny.
Jay |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Fri Dec 04, 2015 12:09 pm |
|
|
You've already programmed a device to get what you want.
Surely you know what you did.
You should then be able to translate to PIC 'C'.
I don't see why you need us.
Mike |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Mon Dec 07, 2015 1:25 am |
|
|
Thanks for yours helping:)
In this project, I must make a circuit to generate pulse same the waveform in the picture above.
The original circuit in sewing machine of my sister, is using for control Triac through PWM signal to drive an AC motor. Now, It's stopped procecude, I can't buy a new to replace so that i think make a new circuit to backup for tomorow.
Because i check the signal with ossciloscope, saw an delay time in waveform, so that I not sure is it a PWM signal.
I dont know that oscciloscope measure PWM frequency is included a delay time or not?
I'm checking a PWM signal frequency to try programe on PIC16F877A/or PIC16F684.
I uploaded an new picture, please reference it and helping me how to creat this signal, in my solution, i think creat a PWM signal, with number of period is change, then, insert a delay, and continues with PWM, ..delay ... PWM... delay..
Pls help me.
Thanks you.
https://drive.google.com/file/d/0Bz215_lkn4g-bWNWY0dJQTExb3c/view?usp=sharing _________________ Begin Begin Begin !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Mon Dec 07, 2015 2:19 am |
|
|
There is no need for PWM to drive a TRIAC. The way TRIAC's work, you need a signal synchronised to the mains. which is a pulse at an interval _before_ the next zero crossing. The TRIAC then turns 'on', and remains on until the zero crossing. If you turn it on right at the start of the cycle, you get full power (with the TRIAC being on for the entire cycle). Generate the pulse just before the zero crossing, and you get almost no power (with the TRIAC being on just for a small moment).
There are different output topologies, depending on how the motor is actually connected. Many devices like sewing machines, actually use DC motors, with the TRIAC circuit being followed by a full-wave rectifier that actually feeds the motor. This might be what is involved, since then you can effectively just use a PWM to control a rough percentage of the time the TRIAC is 'on', and vary the DC drive this way.
Have a look at this application note:
<http://www.st.com/st-web-ui/static/active/jp/resource/technical/document/application_note/CD00003829.pdf>
This shows the two commonest TRIAC topologies (and an IGBT one). The ST6210 involved here might well be the easiest way to go (don't re-invent the wheel....). If you want complex control, just feed this with a DC voltage synthesised from the PIC PWM. Big advantage is that this handles all the AC sync etc., for you. |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Fri Dec 11, 2015 5:01 am |
|
|
Thanks for your supporting
About this circuit, I want to know clearly about a signal, is it a PWM signal or not?
Because it have a delay between string of pulse.
Really I want to know about characteristics of this signal.
Pls ref video I check it.
Thanks you.
https://youtu.be/5Mbo8kJIaL4 _________________ Begin Begin Begin !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri Dec 11, 2015 10:06 am |
|
|
It's not a PWM really. It is string of trigger pulses for the TRIAC, with the string being turned on for a while (to have the output 'on' for most of the time), then off for a while. The pulse width doesn't change, and the way it is done, will give noticeable buzzing of the motor, unless the motor is DC. In which case the output will be integrated to give the DC for the motor. |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Thu Dec 17, 2015 7:55 pm |
|
|
Ttelmah wrote: | It's not a PWM really. It is string of trigger pulses for the TRIAC, with the string being turned on for a while (to have the output 'on' for most of the time), then off for a while. The pulse width doesn't change, and the way it is done, will give noticeable buzzing of the motor, unless the motor is DC. In which case the output will be integrated to give the DC for the motor. |
Thanks for your answers
Yes, you true. I'm checked again and it's a DC motor. The first time I careless when think a AC motor when saw it supply by AC power direct.
About my plan, I choosed pic16F684 to program, but when i process with ADC, it take me more ROM, because i use a float variable to processing.
Now can I processing ADC without float variable, I also tried processed with step ADC but its still a float result.
Code: | setup_adc_ports(sAN3);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(3);
delay_us(100);
volt_adc= read_adc();
volt-in= volt_adc*0.0045;
|
processing code:
Code: | if( (volt_in>=1.7) && (volt_in<=1.9) ) { pos_width=11396; neg_width=11802; loop=1; pulse_delay=0;}
...
....
many condition statement like as above made code take a more ROM
... |
Pls help me to minimum a code
Thanks you. _________________ Begin Begin Begin !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri Dec 18, 2015 1:49 am |
|
|
There are a lot of threads here showing integer ways of doing things like this.
It is though down to how you 'think'.
You are solving to get a 'voltage', in 'volts', so for something like 2.5 volts, 'of course' the result has to be a float. However change your code, so instead you work in mV, and then 2.5v, then becomes a nice integer number (2500). Your multiplication, instead of being *0.0045, becomes *4.5, which solves more in integer, as *4 plus *1/2.
There is also something wrong, you seem to be trying to use volt-in as a variable - presumably volt_in....
Code: |
int16 mvolt_in, volt_adc;
setup_adc_ports(sAN3);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(3);
delay_us(100);
volt_adc= read_adc();
mvolt_in = volt_adc*4;
mvolt_in += volt_adc/2;
|
This then gives *4.5, involving only an integer multiplication by 4, and an integer division by 2. Both done by just simple rotations.
Start to think in terms of 'counts', 'mV', and similar integer values, instead of 'volts' etc...
Have a look at this thread:
<http://www.ccsinfo.com/forum/viewtopic.php?t=54661>
Which gives an output which displays as N.NNN, yet works in integers all the way!. |
|
|
tienchuan
Joined: 25 Aug 2009 Posts: 175
|
|
Posted: Fri Dec 18, 2015 9:38 pm |
|
|
Thanks for your answers
About this problem, I change to read a step ADC for read a voltage.
But now i have a problem when not enough ROM to write a program, I amazing when CCS build a code take a more ROM or my program not optimized.
I'm using PIC16F684 and CCS C ver 5.044
Here is code which I build take a 85% ROM, it not finish code.
Code: |
#include <16F684.h>
#device ADC=10
#FUSES PUT //Power Up Timer
#FUSES PROTECT //Code protected from reads
#FUSES NOCPD //Data EEPROM Code Protected
#FUSES NOBROWNOUT //No brownout reset
#FUSES MCLR
#FUSES NOWDT
#FUSES NOIESO
#FUSES NOFCMEN
#FUSES INTRC_IO
#use delay(internal=8000000)
#define led_dbg PIN_A2
#define pulse PIN_C0
//!#define mode1 input(PIN_C2)
//!#define mode2 input(PIN_C3)
//!#define mode3 input(PIN_C4)
//!#define mode4 input(PIN_C5)
//!// ngoai tru 4 mode se roi vao mode 0
unsigned int16 volt_adc=0;
unsigned int16 pos_width=0, neg_width=0;
unsigned int8 loop=0;
unsigned int32 pulse_delay=0;
//!unsigned int16 pulse_delay1=0, pulse_delay2=0;
unsigned int8 tick_t0=0;
unsigned int1 check_adc=0;
unsigned int8 mode=0;
//--------------------------------------------------------------------------------------------------------------------------
#int_timer0
void ngat_timer0(void)
{
set_timer0(0);
tick_t0++;
if(tick_t0==10)
{
tick_t0=0;
check_adc=1;
}
}
//--------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------
void out_pulse( void)
{
unsigned int8 i_loop;
for( i_loop=1; i_loop<=loop; i_loop++)
{
output_high(pulse);
delay_us(pos_width);
output_low(pulse);
delay_us(neg_width);
}
if(pulse_delay !=0)
{
if(pulse_delay>65535)
{
delay_us(pulse_delay-65535);
delay_us(65535);
}
else
delay_us(pulse_delay);
}
}
//--------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------
void main()
{
setup_oscillator(OSC_8MHZ | OSC_INTRC);
delay_ms(500);
set_tris_a(0x10);
set_tris_c(0x3c);
setup_adc_ports(sAN3|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(3);
delay_us(100); //you need this before the first reading
volt_adc= read_adc();
set_timer0(0); // setup timer0: 30ms-- tao tre chong bam counter: 5ms F_cystal=40MHZ
setup_timer_0 (RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);
enable_interrupts(int_timer0);
enable_interrupts(global);
while(TRUE)
{
//----------------------------------------------------------------------------------------------------------
if(input(PIN_C2)==0) mode=1;
else if(input(PIN_C3)==0) mode=2;
else if(input(PIN_C4)==0) mode=3;
else if(input(PIN_C5)==0) mode=4;
else mode=0;
//----------------------------------------------------------------------------------------------------------
if(check_adc==1)
{
volt_adc= read_adc();
check_adc=0;
tick_t0=0;
}
// ---------------------------------------------------------------------------------------------------------
if( mode==0)
{
pulse_delay=0;
loop=1;
}
else if(mode==1)
{
pos_width=2510;
neg_width=3374;
if(volt_adc>=0 && volt_adc<=151) { loop=2; pulse_delay=89581;}
else if(volt_adc>884) { loop=15; pulse_delay=7205;}
}
else if(mode==2) { pos_width=2187; neg_width=3059;}
else if(mode==3) { pos_width=7111; neg_width=8000;}
else if(mode==4) { }
// ---------------------------------------------------------------------------------------------------------
if( (volt_adc>=0) && (volt_adc<=40) )
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=11197; neg_width=11557;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>40 && volt_adc<=43)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=10800; neg_width=11209;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>43 && volt_adc<=59)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=10796; neg_width=11000;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>59 && volt_adc<=78)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=10596; neg_width=10809;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>78 && volt_adc<=110)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=10202; neg_width=10606;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>110 && volt_adc<=151)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=9995; neg_width=10208;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>151 && volt_adc<=210)
{
if( mode==1) { loop=3; pulse_delay=83697;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=9395; neg_width=9608;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>210 && volt_adc<=267)
{
if( mode==1) { loop=4; pulse_delay=77813;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=8795; neg_width=9008;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>267 && volt_adc<=327)
{
if( mode==1) { loop=5; pulse_delay=71929;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=8195; neg_width=8608;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>327 && volt_adc<=379)
{
if( mode==1) { loop=6; pulse_delay=66045;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=7595; neg_width=8001;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>379 && volt_adc<=430)
{
if( mode==1) { loop=7; pulse_delay=60161;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=6994; neg_width=7602;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>430 && volt_adc<=481)
{
if( mode==1) { loop=8; pulse_delay=54277;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=6401; neg_width=7001;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>481 && volt_adc<=547)
{
if( mode==1) { loop=9; pulse_delay=48393;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=5994; neg_width=6407;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>547 && volt_adc<=599)
{
if( mode==1) { loop=9; pulse_delay=42509;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=5394; neg_width=5807;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>599 && volt_adc<=657)
{
if( mode==1) { loop=10; pulse_delay=36625;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=4994; neg_width=5207;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>657 && volt_adc<=716)
{
if( mode==1) { loop=11; pulse_delay=30741;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=4394; neg_width=4607;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>716 && volt_adc<=766)
{
if( mode==1) { loop=12; pulse_delay=24857;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=3594; neg_width=4007;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>766 && volt_adc<=833)
{
if( mode==1) { loop=13; pulse_delay=18973;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=3194; neg_width=3607;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>833 && volt_adc<=884)
{
if( mode==1) { loop=14; pulse_delay=13089;}
else if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=2594; neg_width=3007;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>884 && volt_adc<=917)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=2394; neg_width=2607;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>917 && volt_adc<=952)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=1993; neg_width=2406;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>952 && volt_adc<=968)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=1606; neg_width=2200;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>968 && volt_adc<=980)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=1593; neg_width=2000;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>980 && volt_adc<=991)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=1400; neg_width=2000;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>991 && volt_adc<=1004)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=1400; neg_width=1806;}
}
//---------------------------------------------------------------------------------------------
else if ( volt_adc>1004)
{
if(mode==2) {}
else if(mode==3) {}
else if(mode==4) {}
else { pos_width=1202; neg_width=1607;}
}
out_pulse();
}
}
|
_________________ Begin Begin Begin !!!
Last edited by tienchuan on Mon Dec 21, 2015 3:22 am; edited 1 time in total |
|
|
|