- Labornetzteil AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 19

Thema: problem mit SRF02

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    15.11.2007
    Alter
    44
    Beiträge
    16

    problem mit SRF02

    Anzeige

    Praxistest und DIY Projekte
    Hallo zusammen ,ich hab ein Problem mit dem SRF02,ich hab bis jetzt nur falsche Messung bekommen. ich versuche euch zu erklären was ich genau mache:
    -benutze ein STK500
    -benutze die ATMEGA8515L
    -SRF02
    -programmiere mit dem AVR studio 4 also mit c
    -benutze die Bibliothek von P.Fleury. hab versucht da was zu ändern wir z.B. Port und Pin nun für SDA und SCL.
    -auslesen mit dem Programm :Hterm. eingestellt auf 9600.data 8,stop1 und Parity none

    Also den Sensor steuere ich mit dem I2C Schnittstelle und auslesen mit RS232 am PC.
    Ich hab am Sensor die Pullup wiederstände angebaut .und kann ausschliessen dass ein Hardware fehler gibt.
    Also wenn ich mit (start Debugging) versuche ,bleibt bei i2c_start(0xE0); hängen.
    Wenn ich kompiliere läuft alles ok aber beim auslesen bekomme ich nur 255.Ich weiß dass die 255 bekommt man wenn der Sensor nicht mit messen fertig ist aber ich weiß nicht wie ich es bringe fertig zu sein .-)
    Also ich würde mich freuen wenn jemand von euch mir sagen kann was ich hier falsch mache.
    Hier ist mein Code
    .
    Code:
    #include <avr/io.h>
    #include "i2cmaster.h"
    #define  SRF 0xE0 
    #define F_CPU 8000000UL 
    #include <util/delay.h> 
    #define BAUD 9600
    #include <avr/iom8515.h>
    #include <avr/sfr_defs.h> 
    #define SDA     	0		// SDA Port E, Pin  0 
    #define SCL		    1		// SCL Port E, Pin  1
    #define SDA_PORT        PORTE           // SDA Port E
    #define SCL_PORT        PORTE           // SCL Port E     
    
    
    
    // USART_INIT--
     void initusart(void)           					// Hauptfunktion
     {
    	unsigned char x;							//Hilfsvariable
    //  #idef UBRRL									//USART-Schnittstelle
    	UBRRL = (F_CPU / (16UL*BAUD)) -1;		//Baudrate mit TAKT und Baud
    	UCSRB |= (1<<TXEN) | (1<<RXEN);		//Sender und Empfänger ein
    	UCSRC |= (1<< URSEL) | (1<< UCSZ1) | (1<<UCSZ0); 		//ansync 8bit
    
    	x = UDR;
    }
    
    void sendeusart(int x)
    {
        while (!(UCSRA & (1<<UDRE)));   // warten bis Senden moeglich
    	{
    	}
    
    	UDR = x;
     
    }
    int distance;
    int main(void)
    
    {
    
    
    int distance =0;
    i2c_init();
    initusart();
    //sendeusart(distance);
    unsigned char Lbyte,Hbyte;
    
    
    DDRE = 0xff;
    PORTE = 0xff;
    
    
    while(1)
    { 
    i2c_init();
    i2c_start(0xE0);
    i2c_write(0x00);
    i2c_write(0x51);
    i2c_stop();
    
    _delay_ms(70);
    
    
    
    i2c_start(0xE0);
    
    i2c_write(0x02);
    i2c_start(0xE0);
    i2c_write(0xE1);
    
    Lbyte=i2c_readNak();
    
    Hbyte=i2c_readAck();
    
    distance=(Hbyte*256)+Lbyte;
    
    i2c_stop();
    
     
    sendeusart(distance);
    
    }
    
    }
    ich würde mich sehr freuen für eine Antwort.danke jungs
    Alexandra

  2. #2
    Hallo,

    ich hab da mal was gehört von den internen Pullups am AVR Board, dass man die aktiviert, sobald man den Pin auf 1 also Eingang stellt. Brauchst du da noch die externen Widerstände für den IIC _ Bus?? Genaueres kann ich dir aber nicht sagen, da ich kein AVR Board benutze und nur mit PICs arbeite.

    Aber da könnte auch ein Problem in deiner Routine sein.
    Versuchs mal so:

    i2c_init();
    i2c_start();
    i2c_write(0xE0);
    i2c_write(0x00);
    i2c_write(0x51);
    i2c_stop();

    _delay_ms(70);

    i2c_start();
    i2c_write(0xE0);
    i2c_write(0x02);
    i2c_stop();
    i2c_start();
    i2c_write(0xE1);

    Lbyte=i2c_readNak();

    Hbyte=i2c_readAck();

    distance=(Hbyte*256)+Lbyte;

    i2c_stop();

    Kannst Du bei deinen Routinen generell schon bei i2c_start() eine Geräteadresse übergeben? Bist du da sicher? Das mit dem Restart vor dem Auslesen würde ich durch einen i2c_stop() ersetzten(wie oben im Codestück). Blinkt beim Messen eigentlich die Led, damit man davon ausgehen kann, dass der Senor auch misst?

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.06.2007
    Ort
    München
    Alter
    61
    Beiträge
    199
    Meiner Meinung nach hat Bernhard mit beiden Hinweisen unrecht:
    1. Die internen Pullups an SDA und SCL sind im AVR bei I2C immer deaktiviert, egal was im PORT Register für die beiden Pins steht.
    2. Die Funktion i2c_start(address + {0 oder 1 für Schreiben bzw. Lesen}) erfordert zwingend den o.g. Inhalt als Parameter.

    Meiner Meinung nach liegt Dein Fehler hier, Auszug aus Deinem Code:

    i2c_start(0xE0); <- Fehler, besser i2c_start(0xE1);
    i2c_write(0xE1); <- Fehler, löschen

    Lbyte=i2c_readNak(); <- wie bernhard geschrieben hat: hinter den nächsten Befehl schieben

    Hbyte=i2c_readAck();


    Direkt vor dem Lesen (mit i2c_readAck) müßte es richtig heißen:
    i2c_start(0xE1)

    Du kannst nicht einfach ohne i2c_start von Schreiben auf Lesen wechseln.

    Gruß, Dirk.

  4. #4
    Hallo,

    ich sollte meine Vorlaute Klappe halten. Ich werd keine Kommentare mehr über das AVR abgeben, weils ja auch nicht mein Gebiet ist.

    Hier das Code Beispiel aus der Doku des Sensors SRF10:

    Srf10_slaveid_read = Srf10_slaveid + 1
    'Messvorgang in starten
    I2cstart
    I2cwbyte Srf10_slaveid
    I2cwbyte 0
    I2cwbyte 81 'in Zentimetern messen
    I2cstop

    Warteaufmessung:
    Waitms 1
    Firmware = Srf10_firmware(&He0)
    If Firmware = 255 Then Goto Warteaufmessung

    I2cstart
    I2cwbyte Srf10_slaveid
    I2cwbyte 2 Leseregister festlegen
    I2cstop
    I2cstart
    I2cwbyte Srf10_slaveid_read
    I2crbyte Hib , Ack
    I2crbyte Lob , Nack
    I2cstop

    Ich hab blöderweise bei i2c_read übersehen, dass sterncapture die beiden Zeilen für das Auslesen von Hbyte und Lbyte verwechselt hat. Es muss so wie in diesem Auszug sein, dann gehts.

    mfg.

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    15.11.2007
    Alter
    44
    Beiträge
    16
    Hallo Jungs!

    Danke für Eure Hilfe. Aber leider funktioniert es immer noch nicht. Ich bekomme immer 255 als Antwort. Ich kann nicht i2c_start() so schreiben, sonst gibt es eine Fehlermeldung. Weil ich die Bibliothek von Pfleury benutze. Aber ich verstehe immer noch nicht, wieso beim Debugg das Programm bei i2c_start(0*E0). Der Sensor blinkt immer und signalisiert, dass er misst, aber ich bekomme immer 255. Jungs, ich bin echt ratlos. Fällt Euch vielleicht noch eine andere Lösung ein. Bitte helft mir!!!!

    Mit freundlichen Grüßen
    Alexandra

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    15.11.2007
    Alter
    44
    Beiträge
    16
    danke bernhard1366 kannst du bitte den Code von dem SFR10 auf C sprache übersetzen ,umzu sehen ob es so funktionieren kann,da leider meine kenntnisse was C programmieren angeht nicht so toll sind.
    danke sehr .

    MFG
    Alexandra

  7. #7
    Hallo Sterncaptue

    Ich kenne die Bibliothek von Pfleury nicht, da meine IIC - Routinen selber geschrieben sind, also werde ich darüber auch nichts mutmaßen.
    Hast du deinen Fehler beim Auslesen schon ausgebessert?
    Also du musst zuerst das Hbyte auslesen und dazu den Befehl i2c_readACK() verwenden und dann das Lbyte mit i2c_readNAK().

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.06.2007
    Ort
    München
    Alter
    61
    Beiträge
    199
    Hallo Sterncapture,

    lautet Dein Code zum Lesen nun so?

    i2c_start(0xE1);
    Hbyte=i2c_readAck();
    Lbyte=i2c_readNak();
    i2c_stop();

    Lies Dir bitte noch mal meinen Comment oben durch, ich hab noch kleinere Fehler ausgebessert.

    Ansonsten schreib bitte nochmal genau, mit welchem Code Du nun arbeitest.

    Gruß, Dirk.

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    15.11.2007
    Alter
    44
    Beiträge
    16
    Hallo uffi;
    danke für die Erklärung,ich hab genau geschrieben ,was du mir gesagt hast ,leider das Ergibniss ist immer das gleiche hier ist mein Code nochmal :

    Code:
    #include <avr/io.h>
    #include "i2cmaster.h"
    #define  SRF 0xE0 
    #define F_CPU 8000000UL 
    #include <util/delay.h> 
    #define BAUD 9600
    #include <avr/iom8515.h>
    #include <avr/sfr_defs.h> 
    #define SDA     	0		// SDA Port E, Pin  0 
    #define SCL		    1		// SCL Port E, Pin  1
    #define SDA_PORT        PORTE           // SDA Port E
    #define SCL_PORT        PORTE           // SCL Port E     
    
    
    
    // USART_INIT--
     void initusart(void)           					// Hauptfunktion
     {
    	unsigned char x;							//Hilfsvariable
    //  #idef UBRRL									//USART-Schnittstelle
    	UBRRL = (F_CPU / (16UL*BAUD)) -1;		//Baudrate mit TAKT und Baud
    	UCSRB |= (1<<TXEN) | (1<<RXEN);		//Sender und Empfänger ein
    	UCSRC |= (1<< URSEL) | (1<< UCSZ1) | (1<<UCSZ0); 		//ansync 8bit
    
    	x = UDR;
    }
    
    void sendeusart(int x)
    {
        while (!(UCSRA & (1<<UDRE)));   // warten bis Senden moeglich
    	{
    	}
    
    	UDR = x;
     
    }
    int distance;
    int main(void)
    
    {
    
    
    int distance =0;
    i2c_init();
    initusart();
    sendeusart(distance);
    unsigned char Lbyte,Hbyte;
    
    
    DDRE =  0xff;
    PORTE = 0xff;
    
    while(1)
    { 
    
    i2c_init();
    
    i2c_start(SRF);
    i2c_write(0x00);
    i2c_write(0x51);
    
    i2c_stop();
    
    _delay_ms(70);
    
    i2c_start(SRF);
    
    i2c_write(0x02);
    
    i2c_stop();
    
    i2c_start(0xE1);
    
    Hbyte=i2c_readAck();
    
    Lbyte=i2c_readNak();
    
    distance=(Hbyte*256)+Lbyte;
    
    sendeusart(distance);
    
    i2c_stop();
    
    }
    
    }
    Danke und ich hoffe das du mir hilfen kannst
    Gruss Alexandra

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    01.06.2007
    Ort
    München
    Alter
    61
    Beiträge
    199
    Hallo Alexandra,

    ich habe mir Deinen Code angesehen und kann - bis auf ein paar Unschönheiten - keinen plausiblen Grund finden für den beschriebenen Fehler.

    Aber ich hab noch folgende Idee:
    - könnte es sein, dass Du im makefile das Assembler-File i2cmaster.S nicht mit kompilieren läßt? Du musst das makefile aus der Bibliothek von Peter Fleury benutzen und dort unter Assembler-Sourcen das File i2cmaster.S aufführen.

    Wie stellst Du eigentlich fest, dass Du am I2C Bus nur $FF liest?
    Es könnte doch auch sein, dass Deine RS232 Routine fehlerhaft ist.
    Um das zu überprüfen, würde ich den gelesenen Wert im EEPROM speichern (das habe ich unten im Code eingefügt).

    Ansonsten empfehle ich Dir, Deinen Code wie folgt abgeändert zu übernehmen (Änderungen in Fettdruck):

    #include <inttypes.h>
    #include <avr/eeprom.h>
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #include <math.h>


    #include <avr/io.h>
    #include "i2cmaster.h"
    #define SRF 0xE0
    #define F_CPU 8000000UL
    #include <util/delay.h>
    #define BAUD 9600
    #include <avr/iom8515.h>
    #include <avr/sfr_defs.h>
    #define SDA 0 // SDA Port E, Pin 0
    #define SCL 1 // SCL Port E, Pin 1
    #define SDA_PORT PORTE // SDA Port E
    #define SCL_PORT PORTE // SCL Port E

    unsigned int distance EEMEM; // reserve storage space in EEPROM

    // USART_INIT--
    void initusart(void) // Hauptfunktion
    {
    unsigned char x; //Hilfsvariable
    // #idef UBRRL //USART-Schnittstelle
    UBRRL = (F_CPU / (16UL*BAUD)) -1; //Baudrate mit TAKT und Baud
    UCSRB |= (1<<TXEN) | (1<<RXEN); //Sender und Empfänger ein
    UCSRC |= (1<< URSEL) | (1<< UCSZ1) | (1<<UCSZ0); //ansync 8bit
    x = UDR;
    }

    void sendeusart(int x)
    {
    while (!(UCSRA & (1<<UDRE))); // warten bis Senden moeglich
    UDR = x;
    }

    int main(void)
    {
    i2c_init(); // einmal zu Anfang reicht
    initusart();
    sendeusart(distance);
    unsigned char Lbyte,Hbyte;

    DDRE = 0xff;
    PORTE = 0xff;

    while(1)
    {
    i2c_start(SRF);
    i2c_write(0x00);
    i2c_write(0x51);
    i2c_stop();

    _delay_ms(70);

    i2c_start(SRF);
    i2c_write(0x02);
    i2c_stop();

    i2c_start(0xE1);
    Hbyte=i2c_readAck();
    Lbyte=i2c_readNak();
    i2c_stop();

    distance=(Hbyte*256)+Lbyte;
    eeprom_write_word(&distance,distance); //save to EEPROM

    sendeusart(distance);
    }
    }

    Auszug aus dem makefile:

    # Target file name (without extension).
    TARGET = "Dein Dateiname"

    # List C source files here. (C dependencies are automatically generated.)
    SRC = $(TARGET).c

    # List Assembler source files here.
    # Make them always end in a capital .S. Files ending in a lowercase .s
    # will not be considered source files but generated files (assembler
    # output from the compiler), and will be deleted upon "make clean"!
    # Even though the DOS/Win* filesystem matches both .s and .S the same,
    # it will preserve the spelling of the filenames, and GCC itself does
    # care about how the name is spelled on its command-line.
    ASRC = i2cmaster.S

    Gruß, Dirk.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad