Genetating sound signal using DAC on Core module


#1

Hi there.
I would like to generate simple analog sound signal using DAC on Core module with sampling frequency of 16kHz for the upcoming project. Initially it just enough to be generated as a link signal to 3.5 jack. Which module and equipment or components do i need?

Thanks Matouš.


#2

Hello/Ahoj Matouši,

the DAC0 and DAC1 pins are P4 & P5. You can connect directly to them or use Sensor Module which has routed these pins to the A and B channels screw terminals, see the schematic:

This signal is 0-3V so if you use headphones you need to amplify this signal. Or at least put a capacitor in series between the GPIO and headphones/amplifier.
http://www.learningaboutelectronics.com/Articles/What-is-a-coupling-capacitor

Did you tried the example in the How To section?
https://www.bigclown.com/doc/firmware/how-to-da-converter/

Martin


#3

Thanks @hub.martin

I haven’t noticed da convertor how to section. It looks handy.

I will try it.


#5

Hi @hub.martin and all bigclownians.
I tested mentioned code from DAC how-to section and find out working with pre generated array is pretty simple and it is working fine but I want to generate tones (sine signal) in a pre determined range of frequencies and with a variet amplification (custom filters)
My question is if there is an option to “feed” DAC with computed data in realtime. Tiny deley permitted.

Thanks,
+Matouš S.


#6

Hello Matouši,

if you remove the word const from the sine_wave array definition, then instead of FLASH the array is created in RAM and you can modify the array any time, even when the DAC is running.

uint8_t sine_wave[] = {
  0x80, 0x86, 0x8C, 0x93,
  0x99, 0x9F, 0xA5, 0xAB,....

It would be bettter to know more detail what you mean by realtime. Where the realtime data will be read? Generated by sin() and other math functions? Read from ADC? Complete details of your project will help to choose the right solution. Right now there are two ways to change the output waveform, easy and the other little bit harder and I’n not sure now which will be better for you usage.

a) If you would like to create arbitrary generator (google for that) then you create your buffer as big as your lowest frequency output. Then you fill the array with sin()/whaever function and the re-run the DAC with the lenght that match perfectly with the single period of your signal. You can generate saw, pulses and other waveforms, apply filters to them.

b) If you really need realtime updating of the continous DAC output, then you need to use double buffering. Its called double buffering, but you really have only single buffer like now, only divided in two halfs. While the first half of the buffer is fed out to the DAC, the second half of the sine_wave array can be modified in your code on-the-fly. Then when the DAC reaches the second half of the buffer, you continue to update the first half. In the SDK there are events for that. But you need to have the timing right, so you code has enough time to fill second part of the buffer until the DAC runs to it. Let me know if you need some example or test, it will take me few mintues to check that on the scope.

So you need to register you event handler by calling bc_dac_set_event_handler and check for that two events which tell you if the DAC has finnished sending first half of the buffer, or end of the buffer (done).

These events are fired:


Martin