Forum: Mikrocontroller und Digitale Elektronik Sprachausgabe mit AVR


von Ingo L. (grobian)


Lesenswert?

Hallo Welt

kennt jemand ein Projekt:
Drei Wave Dateien (oder auch mehr) auf SD, drei Knöppe, ein AVR, ein LSP 
und auf Knopfdruck sollen die Dateien abgespielt werden. Bespielen der 
SD mit WAV-Dateien von Windows aus. Wobei mir das Abspielen mit 
Wave-Dateien schon gelungen ist, allerdings standen da die Dateien im 
internen Flash vom MEGA 32. Hatte da die ersten 44 Byts gekappt und 
direkt mit in den Speicher geflasht. Mein Problem ist vielmehr das 
Handling mit der Speicherkarte. Wie komme ich an die Daten der SD-Karte 
ran. Denke mal die müssen irgendwie kurzfristig zwischen gespeichert 
werden. Würde diesbezüglich hier gerne öffentlich ein kleines Projekt 
mit eurer Hilfe starten. Wenn jemand ideen hat, kann er sie ja bitte 
posten. Wie gesagt das Problem ist die Speicherkarte.

Vielen Dank und Gruß aus Berlin
Ingo

von Florian (Gast)


Lesenswert?

Hallo Ingo,

wenn ich Dich richtig verstanden habe suchst Du Unterstützung beim SD 
Kartenzugriff.
Projekte die sich mir SD Karten beschäftigen gibt es zu hauf. Bei Ulrich 
Radig z.B. http://www.ulrichradig.de/ -> AVR -> MMC-SD. Dort findest Du 
neben der Beschaltung auch einen Beispielcode mit Lib.
Ich hoffe das hilft Dir weiter.

Gruß
Florian

von Ingo L. (grobian)


Lesenswert?

Werde mich mal mir dieser Aufgabenstellung annehmen und erstma Ullis 
Schaltungsbeispiel aufbauen.

BTW: ist es eigentlich auch möglich eine SD über BASCOM anzusprechen ?

Gruß aus Berlin (ohhhh Somme scheint heute)

Ingo

von Matthias S. (mat-sche)


Lesenswert?

Moin Ingo,

auch bei Bascom gibt es zu hauf Anwendungen mit einer SD Card. Auch gibt 
es eine Lib: 
http://www.mcselec.com/index.php?option=com_content&task=view&id=20&Itemid=41

Auch findest Du so einige Foren mit Lösungen.
Gruß MAT

von geist (Gast)


Lesenswert?


von Mario G. (mario)


Lesenswert?

Genau das was du brauchst: http://elm-chan.org/works/sd8p/report.html

von drone (Gast)


Lesenswert?

sd8p : benötigt tiny85

von Ingo L. (grobian)


Lesenswert?

Mario Grafe schrieb:
> Genau das was du brauchst: http://elm-chan.org/works/sd8p/report.html

Hallo Mario,

hatte ich schon entdeckt, bloß ich brauche drei - vier Sounds die ich 
per Tastendruck auslösen möchte.

Wo finde ich den Slot für die SD-Karte (Reichelt). Weiß die genaue 
Bezeichnung nicht.

von Mario G. (mario)


Lesenswert?


von Bauteiltöter (Gast)


Lesenswert?

Hi


Ich habe grade soetwas programmiert:
http://www.youtube.com/watch?v=N918HeWlKII
http://www.youtube.com/watch?v=C-gq5afOopY&feature=related

Ist in BASCOM geschrieben.
SD-Karte mit FAT16/32
Dateien im Root-Verzeichniss, Unterverzeichnisse auch möglich
-WAVE-Dateien 8bit/8khz mono
Code hat ca. 8kB

von Ingo L. (grobian)


Lesenswert?

Bauteiltöter schrieb:
> Hi
>
>
> Ich habe grade soetwas programmiert:
> http://www.youtube.com/watch?v=N918HeWlKII
> http://www.youtube.com/watch?v=C-gq5afOopY&feature=related
>
> Ist in BASCOM geschrieben.
> SD-Karte mit FAT16/32
> Dateien im Root-Verzeichniss, Unterverzeichnisse auch möglich
> -WAVE-Dateien 8bit/8khz mono
> Code hat ca. 8kB

Ist ja Irre :-)

Dachte jetzt eigentlich Bascom ist für solch Projekte nicht schnell 
genug.


Denke mal
http://www.reichelt.de/index.html?ACTION=3;GROUP=C136;GROUPID=3768;ARTICLE=56476;SID=26PWyIoawQARoAAHPwUSAe1c6fe7c81aefc3016a6c13c62937724

das wird der richtige sein. TEUUUUUUER brrrrr

von Ingo L. (grobian)


Lesenswert?

anderes Ding..
wird ein Mega 8 in Verbindung mit einer 1GB SD-Karte ausreichen für mein 
Vorhaben ?
Als Hardware ankopplung denke ich an die Lösung von Ullich Radig.

von Vlad T. (vlad_tepesch)


Lesenswert?

Ingo Laabs schrieb:
> TEUUUUUUER brrrrr

schau bei ebay, da gibts die für <1€ in Hongkong

Oder such dir bei ebay eine micro-SDkarte mit adapter auf mini oder SD 
und löte den Adapter fest auf die Platine.

von Michael B. (planlessmichi)


Lesenswert?

@Ingo:
Die Kartenslots bei Reichelt sind wirklich heftig; aber wenn Du schon 
Ulrichs Lösung in Betracht ziehst, kannst ja auch mal ein seinen Shop 
schauen; da gibts die Kartenslote für 1,99 Euro ;-)

von Helfer (Gast)


Lesenswert?

oder von pollin 720928, auslöten. Dann hat man für andere Speichermedien 
auch noch welche

von Rainer U. (r-u)


Lesenswert?

Das ganze Gerät gibt's auch als fertige Platine bei Sparkfun:

http://www.sparkfun.com/commerce/product_info.php?products_id=9715

von Ingo L. (grobian)


Lesenswert?

Und schon gehn die Probleme los....ist doch irgendwie doof, jetzt 
befinden sich die Pins für die SPI am Mega 8 genau da, wo auch die PWM 
erzeugt werden soll. Anderen uP oder kann ich das SPI auch an anderen 
Pins betreiben ?

von Klaus (Gast)


Lesenswert?

Hey Ingo, du kannst in 15 Minuten ne SPI Schnittstelle per Software an 
beliebige I/O-Pins basteln.

von Ingo L. (grobian)


Lesenswert?

Klaus schrieb:
> Hey Ingo, du kannst in 15 Minuten ne SPI Schnittstelle per Software an
> beliebige I/O-Pins basteln.

Hi Klaus,

na dann ist ja OK. Nein, zur Zeit mache ich mir Gedanken (und 
Schaltplan) über die Hardware und hatte dabei nur festgestellt, dass da 
ja die selben Ports benutzt werden. Aber wenn ich das umgehen kann, ist 
ja OK.
Also kein Hardware SPI. Wobei ich immer noch nicht weiß, ob der MEGA 8 
dazu geeignet ist.

von Bauteiltöter (Gast)


Lesenswert?

Ingo Laabs:
>Dachte jetzt eigentlich Bascom ist für solch Projekte nicht schnell
>genug.

Doch, da geht auch noch mehr. 8Bit/44khz mono sollte drinn sein, wenn 
man den Code ein wenig optimiert.

Die Qualität ist im moment leider nicht so doll, aber ich weiß nicht 
worann es liegt.
Ich habe leider kein Oszi um da weiter nachzuforschen...

Ich verwende für die SD-Karte die avr-dos-lib in Bascom, die ist echt 
irre.
SD-Karten, CF-Karten und IDE-HDDs gehen mit dem Player, man müsste nur 
die Treiber tauschen (andere einbinden).

von Ingo L. (grobian)


Lesenswert?

Wo bekomme ich das AVR-DOS bzw wie binde ich es denn in mein BASCON ein.
Habe mir mal das Bsp. geladen, bekomme da jedoch jede menge 
Fehlermeldungen.

Gruß Ingo

von Torben H. (bauteiltoeter)


Lesenswert?

Hi,

hast du die Demo von Bascom oder die Vollversion?
Mit der Demoversion kannst du AVR-Dos nicht benutzen, da der Code 
deutlich über 4kB groß wird.

Eigentlich ist AVR-Dos schon in BASCOM integriert.
Als beispiel solltest du dir die Datei 
/BASCOM-AVR/SAMPLES/AVRDOS/Test_DOS_drive.bas benutzen.

du musst die Zeile include "config_HardDisk_M128.bas" auf deine Hardware 
anpassen.
z.B. auf include "config_mmc.bas".
Danach musst du dir config_mmc.bas öffenen und auf deine Hardware 
anpassen

Die config_AVR-Dos.bas solltest du erstmal unberührt lassen.

MfG Torben

von Ingo L. (grobian)


Lesenswert?

Setze mich jetzt mit dem Code von Ulrich Radig auseinander und bekomme 
hier jetzt folgende Meldung :

