Forum: Mikrocontroller und Digitale Elektronik Sinus sehr seltsam


von William (Gast)


Lesenswert?

Hallo,
es gibt viele Threads dazu, die mir alle nicht weiterhelfen.

ich möchte per pwm einen hörbaren Sinus mit verschiedenen Frequenzen 
realisieren.
ATtiny44a  3V

ich habe dieses Beispiel in die Register meines AVR's übersetzt:
http://www.infolexikon.de/blog/atmega-music/

ich habe keine Filterung und ein Piezo ist direkt zwischen Pin und 
Masse.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <stdio.h>
4
#include <stdint.h>
5
#include <avr/pgmspace.h>
6
#include <util/delay.h>
7
// Noten-Frequenzen
8
#define c 2
9
#define d 90
10
#define e 50000
11
#define p 0   // Pause
12
struct notendauer
13
{
14
uint16_t note;
15
uint16_t dauer;
16
};
17
struct notendauer entchen[3] =
18
{
19
{c,1200}, {d,1200}, {e,500}
20
};
21
22
// einfache Sinuswelle in 128 Werten
23
const uint8_t  sinewave[1][128] PROGMEM=
24
{
25
{
26
127, 
27
133, 
28
139, 
29
// ... für das Forum verkürzt, es sind wirklich 128 ...
30
31
115, 
32
121
33
}
34
};
35
uint16_t i=0;
36
uint8_t tone=0;
37
volatile uint16_t scale=523;
38
39
// Interrupt-Funktion, die den "Zeiger" hochzählt
40
// je nach gewünschter Frequenz wird "scale" verändert, 
41
// und somit die Sinuswelle schneller (hoher ton) 
42
// oder langsamer (tiefer Ton) abgelaufen
43
ISR(TIM1_COMPA_vect){
44
  OCR1A=pgm_read_byte(&sinewave[tone][(i>>8)]);
45
     i += scale;
46
}
47
int main(void)
48
{
49
    // PWM-INIT -----------------------------------
50
  // PA 6 als ausgang pwm ausgang 44a
51
  DDRA=(1<<PA6);  
52
  // Anfangswert der PWM
53
  OCR1A=0x80;  // 128  
54
  //Output compare OC1A 8 bit non inverted PWM
55
  TCCR1A=0x91;  
56
  // Timer ohne Prescaler starten
57
    TCCR1B=(1<<CS10); 
58
  
59
  // Einschalten des Ausgangs-Vergleichs-Interrupts auf OC1A (PA6)
60
      TIMSK1=(1<<OCIE1A);
61
  //enable global interrupts
62
  sei();
63
    // MAIN-LOOP ----------------------------------
64
    while(1)
65
    {
66
  // durch das Noten-Array laufen und nacheinander
67
  // die Töne in jeweiliger Länge abspielen
68
  // da "scale" global definiert ist, kann es einfach
69
  // hier geändert werden!
70
  for(int y=0;y<3;y++){
71
    scale = entchen[y].note;
72
//  scale = 9000;
73
  //  _delay_ms(entchen[y].dauer);
74
  _delay_ms(9000);
75
76
    // Interrupt kurz ausschalten
77
    cli();
78
    i=0;
79
    sei();
80
  }
81
    }
82
    return 0;
83
}


Das Problem ist, dass immer die gleiche Frequenz raus kommt. Wenn scale 
klein ist also so zwischen 2 und 90 höre ich diese Frequenz schwingend 
lauter und leiser werden. Wenn scale sehr groß ist, brummt es.
Wenn ich PROGMEM nicht verwende scheint alles schneller zu laufen: bei 
hohem scale hört man Rauschen (mit der alt bekannten Frequenz im 
Hintergrund) bei niedrigem scale hat man wieder den Tremolo-effekt.

Auch das Orginal klingt auf einem ATMEGA 8 nicht nach Alle meine 
Entchen.
Was ist da los?

kann mir jemand helfen?

von Uwe (Gast)


Lesenswert?

Hi!
>ich habe keine Filterung
Aus dem Bauch heraus würde ich sagen das ist dein Problem weil du die 
Grundfreqenz der PWM überlagert hast. Obwohl, du hast ja 8-Bit PWM, 
wobei 1MHz/256=3,9KHz... da spielst du überhaupt kein Entchen. Mit 16MHz 
biste bei 62,4KHz, das könnte eher gehen. Vermutlich biste aber so bei 
1MHz und dein Tremolo könnte doch glatt der Ton sein. Musste halt etwas 
langsamer hören, da wirds schon passen ;)Welchen Grundtakt hat denn der 
Proz.?

Schöne Nacht noch, Uwe

von Michael (Gast)


Lesenswert?

William schrieb:
> // Interrupt kurz ausschalten
>     cli();
>     ...
>     sei();

Wozu das?

von Stefan P. (form)


Lesenswert?

William schrieb:
>ein Piezo ist direkt zwischen Pin und Masse.

Achtung, es gibt auch welche die "von selbst" schwingen.
Wenn Du 5 Volt dranhälst - Knackt es oder piept es?

von William (Gast)


Lesenswert?

Guten Morgen,
Dankefür Antworten

> 1MHz und dein Tremolo könnte doch glatt der Ton sein. Musste halt etwas
> langsamer hören, da wirds schon passen ;)Welchen Grundtakt hat denn der
> Proz.?

über die Fuse sind 8MHZ eingestellt, im Datenblatt steht oben bei der 
Übersicht  0 – 10 MHz @ 2.7 – 5.5V  ich habe 3V und keinen externen 
Quarz.
wie kann ich Frequenz "messen"?
wenn ich statt 256 Sinusstützpunkten 128 nehme ist der Ton der gleiche, 
Tremolo aber schneller.

Bei höherem scale (z.B. 30000) rauscht es dann aber mit Grundton leise 
im Hintergrund. Auch ohne Filterung müsste ich doch was anderes hören. 
Oder nein, bei 30000 springt er 30000 Schritte weiter was kein Sinus 
mehr ist sondern Chaos?!??

Wenn nun der Tremolo mein Ton ist (was ich auch irgendwie glaube), wie 
bekomme ich ihn in den hörbaren bereich als Sinus???  Und warum höre ich 
einen Ton mit Tremolo? und nicht einfach nur Tremolo ohne Ton, also 
nichts?

>     cli();
>     sei();
>Wozu das?
im Original um Töne zu trennen, da ist noch ein kurzes delay drin um 
Pausen zwischen Tönen hervorzurufen, wenns weg ist ändert sich nichts.

>"von selbst" schwingen
der Piezo hat keine eingebaute Elektronik, es kommt raus was ich rein 
gebe.

thank you very much

von William (Gast)


Angehängte Dateien:

Lesenswert?

das Beispiel aus dem Thread Beitrag "atmega8, pwm, tongenerator ganz einfach" 
klingt genauso auf dem Amega8, habs mal aufgenommen.
irgend etwas mache ich immer falsch ...
weiß niemand weiter? stehe total auf dem schlauch

von Michael R. (mexman) Benutzerseite


Lesenswert?

William schrieb:
> weiß niemand weiter? stehe total auf dem schlauch

Woher wissen wir, was DU falsch machst?

Was sagt das Oszilloskop?
Wie laeuft der Code im Emulator?


Gruss

Michael

von William (Gast)


Angehängte Dateien:

Lesenswert?

die Fuse war auf 1MHZ
jetzt ist sie auf 8MHZ int. osz.
und der Atmega8 war dummerweise verpolt
neues Soundbeispiel
habe leider kein Oszi, aber Sound vergrößert sieht so aus wie auf dem 
Bild
ich weiß wirklich nicht warum das nicht genauso klingt wie in dem 
Beispiel von dem anderen Thread, von dem ich es ja habe. (.c datei 
unten) dieses hier springt auch nicht in den Tönen...
vielleicht könnt ihr mir einen Tipp wie ich weiter machen soll geben, 
mit Eurer Erfahrung + Hintergrundwissen?
Emulator hab ich leider auch keinen.
Was könnte noch falsch sein?
Klingt das so weil kein Filter dahinter?
danke

von MWS (Gast)


Lesenswert?

Kann nicht gehen.
1
const uint8_t  sinewave[1][128] PROGMEM=
2
...
3
uint16_t i=0;
4
...
5
OCR1A=pgm_read_byte(&sinewave[tone][(i>>8)]);
6
i += scale;
Deine Sinustabelle enthält 128 Werte/Bytes. Nimm das im ersten Lauf 
maximale Ergebnis für i = 65375, schiebe 8 mal und Du hast einen Index 
von 255. Bisserl mehr Index als Inhalt :D

