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.

Reading strange data from ADS7825 interfacing with At90USB1286

Status
Not open for further replies.

raosige

Newbie level 4
Joined
Aug 29, 2016
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
108
Hi All,

I am interfacing ADS7825 to AT90USB1286 in Parallel mode please see below circuit diagram. But i can't read the correct data.

Can any one tried this successfully any sample code to read the data.

i have few questions, before giving the questions let me put my work details here.

1. I connected two nos of 2.2uF/35V Tantalum Capacitors one on 6th pin to ground and another is on 7th pin to ground.

2. I made CONTC=0 i.e. manual mode.

3. I am using AT90USB1286 MIcro controller to read the data.

4. I connected AGND1, AGND2 and DGND to same ground(please see below circuit diagram).

5. I am giving 0 to 1.5V to ADC Channel 1 (i.e. AIN0 )for testing purpose only. But actually i will give +/-10v to all four channels

of ADC.

6. I measured 2.502V at Vref to ground.



MY CODE is:


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/** 
** crystal frequency is 11.0592Mhz 
** microcontroller is AT90USB1286 
** programming tool Atmel studio 6.2 
**/ 
 
#include <avr/io.h> 
#include <math.h> 
#include <stdlib.h> 
#include <avr/interrupt.h> 
#include <avr/pgmspace.h> 
#include <util/delay.h> 
#include <string.h> 
#include <inttypes.h> 
 
 
#define F_CPU 11059200UL 
#define cnstt 0 
#define slope 3276.7 
 
#define LCD_DPRT PORTA        // LCD DATA PORT 
#define LCD_DDDR DDRA        // LCD DATA DDR 
#define LCD_DPIN PINA        // LCD DATA PIN 
#define KEY_PRT PORTE        // LCD DATA PORT 
#define KEY_DDR DDRE        // LCD DATA DDR 
#define KEY_PIN PINE        // LCD DATA PIN 
 
 
#define LCD_RSOFF PORTD&=~(1<<PD5) 
#define LCD_RSON PORTD|=(1<<PD5) 
#define LCD_RWOFF PORTD&=~(1<<PD6) 
#define LCD_RWON PORTD|=(1<<PD6) 
#define LCD_EOFF PORTD&=~(1<<PD7) 
#define LCD_EON PORTD|=(1<<PD7) 
 
#define A_zeroOFF PORTD &=~(1<<PD0)                        // channel selection of adc  A0 is low 
#define A_zeroON PORTD |=(1<<PD0)                        // channel selection of adc  A0 is high 
 
#define A_oneOFF PORTD &=~(1<<PD1)                        // channel selection of adc  A1 is low 
#define A_oneON PORTD |=(1<<PD1)                        // channel selection of adc  A1 is high 
 
#define RC_OFF PORTD &=~(1<<PD2) 
#define RC_ON PORTD |=(1<<PD2) 
 
#define BYTE_MSB PORTD &=~(1<<PD4) 
#define BYTE_LSB PORTD |=(1<<PD4) 
 
//unsigned int readinput; 
signed int msbbits,lsbbits; 
signed int i,count,cnt; 
double in; 
char itmp[20]; 
char i_tmp[20]; 
                         
void lcd_chone(); 
void lcd_chtwo(); 
void lcd_chthree(); 
void lcd_chfour(); 
void adcinit_readdata(); 
void lcd_init(); 
void lcd_print(char * str); 
void lcdCommand(unsigned char cmnd); 
void lcdData(unsigned char data); 
void lcd_gotoxy(unsigned char x, unsigned char y); 
 
//********************************************* Main function starts from here *******************************************// 
 
int main (void) 
{ 
    unsigned char upperNibble, keyCode,i; 
    unsigned int readinput; 
    DDRB=0xFF;     
    DDRD=0xF7; 
    DDRE=0x00;                                             
                                     
                                             
    msbbits=0; 
    lsbbits=0;     
    cnt=0;                                                         
    count=0; 
    in=0.0; 
    readinput=0; 
     
     
    lcd_init();                                             
    _delay_ms(50); 
     lcdCommand(0x01) 
     
     
     
     while(1)                                             
        { 
             
        lcd_chone();adcinit_readdata(); 
        
 
        }             
                     
        }             
      
              
 
     
      
//******************************* functions of ADC Channels 1,2,3,4 respectively**************************************// 
         
void lcd_chone()                         
{ 
    CH1_LOW; 
    A_zeroOFF;   
     _NOP();
     _NOP();
     _NOP();                               
    _delay_us(1);                                 
    A_oneOFF; 
    _NOP();   
    _NOP();
     _NOP();                                         
     
} 
 
 
 
 
 
 
 
