LED control using c programming

Thread Starter

Don Omar

Joined May 5, 2017
49
Hi dear,
I really need Ur help with this program that i have to do
In a continuous loop and using the SYNC pulse from the pickit3 as a reference, i need to generate a variable length waveform on bit RB1 (bottom segment of display) .
The output will normally be low and will go high for anything between approximately 250 µs and 4 ms depending on the setting of the potentiometer which is attached to pin A0.
could you please help me
thanks
 

Thread Starter

Don Omar

Joined May 5, 2017
49
Did you decide which PIC microcontroller you will use?
Hi shteii01,
im using the pic18f1220 and this is what i have done i cant go any further please help me


C:
#include    <xc.h>
#include    <timers.h>
#include    <adc.h>

#define        TRUE    1
#define        FALSE    0

// Configuration settings
#pragma config OSC=HS,FSCM=OFF,IESO=OFF
#pragma config PWRT=ON,BOR=OFF,BORV=45
#pragma config WDT=OFF
#pragma config MCLRE=ON
#pragma config STVR=OFF,LVP=OFF,DEBUG=OFF
#pragma config CP0=OFF,CP1=OFF
#pragma config CPB=OFF,CPD=OFF
#pragma config WRT0=OFF,WRT1=OFF
#pragma config WRTB=OFF,WRTC=OFF,WRTD=OFF
#pragma config EBTR0=OFF,EBTR1=OFF
#pragma config EBTRB=OFF

///////////////

void main(void)
{
    OSCCONbits.SCS0=0;     //set oscillator to external
    OSCCONbits.SCS1=0;
    TRISA = 0b00110011;        //Set port input output directions
    TRISB = 0b11000100;
    ADCON1 = 0b11111100;    //All bits digital I/O except AN0 and AN1
    RCON=0b00000000;        //disable interrupt priorities (compatible with 16F series)
    INTCON=0b00000000;        //disable interrupts
    INTCON2=0b00000000;     //pull-ups enabled interrupt are all low priority
    PORTA=0xFF;            //Turn off seven segment display
    PORTB=0xFF;            //Note LED?s active low ie turned on with logic 0
    PORTBbits.RB4 = 0;
    LATB=0b11111111;
    LATA=0b11111111;

    OpenTimer0 (TIMER_INT_OFF    & //no timer interrupts
                T0_16BIT        & //16 bit mode
                T0_SOURCE_INT    &
                T0_EDGE_FALL    & //Not important for this
                T0_PS_1_64           // divide by 64 prescaler  
                );
    OpenADC(    ADC_FOSC_16 & ADC_LEFT_JUST & ADC_8_TAD,
            ADC_CH0 & ADC_INT_OFF & ADC_VREFPLUS_VDD,
            0b01111110 ); //ADCON1 - AN0 set as analogue in
Mod edit: code tags
 
Last edited by a moderator:

danadak

Joined Mar 10, 2018
4,057
Assuming goal is the change brightness of LED with respect to POT voltage
you would -

1) Set up a PWM, period faster than human eye bling rate, say 100 Hz or more for the
period.
2) Take A/D input, and that becomes the compare value for the PWM to vary the pulse
width. If TIMER and A/D 8 bit, then virtual hand-off of data between A/D and compare
register of PWM. If PWM 16 bits, A/D N bits (N < 16) then take A/D result and left shift
by 16 -N so that A/D value occupies MSBs of compare register.

3) Obviously compare reg flag/interrupt becomes basis for turning on/off LED.

Regards, Dana.
 

Thread Starter

Don Omar

Joined May 5, 2017
49
Assuming goal is the change brightness of LED with respect to POT voltage
you would -

1) Set up a PWM, period faster than human eye bling rate, say 100 Hz or more for the
period.
2) Take A/D input, and that becomes the compare value for the PWM to vary the pulse
width. If TIMER and A/D 8 bit, then virtual hand-off of data between A/D and compare
register of PWM. If PWM 16 bits, A/D N bits (N < 16) then take A/D result and left shift
by 16 -N so that A/D value occupies MSBs of compare register.

3) Obviously compare reg flag/interrupt becomes basis for turning on/off LED.

Regards, Dana.
Hi Dana,
thanks for ur help i really appreciate it
i found this code online please have a look at it ,i dont understand how to make the output go low and high between 250 µs and 4 ms
thanks

C:
while (1)
{
ADCON0bits.GO_DONE=1; //do A/D measurement
while(ADCON0bits.GO_DONE==1);
analog_reading= ADRESL + (ADRESH *256);

PORTBbits.RB4= analog_reading;
}
}
Mod edit: code tags.
 
