beagleboard / bonescript

Scripting tools for the BeagleBoard and BeagleBone
http://beagleboard.org
MIT License
32 stars 9 forks source link

Smooth PWM output #30

Closed jadonk closed 4 years ago

jadonk commented 6 years ago

From @colinbes on August 27, 2014 15:55

In my application I am sweeping frequencies using the pwm outputs. In order to meet duty-cycle and period value requirements the present library (in version 0.2.4) perform a hard write of '0' to duty cycle before writing the period value. In my case this is causing a noticeable effect on out frequency due to setting duty-cycle to zero.

I added my own pwm analog write function that seems to satisfy the register requirements and provides a much smoother frequency transition when changing frequencies.

I did fork the bonescript project with intention of recreating project and then doing a pull request but I couldn't figure out how install my modified bonescript project locally so I thought to just post the code snippet here (if you have a document/suggestions on how to use forked project and install it I'd be happy to assist but it's not essential my end).

I'd like to suggest a change to pwm write plus adding an addition of enablePWM function as the method of writing a zero duty cycle doesn't work as expected (as per one of earlier posts, when writing a duty-cyclle of zero I still see narrow glitches on output pin).

Here's suggested code snippets - note I have simply read the current state of pin for comparison, I am not sure on cost penalty of doing this. I originally stored the value (much like the path is stored) but realized it may easily get out of sync.

/**
 * Enable/Disable PWM output
 * params: pin to set, 
 *         enable = true enables pwm, false disables pwm output
 */
exports.enablePWM = function(pin, enable, resp) {
    var path = pwmPrefix[pin.pwm.name];
    try {
        if (enable===true) {
            fs.writeFileSync(path+'/run', 1)
        } else {
            fs.writeFileSync(path+'/run', 0);
        }
    } catch(ex) {
        resp.err = 'error updating PWM freq and value: ' + path + ', ' + ex;
        winston.error(resp.err);
    }
    return(resp);
};

/**
 * Write PWM
 */
exports.writePWMFreqAndValue = function(pin, pwm, freq, value, resp) {
    var path = pwmPrefix[pin.pwm.name];
    try {
        var period = Math.round( 1.0e9 / freq ); // period in ns
        var duty = Math.round( period * value );

        var currentDuty = fs.readFileSync(path+'/duty')
        var currentPeriod = fs.readFileSync(path+'/period')

        if (period > currentDuty) {
            fs.writeFileSync(path+'/period', period)
            fs.writeFileSync(path+'/duty', duty)
        } else if (duty < currentPeriod) {
            fs.writeFileSync(path+'/duty', duty)
            fs.writeFileSync(path+'/period', period)        
        } else {
            //safety net
            fs.writeFileSync(path+'/duty', 0);
            fs.writeFileSync(path+'/period', period);
            fs.writeFileSync(path+'/duty', duty);
        }

    } catch(ex) {
        resp.err = 'error updating PWM freq and value: ' + path + ', ' + ex;
        winston.error(resp.err);
    }
    return(resp);
};

More than happy to assist where I can.

Copied from original issue: jadonk/bonescript#94

jadonk commented 6 years ago

Thanks!