Go Down

### Topic: Simple sketch for "analog" output from digital pins using PDM (Read 1 time)previous topic - next topic

#### P13rrot

##### May 10, 2013, 02:13 am
Hiya all!  XD

I've written a simple function to output analog samples through the arduino uno's digital pins using pulse density modulation.

To use, just call it from the loop() section of your sketch. As it works fully in software, the more times you can call it per second, the better it will work!... heh, heh... hopefully your loop runs really fast

Code: [Select]
`/*    playPdmSample8( pin, sample, sampleRate_ms )        Plays back the appropriate sample on the indicated pin    and returns the number of samples to increment for playback    at the given sample rate.        Maintains data for each pin -- you could use all fourteen at once!    pin              - the digital pin to use as output    sample           - the 8-bit sample to play    sampleRate_ms    - number of samples to play per ***MILLISECOND****/static unsigned long playPdmSample8(int pin, byte sample, unsigned long sampleRate_ms) {    // Pulse density modulation data (pin-dependent)    static byte            err[14]    = {};    static byte            out[14]    = {};        // Sample rate data    static unsigned long   time[14]   = {micros()};   // Relative starting time ***IN MICROSECONDS***    static unsigned long   sampleIncr = 0;            // Number of samples to be incremented to maintain sample rate        sampleIncr = (sampleRate_ms * (micros() - time[pin])) >> 10; // The bit shift is a hackish divide-by-1000        if(sampleIncr >= 1) {        // Output a sample using pulse density modulation                if(sample > err[pin]) {            if(out[pin] == 0) {                digitalWrite(pin, HIGH);                out[pin] = 255;            }        } else {            if(out[pin] == 255) {                digitalWrite(pin, LOW);                out[pin] = 0;            }        }                err[pin] += (out[pin] - sample);                        // Reset the time        time[pin] = micros();    }        return(sampleIncr);}`

Hopefully you find this marginally useful or at least marginally interesting!

#### P13rrot

#1
##### May 10, 2013, 02:28 am
Just a demo  :

Code: [Select]
`const int    LED = 13;byte         sinLUT[256];void setup() {    pinMode(LED, OUTPUT);        for(long i = 0; i < sizeof(sinLUT); i++) {        sinLUT[i] = (255.0 * (sin((6283.0 * i) / ((sizeof(sinLUT)-1) * 1000.0)) + 1.0)) / 2;    }}void loop() {    // output at 1 kHz sample rate    playPdmSample8(LED, sinLUT[byte(millis() >> 2)], 1);}/* ... code for the playPdmSample8 function ... */`

You should see your onboard LED fade at a 1 Hz sine wave

Go Up

Please enter a valid email to subscribe