//********************************************* LCD functions **************************************// 
 
void lcdCommand(unsigned char cmnd) 
{ 
    LCD_DPRT = cmnd;                 
    LCD_RSOFF;                         
    LCD_RWOFF;                                 
    LCD_EON;                                 
    _delay_us(1);                     
    LCD_EOFF;                                 
    _delay_us(100); 
} 
 
void lcdData(unsigned char data) 
{ 
    LCD_DPRT = data;                 
    LCD_RSON;                         
    LCD_RWOFF;                         
    LCD_EON;                       
    _delay_us(1);                     
    LCD_EOFF;                                 
    _delay_us(100); 
} 
 
void lcd_init() 
{ 
    LCD_DDDR = 0xFF; 
    //LCD_CDDR = 0xFF; 
    LCD_EOFF;                         
    _delay_us(2000);                 
    lcdCommand(0x38);                 
    lcdCommand(0x0E);                 
    lcdCommand(0x01);                 
    _delay_us(2000);                 
    lcdCommand(0x06);                 
} 
 
void lcd_gotoxy(unsigned char x, unsigned char y) 
{ 
    unsigned char firstCharAdr[]={0x80,0xC0,0x94,0xD4}; 
    lcdCommand(firstCharAdr[y-1]+x-1);                     
    _delay_us(100); 
} 
 
void lcd_print(char * str) 
{ 
    unsigned char i=0; 
    while(str[i]!=0) 
    { 
        lcdData(str[i]); 
        i++; 
    } 
} 
 
//*****************************  16-bit DATA transferring from ADC to MC Through Parallel Mode    *****************************// 
 
    void adcinit_readdata() 
    { 
        RC_OFF;                                  // RC LOW 
        _delay_us(10);                       // delay up to 5 Micro seconds 
        RC_ON;                                 // RC ON 
       _NOP();
        _NOP();
        _NOP();
        _NOP();
        _NOP();
        if(PIND & 0b00001000)                               // if BUSY Pin goes high then the data is ready to accumulate 
        { 
            BYTE_MSB;                              // BYTE=1 
            _NOP();
            _NOP();
            _NOP();
            _NOP();
            _NOP();
             msbbits=PINE;                                       // store the data available on PORTE into  msbbits. Here,  most MSB bits are available 
            BYTE_LSB;                            // Byte=0 
            _NOP();
            _NOP();
           _NOP();
           _NOP();
           _NOP();
 
 
 
            lsbbits=PINE;                          // store the data available on PORTE into lsbbits. Here, Least LSB bits are available 
            count=msbbits<<8;                        // right shift the data 8 times                     
            count=count+lsbbits;                     // now add count=count+lsbbits to get actual 16bit signed 2's complement digital value  
                                     
            in=(count-cnstt)/slope;     
            lcd_gotoxy(1,1);                         
            ltoa(count, i_tmp, 10); 
            lcd_print(i_tmp); 
            lcd_gotoxy(1,2); 
            dtostrf(in,10,5,itmp);lcd_print(itmp);lcd_print("V     "); 
            msbbits=0;                                 
            lsbbits=0;                                         
            count=0; 
            in=0.0; 
             
                 
        } 
       // else 
       //_delay_us(10); 
         
    }


Therefore my problems are:

1. I am able read the correct data from ADC but i am getting strange data.

2. Are the connections between AT90USB1286 to ADS7825 right?

3. Are there any mistakes in my code?


for example, I f i give 1V as i/p signal to AIN0 of ADS7825 it is giving digital count 3276(approx) for +/-10V range.

But whenever i change the input signal from 1v to 1.080 or 1.112 e.t.c. it is giving -9.8788V(with equivalent digital count) and some times it is giving an exact input voltage(i.e.when i change the input signal amplitude).
i can't understand what is happening.

please tell any one where did i mistake.

thank you in advance.

excuse me for bad english
 
Last edited by a moderator:

Sounds like you are overriding the ADC samplerate.
The ADC needs 25µs between conversions.
Violating the timing without changing the input may not lead to a faulty signal, but when signal changes, this will cause issues.
I would suggest you add a delay at the end of adcinit_readdata()
 

hi,
please find the attached file which is my circuit diagram

- - - Updated - - -

**broken link removed**

hi,
please find the attached file which is my circuit diagram
 

Attachments

  • circuit_0.jpg
    circuit_0.jpg
    122.7 KB · Views: 101

Hi,

don´t leave AIN1..3 floating.

This is a general rule for high impedance inputs.

(I once used a multi channel ADC and it refused to give meaningful results at any channel even when a single channel input was floating)

This may cause the problem, but for sure you have to keep on the timing.