rm -rf usart.o fat.o main.o mmc.o  SD_CARD.elf dep/* SD_CARD.hex 
SD_CARD.eep SD_CARD.lss SD_CARD.map
Build succeeded with 0 Warnings...

make: *** No rule to make target `../../Eigene', needed by `usart.o'. 
Stop.
Build failed with 1 errors and 0 warnings...

wat dat ??

Gruß
Ingo

von holger (Gast)


Lesenswert?

>make: *** No rule to make target `../../Eigene', needed by `usart.o'.
>Stop.
>Build failed with 1 errors and 0 warnings...

>wat dat ??

Leerzeichen im Pfad? Leg deine Dateien mal woanders hin.

von Ingo L. (grobian)


Lesenswert?

holger schrieb:
>>make: *** No rule to make target `../../Eigene', needed by `usart.o'.
>>Stop.
>>Build failed with 1 errors and 0 warnings...
>
>>wat dat ??
>
> Leerzeichen im Pfad? Leg deine Dateien mal woanders hin.


kein Leerzeichen da :-(

von Klaus (Gast)


Lesenswert?

Ingo Laabs schrieb:
> No rule to make target `../../Eigene', needed by `usart.o'.

Das 'Eigene' dort stammt doch bestimmt von 'Eigene Dateien', oder nicht?

von Ingo L. (grobian)


Lesenswert?

Klaus schrieb:
> Ingo Laabs schrieb:
>> No rule to make target `../../Eigene', needed by `usart.o'.
>
> Das 'Eigene' dort stammt doch bestimmt von 'Eigene Dateien', oder nicht?

jeeepppp
danke,danke...kniefall

von Ingo L. (grobian)


Lesenswert?

OK, nachdem das jetzt wohl funzt, werde ich jetzt mal so langsam die 
Hardware aufbauen.
Angedacht sind:
Mega32,1GB SD

Gruß aus Berlin
Ingo

von Ingo L. (grobian)


Lesenswert?

lt. Ulrich Radigs Programm würde ich auf folgende Beschaltung kommen

AVR_ATmega32
SPI_DI          (MISO)  PB6  an  Data Output der SD-Karte (PIN 7)
SPI_DO          (MOSI)  PB5  an  Data Input der SD-Karte (PIN 2)
SPI_Clock       (SCK)   PB7  an  Clock der SD-Karte (PIN5)
MMC_Chip_Select (OC0)   PB3  an  Chip Select der SD-Karte (PIN 1)
SPI_SS                  PB4
                GND  an  SD-Karte (PIN6/3)
                VCC  an  SD-Karte (PIN4)

Stimmt ?

von Ingo L. (grobian)


Angehängte Dateien:

Lesenswert?

lt. Ulrich Radigs Programm würde ich auf folgende Beschaltung kommen

AVR_ATmega32
SPI_DI          (MISO)  PB6  an  Data Output der SD-Karte (PIN 7)
SPI_DO          (MOSI)  PB5  an  Data Input der SD-Karte (PIN 2)
SPI_Clock       (SCK)   PB7  an  Clock der SD-Karte (PIN5)
MMC_Chip_Select (OC0)   PB3  an  Chip Select der SD-Karte (PIN 1)
SPI_SS                  PB4
                GND  an  SD-Karte (PIN6/3)
                VCC  an  SD-Karte (PIN4)

Stimmt ?

von Ingo L. (grobian)


Lesenswert?

Warum verwendet Ulrich Radig PB3 anstatt den SS Pin für den CS der Karte 
?

von Klaus (Gast)


Lesenswert?

Ingo Laabs schrieb:
> Warum verwendet Ulrich Radig PB3 anstatt den SS Pin für den CS der Karte

Der SS Pin ist nur wichtig, wenn du den AVR im SPI-Slave-Mode 
verwendest. Im Master-Mode hat der keine besondere Bedeutung und du 
kannst jeden beliebigen IO-Pin an CS anschließen.

von Ingo L. (grobian)


Angehängte Dateien:

Lesenswert?

Habe jetzt meine SD-Karte angeschlossen was auch funktioniert..aber..
es befinden sich vier Dateien auf der Karte und es werden nur drei 
angezeigt.

von Ingo L. (grobian)


Lesenswert?

Habe jetzt versucht die Datei NESSAJA.WAV auszugeben, will aber nicht so 
recht.
Habe die main-Datei von Ulrich wie unten aufgeführt ( habe nur den 
geänderten Teil hier reingestellt da sie ja bekannt sein sollte) 
geändert..aber nach nessaja klingt es nicht.
Die Delays habe ich nur zu Testzwecken eingefügt. Meine Datei hat das 
Format 8Bit/mono/PCM/22Khz
Kann mal einer auf den Code schauen wo da der Fehler liegt ?
Danke und Gruß aus Berlin
Ingo


//Lade Cluster für das index.htm File in den Speicher
  Clustervar = 0;//suche im Root Verzeichnis
  if (fat_search_file((unsigned char 
*)"NESSAJA.WAV",&Clustervar,&Size,&Dir_Attrib,Buffer) == 1)
    {
    usart_write("\nFile Found!!\r\n");

//  init PWM

DDRD = (1 << PD5 );

TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (0<<WGM11)  | (1<<WGM10) ;
TCCR1B = (0<<CS12)   | (0<<CS11)   | (1<<CS10);


    //Lese File und gibt es aus
    for (int b = 0;b<52;b++)
      {
      fat_read_file (Clustervar,Buffer,b);
      for (int a = 0;a<512;a++)
        {
        OCR1A = Buffer[a];
           _delay_us(100);   // nur zum test !!

        }
      }
    }

  usart_write("FERTIG!!\r\n");

von Vlad T. (vlad_tepesch)


Lesenswert?

Klaus schrieb:
> Der SS Pin ist nur wichtig, wenn du den AVR im SPI-Slave-Mode
> verwendest. Im Master-Mode hat der keine besondere Bedeutung und du
> kannst jeden beliebigen IO-Pin an CS anschließen.

da der Pin sowiso als Ausgang konfiguriert werden muss, kann man doch 
direkt den nehmen.

von Ingo L. (grobian)


Lesenswert?

als Nachtrag..die Datei NESSAJA.WAV wird erkannt und auch gelesen !!

von Ingo L. (grobian)


Lesenswert?

keiner ne Idee ??
oder fehlen irgendwelche Angaben ?

Gruß aus dem heute sonnigem Berlin

Ingo

von Olli (Gast)


Lesenswert?

Hallo Ingo,

hast Du das Problem gelöst ?
Kannst Du mal den ganzen Code posten, und nicht nur ein Stück.

Olli

von Ingo L. (grobian)


Lesenswert?

Konnte das Problem beheben . Der Fehler lag hier:

for (int b = 0;b<52;b++)

Die Variable b muss den Wert der Dateigroße / 512 enthalten. Dann 
funktioniert es.

Soweit funktioniert die Sprachausgabe jetzt. Habe nun ein wenig Probleme 
mit der Samplingfrequenz, weil ich nicht weiß wie lange der Zugriff auf 
die Karte dauert. Ansonsten klingt es schon ganz gut. Sobald ich das 
Projekt fertig habe, werde ich es hier posten.

Einen 4:0 Gruß aus Berlin

Ingo

von Ingo L. (grobian)


Lesenswert?

Kann  ich mir dieses ganze Pegelgewandle eigentlich nicht dadurch 
ersparen indem ich den Mega32 gleich mit an 3,3 Volt betreibe ?

von Klaus (Gast)


Lesenswert?

Ingo Laabs schrieb:
> Kann  ich mir dieses ganze Pegelgewandle eigentlich nicht dadurch
> ersparen indem ich den Mega32 gleich mit an 3,3 Volt betreibe ?

Ja, ist möglich. Bedenke aber, dass du dann nicht mehr die vollen 16Mhz 
nutzen kannst.

von Ingo L. (grobian)


Lesenswert?

habe bisher mit 12 MHz getaktet.

von Ingo L. (grobian)


Angehängte Dateien:

Lesenswert?

Mit der hier aufgeführten Konstellation bin ich jetzt zum Erfolg 
gekommen.
Verwenden tu ich eine 1GB SD-Karte. Zur Zeit takte ich mit 12 MHz (nicht 
im Schalplan eingezeichnet).
Dateiformat der WAV 8 Bit,mono,22 KHz
Wobei ich die Dateien von Ulrich R, verwendet habe. Die Main.c  habe ich 
natürlich ändern müssen.( Es sind noch viele Sachen in dem Code die 
nicht gebraucht werden wie z.B der USART). Es müssen aber auch noch 
Dinge geändert werden wie zum Beispiel sollte sich die Dateilänge 
errechnen lassen die ich bisher noch von Hand eintrage, und die ersten 
44 Byts von der WAV müssen noch gekappt werden (Beim Abspielen knackt es 
Anfang ein bissel). Ob die Verzögerung von 45 uS beim Abspielen da so in 
der Form sinnvoll ist weiß ich noch nicht.  Aber sonst Spricht das Ding. 
Am Ausgang muss wohl noch ein Filter (Butterworth ?) gesetzt werden.

von Matthias R. (reichema)


Lesenswert?

Super ! Ich habs gerade auf dem Steckbrett zum testen aufgebaut. Vorerst 
mit internem Takt.
Das ist genau das was ich für mein nächstes Projekt gesucht habe. Danke 
an alle beteiligten.

von Simon K. (simon) Benutzerseite


Lesenswert?

Für höhere Geschwindigkeiten würde ich aber den Innenwiderstand des 
Spannungsteilers mindestens halbieren. Bzw. Serienwiderstand max. 1kOhm. 
Ansonsten haste Probleme mit den kapazitiven Eingängen. Also zumindest 
so über den Daumen jetzt mal gepeilt.

von Ingo L. (grobian)


Lesenswert?

Matthias Reichelt schrieb:
> Super ! Ich habs gerade auf dem Steckbrett zum testen aufgebaut. Vorerst
> mit internem Takt.
> Das ist genau das was ich für mein nächstes Projekt gesucht habe. Danke
> an alle beteiligten.

Hallo Matthias,

habe hier einen Filter gefunden
http://www.elv-downloads.de/service/manuals/75344_Mini_Sound_Modul_km_web_um.pdf
ganz unten abgebildet.

Bin leider noch nicht dazu gekommen ihn nach zubauen (Fussball ist 
angesagt.)Denke aber der sollte so in der Form funktionieren, da das 
Soundmodul ebenfalls mit 8 Bit,22KHz arbeitet.
Wenn du Erfahrungen damit gemacht hast, kannst du sie ja posten oder 
warten bis wieder Fussball frei ist. Denke mal als OP kannst du auch 
einen LM324 verwenden

Gruß aus Berlin
Ingo

(Daumen drücken heute)

von Matthias R. (reichema)


Lesenswert?

Danke für den Tip. Werde das Filter vielleicht schon heute abend 
aufbauen.


Grüße aus Wien

von Matthias R. (reichema)


Lesenswert?

Hallo Ingo,

Ich habe den Filter jetzt fertig und ein bischen damit getestet. Auf dem 
Oszi schaut es ziemlich gut aus aber die Sprache ist noch nicht viel 
besser wenn ich es über den Verstärker wiedergebe.
Das leichte Brummen ist nun weg aber es klingt noch immer nicht optimal.
Der Gewinn ist so gering, daß ich mir den Bau des Filters sparen könnte 
denn der "Roboterstimmeneffekt" ist vor und hinter dem Filter gleich.
Ich glaube das Problem liegt schon beim PWM signal.

Ich verwende 8Mhz Takt extern und Wav files mit 22khz und 8 Bit mono.
Die Sprache ist etwas langsamer als orginal :-)

von holger (Gast)


Lesenswert?

>Ich verwende 8Mhz Takt extern und Wav files mit 22khz und 8 Bit mono.
>Die Sprache ist etwas langsamer als orginal :-)

Dann geh auf 16MHz und benutz einen Double Buffer.

von Matthias R. (reichema)


Lesenswert?

War auch als nächster Schritt geplant. Hab nur keine anderen Quarze im 
Haus. Gehe die Tage noch einkaufen :-)

von Ingo L. (grobian)


Lesenswert?

Matthias Reichelt schrieb:
> ch verwende 8Mhz Takt extern und Wav files mit 22khz und 8 Bit mono.
> Die Sprache ist etwas langsamer als orginal :-)

Also mein Ding läuft mit 12 Mhz und liefert schon ohne Filter akzeptable 
ergebnisse. Solltest wiklich mal versuchen den Quarz zu ändern.

von Matthias R. (reichema)


Lesenswert?

Ich taste mich langsam heran. Einen 10Mhz Quarz habe ich noch gefunden. 
Es ist nun besser und keine Frage, es ist absolut akzeptabel als 
Sprachausgabe.

Das Filter ( momentan noch am Steckbrett ) werde ich wohl nicht 
aufbauen. Es bringt relativ wenig und ohne ist es schon gut genug. Es 
soll alles in ein gleines Gehäuse passen ( Pollin Blitzgong ) und da 
muss ich mit dem Platz haushalten.

Danke nochmal

von Matthias R. (reichema)


Angehängte Dateien:

Lesenswert?

Funktioniert jetzt super. Mit 12Mhz Quarz. Evtl. spiele ich trotzdem 
noch ein bischen mit dem Buffer.

Ich habe einen kleinen NF Verstärker mit LM386 und den Ultraschall 
Abstandswarner vom C hinzugefügt. Das RFM12 fehlt noch und dann spare 
ich mir die nicht vorhandene Haustürglocke :-)

Übrigens, ich schalte die Versorgungsspannung von Verstärker mit einem 
kleinen Relais weg, wenn nichts ausgegeben wird.

Grüße
Matthias

von Ingo L. (grobian)


Lesenswert?

Matthias Reichelt schrieb:
> Funktioniert jetzt super. Mit 12Mhz Quarz. Evtl. spiele ich trotzdem
> noch ein bischen mit dem Buffer.
>
> Ich habe einen kleinen NF Verstärker mit LM386 und den Ultraschall
> Abstandswarner vom C hinzugefügt. Das RFM12 fehlt noch und dann spare
> ich mir die nicht vorhandene Haustürglocke :-)
>
> Übrigens, ich schalte die Versorgungsspannung von Verstärker mit einem
> kleinen Relais weg, wenn nichts ausgegeben wird.
>
> Grüße
> Matthias

Na iat doch super wenn alles geklappt hat. Wenn du den Buffer geändert 
hast,
kannst Du den Code mal posten. Bei mir hat der Filter doch einiges 
gebracht.
Aber jetzt geht es erstmal in die heiße Fussballphase und hier in Berlin 
ist wiklich die Hölle los.
Freue mich aber über jeden Beitrag der das Projekt weiter bringt.

von Ingo L. (grobian)


Lesenswert?

Möchte jetzt zur Anbindung der SD an den Controller auf das 
Widerstandsgedöhns verzichten. Soll ja jetzt nicht die Kavalierslösung 
sein mit den Widerständen.
Von daher mal die Bitte an euch: Welcher Pegelwandler/Treiber scheint da 
am sinnvollsten zu sein. (Schaltplan findet ihr ja etwas weiter oben)
danke

Gruß Ingo

von Ingo L. (grobian)


Lesenswert?

Nachdem die WM und die Hitze doch nun beendet ist, habe ich mich wieder 
meinem Projekt gewidmet.
Soweit funktioniert ja alles.
Doch habe ich in der Ausgabe der Sounddateien einen Vibrator ähnlichen 
Effekt. Habe es jetzt schon mit
diversen Samplingfrequenzen probiert. Der Effekt wird jedoch intensiver 
je höher ich die Samplingfrequenz
Setze. Es macht den Eindruck  als wenn die Sounddatei moduliert wird.
Hatte hier jemand schon mal mit ähnlichen Problemen zu kämpfen ?
Ein entsprechender Filter bringt keine Abhilfe.

von holger (Gast)


Lesenswert?

>Doch habe ich in der Ausgabe der Sounddateien einen Vibrator ähnlichen
>Effekt. Habe es jetzt schon mit
>diversen Samplingfrequenzen probiert. Der Effekt wird jedoch intensiver
>je höher ich die Samplingfrequenz Setze.

Dann ist dein Puffer schneller abgespielt als du Daten von der SD lesen
kannst. Nimm zwei Puffer. Einer wird abgespielt und der andere von der 
SD
gefüllt. Dann immer schön die Puffer umschalten.

von Ingo L. (grobian)


Lesenswert?

Gut!

Ich fülle hier meinen buffer und gebe ihn an OCR1A aus.
Wie kann ich denn heir während der Ausgabe den zweiten buffer füllen ?
Komme damit irgendwie nicht klar.

//Lese File und gibt es aus
    for (int b = 0;b<52;b++)
      {
      fat_read_file (Clustervar,Buffer,b);
      for (int a = 0;a<512;a++)
        {
        OCR1A = Buffer[a];
           _delay_us(42);   // nur zum test !!

        }
      }

von Ingo L. (grobian)


Lesenswert?

keiner ne Idee. Komme wirklich nicht weiter..jammer !!

von Karl H. (kbuchegg)


Lesenswert?

>       for (int a = 0;a<512;a++)
>         {
>         OCR1A = Buffer[a];
>            _delay_us(42);   // nur zum test !!
>
>         }
>       }

> keiner ne Idee. Komme wirklich nicht weiter..jammer !!

sobald du ein _delay_us im System hast, ist jegliche Frage nach anderen 
Sytsematiken sinnlos geworden.
Der _delay muss weg!
Eine Timer ISR, die Bytes ausgibt, muss her!

von Ingo L. (grobian)


Lesenswert?

ja aber muss ich da nicht letztendlich auch eine Verzögerung einsetzen 
um auf die Samplingrate zu kommen ??

von Karl H. (kbuchegg)


Lesenswert?

Ingo Laabs schrieb:
> ja aber muss ich da nicht letztendlich auch eine Verzögerung einsetzen
> um auf die Samplingrate zu kommen ??

KLar.
Aber anders.
Was du zur Zeit machst, ist aktives Warten, bis das nächste Byte 
rausmuss.
Was du aber tun solltest, ist ganz normal weiterarbeiten ohne dich um 
die Ausgabe zu kümmern und wenn es Zeit ist, das nächste Byte 
auszugeben, benachrichtigt dich deine Stoppuhr. Du gibst das Byte aus 
und kehrst wieder zurück an deine eigentliche Arbeit. Bis die Uhr das 
nächste mal klingelt.

Genau das macht man in einem AVR mit einem Timer und seiner zugehörigen 
ISR. Der Timer gibt die Stoppuhr vor und die ISR ist der Code der dann 
in regelmässigen Abständen ausgeführt wird. Und die Samplingrate stellst 
du ein, indem du die Zeit bis zur nächsten Unterbrechung (=ISR Aufruf) 
am Timer einstellst. Der CTC Modus wird da hilfreich sein.

von Ingo L. (grobian)


Lesenswert?

Karl heinz Buchegger schrieb:
>
>
> Genau das macht man in einem AVR mit einem Timer und seiner zugehörigen
> ISR. Der Timer gibt die Stoppuhr vor und die ISR ist der Code der dann
> in regelmässigen Abständen ausgeführt wird. Und die Samplingrate stellst
> du ein, indem du die Zeit bis zur nächsten Unterbrechung (=ISR Aufruf)
> am Timer einstellst. Der CTC Modus wird da hilfreich sein.

d.h.
ich programmiere meinen Timer in soweit, dass er mir alle 45 uS einen 
Interrupt auslöst der mir in der Interruptroutine mein Byte ausgibt:

//TIMER1 setzen
  TIMSK |= (1 << TOIE1);
//VORTEILER auf 64
  TCCR1B = (1<<CS10 | 1<<CS11);
//Zähler setzen
  TCNT1 = 65535 - (20000000/64/22050);

//Interrupts zulassen
  sei();

//Timer1 Interrupt
ISR (TIMER1_OVF_vect)
{
  //hier dann irgendwie das Byte ausgeben
}


habe einen 20 MHz Quarz eingesetzt und Samplingrate 22,05 MHz, komme 
dann auf 44,8 us (45 us sollten es sein)

von Ingo L. (grobian)


Lesenswert?

keine Reaktion ??

von spess53 (Gast)


Lesenswert?

Hi

>keine Reaktion ??

Was soll denn das sein:

>TCNT1 = 65535 - (20000000/64/22050);  ?

Karl-Heinz schrieb:
>> am Timer einstellst. Der CTC Modus wird da hilfreich sein.

Warum benutz du den CTC-Mode nicht. Mit deiner Initialisierung bekommst 
du etwa alle 210ms einen Interrupt.

MfG Spess

von Ingo L. (grobian)


Lesenswert?

20 Mhz Takt // 64 Prescaler // Samplingfrequenz (22,05 Mhz)
sind doch dann der Zählerstand den ich vorladen muss oder ?

von spess53 (Gast)


Lesenswert?

Hi

>20 Mhz Takt  64 Prescaler  Samplinfrequenz (22,05 Mhz)
>sind doch dann der Zählerstand den ich vorladen muss oder ?

Bei CTC brauchst du nichts vorladen.

TCCR1B = 1<<WGM12|1<<CS10 //CTC, Vorteiler 1
OCR1A  = 899              //Macht genau 45µs
TIMSK  = 1<<OCIE1A        //OC1A Interrupt

Fertig.

Eigentlich würde auch ein 8-Bit-Timer reichen.

MfG Spess

von Ingo L. (grobian)


Lesenswert?

OCR1A
benutze ich als PWM Ausgang

von spess53 (Gast)


Lesenswert?

Hi

>OCR1A benutze ich als PWM Ausgang

Dann kannst du TCNT1 auch nicht manipulieren. Hast du noch einen anderen 
Timer frei?

MfG Spess

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Timer1 kann auch über das ICR im CTC betrieben werden. Zumindest bei 
vielen AVRs.

von Ingo L. (grobian)


Lesenswert?

spess53 schrieb:
> Hi
>
>>OCR1A benutze ich als PWM Ausgang
>
> Dann kannst du TCNT1 auch nicht manipulieren. Hast du noch einen anderen
> Timer frei?
>
> MfG Spess


eigetlich alle bis auf den besagten

von Floh (Gast)


Lesenswert?

Ähm mal ne Anmerkung:
Mit 22MHz Samplingrate geht das nicht, du müsstest ja alle ~50 ns nen 
neuen Wert zum Lautsprecher rausgeben.
Wahrscheinlich meinst du 22kHz :-)

von spess53 (Gast)


Lesenswert?

Hi

>Timer1 kann auch über das ICR im CTC betrieben werden. Zumindest bei
>vielen AVRs.

Aber er benutzt doch Timer1 anscheinend schon für die PWM. Wobei jetzt 
die Frage ist: Welche PWM-Frequenz? Wenn er alle 45µs das OC-Register 
nachladen will, sollte die PWM-Frequenz schon um einiges höher, als die 
Samplingfrequenz sein. Eigentlich macht da ein 16-Bit-Timer wenig Sinn.

MfG Spess

von Ingo L. (grobian)


Lesenswert?

Floh schrieb:
> Ähm mal ne Anmerkung:
> Mit 22MHz Samplingrate geht das nicht, du müsstest ja alle ~50 ns nen
> neuen Wert zum Lautsprecher rausgeben.
> Wahrscheinlich meinst du 22kHz :-)


röchtög...tippfehler  22,05 Khz

von spess53 (Gast)


Lesenswert?

Hi

In welchem Format liegen sie Sounddaten eigentlich vor?

MfG Spess

von Ingo L. (grobian)


Lesenswert?

8 Bit, mono, 22,05 Khz...siehe Beitrag oben..es funktioniert ja schon, 
aber leider mit Vibratoreffekt. Denke mal dass das an den 
Bufferzugriffen der SD Karte liegt. Schau die mal bitte den Beitrag 
komplett an, Vllt. hast du ja eine andere Idee dazu..ware echt dankbar..

von spess53 (Gast)


Lesenswert?

Hi

Und mit welcher Frequenz läuft deine PWM?

MfG Spess

von Ingo L. (grobian)


Lesenswert?

Hääää??

von Ingo L. (grobian)


Lesenswert?

wie ermittel mich die PWM Frequenz, kann dir wirklich nur sagen dass das 
Ding mit 20 Mhz läuft, und ich 8 Bit PWM mono mit 22,05 Khz verwende was 
auch schon brauchbare Ergebnisse bringt.
Oben findest du auch den Schaltplan mit dem geänderten Programm. Für die 
Zugriffe auf die SD-Karte verwende ich die (hoffe ich )bekannten 
Routinen von U.Radig.

Gruß Ingo

von spess53 (Gast)


Lesenswert?

Hi

Dann läuft deine PWM mit ca. 78kHz. Das hat aber zu Folge, da du mit 
22,5Hz nachlädst, einige Sound-Werte 4x andere nur 3x 'abgespielt' 
werden. Möglicherweise kommt dein 'Vibrato'-Effekt daher. Persönlich 
würde ich PWM und Nachladen synchronisieren.

MfG Spess

von Ingo L. (grobian)


Lesenswert?

hmmm...wie gehe ich da bei..kleinen Tipp an Board ?

Wie kommst du auf die 78 Khz. Wäre für mich mal interessant wie sich der 
Wert
errechnet.

von spess53 (Gast)


Lesenswert?

Hi

>Wie kommst du auf die 78 Khz. Wäre für mich mal interessant wie sich der
>Wert errechnet.

Datenblatt S.101. Du hast 20MHz, Vorteiler 1 und Top=255.

->  Fpwm= 20MHz/(1+255) = 78,125kHz

>hmmm...wie gehe ich da bei..kleinen Tipp an Board ?

Wenn du den Timermode 14 benutzt, kannst du die PWM-Frequenz mit ICR1 
einstellen. Mit einem ICR1-Wert von 299 bekommst du eine PWM-Frequenz 
von 66,67kHz. Damit dauert eine PWM-Periode 15µs. Das ist 1/3 deiner 
Sample-Periode. Wenn du also bei jedem dritten OCR1A-Interrupt das 
Register nachlädst, kommst du auf genau 45µs.
Einen Nachteil hat die Sache allerdings: Mit deinen 8-Bit-Sound-Daten 
läuft die PWM mit maximal 85%. Das bringt eine etwas geringere 
Lautstärke. Lässt sich aber bestimmt ausgleichen.

MfG Spess

von Ingo L. (grobian)


Lesenswert?

d.h. ich muss unbedingt die Daten ausschließlich über einen Timer 
Interrupt ausgeben.

von spess53 (Gast)


Lesenswert?

Hi

>d.h. ich muss unbedingt die Daten ausschließlich über einen Timer
>Interrupt ausgeben.

Ja. Wo ist da das Problem?

MfG Spess

von Ingo L. (grobian)


Lesenswert?

das ich OCR1A für die PWM benutze als ausgang benutze

von spess53 (Gast)


Lesenswert?

Hi

>das ich OCR1A für die PWM benutze als ausgang benutze

Was hat denn der OCR1A-Interrupt mit dem OCR1A-Pin zu tun? Die PWM läuft 
autonom. Der Interrupt ändert nichts an der Funktionalität der PWM.

MfG Spess

von Ingo L. (grobian)


Lesenswert?

bist Du denn sicher, dass durch diese Maßnahme der vibratorähnliche 
Effekt verschwindet ?

von erhardd (Gast)


Lesenswert?

@Ingo
--nur mal so ins Blaue:
Du gibst doch sicher die Wav über einen Lautsprecher an einem 
Leistungsverstärker aus?!
Ich hatte schon die seltsamsten ungewollten Modulationseffekte, weil der 
Stützkondensator der Spannungsversorgung zu niedrig war!

von Ingo L. (grobian)


Lesenswert?

nein, gehe an meine Hifi-Endstufe. Es ist kein Leistungsverstärker der 
an der Versorgungsspannung vom SD-Waver (so nenne ich ihn jetzt mal) 
hängt.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Wieso zum Geier nutzt Du nicht den Overflow-Interrupt Deiner PWM zum 
Nachladen der Daten? Parallel zur ohnehin laufenden PWM wird bei 
TimerTOP das Overflow-Flag gesetzt, die Samplerate ist dabei abhängig 
vom Wert im ICR_Register, wie schon erwähnt im Timer-Mode 14. Da das 
OCR-Register gepuffert ist, wird bei der nächsten Runde der 
aktualisierte Wert in die PWM übernommen. Somit brauchst Du nur alle 
22kHz 1x das Capture-Register neu zu beschreiben.

von Ingo L. (grobian)


Lesenswert?

Das nachladen der Daten scheint ja zu funktionieren. Wie gesagt das Ding 
funktioniert ja schon, nur leider mit einem Vibratoreffekt der schneller 
wird je höher ich die Samplingrate setze und ich keinen blassen schimmer 
habe woran es liegt. Es geht mir nicht darum die Daten auszugeben. Das 
funktioniert ja.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Ingo Laabs schrieb:
> Es geht mir nicht darum die Daten auszugeben. Das
> funktioniert ja.

Wenn die Daten nicht exakt synchron zur Samplerate gegeben werden, dann 
entstehen Schwebungen. Es macht auch keinen ernsthaften Sinn, die PWM 
mit 65kHz laufen zu lassen, wenn man nur mit 22kHz ausgibt. Wenn Du aber 
so hoch takten willst, um zum Beispiel kleinere externe 
Filterkomponenten zu verwenden, kannst Du natürlich auch einen 
Interruptzähler einbauen und nur bei jedem 3. Interrupt Daten nachladen. 
Das entlastet die CPU. Wichtig ist nur, daß der Timer, der die PWM 
generiert, auch für den Datentransfer zum OCR-Register benutzt wird.

von spess53 (Gast)


Lesenswert?

Hi

>Wenn die Daten nicht exakt synchron zur Samplerate gegeben werden, dann
>entstehen Schwebungen....

Das hatte ich ihm schon weiter oben vorgeschlagen. Allerdings würde ich 
zum Nachladen den OC-Interrupt nehmen. Dann wird das OC-Register beim 
nächsten Top aktualisiert.

MfG Spess

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

spess53 schrieb:
> Das hatte ich ihm schon weiter oben vorgeschlagen. Allerdings würde ich
> zum Nachladen den OC-Interrupt nehmen. Dann wird das OC-Register beim
> nächsten Top aktualisiert.

Wenn man den Overflow-Interrupt nimmt, wird das OCR zwar einen Zyklus 
später ausgegeben, aber dafür jitterfrei. Beim Output-Compare Interrupt 
kann es passieren, daß bei einem oberen Tastverhältnis der Update des 
Registers zu spät kommt und die Übernahme dann doch erst im nächsten 
Zyklus stattfindet. Außerdem kommt der OC-Interrupt zu nicht definierten 
Zeiten, abhängig vom Sample-Inhalt. Das ist für das darunter laufende 
Programm eher nachteilig. Der Overflow-Interrupt kommt immer zur 
Samplerate oder einem Vielfachen davon, punktgenau.

von Simon K. (simon) Benutzerseite


Lesenswert?

spess53 schrieb:
> Hi
>
>>Wie kommst du auf die 78 Khz. Wäre für mich mal interessant wie sich der
>>Wert errechnet.
>
> Datenblatt S.101. Du hast 20MHz, Vorteiler 1 und Top=255.
>
> ->  Fpwm= 20MHz/(1+255) = 78,125kHz

Fehlt da nicht noch ein "geteilt durch 2"?

von spess53 (Gast)


Lesenswert?

Hi

>Fehlt da nicht noch ein "geteilt durch 2"?

Wenn er Phase/Frequence Correct hat Ja. Hab ich wohl übersehen. Dann 
wundert mich sein Vibrato eigentlich nicht mehr. Ich werde das morgen 
mal schnell selbst testen.

MFg Spess

von Simon K. (simon) Benutzerseite


Lesenswert?

spess53 schrieb:
> Hi
>
>>Fehlt da nicht noch ein "geteilt durch 2"?
>
> Wenn er Phase/Frequence Correct hat Ja.

Habe das eigentlich verwechselt mit dem Output Compare.
Aber er hat tatsächlich den Phase correct mode (WGM10 gesetzt).

> Hab ich wohl übersehen. Dann
> wundert mich sein Vibrato eigentlich nicht mehr. Ich werde das morgen
> mal schnell selbst testen.

Jupp, eine Synchronisation ist absolut erforderlich. Am besten (wie 
schon erwähnt) das Einlesen zum PWM Takt synchronisieren.

von holger (Gast)


Lesenswert?

>Das nachladen der Daten scheint ja zu funktionieren. Wie gesagt das Ding
>funktioniert ja schon, nur leider mit einem Vibratoreffekt der schneller
>wird je höher ich die Samplingrate setze und ich keinen blassen schimmer
>habe woran es liegt.

Wie sieht denn dein Programm aus? Das lesen der Daten
von der SD braucht Zeit. Das bedeutet eine Pause in
der Ausgabe. Vibratoreffekt. Wie kann man das lösen?
Zwei Puffer verwenden. Puffer1 wird für die Ausgabe benutzt,
Puffer2 zum lesen von der SD Karte. Diese beiden Puffer
werden bei Bedarf umgeschaltet. Sprich: Wenn die Ausgabe von
Puffer1 beendet ist muss Puffer2 die neuen Daten zur Ausgabe
bereits enthalten. Puffer1 und Puffer2 wechseln dann die Funktion.
Das bedeutet aber auch das schon während der Ausgabe von Puffer1
der Puffer2 mit Daten von der SD Karte gefüllt wird. Also schön
verschachteln diese beiden Aktionen.

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

Ich hatte gestern versprochen das mal zu Testen. Bei den ersten beiden 
Oszilliogramme wird der OC-Wert synchron zur PWM nach geladen 
(OC-Interrupt bzw. Overflow-Interrupt). Das dritte Bild zeigt die 
Auswirkung von asynchronen Nachladen. Die sichtbaren Unregelmässigkeiten 
sind deutlich als 'zweiter' Ton zu hören.

MfG Spess

von Ingo L. (grobian)


Lesenswert?

spess53 schrieb:
> Hi
>
> Ich hatte gestern versprochen das mal zu Testen. Bei den ersten beiden
> Oszilliogramme wird der OC-Wert synchron zur PWM nach geladen
> (OC-Interrupt bzw. Overflow-Interrupt). Das dritte Bild zeigt die
> Auswirkung von asynchronen Nachladen. Die sichtbaren Unregelmässigkeiten
> sind deutlich als 'zweiter' Ton zu hören.
>
> MfG Spess

Könntest du mir dein Testprogramm mal zur Verfügung stellen.
Wäre echt nett von dir.

Gruß aus Berlin

Ingo

von spess53 (Gast)


Lesenswert?

Hi

>Könntest du mir dein Testprogramm mal zur Verfügung stellen.
>Wäre echt nett von dir.

Ist aber Assembler. Und auch nichtwirklich für andere geschrieben. Immer 
noch interessiert?

MfG Spess

von Ingo L. (grobian)


Lesenswert?

ja, willst du meine E-mail addi ?

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

>ja, willst du meine E-mail addi ?

Warum so umständlich. Ist aber wie gesagt 'Quick & Dirty'.

Sieh es dir mal an.

MfG Spess

von Matthias R. (reichema)


Lesenswert?

Hallo zusammen,

gibt es was neues zum Thema ?

Grüße
Matthias

von chris (Gast)


Lesenswert?

vllt. hilfts ja weiter http://www.watterott.com/de/Schnittstellen/Audio
dort gibt es audio module wo man audio files von sdkarte abspielen 
lassen kann

von Ingo L. (grobian)


Lesenswert?

Irgendwie will der Groschen bei mir noch nicht fallen. Also mein 
Vibratoreffekt kommt wohl daher,dass ich zwischen den Bufferzugriffen 
auf die SD-Karte (also alle 512 Bytes) eine Lücke habe. Ich denke mal 
das dass die Zeit ist die das Programm benötigt um sich die neuen Daten 
in den Zwischenspeicher ( Buffer zu laden). Gut, jetzt kann ich mit dem 
Timer alle 45 uS einen Interrupt auslösen der mir das Bytet aus dem 
gefüllten Buffer in das OCR-Register schreibt. Soweit ist ja alles OK. 
Aber irgendwann habe ich ja das letzte Byte aus dem Buffer ausgelesen 
und muss mir die nächsten Daten aus der Karte in den Buffer schreiben. 
Dort werde ich doch wieder das gleiche Problem haben, dass dieser 
Vorgang zu lange dauert und meine Lücke wieder entsteht.

von Karl H. (kbuchegg)


Lesenswert?

Ingo Laabs schrieb:

> Dort werde ich doch wieder das gleiche Problem haben, dass dieser
> Vorgang zu lange dauert und meine Lücke wieder entsteht.

Eines ist klar.
Wenn das Lesen von 512 Bytes von der SD-Karte länger dauert, als die 
getaktete Ausgabe von 512 Bytes, dann hast du ein prinzipielles Problem. 
Da kann dir kein Mensch dabei helfen.

Wenn in eine Badewanne durch den Ablauf mehr Wasser abrinnt als 
gleichzeitig durch den Zulauf zulaufen kann, dann wird sich in der Wanne 
niemals ein Schaumbad ergebem. So sicher wie das Amen im Gebet.

Allerdings:
> dass ich zwischen den Bufferzugriffen auf die SD-Karte
> (also alle 512 Bytes) eine Lücke habe

Was soll das heißen 'du hast eine Lücke'?

Das Lesen von der SD Karte muss passieren, während gleichzeitig über den 
Timer Interrupt der vorhergehende (bereits vollständig gelesene) Buffer 
ausgegeben wird. Und logischerweise wäre es gut, wenn das Lesen von 512 
Bytes abgeschlossen ist, ehe der vorhergehende Buffer komplett 
rausgetaktet wurde. Ist die SD Routine fertig, so wird gewartet, bis die 
Timerinterrupt Routine den vorhergehenden Buffer abgearbeitet hat und 
sich den eben erst gelesenen vornimmt. Erst dann kann die SD Routine 
wieder loslegen und den dann freien Buffer wieder mit Daten befüllen. 
Von daher ist zu erwarten, dass es eine zeitliche Lücke des Nichtstuns 
zwischen 2 SD-Karten Lesevorgängen geben muss. Erst wenn diese Lücke 
gegen 0 schrumpft bekommt man ein Problem.

Wenn du es genau wissen willst, dann hör auf im Trüben zu fischen und 
miss die Zeit, die deine Leseroutine braucht um 512 Bytes zu lesen.
Rechne dir aus, wie lange es dauert bis diese 512 Bytes ausgegeben 
werden.

Zu der Zeit für den Lesevorgang nimmst du noch ein paar Prozent dazu 
(vielleicht 10%) für allgemeinen Verwaltungskram rundherum und dann 
siehst in Zahlenform ob es sich ausgeht oder nicht oder ob das knapp 
wird.

von Ingo L. (grobian)


Angehängte Dateien:

Lesenswert?

Karl heinz Buchegger schrieb:
> Das Lesen von der SD Karte muss passieren, während gleichzeitig über den
> Timer Interrupt der vorhergehende (bereits vollständig gelesene) Buffer
> ausgegeben wird. Und logischerweise wäre es gut, wenn das Lesen von 512
> Bytes abgeschlossen ist, ehe der vorhergehende Buffer komplett
> rausgetaktet wurde. Ist die SD Routine fertig, so wird gewartet, bis die
> Timerinterrupt Routine den vorhergehenden Buffer abgearbeitet hat und
> sich den eben erst gelesenen vornimmt. Erst dann kann die SD Routine
> wieder loslegen und den dann freien Buffer wieder mit Daten befüllen.

und genau da habe ich das Problem, dass ich nicht genau weiss, wie das 
zu gehen hat. Ich gebe einen buffer aus und soll den nächsten lesen.

Die Lücke habe ich mal vereinfacht dargestellt. Wobwei die Lücke immer 
der Moment ist, an dem sich der nächste Buffer vorgenommen wird.

Und gehen muss es ja irgendwie, da ich schon Projekte gesehen habe, die 
genau das mit ner SD-Karte machen.

von Karl H. (kbuchegg)


Lesenswert?

Ingo Laabs schrieb:
> Karl heinz Buchegger schrieb:
>> Das Lesen von der SD Karte muss passieren, während gleichzeitig über den
>> Timer Interrupt der vorhergehende (bereits vollständig gelesene) Buffer
>> ausgegeben wird. Und logischerweise wäre es gut, wenn das Lesen von 512
>> Bytes abgeschlossen ist, ehe der vorhergehende Buffer komplett
>> rausgetaktet wurde. Ist die SD Routine fertig, so wird gewartet, bis die
>> Timerinterrupt Routine den vorhergehenden Buffer abgearbeitet hat und
>> sich den eben erst gelesenen vornimmt. Erst dann kann die SD Routine
>> wieder loslegen und den dann freien Buffer wieder mit Daten befüllen.
>
> und genau da habe ich das Problem, dass ich nicht genau weiss, wie das
> zu gehen hat. Ich gebe einen buffer aus und soll den nächsten lesen.


Wo liegt da das Problem?

2 Aktionen die nebeneinander herlaufen.
Die eine wird regelmässig im Interrupt gemacht, die andere in der 
Hauptschleife.

> der Moment ist, an dem sich der nächste Buffer vorgenommen wird.

Du darfst nicht warten, bis dein Interrupt den Ausgabepuffer 
abgearbeitet hat! Du müsst mit dem Lesen beginnen während die 
Interrupt Routine einen Buffer ausgibt!


Wenn ich mir deine Performance hier so ansehe, dann denke ich, dass 
dieses Projekt noch 5 Nummern zu groß für dich ist.

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:

> Wo liegt da das Problem?
>
> 2 Aktionen die nebeneinander herlaufen.
> Die eine wird regelmässig im Interrupt gemacht, die andere in der
> Hauptschleife.

Ungefähr so
1
// 2 Buffer die wechselweise zum Einlesen bzw. Abspielen benutzt werden
2
// wird aus dem einen abgespielt, dann wird in den anderen von der SD eingelesen
3
// und umgekehrt.
4
//
5
uint8_t BufferA[512];
6
uint8_t BufferB[512];
7
8
uint8_t* playBuffer = BufferA;   // die ISR gibt immer aus playBuffer aus
9
uint8_t* readBuffer = BufferB;   // von der SD Karte wird immer in readBuffer eingelesen
10
uint16_t actByte;
11
uint8_t  bufferChanged;
12
13
Interrupt:
14
{
15
   OC_iregendwas = playBuffer[actByte++];  // Byte ausgeben
16
17
   if( actByte == 513 ) {  // aus dem aktiven playBuffer ist alles abgespielt worden
18
19
     // hier an dieser Stelle könnte man noch eine Abfrage einbauen
20
     // wenn an dieser Stelle bufferChanged noch immer 1 ist (wird ja nach
21
     // dem Lesen von der SD Karte auf 0 gesetzt, dann bedeutet das, das die
22
     // SD Routine nicht hinterher gekommen ist
23
     //
24
     // if( bufferChanged == 1 )
25
     //    Overload LED einschalten
26
     // else
27
     //    Overload LED ausschalten
28
     //
29
30
     uint8_t* tmp = playBuffer;    // Buffer A und Buffer B tauschen
31
     playBuffer = readBuffer;      // die Plätze. Beim nächsten ISR Aufruf
32
     readBuffer = tmp;             // wird vom anderen ausgegeben ...
33
34
     actByte = 0;                  // .. und zwar von vorne
35
     bufferChanged = 1;            // .. und die Hauptschleife kriegt Nachricht
36
                                   // dass sie mit dem Einlesen anfangen kann
37
   }
38
}
39
40
int main()
41
{
42
   ...
43
44
45
  while( 1 ) {
46
47
     ....
48
49
    if( bufferChanged == 1 ) {     // die ISR hat den Buffertausch gemacht
50
                                   // readBuffer ist frei zum Einlesen
51
      readFromSDCard( readBuffer );
52
      bufferChanged = 0;
53
    }
54
  }
55
}

Soviel als grobe Skizze

von Ingo L. (grobian)


Lesenswert?

Karl heinz Buchegger schrieb:
> 2 Aktionen die nebeneinander herlaufen.
> Die eine wird regelmässig im Interrupt gemacht, die andere in der
> Hauptschleife.


sie laufen ja nicht nebenher, eine Aktion wird ja immer Unterbrochen.

>Wenn ich mir deine Performance hier so ansehe, dann denke ich, dass
>dieses Projekt noch 5 Nummern zu groß für dich ist.

Dann muß mann halt zusehen, dass man sich auf Nummer 1 runterarbeitet 
und das möchte ich unter anderem mit diesem Projekt erreiche. Wenn ich 
es jetzt wieder in die Ecke lege, bringt mich das nicht weiter und das 
möchte ich eigentlich vermeiden.

Code werde ich mir mal durcharbeiten um ihn zu verstehen.

von Karl H. (kbuchegg)


Lesenswert?

Ingo Laabs schrieb:
> Karl heinz Buchegger schrieb:
>> 2 Aktionen die nebeneinander herlaufen.
>> Die eine wird regelmässig im Interrupt gemacht, die andere in der
>> Hauptschleife.
>
>
> sie laufen ja nicht nebenher

Sie müssen aber!

(Siehe das Codefragment 1 Posting höher)


> Dann muß mann halt zusehen, dass man sich auf Nummer 1 runterarbeitet
> und das möchte ich unter anderem mit diesem Projekt erreiche.

Man fängt aber üblicherweise nicht als Kleinkind an, für den New York 
Marathon zu trainieren, sondern man macht erst mal seine ersten 
Schritte, lernt gehen, lernt laufen, läuft in der Regionalliga und 
irgendwann ist man dann soweit für eine große Veranstaltung.

> Wenn ich
> es jetzt wieder in die Ecke lege, bringt mich das nicht weiter und das
> möchte ich eigentlich vermeiden.

Es bringt dich auch so nicht weiter, weil du die dahinterliegenden 
Techniken noch nicht entdeckt hast. Und nein: 2 Dinge mehr oder weniger 
gleichzeitig zu tun, ist keine Raketentechnik. Das ist absolut simpel, 
wenn die eine sowieso schon im Interrupt abgearbeitet wird.
Der einzige "Trick" im geposteten Fragment besteht darin, 2 Pointer zu 
benutzen, die auf die eigentlichen Buffer zeigen. Das müsste man nicht 
so machen, wenn man die Aufgabenstellung das erste mal macht, machen die 
meisten Neulinge erst mal eine Variable die anzeigt welcher Buffer was 
macht und spicken dann den Code mit if-s. Mit den Hilfspointern ist das 
deutlich einfacher. Aber abgesehen von diesem Detail ist die Benutzung 
von 2 Buffern, die wechselweise zum Abspielen/Einlesen benutzt werden 
ziemlich naheliegend.

von Matthias R. (reichema)


Lesenswert?

Schade, dass hier immer wieder auf dieser Ebene Diskutiert werden muss. 
Das bringt und nicht weiter.

Übrigens: Habe auch mit aufwendigeren Dingen begonnen und später auch 
sehr einfache Dinge umgesetzt, die ich im Haus noch so benötigt habe. So 
war es für mich zwar schwer aber reizvoller und es hat gut funktioniert.

von Karl H. (kbuchegg)


Lesenswert?

Wenn ich mir ansehe, dass die Aufgabenstellung "SD-Karte auslesen und 
mittels PWM abspielen" mitlerweile ins vierte Monat geht, dann ist das 
nicht gerade ein überzeugender Beweis für die These "Es ist ok, mit 
Dingen anzufangen, die noch 5 Schuhnummern zu groß sind"

von Matthias R. (reichema)


Lesenswert?

ok

von Ingo L. (grobian)


Lesenswert?

Karl heinz Buchegger schrieb:
> Wenn ich mir ansehe, dass die Aufgabenstellung "SD-Karte auslesen und
> mittels PWM abspielen" mitlerweile ins vierte Monat geht, dann ist das
> nicht gerade ein überzeugender Beweis für die These "Es ist ok, mit
> Dingen anzufangen, die noch 5 Schuhnummern zu groß sind"


offtopic:
Vllt. hat man ja auch nicht immer die Zeit um sich darum zu kümmern. Es 
existiert ja auch noch eine Familie. Ich kann mich mit Sicherheit 2 
Wochen in ein mein Kämmerchen sperren, aber der Preis, den ich dann 
gegenüber meiner Familie dafür zahle wäre ein bissel hoch, gell.
Von daher bin für jede Hilfe dankbar. Ich bin was das bertrifft mit 
Sicherheit kein Profi und werde es wohl auch mit Sicherheit auch nicht 
werden. Das hält mich aber nicht ab, Dinge umzusetzen, auch wenn es 
aufgrund meines nicht Profidaseins ein wenig länger dauert. Von daher 
bin ich jedem Profi hier, der sich das hart erarbeitet hat, dankbar.

von Karl H. (kbuchegg)


Lesenswert?

OK. Einmal noch. Dann halt ich mich wieder raus

Ingo Laabs schrieb:

> Vllt. hat man ja auch nicht immer die Zeit um sich darum zu kümmern.

Immer Zeit?
Tschuldigung. Wenn ich das da oben in 5 Minuten aus dem Ärmel schütteln 
kann, dann erwarte ich von jemanden, der das noch nie gemacht hat, aber 
die Grundlagen dazu hat, dass er das in deutlich unter einem Nachmittag 
hinbringt. Da sind wir von 4 Monaten weit entfernt.

von Ingo L. (grobian)


Lesenswert?

Die Nachmittage die ich dazu nutze, 2 Kindern die Hausaufgaben 
beizubringen.
Gott sei dank programmieren die nicht in der Schule, sonst würde ich auf 
dem schlauch stehen.
Es ist doch so Karl-Heinz, du darfs auch nicht vergssen, dass du, so wie 
ich das hier mitkriege der absolute Profi bist und ich nur ein kleiner 
ich-habe-mal-lust-programmierer der den Kindern was lustiges bauen 
möchte was kein anderer hat.
Nun aber beim Thema bleiben, sonst wird das Thema hier noch geschlossen 
(nicht von mir glaube ich).

von Ingo L. (grobian)


Lesenswert?


von Matthias R. (reichema)


Lesenswert?

Guter Ansatz.
Weiterbauen bestimmt. Wenn mal wieder Zeit ist :-( 10 Tracks sind mir zu 
wenig.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

10 Playlisten a 255 Tracks alternativ. Wenn der Controller ein AVR ist, 
wonach es aussieht, kann man die Firmware ja auch patchen oder als 
Open-Source-Projekt neu gestalten. Gibt ja genug Geeks hier :-).

von Ingo L. (grobian)


Lesenswert?

Werde mal versuchen den von Karl-Heinz vorgeschlagenen Buffertausch zu 
realisieren.
Habe aber parallel dazu noch mal folgende Überlegung im Kopf. Da das 
Problem ja immer dann auftritt wenn der neuer Buffer von der Karte 
gelesen wird, kann ich dann eigentlich nicht auch wenn das letzte Byte 
gelesen wurde den delay entsprechend des Bufferzugriffs auf die Karte 
kürzen.

1
while (1)
2
  {
3
  // taste 3
4
   if  ( !(PINA & (1<<PINA3)) ) // ist 0 ? 
5
    //Lade Cluster für das index.htm File in den Speicher 
6
    Clustervar = 0;//suche im Root Verzeichnis
7
    if (fat_search_file((unsigned char *)"ABAUF.WAV",&Clustervar,&Size,&Dir_Attrib,Buffer) == 1)
8
    {
9
    //Lese File und gibt es als PWM aus
10
    for (int b = 0;b<224;b++)
11
      {
12
      fat_read_file (Clustervar,Buffer,b);
13
      for (int a = 0;a<511;a++)
14
        {
15
        OCR1A = Buffer[a];
16
        _delay_us(45);
17
                            
18
        }
19
20
      OCR1A = Buffer[511]; 
21
      _delay_us(22);    // hier kürzer warten
22
23
      }
24
    }
25
  // taste 3 ende
26
  }

von Ingo L. (grobian)


Lesenswert?

Habe die Idee von Karl-Heinz jetzt mal umgesetzt.
Tausche jetzt die Buffer aus. Es ist aber immer noch das Problem 
geblieben, dass folgender Zugriff auf die Karte

 fat_read_file (Clustervar,Buffer,b);

einfach zu lange dauert und ich immer noch Lücken in der Ausgabe habe.

von Matthias R. (reichema)


Angehängte Dateien:

Lesenswert?

Hallo Ingo,

ich habe mich noch einmal an die Interrupt Lösung gemacht und die 
Sprache hört sich nun besser an. Probiers mal aus.
Ich habe allerdings auf 12Mhz Quarz und ein 8khz wave File umgestellt.

Zugegeben, ich habe den Code einfach "hingebogen" bis es passt aber mir 
gings mal um die Verbesserung der Sprachqualität.

Die Interrupts müssten nochmal nachgerechnet werden um die exakte 
Geschwindigkeit hinzugekommen.

Viel Spaß
Grüße
Matthias

von Matthias R. (reichema)


Angehängte Dateien:

Lesenswert?

Hier nochmal das ganze mit:

Erkennung der Dateilänge. (Beendet Audioausgabe am Dateiende)

PortC0 schaltet Relais für den Verstärker (Stromversorgung ein und aus)

Pullups an den Eingängen wieder drin. ( Hatte ich versehentlich 
auskommentiert).

Implementiert ist momentan jedoch nur die Datei ABAUF.WAV. Kann man aber 
beliebig auf andere Dateien erweitern.

von Surfer (Gast)


Lesenswert?

Ingo Laabs schrieb:
> http://www.elv.de/output/controller.aspx?cid=74&de...
> http://www.elv-downloads.de/downloads/Leseproben/J...
> soll man da jetzt noch weiterbauen ?..20,00 Euro

Keine schlechte Hardware, und anscheinend ein "Atmel" Prozessor drauf. 
VLSI, Verstärker, Micro-SD Kartenslot..

von Matthias R. (reichema)


Lesenswert?

Ist es sicher. Ich freue mich auf die ersten Berichte.
Selbstgemacht und "lowest cost" wenn geht macht mir jedoch mehr Spaß.

Übrigens: Meine letzte Bestellung aus der E.. Apotheke hat 3,5 Monate 
auf sich warten lassen. :-) War dann ganz überrascht über das Paket. Ist 
nicht so mein Shop.

von Ingo L. (grobian)


Lesenswert?

Matthias Reichelt schrieb:
> Hallo Ingo,
>
> ich habe mich noch einmal an die Interrupt Lösung gemacht und die
> Sprache hört sich nun besser an. Probiers mal aus.
> Ich habe allerdings auf 12Mhz Quarz und ein 8khz wave File umgestellt.
>
> Zugegeben, ich habe den Code einfach "hingebogen" bis es passt aber mir
> gings mal um die Verbesserung der Sprachqualität.
>
> Die Interrupts müssten nochmal nachgerechnet werden um die exakte
> Geschwindigkeit hinzugekommen.
>
> Viel Spaß
> Grüße
> Matthias

WOW..Super,
muss jetzt mal schauen wo ich in meinem Programmteil zum Buffertausch 
den Bockmist geschossen habe.
Hier ein Programm um die Timer zu berechnen.

http://www.avrcalc.com/

Gruß aus Berlin
Ingo

von Matthias R. (reichema)


Lesenswert?

Hab das 8khz file auch mal auf einen ordentlichen Verstärker gegeben. 
Das Knattern ist definiv weg.
Lass hören, wenn Du das mit dem 22khz file noch hinbekommst. Ich habe 
die 8khz gewählt um Zeit beim Lesen der Karte zu gewinnen. Evtl. höheren 
Takt verwenden.

Ich versuche erstmal nichts weiter in der Richtung sondern kümmere mich 
um den Anschluß des RFM Moduls damit ich remote samples abspielen lassen 
kann.

Grüße aus Wien
Matthias

von Matthias R. (reichema)


Lesenswert?

Ups, sehe gerade, dass ich beim ersten Buffertausch noch keine Daten 
geladen habe. Wahrscheinlich kommt daher der eine Knackser zu Beginn des 
Abspielens.

von Ingo L. (grobian)


Lesenswert?

Werde heute Abend es mit den 22050 Hz probieren. Konte gestern Abend nur 
mal kurz probieren. Bin jetzt auf Arbeit. Evtl wäre für den Interrupt 
der CTC Mode angebracht. Erspart das nachladen des Timers.

von Ingo L. (grobian)


Lesenswert?

Habe letzt 20MHz genommen un bekomme bei 16KHz brauchbare Ergebnisse. 
Bissel Rattert es noch..aber brauchbar.

von holger (Gast)


Lesenswert?

>Habe letzt 20MHz genommen un bekomme bei 16KHz brauchbare Ergebnisse.
>Bissel Rattert es noch..aber brauchbar.

Also ich schaff mit 16MHz eine 22kHz Ausgabe ohne rattern.
Irgendwas machst du falsch;)

von Ingo L. (grobian)


Lesenswert?

holger schrieb:
>>Habe letzt 20MHz genommen un bekomme bei 16KHz brauchbare Ergebnisse.
>>Bissel Rattert es noch..aber brauchbar.
>
> Also ich schaff mit 16MHz eine 22kHz Ausgabe ohne rattern.
> Irgendwas machst du falsch;)

kannste mal code posten?

den hier habe ich bei 20 MHz und 22050 KHz sampling
1
#include <stdio.h>
2
#include <string.h>  
3
#include <avr/io.h>  
4
#include <avr/eeprom.h>  
5
  
6
#include "mmc.h"
7
#include "fat.h"
8
#include "usart.h"
9
#include <util/delay.h>
10
#include <avr/interrupt.h>
11
12
volatile int a;
13
int b;
14
int dl2;  
15
unsigned char Buffer[512];
16
unsigned char playBuffer[512];
17
uint8_t  bufferChanged;
18
19
20
21
22
23
ISR(TIMER2_OVF_vect)
24
{
25
26
  TCNT2=0x8F;  
27
28
  if(a<512)
29
  {
30
  OCR1A = playBuffer[a];a++;
31
   }
32
     if(a==512)
33
   {
34
  }
35
      
36
}
37
38
//Hauptprogramm
39
int main (void)
40
{
41
  //SYSCLK defined in usart.h
42
  //Initzialisierung der seriellen Schnittstelle
43
44
  
45
   TCCR2 |= (1<<CS21) | (0<<CS20) | (0<<CS22); // Start timer at Fcpu/08
46
   //Enable Overflow Interrupt Enable
47
   TIMSK|=(1<<TOIE2);
48
49
  
50
51
   dl2=0;  
52
53
54
//Initialisierung der MMC/SD-Karte
55
  usart_write("System Ready!\r\n");  
56
  while ( mmc_init() !=0) //ist der Rückgabewert ungleich NULL ist ein Fehler aufgetreten
57
    {
58
    usart_write("** Keine MMC/SD Karte gefunden!! **\n");  
59
    }
60
  usart_write("Karte gefunden!!\n");
61
  
62
  fat_init();//laden Cluster OFFSET und Size
63
  //Initialisierung der MMC/SD-Karte ENDE!
64
65
    unsigned int tmp;
66
  
67
  mmc_read_csd (Buffer);
68
  
69
  for (tmp = 0;tmp<16;tmp++)
70
    {
71
    usart_write("%x ",Buffer[tmp]);
72
    };
73
74
75
  //Ausgabe des Root Directory
76
  unsigned int Clustervar;
77
  unsigned char Dir_Attrib = 0;
78
  unsigned long Size = 0;
79
  usart_write("\r\nDirectory\r\n");
80
  for (char a = 1;a < 240;a++)
81
  {
82
    Clustervar = fat_read_dir_ent(0,a,&Size,&Dir_Attrib,Buffer);
83
      if (Clustervar == 0xffff)
84
      {
85
        break;
86
      }
87
    tmp = (Size & 0x0000FFFF);
88
    usart_write("Cluster = %4x DirA = %2x FileName = ",Clustervar,Dir_Attrib);
89
    usart_write("%s",Buffer);
90
    usart_write("\r\n");
91
  }
92
  usart_write("\r\nDirectory Ende\r\n");
93
94
95
96
97
DDRA  &= ~(1<<PA3) | (1<<PA2)  | (1<<PA1) | (1<<PA0);  /* Pin PA3 als Eingang */
98
PORTA |= (1<<PA3)  | (1<<PA2)  | (1<<PA1) | (1<<PA0);    /* internen Pull-Up an PA4 aktivieren */
99
100
101
102
  
