SoftPWM
SoftPWM copied to clipboard
on is not on, i.e pwm of 255 have a short period of 0
"on" is not fully "on", i.e. pwm of 255 have a short period of 0
This is how i patched it to work for my application (DC motor - h-bridge with "break" and "coast" ): Note: My "h-bridge" ic require "full width high" for a "break" and "full width low" for a "coast"
What I did is:
- Reset high and low when "++_isr_softcount == 0"
- Skip "hit width" validation test for "checkval == 0" and "checkval == 255"
see the modified interrupt function below:
{
uint8_t i;
int16_t newvalue;
int16_t direction;
if (++_isr_softcount == 0)
{
// set all channels high - let's start again
// and accept new checkvals
for (i = 0; i < SOFTPWM_MAXCHANNELS; i++)
{
if (_softpwm_channels[i].fadeuprate > 0 || _softpwm_channels[i].fadedownrate > 0)
{
// we want to fade to the new value
direction = _softpwm_channels[i].pwmvalue - _softpwm_channels[i].checkval;
// we will default to jumping to the new value
newvalue = _softpwm_channels[i].pwmvalue;
if (direction > 0 && _softpwm_channels[i].fadeuprate > 0)
{
newvalue = _softpwm_channels[i].checkval + _softpwm_channels[i].fadeuprate;
if (newvalue > _softpwm_channels[i].pwmvalue)
newvalue = _softpwm_channels[i].pwmvalue;
}
else if (direction < 0 && _softpwm_channels[i].fadedownrate > 0)
{
newvalue = _softpwm_channels[i].checkval - _softpwm_channels[i].fadedownrate;
if (newvalue < _softpwm_channels[i].pwmvalue)
newvalue = _softpwm_channels[i].pwmvalue;
}
_softpwm_channels[i].checkval = newvalue;
}
else // just set the channel to the new value
_softpwm_channels[i].checkval = _softpwm_channels[i].pwmvalue;
// now set the pin low (checkval == 0x00) otherwise high
if (_softpwm_channels[i].checkval == 0x00)
{
if (_softpwm_channels[i].polarity == SOFTPWM_NORMAL)
*_softpwm_channels[i].outport &= ~(_softpwm_channels[i].pinmask);
else
*_softpwm_channels[i].outport |= _softpwm_channels[i].pinmask;
}
else
{
if (_softpwm_channels[i].polarity == SOFTPWM_NORMAL)
*_softpwm_channels[i].outport |= _softpwm_channels[i].pinmask;
else
*_softpwm_channels[i].outport &= ~(_softpwm_channels[i].pinmask);
}
}
}
for (i = 0; i < SOFTPWM_MAXCHANNELS; i++)
{
if (_softpwm_channels[i].pin >= 0) // if it's a valid pin
{
// skip hit on checkval 0 and 255
if (_softpwm_channels[i].checkval != 0x00 && _softpwm_channels[i].checkval != 0xFF)
{
if (_softpwm_channels[i].checkval == _isr_softcount) // if we have hit the width
{
// turn off the channel
if (_softpwm_channels[i].polarity == SOFTPWM_NORMAL)
*_softpwm_channels[i].outport &= ~(_softpwm_channels[i].pinmask);
else
*_softpwm_channels[i].outport |= _softpwm_channels[i].pinmask;
}
}
}
}
}