RoboDurden / Esp32_20A_80V_dcdc

20A 80V dcdc/mppt with Esp32 and touch display
MIT License
0 stars 1 forks source link

10bit and 12bit dac with Esp32 ledcWrite() #2

Open RoboDurden opened 5 months ago

RoboDurden commented 5 months ago

I did some testing today to go from 8bit dac to 10bit or 12bit. As the dac_2 does not work on my S2 Minis, i already had to use pwm and a 100 nF low pass anyway. So i tested this PIN_DACout with higher bit ranges:

Here 10 bit with 10,000 Hz: DAC 10 bit 10000 Hz

For 12 bit the frequency must be reduced to 5000 Hz, otherwise ledcAttach(PIN_DACout, DAC_Freq, DAC_Bits) will fail: DAC 12 bit 5000 Hz

14 bit only succeeds at 2000 Hz but i guess that would need a 1 uF low pass: DAC 14 bit 2048 Hz

@AILIFE4798, you need an opamp when you want to drive something like a loudspeaker. I am still confident that the max 40mA source- and 28mA sink-currents of the Esp32S2 are enough to control the feedback inputs(!) of the LT8705

Here the Arduino test code. 'f5000' sent from the terminal will change frequency to 5000 Hz, 'b8' will set the bit range to 8:


#define ESP32_CORE3  // new 3.0.x Espressif Arduino Core needs differet ledc functions :-/

#define SERIALDEBUG Serial  // uncomment to disable Serial 115200 baud debug output
#ifdef SERIALDEBUG
  #define OUT2T(s,i)  {SERIALDEBUG.print(s);SERIALDEBUG.print(": ");SERIALDEBUG.print(i);SERIALDEBUG.print("  ");}
  #define OUT2N(s,i)  {SERIALDEBUG.print(s);SERIALDEBUG.print(": ");SERIALDEBUG.print(i);SERIALDEBUG.println();}
#else
  #define OUT2T(s,i)
  #define OUT2N(s,i)
#endif

#define PIN_DACin   17
#define PIN_DACout 18
#define LED_BUILTIN 16

#define DAC_Freq 5000
#define DAC_Bits 12

uint8_t iBits = DAC_Bits;
uint32_t iFreq = DAC_Freq,iFreqSet;

#define CHANNEL_DacOut 0  // Arduio ESP32 Core 2.x needs channel

void DacChange()
{
  #ifdef ESP32_CORE3
    iFreqSet = ledcChangeFrequency(PIN_DACout, iFreq, iBits);
  #else
    iFreqSet = ledcSetup(CHANNEL_DacOut, iFreq, iBits);  // configure LED PWM functionalitites
    ledcAttachPin(PIN_DACout, CHANNEL_DacOut);  // attach the channel to the GPIO to be controlled
  #endif
}

void DacSetup()
{
  #ifdef ESP32_CORE3
    iFreqSet = ledcAttach(PIN_DACout, iFreq, iBits);
  #else
    iFreqSet = ledcSetup(CHANNEL_DacOut, iFreq, iBits);  // configure LED PWM functionalitites
    ledcAttachPin(PIN_DACout, CHANNEL_DacOut);  // attach the channel to the GPIO to be controlled
  #endif
}

void DacWrite(uint32_t iOut)
{
  #ifdef ESP32_CORE3
    ledcWrite(PIN_DACout, iOut);
  #else
    ledcWrite(CHANNEL_DacOut, iOut );
  #endif
}

void setup() 
{
  Serial.begin(115200);

  // Initialize pins as LEDC channels 
  // resolution 1-16 bits, freq limits depend on resolution, channel is automatically selected
  //ledcAttach(PIN_DACout, 10000, 8); // 10 kHz PWM, 8-bit resolution

  pinMode(LED_BUILTIN,OUTPUT);

  DacSetup();

}

#define TIME_Display 500
unsigned long iNow,iTimeDisplay=0;
void loop() 
{
  //OUT2T("iFreq",iFreq)
  iNow = millis();
  digitalWrite(LED_BUILTIN,iNow%1000<500 ? 1 : 0);

  if (Serial.available())
  {
    String s = Serial.readStringUntil('\n');
    OUT2T("serial input",s)
    char c = s.charAt(0);
    s = s.substring(1);
    switch(c)
    {
      case 'f':  iFreq = s.toInt();   OUT2T("set new frequency",iFreq)  break;
      case 'b':  iBits = s.toInt();  OUT2T("set new bit resolution",iBits)  break;
    }
    DacChange();
  }

  uint32_t iRange = (2 << (iBits-1));
  uint32_t iOut = (micros()/100) % iRange;

  DacWrite(iOut);

  if (iNow < iTimeDisplay)
    return ;
  iTimeDisplay = iNow + TIME_Display;

  OUT2T("Hz 'f'", iFreqSet)  OUT2T("bits 'b'",iBits)  OUT2N("range",iRange)
}
RoboDurden commented 5 months ago

If 30 mA would be the max current of the dac pin, then the low pass resistor should not be smaller than 3V/0,03A = 100 Ohm. I am using R10=12k + R11=0.9k = 12.9k and can control the output voltage from 27.6V to 58.8V. That is a range of 31.2 Volt, divided by 255 steps gives a resolution of 0.12 Volt, that currently needs to be shifted with the original potentiometer on the dcdc module if you would want to charge a 12 Volt battery..

I can easily go to 10 bit and would have a step size of 0.03 Volt. 12 bit and i had 7.7 mV

And reducing R10 to 3.3k might already give the full range from 1.4V to 79V. Which should increase the step size to 0.1V at 10bit and 0.023V for 12 bit. The dac would then cover a greater voltage range.

grafik

RoboDurden commented 5 months ago

grafik

grafik

I-hate-2FA commented 5 months ago

for refrence,this is a schematic of a dps5005 power supply https://github.com/kanflo/opendps/blob/master/hardware/reverse-engineering/dps3003/DPS3003.pdf