Forum: Mikrocontroller und Digitale Elektronik Sauberes Audio Signal mit Attiny85


von Toni (Gast)


Lesenswert?

Hallo zusammen,

ich möchte mit dem Attiny85 ein Audio Signal von ca. 13kHz erzeugen. 
Soll ein Marderschreck werden. Den Ton bekomme ich leider mit etwas 
jitter Effekten, bzw. zeigt mein Scope an dass die Perioden etwas 
zittern und somit auch ein verrauschtes Signal wahrgenommen wird. 
Arbeite hier mit dem CTC Modus des Attiny, Spannungsversorgung ist 
sauber und ein 0.1uF Kondensator wurde auch implementiert. Kann mir 
jemand sagen an was es liegt? Untere Frequenzen wie bspw. 500 Hz sind 
nicht so sehr verrauscht wie die im oberen Bereich.

Hier mein Code:

#include <avr/io.h>

int a = 1;

void setupTimer1() {
  noInterrupts();
  TCNT1 = 0;
  TCCR1 = 0;
  GTCCR |= (1 << PSR1);
  TCCR1 |= (1 << CTC1);
  OCR1C = 4;
  OCR1A = OCR1C;
  TCCR1 |= (0 << CS13) | (1 << CS12) | (1 << CS11) | (1 << CS10);
  TIMSK |= (1 << OCIE1A);

  interrupts();
}

void setup() {
  DDRB = 0b00000010;
  setupTimer1();
}

void loop() {
}

ISR(TIMER1_COMPA_vect) {

    if(a==1){
      PORTB = 0b00000010;
      a=0;
    }else if(a==0){
      PORTB = 0b00000000;
      a=1;
    }

}

von Michael U. (amiga)


Lesenswert?

Hallo,

setup() und loop() sieht nach Arduino aus, da läuft auch noch was davon, 
Timer0 für mills() wenn ich nicht irre.

Laß setup() und loop() weg und nutze nur einen main(), dann wird nichts 
gemacht, was Du nicht reinschreibst.
Timer im CTC-Mode kann ein Ausgangspin alleine toggeln, das braucht dann 
keine IRQ-Routine.
Also nur
1
main()
2
{
3
.. Timer passend initialisieren
4
 while(1); // und garnichts weiter machen
5
}

Gruß aus Berlin
Michael

von Stefan F. (Gast)


Lesenswert?

Inwiefern braucht man einen "sauberen Ton" um Marder zu erschrecken?

Abgesehen davon wurde hier im Forum bereits mehrfach berichtet, dass 
diese Akustische Abschreckung nur wenige Tage lang wirksam ist. Auf der 
anderen Seite belästigt man damit zahlreiche andere Tiere.

von Toni (Gast)


Lesenswert?

Hi Michael,

habe den Code angepasst. Tut sich leider noch nichts. Muss ich zum 
toggeln noch ein anderes Register setzen?

#include <avr/io.h>
#include <avr/interrupt.h>

int main(void)
{

  DDRB = 0b00000010;
  TCNT1 = 0;
  TCCR1 = 0;
  GTCCR |= (1 << PSR1);
  TCCR1 |= (1 << CTC1);
  OCR1C = 4;
  OCR1A = OCR1C;
  TCCR1 |= (0 << CS13) | (1 << CS12) | (1 << CS11) | (1 << CS10);
  TIMSK |= (1 << OCIE1A);

 while(1);
}



Wo liegt mein Fehler?

Grüße aus Berlin zurück

von Stefan F. (Gast)


Lesenswert?

Toni schrieb:
> Wo liegt mein Fehler?

Unvollständiger Code.

OCIE1A aktiviert einen Interrupt. Du hast keine zugehörige ISR.

von Toni (Gast)


Lesenswert?

Gerade herausgefunden, danke. Hier der funktionierende Code:

#include <avr/io.h>
#include <avr/interrupt.h>

int main(void)
{

  DDRB = 0b00000010;
  TCNT1 = 0;
  TCCR1 = 0;
  GTCCR |= (1 << PSR1);
  TCCR1 |= (1 << CTC1);
  TCCR1 |= (1 << COM1A0);
  TCCR1 |= (0 << CS13) | (1 << CS12) | (1 << CS11) | (1 << CS10);
  OCR1C = 4;
  OCR1A = 4;

 while(1);
}

von Audiomann (Gast)


Lesenswert?

Ist denn ein sauberes Signal für den Marder überhaupt hilfreich? Wäre 
ein Zerrton nicht besser? Oder ist das Zerren im hörbaren Bereich?