103
  // INIT PWM
104
    
105
    DDRD = (1 << PD5 );
106
    TCCR1A = (1<<COM1A1) | (0<<COM1A0) | (0<<WGM11)  | (1<<WGM10) ;
107
    TCCR1B = (0<<CS12)   | (0<<CS11)   | (1<<CS10);
108
109
  DDRC = 0b00000001; //Verstärkerrelais
110
111
112
  // INIT PWM ENDE
113
114
while (1)
115
  {
116
  // taste 3
117
if  ( !(PINA & (1<<PINA3)) ) // ist 0 ? 
118
   {
119
  
120
  
121
  //Lade Cluster für das index.htm File in den Speicher 
122
    Clustervar = 0;//suche im Root Verzeichnis
123
    if (fat_search_file((unsigned char *)"ABAUF.WAV",&Clustervar,&Size,&Dir_Attrib,Buffer) == 1)
124
    {
125
126
127
  PORTC |= (1<<PC0);  //Verstärker ein
128
129
  b=0;    
130
131
132
133
  //Ersten Datensatz lesen
134
  fat_read_file (Clustervar,Buffer,b);
135
  memcpy (playBuffer,Buffer,512);
136
  a=0;
137
  b=1;
138
139
140
141
142
143
   //Interruptcounter initialisieren
144
    TCNT2=0x8F;
145
146
  sei();
147
148
149
150
    //Lese File aus File
151
        while(b<(Size/512))
152
          {
153
      
154
          if(a==512)
155
          {
156
   
157
        memcpy (playBuffer,Buffer,512);
158
        a=0;
159
          fat_read_file (Clustervar,Buffer,b);
160
  
161
        b++;
162
    
163
            }
164
        }
165
166
  
167
    cli();
168
169
170
171
      PORTC &= ~(1<<PC0); //Verstärker aus
172
  
173
174
175
    }//search file abauf
176
   }//port A3
177
  }//endlosschleife 
