mrfunkyjay said:My problem is still, difficult to have both flashing modes for steering and throttle triggers run at the same time (well not at the same time, but almost the same time).
thanks 3v0 for your explanation, I appreciate it so much
Now I used the code from Mike, I changed a little bit in Delay. Here what I get.
both LED function - Steering and Throttle run simultaneously, good that I saw difference compared to the first source code before. The thing is they kinda lag.
To explain it further, let's say I have a blinking rate for steering lights as 1s ON then 1s OFF until forever. When I send a throttle signal to it (while steering lights are still blinking), the steering lights kinda lagging. I am not sure about the period of flashing but it seems double or less. 2s ON then 2s OFF.
If you mean that there is a delay between when you move the stick and when the lights indicate the change try making the delay smaller. The LEDs may seem to stay on because they are flashing fast with a small delay. In Mikes code the sample rate and the blink rate are the same.
Well, for your code, 3v0, it seems that I have miscalculated the counter or something in timing issue. I got my LEDs for steering not blinking at all, or perhaps, it blinked, but it was too fast. Something wrong with the setting.
I use 20Mhz ext osc and I read somewhere to calculate the amount of delay you want to have, simply divide the freq OSC by 4, count the period by T=1/f and lastly multiply by the instruction cycle. If I noticed here, to calculate the instruction cycle, it is just another way around.
Delay10KTCYx(n) delays multiples of 10,000 Tcy.
The osc is 20,000,000. The instruction rate is 4 time slower or 5,000,000. The period is 1/(instruction rate) or 0.0000002. Then (0.0000002 * 10,000) is .002 seconds. So n is (delay_in_seconds/.002). Hope I got that rightIf you want to blink once per second use a delay of about ((1/256)/.002). (1/256) because you need to go through the loop 256 times for one blink. The actual blink rate will be a little slower because it takes time to execute the code, most the sample.
For your case 3v0, the thing that I did not really understand is the usage of 8bit counter here. I know it has range of 0-255. and simply half of it would be 127. But I just don't really get the logic of count>0x7f you wrote before. Hmm I mean, atm I used Delay10KTCYx(n), which n range from 0-255 to add delays. Hmm, I would be extremely happy if you would explain. Thanks in advance!
(count>0x7F) evaluates to a 0 for count less then 7F and 1 for count equal or greater to 7F.
So instead of
I can write the single line.Code:if (count>0x7F) { LATBbits.LATB0 = 1; } else { LATBbits.LATB0 = 0; }
Code:LATBbits.LATB0 = (count>0x7F);
My code will measure the pulse and set the LEDs 255 times for each LED blink (on/off). Use this simple code to test the blink rate.
Get that working and set the delay to blink the led at the rate you want.Code:unsigned char count; // make count a byte count = 0; while(1) { LATBbits.LATB0 = (count>0x7F); count++; delay(some value) }
Use that delay in the code I posted earlier and you should get the right blink rate.
Regards,
Kelvin
Hmm I have tried to decrease the delays, but it seems that the "lag" still there. If you mentioned computer is fast, then could it be, my Ext OSC is damaged?? Should I try changing to new one?
#include <p18f4520.h>
#include <delays.h>
#pragma config OSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#define L_LED LATBbits.LATB0
#define R_LED LATBbits.LATB1
int i, iPulse1, iPulse2;
/*Counts the length of a pulse on Pin RA1*/
int GetPulse1(){
T1CON=0b00000000; /*Init timer1*/
TMR1L=0;
TMR1H=0;
TRISAbits.TRISA1=1; /*Make this pin as an input*/
while(PORTAbits.RA1==1); /*Make pin low*/
while(PORTAbits.RA1==0); /*While pin is high*/
T1CONbits.TMR1ON=1; /*Start timer0*/
while(PORTAbits.RA1==1); /*When pin is low*/
T1CONbits.TMR1ON=0; /*Stop timer0*/
return TMR1H*256+TMR1L; /*return 16bit timer value*/
}
/*Counts the length of a pulse on Pin RA2*/
int GetPulse2(){
T3CON=0b00000000; /*Init timer3*/
TMR3L=0;
TMR3H=0;
TRISAbits.TRISA2=1; /*Make this pin as an input*/
while(PORTAbits.RA2==1); /*Make pin low*/
while(PORTAbits.RA2==0); /*While pin is high*/
T3CONbits.TMR3ON=1; /*Start timer0*/
while(PORTAbits.RA2==1); /*When pin is low*/
T3CONbits.TMR3ON=0; /*Stop timer0*/
return TMR3H*256+TMR3L; /*return 16bit timer value*/
}
void main(void)
{
TRISA = 0b00000111; /*Initialize RA0 as Input Port to read PWM Signal*/
TRISB = 0b00000000; /*Initialize Port B as Output Port to flash LEDs*/
ADCON1 = 15; /*Digital Input*/
PORTB = 0;
while(1)
{
L_LED = 0;
R_LED = 0;
iPulse1=GetPulse1();
if(iPulse1<7000){ /*If the Pulse Width is less than 1.4ms*/
R_LED = 0;
Delay10KTCYx(200);
L_LED = ~L_LED; /*Blinks left LED*/
Delay10KTCYx(150);
}
if(iPulse1>8000){ /*If the Pulse Width is more than 1.6ms*/
L_LED = 0;
Delay10KTCYx(200);
R_LED = ~R_LED; /*Blinks right LED*/
Delay10KTCYx(150);
}
iPulse2=GetPulse2();
if (iPulse2 < 6000)
{
for(i=0;i<1;i++)
{
LATBbits.LATB2 = 1;
Delay10KTCYx(50);
LATBbits.LATB2 = 0;
Delay10KTCYx(50);
LATBbits.LATB3 = 1;
Delay10KTCYx(50);
LATBbits.LATB3 = 0;
Delay10KTCYx(50);
LATBbits.LATB4 = 1;
Delay10KTCYx(50);
LATBbits.LATB4 = 0;
Delay10KTCYx(50);
LATBbits.LATB5 = 1;
Delay10KTCYx(50);
LATBbits.LATB5 = 0;
Delay10KTCYx(50);
}
}
if (iPulse2 > 8000)
{
for(i=0;i<1;i++)
{
LATBbits.LATB2 = 1;
Delay10KTCYx(30);
LATBbits.LATB2 = 0;
Delay10KTCYx(30);
LATBbits.LATB3 = 1;
Delay10KTCYx(30);
LATBbits.LATB3 = 0;
Delay10KTCYx(30);
LATBbits.LATB4 = 1;
Delay10KTCYx(30);
LATBbits.LATB4 = 0;
Delay10KTCYx(30);
LATBbits.LATB5 = 1;
Delay10KTCYx(30);
LATBbits.LATB5 = 0;
Delay10KTCYx(30);
}
}
}
}
Delay10KTCYx(50);
LATBbits.LATB2 = 0;
Delay10KTCYx(50);
LATBbits.LATB3 = 1;
Delay10KTCYx(50);
LATBbits.LATB3 = 0;
Delay10KTCYx(50);
LATBbits.LATB4 = 1;
Delay10KTCYx(50);
LATBbits.LATB4 = 0;
Delay10KTCYx(50);
LATBbits.LATB5 = 1;
Delay10KTCYx(50);
LATBbits.LATB5 = 0;
Delay10KTCYx(50);
unsigned char Mask = 0b00000100; //
...
if (Pulse2 > 16000) // if Pulse2 > 1.6 msecs
{ LATB &= ~Mask; // turn off previous LED
if (Mask == 0b00100000) // if RB5 (end of sequence)
Mask = 0b00000100; // reset mask for RB2
else // else
Mask <<= 1; // shift Mask bit left
LATB |= Mask; // turn on new LED
}
else // if Pulse2 < 1.6 msecs
{ LATB &= 0b00000011; // clear RB2..RB5 LEDs
Mask = 0b00000100; // reset mask for RB2
}
#include <p18f4520.h>
#include <delays.h>
#pragma config OSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#define L_LED LATBbits.LATB0
#define R_LED LATBbits.LATB1
int i, iPulse1, iPulse2;
unsigned char Mask = 0b00000100;
/*Counts the length of a pulse on Pin RA1*/
int GetPulse1(){
T1CON=0b00000000; /*Init timer1*/
TMR1L=0;
TMR1H=0;
TRISAbits.TRISA1=1; /*Make this pin as an input*/
while(PORTAbits.RA1==1); /*Make pin low*/
while(PORTAbits.RA1==0); /*While pin is high*/
T1CONbits.TMR1ON=1; /*Start timer0*/
while(PORTAbits.RA1==1); /*When pin is low*/
T1CONbits.TMR1ON=0; /*Stop timer0*/
return TMR1H*256+TMR1L; /*return 16bit timer value*/
}
/*Counts the length of a pulse on Pin RA2*/
int GetPulse2(){
T3CON=0b00000000; /*Init timer3*/
TMR3L=0;
TMR3H=0;
TRISAbits.TRISA2=1; /*Make this pin as an input*/
while(PORTAbits.RA2==1); /*Make pin low*/
while(PORTAbits.RA2==0); /*While pin is high*/
T3CONbits.TMR3ON=1; /*Start timer0*/
while(PORTAbits.RA2==1); /*When pin is low*/
T3CONbits.TMR3ON=0; /*Stop timer0*/
return TMR3H*256+TMR3L; /*return 16bit timer value*/
}
void main(void)
{
TRISA = 0b00000111; /*Initialize RA0 as Input Port to read PWM Signal*/
TRISB = 0b00000000; /*Initialize Port B as Output Port to flash LEDs*/
ADCON1 = 15; /*Digital Input*/
PORTB = 0;
while(1)
{
Delay10KTCYx(150);
iPulse1 = GetPulse1();
if (iPulse1 < 7000) // if Pulse1 < 1.4ms
{
R_LED = 0; // turn off right LED
L_LED = ~L_LED; // toggle left LED @ 2 Hz
}
if (iPulse1 > 8000) // if Pulse1 > 1.6ms
{
L_LED = 0; // turn off left LED
R_LED = ~R_LED; // toggle right LED @ 2 Hz
}
iPulse2 = GetPulse2();
if (iPulse2 < 6000) // if Pulse2 < 1.4ms
{
LATB &= ~Mask; // turn off previous LED
if (Mask == 0b00100000) // if RB5 (end of sequence)
Mask = 0b00000100; // reset mask for RB2
else // else
Mask <<= 1; // shift Mask bit left
LATB |= Mask; // turn on new LED
}
if (iPulse2 > 9000) // if Pulse2 > 1.8ms
{
LATB &= ~Mask; // turn off previous LED
if (Mask == 0b00000100) // if RB2 (end of sequence)
Mask = 0b00100000; // reset mask for RB5
else // else
Mask >>= 1; // shift Mask bit right
LATB |= Mask; // turn on new LED
}
if (iPulse1 >= 7001 && iPulse1 <= 7999) //Steering Standby Mode
{
L_LED = 0;
R_LED = 0;
}
if (iPulse2 >= 6001 && iPulse2 <= 8999) //Throttle Standby Mode
{
LATBbits.LATB2 = 0;
LATBbits.LATB3 = 0;
LATBbits.LATB4 = 0;
LATBbits.LATB5 = 0;
}
}
}
unsigned byte prcnt, brightness;
prcnt = 0;
while(1)
{
LATBbits.LATB0 = (prcnt < brightness);
prcnt++;
if (prcnt>99)
{
prcnt = 0;
}
}
unsigned byte prcnt, brightness;
prcnt = 0;
while(1)
for (brightness=0; brightness<100; brightness++)
{
LATBbits.LATB0 = (prcnt < brightness);
prcnt++;
if (prcnt>99)
{
prcnt = 0;
}
}
unsigned byte prcnt, brightness;
while(1)
{
for (prcnt=0; prcnt<100; prcnt++)
{
// do not sample every time through the loop
if (prcnt == 0)
{
iPulse1=GetPulse1();
if (iPulse1 < 7000) // if Pulse1 < 1.4ms
{
R_LED = 0; // turn off right LED
L_LED = ~L_LED; // toggle left LED @ 2 Hz
}
if (iPulse1 > 8000) // if Pulse1 > 1.6ms
{
L_LED = 0; // turn off left LED
R_LED = ~R_LED; // toggle right LED @ 2 Hz
}
}
// do not sample every time through the loop
if (prcnt == 0)
{
iPulse2=GetPulse2();
if (iPulse2>9000)
{
brightness = 100;
}
else
{
brightness = 50;
}
}
// every time we check to see if we need to turn of LED
LATBbits.LATB4 = (prcnt < brightness); // on while prctn < brightness
prcnt++;
if (prcnt>99)
{
prcnt = 0;
}
delay(??);
}
}
Okay!!!!!!!!! It is working, thanks a lot!!
Btw, now for simulating the braking signal, hmm, how to put this.
Initial condition:
50% brightness LED
iPulse2 > 9000:
100% brightness LED
Any comments? Thanks!!!
Yes, it is good to know how to do it both ways.Some good suggestions above but, be aware that (each of) the GetPulse routine(s) could wait 20mS before returning. It may be simpler to have the variable LED fed by two pins and use two resistors and only switch 1 pin to output at any time.
Mike.
That's why I suggested collecting pulse width values as a background task. I didn't push it however because interrupt processing can be a bit overwhelming for newcomers and I also thought that a variable 20 to 40 msecs wouldn't affect the timing that much with the relatively long delays we were talking about. Now that we're considering shorter loop delays, it could be a factor.
Mike
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?