Giter VIP home page Giter VIP logo

pwm's Introduction

License: MIT

Bolder Flight Systems Logo     Arduino Logo

Pwm

This library sends commands to PWM servos and is compatible with Arduino and CMake build systems.

Description

Pulse Width Modulation (PWM) is a protocol for receivers to send commands to servos. Each servo is sent a high pulse with the width of the pulse dictating the commanded position. Traditionally, PWM commands are sent at a 50 Hz interval with pulse widths varying between 1000 us and 2000 us. Some servos and Electronic Speed Controllers (ESCs) support higher frequencies, which typically requires a shorter pulse width range. PWM is the most common protocol for sending servo and ESC commands, but they require a PWM capable pin for each servo being controlled.

Usage

This library presents a similar interface as our SBUS library and uses analogWrite to generate the PWM pulses. analogWrite does not have a well defined interface across Arduino devices and this library is not anticipated to work with boards other than Teensy 3.x, 4.x, and LC. Compared to the Servo library, analogWrite sends all the pulses at the same rising pulse, whereas Servo sends them one after another, which causes an undesirable and variable latency, especially in later channels.

Installation

Arduino

Simply clone or download and extract the zipped library into your Arduino/libraries folder. The library is added as:

#include "pwm.h"

An example is located in examples/arduino/pwm_example/pwm_example.ino. This library is tested with Teensy 3.x, 4.x, and LC devices and is not expected to work with other Arduino devices.

CMake

CMake is used to build this library, which is exported as a library target called pwm. The header is added as:

#include "pwm.h"

The library can be also be compiled stand-alone using the CMake idiom of creating a build directory and then, from within that directory issuing:

cmake .. -DMCU=MK66FX1M0
make

This will build the library and example executable called pwm_example. The example executable source file is located at examples/cmake/pwm_example.cc. Notice that the cmake command includes a define specifying the microcontroller the code is being compiled for. This is required to correctly configure the code, CPU frequency, and compile/linker options. The available MCUs are:

  • MK20DX128
  • MK20DX256
  • MK64FX512
  • MK66FX1M0
  • MKL26Z64
  • IMXRT1062_T40
  • IMXRT1062_T41

These are known to work with the same packages used in Teensy products. Also switching the packages is known to work well, as long as it's only a package change.

The pwm_example target creates an executable for communicating with PWM servos. This target also has a _hex for creating the hex file and an _upload for using the Teensy CLI Uploader to flash the Teensy. Please note that the CMake build tooling is expected to be run under Linux or WSL, instructions for setting up your build environment can be found in our build-tools repo.

Namespaces

This library is within the namespace bfs

PwmTx

PwmTx(const std::array<int8_t, N> &pins) This class is templated with the number of PWM pins and takes an array of pin numbers as input.

std::array<int8_t, 6> pins = {21, 22, 23, 2, 3, 4};
bfs::PwmTx<pins.size()> pwm(pins);

An optional template parameter is the PWM resolution.

/* 12 bit PWM resolution */
std::array<int8_t, 6> pins = {21, 22, 23, 2, 3, 4};
bfs::PwmTx<pins.size(), 12> pwm(pins);

By default the resolution is 16 bits.

void Begin() Initializes the PWM pins at the default frequency of 50 Hz.

pwm.Begin();

void Begin(const float freq) Initializes the PWM pins at the given frequency in Hz. Note that each PwmTx object only supports a single frequency. PWM pins are grouped by timer, changing the frequency of any pin in the group changes the frequency for all pins in the group. Refer to the analogWrite for the groupings.

void Write() Updates the PWM commands sent to the servos.

pwm.Write();

static constexpr int8_t NUM_CH() A constant defining the number of PWM channels, useful for defining arrays to write the data from.

void ch(const std::array<int16_t, N> &cmds) Sets the channel data to be transmitted, given an array of PWM commands.

std::array<int16_t, 6> cmd = {1000, 1200, 1300, 1400, 1500, 1600};
pwm.ch(cmd);

std::array<int16_t, N> ch() Returns the channel data to be transmitted.

std::array<int16_t, 6> cmd = pwm.ch();

pwm's People

Contributors

flybrianfly avatar leon4413 avatar tl-4319 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

tl-4319 leon4413

pwm's Issues

Arduino MEGA

I'm not having any luck with an Arduino Mega and the sample code. I'm using an inverter that has worked with an MKR1010 and I'm have RX pinned to 17 (RX2).

#include "sbus.h"

/* SBUS object, reading SBUS */
bfs::SbusRx sbus_rx(&Serial2);
/* SBUS object, writing SBUS */
bfs::SbusTx sbus_tx(&Serial2);
/* SBUS data */
bfs::SbusData data;

void setup() {
  /* Serial to display data */
  Serial.begin(115200);
  while (!Serial) {}

  delay(2000);

  /* Begin the SBUS communication */
  Serial.println("Begin SBUS...");
  sbus_rx.Begin();
  sbus_tx.Begin();
}

void loop() {

  Serial.println("Begin SBUS...");
  if (sbus_rx.Read()) {
    /* Grab the received data */
    data = sbus_rx.data();
    /* Display the received data */
    for (int8_t i = 0; i < data.NUM_CH; i++) {
      Serial.print(data.ch[i]);
      Serial.print("\t");
    }
    
    /* Display lost frames and failsafe data */
    Serial.print(data.lost_frame);
    Serial.print("\t");
    Serial.println(data.failsafe);
    /* Set the SBUS TX data to the received data */
    sbus_tx.data(data);
    /* Write the data to the servos */
    sbus_tx.Write();
  }
}

Occasionally I will receive data from sbus_rx.Read()

sbus-data

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.