[pwm]

The Raspberry Pi’s outputs are not capable of directly driving third party devices. If you wish to drive other devices such as tachometers you will likely need relevant circuitry connected to the nominated PWM pin to allow the load to be switched without causing damage to the Pi.

The PWM section allows two Pulse Width Modulated channels (outputs) to be defined, with each channel being driven by any attribute that can normally be accessed by the rest of SDC. This may include attributes that are being sourced via canbus, as well as any Speeduino attribute. but does not include definitions or settings.

The PWM outputs are hardware based, so should be very accurate. An example of an attribute used to drive PWM is RPM. It is possible to generate a square wave output that can be subsequently used to drive an analog type tachometer if you prefer it to a digital one. There are advantages to doing this over using the Speeduino tacho output, because the Speeduino one has some limitations on the available pulse configurations both in terms of frequency and pulse width due to it being a software based output with only a 1 millisecond resolution that is closely related to the ignition firing pattern. You can also obviously use it to generate pulse based outputs for things that speeduino does not support.

PWM’s are defined as follows:

[pwm]
<pwm0|pwm1>=<freq|duty>,<attribute>,<maxval>,<ppu>,<multiplier>,<divider>[,<duty %>]

Where:

  • <pwm0|pwm1> is the name of the PWM channel you want to use. Only the values pwm0 or pwm1 are valid. pwm0 is always output on GPIO18, and pwm1 is always output on GPIO19. These pins are on the header of the SDC I/O hat but may be being used for other devices such as the rotary encoder or TinySDC brightness control. In practice only pwm1 GPIO19 is guaranteed to be free as this is not reserved for any specific use by SDC.
  • <freq|duty> The type of the output. Either freq or duty. If freq is specified then the PWM output is maintained at 50% duty cycle (you can override that), and the frequency of the PWM output is changed using the value of the attribute (after multiplication and division). If duty is specified, then the PWM duty cycle is set based on the value of the attribute after multiplication and division, with the range being defined by the maxval parameter. The specified maxval determines what the frequency will be.
  • <attribute> is the name of a valid attribute whose value is to be used to drive either the frequency or the duty cycle of the PWM output.
  • <maxval> is the maximum value expected and is ONLY used for the ‘duty’ type. It is ignored for the frequency type. In the ‘duty’ mode, if the value of the attribute were to be equal to or above the max value, then the duty cycle becomes 100% i.e. the PWM output is permanently HIGH. Note that higher maximum values in duty mode always result in lower frequencies. For example a maxval of 8000 will produce a square wave with a frequency of around 33hz whose duty cycle will vary up to the specified maximum, whereas a maxval of 1000 will produce a frequency of around 250hz with a more limited range of 1000 different duty values.
  • <ppu> is the “pulses per unit” to be generated. For example, if you were using rpm and knew that a tachometer you wanted to drive required 2 pulses per revolution, then you could set ppu to 2. PPU is only used in freq mode and is ignored in duty mode. PPU really only exists to help with clarity. You could just as easily leave PPU at 1 and use the multiplier to achieve the same thing.
  • <multiplier> The attribute value is multiplied by this value before being applied to the PWM output.
  • <divider> After multipication, the value is divided by this value before being applied to the PWM output.
  • <duty%> The optionally specified duty cycle percentage to be used in the freq mode. This overrides the default 50% duty cycle. This parameter is not used in duty mode where the duty cycle is varied based on the attribute in use.

Example:

[pwm]
pwm1=freq,rpm,0,1,1,1

This defines pwm1 as a frequency based PWM output. The frequency is controlled by the ‘rpm’ attribute. The output will be on GPIO19, with the value of RPM being used directly as the frequency (because 1 pulse per unit is specified, and it is both multiplied by and then divided by 1). At 5000rpm, the frequency of the output will be 5000hz, and the duty cycle will be 50%.

As the type is set to freq the maximum value of zero is ignored.

In the following example:

[pwm]
pwm0=duty,rpm,5000,1,2,3

The other PWM channel (zero) is here defined as an output on GPIO18, whose duty maximum value is 5000. The duty cycle of the output is driven by 2/3rds of the RPM value. Therefore at 7500rpm the duty will reach 100% because 2/3rds of 7500 is 5000. There are limited uses for this kind of output; the frequency based output is probably more useful. You can still use the multipliers and dividers there but they apply to the frequency instead of the duty.

Driving a Tachometer using rpm

This example shows how you can convert an rpm value to a frequency based output which can in theory be used to drive a tachometer, assuming you have relevant external circuitry in place to use the 3.3v square wave signal that SDC generates. It also assumes that the device you are driving works with a frequency based square wave with a duty cycle of 30% (you can change the duty; not specifying it gives 50%). You cannot typically connect such an output directly to another device as it may cause damage to the Raspberry Pi, or at best just not work.

[pwm]
pwm1=freq,rpm,0,2,1,60,30

This pwm output is defined as follows:

  • Type - freq. The output will vary its frequency
  • Attribute - rpm
  • (Maxval of 0 is ignored due to the type being ‘freq’)
  • Pulses Per Unit - 2. This has the effect of doubling the frequency of pulses. It is an example of a typical 4 cylinder 4 stroke engine, which has 2 ignition pulses per revolution.
  • Multiplier - 1. This value has no effect due to the mathematical equivalence of multiplying by 1.
  • Divider - 60. This converts the “revolutions per minute” of the rpm attribute into “revolutions per second”. This is required because we are generating a frequency based output in hertz.
  • Duty percentage - 30%. The square wave will be at a high value for 30% of the cycle and a low value for the other 70%. This overrides the default of 50%. Note that the length of time for the highs and lows varies with the value of the attribute as this is a frequency type PWM.

At 1000rpm, the calculated value will be:

1000 * 2ppu * 1 / 60 = 33.3hz
This will be truncated to 33hz

At a 30% duty this means highs will last approximately 9 milliseconds and lows will last approximately 21 milliseconds.

At 8000rpm, the calculated value will be:

8000 * 2 * 1 / 60 = 266hz (truncated)

Note that at this higher frequency the highs will last only 1.1ms and the lows 2.6ms, at the the 30% duty cycle setting.

Generating a speed based output

pwm1=speedmph,0,48,1,1,freq

This example uses the ‘speedmph’ attribute to get the speed in miles per hour. This is multiplied by a ppu of 48. As the other multipliers and dividers are 1, this results in a frequency based output of 48 * speedmph. So for example at 10mph the frequency will be 480hz. As in other examples, the output will be a square wave with a 50% duty cycle.

Licensing

The freee SDC license limits the available duty cycle to 25% (for the duty type) and the maximum frequency for the freq type to 30hz. This should be sufficient to test any third party devices.