Another treadmill controller question

hi there . I'm real new to the Arduino , though I've been trying to read & learn . I have a project that I would like to try & need some input on which Arduino I would need for the project .Like the title says I would like to be able to control a treadmill motor with a MC2100 treadmill controller board using a Arduino . What I would like to have is a 4 x 4 keypad that I can punch in my desired speed to , & have a tach with feedback to keep the motor at set speed & read the set & actual speed on a display , & if possible have a relay in there that can reverse the motor direction by using one of the non number keys on the keyboard .
I have seen some conversations about a project like this but not with all the functions I would like to have .
The MC2100 has PWN input so I know that I can get PWM out of a Arduino . I have a few UNO's, will they be powerful enough for this project or should i get a different Arduino ?
thank you
Animal

I'll answer your last question first.
Yes.

On the other hand, unless you provide the datasheet or schematic for the "MC2100 treadmill controller board", no one is going to be able to help you.

Thank you Steve , here's a reversed engineered schematic , I will try to find more info tomorrow
animal

my treadmill uses a simple pot to change speed.
I use a hand controlled pot and I did look at using a motor controlled pot.
decided there was no benefit on my lathe for speed control.

for PWM, you need to use a optoisolator so you do not share any wires between the two boards.
lots of people have done what you ask, but with discrete parts. RPM display, speed control, etc.

if you google, there are some 555 circuits that PWM for that motor driver. You can replace that 555 circuit with one PWM out from the Arudino.

Motor RPM is best with an actual tacho, reflective paint, IR sensor, also well documented for Arduinos.

I would highly suggest you search this forum for treadmill as this does come up a couple times a year.

I have that controller board and most of the info I found on it came from this blog:MC-2100 Motor Controller | Sons of Invention

It's been a long time since I messed with it but I did write a program that gives the correct 20 hz PWM that it requires that I would be glad to share.

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

   VERSION: 0.0.1

   IDE VERSION: 1.8.9

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

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

// ================= VARIABLES ================
uint16_t dutyCycle;


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

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

  init20hzPWM();

}// End setup()


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

void loop()
{
  getDutyCycle();
  applyDutyCycle();

}// End loop()


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

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


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

void applyDutyCycle()
{
  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()
{
  constexpr uint16_t PRESCALER = 64; // clock divisor
  constexpr uint16_t FREQUENCY = 20; // Herz
  constexpr uint16_t TOP_COUNT = F_CPU / PRESCALER / FREQUENCY / 2; // Formula derived from Secrets of Arduino PWM (http://www.righto.com/2009/07/secrets-of-arduino-pwm.html)

  // Set prescaler to /64
  TCCR1B |= (1 << CS10) | (1 << CS11);

  //TCCR1A |= (1 << WGM10) | (1 << WGM11); // Set WGM mode 11 - phase correct pwm using OCR1A as TOP
  TCCR1A |= (1 << WGM11);                  // Set WGM mode 10 - phase correct pwm using ICR1 as TOP
  TCCR1B |= (1 << WGM13);
  //OCR1A = TOP_COUNT;
  ICR1 = TOP_COUNT;
  
  //TCCR1A |= (1 << COM1A1) | (1 << COM1B1); // Set Timer1 to output on pins 9(OC1A) and 10(OC1B), WGM mode 11
  TCCR1A |= (1 << COM1A1);                   // Set Timer1 to output on pin 9(OC1A), WGM mode 10

  // setting OCR1x applies dutyCycle
  //OCR1B = dutyCycle; // output on pin 10, pin 9 tied up, WGM mode 11
  OCR1A = dutyCycle;   // output on pin 9, WGM mode 10

}// End init20hzPWM()

// ================================================================
// *                           map2()                             *
// * bperrybap https://forum.arduino.cc/index.php?topic=417690.30 *
// ================================================================

int32_t map2(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max)
{
  if( x == in_max)
    return out_max;
  else if(out_min < out_max)
    return (x - in_min) * (out_max - out_min+1) / (in_max - in_min) + out_min;
  else
    return (x - in_min) * (out_max - out_min-1) / (in_max - in_min) + out_min;
} // End map2()

EDIT: I should of cleaned that prog up a little but it will have to wait gotta go to work.

Here's info on the motor controller & board pinouts . yea , you can run a MC 40 or MC 80 with just a pot , 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

ok the PDF didn't get through , lets try again
animal

ok the PDF didn't get through , lets try again
animal

MC-2100.pdf (146 KB)

MC-2100.pdf (146 KB)

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()

Thanks Hutkikz , I'll try to mess with it this weekend
animal