von William (Gast)


Lesenswert?

danke für die Antwort!
oh ok
das (i>>8) hab ich auch noch garnicht verstanden
schieben?
wie mache ich es besser?

bei kleinem scale (z.B. 30) müsste es trotzdem klappen, oder?
ich versuche gleich mal die frequenz raus zu finden mit der der Tremolo 
schwingt...

von William (Gast)


Lesenswert?

ach nein er zählt ja bei jedem interruptaufruf einmal scale weiter hoch 
also kommt er auch immer an die obergrenze ...

von William (Gast)


Angehängte Dateien:

Lesenswert?

mit meinem tiny44a (ansatz von ganz oben) und codeänderungen:
#define c 1
#define d 900
#define e 50000
//...
const uint8_t  sinewave [32] =
// 32 werte hier
//...
OCR1A=pgm_read_byte(&sinewave[tone][(i>>8)]);
...
bekomme ich schon so etwas wie tiefe Töne hin.
drei verschiedene habe ich ja. sie verändern sich nach jedem durchlauf 
(höre soundbsp.)

bestimmt liegt es wirklich an dem falschen "schieben" und an dem Takt 
des Prozessors. Mit 1MHZ muss ich doch trotzdem 20000Hz sinustöne 
erzeugen können???

von Rolf Magnus (Gast)


Lesenswert?

Bei 1MHz Grundfrequenz hat eine 8-Bit-PWM nur 1Mhz/256=3,9kHz. Wie 
willst du damit einen Sinuston von 20kHz ausgeben?

von William (Gast)


Lesenswert?

mit nur 32 stützpunkten
1 MHZ/32= 31,250 KHZ
32 reichen mir erstmal, soll nur etwas schöner als das rechteck klingen
wie ändere ich die Zeile
OCR1A=pgm_read_byte(&sinewave[tone][(i>>8)]);

bei
const uint8_t  sinewave [32] =
???
tausend dank für alle antworten, hab das gefühl ich bin kurz vor fertig

von William (Gast)


Lesenswert?

bzw wenn ich scale bei 128 werten hoch drehe müsste es auch gehen?

von Rolf Magnus (Gast)


Lesenswert?

William schrieb:
> mit nur 32 stützpunkten
> 1 MHZ/32= 31,250 KHZ

Du rechnest immer noch falsch. Mit 1 MHz Prozessortakt hast du ein 
3,9kHz-PWM! Wenn du da 32 Stützpunkte pro Schwingung hast, kommt dein 
Sinus auf eine Frequenz von 3,9kHz/32=122Hz.

von MWS (Gast)


Lesenswert?

William schrieb:
> wie mache ich es besser?

Um innerhalb des Indexes der Sinustabelle zu bleiben, muss man 9 mal 
schieben.

von Karl H. (kbuchegg)


Lesenswert?

William schrieb:

> wie mache ich es besser?

Indem du, wenn du das nächste mal Code klaust, den Code einfach nur auf 
das Allernotwendigste anpasst. D.h. andere Registernamen ausbügeln aber 
mehr nicht!

Dann lässt du diesen geklauten Code laufen und analysierst ihn. 
Eventuell machst du kleine Eingriffe um zu überprüfen, ob du verstanden 
hast wie der Code arbeitet. Nach dem Muster: Wenn ich das hier so 
ändere, dann müsste eigentlich das passieren. Tut es das auch?

Und erst dann fängst du an, größere Codeänderungen zu machen.
Ein offenbar notwendiges Array in der Größe zu ändern ist eine größere 
Änderung!

von William (Gast)


Lesenswert?

der geklaute Code lief ja auch schon nicht richtig, selbst auf dem im 
Original verwendeten Mega8 lief der Originalcode nicht richtig. Deshalb 
wundere ich mich ja.
Aber jetzt durch hin und her verändern (und eine Menge dabei lernen) 
habe ich schon was in die richtige Richtung hin bekommen.
>analysieren
>Wenn ich das hier so ändere, dann müsste eigentlich das passieren. Tut es das 
auch?
genau das mache ich...
>Um innerhalb des Indexes der Sinustabelle zu bleiben, muss man 9 mal
schieben
ok für welches array? 128 oder 32? wie rechne ich mir das selber aus?

