I am currently implementing the following setup:
Arduino Mega 2650 -- DRV8834 -- Stepper motor
Everything works fine, however since it can provide a higher torque I want to run the stepper in half step mode. Each step is triggered by a single pulse coming from the Arduino to the driver. If one uses the Digital Pins for this purpose as done by AccelStepper, the maximum frequency is around 1000 pps (points per second). This is a third of what I want to achieve. The second option would be to use the PWM of the Arduino which naturally runs at 16 MHz (way to high). There is a way to downgrade this frequency, however the steps are only discrete and not accurate enough for a nice speed control.
Therefore I want to do the following
Arduino Mega 2650 -- Controller -- DRV8834 -- Stepper motor
whereby the Controller is creating a PWM with a frequency (100 to 3000 Hz) depending on some signal coming from the Arduino (I2C, voltage level or something else). I was now searching two days for a component and have no clue what I could use.
How can I create a PWM from 100 to 3000Hz with an arduino?
Edit 1: I have to read out sensors while the motor is running. Therefore, the so called "bit banging" PWM
void loop(){
digitalWrite(pinSTEP, HIGH);
delayMicroseconds(T/2);
digitalWrite(pinSTEP, LOW);
delayMicroseconds(T/2);
}
where T = 1 / f is not feasible since I have to read out a sensor in the loop which destroys the motor timing.
Edit 2: There is a method to change the register of the timers. One can adapt a so called prescalar values (from 0 to 7) which will define the frequency of our PWM. However with only seven discrete steps this leads to the following freuquencies:
prescalar = 1 ---> PWM frequency is 31000 Hz
prescalar = 2 ---> PWM frequency is 4000 Hz
prescalar = 3 ---> PWM frequency is 490 Hz (default value)
prescalar = 4 ---> PWM frequency is 120 Hz
prescalar = 5 ---> PWM frequency is 30 Hz
prescalar = 6 ---> PWM frequency is <20 Hz
which is not sufficient for my application.
For more about this method:
- http://usethearduino.blogspot.ch/2008/11/changing-pwm-frequency-on-arduino.html
- http://forum.arduino.cc/index.php?topic=72092.0
Sometimes a solution is so easy that it hurts ;) Based on the input of this wonderful community I found my solution. Code:
#include <TimerThree.h>
// TimerThree PWM Pins 2, 3, 5
#define pinPWM 2
#define pinM0 22
#define pinM1 24
#define pinSleepnot 28
#define pinDir 30
void setup(void){
// Define output pins
pinMode(pinM0, OUTPUT);
digitalWrite(pinM0, HIGH);
pinMode(pinM1, OUTPUT);
digitalWrite(pinM1, LOW);
pinMode(pinSleepnot, OUTPUT);
digitalWrite(pinSleepnot, HIGH);
pinMode(pinDir, OUTPUT);
// Initialize serial communication
Serial.begin(9600);
}
void loop(void){
for (float frequency = 500; frequency < 3000; frequency = frequency + 1) {
float T = 1 / frequency * 1000000;
Serial.print("Frequency: ");
Serial.println(frequency);
Timer3.initialize(T);
Timer3.pwm(pinPWM, 100);
delay(5);
}
}