Another treadmill controller question

animal12:
but the MC 2100 needs some sort of PWM input & I would like to see if I could do one with a few more bells & whistle's
thanks
animal

Specifically The MC-2100 requires a 20hz PWM which is not the default frequency of the Arduino.
That's why I wrote this program that sets up timer 1 to output the correct frequency. Currently it uses a pot for input control but you can modify the getDutyCycle() function to accept any kind of input you like everything else can remain unchanged.

Here is a cleaned up version of the code I posted earlier as promised:

/* ================= HEADER ==================
   PROJECT: Treadmill motor speed Control
            Using a MC-2100 controller that requires a 20 hz phase correct 
            PWM signal with a 0-85% dutycycle
            Output is on Pin 9

   VERSION: 0.0.2

   IDE VERSION: 1.8.9

   HARDWARE: Uno/Nano (328p)
             Potentiometer
             MC-2100 REV.B Motor Controller
             Treadmill Motor
*/

// ================= CONSTANTS ================
constexpr uint8_t PWM_PIN = 10;
constexpr uint8_t SPEED_POT = A0;

// ================= VARIABLES ================


// ================================================================
// *                              SETUP                           *
// ================================================================

void setup()
{
  pinMode(PWM_PIN, OUTPUT);

  // Initializes timer 1 to produce a 20 hz pwm
  init20hzPWM();

}// End setup()


//============================================================
// *                       MAIN PROGRAM LOOP                      *
//============================================================

void loop()
{
  applyDutyCycle(getDutyCycle());
  
}// End loop()


//============================================================
// *                       getDutyCycle()                         *
//============================================================

uint16_t getDutyCycle()
{
  constexpr uint16_t MIN_DUTY = 0;
  constexpr uint16_t MAX_DUTY = 5300; // 85% of TOP_COUNT
  uint16_t rawPot = analogRead(SPEED_POT);
  uint16_t dutyCycle = map(rawPot, 0, 1023, MIN_DUTY, MAX_DUTY);
  return dutyCycle;
}// End getDutyCycle()


//============================================================
// *                       applyDutyCycle()                       *
//============================================================

void applyDutyCycle(uint16_t dutyCycle)
{
  static uint16_t oldDutyCycle;
  if (oldDutyCycle != dutyCycle)
  {
    OCR1A = dutyCycle; // setting OCR1x applies dutyCycle
    oldDutyCycle = dutyCycle;
  }
}// End applyDutyCycle()


//============================================================
// *                       init20hzPWM()                          *
// *  Set up Timer1 for 20hz phase correct PWM output on pin 9    *
//============================================================

void init20hzPWM()
{
  // clock divisor
  constexpr uint16_t PRESCALER = 64;

  // Desired Frequncy in Herz
  constexpr uint16_t FREQUENCY = 20; 
  
  // Formula derived from Secrets of Arduino PWM 
  // (http://www.righto.com/2009/07/secrets-of-arduino-pwm.html)
  constexpr uint16_t TOP_COUNT = F_CPU / PRESCALER / FREQUENCY / 2; 

  // Set prescaler to /64
  TCCR1B |= (1 << CS10) | (1 << CS11);
  
  // Set WGM mode 10 - phase correct pwm using ICR1 as TOP
  TCCR1A |= (1 << WGM11);  
  TCCR1B |= (1 << WGM13);
  ICR1 = TOP_COUNT;

  // Set Timer1 to output on pin 9(OC1A)
  TCCR1A |= (1 << COM1A1); 

  // setting OCR1x applies dutyCycle
  // initialize to 0(off)
  OCR1A = 0;   // output on pin 9, WGM mode 10

}// End init20hzPWM()