- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 10 von 13

Thema: Ultraschall Sensor im Selbstbau

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    08.04.2006
    Beiträge
    23
    Hallo,
    hier schonmal die I2C Version mit einem Sensor:
    Code:
    	#define F_CPU 8000000 			//internal Oscillator CKDIV8 not set fuse low 0xXX //TODO
    	#define	TWI_slaveAddress  0x10
    	#define ULTRASONIC_VERSION	"Built " __DATE__ " " __TIME__	
    
    	#define TRANSMIT_DIST01	0x01
    
    	#include <avr/io.h>
    	#include <avr/interrupt.h>
    	#include <util/delay.h>
    	#include "i2c-slave.h"
    
    
    	void us_burst(void);
    	void clear_burst(void);
    	void enable_ain(void);
    
    
    	#define soundspeed_per_tick 4 		//4.3mm both ways per tick
    
    	#define BURSTS 16					// number of half periods to "ping"
    	#define TIMERCOUNT 	F_CPU / 80000	// preload for timer
    										// toggle the ports when reached 8 000 000 / 80 000 = 100 !!!
    
    	register unsigned char timer_ticks asm("r10"); 	/* ticks since start of ping */
    	unsigned char echo_ticks=0; 	 				/* ticks when the echo was received */
    	int distance=0;
    	unsigned char disp;
    
    /* 
     * Main Program
     */
    int main (void){
    
    
    	unsigned char command, active;
    
      	// Own TWI slave address
      	i2c_initialize ( TWI_slaveAddress );
    	sei(); 			// allow ints
    	
    
    	DDRD = 0x7f; 	// everything output
    
    	DDRB |= (1<<PB2);   // Pin 2 Output
    	DDRB |= (1<<PB3);   // Pin 3 Output
    	DDRB &= ~(1<<PB1);// Pin 0 Input
    	DDRB &= ~(1<<PB0);// Pin 0 Input
        PORTD = 0x7f;
    	active = 0;
    	while (1) {
    		if (active==0) {
    			echo_ticks = 0;
    			timer_ticks = 0;
    			us_burst();
        		enable_ain();
    			active = 1;
    		}
    		if ((active==1) & (timer_ticks>240))
    		{		
    			//while ((timer_ticks<240) ){	//arbitrary end but mine can't see further
    				asm("nop"); 
    			clear_burst();
    			active = 0;
    			//distance = echo_ticks * soundspeed_per_tick;
    
    			
    			disp = 0;
    			if (echo_ticks > 110) {
    				disp |= _BV(PD6);
    			}
    			if (echo_ticks > 80) {
    				disp |= _BV(PD5); 
    			}
    			if (echo_ticks > 50) {
    				disp |= _BV(PD4);
    			}	
    			if (echo_ticks > 30) {
    				disp |= _BV(PD3);
    			}	
    			if (echo_ticks > 20) {
    				disp |= _BV(PD2);
    			}	
    			if (echo_ticks > 10) {
    				disp |= _BV(PD1);
    			}	
    			if (echo_ticks > 0) {
    				disp |= _BV(PD0);
    			}	
    			PORTD = disp;			//show it
    			while (i2c_reply_ready()==0) {} //wait to put data
    			if (i2c_reply_ready()){
    			    i2c_rdbuf[0] = echo_ticks;		// put data in I2C buffer
       				i2c_reply_done(1);
    			}
    		}
    
    	
    		if (i2c_message_ready()) {
       			i2c_message_done(); // don't do anything
    		}
    		_delay_ms(3.0);		// wait for next run	
    
    	}
    }
    
    /*
     * Interrupt Handler for Timer/Counter 0 
     */
    ISR (TIMER0_COMPA_vect){
     timer_ticks ++;
     if (timer_ticks <=BURSTS) {	
    	 PORTB ^= ((1<<PB3)|(1<<PB2)); //toggle the Pins
     }
    }
    
    
    
    /*
     * Timer 0:
     */
    void us_burst(void){
    	PORTB |= (_BV(PB3)); 		// ON
    	PORTB &= ~(_BV(PB2)); 		// OFF
     	TCNT0  = 0x00;             	// TIMER0 preload
    
    	TCCR0A &=  ~(_BV(COM0A1));
    	TCCR0A &=  ~(_BV(COM0A0)); 	//Normale mode OC0A disconnected
    	TCCR0A &=  ~(_BV(COM0B1));
    	TCCR0A &=  ~(_BV(COM0B0)); 	//Normale mode OC0B disconnected
    	TCCR0A |=  _BV(WGM01);		// CTC
    	TCCR0B |=  _BV(CS00) ;		// use internal clock 		
    								//no, we do it by hand
    	//_BV(COM00) ;    			// Toggle OC0 on compare match		
    	OCR0A = TIMERCOUNT;			// toggle bei erreichen 8 000 000 / 80 000 = 100 !!!
    	TIMSK  |= _BV(OCIE0A);	 	// enable Output Compare 0 overflow interrupt
    	GTCCR  |= _BV(PSR10);		// clear timer counter prescaler
    	SREG   |= _BV(SREG_I);
    	sei();                		// enable interrupts
    }
    
    void clear_burst(void) {
    	//Stop it
     	TCCR0A &= ~(1<<CS00); // stopt den timer 
     	TCCR0A &= ~(1<<CS01);
     	TCCR0A &= ~(1<<CS02);
     	TIMSK &= ~(1<<OCIE0A);
    	PORTB &= ~(_BV(PB2) | _BV(PB3) ); // OFF
    }
    
    
    /*
     * Analog compare handling
     */
    
    ISR (ANA_COMP_vect) {
    	echo_ticks = timer_ticks;
    	ACSR &= ~(_BV(ACIE)); // turn interupt off, so we don't catch the next wave again	
    }
    
    void enable_ain(void) {
    	ACSR &= ~(_BV(ACIE)); // interupt has to be off whenn switching ACD (see Datasheet) 
    	ACSR &= ~(_BV(ACD));  // zero means turn on Analog comparator
    	ACSR |=  _BV(ACIE) | _BV(ACIS0) | _BV(ACIS1); // interupt enable, trigger on rising edge
    }
    Dazu braucht ihr noch die usi-slave.zip, die es in folgendem Thread zum download gibt (relativ weit unten):
    http://www.mikrocontroller.net/forum/read-4-290268.html

    Abfragen könnt ihr den Sensor dann vom "Hauptrechner" aus wie folgt (Beispiel mit der TWI Library von Peter Fleury):
    Code:
    unsigned char readDist01(void) {
    	unsigned char ret;
    	ret = i2c_start(UltrasonicSlaveAddress+I2C_READ);
        if (ret ==1) {
    		beep();
    	}		
    	else {
    		ret = i2c_readNak();
    	}
    	return ret;
    }
    Comments welcome.

    Anbei noch 2 Bilder von Work in Progress. Ich habe versucht den analogen Teil zusammen mit den Kapseln auf eine Platine outzusourcen. Kann das einer von euch mit klassischen Bauteilen (kein SMD) noch kleiner?

    So long
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken sensor2_154.jpg   sensor_671.jpg  

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress