PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Projekt PCF8591



stechmach
02.03.2010, 17:47
Hallo ich habe auf der "asurowiki" Seite ein paar Informationen zu der Analogen Porterweiterung gefunden und wollte hier mal anfragen was das Unterprogramm, welches auf der genannten Seite steht zurückgibt? Von welchem Eingang gibt mir dieses Programm die Daten?

m.a.r.v.i.n
02.03.2010, 19:22
Die Funktion read_pcf8591_adc erwartet als Parameter den A/D Kanal (0..3) und gibt den entsprechenden A/D Wert zurück.

Hier noch der Link zur Schaltung und zum Programm:
http://www.asurowiki.de/pmwiki/pmwiki.php/Main/I2CAnalogPorterweiterung

stechmach
02.03.2010, 20:57
Ok das hilft mir schon mal weiter. Aber ich bekomme immer Fehlermeldungen beim erstellen meiner Datei.



>Session Environment Variables:
AF_AVRDIR=C:\WinAVR
AF_PROJECT=test
AF_SOURCE_FILES=test.c i2c.c
AF_ASM_SRC_FILES=
AF_PRGDIR=C:\Programme\AsuroFlash
AF_PRJDIR=C:\AsuroFlash\asuro-lib\examples\US
AF_ASURO_LIB_PATH=C:\AsuroFlash\asuro-lib\lib
File test.c saved.
>Default make_all.cmd file created.
>Default makefile created.
Make
C:\AsuroFlash\asuro-lib\examples\US>C:\WinAVR\utils\bin\make.exe all
set -e; avr-gcc -MM -mmcu=atmega8 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=test.lst -IC:\Programme\AsuroFlash\include test.c \
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > test.d; \
[ -s test.d ] || rm -f test.d
-------- begin --------
avr-gcc --version
avr-gcc (WinAVR 20090313) 4.3.2
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Size before:
test.elf :
section size addr
.text 714 0
.bss 17 8388704
.stab 888 0
.stabstr 95 0
.debug_aranges 128 0
.debug_pubnames 335 0
.debug_info 1165 0
.debug_abbrev 592 0
.debug_line 1025 0
.debug_frame 240 0
.debug_str 502 0
.debug_loc 106 0
Total 5807


avr-gcc -c -mmcu=atmega8 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=test.lst -IC:\Programme\AsuroFlash\include test.c -o test.o
test.c: In function 'read_pcf8591_adc':
test.c:12: warning: passing argument 1 of 'StartI2C' makes integer from pointer without a cast
test.c:18: warning: passing argument 1 of 'StartI2C' makes integer from pointer without a cast
test.c: In function 'main':
test.c:42: warning: passing argument 1 of 'SerWrite' makes pointer from integer without a cast
avr-gcc -mmcu=atmega8 -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=test.o -IC:\Programme\AsuroFlash\include test.o i2c.o --output test.elf -Wl,-Map=test.map,--cref -IC:\Programme\AsuroFlash\lib -lm
test.o: In function `read_pcf8591_adc':
C:\AsuroFlash\asuro-lib\examples\US/test.c:17: undefined reference to `Sleep'
test.o: In function `main':
C:\AsuroFlash\asuro-lib\examples\US/test.c:35: undefined reference to `Init'
C:\AsuroFlash\asuro-lib\examples\US/test.c:37: undefined reference to `FrontLED'
C:\AsuroFlash\asuro-lib\examples\US/test.c:42: undefined reference to `SerWrite'
make: *** [test.elf] Error 1

ExitCode 2
>Ready.



Hier mal das Programm. Es soll den Wert von dem ersten Eingang vom PCF8591 über die serielle Schnittstelle senden.

#include "asuro.h"
#include "i2c.h"
#define pcf8591_address 0x90 // I2C Adresse des PCF8574


//liest einen ADC Wert vom PCF8591
unsigned char read_pcf8591_adc(unsigned char adc)
{
unsigned char ret;
unsigned char byte = 0;

ret = StartI2C(pcf8591_address+WriteI2C); // Sende Start Condition
if (ret == 0)

ret = WriteI2C(adc); // Senden des Control Bytes startet die A/D Wandlung
StopI2C(); // Sende Stop Condition, Bus freigeben
Sleep(10); // Warten bis A/D Wandlung benedet (mind. 90µs)
ret = StartI2C(pcf8591_address+ReadI2C); // Sende Start Condition

if (ret == 0)
{
// Mehrmaliges Lesen um alte A/D Werte zu ignorieren
byte = ReadI2C(1); // Lese Byte + acknowledge
byte = ReadI2C(0); // Lese Byte + no acknowledge
}
else ret = 3;
StopI2C(); // Sende Stop Condition, Bus freigeben
return byte;
}

int main(void)
{
unsigned char rled;
unsigned char port;
Init();
InitI2C();
FrontLED(ON);
while(1)
{
port=0;
rled = read_pcf8591_adc(port);
SerWrite(rled,4);
}
return 0;
}

m.a.r.v.i.n
03.03.2010, 10:48
Da fehlt zumindest noch die asuro.c in deinem Projekt. Die Asuro-Lib selbst scheint aber auch zu fehlen. Eigentlich sollte das schon durch das Makefile Template vom AsuroFlash Tool eingebunden werden.
Das ist seltsam, hast du die Templates geändert? Welche AsuroFlash Version verwendest du?

stechmach
03.03.2010, 14:16
Ich verwende die Version 1.4.6.56. Ich habe jetzt nochmal etwas geändert und bekomme aber folgende Fehlermeldung



>Session Environment Variables:
AF_AVRDIR=C:\WinAVR
AF_PROJECT=Project1
AF_SOURCE_FILES=test.c
AF_ASM_SRC_FILES=
AF_PRGDIR=C:\Programme\AsuroFlash
AF_PRJDIR=C:\ASURO_SRC\programm\us
AF_ASURO_LIB_PATH=C:\ASURO_SRC\AsuroLib\lib
File test.c saved.
>Default make_all.cmd file created.
>Default makefile created.
Make
C:\ASURO_SRC\programm\us>C:\WinAVR\utils\bin\make.exe all
set -e; avr-gcc -MM -mmcu=atmega8 -DF_CPU=8000000UL -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=i2c.lst i2c.c \
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > i2c.d; \
[ -s i2c.d ] || rm -f i2c.d
set -e; avr-gcc -MM -mmcu=atmega8 -DF_CPU=8000000UL -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=asuro.lst asuro.c \
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > asuro.d; \
[ -s asuro.d ] || rm -f asuro.d
set -e; avr-gcc -MM -mmcu=atmega8 -DF_CPU=8000000UL -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=test.lst test.c \
| sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > test.d; \
[ -s test.d ] || rm -f test.d
-------- begin --------
avr-gcc --version
avr-gcc (WinAVR 20090313) 4.3.2
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

avr-gcc -c -mmcu=atmega8 -DF_CPU=8000000UL -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=test.lst test.c -o test.o
test.c: In function 'read_pcf8591_adc':
test.c:12: warning: passing argument 1 of 'StartI2C' makes integer from pointer without a cast
test.c:18: warning: passing argument 1 of 'StartI2C' makes integer from pointer without a cast
test.c: In function 'main':
test.c:42: warning: passing argument 1 of 'SerWrite' makes pointer from integer without a cast
avr-gcc -c -mmcu=atmega8 -DF_CPU=8000000UL -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=asuro.lst asuro.c -o asuro.o
avr-gcc -c -mmcu=atmega8 -DF_CPU=8000000UL -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=i2c.lst i2c.c -o i2c.o
avr-gcc -mmcu=atmega8 -DF_CPU=8000000UL -I. -g -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=test.o test.o asuro.o i2c.o --output test.elf -Wl,-Map=test.map,--cref -L../../lib -lm -lasuro
c:/winavr/bin/../lib/gcc/avr/4.3.2/../../../../avr/bin/ld.exe: cannot find -lasuro
make: *** [test.elf] Error 1

ExitCode 2
>Ready.

stechmach
03.03.2010, 15:13
ok hab den Fehler selbst gefunden.

Muss ich an die SDA und SCL Leitung einen Widerstand anschließen?
Laut I2C Spezifikation ist dies doch notwendig?
Weil laut Plan der oben genanten Seite muss man nichts anschließen. Und in dem Video funktioniert diese Schaltung ja. Oder wurde da etwas auf der Hauptplatine geändert?

021aet04
03.03.2010, 15:53
An die SCL und SDA Leitungen müssen Widerstände sein. Oft verwendet man die internen Pullupwiderstände des µC. Für höhere Frequenzen bzw längere Leitungen sollte man aber externe Widerstände verwenden.

MfG Hannes

stechmach
03.03.2010, 17:57
So wenn ich die Bauteile zur Linienverfolgung an die analogen Eingänge des PCF8591 anschliese benötige ich ja auch wieder Pulldown Widerstände. Sollte ich da die gleichen verwenden wie original( 20k Ohm) oder sind da auch andere möglich?

m.a.r.v.i.n
03.03.2010, 22:06
Du solltest schon die gleivhen Widerstände verwenden.
Stimmt, in der Schaltung fehlen die I2C PullUp Widerstände (4,7k nach VCC)

stechmach
04.03.2010, 14:48
So habe alles aufgebaut. Aber es will einfach nicht funktionieren. Ich habe den rechten Liniensensor auf den ersten und den linken Sensor auf den zweiten Eingang gelegt, aber ich bekomme keinen vernünftigen Werte über mein Programm. Ich habe mit einem Multimeter nachgemessen und habe festgestellt das sich die Spannung am den Eingängen ändert. Hat jemand ne idee wie ich die Werte in mein Programm bekomme?

021aet04
04.03.2010, 14:57
Zeig einmal dein Programm. Dann kann man helfen.

MfG Hannes

stechmach
04.03.2010, 17:00
#include "asuro.h"
#include "i2c.h"
#include "myasuro.h"
#define pcf8591_address 0x90 // I2C Adresse des PCF8574


//liest einen ADC Wert vom PCF8591
unsigned char read_pcf8591_adc(unsigned char adc)
{
unsigned char ret;
unsigned char byte = 0;

ret = StartI2C(pcf8591_address+WriteI2C); // Sende Start Condition
if (ret == 0)

ret = WriteI2C(adc); // Senden des Control Bytes startet die A/D Wandlung
StopI2C(); // Sende Stop Condition, Bus freigeben
Sleep(10); // Warten bis A/D Wandlung benedet (mind. 90µs)
ret = StartI2C(pcf8591_address+ReadI2C); // Sende Start Condition

if (ret == 0)
{
// Mehrmaliges Lesen um alte A/D Werte zu ignorieren
byte = ReadI2C(1); // Lese Byte + acknowledge
byte = ReadI2C(0); // Lese Byte + no acknowledge
}
else ret = 3;
StopI2C(); // Sende Stop Condition, Bus freigeben
return byte;
}

int main(void)
{
unsigned char rled;
unsigned char lled;
Init();
InitI2C();
FrontLED(ON);
while(1)
{
rled = read_pcf8591_adc(0);
lled = read_pcf8591_adc(1);
SerPrint("\r\n Port 1: ");
SerWrite(rled,3);
SerPrint("\r\n Port 2: ");
SerWrite(lled,3);
Msleep(500);
}
return 0;
}

m.a.r.v.i.n
04.03.2010, 19:28
Vielleicht hast du SDA und SCL vom I2C Bus vertauscht. Laut der myasuro.h muss SDA mit ADC2 und SCL mit ADC3 verbunden werden.

stechmach
04.03.2010, 19:38
Geht das im Programm einfach zu ändern?

stechmach
04.03.2010, 20:09
Laut meiner myasuro.h ist es anders rum.


/* I2C Bus Definitionen */

//#define MY_I2C_SDA PC3
//#define MY_I2C_SCL PC2

/* Fuer das LCD Modul aus dem Asuro Buch gilt folgende Pinbelegung */
#define MY_I2C_SDA PC3
#define MY_I2C_SCL PC2

Ich habe aber auch schon nachgesehen und meiner Meinung nach stimmt der Anschluss. Ich habe aber auch die myasuro.h geändert und mein Prog neu erstellt und es werden auch keine richtigen Daten und auch keine Änderrungen übertragen.
Muss ich eigentlich die originalen Pulldown Widerstände auf der Asuroplatine entfernen, oder kann man diese eingelötet lassen? (diese 20kOhm)

m.a.r.v.i.n
05.03.2010, 09:34
Die 20kOhm PullDown sind bei meinem Asuro auch drin. Die stören nicht weiter.
Normalerweise muss die AsuroLib neu übersetzt werden, wenn Werte in der myasuro.h geändert werden. Vielleicht hilft das ja. Ansonsten würde ich die read_pcf8591_adc Funktion so ändern, das der Rückgabewert im Fehlerfall eindeutig ist. Z.B. so:


if(ret) byte = 0xFF;
return byte;


Was hast du mit den nicht benutzten A/D Eingängen gemacht? Nicht benutze Eingänge müssen laut Datenblatt auf GND gelegt werden.

stechmach
05.03.2010, 09:41
Bis jetzt sind die zwei noch offenen Eingänge nicht belegt. Es soll aber noch ein US-Modul aus dem Buch "Mehr Spaß mit ASURO" auf einen Eingang gelegt werden.

stechmach
05.03.2010, 09:56
Ist der Befehl eigentlich dazu geeignet den byte Wert zu senden?
SerWrite(rled,3);
Oder hat jemand einen besseren?

m.a.r.v.i.n
05.03.2010, 10:16
Ups, deine Ausgabe Funktion habe ich mir ja gar nicht so richtig angeschaut.


PrintInt(rled)

Sollte man hier verwenden, nicht SerWrite. Dann sollte es auch endlich funktionieren.

stechmach
05.03.2010, 13:16
So ich habe den Code geändert und die 2 offenen Eingänge auf Masse gezogen. Über das Terminal bekomme ich immer den Wert 255 gesendet, obwohl sich die Spannung an den Eingänger ändert.
Wer hat da ne Idee?

#include "asuro.h"
#include "i2c.h"
#include "myasuro.h"
#define pcf8591_address 0x90 // I2C Adresse des PCF8574


//liest einen ADC Wert vom PCF8591
unsigned char read_pcf8591_adc(unsigned char adc)
{
unsigned char ret;
unsigned char byte = 0;

ret = StartI2C(pcf8591_address+WriteI2C); // Sende Start Condition
if (ret == 0)

ret = WriteI2C(adc); // Senden des Control Bytes startet die A/D Wandlung
StopI2C(); // Sende Stop Condition, Bus freigeben
Sleep(10); // Warten bis A/D Wandlung benedet (mind. 90µs)
ret = StartI2C(pcf8591_address+ReadI2C); // Sende Start Condition

if (ret == 0)
{
// Mehrmaliges Lesen um alte A/D Werte zu ignorieren
byte = ReadI2C(1); // Lese Byte + acknowledge
byte = ReadI2C(0); // Lese Byte + no acknowledge
}
else ret = 3;
if(ret) byte = 0xEE;
StopI2C(); // Sende Stop Condition, Bus freigeben
return byte;
}

int main(void)
{
unsigned int rled;
unsigned char lled;
Init();
InitI2C();
FrontLED(ON);
while(1)
{
rled = read_pcf8591_adc(0);
lled = read_pcf8591_adc(1);
SerPrint("\r\n Port 1: ");
PrintInt(rled);
SerPrint("\r\n Port 2: ");
PrintInt(lled);
Msleep(500);
}
return 0;
}

stechmach
05.03.2010, 13:35
Bei der Schaltung von dem PCF859 kann ich doch den AGND auf Masse legen oder ist das falsch? Ich habe auch die Liniensensoren mit einem Widerstand auf Masse gelegt.

stechmach
06.03.2010, 23:40
So dieses Problem hat sich erledigt und ich stehe vor dem nächsten. Ich habe eines US Satz von Conrad nach den Vorgaben von der Arexx Seite aufgebaut und das Testprogramm aus der neuen Lib auf den ASURO gespielt, aber er gibt mir nur sehr große Zahlwerte wieder (so um die 250) hin und wieder gibt er mir bei kurzen Entfernungen Werte zwischen 1 und 8 wieder. Kann mir da einer helfen? desweiteren bräuchte ich hilfe beim verändern des Chirp Befehls. Er soll nicht mehr den ADC3 abfragen, sondern den dritten Eingang vom PCF859 als Eingang für das US Signal verwenden.

m.a.r.v.i.n
07.03.2010, 16:03
Was war denn nun das Problem?

Das Ultraschallmodul an dem PCF8591 anzuschliessen, wird nicht funktionieren. Der A/D Port wird in diesem Fall als Komparator verwendet. Dieses Fature gibt es nicht beim PCF8591

stechmach
07.03.2010, 16:19
Es lag an dem Programm vom I2C von der wiki Seite. Da waren die Werte WriteI2C und ReadI2C drin.

ret = StartI2C(pcf8591_address+WriteI2C); // Sende Start Condition
ret = StartI2C(pcf8591_address+ReadI2C); // Sende Start Condition

Diese sind aber Falsch, es muss so aussehen.
ret = StartI2C(pcf8591_address+WRITE);
ret = StartI2C(pcf8591_address+READ);

Ich bekomme aber bei ret immer den Wert 1. Ich habe den Code so geändert, dass er immer auf 0 geht aber das ist ja eigentlich so nicht gedacht. Hier mal der Code:


unsigned char read_pcf8591_adc(unsigned char adc)
{
unsigned char ret;
unsigned char byte = 0;

ret = StartI2C(pcf8591_address+WRITE); // Sende Start Condition
ret=0;
if (ret == 0)
ret = WriteI2C(adc); // Senden des Control Bytes startet die A/D Wandlung
StopI2C(); // Sende Stop Condition, Bus freigeben
Sleep(10); // Warten bis A/D Wandlung benedet (mind. 90µs)
ret = StartI2C(pcf8591_address+READ); // Sende Start Condition
ret=0;
if (ret == 0)
{
// Mehrmaliges Lesen um alte A/D Werte zu ignorieren
byte = ReadI2C(1); // Lese Byte + acknowledge
byte = ReadI2C(0); // Lese Byte + no acknowledge
}
else ret = 3;
StopI2C(); // Sende Stop Condition, Bus freigeben
return byte;
}

Kann man das US Modul umbauen, dass dieser einfach eine Spannung wiedergibt, wenn etwas in 10 cm entfernung ist?