der Controller hat auch einen 16 bit timer,kann ich damit mehr anfangen?
laut Datenblatt läuft der interne 8Mhz Oszillator bei 3V mit knapp 
7,8Mhz (attiny44a Datenblatt Seite 237)
wie finde ich heraus wie schnell er wirklich läuft?
kann ich es also gänzlich vergessen mit diesem speed z.B. 18kHZ als 
Sinus zu machen?
Wenn ich nur PWM in rechteck mache und den Comparewert ändere, geht das 
gut!

von William (Gast)


Lesenswert?

http://de.wikipedia.org/wiki/Logische_Verschiebung
achso Ok, also
Bytes/(2 hoch n)   <-- abgerundet
256 array entspricht 8 mal verschieben
128 array entspricht 9 mal verschieben
64 array entspricht 10 mal verschieben
32 array entspricht 11 mal verschieben

das habe ich verstanden.

wie siehts mit der Geschwindigkeit aus? Gehts das?

von William (Gast)


Lesenswert?

8bit: 0 bis 255, aber 256 werte
16bit: 0 bin 65535, aber 65536 werte

ich habe ja einen duty circle von 50%
also
OCR1A=0x80;  // 128

dann zählt er bis 128 hoch und liegt somit bei
7,8 MHZ / 128 =  60,9375 KHZ
rechne ich falsch?
oder 7,8MHZ/256= 30,49 KHZ
wie finde ich die geschwindigkeit des Prozessors in etwa ohne Oszi 
heraus?
Danke

von Jonathan S. (joni-st) Benutzerseite


Lesenswert?

Die Frequezabweichung ist gering genug, um Wurscht zu sein. Deine 60kHz 
stimmen so, zumindest wenn Dein Timer im CTC-Mode läuft.

von MWS (Gast)


Lesenswert?

William schrieb:
> 7,8 MHZ / 128 =  60,9375 KHZ
> rechne ich falsch?

Welche 128 ? 8Bit PWM geht bis 256.

Jonathan Strobl schrieb:
> zumindest wenn Dein Timer im CTC-Mode läuft.

Wo soll da ein CTC sein ?

> TCCR1A=0x91;
> TCCR1B=(1<<CS10);

Es wäre Zeit auf den Originalcode zu verlinken...

von Jonathan S. (joni-st) Benutzerseite


Lesenswert?

Gut ich hab' mir den Quälcode nur kurz angeschaut und nicht richtig 
durchgelesen...

von Uwe (de0508)


Lesenswert?

Hallo,

ich habe auch schon erfolgreich per PWM Töne erzeugt, nur nach einen 
etwas anderem Schema.

Du benötigst noch einen PWM TP-Filter, für den Morse-Übungsgenerator mit 
Mikroprozessor habe ich das so gemacht:

Schaltplan
- http://www.qrpforum.de/index.php?page=Attachment&attachmentID=8949

Steckbrett
- http://www.qrpforum.de/index.php?page=Attachment&attachmentID=9097

Der kleine atTiny85 läuft bei mir über den R/C Oszillator + PLL mit 
16MHz  und die beiden PWM-Kanäle mit 64MHz (PLL)!

Und so klingt das:

- http://www.qrpforum.de/index.php?page=Attachment&attachmentID=8945

von MWS (Gast)


Lesenswert?

Jonathan Strobl schrieb:
> Gut ich hab' mir den Quälcode nur kurz angeschaut und nicht richtig
> durchgelesen...

Kein Problem, bei sowas:

> TCCR1A=0x91;

völlig verständlich.

von William (Gast)


Angehängte Dateien:

Lesenswert?

hallo lieben Dank für all die Antworten
also sollte es besser CTC sein?
@Uwe S.
danke .für den Vorschlag, so werde ich es vielleicht das nächte Mal 
machen.
ich habe mich schon ziemlich auf diesen tiny hier vestgelegt und am 
Layout kann ich leider auch nix mehr ändern. Müsste damit doch auch 
klappen ...

nochmal: was ich möchte ist ein Sinus von irgendwas zwischen 12kHz und 
20kHz. schön wäre es wenn ich melodien machen könnte, muss aber nicht 
sein.

also ich bin jetzt nochmal alles durchgegangen und habe quälkot etwas 
besser lesbar gemacht (siehe unten)