Last edited by a moderator:

JohnInTX

Joined Jun 26, 2012
4,787
You did a lot of what you want to do in assembly language here:
https://forum.allaboutcircuits.com/threads/led-flashing-rate-control-using-pic16f684.135040/

You should be able to take the basic design methodology and implement it in C without much trouble. That project uses the ADC and PWM. The design methods used are the same regardless of the language. Revisit that thread, review the code and flowcharts there, make necessary revisions to that design and code it in C.

But, as discussed at length in that thread, if your design process continues to be scabbing code from the internet without designing and understanding the solution yourself, you probably are in for a difficult time once again.

Good luck!
 

Thread Starter

Don Omar

Joined May 5, 2017
49
You did a lot of what you want to do in assembly language here:
https://forum.allaboutcircuits.com/threads/led-flashing-rate-control-using-pic16f684.135040/

You should be able to take the basic design methodology and implement it in C without much trouble. That project uses the ADC and PWM. The design methods used are the same regardless of the language. Revisit that thread, review the code and flowcharts there, make necessary revisions to that design and code it in C.

But, as discussed at length in that thread, if your design process continues to be scabbing code from the internet without designing and understanding the solution yourself, you probably are in for a difficult time once again.

Good luck!
Hi JohnInTX,
thanks for Ur reply,i tried to understand but it so difficult please help me this time i dont know where to start, i forgot everything about the assembler programming i did this is all new to me
 

JohnInTX

Joined Jun 26, 2012
4,787
Hi JohnInTX,
thanks for Ur reply,i tried to understand but it so difficult please help me this time i dont know where to start, i forgot everything about the assembler programming i did this is all new to me
Sorry. The fact that you spent less than 18 minutes replying says that you didn't look much at the thread I referenced, if at all, nor any others in the Similar Threads window. A number of members invested lots of time with you over there and I pointed out that this new assignment is very similar to that one so it would be a good starting point. But IMHO, you continue to demonstrate that you are unwilling to invest the time and effort necessary for success or even enough to provide some motivation to offer help. I can't speak for other members but this one is a non-starter for me.

Good luck.
 

danadak

Joined Mar 10, 2018
4,057
At the most basic level a PWM is a counter with a period value. So
you set the period in counts, and a clock makes it go up to period
value (if it was implemented with up counter) and then reloads and
repeats the cycle. If a down counter it counts down from the period
value to 0, then reloads and repeats. In either case the counter can
also be thought as a freq divider.

So if I set period = 10, clock in = 100 Hz, the counter cycle is
10 Hz.

Now add a register that has a value in it <= period value. And couple
that register and the PWM counter with a logical comparator. So for
example let period = 9, compare = 4, counter is up counter. Let
compare operation true if PWM counter > compare value. So PWM
counter counts from 0, hits 5, and the comparator out goes
true during 5 6 7 8 9, then counter resets to 0 and does this over,
but when it goes from 9 to 0 the compare operation is no longer
true so outputs 0. So for compare output, counter 0 - 4 its false,
counter 5 - 9 true. True/False are logic1/0 respectively.

So duty cycle of compare out is 50%. If we set compare value higher
then compare out spends less time true, so duty cycle drops. Lower
the duty cycle is higher.

This is an upcounter pwm



The compare value is labeled top value, 190, 200 is period value in above example.
As you can see for up counter implementation as compare value goes up, duty cycle
goes down. Opposite is true for down counter.

https://en.wikipedia.org/wiki/Duty_cycle

Regards, Dana.
 
Last edited:

Thread Starter

Don Omar

Joined May 5, 2017
49
its been a week since last time ,i tried to do something the only thing i manage to do is this code i tried it on pic-kit3 its seems to be working all it does is changing the flashing rate of the led but i dont know if will work once i use the reference voltage. im really confused plz see if you can help me thanks


C:
#include <p18f1220.h>
#pragma config WDT=OFF, OSC=INTIO2, PWRT=ON, LVP=OFF, MCLRE=OFF


int analog_reading;

void main(void)
{
//SET UP
ADCON1= 0b00111110; //AN0 ad AN6 are analogue
TRISA= 0b11111111; //sets PORTA as all inputs, bit0 is AN0
TRISB= 0b00000000; //sets PORTB as all outputs
PORTB= 0b00000000; //sets all outputs of PORTB off to begin with
ADCON0bits.ADON=1; //turns on A/D
ADCON2= 0b10000000; //right justified, acquisition times are at 0 with 31KHz

while (1)
{ADCON0bits.GO_DONE=1; //do A/D measurement

while(ADCON0bits.GO_DONE==1);

analog_reading= ADRESL + (ADRESH *256);


PORTBbits.RB4= analog_reading;
}
}
Mod edit: code tags
 
Last edited by a moderator:

odm4286

Joined Sep 20, 2009
265
its been a week since last time ,i tried to do something the only thing i manage to do is this code i tried it on pic-kit3 its seems to be working all it does is changing the flashing rate of the led but i dont know if will work once i use the reference voltage. im really confused plz see if you can help me thanks


C:
#include <p18f1220.h>
#pragma config WDT=OFF, OSC=INTIO2, PWRT=ON, LVP=OFF, MCLRE=OFF


int analog_reading;

void main(void)
{
//SET UP
ADCON1= 0b00111110; //AN0 ad AN6 are analogue
TRISA= 0b11111111; //sets PORTA as all inputs, bit0 is AN0
TRISB= 0b00000000; //sets PORTB as all outputs
PORTB= 0b00000000; //sets all outputs of PORTB off to begin with
ADCON0bits.ADON=1; //turns on A/D
ADCON2= 0b10000000; //right justified, acquisition times are at 0 with 31KHz

while (1)
{ADCON0bits.GO_DONE=1; //do A/D measurement

while(ADCON0bits.GO_DONE==1);

analog_reading= ADRESL + (ADRESH *256);


PORTBbits.RB4= analog_reading;
}
}
Mod edit: code tags
Ok, I wish I had more time to dig into this for you but I did notice one thing right off the bat. If you want to read ADRESL and ADRESH into an int, do this...

Code:
analog_reading = ADRESH;
analog_reading <<= 8;
analog_reading |= ADRESL;
I've included a function I use to do this from something I'm working on. Let me know if you need an explanation!

Code:
unsigned int two_bytes_to_int(char MSB, char LSB)
{
    int buffer;
    buffer = MSB;               // grab the most signifigant 8 bits
    buffer <<= 8;                 // shift buffer over 8 bits left 
    buffer |= LSB;               // or to grab the remaining 8 lower bits
    return buffer;
}
Lastly, what are you trying to do here?
Code:
PORTBbits.RB4= analog_reading;
I have a feeling you want to use the analog reading to change the state of RB4 right? Well, how do you want that state to change? A simple on/off or something gradual?
 

Thread Starter

Don Omar

Joined May 5, 2017
49
Ok, I wish I had more time to dig into this for you but I did notice one thing right off the bat. If you want to read ADRESL and ADRESH into an int, do this...

Code:
analog_reading = ADRESH;
analog_reading <<= 8;
analog_reading |= ADRESL;
I've included a function I use to do this from something I'm working on. Let me know if you need an explanation!

Code:
unsigned int two_bytes_to_int(char MSB, char LSB)
{
    int buffer;
    buffer = MSB;               // grab the most signifigant 8 bits
    buffer <<= 8;                 // shift buffer over 8 bits left
    buffer |= LSB;               // or to grab the remaining 8 lower bits
    return buffer;
}
Lastly, what are you trying to do here?
Code:
PORTBbits.RB4= analog_reading;
I have a feeling you want to use the analog reading to change the state of RB4 right? Well, how do you want that state to change? A simple on/off or something gradual?
Hi odm4286,
thanks for the reply this is what im trying to do:
In a continuous loop and using the SYNC pulse from the toothed wheel simulator as a reference, generate a variable length waveform on bit RB1 (bottom segment of display) for every crank revolution. This output will normally be low and will go high for anything between approximately 250 µs and 4 ms depending on the setting of the potentiometer which is attached to pin A0
 

odm4286

Joined Sep 20, 2009
265
Hi odm4286,
thanks for the reply this is what im trying to do:
In a continuous loop and using the SYNC pulse from the toothed wheel simulator as a reference, generate a variable length waveform on bit RB1 (bottom segment of display) for every crank revolution. This output will normally be low and will go high for anything between approximately 250 µs and 4 ms depending on the setting of the potentiometer which is attached to pin A0
Ok, sounds like you want to use PWM here. I'll try to see if I can write something for you tonight after work. In the meantime, can you post all of your code?
 
Last edited:

Thread Starter

Don Omar

Joined May 5, 2017
49
Ok, sounds like you want to use PWM here. I'll try to see if I can write something for you tonight after work. In the meantime, can you post all of your code?
Hi odm4286,
I'll really appriete ur help
The only code i did is the one I post it earlier in post 11
Thanks
 
Top