KR-500
17.01.2011, 20:05
Hallo
also ich wollte euch mal wieder eines meiner neuen Projekte vorstellen. Diesmal ist es wie der Titel schon sagt eine Tonsteuerung. Ich hab dieses YouTube-Video ( http://www.youtube.com/watch?v=D-anbOj4O1c ) gesehen und war ziemlich begeistert davon also hab ich beschlossen das einmal nachzubauen.
Als Mikrofon benutze ich eine kleine Elektretkapsel, die mit einem 10K Widerstand gegen Masse geschaltet ist, jetzt kann man schon erste Signale am Oszilloskop sehen. Das reicht jedoch nicht ganz aus, also musste ein Vorverstärker her. Den habe ich mit einem Transistor(2n2222) realisiert. Das vorverstärke Signal geht nun in einen Subtrahierer, der mit einem OPV realisiert ist. Das Signal wird wiederum mit einem anderen OPV um den Faktor 20 verstärkt. Jetzt geht es in die letzte Station den Schmitt-Trigger, hier wird also aus dem Sinussignal ein Rechtecksignal "gezaubert".
Das Rechtecksignal geht wiederum in den AVR an einen Interrupt-Eingang wo man nun bequem die Zeit zwischen 2 Flanken messen kann. Hier ist der Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "USART_Util.h"
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
volatile uint8_t flag=0;
volatile unsigned int tcnt=0;
volatile char s[11];
volatile int count = 0;
volatile int count1 = 0;
volatile int count2 = 0;
volatile int count3 = 0;
uint16_t adc_init (int mux) {
uint16_t result;
ADMUX = mux; //0b00100000
ADCSRA |= (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while ( ADCSRA & (1<<ADSC) ) {
;
}
result = ADCH;
result = 0;
_delay_ms (35);
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while ( ADCSRA & (1<<ADSC) ) {
}
result = ADCH;
return result;
}
uint16_t read_adc0 (void){
uint16_t y=0;
ADMUX = 0b11100000;
ADCSRA |= (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while ( ADCSRA & (1<<ADSC) ) {
}
y = ADCH;
return y;
}
int main (void) {
USART_Init(USART_BAUD_SELECT);
uint16_t data;
DDRD = 0x00;
adc_init(0);
USART_String("Hello World!\n");
DDRA = 0xFF;
GICR |= (1<<INT0);
MCUCR |= (1<<ISC00) | (1<<ISC01);
sei();
while(1){
}
return 0;
}
ISR( INT0_vect ){
if(flag == 0){
flag = 1;
TCCR1B |= (1<<CS11) | (1<<CS10); //| (1<<CS10);
PORTA = 0x00;
}
else{
flag = 0;
TCCR1B = 0x00;
if((TCNT1 >= 234) && (TCNT1 <= 300)){
count++;
}
if(count == 25){
PORTA |= (1<<PA0);
count=0;
}
if((TCNT1 >= 151) && (TCNT1 <= 233)){
count3++;
}
if(count3 == 25){
PORTA |= (1<<PA1);
count3 = 0;
}
if((TCNT1 >= 80) && (TCNT1 <= 150)){
count2++;
}
if(count2 == 25){
PORTA |= (1<<PA2);
count2=0;
}
TCNT1 = 0x00;
}
}
Die Auswertung klappt schon ganz gut allerdings funktioniert das nur aus maximal 50 cm Entfernung, das ist enttäuschend, da geplant war das man dem Roboter wie im Video aus ca. 1-2 Meter Entfernung Steuern kann. Leider weiß ich nicht weiter denn selbst die Erhöhung der Verstärkung bringt nicht wirklich ein besseres Ergebnis.
Hat vielleicht schon jemand Anderes Erfahrung mit Mikrofonen und könnte mir Tipps geben? Danke im Vorraus.
Im Anhang befindet sich ein Bild von dem Aufbau.
KR-500
also ich wollte euch mal wieder eines meiner neuen Projekte vorstellen. Diesmal ist es wie der Titel schon sagt eine Tonsteuerung. Ich hab dieses YouTube-Video ( http://www.youtube.com/watch?v=D-anbOj4O1c ) gesehen und war ziemlich begeistert davon also hab ich beschlossen das einmal nachzubauen.
Als Mikrofon benutze ich eine kleine Elektretkapsel, die mit einem 10K Widerstand gegen Masse geschaltet ist, jetzt kann man schon erste Signale am Oszilloskop sehen. Das reicht jedoch nicht ganz aus, also musste ein Vorverstärker her. Den habe ich mit einem Transistor(2n2222) realisiert. Das vorverstärke Signal geht nun in einen Subtrahierer, der mit einem OPV realisiert ist. Das Signal wird wiederum mit einem anderen OPV um den Faktor 20 verstärkt. Jetzt geht es in die letzte Station den Schmitt-Trigger, hier wird also aus dem Sinussignal ein Rechtecksignal "gezaubert".
Das Rechtecksignal geht wiederum in den AVR an einen Interrupt-Eingang wo man nun bequem die Zeit zwischen 2 Flanken messen kann. Hier ist der Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "USART_Util.h"
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
volatile uint8_t flag=0;
volatile unsigned int tcnt=0;
volatile char s[11];
volatile int count = 0;
volatile int count1 = 0;
volatile int count2 = 0;
volatile int count3 = 0;
uint16_t adc_init (int mux) {
uint16_t result;
ADMUX = mux; //0b00100000
ADCSRA |= (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while ( ADCSRA & (1<<ADSC) ) {
;
}
result = ADCH;
result = 0;
_delay_ms (35);
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while ( ADCSRA & (1<<ADSC) ) {
}
result = ADCH;
return result;
}
uint16_t read_adc0 (void){
uint16_t y=0;
ADMUX = 0b11100000;
ADCSRA |= (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while ( ADCSRA & (1<<ADSC) ) {
}
y = ADCH;
return y;
}
int main (void) {
USART_Init(USART_BAUD_SELECT);
uint16_t data;
DDRD = 0x00;
adc_init(0);
USART_String("Hello World!\n");
DDRA = 0xFF;
GICR |= (1<<INT0);
MCUCR |= (1<<ISC00) | (1<<ISC01);
sei();
while(1){
}
return 0;
}
ISR( INT0_vect ){
if(flag == 0){
flag = 1;
TCCR1B |= (1<<CS11) | (1<<CS10); //| (1<<CS10);
PORTA = 0x00;
}
else{
flag = 0;
TCCR1B = 0x00;
if((TCNT1 >= 234) && (TCNT1 <= 300)){
count++;
}
if(count == 25){
PORTA |= (1<<PA0);
count=0;
}
if((TCNT1 >= 151) && (TCNT1 <= 233)){
count3++;
}
if(count3 == 25){
PORTA |= (1<<PA1);
count3 = 0;
}
if((TCNT1 >= 80) && (TCNT1 <= 150)){
count2++;
}
if(count2 == 25){
PORTA |= (1<<PA2);
count2=0;
}
TCNT1 = 0x00;
}
}
Die Auswertung klappt schon ganz gut allerdings funktioniert das nur aus maximal 50 cm Entfernung, das ist enttäuschend, da geplant war das man dem Roboter wie im Video aus ca. 1-2 Meter Entfernung Steuern kann. Leider weiß ich nicht weiter denn selbst die Erhöhung der Verstärkung bringt nicht wirklich ein besseres Ergebnis.
Hat vielleicht schon jemand Anderes Erfahrung mit Mikrofonen und könnte mir Tipps geben? Danke im Vorraus.
Im Anhang befindet sich ein Bild von dem Aufbau.
KR-500