- LiFePO4 Speicher Test         
Ergebnis 1 bis 8 von 8

Thema: Ansteuerung Ultraschallsensor HC-SR04

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    07.07.2009
    Alter
    28
    Beiträge
    96

    Frage Ansteuerung Ultraschallsensor HC-SR04

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo Community!

    Ich möchte einen hc-sr04 mit einem Atmega8 auslesen
    es gibt ja ein paar programme dazu im Internet, die ich allerdings nicht zum laufen bekomme.

    nun meine Frage: Warum geht das nicht so einfach wie im folgenden Code probiert?
    also es lässt sich ohne Fehler Compilieren, danach leuchtet die LED allerdings nur rot.

    das Programm soll die LED einschalten wenn etwas näher als 5 cm am Ultraschallsensor ist.

    Trigger: PC0
    Echo: PC1
    LED: PC3

    Code:
    #define F_CPU 16000000UL
    
    #include <avr/io.h>
    #include <util/delay.h>
    
    
    
    #define ps 1024 //prescaler
    #define ss 343.2 //sound speed
    
    
    
    
    volatile uint16_t value;
    
    
    void timer_init(void){
        TCCR0|=(1<<CS02)|(1<<CS00);//prescale for timer 1024 @16MHz
    }
    
    
    uint8_t HC_SR04(void)
    {
        //generate a trigger signal
        PORTC &= ~(1<<PC0);
        _delay_us(1);
        PORTC |= (1<<PC0);
        _delay_us(10);
        PORTC &= ~(1<<PC0);
        
        while(!(PINC & (1<<PC1)))
        {
            
        }
        //wait until echo pin be high
        TCNT0=0;
        while(PINC & (1<<PC1))
        {
            
        }
    
    
        //count until echo pin be low
        
        return TCNT0*ps*(1/F_CPU)*ss*100;
    }
    
    
    
    
    
    
    void motorInit(void)
    {
        DDRD |= (1<<7) | (1<<6) | (1<<5);
        DDRB |= (1<<0);
        
        PORTD |= (1<<7);
        PORTB |= (1<<0);
        
        PORTD &= ~((1<<6) | (1<<5));
    }
    
    
    
    
    
    
    
    
    
    
    
    
    int main(void)
    {
        motorInit();    //muss aufgrund der gegebenen Platine ausgeführt werden
        
        uint16_t y;
        
        DDRC |= (1<<3) | (1<<0);
        DDRC &= ~(1<<1);
        PORTC &= ~(1<<1);
        timer_init();
        
        while(1)
        {
        
            y=HC_SR04();
            if(y<5)
            {
                PORTC |= (1<<3);
            }
            else 
            {
                PORTC &= ~(1<<3);
            }
            
            _delay_ms(1000);
        }
    }
    Ich hab denk ich alles durchprobiert und da schon einige Stunden dran geschwitzt ^^

    würde mich sehr freuen, wenn mir jemand helfen kann!

    Lukas

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Bist du sicher das die Rechnung nicht 0 ergibt?

    return TCNT0*ps*(1/F_CPU)*ss*100;

    1/F_CPU ergibt sicher 0 bei einem uint8_t
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    07.07.2009
    Alter
    28
    Beiträge
    96
    Erstmal vielen Dank für die Antwort!

    ich hab jetzt nochmal probiert mich in die Formel reinzudenken.

    dabei ist mir was aufgefallen.

    der Timer läuft ja mit einer Frequenz von 16000000/1024 also 15625 Hz.
    da es ja ein 8-bit timer ist kann er ja nur bis 256 Zählen.
    also ist alle 256/15625te Sekunde ein Overflow. also alle 0,016384 Sekunden ein Overflow.
    in der Zeit würde der Schall ja 0,016384*343m zurücklegen. also 5,6 m.
    da er ja in der Zeit hin und zurück muss das ganze durch 2 also 2,8 m.
    na das reicht ja sogar fürs erste^^



    Ich hab jetzt als neue Formel.

    (TCNT0*ps*ss)/(F_CPU*100)

    und ich mach jetzt nen uint_16t draus..

    - - - Aktualisiert - - -

    Immer noch kein Erfolg..
    weiterhin leuchtet die LED nur rot..

    der Code ist jetzt:

    Code:
    #define F_CPU 16000000UL
    
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    
    
    
    
    
    
    #define USART_BAUDRATE 9600
    #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
    #define CR "\r\n"
    #define ps 1024 //prescaler
    #define ss 343.2 //sound speed
    
    
    
    
    volatile uint16_t value;
    
    
    void timer_init(void){
        TCCR0|=(1<<CS02)|(1<<CS00);//prescale for timer 1024 @16MHz
    }
    
    
    uint16_t HC_SR04(void)
    {
        //generate a trigger signal
        PORTC &= ~(1<<PC0);
        _delay_us(1);
        PORTC |= (1<<PC0);
        _delay_us(10);
        PORTC &= ~(1<<PC0);
        
        while(!(PINC & (1<<PC1)))
        {
            
        }
        //wait until echo pin be high
        TCNT0=0;
        while(PINC & (1<<PC1))
        {
            
        }
    
    
        //count until echo pin be low
        
        return (TCNT0*ps*ss)/(F_CPU*100);
    }
    
    
    
    
    
    
    void motorInit(void)
    {
        DDRD |= (1<<7) | (1<<6) | (1<<5);
        DDRB |= (1<<0);
        
        PORTD |= (1<<7);
        PORTB |= (1<<0);
        
        PORTD &= ~((1<<6) | (1<<5));
    }
    
    
    
    
    
    
    
    
    
    
    
    
    int main(void)
    {
        motorInit();    //muss aufgrund der gegebenen Platine ausgeführt werden
        
        uint16_t y;
        
        DDRC |= (1<<3) | (1<<0);
        DDRC &= ~(1<<1);
        PORTC &= ~(1<<1);
        timer_init();
        
        while(1)
        {
        
            y=HC_SR04();
            if(y<5)
            {
                PORTC |= (1<<3);
            }
            else 
            {
                PORTC &= ~(1<<3);
            }
            
            _delay_ms(1000);
        }
    }

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    (TCNT0*ps*ss)/(F_CPU*100)

    Meiner Meinung nach hast du hier ein paar Gedankenfehler. sehen wir uns die Brechung mal an, wie sie tatsächlich gerechnet wird.
    1, (TCNT0*ps*ss) <-- hier hast du als Einheiten eine UNIT8 und 2 defines die max ein Uinteger sind, hiermit wird das Zwischenergebnis auch im besten Fall ein Uinteger.
    Beispiel: TCNT0 kann max 255 sein. 255*1024*343.2= 89616384 ABER du hast nur einen Uinteger, hiermit Max 65535
    Weiters ist ein define 343.2 ist auch gefährlich. Im Besten Fall macht er schneidet er das Nachkomma weg.

    2, F_CPU*100 <- wird eine sehr große zahl 16*10^8

    3, du rechnest 65535/ 16*10^8 <-- da kommt immer null bzw eine sehr kleine Kommazahl heraus die automatisch als null gilt.

    Um sicher zu gehen, wurde ich die Rechnung mal aufteilen und die Zwischenwerte über UART ausgeben.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  5. #5
    shedepe
    Gast
    Und als weiteren Hinweis würde ich dir empfehlen dazu Interrupts zu verwenden, damit du noch mehr Sachen parallel auf dem Controller machen kannst.

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    07.07.2009
    Alter
    28
    Beiträge
    96
    Code:
    int main(void){
    	USART_Init();  // Initialise USART
    	sei();         // enable all interrupts
    	motorInit();	//muss aufgrund der gegebenen Platine ausgeführt werden
    	
    	uint16_t y;
    	
    	DDRC |= (1<<3) | (1<<0);
    	DDRC &= ~(1<<1);
    	PORTC &= ~(1<<1);
    	timer_init();
    	
    	unsigned long v;
    	char v2[12];
    	
    	while(1)
    	{
    		PORTC &= ~(1<<PC0);
    		_delay_us(1);
    		PORTC |= (1<<PC0);
    		_delay_us(10);
    		PORTC &= ~(1<<PC0);
    		
    		while(!(PINC & (1<<PC1)))
    		{
    			
    		}
    		//wait until echo pin be high
    		TCNT0=0;
    		while(PINC & (1<<PC1))
    		{
    			
    		}
    
    
    		//count until echo pin be low
    		
    
    
    		v=TCNT0;
    		sprintf( v2, "%d", v );
    		uart_puts( v2 );
    		uart_puts( "WERT" CR);
    		
    		_delay_ms(500);
    	}
    }
    so sieht jetzt mein code aus..
    und er gibt konstant 169 oder 170 aus..
    warum ist mir zur zeit auch noch unerklärlich. eigentlich müsste er doch schon abstandsabhängig was ausgeben oder?
    Geändert von icebreaker (05.08.2013 um 22:18 Uhr)

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    07.07.2009
    Alter
    28
    Beiträge
    96
    achso und ja mit interrupts werd ichs auch noch probiern, aber erst mal muss es so klappen (;

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    07.07.2009
    Alter
    28
    Beiträge
    96
    auf wundersame weise funktioniert es jetzt doch. ich hab eigentlich nichts geändert.

    jedoch ist mir in der Formel noch ein grober fehler aufgefallen.
    sie muss statt
    (TCNT0*ps*ss)/(F_CPU*100)
    (TCNT0*ps*ss*100)/(F_CPU*2)
    heißen.
    oder in meinem Fall jetzt gekürzt
    TCNT0*(625/686)

    Ich möchte mich nochmal für die Hilfe insbesonders bei Hubert.G Bedanken!

Ähnliche Themen

  1. SR04 mit C Programm Ansteuern.
    Von Catedral im Forum Raspberry Pi
    Antworten: 1
    Letzter Beitrag: 24.04.2013, 13:05
  2. Probleme mit HC-Sr04
    Von bruger im Forum Sensoren / Sensorik
    Antworten: 1
    Letzter Beitrag: 04.01.2013, 09:50
  3. [ERLEDIGT] Abfrage Ultraschallsensor HC-SR04 unter BASCOM
    Von JoeM1978 im Forum Sensoren / Sensorik
    Antworten: 14
    Letzter Beitrag: 15.11.2012, 18:04
  4. Ultraschallsensor
    Von botneuling im Forum Sensoren / Sensorik
    Antworten: 16
    Letzter Beitrag: 04.01.2012, 17:47
  5. Ultraschallsensor HC-SR04 Probleme ungenauigkeit
    Von anfaenger201 im Forum Sensoren / Sensorik
    Antworten: 4
    Letzter Beitrag: 04.08.2010, 15:06

Stichworte

Berechtigungen

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

Labornetzteil AliExpress