178
}//main

von holger (Gast)


Angehängte Dateien:

Lesenswert?

>kannste mal code posten?

Klar. Hier mal die main.c. Das komplette Projekt
poste ich später mal oder packs gleich in die Codesammlung.
Ich bin da noch ein bisschen am basteln;)

von Ingo L. (grobian)


Lesenswert?

hmmm..das is ja jetzt was völlig anderes als das was wir hier 
haben..dachte jetzt du hast es mit dem vorhandenen code gemacht

von holger (Gast)


Lesenswert?

>hmmm..das is ja jetzt was völlig anderes als das was wir hier
>haben..dachte jetzt du hast es mit dem vorhandenen code gemacht

Naja, nicht jeder nutzt Ulrichs Code;)

von Matthias R. (reichema)


Lesenswert?

Na super. Ich würde sagen wir stehen dann kurz vor gleich zwei 
Durchbrüchen zum Ziel. Wenn auch überraschend.

von holger (Gast)


Angehängte Dateien:

Lesenswert?

So, hier mal eine vorläufige Version zum schnuppern als AVR-Studio 
Projekt.

Soundausgabe erfolgt an OC2/PD7 per PWM.
Standard SPI Anschluss der SD-Karte an MISO,MOSI, SCK.
CS der SD am SS Pin. ATMega32 getaktet mit 16MHz.

