Forums

Problem with A/D

Started by Dado May 21, 2005
Hello,
I have problem with .C programming! (Working with Code Vision for AVR).
I have set up one PCF8591 on I2C BUS.

Can You help me with code, where I m doing wrong?


Chip type : ATmega8515
Program type : Application
Clock frequency : 4,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 128


Communication parameters: 9600 8N1


[RS232 SPARE header] [PORTD header]
RXD - 1 PD0
TXD - 2 PD1

I2C bus port bits allocations for PORTA
NOTE: 3.3k..4.7k PULL-UP RESITORS TO +5V MUST
BE USED FOR THE SDA & SCL I2C BUS SIGNALS

*****************************************************/
/*#include <mega8515.h>

// printf
#include <stdio.h>

#include <delay.h>

// I2C Bus functions
#asm
.equ __i2c_port=0x1B ;PORTA
.equ __sda_bit=0
.equ __scl_bit=1
#endasm
#include <i2c.h>



// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x15 ;PORTC
#endasm
#include <lcd.h>




// Declare your global variables here
//char lcd_buffer[33];
int ch;
int vlt;
int volts2;
// int j;

void main(void)
{
// Declare your local variables here


// enable the transmitter
UCSRB=8;
// Baud=9600 @ 4.000 MHz
UBRRL=25;




// I2C Bus initialization
i2c_init();


// Initialize the LCD for
// 2 lines & 16 columns
lcd_init(16);

// go on the second LCD line
lcd_gotoxy(1,2);

// temperature transmission loop

while (1)
{
//for(j=0;j<2;j++){ // go twice to ignore 1st false reading???



i2c_start();
i2c_write(0x90);

i2c_write(0x40);
i2c_stop();

i2c_start();
i2c_write(0x91);
//read data

i2c_read(ch);
//convert to volts

i2c_read(ch);

volts2 =ch;
volts2 = (0.01670 * vlt);
printf("%4.2f\n",volts2);
//call stop
i2c_stop();
delay_ms(800);
}

}

I do not have readings from chanel 0, nothing????

Many thanks!
Damir


Dado wrote:
> Hello, > I have problem with .C programming! (Working with Code Vision for
AVR).
> I have set up one PCF8591 on I2C BUS. > > Can You help me with code, where I m doing wrong? > > > Chip type : ATmega8515 > Program type : Application > Clock frequency : 4,000000 MHz > Memory model : Small > External SRAM size : 0 > Data Stack size : 128 > > > Communication parameters: 9600 8N1 > > > [RS232 SPARE header] [PORTD header] > RXD - 1 PD0 > TXD - 2 PD1 > > I2C bus port bits allocations for PORTA > NOTE: 3.3k..4.7k PULL-UP RESITORS TO +5V MUST > BE USED FOR THE SDA & SCL I2C BUS SIGNALS > > *****************************************************/ > /*#include <mega8515.h> > > // printf > #include <stdio.h> > > #include <delay.h> > > // I2C Bus functions > #asm > .equ __i2c_port=0x1B ;PORTA > .equ __sda_bit=0 > .equ __scl_bit=1 > #endasm > #include <i2c.h> > > > > // Alphanumeric LCD Module functions > #asm > .equ __lcd_port=0x15 ;PORTC > #endasm > #include <lcd.h> > > > > > // Declare your global variables here > //char lcd_buffer[33]; > int ch; > int vlt; > int volts2; > // int j; > > void main(void) > { > // Declare your local variables here > > > // enable the transmitter > UCSRB=8; > // Baud=9600 @ 4.000 MHz > UBRRL=25; > > > > > // I2C Bus initialization > i2c_init(); > > > // Initialize the LCD for > // 2 lines & 16 columns > lcd_init(16); > > // go on the second LCD line > lcd_gotoxy(1,2); > > // temperature transmission loop > > while (1) > { > //for(j=0;j<2;j++){ // go twice to ignore 1st false reading??? > > > > i2c_start(); > i2c_write(0x90); > > i2c_write(0x40); > i2c_stop(); > > i2c_start(); > i2c_write(0x91); > //read data > > i2c_read(ch); > //convert to volts > > i2c_read(ch); > > volts2 =ch;
Did you omit code? What is the prototype of the i2c_read function? If ch is passed by value, you will not get a result written to it.
> volts2 = (0.01670 * vlt); > printf("%4.2f\n",volts2); > //call stop > i2c_stop(); > delay_ms(800); > } > > } > > I do not have readings from chanel 0, nothing???? > > Many thanks! > Damir
> > Did you omit code?
I do not know!
> What is the prototype of the i2c_read function? > If ch is passed by value, you will not get a result written to it. >
I do change to a code and get nothing again I do not know what to do? #include <mega8515.h> // printf #include <stdio.h> #include <delay.h> // I2C Bus functions #asm .equ __i2c_port=0x1B ;PORTA .equ __sda_bit=0 .equ __scl_bit=1 #endasm #include <i2c.h> // Declare your global variables here unsigned char ch; unsigned character float volts2; varijable float I think is ok! But I do not know! void main(void) { // Declare your local variables here // enable the transmitter UCSRB=8; // Baud=9600 @ 4.000 MHz UBRRL=25; // I2C Bus initialization i2c_init(); while (1) { i2c_start(); i2c_write(0x90); i2c_write(0x40); i2c_stop(); //read data i2c_start(); i2c_write(0x91); ch=i2c_read(0); i2c_stop(); i2c_start(); i2c_write(0x91); ch=i2c_read(0); i2c_stop(); //convert to volts volts2 = (0.01961 * ch); printf("%4.2f \n",volts2); this line i do not understand!What for is 4.2 ok f is a float delay_ms(800); } } Thanks again! Damir
Dado wrote:
> > > > Did you omit code? > > I do not know! > > > What is the prototype of the i2c_read function? > > If ch is passed by value, you will not get a result written to it. > > > > I do change to a code and get nothing again > I do not know what to do?
Check the prototype. It could be something like ret_value = i2c_read(code).
> > #include <mega8515.h> > > // printf > #include <stdio.h> > > #include <delay.h> > > // I2C Bus functions > #asm > .equ __i2c_port=0x1B ;PORTA > .equ __sda_bit=0 > .equ __scl_bit=1 > #endasm > #include <i2c.h> > > > // Declare your global variables here > > unsigned char ch; unsigned character > > float volts2; varijable float I think is ok! But I > do not know! > > > void main(void) > { > // Declare your local variables here > > // enable the transmitter > UCSRB=8; > // Baud=9600 @ 4.000 MHz > UBRRL=25; > > > // I2C Bus initialization > i2c_init(); > > > while (1) > { > i2c_start(); > i2c_write(0x90); > i2c_write(0x40); > i2c_stop(); > > //read data > > i2c_start(); > i2c_write(0x91); > ch=i2c_read(0); > i2c_stop(); > > i2c_start(); > i2c_write(0x91); > ch=i2c_read(0); > i2c_stop(); > > //convert to volts > > volts2 = (0.01961 * ch); > printf("%4.2f \n",volts2); this line i do not understand!What for
is 4.2
> ok f is a float > delay_ms(800); > } > > } > > Thanks again! > Damir
On Sunday, in article <d6ol2p$884$1@ss405.t-com.hr>
     rdamir@net.hr "Dado" wrote:
>Hello, >I have problem with .C programming! (Working with Code Vision for AVR). >I have set up one PCF8591 on I2C BUS.
If any help look at some I2C code I put in the public domain in C originally for H8 and attached PCF8583 I2C controller, there are modules for PCF8591 PCF8574(A), PCF8575 and a couple of other parts. These may help you with how to organise your code. I ask that if you use the code you acknowledge it.
>Can You help me with code, where I m doing wrong? > > >Chip type : ATmega8515 >Program type : Application >Clock frequency : 4,000000 MHz >Memory model : Small >External SRAM size : 0 >Data Stack size : 128 >
....
>// I2C Bus initialization >i2c_init(); >
...
>i2c_start(); >i2c_write(0x90); > >i2c_write(0x40);
Configure PCF8591 as 4 single ended inputs, start at channel 0, NO auto channel increment and enable the DAC output.
>i2c_stop(); > >i2c_start(); >i2c_write(0x91); >//read data > >i2c_read(ch);
So where have you saved the data? 'ch' being passed by value into a read function is probably superfluous. I would have expected something like ch = i2c_read( ); For most I2C libraries, check the documentation for your I2C library.
>//convert to volts > >i2c_read(ch);
Second read as the first read is normally a dummy read for PCF8591.
>volts2 =ch;
Assumes returned data is already in 'ch' which it won't be until you use the correct call method to i2c_read above.
>volts2 = (0.01670 * vlt);
Now you FORGET the original data in 'volts2' and overwrite it with values for 'vlt'. I don't see where vlt gets updated from the reading data. Firstly I believe to actually USE the returned data that line should read volts2 = (0.01670 * volts2); Secondly beware of using fixed multipliers on PCF8591 as the scaling is dependent on Vref, So unless you have an external reference that is a fixed reference and not supply rail as a lot of people use, you might be able to use a fxed multiplier. When tied to supply rail the device works with power rails from 2.5V to 6V so the refernce tied to supply rail will change. The multiplier you use assumes a single ended input with a reference of 4.26V.
>printf("%4.2f\n",volts2);
As I have said above the value in volts2 will not change as the readings are not used.
>//call stop >i2c_stop();
I would put this line after the second read of the PCF8591 to avoid printf delays confusing I2C bus timing.
>delay_ms(800); >} > >} > >I do not have readings from chanel 0, nothing???? >
-- Paul Carpenter | paul@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.gnuh8.org.uk/> GNU H8 & mailing list info <http://www.badweb.org.uk/> For those web sites you hate
On Sunday, in article <d6pll9$ecv$2@ss405.t-com.hr>
     rdamir@net.hr "Dado" wrote:
.....
>I do change to a code and get nothing again >I do not know what to do?
Which I2C library are you using for functions i2c_start, i2c_write, i2c_read ? Who supplied it or wrote it for you? Do the functions return error codes ? If error codes are returned print them as they will tell you if the bus is acknowledging the transfer correctly.
>#include <mega8515.h> > >// printf >#include <stdio.h> > >#include <delay.h> > >// I2C Bus functions >#asm > .equ __i2c_port=0x1B ;PORTA > .equ __sda_bit=0 > .equ __scl_bit=1 >#endasm >#include <i2c.h> > >
...
>void main(void) >{
....
>// I2C Bus initialization >i2c_init(); > > >while (1) > { >i2c_start(); >i2c_write(0x90); >i2c_write(0x40); >i2c_stop();
Assuming these do not return error codes and are working correctly fine. Use printf (if that works on your system) to print out the error codes for EACH i2c function to work out which one is wrong.
>//read data > >i2c_start(); >i2c_write(0x91); >ch=i2c_read(0);
I assume i2c_read requires a parameter of '0' to be passed in? What does the file "i2c.h" say for this function? From here
>i2c_stop(); > >i2c_start(); >i2c_write(0x91);
To here is NOT needed when doing succesive reads of the PCF8591.
>ch=i2c_read(0); >i2c_stop(); > >//convert to volts > >volts2 = (0.01961 * ch); >printf("%4.2f \n",volts2); this line i do not understand!What for is 4.2 >ok f is a float >delay_ms(800); >} > >} > >Thanks again! >Damir
-- Paul Carpenter | paul@pcserviceselectronics.co.uk <http://www.pcserviceselectronics.co.uk/> PC Services <http://www.gnuh8.org.uk/> GNU H8 & mailing list info <http://www.badweb.org.uk/> For those web sites you hate
Thanks for the help I think I know what to do!
Thanks again!
Damir

> Check the prototype. > It could be something like > ret_value = i2c_read(code). >
Thanks for the help, help!
Now I know what to do.
Thanks again!
Damir



Dado wrote:

> Hello, > I have problem with .C programming! (Working with Code Vision for AVR). > I have set up one PCF8591 on I2C BUS. > > Can You help me with code, where I m doing wrong? > > Chip type : ATmega8515 > Program type : Application > Clock frequency : 4,000000 MHz > Memory model : Small > External SRAM size : 0 > Data Stack size : 128 > > Communication parameters: 9600 8N1 > > [RS232 SPARE header] [PORTD header] > RXD - 1 PD0 > TXD - 2 PD1 > > I2C bus port bits allocations for PORTA > NOTE: 3.3k..4.7k PULL-UP RESITORS TO +5V MUST > BE USED FOR THE SDA & SCL I2C BUS SIGNALS > > *****************************************************/ > /*#include <mega8515.h> > > // printf > #include <stdio.h> > > #include <delay.h> > > // I2C Bus functions > #asm > .equ __i2c_port=0x1B ;PORTA > .equ __sda_bit=0 > .equ __scl_bit=1 > #endasm > #include <i2c.h> > > // Alphanumeric LCD Module functions > #asm > .equ __lcd_port=0x15 ;PORTC > #endasm > #include <lcd.h> > > // Declare your global variables here > //char lcd_buffer[33]; > int ch; > int vlt; > int volts2; > // int j; > > void main(void) > { > // Declare your local variables here > > // enable the transmitter > UCSRB=8; > // Baud=9600 @ 4.000 MHz > UBRRL=25; > > // I2C Bus initialization > i2c_init(); > > // Initialize the LCD for > // 2 lines & 16 columns > lcd_init(16); > > // go on the second LCD line > lcd_gotoxy(1,2); > > // temperature transmission loop > > while (1) > { > //for(j=0;j<2;j++){ // go twice to ignore 1st false reading??? > > i2c_start(); > i2c_write(0x90); > > i2c_write(0x40); > i2c_stop(); > > i2c_start(); > i2c_write(0x91); > //read data > > i2c_read(ch); > //convert to volts > > i2c_read(ch); > > volts2 =ch; > volts2 = (0.01670 * vlt); > printf("%4.2f\n",volts2); > //call stop > i2c_stop(); > delay_ms(800); > } > > } > > I do not have readings from chanel 0, nothing???? > > Many thanks! > Damir
volts2 is an int and you are doing floating point on it. are you getting warnings? the result may be 0. try printing the AD counts first and try that.