Hello,
I want to play some .wav sound files from a SD card on the QG8 MC. I already read a lot about 1-Bit PWM sound and on reading SD cards by SPI on AVR controllers. Fortunately SPI and the PWM module can use different pins on the QG8, so this should be possible.
Every expired PWM period I'll get an interrupt and then I'll feed a new value for the duty cycle from a buffer.
So, what do you think, is the MCU fast enough (at 8MHz) to handle this?
I think I have to implement a small dobule-buffer sheme, which reads part of a sector in each buffer, because reading the flash directly in the ISR will be much too slow (some ms).
The main function will fill the buffers from the SD card and will poll a flag, which indicates the buffer switch (this happens when the ISR has finished playing one buffer).
What do you think about this concept? Any better ideas?
Thanks in advance and bye,
Nice job!!! Sounds very nice, and very original solution.
Maybe you can use PTB5/TPMCH1/SS for another PWM and manually set/clear another pin for SS signal of SD card.
In my case I used 2 PWM, one with a 560K resistor, the other with a 2K2 resistor, one plays the high byte and the other the low byte. And maybe you can use MTIM module to achive your sample rate (for example 22Khz), this free your PWM signals (you can achieve 8Mhz/256=31Khz PWM, easier to filter with simple caps, in my project running at 16Mhz I got 62Khz PWM ).
Also, I lowered the SD bitrate using 8bit ulaw samples (using cooledit) that expands to 16 bits via a table, they sounds almost identical to 16 bits raw samples.
Cheers
Hi,
these are very interesting ideas. Yes, I'm able to use PTB5 for my second PWM and the SlaveSelect can be done by another GPIO pin.
My MC is limited to 10 MHz, so I can't get a faster PWM. If I use a different frequency for the MTIM and the PWM module then I fear some aliasing effects, because the frequencys are very close to each other. But with your ideas it should be possible to get near 16 bit quality even on this small MCU. Or stereo sound.
Bye,
Hello,
I found your post and I have a very similar project to implement: use a SD card reader to load data on some eeprom chips.
Without implementing a FAT how would you know where to look for the file name in the SD memory given the base block address where the file was written?
I am using SD Card Reader Using the M9S08JM60 demo board.
Any suggestion would be greatly appreciated
thanks
Last week I started this project and I made some experiences.
I took an SD-MicroSD-Card Adapter and wired it to my breadboard.
I had to connect it directly to the battery (3.6V lithium cell) and not
behind my circuit protection diode, because the voltage drop was too high
when operating and my MCU run wild.
I took the SD card and SPI code from the following webinar:
This code was for the flexis MCU series but it was very easy to port it for the QG8.
Then I wrote with "dd" for windows an 8-Bit sample in raw format to a MicroSD card
and I could hear sound with some kind of distortion.
I found that the function for reading a 512 byte block was too slow. I have time for 46.000 MCU cycles and it took 60.000 cycles.
But now I realized that my approach was too complicated. Instead of filling a 128 byte buffer
and reading every SD sector four times I can read byte for byte in the timer overflow interrupt
by SPI, because SPI defines no timing and the SD card already buffers the data.
I'll check this aproach in the next days.
Bye,
Hi,
last week I had some time for this project and fortunately it works really good now. I start the data stream from the SD card with command 18 (endless block read) and I read in my timer overflow interrupt only one byte. Every 512 bytes I have to discard 4 bytes (CRC and two other bytes).
In the timer ISR is enough time to read higher sample rates or 16-bit wav. But on this controller it doesn't make sense, because the duty cycle is in the range from 0 to 362 (8 MHz, 22 KHz PWM).
To increase the resolution I would need a second PWM, but the pin is already used by SPI.
To utilize the whole range I normalize my wav on the computer to 70% and I double the values in the ISR. I'm amazed how good it sounds! I have one button to switch between different songs. If someone presses the button, then the stop command (12) is send to the card and another block stream command is given with a different start sector. With a cheap 2GB SD card I'm able to play more than 2000 min of sound.
So, if someone is interested I'll post the project code here.
Bye,
I am really interested. Pls do it.
Thanks in advance.
Cheers,
Celso
So, here's the project. It plays four songs on the SD card when you switch a button, but it plays endless. The software is not finished yet, but adding a sector counter and stopping the sound is trivial.
Maybe adding FAT support would be interesting, but for my purpose it is good enough.
Bye,
Hello again,
for all of you who are interested in the sound quality of the board:
I sampled with an Soundblaster audigy directly from the PWM pin output on my circuit (with two filter capacitors). The sound is from an old C64 game ("Monty on the run") and was played with 8 bit and 22 KHz on the MC9S08QG8.
Bye,
QG8 has only 512 bytes of RAM, SD's sectors are 512 bytes long, so you won't be able to read a complete sector at once. Besides, Fat adds more complexity and you need at least whole sector read and aditional reads when data accessing.
However, you can simplify your app by not using a filesystem, just storing your wave data in raw sectors of SD cards (you may have to develop you custom app to record SD, in Windows XP it's easy, just opening the media with Createfile and \\.\PhysicalDrive1,2,3,etc. and then Writefile to write 512bytes sectors). Also, you can combine two PWM outputs to increase resolution, in my case I combined two 8 bits PWM to get a 16 bits output (well, it sounds as good as a 12 bits DAC, a lot better than a simple 8 bits PWM). You can store your samples using 8 bits u-law (16 bits when decoded, sounds really good), and decode it using a simple table (256 x 16bits).
Cheers.
PD: Sorry for my English
Hello,
polosoft wrote:QG8 has only 512 bytes of RAM, SD's sectors are 512 bytes long, so you won't be able to read a complete sector at once.
That should be no problem as I'm able to read a sector more then once. With two 128 byte buffers, for example, I would read a sector four times. Not very effective, but with a sample FRQ of 22 kHz / 8 bit the timing should be possible. With this FRQ I have to read every ~6 ms a new buffer and a SD sector read should take ~3 ms.
Besides, Fat adds more complexity and you need at least whole sector read and aditional reads when data accessing.
There is a very interesting page about the "Petit FAT File System Module":
http://elm-chan.org/fsw/ff/00index_p.html
But using no file system at all is also a fine solution. Writing a small Windows program is easier for me than implementing the FAT in the MC.
I want to use the QG8 because:
- It must be cheap. Total cost < 10 Euro
- Batterie supplied. The QG8 has very good low power modes.
- DIP housing. It is only for a hobby project (a Geocache)
- I have 15 pieces of the MCU at home :smileywink:
The use of two PWM for increasing resolution looks very interesting!
Thanks for all your suggestions.
I'll start with this project in the near future and then I'll report how far I got.
Bye,
SB,
This is just to tell you that you can built DIP prototypes w/ more powerful processors, there are the flexis DIP adapters that turn SMT to 4x16 pinhead, they are not small but you can swap processors easily. The JS16 probably will meet your budge.
Cheers,
Celso
Maybe the QG8 is too small for the task. For SD Card you could check FAT-lite available for the flexis series. I've recently ported this SD software for MCF51.
The idea sounds very interesting to me, maybe we could work together on this.
Cheers,
Celso