View previous topic :: View next topic |
Author |
Message |
pdl
Joined: 01 Jun 2005 Posts: 45 Location: UK
|
Any other way |
Posted: Sun Jul 13, 2008 2:58 pm |
|
|
Hi guys
is there any other way of doing this program.
Code: |
#include <12F629.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOCPD //No EE protection
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOPUT //No Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES BANDGAP_HIGH
#use delay(clock=4000000)
#define PWM_PIN Pin_A2
#define Rx_Input Pin_A3
#define Min_Width 0x07 // 1.0mS / 128uS = 07dec = 07h.
#define Max_Width 0x0F // 2.0mS / 128uS = 16dec = 0Fh.
#define Low_Trip 0x0A // 1.4mS / 128uS = 10dec = 0Ah.
#define High_Trip 0x0C // 1.6mS / 128uS = 12dec = 0Ch.
#define Max_Frame 0x9C // 20mS / 128us = 156dec = 9Ch.
int i;
void lighton(){
for(i=0; i<30; i++){
output_high(PWM_PIN);
delay_us(5500);
output_low(PWM_PIN);
delay_us(4500);
}
}
void wait_for_low_to_high() {
while(input(Rx_Input)) ;
delay_us(3);
while(!input(Rx_Input));
}
void wait_for_low() {
delay_us(3);
while(input(Rx_Input));
}
void main(void)
{
int PulseWidth;
int BeginPulse;
setup_counters( RTCC_INTERNAL, RTCC_DIV_128 );
while(1)
{
wait_for_low_to_high();
BeginPulse = get_rtcc();
wait_for_low();
PulseWidth = (get_rtcc() - BeginPulse);
if (PulseWidth >= High_Trip)
{
lighton();
}
}
} |
thanks
Pete |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sun Jul 13, 2008 3:47 pm |
|
|
Quote: | is there any other way of doing this program. | Yes.
But for us to give a hint to a solution it would be very helpful if you can tell us why your implementation isn't good for the job. |
|
|
pdl
Joined: 01 Jun 2005 Posts: 45 Location: UK
|
|
Posted: Mon Jul 14, 2008 12:42 am |
|
|
I am trying to light an led with out a resistor and with out it flickering and turning ever now and again
Pete |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Jul 14, 2008 1:28 am |
|
|
I could give you ten possible suggestions for implementing such a function and than have you choose the single suggestion fitting your needs ...
... or you give more details about your system and requirements.
Because of my limited (spare) time you'll have to do with the last option. Also explain _why_ your example code is not sufficient. |
|
|
pdl
Joined: 01 Jun 2005 Posts: 45 Location: UK
|
|
Posted: Mon Jul 14, 2008 2:01 am |
|
|
Thank you for you help ckielstra as you can see by my code i am new to C.
The Led Flickers ever now and again
What i would like when the program sees 1.6ms and a bove the Led stays on until the pluse is no longer 1.6ms or greater.
its just not stable a the minute
Pete |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Jul 14, 2008 3:27 am |
|
|
I don't know the characteristics of your input signal, but most likely the waiting for a pulse is what causes your LED to flicker.
The easiest method to solve this is by removing the LED modulation out of the main loop. Create a timer driver interrupt which will drive your LED. Right now I don't have time to post example code but if you search this forum with the keywords 'soft PWM' you will find some related posts. |
|
|
pdl
Joined: 01 Jun 2005 Posts: 45 Location: UK
|
|
Posted: Mon Jul 14, 2008 3:43 am |
|
|
I have tried that
I tried to use some of this code but could not get it to work properly.
The input pulse is a 1ms to 2ms pulse the same type of pluse that drives a model servo.
thanks
Pete
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#define PWM_PIN PIN_B0
#define LOOPCNT 39
int8 width;
//-------------------------------
#INT_RTCC
void tick_interrupt(void);
//====================================
main()
{
width = 0;
setup_counters(RTCC_INTERNAL, RTCC_DIV_1);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
// Step through all values for width, from 0 to 39.
// This will slowly increase the duty cycle from 0 to 100%,
// by doing one step every 100 ms.
while(1)
{
for(width = 0; width <= LOOPCNT; width++)
delay_ms(100);
}
}
//====================================
#INT_RTCC
void tick_interrupt(void)
{
static int8 loop = LOOPCNT;
static int8 pulse;
if(--loop == 0)
{
loop = LOOPCNT;
pulse = width;
}
if(pulse)
{
output_high(PWM_PIN);
pulse--;
}
else
{
output_low(PWM_PIN);
}
} |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Jul 14, 2008 5:12 am |
|
|
Code: | #include <16F877.H> | Are you sure this is correct? Your first post was using a PIC12F629
Code: | #fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP | The XT fuse is for an external crystal. Your first post was using the internal clock generator. |
|
|
pdl
Joined: 01 Jun 2005 Posts: 45 Location: UK
|
|
Posted: Mon Jul 14, 2008 5:19 am |
|
|
Yes i changed the pic i was using
i tried to use some of this code with the pulse measurement code and i could not get it working
Pete |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Jul 14, 2008 6:36 am |
|
|
Try to be more detailed in your descriptions, just saying 'it's not working' is too limited. What do you expect to see, what is different and what behaviour do you actually see?
Are you using the PIC16F877 or the PIC16F877A? The first is very old...
Note that the PIC16F877 has two internal PWM hardware modules which are easier to use, will work more accurate and have less impact on the CPU usage than the soft PWM based on interrupts. |
|
|
pdl
Joined: 01 Jun 2005 Posts: 45 Location: UK
|
|
Posted: Mon Jul 14, 2008 7:44 am |
|
|
Hi ckielstra
I am using the 12f629
When i say it did not work i was putting a 1ms to 2 ms pulse in on PIN_A3 and was not getting anything out of PIN_A2 but looking at it now i think that the ICD was setup for MCLR and not I/O.
I expect For the LED to light when i put a 1.6ms pulse on PIN_A3
PIN_A2 should have a 100hz PWM output a 50% duty
When the input pulse is below 1.6ms the LED should stay turned off and not come on until the 1.6ms pulse is back on the input pin.
hope this a bit more clear
Pete |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Mon Jul 14, 2008 9:18 am |
|
|
pdl wrote: | I am trying to light an led with out a resistor and with out it flickering and turning ever now and again
Pete |
So what sets the current during the ON time? Are you relying on the over-current protection of the PIC pin logic? That is going to be very temperature sensitive. This may be OK for a home project, but I would not recommend it for a commercial product! _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
pdl
Joined: 01 Jun 2005 Posts: 45 Location: UK
|
|
Posted: Mon Jul 14, 2008 9:47 am |
|
|
I am using a Mosfet as the LEDs i am using draw 350ma at 3.6v
Pete |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Jul 14, 2008 3:52 pm |
|
|
Thanks for explaining your circuit in more detail. Now it makes more sense.
Quote: | When i say it did not work i was putting a 1ms to 2 ms pulse in on PIN_A3 and was not getting anything out of PIN_A2 but looking at it now i think that the ICD was setup for MCLR and not I/O. | Does it work after fixing the MCLR setup?
If not, please post your code for the PIC12F629 and tell us what behaviour you see. |
|
|
pdl
Joined: 01 Jun 2005 Posts: 45 Location: UK
|
|
Posted: Mon Jul 14, 2008 6:42 pm |
|
|
Here is my code so far i now can turn on some sort of PWM with my input which is 1ms to 2ms and the trip should be 1.6ms but i can not get the
timing right to get 100Hz 50% duty from the PWM pin
I have a Mosfet which i supply 7.4v to and with the 50%duty from the PWM i was hoping to get 3.7v output from the Mosfet.
thanks
Pete
Code: |
#include <12F629.h>
#FUSES NOWDT, INTRC_IO, NOCPD, NOPROTECT, NOMCLR, NOPUT, NOBROWNOUT, BANDGAP_HIGH
#use delay(clock=4000000)
#define PWM_PIN PIN_A2
#define Rx_Input PIN_A3
#define Min_Width 0x07 // 1.0mS / 128uS = 07dec = 07h.
#define Max_Width 0x0F // 2.0mS / 128uS = 16dec = 0Fh.
#define Low_Trip 0x0A // 1.4mS / 128uS = 10dec = 0Ah.
#define High_Trip 0x0C // 1.6mS / 128uS = 12dec = 0Ch.
#define Max_Frame 0x9C // 20mS / 128us = 156dec = 9Ch.
#define LOOPCNT 39
int8 width;
#INT_RTCC
void tick_interrupt(void)
{
static int8 loop = LOOPCNT;
static int8 pulse;
if(--loop == 0)
{
loop = LOOPCNT;
pulse = width;
}
if(pulse)
{
output_high(PWM_PIN);
pulse--;
}
else
{
output_low(PWM_PIN);
}
}
void wait_for_low_to_high() {
while(input(Rx_Input)) ;
delay_us(3);
while(!input(Rx_Input));
}
void wait_for_low() {
delay_us(3);
while(input(Rx_Input));
}
void main()
{
int PulseWidth;
int BeginPulse;
width =19;
setup_counters( RTCC_INTERNAL, RTCC_DIV_128 );
while(1)
{
wait_for_low_to_high();
BeginPulse = get_rtcc();
wait_for_low();
PulseWidth = (get_rtcc() - BeginPulse);
if (PulseWidth >= High_Trip)
{
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
}
if (PulseWidth <= Low_Trip)
{
clear_interrupt(INT_RTCC);
disable_interrupts(INT_RTCC);
disable_interrupts(GLOBAL);
output_low(PIN_A2);
}
}
} |
|
|
|
|