Bei Problemen schlagen sie ihren Arzt oder...;)

von Matthias R. (reichema)


Lesenswert?

Gut, ich denke ich habe alles zusammen was ich brauche.

Vielen Dank für die Initiative und an die Beteiligten.

Danke auch an Holger für den Code. Werde mir Deine Lösung noch anschauen 
und testen, wenn ich einen Quarz nachbesorgt habe.

von holger (Gast)


Lesenswert?

>Danke auch an Holger für den Code. Werde mir Deine Lösung noch anschauen
>und testen, wenn ich einen Quarz nachbesorgt habe.

Funktioniert auch bei 8MHz noch gut. Bei 4MHz raschelt es dann
doch ein wenig mit 22kHz Samplerate;)

von Ingo L. (grobian)


Lesenswert?

Danke auch an allen die das Projekt mit unterstützt haben.

von Ingo L. (grobian)


Lesenswert?

Hallo Matthias,

das
1
int dl2;
ist das noch ein überbleibsel aus der Probierphase

von Matthias R. (reichema)


Lesenswert?

Ja, ist es natürlich. Ich habe da nicht mehr sauber gemacht.

von Matthias R. (reichema)


Lesenswert?

Ingo Laabs schrieb:
> Habe letzt 20MHz genommen un bekomme bei 16KHz brauchbare Ergebnisse.
> Bissel Rattert es noch..aber brauchbar.

