Hallo,
Ich möchte mit einen Attiny85 Digispark V3 USB-Board mit einen kleinen
Lautsprecher einen Dauerton erzeugen. Leider erzeugt der folgende
Arduino-Code nur einen sehr leisen Ton.
1 | for (int n=0; n<=800; n++)
|
2 | {
|
3 | digitalWrite(TON, HIGH);
|
4 | delayMicroseconds(500);
|
5 | digitalWrite(TON, LOW);
|
6 | delayMicroseconds(500);
|
7 | }
|
Nach einigen Recherchen habe ich dann bei gleicher elektrischer
Schaltung, folgenden Code getestet.
1 | const int Clock = ((F_CPU/1000000UL) == 16) ? 4 : ((F_CPU/1000000UL) == 8) ? 3 : 0;
|
2 | const uint8_t scale[] PROGMEM = {239,226,213,201,190,179,169,160,151,142,134,127};
|
3 | const int Output = 1;
|
4 | void test_sound ()
|
5 | {
|
6 | for (int n=0; n<=12; n++)
|
7 | {
|
8 | note(n, 4);
|
9 | if (n!=4 && n!=11) n++;
|
10 | delay(100);
|
11 | note(0, 0);
|
12 | delay(100);
|
13 | }
|
14 | TCCR1 &= ~(1 << COM1A0);
|
15 | }
|
16 | void note (int n, int octave)
|
17 | {
|
18 | int prescaler = 8 + Clock - (octave + n/12);
|
19 | if (prescaler<1 || prescaler>15 || octave==0)
|
20 | prescaler = 0;
|
21 | DDRB = (DDRB & ~(1<<Output)) | (prescaler != 0)<<Output;
|
22 | OCR1C = pgm_read_byte(&scale[n % 12]) - 1;
|
23 | GTCCR = (Output == 4)<<COM1B0;
|
24 | TCCR1 = 1<<CTC1 | (Output == 1)<<COM1A0 | prescaler<<CS10;
|
25 | }
|
Und siehe da, dieser Code erzeugt einen gut hörbaren Ton. Leider lässt
sich der Ton nicht abstellen und der Code funktioniert auch nicht mit
externer Spannungsversorgung ohne USB-Anschluss.
Seltsam ist aber das bei identischer elektrischer Beschaltung (es wurde
nur das andere Programm auch den Attiny gespielt) so verschiedene
Ergebnisse erzeugt.
Daraufhin habe ich das Ausgangssignal mit einen Oszilloskop überprüft.
Ohne Last könnte ich beim 1.Code ein etwas verformtes (steile
High-Flanke; LOW-Wert wie eine Kondensatorentladung) 5V Rechtecksignal
messen. Unter Last brach dann aber die Ausgangsspannung zusammen. Bei
einer Last von 10 kOhm war nur noch ca.50% der Amplitudenspannung am
Ausgang vorhanden. Das Rechtecksignal war dann aber relativ sauber.
Beim 2.Code wurde im Leerlauf ein relativ sauberes 5V Rechtecksignal mit
einem Überschwinger in den Flanken gemessen. Bei einer Last von nur
ca.12 Ohm waren noch ca.50% der durchschnittlichen Amplitudenspannung am
Ausgang vorhanden. Die Spannung der Überschwinger war ca. Doppelt so
hoch.
Demnach müsste beim 1.Code der Ausgang einen Innenwiderstand von ca. 10
kOhm haben und beim 2.Code einen Innenwiderstand von ca. 12 Ohm haben.
Dieses Verhalten ist eigentlich nicht nachvollziehbar, da nur die
Software geändert wurde. Leider konnte ich im Datenblatt des Attiny85
nichts finden, was diesen Effekt erklären könnte. Ich bin eigentlich
davon ausgegangen, dass die Funktion digitalWrite() auch nur die
Register setzt. Anscheinend gibt es aber einen Unterschied.
Hat jemand eine Idee wie dieses unterschiedliche Verhalten an ein und
den selben Port zu erklären ist ?