|
|
View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 31, 2017 12:51 pm |
|
|
Quote: |
it seems like it only reads channel-0 and does not read channel 4.
I noticed one thing when I'm taking input from channel 4 |
Are you sure you have the channel 4 signal connected to the correct pin ?
Analog pin AN4 is on pin RA5 in the 16F914 data sheet.
Do you accidentally have it connected to pin RA4 ? This is a common mistake. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19245
|
|
Posted: Mon Jul 31, 2017 12:58 pm |
|
|
Aargh.
Sorry.
With the two threads about ADC problems, I was looking at the F88 data sheet....
On the F88, it is handling it wrongly. On the 914 it isn't.
So this code fixes the handling on the F88 (other thread from the same poster)....
For the 914, the fix would be:
Code: |
#byte ADCON0=getenv("SFR:ADCON0")
#define SET_AN_CHANNEL(x) ADCON0=((ADCON0 & 0xE3)+(x<<2))
|
Agree for that analog pin the most likely thing would be that he is connecting to the pin next door... |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Mon Jul 31, 2017 1:19 pm |
|
|
no I am positive. I am connecting it to pin7 (AN4) of microcontroller. i checked twice before posting the result. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 31, 2017 1:32 pm |
|
|
OK. Let's look at the rest of your code.
In the code that you most recently posted, you have messed up the ch. 4
section. You load the adc result into 'reading2', but then you don't move
it into 'reading'.
Quote: | if(seconds>=2)
{
SET_AN_CHANNEL (4);
delay_us(5);
reading2 = read_adc();
reading = reading1;
} |
You did it correctly in your two previous postings of your code, but in
the latest one you made this incorrect change. Remember what ezflyer
posted earlier in this thread:
Quote: | Successful programming demands care, and attention to detail.
Randomness is not a good programming attribute..... |
|
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Mon Jul 31, 2017 1:44 pm |
|
|
I agree that. I have corrected the mistake but still it is not reading channel 4.
Code: |
#include <16F914.h>
#device ADC = 10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)
#byte ADCON0=getenv("SFR:ADCON0")
// to move channel parameter two bits left in Chsx
#define SET_AN_CHANNEL(x) ADCON0=((ADCON0 & 0xe3)+(x<<2))
//============================================================================================//
//===========================================================================================//
// LCD Configuration //
//==========================================================================================//
// Digit segments A B C D E F G DP
// b7 b6 b5 b4 b3 b2 b1 b0
#define DIGIT5 COM0+17, COM1+17, COM2+17, COM3+17, COM2+18, COM0+18, COM1+18, COM3+18
#define DIGIT4 COM0+3, COM1+3, COM2+3, COM3+3, COM2+2, COM0+2, COM1+2, COM3+2
#define DIGIT3 COM0+1, COM1+1, COM2+1, COM3+1, COM2+0, COM0+0, COM1+0, COM3+0
#define DIGIT2 COM0+19, COM1+19, COM2+19, COM3+19, COM2+20, COM0+20, COM1+20, COM3+20
// ComX+Y is combination of Backplan0-3 and Segment0-SegmentXX
//=======================================================================================//
// character 0 1 2 3 4 5 6 7 8 9 Null
byte const Digit_Map[11] = {0xFD,0x61,0xDB,0xF3,0x67,0xB7,0xBF,0xE1,0xFF,0xF7,0x01}; //Decimal
byte const Digit_Map_1[11] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0x00}; //no Decimal
//=======================================================================================//
// Segments Initilization //
// Seg23 Seg22 ... Seg12 Seg11 Seg10 Seg9 Seg8 Seg7 Seg6 Seg5 Seg4 Seg3 Seg2 Seg1 Seg0 //
// 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 //
// if bit_SegX is 1, SegX is set as Segment Output. Otherwise //
////=====================================================================================//
#define Segments 0x1E000F // Initilize LCD SegmentX
//============================================================================//
#define INTS_PER_SECOND 76 // (20000000/(4*256*256))
int int_count=INTS_PER_SECOND;
int count5 = 0;// after decimal
int count_5 = 0;
int count4=0; // 1st digit
int count_4=0; // 1st digit
int count3=0; // 2nd digit
int count_3=0;
int count2=0; // 3rd digit
int count_2=0;
long seconds=0;
long reading;
long reading1;
long reading2;
//============================================================================//
#int_rtcc //This function is called
void clock_isr()
{ //every time the RTCC (timer0)
//overflows (255->0)
//For this program this is apx
//31 times per second.
if(--int_count==0)
{
seconds++;
int_count=INTS_PER_SECOND;
}
}
//============================================================================//
void Disp_num()
{
if(reading < 10)
{
count_5=reading;
count_2=11;
count_3=11;
count_4=11;
}
if(10<= reading < 100)
{
count_5=reading%10;
count_4=reading/10;
count_3=11;
count_2=11;
}
if(100 <= reading <999)
{
count_5=reading%10;
count_4=reading%100/10;
Count_3=reading%1000/100;
count_2=11;
}
if(1000 <= reading < 1024)
{
count_5=reading%10;
count_4=reading%100/10;
Count_3=reading%1000/100;
count_2=reading%10000/1000;
}
}
//=============================================================================//
void sec_disp()
{
count4=count_4;
count5=count_5;
count2=count_2;
count3=count_3;
}
//============================================================================//
void Display()
{
lcd_symbol (Digit_Map_1[count5], DIGIT5);
lcd_symbol (Digit_Map[count4], DIGIT4);
lcd_symbol (Digit_Map_1[count3], DIGIT3);
lcd_symbol (Digit_Map_1[count2], DIGIT2);
}
//============================================================================//
void Digit()
{
if(seconds>=1)
{
SET_AN_CHANNEL (0); // selecting Channel A0;
delay_us(5); // TACQ > 4.67 us as per data sheet
reading1 = read_adc();
reading = reading1;
}
if(seconds>=2)
{
SET_AN_CHANNEL (4);
delay_us(5);
reading2 = read_adc();
reading = reading2;
}
seconds=0;
}
void main()
{
set_tris_a (0xe9); //set RA-0,3,5,6,7 as inputs
set_tris_b (0xc0);
set_tris_c (0x07);
set_tris_e (0x08);
setup_adc_ports(sAN0|sAN4,VSS_VREF);
setup_adc (ADC_CLOCK_DIV_32);
set_rtcc(0);
setup_counters (RTCC_INTERNAL, RTCC_DIV_256);
enable_interrupts (INT_RTCC);
enable_interrupts(GLOBAL);
setup_lcd(LCD_MUX14|LCD_STOP_ON_SLEEP,3, Segments); // set segments
count5 = 8;
count4 = 8;
count3 = 8;
count2 = 8;
Display ();
delay_ms (1000);
while (TRUE)
{
digit();
Disp_num();
sec_disp();
display();
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 31, 2017 1:53 pm |
|
|
Well then look at the rest of your code.
Suppose 'seconds' is set to 1 in the isr. Then it executes the first if()
statement. Then what does it do ? It falls down to the end of the Digit()
function and executes the 'seconds = 0' line. It will never get = 2.
Quote: |
void Digit()
{
if(seconds>=1)
{
SET_AN_CHANNEL (0); // selecting Channel A0;
delay_us(5); // TACQ > 4.67 us as per data sheet
reading1 = read_adc();
reading = reading1;
}
if(seconds>=2)
{
SET_AN_CHANNEL (4);
delay_us(5);
reading2 = read_adc();
reading = reading2;
}
seconds=0;
} |
Also, your test is wrong. Your first if() statement checks if 'seconds' is
greater than or equal to 1. So let's say you fix the first bug above.
Now 'seconds' can become 2 in the isr. Then it enters the Digit() function
and what does it do ? It sees that 2 is >= 1, and it executes the first if().
I have added the necessary changes to the code below, as shown in bold:
Quote: |
void Digit()
{
if(seconds == 1)
{
SET_AN_CHANNEL (0); // selecting Channel A0;
delay_us(5); // TACQ > 4.67 us as per data sheet
reading1 = read_adc();
reading = reading1;
}
if(seconds == 2)
{
SET_AN_CHANNEL (4);
delay_us(5);
reading2 = read_adc();
reading = reading2;
seconds=0;
}
} |
The changes are:
1. Change the => test in each if() statement to be ==.
2. Move the 'seconds = 0;' line inside the 2nd if() statement.
Last edited by PCM programmer on Mon Jul 31, 2017 2:02 pm; edited 1 time in total |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Mon Jul 31, 2017 2:00 pm |
|
|
what a mistake. i got it working now but for first channel the last digit on LCD is kind of flickering . can you help me with that ?
Code: |
//============================================================================//
// Inclinometer //
// Date: 7-24-2017 //
// //
//============================================================================//
#include <16F914.h>
#device ADC = 10
#fuses HS, MCLR, NOWDT, PUT, NOIESO, BROWNOUT, NOFCMEN
#use delay(clock=20000000)
#byte ADCON0=getenv("SFR:ADCON0")
// to move channel parameter two bits left in Chsx
#define SET_AN_CHANNEL(x) ADCON0=((ADCON0 & 0xe3)+(x<<2))
//============================================================================================//
//===========================================================================================//
// LCD Configuration //
//==========================================================================================//
// Digit segments A B C D E F G DP
// b7 b6 b5 b4 b3 b2 b1 b0
#define DIGIT5 COM0+17, COM1+17, COM2+17, COM3+17, COM2+18, COM0+18, COM1+18, COM3+18
#define DIGIT4 COM0+3, COM1+3, COM2+3, COM3+3, COM2+2, COM0+2, COM1+2, COM3+2
#define DIGIT3 COM0+1, COM1+1, COM2+1, COM3+1, COM2+0, COM0+0, COM1+0, COM3+0
#define DIGIT2 COM0+19, COM1+19, COM2+19, COM3+19, COM2+20, COM0+20, COM1+20, COM3+20
// ComX+Y is combination of Backplan0-3 and Segment0-SegmentXX
//=======================================================================================//
// character 0 1 2 3 4 5 6 7 8 9 Null
byte const Digit_Map[11] = {0xFD,0x61,0xDB,0xF3,0x67,0xB7,0xBF,0xE1,0xFF,0xF7,0x01}; //Decimal
byte const Digit_Map_1[11] = {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0x00}; //no Decimal
//=======================================================================================//
// Segments Initilization //
// Seg23 Seg22 ... Seg12 Seg11 Seg10 Seg9 Seg8 Seg7 Seg6 Seg5 Seg4 Seg3 Seg2 Seg1 Seg0 //
// 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 0/1 //
// if bit_SegX is 1, SegX is set as Segment Output. Otherwise //
////=====================================================================================//
#define Segments 0x1E000F // Initilize LCD SegmentX
//============================================================================//
#define INTS_PER_SECOND 76 // (20000000/(4*256*256))
int int_count=INTS_PER_SECOND;
int count5 = 0;// after decimal
int count_5 = 0;
int count4=0; // 1st digit
int count_4=0; // 1st digit
int count3=0; // 2nd digit
int count_3=0;
int count2=0; // 3rd digit
int count_2=0;
long seconds=0;
long reading;
long reading1;
long reading2;
//============================================================================//
#int_rtcc //This function is called
void clock_isr()
{ //every time the RTCC (timer0)
//overflows (255->0)
//For this program this is apx
//31 times per second.
if(--int_count==0)
{
seconds++;
int_count=INTS_PER_SECOND;
}
}
//============================================================================//
void Disp_num()
{
if(reading < 10)
{
count_5=reading;
count_2=11;
count_3=11;
count_4=11;
}
if(10<= reading < 100)
{
count_5=reading%10;
count_4=reading/10;
count_3=11;
count_2=11;
}
if(100 <= reading <999)
{
count_5=reading%10;
count_4=reading%100/10;
Count_3=reading%1000/100;
count_2=11;
}
if(1000 <= reading < 1024)
{
count_5=reading%10;
count_4=reading%100/10;
Count_3=reading%1000/100;
count_2=reading%10000/1000;
}
}
//=============================================================================//
void sec_disp()
{
count4=count_4;
count5=count_5;
count2=count_2;
count3=count_3;
}
//============================================================================//
void Display()
{
lcd_symbol (Digit_Map_1[count5], DIGIT5);
lcd_symbol (Digit_Map[count4], DIGIT4);
lcd_symbol (Digit_Map_1[count3], DIGIT3);
lcd_symbol (Digit_Map_1[count2], DIGIT2);
}
//============================================================================//
void Digit()
{
if(seconds>=1)
{
SET_AN_CHANNEL (0); // selecting Channel A0;
delay_us(5); // TACQ > 4.67 us as per data sheet
reading1 = read_adc();
reading = reading1;
}
if(seconds>=2)
{
SET_AN_CHANNEL (4);
delay_us(5);
reading2 = read_adc();
reading = reading2;
seconds=0;
}
}
void main()
{
set_tris_a (0xe9); //set RA-0,3,5,6,7 as inputs
set_tris_b (0xc0);
set_tris_c (0x07);
set_tris_e (0x08);
setup_adc_ports(sAN0|sAN4,VSS_VREF);
setup_adc (ADC_CLOCK_DIV_32);
set_rtcc(0);
setup_counters (RTCC_INTERNAL, RTCC_DIV_256);
enable_interrupts (INT_RTCC);
enable_interrupts(GLOBAL);
setup_lcd(LCD_MUX14|LCD_STOP_ON_SLEEP,3, Segments); // set segments
count5 = 8;
count4 = 8;
count3 = 8;
count2 = 8;
Display ();
delay_ms (1000);
while (TRUE)
{
digit();
Disp_num();
sec_disp();
display();
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 31, 2017 2:03 pm |
|
|
I was editing my post while you posted your reply. Look at it and see
what I said about the >= test. It must be made into '=='. |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Mon Jul 31, 2017 2:17 pm |
|
|
bingo !!
It is working. Thanks a lot PCM Programmer & Ttelmah for support. I am trying to add 3rd analog output at AN7. I get you back if i have problems as i move further. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 31, 2017 2:21 pm |
|
|
Quote: | I get you back if i have problems as i move further. |
I would prefer that you learn to trouble-shoot your own code.
You shouldn't use us to debug your code. Read over the thread and
see the things I looked at. Then do that if you have any future problems. |
|
|
POPE19
Joined: 27 Jun 2017 Posts: 71
|
|
Posted: Tue Aug 01, 2017 4:49 am |
|
|
i am not using you guys but i dont have that much coding knowledge nor in depth for pic. as i said i am a newbie so couldnot figure out somethings and i have a short deadline for this one . but good thing is along with your suggestions i am learning new things too. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|