Ich hab grad noch mal ein bisschen experimentiert. 16khz laufen bei mir 
mit 12Mhz problemlos. ( Version Ingo ) Kein Rattern zu hören.

Übrigens. Hab nette Ergänzungen gefunden:

Pollin Deckenlautsprecher  640 379

und Wavefiles von Balabolka. ( Text-to-Wave converter )

von Ingo L. (grobian)


Lesenswert?

Was für WAV-Files verwendest du? (Sampling-Frequenz ?)

Gruß Ingo

von Matthias R. (reichema)


Angehängte Dateien:

Lesenswert?

Hallo Ingo,

16khz.Siehe anbei screenshot aus dem "Audiorecorder" von Windows

von Uwe S. (de0508)


Angehängte Dateien:

Lesenswert?

Hallo,

noch eine Anmerkung zur PCM Ausgabe per atTiny861.

ChaN beschreibt in seinem Artikel vom 11.09. einen "255-Voice PCM Sound 
Generator".

http://elm-chan.org/works/sd20p/report.html

Da ich auch eine Sprachausgabe benötige, habe ich die Idee aufgegriffen 
auf mit einem atTiny861V-10 auf einem Steckbrett die Software getestet.

original Schaltplan: http://elm-chan.org/works/sd20p/sdsg.png

