UNO R4 DAC Resolution

Hi - I'm trying to use the analogwave library on my UNO R4 WiFi with in-built DAC to generate a sine wave of 1000Hz as per the example code. This is my code:-

#include "analogWave.h" // Include the library for analog waveform generation
 analogWave wave(DAC);   // Create an instance of the analogWave class, using the DAC pin
 int freq = 1000;  // in hertz, change accordingly
 
void setup() 
{
  Serial.begin(9600);  // Initialize serial communication at a baud rate of 115200
  wave.sine(freq);       // Generate a sine wave with the initial frequency
}
 
void loop() 
{
  Serial.println("Frequency is now " + String(freq) + " hz");
   wave.freq(freq);  // Set the frequency of the waveform generator to the updated value
  delay(1000);      // Delay for one second before repeating
}

and it works OK, I have an oscilloscope attached to ground and A0 (the DAC pin) and the sine wave generated clearly has 'steps' in it presumably because the resolution is 8 bits. There are numerous documentation snippets that say the resolution can be set up to 12 bits, but the only way I can find to do that is 'analogwriteresolution' function however that appears to be used if you subsequently use analogwrite, which I am not as the library takes care of the writing to the DAC.

So - my question is can the I use the analogwave library and use 12 bit resolution somehow?

PS - I don't want to do analogwrite() to the DAC as I tried this in a tight loop (no delay between writes) and all I could get was about 2 millisecond frequency so not enough for my purposes.

Thanks

Hi - thanks for your reply. I need to state that I am not an expert programmer, but just have basic knowledge. I was hoping that the analogwave library would have some clear documentation on constructors and class variables and methods, but if it does, I can't find it.

If I was capable of looking into the code of the library and recompiling with what was required, I would have done that.

So my question for anyone who does know that library well is, can I adjust it somehow so these discrete steps appearing on the analog waveform can be smoother?

Thanks

I glanced at the analogWave library code, and it appears that you overlooked this overload of the analogWave constructor in the library, with allows to specify arbitrary waveforms. This has nothing to do with bit depth setting, though.

  /* constructor 2 with buffer to be used (sample in buffer are output ciclycally */
  analogWave(pin_size_t pinNumber, uint16_t *_buffer, uint32_t _size, uint32_t _offset);

A few minutes of your time studying the .h and .cpp files (and comments therein) would probably be well spent. ArduinoCore-renesas/libraries/AnalogWave/analogWave.h at main · arduino/ArduinoCore-renesas · GitHub

Edit: a second glance at the code reveals quite a bit about how bit depth is automatically selected:

void analogWave::init(pin_size_t pinNumber) {

  buffer = nullptr;
  size = 0;
  index = 0;
  _amplitude = 1.1;

  dac_bits = 0;

  if (IS_DAC(pinNumber)) {
    auto cfg_dac = getPinCfgs(pinNumber, PIN_CFG_REQ_DAC);
    pin = cfg_dac[0];
    if (IS_DAC_8BIT(pin)) {
      dac_bits = 8;
      dtc_info.transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE;
      if (GET_CHANNEL(pin) == 0) {
#ifdef DAC_ADDRESS_8_CH0
        dtc_info.p_dest = (void *)DAC_ADDRESS_8_CH0;
#endif
      } else if (GET_CHANNEL(pin) == 1) {
#ifdef DAC_ADDRESS_8_CH1
        dtc_info.p_dest = (void *)DAC_ADDRESS_8_CH1;
#endif
      }
    } else {
      dac_bits = 12;
      dtc_info.transfer_settings_word_b.size = TRANSFER_SIZE_2_BYTE;
      if (GET_CHANNEL(pin) == 0) {
#ifdef DAC_ADDRESS_12_CH0
        dtc_info.p_dest = (void *)DAC_ADDRESS_12_CH0;
#endif
      } else if (GET_CHANNEL(pin) == 1) {
#ifdef DAC_ADDRESS_12_CH1
        dtc_info.p_dest = (void *)DAC_ADDRESS_12_CH1;
#endif
      }
    }
  }

Thanks for your reply, I had tried to look through that, but unfortunately it is not clear to me. Ill get someone more versed in programming to go through it with me, thanks!

You might be interested in this thread
https://forum.arduino.cc/t/arduino-uno-r4-dac-speed/1177741/12

The AnalogWave library is a very poorly written library as it tries to squash the whole wave into one call irrespective of the wave shape. As a result it can't work very fast and the harmonic distribution of the resulting wave changes with the frequency of the wave you are trying to make.

There are better ways of generating audio signals for this processor,

I'm having the same problems - new to coding and unable to increase analogWave from 8 to 12 bit. This is my first contribution and I can't help you sorry, yet I was convinced the whole point of these fora were for people with know how to help other, less experienced people get a better grip, but this place seems like pancakes smothered in treacle - if pancakes were genuine help and treacle was eye-rolling snark.

Anyway, good luck finding a solution or better yet, perhaps you've already found one.

Rob

Hi from France
Just discover this today:

The AnalogWave librarie has a .h file and in this file, the amount of sample is défined, just see:

Here is the orginal .h file:

#ifndef ARDUINO_ANALOG_WAVE
#define ARDUINO_ANALOG_WAVE

#include "FspTimer.h"
#include "r_dtc.h"

#define SAMPLES_FOR_PREDEFINED_WAVE 24
#define WAVE_PRIORITY  1

class analogWave {
private:
  FspTimer timer;
  volatile uint32_t pin;

and now, the modified code:

#ifndef ARDUINO_ANALOG_WAVE
#define ARDUINO_ANALOG_WAVE

#include "FspTimer.h"
#include "r_dtc.h"

#define SAMPLES_FOR_PREDEFINED_WAVE 96
#define WAVE_PRIORITY  1

class analogWave {
private:
  FspTimer timer;
  volatile uint32_t pin;

the line: #define SAMPLES_FOR_PREDEFINED_WAVE 24

Look for the value: 24, this is the number of samples generated to make the wave, you can modify it with values multiples of 4, for my exemple, i've modified it with the value 96, this give me a correct sin wave.

You can test with higher values, limit is the frequency of your wave form.

regards

Olivier

You could add a filter to smooth the bumps out …..

Yes but, better is the sample, less is the filter.....CQFD

Olivier