Giter Club home page Giter Club logo

pulse400's Introduction

Pulse400 - High speed 400 Hz Arduino ESC & Servo library.

TODO

  • Document that frequency is now global & max 8 channels
  • Overclocking documentation 'Beyond 400 Hz'
  • Add Saleae logic screenshots
  • Add a ToC
  • Comparison with Servo
  • Publish on the Arduino Library Manager

Generates 400 Hz PWM control pulses for servos and multicopter electronic speed controllers (ESC). By varying the pulse and period width frequencies of well over 400 Hz can be obtained (provided the attached hardware can handle the signals). Can control 8 ESC's and/or Servo's at the same time out of the box but that can be inncreased or decreased by simply changing the PULSE400_MAX_CHANNELS constant in the Pulse400.h file.

Provides the following front-end classes

  • Esc400: Control motor (esc) as a single object
  • Multi400: Control multiple motors (bank) as a single object
  • Servo400: Drop in replacement for the Arduino Servo library

Installation

Install the TimerOne library with the Arduino library manager ( Sketch > Include Library > Manage libraries > ).

Download the Pulse400 library from here. Unzip it in your Arduino libraries folder and rename the directory from Pulse400-master to just Pulse400. Restart the Arduino IDE and you should be able to open and run the included examples.

Principle of operation

The standard Arduino Servo library can be sued to control electronic speed controllers for multicopters, but it's not really suited for it. It runs at 50Hz and is difficult to improve because the pulses are generated in a sequential manner (using multiple timers if needed). A standard ESC PWM pulse takes up 2.5 milliseconds so outputting 4 PWM signals in sequence takes up 10ms and would require at most a 100 Hz signal.

The Pulse400 class is not meant to be used directly in a sketch. Instead use one (or more) of the Esc400/Multi400/Servo400 front-end classes or write your own. They work together fine, so you can use a Multi400 object to control your quadcopter's 4 motors while controlling your camera pan & tilt with two Servo400 objects.

The Esc400 and Multi400 classes allow you to manipulate the minimum and maximum pulse width that is used and they also allow you to tune the period setting. By changing the period setting from the default 2500 a lower value and adapting the minimum and maximum pulse to fit within that period you can increase the frequency even further. Setting the period width or the frequency has a global effect on all PWM streams generated by Pulse400. See below for further explanation.

The main challenge was to keep a list of PWM channels (queue) and keep it sorted on (often rapidly changing) pulse width at all times so that the interrupt service routine can quickly access the next pin that needs to be flipped without too many calculations. This was done by keeping two separate queues, and ACTive and an ALTernate one which can be edited by the main code. Whenever the ALTernate queue has been updated the main code sets a switch_queue flag which signals to the interrupt handler that whenever a new period starts it should switch from the ACTive queue to the ALTernate queue, which then becomes the ACTive queue.

The Esc400 class

The Esc400 class controls one PWM channel, so you basically create one for each motor.