Andere Idee: Es gibt doch die Selbständigen Audioplayer auf Sparkfun. 
Wie wäre es denn, einfach Helene Fischers Atemlos auf alles über 100Hz 
zu begrenzen und so ein File mit Faktor 256 abzuspielen? Es gabe nur 
Frequenzen ab 25kHz und die 3min40 wären in 1 Sekunde abgestrahlt. Den 
Marder möchte ich mal sehen, der dabei noch Appetit auf Kabel hat.

von Toni (Gast)


Lesenswert?

@Audiomann, gute Idee, doch was machen wir wenn daraus ein Helene 
Fischer Marder Fanclub entsteht? Das kann ganz schöne Folgen haben...

von Toni (Gast)


Lesenswert?

Nächste Frage gute Frage, ich möchte den Ton nur alle x Sekunden 
ausgeben. Wie stelle ich das nun am besten an? Ich würde jetzt spontan 
den Timer0 nutzen um eben den Timer1 alle x Sekunden zu triggern und 
dann wieder die Register alle x + t Sekunden zurückzusetzen. Was meint 
ihr?

von Audiomann (Gast)


Lesenswert?

Toni schrieb:
> @Audiomann, gute Idee, doch was machen wir wenn daraus ein Helene
> Fischer Marder Fanclub entsteht? Das kann ganz schöne Folgen haben...

Nur die, dass sich die verirrten Viecher headbangend unter dem Auto des 
TE versammeln und damit kann ich leben. So haben wir ja das Problem, 
dass Marder verschreckt werden und unter andere Autos kriechen, deren 
Besitzer dann auch wieder Marderschreckschaltungen kaufen müssen. Am 
Ende gehen die Marder dann doch unter ein Auto und zwar unter das, das 
am leisesten ist. Wir kriegen also eine Aufrüstung.

Im Ernst: Ich bin gegen diese Lärmdinger, weil sie die Natur stören. 
Nicht nur Fledermäuse hören im Ultraschall. Das Ganze wird langsam zum 
Problem, weil jeder Dödel auf die Idee kommt, Lärm zu produzieren, um 
Tiere abzuschrecken. Neuester Unfug sind Ultraschalltröten am Auto, die 
bei Fahrtwind Dauerlärm machen.

Wer Angst hat vor Tieren hat, soll langsam fahren und bei Mardern 
einfach die Garage oder den Unterboden abdichten. Es gibt dafür 
einfacher Gitterlösungen. Hat meiner auch, vom Händler nachgerüstet.

von Toni (Gast)


Lesenswert?

Das Problem ist nicht am Auto... Sondern unterm Dach ^^ Die Dinger sind 
bei uns ca. in 10 Meter Höhe installiert... Rein empirisch 
funktioniert's bei uns. Das Signal sollte aber nicht nach einem festen 
Muster "abgespielt" werden.

Kann eure Gründe gut nachvollziehen... Dachschaden ^^ bleibt aber 
Dachschaden. Ist es tatsächlich so dass Töne bei 12 kHz von Fledermäusen 
gehört werden können? Wenn das stimmen sollte dann ist die Lösung 
natürlich suboptimal. Ich dachte Ultraschall fängt bei ca 16kHz-20kHz 
an.

von Joe F. (easylife)


Lesenswert?

Portänderung ganz am Anfang vom Interrupt machen.
So jittert es weniger.
Die ganzen if's braucht mam auch nicht.
1
int a=0;
2
3
ISR(TIMER1_COMPA_vect) 
4
{
5
  PORTB = a;
6
  a ^= 0b00000010;
7
}

: Bearbeitet durch User
von Einer K. (Gast)


Lesenswert?

Toni schrieb:
> ISR(TIMER1_COMPA_vect) {
>
>     if(a==1){
>       PORTB = 0b00000010;
>       a=0;
>     }else if(a==0){
>       PORTB = 0b00000000;
>       a=1;
>     }
>
> }

ISR(TIMER1_COMPA_vect)
{
  PINB = 0b00000010;
}

Aber wozu ISR, wenns denn in Hardware geht.

von Bernd (Gast)


Lesenswert?

Beim Tiny85 kannst Du den Timer 1 auch im asynchronen Modus betreiben:
1
PLLCSR = 1<<PLLE | 1<<PCKE;
Damit läuft der Timer mit einem Takt von 64 MHz.

Rechteck, Sägezahn, Dreieck:
http://www.technoblogy.com/show?QVN

Sinus:
http://www.technoblogy.com/show?22HF

Da wird der Marder aber gucken (bzw. lauschen)...


P.S.: BTW - Weiß jemand, welche AVRs auch noch so einen High-Speed-Timer 
haben?
Bisher sind mir die ATtiny25/45/85, ATtiny26, ATtiny261/461/861 und die 
AT90PWM2/3/2B/3B mit dem Power Stage Controller bekannt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.