Klaus
 

Hi,
I connected AIN1..3 to GND. hence my problem(getting -9.1012v e.tc at input signal 1v) was solved. But,
whenever i change the input signal from 1v to 1.080 or 1.112 e.t.c. it is giving random error of 4mV and 20mV and some times,
it is giving an exact input voltage(i.e.when i change the input signal amplitude).
for this, i put some delay(10us to 25us) at end of the adcinit_readdata() function. i tried a lot. i can't fix the problem.
refer my code on above post and suggest me an example code if possible.
 

Hi,

maybe you compare the ADC values with a DVM:

-> your ADC conversion runs many times a second (I don´t know how often)
and your ADC input low pass filter cutoff frequency is about 16000Hz


--> your DVM conversion rate maybe is 3 times per second
and your DVM input low pass filter cutoff frequency maybe is less than 1Hz

So you compare two different measurements.

***
Try to replace R3 with 1kOhms and C5 with 100uF.

***
If the problems still exist, then I assume your PCB is not properly routed.
(In case you are working with a breadboard, then don´t expect any precision. Be happy if it works at all.)

PCB: (for DC performance)
* route DGND independently to your GND (Star point?)
* route AGND independently to your GND (Star point?)
* route R4_GND independently to your GND (Star point?)

Klaus
 

hi,
thanks for the suggestions.
i placed my total circuit on general purpose PCB.
yes, i am trying to compare with DVM.
i did changes on my circuit that what you suggest me in the previous post.
i replaced R3 with 1kOhms and C5 with 100uF. I put some delay(150ms) at end of the adcinit_readdata() function so that conversion rate is 8 times per second.
Now, i am able to read the the data with+/-20mV error( i knew that because of poor routing).
But, when i tried to give beyond 5V to the AIN0(channel one of ADC) it gives unexpected value please see below,

I/P(V) digital count

1 3328(approx)
2 6654(approx)
3 9985(approx)
4 13300(approx)
5 15926(approx)

6 3328(approx)
7 6654(approx)
8 9985(approx)
9 13300(approx)
10 15926(approx)

i followed the hardware recommendations which are specified in the datasheet except grounding.
i put delay 150ms
i want to give I/P signal range is -10V to 10V.


excuse me for bad english,
rao sige
 

Hi,

In line 194 you check busy_bit. When it is high you process the data, but when low (likely, because it is low for about 20us) you don't wait for the busy flag to become high, you just wait a little then leave the routine without processing the data.

For a quick test I recommend to put a 25us delay, then you don't need to check the busy flag at all.
For a better solution I recommend to use a loop to really wait until busy = high.

Try this, let's see what happens..

Klaus
 

hi,
see the below code, i did changes those what you said to me

Code:
void adcinit_readdata()
{
	RC_OFF;                                 
	_delay_us(10);                       
	RC_ON;                                
	_NOP();
	_NOP();
	_delay_us(25);
                            
	
		BYTE_MSB;                             
		_NOP();
		_NOP();
		msbbits=PINE;                                       
		BYTE_LSB;                           
		_NOP();
		_NOP();
		lsbbits=PINE;                          
		count=msbbits<<8;                        
		count=count+lsbbits;                    
		lcd_gotoxy(1,1);
		lcd_print("Digital count");
		lcd_gotoxy(1,2);
		ltoa(count, i_tmp, 10);
		lcd_print(i_tmp);lcd_print("     ");
		msbbits=0;
		lsbbits=0;
		count=0;
			
}

but, same problem (i mentioned in previous post) is persisting.
i don't know why the adc's value fall-down when i try to increase the input signal beyond 5V.

sorry, for asking again and again on this problem. actually i am unable to find the problem where it is?

excuse me for bad english
 

Hi,

I´m not familiar with C.....
but maybe the problem is how you read and combine the two bytes.

you defined msbits and lsbits as signed integer (16 bit I assume)

now you read msbits from port with 0x00 to 0xFF (where 0x01 represents a positive value and 0xFF represents a negative value)

Now if you read them in then there ix 0x0000 to 0x00FF in msbits. But now all is represented as positive values. (because bit 15 is never set)

If this is the problem, then try this:
test if bit 7 of msbits is set (means negative ADC value)
If it is set, then add 0xFF00 to msbits (to indicate it is a negative 16 bit value)

Klaus
 

seems there is some overflow on the variables.
Try to change as follows:
unsigned int msbbits,lsbbits;
count=((msbbits<<8)|lsbbits);
 

Hi,
Thank you very much rho-bot.
Problem fixed.
Now I am able read correct data
Once again thank you and klausST

Regards,
Raosige
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top