Method Description
begin( int8_t pin Initializes the object and attaches it to a pin.
speed( uint16_t v ) Sets the speed for the ESC, value must be between 0 (min throttle) and 1000 (max throttle)
speed() Retrieves the current speed.
range( uint16_t min, uint16_t min ) Defines the mapping of the min - max throttle value (0 - 1000) to a pulse length in microseconds.
end() Detaches the object from the pin.

N

Example code

#include <Pulse400.h>

int pin[] = { 4, 5, 6, 7 };

Esc400 motor[4];

void setup() {
  for ( int m = 0; m < 4; m++ ) 
    motor[m].begin( pin[m] );
  delay( 1000 );
  for ( int m = 0; m < 4; m++ )
    motor[m].speed( 200 );
  delay( 1000 );
  for ( int m = 0; m < 4; m++ )
    motor[m].speed( 0 );
}

void loop() {
}

The Multi400 class

Use this class to control up to 8 motors (bank) as a single object. Setting the motor speeds for multiple motors is a lot more efficient than setting it for one motor at a time (as the Esc400 class does). To be able to efficiently generate a waveform the Pulse400 class must maintain a list (queue) of steps (pin or or off) to execute. This list must be sorted by pulse width. For each change in speed the list must be inspected and ossible resorted which is relatively expensive in MCU time. By using the Multi400 class and setting the speeds for all motors at once, the generator only needs to sort the list once per bank and not once per motor.

Method Description
begin( int8_t pin0, int8_t pin1, ..., int8_t pin7 ) Initializes the object and attaches it to a series of pins. All arguments but the first are optional, specify at least 1 and at most 8 ESCs/motors.
setSpeed( int16_t v0, int16_t v0,..., int16_t v7 ) Sets the speed for all ESCs at the same time, value must be between 0 (min throttle) and 1000 (max throttle).
speed( uint8_t no, uint16_t v ) Sets the speed for the ESC identified by 'no', value must be between 0 (min throttle) and 1000 (max throttle).
speed( uint8_t no ) Retrieves the current speed for ESC 'no'.
range( uint16_t min, uint16_t min ) Defines the mapping of the min - max throttle value (0 - 1000) to a pulse length in microseconds.
end() Detaches the object from the attached pins

Example code

#include <Pulse400.h>

int pin[] = { 4, 5, 6, 7 };

Multi400 motors;

void setup() {
  motors.begin( pin[0], pin[1], pin[2], pin[3] );
  delay( 1000 );
  motors.setSpeed( 200, 200, 200, 200 );
  delay( 1000 );
  motors.setSpeed( 0, 0, 0, 0 );
  motors.end();
}

void loop() {
}

The Servo400 class

The Servo400 class strives to be an exact copy of the standard Arduino Servo class. The default PWM frequency is 400 Hz, but that can be changed with the pulse400.frequency() method.

Method Description
attach( int pin ) Attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure
attach( int pin, int min, int max ) As above but also sets min and max values for writes
detach() Detaches the object from the pin
write( int value ) If value is < 200 its treated as an angle, otherwise as pulse width in microseconds
writeMicroseconds( int value ) Write pulse width in microseconds
read() Returns current pulse width (int) as an angle between 0 and 180 degrees
readMicroseconds() returns current pulse width (int) in microseconds for this servo
attached() return true if this servo is attached, otherwise false

Example code

/* Sweep
 by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.

 modified 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Pulse400.h>

Servo400 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
  pulse400.frequency( PULSE400_50HZ );  // Slow it down to the 'standard' 50 Hz
}

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 15ms 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 15ms for the servo to reach the position
  }
}

The example code and method descriptions are taken from the Servo library documentation and adapted slightly for Servo400.

The Pulse400 class

The Pulse400 class is the actual PWM generator that is used by the Esc400, Multi400 and Servo400 front-end classes. A (singleton) object named pulse400 is automatically instantiated when Pulse400.h is included.

Method Description
attach( int8_t pin, int8_t force_id = -1 ) Attaches the specified pin and allocates a PWM channel for it. Returns a channel id or -1 on failure (no more channels available). The optional second argument forcibly sets the channel id.
detach( int_8 id_channel ) Detaches the pin and frees the channel
pulse( int8_t id_channel, uint16_t pulse_width, bool no_update = false) Sets the pulse width for the specified channel. Set no_update to true to delay updating the PWM generator. Call the update() method after setting a set of channnels. The pulse_width argument takes values from 1 to period length (normally 2500).
pulse( int8_t id_channel ) Returns the current pulse for the specified channel.
update() Updates the PWM generation queue after a (series of) speed updates.
frequency( uint16_t f ) Set the frequency for the Pulse400 PWM generator. The frequency can be set between 29 and about 2000 Hz. (with a severely restricted maximum pulse time)

Advanced: Running faster than 400 Hz

Advanced: Synchronizing the pulse signal

pulse400's People

Contributors

tinkerspy avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.