Den Schaltplan habe ich etwas erweitert:

a) PB7 Reset - PullUp mit 10k an +5V
b) mit MMCSDSCH.JPG habe ich eine 4GB SDHC Karte per Floppystecker mit 
dem atTiny861V-10 verbunden.
c) ein kleiner a Kopfhörverstärker LM386 gain=20 treibt einen 8 Ohm 
Lautsprecher.
d) ein 3,3V Spannungsregler mit PO30RV11 Regler für die SD-Karte.

Leider habe ich noch Abbrüche beim abspielen der WAV Dateien, sie laufen 
zwischen 1-20 sek, dann zeigt die Software einen Fehler beim Zugriff auf 
das Dateisystem an.

Ich denke es liegt an der SDHC Karte Verkabelung - zu lange <=5cm.

von Uwe S. (de0508)


Lesenswert?

Hallo,

Lösung für den "255-Voice PCM Sound Generator":

http://elm-chan.org/works/sd20p/report.html

Nun habe ich die SD-Karte und den atTiny861 direkt an die 3,3V des 
Spannungsregler PO30RV11 angeschlossen.

- der atTiny861 ist direkt mit der SD-Karte verbunden, also keine 
Spannungsteiler Widerstände mehr !

- ein 10k PullUp (3,3V) Widerstand ist noch an die CS-Leitung (PB0) der 
SD-Karte angeschlossen.

