16-Bit DAC / PWM on Arduino UNO - Ec-Projects

Поделиться
HTML-код
  • Опубликовано: 27 окт 2024

Комментарии • 57

  • @olivercouch1651
    @olivercouch1651 6 лет назад +2

    I have also been building my own ADC, and looked into this method. It is possible to change the PWM frequency by changing the timer prescale values, which allows you to decrease your settling time while maintaining a low voltage ripple. There are 3 timers in the Arduino, and one of them is used for a lot of timing functions, so changing that one is a difficult option, but the other two can get you ~32kHz at 16MHz clock speed. Much better than the 470Hz default!

  • @phantom349uj
    @phantom349uj 8 лет назад +3

    thank you for this wonderful idea. I'm using this out this output to a transistor base in order to modulate a 4 to 20 milliamp source for a DIY industrial control calibrator. I'll post my kicad drawing in a month or so when I'm finished

  • @caall99
    @caall99 10 лет назад +1

    Excellent video explaining the implications of using PWM and RC filters for a precision voltage source! Thank you!

    • @EcProjects
      @EcProjects  10 лет назад +1

      caall99 Thank you :) And you are welcome !!!

  • @raykent3211
    @raykent3211 9 лет назад +2

    Very interesting and thorough, thanks. A couple of points. You could probably reduce the spikes you got when using bigger capacitors on the 8-bit outputs by putting a capacitor on the final output. Secondly, I'm surprised you got a good result from your first attempt... luck? The voltage change between on and off states for the most significant bit is about 64000 times more significant than that of the least significant bit, for 16 bit accuracy. So if switching the lsb makes a difference of 1mV, switching the lsb should make a difference of 64V !!! Even if you can get an accuracy of 100 microvolt on the lsb, you still need a swing of 6.4 V on the msb, more than an arduino output. I don't think you can buy resistors for your circuit that are accurate to one part in 64000, so this approach involves patching together several close tolerance, high stabilty resistors ad hoc. Last but not least, you can get an accuracy way beyond 16-bit from an arduino uno in other domains.... (eg connect it to internet for timing error of 1 second in 10 years or more.... ha ha ). Hope your later work with dac chips turned out well!

  • @keninorlando9
    @keninorlando9 10 лет назад +1

    I wound up using an I²C DAC myself - just made life a lot simpler. No matter how much software voodoo I tried I could not get tight fixed current using PWM but had hoped for a little better results. Either too much ripple or too slow reaction time. I wish the AT chip had a real DAC built in as well as 16 bit or high ADC. Oh, well, can't have everything.
    Years ago I'd write PWM routines for the PC parallel port, but that's another topic for another system.

    • @BenjaminEsposti
      @BenjaminEsposti 9 лет назад

      From what I've heard, it is very very difficult to get higher than 12 bits DAC/ADC in an MCU because of digital noise, and chip layout. Might be some other reasons as well.

    • @talktalktalktalktalk
      @talktalktalktalktalk 9 лет назад

      what dac did you use?

    • @agonymobile
      @agonymobile 9 лет назад

      Benjamin Esposti how about raise the frequency of pwm to max prescaler and use timer 1 which is already 16 bit resolution.
      Read more about it to understand how you can set that..

  • @RAM9031
    @RAM9031 9 лет назад +1

    Verdaderamente ingenioso me gusta tu razonamiento. Gracias por tu aporte!

  • @taz0k2
    @taz0k2 8 лет назад +5

    I am guessing that you used the AnalogWrite function? The Arduino libraries are easy to use at first, but it's many times better to directly set the registers. The AnalogWrite function contains a "hack" that creates your problem. Setting a value of 0 into the PWM register gives a duty cycle of 1/256, a value of "n" gives (n+1)/256. The Arduino dudes didn't like that behavior, because they thought that a value of 0 should give a duty cycle of 0/256!! Exactly there lies the problem. So AnalogWrite(0) gives a duty cycle of 0/256, but for all other values it has the same behavior as setting the register directly i.e. AnalogWrite(n) gives duty cycle of (n+1)/256.

    • @taz0k2
      @taz0k2 8 лет назад +1

      +taz0k2 Essentially they just added a simple if-case for the zero case: "if zero then just put the pin LOW". Not very intuitive imho. Also explained here: www.righto.com/2009/07/secrets-of-arduino-pwm.html just above the Troubleshooting subheading.

  • @rashmiranjannayak3251
    @rashmiranjannayak3251 5 лет назад

    Perfect work and genius out put. Thanks for sharing.

  • @y2ksw1
    @y2ksw1 Год назад

    Interesting approach!

  • @TooSlowTube
    @TooSlowTube 2 года назад

    15:50 You could remove the spike caused by the LSB PWM output going to zero, by removing the capacitor for that output. The other capacitor is on the total output of the combined signal, so that should be enough.
    You could also reduce the amplitude of the ripple by increasing the PWM frequency, keeping the same capacitor value. I'm not sure if you said what it was - if so, I missed it.

  • @michaelwilkes0
    @michaelwilkes0 2 года назад

    the analogwrite function jumps from 0 to 2, skipping 1. you cannot set the duty cycle to 1. this is by design because of a quirk about the fastpwm mode on these atmega chips. the hardware can be set to 1, but it cant be set to 0. you cant get 0% duty cycle. the Arduino team decided 0% duty cycle was more important so they just disable the pwm at 0 and then skip the first value. i agree with their decision. you CAN get the pwm to honor all values correctly if you change the mode from fastpwm to phase correct pwm which is what i usually do. its a little harder. you have to read the chip manual and setup the timer registers yourself and you can't use the analogwrite function any more. you have to change the output compare register value to adjust the duty cycle. its not necessarilly hard, but if you're at novice level you might not want to dive that deep. honestly i wish arduino would just make phase correct mode the default instead of fastpwm. i cant really think of any downside to that.

  • @omarhalabi9200
    @omarhalabi9200 10 лет назад +4

    This is why you have a problem:
    The PWM outputs generated on pins 5 and 6 will have higher-than-expected duty cycles. This is because of interactions with the millis() and delay() functions, which share the same internal timer used to generate those PWM outputs. This will be noticed mostly on low duty-cycle settings (e.g 0 - 10) and may result in a value of 0 not fully turning off the output on pins 5 and 6.
    arduino.cc/en/Reference/AnalogWrite

    • @EcProjects
      @EcProjects  10 лет назад +1

      ***** Thanks, I will have to look into that.. :)

    • @atmark666
      @atmark666 8 лет назад

      +EcProjects Increase PWM bit resolution
      arduino.stackexchange.com/questions/12718/increase-pwm-bit-resolution

  • @iamNaddy_
    @iamNaddy_ 2 месяца назад

    Can I have the source code ? I tried to refer to the website you have provided but I couldn't download the code

  • @bbreeuwer4577
    @bbreeuwer4577 8 лет назад +1

    Why not using a 2nd order Sallen Key output filter?
    That way your ripple is much lower and your filter is much faster.

  • @Neo55378008
    @Neo55378008 10 лет назад +1

    Awesome video! Did you ever figure out what caused that jump on the first high bit?
    Have you tried an R-2R latter between the two outputs to weight it? I'm curious if that would be better or worse.

    • @EcProjects
      @EcProjects  10 лет назад +1

      Neo55378008 Hey! Thanks :) I didn't look further into it. Just an idea that came to my mind which I wanted to try out :) Nope haven't tried the R 2R :)

  • @tbilal11201
    @tbilal11201 2 года назад

    hello, sorry the link you given is not there anymore? could you please reupload that code?😁

  • @acatisfinetoo3018
    @acatisfinetoo3018 2 года назад

    Is there any chance this would work for 16 bit audio? i know it's hacky, but would this be fast enough for 16 bit PCM...like sending 8 bit samples on timers at the same time. would be interesting to know.

  • @zaneenaz4962
    @zaneenaz4962 2 года назад

    Hi ....where can i see the source code ?? your link is dead

  • @rchandos
    @rchandos 3 года назад

    You might try eliminating the spiké by connecting a diode across the 1k resistor.

  • @HakAtIt
    @HakAtIt 3 года назад

    Thank you !

  • @soumendrasingh1
    @soumendrasingh1 8 лет назад

    What should be the pulse width and duty cycle of the PWM output?

  • @protonspeed
    @protonspeed Год назад

    Why don't you just use Timer 1 for 16 bit PWM output.

  • @DiegoSynth
    @DiegoSynth 4 года назад

    FANTASTIC!!! Thank you very much for this :)

  • @caall99
    @caall99 10 лет назад

    Could you pull another Arduino 8 bit PWM IO pin into this project? Effectively making a 24 bit DAC? I would like to experiment with making a precision voltage source, settling time of the RC filter is a non-issue. Also, is your code available for download? Thanks!

    • @EcProjects
      @EcProjects  10 лет назад

      caall99 Hello ! In theory you could do that, but in practice it will be very difficult :) You will have to get all the resistor values 100% exact. And there is probably too much noise on the PWM :)But hey, still worth a try :) I have put a link to the source code in the video description. :)

  • @motormadness9975
    @motormadness9975 5 лет назад

    Whats wrong with using the 16bit pwm timer that the atmega328 has on it? I dont get the point of this

    • @CIOWhitepapers
      @CIOWhitepapers 4 года назад

      Did you ever find an answer to that question? Perhaps the same principle can be applied to attiny85 type chips with only 8bit timer?

    • @odissey2
      @odissey2 2 года назад

      Because the Timer period becomes too long, unusable for audio, for example: 16MHz / 2^16 = 244Hz. Harder to filter out such low frequency either.

  • @odissey2
    @odissey2 2 года назад

    It is not possible to achieve 16 bit DAC output using PWM from uC pins. 10-12 bits max. Any videos on this matter must be supplemented with INL/DNL curves as a matter of proof.
    Notice that the power to the uC is provided by USB bus, which level varies considerably and inherently noisy. Just move PC mouse to see 50mV jumps!

  • @fugaku1480
    @fugaku1480 3 года назад

    言葉は分かりませんが、たいへんおもしろいアイデアの動画でした。

  • @danz9810
    @danz9810 6 лет назад

    I bet the initial too-large jump is because you're using a fast PWM timer (rather than phase correct PWM). Fast PWM has a period of 256 ticks but you can only specify a duty of 255. Arduino "corrects" this by switching the output off when you choose duty=0, but setting the duty to N+1 when you specify duty=nonzero N. If I'm right, it will be corrected if you use timer 1 or 2 (move the pin 6 connection to pin 9, 10, 11, or 3). See www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM

  • @poweredbysergey
    @poweredbysergey 7 лет назад

    Cool!

  • @caall99
    @caall99 10 лет назад

    Ahhhh... looks like you took down your source code! Can you upload again? Working on my 24 bit variant as i type this. Thanks.

    • @EcProjects
      @EcProjects  10 лет назад

      There is an .ino file at the bottom of the page ?

    • @caall99
      @caall99 10 лет назад

      EcProjects
      Its back now. i think the link was down for a little. thanks!

    • @caall99
      @caall99 10 лет назад

      EcProjects Would you be able to link to pre-bug fixed version of your file? I am trying to learn bit shifting and don't quite understand how to combine two outputs to increase resolution. If my input is a number between 0-65535 (16 bit), how can i make one output do the high 8 bits and the other the low 8 bits. Confused.

    • @caall99
      @caall99 10 лет назад

      caall99 I figured it out :) had to looking into binary parallel summing.

    • @EcProjects
      @EcProjects  10 лет назад

      I don't think I have that file any more sorry :(

  • @albertjansen5996
    @albertjansen5996 6 лет назад

    You put 8 bits (255 steps) in to 1 (lager step)bit, then you have 64 bits (8x8)?? not 16! NO that's not right. 256*(8+1)=2304 steps in total = a resolution of 11 bits + some spare I think?.( I'm confused now lol) and you have to put a capacitor at the output, not on the separate outputs!

    • @jsaturnus
      @jsaturnus 6 лет назад +3

      when raising to a power you must add exponents. So 2^8 x 2^8 = 2^16 (= 16bit)
      basic math ;)

  • @subhadipghorui2216
    @subhadipghorui2216 6 лет назад

    Can yyou read analog signal with pwm digital pin.?

  • @habiks
    @habiks 9 лет назад

    dac/pwm? that's 2 different things..

  • @talashganvir4144
    @talashganvir4144 5 лет назад

    can any give me code for avr