- 12V Akku mit 280 Ah bauen         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Lautsprecher auf rncontrol ansprechen

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    22.11.2003
    Beiträge
    214

    Lautsprecher auf rncontrol ansprechen

    Anzeige

    Powerstation Test
    Hallo,
    ich kämpfe immer noch mit C.
    Ich möchte gerne den Lautsprecher ansteuern. Er hängt an PortD.7/OC2.
    Mit Bascom geht das ganz einfach mit "Sound Portd.7 , 400 , 450".
    So etwas hätte ich gerne auch in C. Aber ich verstehe einfach nicht was ich machen muss und werde aus dem Dantenblatt nicht schlau.
    Kann mir jemand helfen oder einen Hinweis geben wo ich suchen muss?
    Ich kann wohl den Port setzen warten und wieder auf 0 setzen und wieder warten, aber das ist wohl nicht im Sinne des Erfinders.
    Im Prinzip müsste das doch über den Interupt gehen? Aber Ton soll nicht dauerhaft ertönen, so bräuchte man eine Zeitvariable die bei jedem Interupt verkleinert wird. Oder wie kann man das machen?
    Danke
    Gruß Stefan

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Hallo,
    OC2 ?
    Dann ist PWM dein Freund...
    Schau mal unter Timer/Counter2

    Gruß Sebastian

  3. #3
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    22.11.2003
    Beiträge
    214
    Hallo,
    wie soll dasüber PWM funktionieren. Den müsste ich doch auch laufen lassen und warten bis die Tondauer vorbei ist und dann erst den AVR weiter beschäftigen. Oder kann man auch den PWM in einer bestimmten Frequenz für eine bestimmte Zeit laufen lassen und er schaltet sich automatisch ab?
    gruß stefan

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    31.01.2004
    Ort
    36399
    Alter
    49
    Beiträge
    1.562
    oder so geht es auch

    Code:
    	SETBIT(DDRD,PD7); // Das ist der lautsprecher
    	Sound(100,2); // ca. 500 hz bei 16 Mhz wenn die Rechnung stimmt 500 hz = 2000 us 
    	Sound(100,1); // ca. 250 hz bei 16 Mhz
    	Sound(100,2);
    
    void Sound(WORD Count,WORD PulsTime)
    {
    	//am PORTD Pin 7 ist bei der RN-Control ein lautsprecher
    	for(int x=0;x<Count;x++)
    	{
    		wait_ms(PulsTime);
    		SETBIT(PORTD,PD7);
    		wait_ms(PulsTime);
    		CLEARBIT(PORTD,PD7);
    	}
    }
    
    void wait_ms(int ms)
    {
    	int t1,t2;
    	for(t1 = 0;t1 < ms; t1++)
    	{
    		for(t2 = 0 ;t2 < (137 * 16) ; t2++)
    		{
    			asm volatile("nop" ::);
    		}
    	}
    }
    wenn "nur" musik macht ist das ein alternative klar er macht nix anderes in der zeit.
    P: Meine Tochter (06.11.07) und https://www.carnine.de
    M: Träumen hat nix mit Dummheit zu tun es ist die Möglichkeit neues zu erdenken

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Oder kann man auch den PWM in einer bestimmten Frequenz für eine bestimmte Zeit laufen lassen und er schaltet sich automatisch ab?
    Das kannst Du natürlich mit einem Timer erledigen, oder so wie Number Five schrieb mit Delay, kommt drauf an, ob Du eine Symphonie abspielen willst, oder eben hin und wieder einen Piep.

    Gruß Sebastian

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    22.11.2003
    Beiträge
    214
    Danke numberfive,
    so etwas habe ich auch schon wenn auch nicht ganz so schön so, aber ich würde den roboter gerne einen pieb ausgeben lassen, wenn er mit den Sensor z.B. einen Gegenstand gefunden hat und da wäre es günstig wenn der Roboter weiter arbeiten würde.
    Mit dem PWM wirds bei genauerer Betrachtung auch schwierig - glaube ich - da die beiden PWMs für die Motoren benutzt werden.
    Bleibt nur noch der letzte Timer, der über einen Interupt den Port setzt und löscht. Mir ist nur nicht klar welcher timer der letzte ist, wie man initialisiert und welcher interupt vektor der richtige ist. die zeit muss man wohl über einen zeiger setzen und pro interupt aufruf herunterzählen.
    Vielen Dank für deine Hilfe
    gruß
    stefan

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,
    der Lautsprecher hängt an OC2, das gehört zu Timer2, die Motoren laufen mit Timer1 PWM !
    Wenn Du schon einen Timer übrig hast, kann man den auch gleich die Frequenz per PWM erzeugen lassen, und nur warten bis die Zeit rum ist, danach den Ton wieder ausmachen.

  8. #8
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    22.11.2003
    Beiträge
    214
    Aber das Warten gefällt mir einfch nicht. Ich hoffe in den nächsten Tagen Zeit zu haben und etwas genauer in die Interupt funktionen hineinzuschnuppern. Es muss einfach gehen und den Bot lahm zu legen...
    Gruß
    Stefan

  9. #9
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    22.11.2003
    Beiträge
    214
    Hallo,
    nach etwas genauerer Beschäftigung gebe ich den Vorrednern Recht - man gut mit PWM arbeiten. Ich habe mir nun überlegt den Timer mit dem IRQ im Vergleichs-Modus des Timers 2 laufen zu lassen. Ich habe dazu eine globale Variable definiert, die bei jedem IRQ herunter gezählt wird. Ist sie 0 wird der Timer2 und der IRQ ausgeschaltet.
    Ich habe nur noch ein Problem mit der Tondauer. Übergebe ich sie in Sekunden funktioniert alles, Übergebe ich sie in Millisekunden höre ich nur einen kurzen Ton. Warum?
    Hier mal der Code:
    Code:
    /* TODO
    Der OC2 Port muss als Ausgang definiert werden
    Timer/Counter Control Register – TCCR2:
    	Wir Wählen Mode 2 CTC also WGM21 (1)	WGM20 (0) 
    	Wir benötigen den wechsel an OC2 also muss COM21 0 und COM20 1 sein
    	Nun muss der Prescaler gesetzt werden.
    	Table 54. Clock Select Bit Description
    		CS22 	CS21 	CS20 	Description
    		0 		0 		0 		No clock source (Timer/Counter stopped).
    		0 		0 		1 		clkT2S/(No prescaling)
    		0 		1 		0 		clkT2S/8 (From prescaler)
    		0 		1 		1 		clkT2S/32 (From prescaler)
    		1 		0 		0 		clkT2S/64 (From prescaler)
    		1 		0 		1 		clkT2S/128 (From prescaler)
    		1 		1 		0 		clkT2S/256 (From prescaler)
    		1 		1 		1 		clkT2S/1024 (From prescaler)
    
    Output Compare Register – OCR2 Hier setzen wir die Länge des Zählerveergleichs ein
    
    Die Quelle für den Takt des Timers lassen wir auf default
    
    Special Function IO Register – SFIOR brauchen wir nicht zu beachten
    
    Timer/Counter Interrupt Mask Register – TIMSK
    • Bit 7 – OCIE2 wird auf 1 gesetzt um den Interupt zu aktivieren, wenn der Vergleich stimmt
    	(Compare)
    */
    
    void Soundirq (unsigned int Ton, unsigned int Zeit)
    {
    	unsigned int Impulsanz;			
    	unsigned long Impulsanz_L;
    	unsigned int Laenge_L;			
    	unsigned char tmp_sreg;  		// temporaerer Speicher fuer das Statusregister des IRQ
    	unsigned char Laenge;			// Wie lange soll der Timer 2 zählen?
    	
    	/* Wenn ich mich nicht verrechnet habe ist bei 16 MHZ ein Prescaler von 1024 sinnvoll
    		16Mhz / 1024 = 15625 Hz 
    		Dies ist aber nur die doppelte Frequenz. Also kann der höchste Ton eine Frequenz
    		von ca 7,8 kHz erreicht werden.
    		Die niedrigste Frequenz ergibt sich aus diesem Wert durch 255 geteilt.
    		Also ist der tiefste Ton also 30Hz
    		Die Formel für die Länge des Comperatorregisters OCR2 ergibt sich:
    		Laenge = f_quarz / (2* Ton * Prescaler)
    		also ergibt sich mit den ausgerechneten Konstanten: Laenge = 7812 / Ton
    	*/	
    	
    	Laenge_L = 7812 /  Ton; 	// Wie lang ist eine halbe Periodendauer
    	Impulsanz_L = (2 * Ton * Zeit) / 1000; // Wieviele Interupte sind nötig
    	Impulsanz = Impulsanz_L;
    	Laenge = Laenge_L;
    	TCCR2 |= (1 << WGM21) | (0 << WGM20) | (0 << COM21) | (1 << COM20);
    									// Ein IRQ muss in einer Periode 2 mal ausgelöst werden
    	DDRD |= (1 << DDD7); 			// Port D.7 auf Ausgang legen
    	tmp_sreg = SREG;   				// Statusregister (also auch das IRQ-Flag darin) sichern
    	cli();             				// Interrupts global deaktivieren
    	gSounddauer = Impulsanz;
    	OCR2 = Laenge;
    	TCCR2 |= (1 << CS22) | (1 << CS21) | (1 <<	CS20);	// Prescaler auf 1024 setzen 
    	TIMSK |= (1 << OCIE2);			// Timerinterupt einschalten
    	SREG = tmp_sreg;     			// Status-Register wieder herstellen und auch das IRQ-Flag
    									// auf gesicherten Zustand setzen
    	sei();							// Interupt wieder einschalten - falls er nicht schon an war
    }
    
    /*
    Timer 2 ausschalten. Es werden keine Interupts durch ihn ausgelöst
    */
    void Soundirq_aus(void)
    {
    	unsigned char tmp_sreg;  		// temporaerer Speicher fuer das Statusregister
    	tmp_sreg = SREG;   				// Statusregister (also auch das IRQ-Flag darin) sichern
    	cli();             				// Interrupts global deaktivieren
    	TCCR2 = 0;						// Timer 2 wird ausgeschaltet
    	TIMSK &= (0 << OCIE2);			// Timerinterupt ausschalten
    	SREG = tmp_sreg;     			// Status-Register wieder herstellen und auch das IRQ-Flag
    									// auf gesicherten Zustand setzen
    }
    
    
    /* 
    Timer2 Compare Match IRQ Routine
    Wird benutzt um den Ton nur eine bestimme Zeit laufen zu lassen
    PWM möglich oder Port jeweils Invertieren
    */	
    ISR(TIMER2_COMP_vect)
    {
    	if (gSounddauer > 1)
    	{
    		gSounddauer--;				// Anzahl der Impulse veringern, so dass der Ton beendet wird	
    		//PORTD^=(1<<PD7); 			// invertiert Bit 7 an Port D (nichtnötig wenn PWM benutzt wird)
    	}
    	else
    	{
    		Soundirq_aus();					// Timer 2 ausschalten
    	}
    }
    kann mir jemand erklären warum: Impulsanz_L = (2 * Ton * Zeit) / 1000;
    ein falsches Ergebnis liefert?
    Danke
    Gruß
    Stefan

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Wie sind denn Werte für Ton und Zeit?

    Timer2 ist ja nur ein 8-Bit-Timer, evtl hast du ein Überlauf, und die Bits ab 8 aufwärts landen in der Tonne?

    Evtl den Prescaler benutzen, denn werden die Werte kleiner.
    Disclaimer: none. Sue me.

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