Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] 16F877A LED lag when ADC value changes

Status
Not open for further replies.

shsn

Junior Member level 3
Junior Member level 3
Joined
Nov 28, 2012
Messages
26
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,523
Hi,


I have written some code that turns on specific LED(s) depending on the ADC value. But when I implement the code on the hardware, a rapid change in input voltage causes the 16F877A to turn the LED(s) on with a few milliseconds of delay. If anyone could please have a look at the code and possibly recommend me a correct direction to drive the LEDs as quickly as possible?

I think the cause of the delay is due to 'too many' if statements as each instruction takes a certain time.

This was my first attempt:
Code:
unsigned int adc_val;
unsigned long volts_m;

void main() {

     TRISD   = 0;                               // PORTD all output to LED
     TRISC   = 0;                               // PORTC all output to LED
     ADCON1  = 0x88;                            // configure Vref, and analog channels
     TRISA   = 0xFF;                            // designate PORTA as input
     
     for (;;) {
           adc_val = ADC_read(1);               // get ADC value for U from channel 1
           volts_m = (long)adc_val*5000/1023;   // Convert ADC value to millivolts
           
           // 0 LED, Target voltage = 0.0v, Range 0.0 - 0.3v
           if (volts_m >= 0 && volts_m <= 350) {
              PORTD = 0b00000000;
              PORTC = 0b00000000;
           }
           // 1 LED, Target voltage = 0.5v, Range 0.4 - 0.6v
           if (volts_m > 350 && volts_m <= 700) {
              PORTD = 0b00000100;
              PORTC = 0b00000000;
           }
           // 2 LEDs, Target voltage = 1.0v, Range 0.9 - 1.1v
           if (volts_m > 700 && volts_m <= 1300) {
              PORTD = 0b00001100;
              PORTC = 0b00000000;
           }
           // 3 LEDs, Target voltage = 1.5v, Range 1.4 - 1.6v
           if (volts_m > 1300 && volts_m <= 1700) {
              PORTD = 0b00001100;
              PORTC = 0b00010000;
           }
           // 4 LEDs, Target voltage = 2.0, Range 1.9 - 2.1v
           if (volts_m > 1700 && volts_m <= 2300) {
              PORTD = 0b00001100;
              PORTC = 0b00110000;
           }
           // 5 LEDs, Target voltage = 2.5, Range 2.4 - 2.6v
           if (volts_m > 2300 && volts_m <= 2700) {
              PORTD = 0b00001100;
              PORTC = 0b01110000;
           }
           // 6 LEDs, Target voltage = 3.0, Range 2.9 - 3.1v
           if (volts_m > 2700 && volts_m <= 3300) {
              PORTD = 0b00001100;
              PORTC = 0b11110000;
           }
           // 7 LEDs, Target voltage = 3.5, Range 3.4 - 3.6v
           if (volts_m > 3300 && volts_m <= 3700) {
              PORTD = 0b00011100;
              PORTC = 0b11110000;
           }
           // 8 LEDs, Target voltage = 4.0, Range 3.9 - 4.1v
           if (volts_m > 3700 && volts_m <= 4300) {
              PORTD = 0b00111100;
              PORTC = 0b11110000;
           }
           // 9 LEDs, Target voltage = 4.5, Range 4.4 - 4.6v
           if (volts_m > 4300 && volts_m <= 4700) {
              PORTD = 0b01111100;
              PORTC = 0b11110000;
           }
           // Flash LEDs, Target voltage = 5.0, Range 4.8 - 5.0v
           if (volts_m > 4700 && volts_m <= 5000) {
              do {
                 PORTD = 0b00000000;
                 PORTC = 0b00000000;
                 delay_ms(300);
                 PORTD = 0b01111100;
                 PORTC = 0b11110000;
                 delay_ms(300);

              }
              while (volts_m > 4700 && volts_m <= 5000);
           }
     }
}

And this is my second set of code that I'm currently working on:
Code:
unsigned int adc_val;

void led (unsigned int adc_val) {
     // LED operation routine goes here
}

void main() {
     PORTC = 0;
     PORTD = 0;
     TRISD = 0;
     TRISC = 0;

     do {
        adc_val = ADC_read(1);
        led (adc_val);
     }
     while(1);
}

I've heard that there are ways to code so that the PIC can 'multitask', for instance continously check for change in ADC value while driving the LED depending on the ADC value. Or am I over my head?

Thank you :)
 

I've solved the issue, simply by re-writing the code; instead of multiple if statements, I've swapped it with else if.
It seems once a match is found, it skips other conditions. Also I have created another routine just for driving the LEDs.
The LEDs are responding very nicely now.
 

Warning [361] D:\Testing\MPLAB\ADC\Untitled.c; 18.11 function declared implicit int;

How to rectify problem in this line ( adc_val = ADC_read(1) ) ?
 

Warning [361] D:\Testing\MPLAB\ADC\Untitled.c; 18.11 function declared implicit int;

How to rectify problem in this line ( adc_val = ADC_read(1) ) ?

Code:
adc_val = ADC_read(1)

The above line uses the library function ADC_Read(). This is a function for mikroC. shsn has used mikroC, whereas you are using another compiler such as Hi-Tech C or CCS C.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top