Someone on this forum posted the below drawing about 3 years ago with questions about choosing the correct power source.
The DC motor I am using is not robust enough to handle the load of a small propeller, so I am considering moving to a LIPO/brushless motor setup. I am a RC flyer so I am familiar with the ESC/BEC with the typical input of the data pulse to the ESC is between 1000uS (zero power) to 2000uS (full power). I have two questions.
How do I setup the PWM output in the code, say pin 9, where the width of the pulse indicates the desired power level (1mS to 2mS)?
The earlier OP was told to use a separate power supply to supply 5v to the arduino. Why, if the output of the BEC on the ESC is 5v?
Thanks for your time.
Just use the servo library. It generates the required signal on ANY digital pin, and that pin does not need to have PWM.
Maybe because of noise in the power supply but that's just my suggestion.
Here is an answer I just posted that addresses your question.
In Arduino, the frequency and duty cycle of PWM (Pulse Width Modulation) signals can be adjusted using various timers and settings, depending on the pins you are working with. Below, I will outline the general concepts and formulas for setting the frequency and duty cycle on an Arduino UNO.
PWM Frequency and Duty Cycle on Arduino UNO
The Arduino UNO uses Timer0, Timer1, and Timer2 to generate PWM signals on different pins. Each timer has different default settings and capabilities.
1. Frequency Calculation:
The frequency of the PWM signal depends on the clock speed of the microcontroller and the settings of the timer's prescaler and TOP value. The general formula for calculating the PWM frequency is:
Frequency=Clock SpeedPrescaler×(TOP+1)\text{Frequency} = \frac{\text{Clock Speed}}{\text{Prescaler} \times (\text{TOP} + 1)}Frequency=Prescaler×(TOP+1)Clock Speed
- Clock Speed: The default clock speed for the Arduino UNO is 16 MHz (16,000,000 Hz).
- Prescaler: This value determines how much the clock speed is divided. Common prescaler values are 1, 8, 64, 256, and 1024.
- TOP: The maximum value the timer counts to before resetting. In the default fast PWM mode on Arduino, TOP is typically 255.
2. Duty Cycle Calculation:
The duty cycle is the proportion of the PWM period that the signal remains HIGH. It is usually expressed as a percentage.
Duty Cycle (%)=(PWM ValueTOP)×100\text{Duty Cycle (%)} = \left(\frac{\text{PWM Value}}{\text{TOP}}\right) \times 100Duty Cycle (%)=(TOPPWM Value)×100
- PWM Value: The value set using
analogWrite()
. For an 8-bit timer, this can range from 0 to 255. - TOP: For an 8-bit timer, this is 255 by default.
Example: Setting PWM Frequency and Duty Cycle on Arduino UNO
Here's an example of how to adjust the frequency and duty cycle using Timer1, which controls pins 9 and 10.
void setup() {
// Set pin 9 as output
pinMode(9, OUTPUT);
// Set Timer1 to Fast PWM mode, 8-bit
TCCR1A = _BV(WGM10) | _BV(COM1A1);
TCCR1B = _BV(WGM12) | _BV(CS11); // Set prescaler to 8
// Set Duty Cycle: 50%
OCR1A = 128; // 50% of 255
}
void loop() {
// Nothing needed here; PWM is handled by Timer1
}
Explanation of the Example:
TCCR1A
andTCCR1B
: These registers configure Timer1's mode and prescaler._BV(WGM10)
and_BV(WGM12)
: Set Timer1 to Fast PWM, 8-bit mode._BV(CS11)
: Sets the prescaler to 8.OCR1A = 128;
: Sets the duty cycle to 50% (128/255).
Key Points:
- Changing the prescaler will affect the frequency.
- Adjusting
OCR1A
will change the duty cycle.
Using these formulas and adjusting the timer registers will allow you to set the PWM frequency and duty cycle on the Arduino UNO according to your requirements.
I am a beginner and I am trying to take a sketch (code) that worked on a DC motor, but need to upgrade to a brushless motor and now need servo control to increase and decrease the motor RPM. I want to merge the bottom code (example sketch) into the below code and I feel like I am trying to put simple code into advanced code and am not sure how to proceed. A big thanks to LarryD for the major help with this project. The code that is currently working is here:
//
//================================================^================================================
//
// https://forum.arduino.cc/t/timer-or-push-button-to-trigger-motor/1298664/2
//
//
//
// Version YY/MM/DD Comments
// ======= ======== ========================================================================
// 1.00 24/09/04 Running code, we still need to add button switch action
//
//
//
// Notes:
//
#define PRESSED HIGH //+5V---[Switch]---Pin---[10k]---GND
#define RELEASED LOW
#define ENABLED true
#define DISABLED false
#define MOTORon HIGH
#define MOTORoff LOW
// G P I O s
//================================================^================================================
//
const byte buttonPin = 2;
const byte MOTORPin = 9;
const byte heartbeatLED = 13;
// V A R I A B L E S
//================================================^================================================
//
bool balloonFlag = DISABLED;
int fadeCounter;
int buttonState;
int lastButtonState = RELEASED;
//timing stuff
unsigned long heartbeatTime;
unsigned long switchesTime;
unsigned long automaticTime;
unsigned long commonTime;
unsigned long machineTime;
unsigned long automaticInterval = 20ul * 1000; //20 seconds, should be less than the auto shut off time
// S t a t e M a c h i n e
//================================================^================================================
//the states in our machine
enum STATES : byte
{
STARTUP, BALLOONup, WAITINGup, BALLOONdown, WAITINGdown
};
STATES mState = STARTUP;
// s e t u p ( )
//================================================^================================================
void setup()
{
Serial.begin(115200);
pinMode(heartbeatLED, OUTPUT);
pinMode(MOTORPin, OUTPUT);
pinMode(buttonPin, INPUT);
Serial.println("System Restart");
} //END of setup()
// l o o p ( )
//================================================^================================================
void loop()
{
//======================================================================== T I M E R heartbeatLED
//is it time to toggle the heartbeat LED ?
if (millis() - heartbeatTime >= 500ul)
{
//restart this TIMER
heartbeatTime = millis();
//toggle the heartbeat LED
digitalWrite(heartbeatLED, digitalRead(heartbeatLED) == HIGH ? LOW : HIGH);
}
//======================================================================== T I M E R switches
//is it time to scan our switches ?
if (millis() - switchesTime >= 50ul)
{
//restart this TIMER
switchesTime = millis();
checkSwitches();
}
//======================================================================== T I M E R automatic
//if the balloon is not moving, is it time to automatically move the balloon ?
if (mState == STARTUP && millis() - automaticTime >= automaticInterval)
{
Serial.println("Balloon automatic operation started");
//starting the balloon sequence automatically
mState = BALLOONup;
//motor speed starts out at 0
fadeCounter = 0;
//restart the TIMER
commonTime = millis();
}
//======================================================================== T I M E R machine
//is it time to check our State Machine ?
if (millis() - machineTime >= 10ul)
{
//restart this TIMER
machineTime = millis();
checkMachine();
}
//================================================
//other non blocking code goes here
//================================================
} //END of loop()
// c h e c k M a c h i n e ( )
//================================================^================================================
void checkMachine()
{
//================================================
//service the current "machine state"
switch (mState)
{
//========================
case STARTUP:
{
//do startup stuff
}
break;
//======================== increase the speed from 0 to 205
case BALLOONup:
{
//has the common TIMER expired ?
if (millis() - commonTime >= 30ul)
{
//restart TIMER
commonTime = millis();
//increase motor speed
analogWrite(MOTORPin, fadeCounter);
fadeCounter = fadeCounter + 3;
//have we reached maximum speed ?
if (fadeCounter > 205)
{
Serial.println("Balloon is at maximum");
//next State
mState = WAITINGup;
//restart the TIMER
commonTime = millis();
break;
}
}
}
break;
//======================== wait here for 10 seconds
case WAITINGup:
{
//has the common TIMER expired ?
if (millis() - commonTime >= 10000ul)
{
Serial.println("Balloon is going down");
fadeCounter = 205;
//next State
mState = BALLOONdown;
//restart TIMER
commonTime = millis();
break;
}
}
break;
//======================== decrease the speed from 205 to 0
case BALLOONdown:
{
//has the common TIMER expired ?
if (millis() - commonTime >= 30ul)
{
//restart TIMER
commonTime = millis();
//decrease motor speed
analogWrite(MOTORPin, fadeCounter);
fadeCounter = fadeCounter - 3;
//have we reached minimum speed ?
if (fadeCounter < 0)
{
Serial.println("Balloon is at minimum");
fadeCounter = 0;
//stop motor
analogWrite(MOTORPin, fadeCounter);
//next State
mState = WAITINGdown;
//restart the TIMER
commonTime = millis();
break;
}
}
}
break;
//======================== wait here for 15 seconds
case WAITINGdown:
{
//has the common TIMER expired ?
if (millis() - commonTime >= 15000ul)
{
Serial.println("Balloon sequence has ended");
//restart the automatic TIMER
automaticTime = millis();
//next State
mState = STARTUP;
break;
}
}
break;
} //END of switch/case
} //END of checkMachine()
// c h e c k S w i t c h e s ( )
//================================================^================================================
void checkSwitches()
{
byte state;
//======================================================================== buttonPin
state = digitalRead(buttonPin);
//================================================
//has this switch changed state ?
if (lastButtonState != state)
{
//update to the new state
lastButtonState = state;
//========================
//if the balloon is stopped, has the switch been pressed ?
if (mState == STARTUP && state == PRESSED)
{
Serial.println("Balloon is going up");
fadeCounter = 0;
//restart the TIMER
commonTime = millis();
//start the sequence for going up
mState = BALLOONup;
}
} //END of this switch
//======================================================================== nextSwitch
} //END of checkSwitches()
Instead of a DC motor, I thought this example code may work for my ESC/BEC controlled motor, but not sure how to include it in the current code. I still want to ramp up (from zero to 90 in steps of 1), hold, and ramp down the motor. Probably a delay (poor choice of words) of 65mS between steps, to make the ramp up slow to full power in ~6 seconds.
The schematic is a very simple one and this is my first attempt at constructing one.
Thank you very much for any help you can give me. This is a project for lifting a Balloon for a Area 51 train layout, and now a pumkin balloon in a spider web bowl. Its for the kids.
/* Sweep
by BARRAGAN <http://barraganstudio.com>
This example code is in the public domain.
modified 8 Nov 2013
by Scott Fitzgerald
https://www.arduino.cc/en/Tutorial/LibraryExamples/Sweep
*/
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards
int pos = 0; // variable to store the servo position
void setup() {
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop() {
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15 ms for the servo to reach the position
}
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15 ms for the servo to reach the position
}
}
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.