- die +5V aus dem USB-Port speisen nun nur noch den LM386 direkt.

Und siehe da, es geht alles - 1A Projekt !

.

von Ingo L. (grobian)


Lesenswert?

na ja.. es kommen ja immer mehr lauffähige Varianten ans 
Tageslicht..respekt

Gruß aus Berlin

Ingo

von Matthias R. (reichema)


Lesenswert?

Wo bekommt man den atTiny861 am einfachsten ?

von Uwe S. (de0508)


Lesenswert?

Hallo Matthias !

Matthias Reichelt schrieb:
> Wo bekommt man den atTiny861 am einfachsten ?

ich habe meine drei Stück über das I-Net bei

- http://www.kessler-electronic.de/

bestellt.

Die Firma ist auch in der Bucht zu finden: kessler-electronic

Das geht immer innerhalb von 1-2 Tagen, wenn man per paypal bezahlt.

.

von Matthias R. (reichema)


Lesenswert?

Eigentlich schade.

Zitat:
Für Lieferungen ins europäische Ausland erfolgt nur per Vorauskasse. Es 
gilt ein Mindestbestellwert von 100,- €. Die Versandkosten betragen hier 
14,95€ pro Paket mit maximal 30 kg Gewicht

Vielleicht komme ich mal die Verlegenheit 30kg Tinys zu bestellen. :-)

Trotzdem Danke für den Tip.

von Uwe S. (de0508)


Lesenswert?

Hallo Matthias,

und wo wohnst Du ?

einen atTiny861V-10 könnte ich abgeben, zu Selbstkosten natürlich.

von Matthias R. (reichema)


Lesenswert?

Hallo Uwe,

das ist wirklich sehr nett. Ich glaube ich werde bei Gelegenheit über 
meinen "Kontaktmann" in Deutschland bestellen und dann weiterschicken 
lassen, da evtl. noch einiges hinzu kommt.

Es ärgert mich nur immer wenn ich solche Phantasiepreise für 
Versandkosten sehe. Macht mein Namensvetter leider auch so.

Grüße aus Wien
Matthias

von Ingo L. (grobian)


Lesenswert?

Kann mir mal einer sagen wo in dem Programm mit dem Tiny 861 die 
Tastatur abgefragt wird ? Das Programm würde für mich mehr Sinn machen, 
wenn ich die Taster einzeln abfragen könnte, also pro PortPin ein Wave 
abspielen.

von Uwe S. (de0508)


Lesenswert?

Guten Morgen Ingo,

eine Änderung ist nicht notwendig.
Lege einfach je eine Datei für jeden Pin ab.

Bit 0 = 001.wav
Bit 1 = 002.wav
Bit 2 = 004.wav
:
Bit 7 = 128.wav

läuft super bei mir !

Die "Tasten" sind Taster und werden über den PinChange Interrupt 
'abgefragt'.

Siehe in "main.c" die Funktion
1
static BYTE chk_input (void)
und die gelesen Bits landen in der Variable
1
Cmd
.

Die Eingangsbits werden in
1
int main (void)
 gesetzt.
1
  PCMSK0 = 0b11111000;      /* Select pin change interrupt pins (SW1..SW8) */
2
  PCMSK1 = 0b01110000;
3
4
  /* Initialize ports */
5
  PORTA = 0b11111011;    /* PORTA [pppppLHp]*/
6
  DDRA  = 0b00000110;
7
  PORTB = 0b01110001;    /* PORTB [-pppLLLH] */
8
  DDRB  = 0b00001111;

.

von Ingo L. (grobian)


Lesenswert?

MAl ne Frage zu den Karten..Sind SD-Karten kompatibel zu den micro und 
mini SD Karten. Werden die selben Routinen verwendet wie für die 
SD-Karte ?

von Uwe S. (de0508)


Lesenswert?

Guten Morgen Ingo,

der Quellcode ist öffentlich und dort wird nicht unterschieden.

Ich habe ja SDHC verwendet ohne irgendwelche SW Anpassungen, der Autor 
eine Micro SD Karte im Einsatz.

Was er dazu schreibt, steht hier:

http://elm-chan.org/works/sd20p/report.html

[I]A MicroSD card is used as storage media and also SD and MMC can be 
used. It is controlled in SPI mode via USI.[/I]

Ok ?

von Henning (Gast)


Lesenswert?

Moin Moin

hab den Code von Holger soweit zum Laufen gebracht. Aber ich komme 
irgendwie nicht drauf, wie man die Soundausgabe stoppen kann, so dass 
man sie hinterher wieder starten kann (evntl auch mit nem anderen 
Track).

wenn ich StopTimer(); und Fclose(); mache, dann kann ich danach nix mehr 
abspielen mit PlayWave();


Hat einer da schon ne Lösung oder Idee?


Grüße Henning

von Henning (Gast)


Lesenswert?

...hat sich erledigt.

Grüße

von Ingo L. (grobian)


Lesenswert?

warum ?
was hast du gemacht ?

von Matthias R. (reichema)


Angehängte Dateien:

Lesenswert?

Ist zwar schon einige Zeit her aber hier noch meine fertige Software mit 
RFM01 Anbindung auf 433.300. RFM empfängt einen string der mit "WAV;" 
beginnt und hinter dem Semikolon folgt der Dateiname der anzuspielenden 
Wave Datei. Der Dateiname besteht aus 5 Buchstaben und der Endung ".WAV"
Damit spiele ich nun schon seit monaten Wave files ferngesteuert von 
meinem AVR-NET board ab.
Der Code ist vielleicht nicht besonders "sauber" geschrieben aber es 
funktioniert prima. Vielleicht kann jemand etwas damit anfangen.
Der Inhalt der SD Karte befindet sich im Verzeichnis "stimmen" des Zip 
Files.
Sprachfiles erstelle ich normalerweise mit Bolabolka am PC.

Viel Spaß

von Ingo L. (grobian)


Lesenswert?

hats auch irgendwo nen schaltplan ?

von Matthias R. (reichema)


Lesenswert?

Ingo Laabs schrieb:
> hats auch irgendwo nen schaltplan ?

Muss ich zu Hause schaun. Wenn dann heute abend.

von Henning (Gast)


Lesenswert?

Ingo Laabs schrieb:
> warum ?
> was hast du gemacht ?

Also, wie gesagt, ich hab versucht, das ganze mit Fclose() und 
StopTimer() zu beenden. Dabei bin ich aber in dieser "ugly waitingloop" 
hängengeblieben.
Hab dann einfach ein zusätzliches Abbruchkriterium hinzugefügt, und 
schon konnte ich Tracks stoppen und danach wieder andere abspielen. Also 
eigentlich wars n blöder Fehler, aber manchmal braucht man ja ein 
bisschen um drauf zu kommen.

Hier der Code, damit du weißt , was ich meine:

void PlayWave(char *name)
//###################################################################### 
#############
{
 unsigned char result;
 unsigned int read_bytes;
 //unsigned long chunksize;

 test = 0;

 result=Fopen(name,'r');
 if(result==F_OK)
  {

  read_bytes = Fread(play_buffer0,0x3A); // skip the wave header (not 
always 0x3A length!)

  play_buffer_index = 0;
  play_buffer_number = 0;

    // fill first audio buffer
  read_bytes = Fread(play_buffer0,PLAY_BUFFER_SIZE);

  StartTimer(); // start playing

  do
  {
   if(play_buffer_number & 1) // buffer number 1 is playing, read buffer 
0
   {
     read_bytes = Fread(play_buffer0,PLAY_BUFFER_SIZE);
       while((play_buffer_number & 1) && (test != 1)); // ugly waiting 
loop, try to use a state machine
   }
   else  // buffer number 0 is playing, read buffer 1
   {
     read_bytes = Fread(play_buffer1,PLAY_BUFFER_SIZE);
       while(((play_buffer_number & 1) == 0 ) && (test != 1));
   }

  } while((read_bytes == PLAY_BUFFER_SIZE) && (test != 1));
  // if read_bytes is smaller PLAY_BUFFER_SIZE ignore these samples
  // or fill buffer with zero samples at the end

  StopTimer();
  Fclose();
  }
}




Grüße Henning

von Matthias R. (reichema)


Angehängte Dateien:

Lesenswert?

Ingo Laabs schrieb:
> hats auch irgendwo nen schaltplan ?

Hallo Ingo,

anbei was ich noch habe. Ich weiss aber nicht, ob ich zwischenzeitlich 
noch Kleinigkeiten geändert habe, die ich nicht im Schaltplan habe. 
Insbesondere bei der Beschaltung der SD Karte.
Für das Prinzipverständnis sollte es jedoch reichen. Schönheitsfehler in 
der Zeichnung bitte ich zu entschuldigen. Ich habe sie nur für mich 
selbst angefertigt.

Eingebaut habe ich das ganze in einen alten "PC Lautsprecher". Da dort 
Netzteil und Verstärker schon eingebaut sind.

Grüße
Matthias

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.