nun bin ich wieder so weit wie am Anfang. Aufnahme habe ich mit 
hochgeladen. So klingt dieser Code. dies ist die Frequenz, die ich nun 
schon seit Tagen höre und es wäre super wenn ich die verändern könnte. 
Originalcode findet sich hier 
http://www.infolexikon.de/blog/atmega-music/


#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdint.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
// Noten-Frequenzen
#define c 1
#define d 90
#define e 4000
#define p 0   // Pause
struct notendauer
{
uint16_t note;
uint16_t dauer;
};
struct notendauer entchen[3] =
{
{c,1200}, {d,1200}, {e,500}
};
// einfache Sinuswelle in 256 diskreten Werten
const uint8_t  sinewave[1][256] PROGMEM=
{
{
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0x 
ab,0xae,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0x 
d5,0xd8,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0x 
f3,0xf5,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0x 
ff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0x 
f8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0x 
de,0xdc,
0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0x 
b6,0xb3,
0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x 
86,0x83,
0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x 
54,0x51,
0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x 
2a,0x27,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x 
0c,0x0a,
0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x 
00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x 
07,0x08,
0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x 
21,0x23,
0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x 
49,0x4c,
0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x 
79,0x7c
}
};
uint16_t i=0;
uint8_t tone=0;
volatile uint16_t scale=523;
// Interrupt-Funktion, die den "Zeiger" hochzählt
// je nach gewünschter Frequenz wird "scale" verändert,
// und somit die Sinuswelle schneller (hoher ton)
// oder langsamer (tiefer Ton) abgelaufen
ISR(TIM1_COMPA_vect){
//  OCR1A=(&sinewave[tone][(i>>11)]);
  OCR1A=pgm_read_byte(&sinewave[tone][(i>>8)]);
     i += scale;
}
int main(void)
{
    // PWM-INIT -----------------------------------
  // PA 6 als ausgang pwm ausgang 44a
  DDRA=(1<<PA6);
  // Anfangswert der PWM
  OCR1A=128;
  //Output compare OC1A 8 bit non inverted PWM
  TCCR1A= (1<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (1<<COM1B0) | 
(1<<WGM10);
  // Timer ohne Prescaler starten
    TCCR1B=(1<<CS10) | (0<<WGM13) | (0<<WGM12);
  // Einschalten des Ausgangs-Vergleichs-Interrupts
      TIMSK1=(1<<OCIE1A);
  sei();
    // MAIN-LOOP ----------------------------------
    while(1)
    {
  // durch das Noten-Array laufen und nacheinander
  // die Töne in jeweiliger Länge abspielen
  // da "scale" global definiert ist, kann es einfach
  // hier geändert werden!
  for(int y=0;y<3;y++){
  scale = entchen[y].note;
  _delay_ms(7000);
    // Interrupt kurz ausschalten, gibt kurze Pause
    // so werden die Töne getrennt
/*
    cli();
    i=0;
    sei();
*/
  }
    }
    return 0;
}

von MWS (Gast)


Lesenswert?

William schrieb:
> also sollte es besser CTC sein?

CTC könnte die Sache schon noch schneller machen, was halt die 
ISR-Ausführungszeit hergibt.

Nur, da Du diesen Code offensichtlich noch nicht recht verstehst, würde 
das noch 'ne Baustelle mehr, auf die Du verzichten solltest.
Wie schon gesagt, bei kleinerer Tabelle musst Du 9 mal schieben, hast Du 
das gemacht ?

Ansonsten fällt am Originalcode auf, daß auch OC1B aktiviert wird, aber 
ohne weitere Maßnahmen, wie DDR-Register auf Ausgang zu setzen. Sieht 
also etwas unausgereift aus. Sowas zeugt auch davon:

> TCCR1A=0x91;
> TCCR1B=0x01;

Versteht kein Mensch.

Wie wär's wenn Du Deinen kompletten Code als Anhang postest ? Dann ist 
der auch schöner formatiert und man kann auch einen Blick auf die 
Sinustabelle werfen.

von William (Gast)


Angehängte Dateien:

Lesenswert?

hi

>da Du diesen Code offensichtlich noch nicht recht verstehst

um euch zu veranschaulichen was ich wie und nicht vielleicht verstehe, 
korrigiert mich wenn ich irgendwo falsch liege:

der Timer1 (16bit!!! bei tiny44a und auch bei mega8 im Original) wird 
ohne Prescaler (in Prozessorgeschwindigkeit) hochgezählt.
Bis wohin habe ich nicht verstanden. Wohl bei 16bit von 0 bis 65535.
Wenn der Timer "überläuft" wird das Interrupt aufgerufen.

Im Interrupt wird von einem Sinusstützwert auf einen anderen in dem 
array verwiesen (gezeigt?)

Das geschieht per DDS (weiß ich was das ist), das man über scale 
einstellt.
scale wiederum wird über das Notenarray geändert.
Das heißt per DDS wird die Sinuskurve steiler oder flacher, je nach 
scale, und somit die Frequenz höher oder tiefer.
Nachteil DDS: Auflösung ändert sich, das ist mir egal.

Das mit Pointer und schieben habe ich noch nicht ganz verstanden.Und 
warum da ein 2dimensionales Array genommen wird auch nicht.

kleine Tabelle und
>9 mal schieben
habe ich gemacht und ändert nichts

hier ist wieder die Original-große Tabelle
ich habe sie mal kleiner gemacht gehabt, weil wenn PROGMEM weg, also 
array in den RAM schreibe, ist RAM in meinem tiny dafür zu kein Platz.

Aus dem RAM lesen scheint schneller zu sein als aus dem Flash.
Array in RAM speichern, kein Problem. Aber auslesen? Wie mache ich das?
ist wieder die Zeile
OCR1A=pgm_read_byte(&sinewave[tone][(i>>8)]);

auch die Notendauer habe ich fest mit delay eingestellt weil die 
Rechnung vom Original zu groß für tiny ist.

>Sieht also etwas unausgereift aus.
finde ich leider auch. Allerdings habe ich nichts besseres gefunden

so, bei meinen ganzen Probehörungen vermute ich dass das  Scrollen im 
Sinusarray zu langsam ist? also Interrupt zu selten aufgerufen wird. 
allerdings wundere ich mich immernoch woher diese Frequenz kommt + 
aufmoduliertem Tremolo. Also zwei Frequenzen.

habt ihr was besseres oder eine theoretische Anleitung wie ich das 
selbst Programmiere, kann doch nicht so schwer sein... vielleicht am 
Besten ohne Pointer für mich? kann auch mit fester hoher Frequenz sein.

von William (Gast)


Lesenswert?

und nochmal zum Geschwindigkeit ausrechnen:
8bit Timer weniger Auflösung, läuft schneller über
16bit Tmer höhere Auflösung, Überlauf seltener

bei unserer 8 bit Rechnung müsste man ja dann schon so rechnen:
 7,8MHz/(2*256) = 15,23kHz
2 mal 256 weil:
1 mal braucht Timer 256 Takte bis Überlauf
1 mal braucht eine volle Sinuswelle 256 mal diesen Überlauf, zumindest 
bei scale=1
oder
7,8 MHZ/256 hoch zwei = 119 Hz

hab ich jetzt richtig gerechnet?

also besser 8bit Timer?
15kHz ist etwas unter dem was ich wollte... wenns höher geht ist besser

von William (Gast)



Lesenswert?

hier noch Bilder zur Aufnahme 5 wav 16bit (siehe oben) und zu dem 
zuletzt geposteten Code.
das reingezoomte Detail (vom scale=1 Ton) sieht mir sehr nach Sinus aus.
Nur das Tremolo warum? und warum gerade diese Frequenz? es sind etwa 3,9 
kHz
vielleicht werdet ihr aus all dem schlau?

von William (Gast)


Lesenswert?

sorry bildernahmen falsch: nicht atm8

von William (Gast)


Lesenswert?

habe es endlich geschafft
mit CTC
eindimensionalem sinusarray
ohne notenarray
und dem hochzählen und ändern von OCR1A in der while(1) schleife
ohne ISR
vielen dank nochmal an alle!

von MWS (Gast)


Lesenswert?

William schrieb:
> Aus dem RAM lesen scheint schneller zu sein als aus dem Flash.

Das geht schnell genug.

William schrieb:
> habe es endlich geschafft
> mit CTC
> eindimensionalem sinusarray
> ohne notenarray
> und dem hochzählen und ändern von OCR1A in der while(1) schleife
> ohne ISR
> vielen dank nochmal an alle!

Dann stell' es doch ein, entweder Andere können daraus lernen, oder man 
kann erkennen, wo der vorherige Fehler lag.

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.