aufgaben weil vergesen zu commiten
This commit is contained in:
@@ -1,32 +1,29 @@
|
||||
License Agreement
|
||||
Janelia Open-Source Software
|
||||
(3-clause BSD License)
|
||||
Janelia Research Campus Software Copyright 1.1
|
||||
|
||||
Copyright (c) 2014, Howard Hughes Medical Institute
|
||||
All rights reserved.
|
||||
Copyright (c) 2021 Howard Hughes Medical Institute
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the Howard Hughes Medical Institute nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written
|
||||
permission.
|
||||
* Neither the name of HHMI nor the names of its contributors may be used to
|
||||
endorse or promote products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
#+TITLE: PCA9685
|
||||
#+AUTHOR: Peter Polidoro
|
||||
#+EMAIL: peterpolidoro@gmail.com
|
||||
#+EMAIL: peter@polidoro.io
|
||||
|
||||
* Library Information
|
||||
- Name :: PCA9685
|
||||
- Version :: 2.1.4
|
||||
- License :: BSD
|
||||
- URL :: https://github.com/janelia-arduino/PCA9685
|
||||
- Author :: Peter Polidoro
|
||||
- Email :: peterpolidoro@gmail.com
|
||||
- Name :: PCA9685
|
||||
- Version :: 3.0.2
|
||||
- License :: BSD
|
||||
- URL :: https://github.com/janelia-arduino/PCA9685
|
||||
- Author :: Peter Polidoro
|
||||
- Email :: peter@polidoro.io
|
||||
|
||||
The PCA9685 is a 16-channel 12-bit PWM controller. All channels operate at a
|
||||
programmable frequency between roughly 25 to 1600 Hz with 16 independent
|
||||
12-bit duty cycles from 0 to 100%. Supports using a single device (for up to
|
||||
16 channels) or up to 55 devices (for up to 880 channels).
|
||||
** Description
|
||||
|
||||
The PCA9685 is a 16-channel 12-bit PWM controller.
|
||||
|
||||
All channels operate at a programmable frequency between roughly 25 to 1600 Hz
|
||||
with 16 independent 12-bit duty cycles from 0 to 100%.
|
||||
|
||||
Supports using a single device (for up to 16 channels) or up to 55 devices
|
||||
(for up to 880 channels).
|
||||
|
||||
BIN
INF/libraries/PCA9685/datasheet/PCA9685.pdf
Normal file
BIN
INF/libraries/PCA9685/datasheet/PCA9685.pdf
Normal file
Binary file not shown.
@@ -3,16 +3,16 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Constants.h"
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
const uint8_t device_address = 0x40;
|
||||
const size_t output_enable_pin = 2;
|
||||
const PCA9685::DeviceAddress device_address = 0x40;
|
||||
const PCA9685::Pin output_enable_pin = 2;
|
||||
|
||||
const size_t loop_delay = 100;
|
||||
const uint16_t frequency_increment = 10;
|
||||
const PCA9685::Frequency frequency_increment = 10;
|
||||
}
|
||||
|
||||
@@ -3,19 +3,20 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
#include <Arduino.h>
|
||||
#include <PCA9685.h>
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
extern const uint8_t device_address;
|
||||
extern const size_t output_enable_pin;
|
||||
extern const PCA9685::DeviceAddress device_address;
|
||||
extern const PCA9685::Pin output_enable_pin;
|
||||
|
||||
extern const size_t loop_delay;
|
||||
extern const uint16_t frequency_increment;
|
||||
extern const PCA9685::Frequency frequency_increment;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
PCA9685 pca9685;
|
||||
|
||||
uint16_t frequency_min;
|
||||
uint16_t frequency_max;
|
||||
uint16_t frequency;
|
||||
PCA9685::Frequency frequency_min;
|
||||
PCA9685::Frequency frequency_max;
|
||||
PCA9685::Frequency frequency;
|
||||
|
||||
void setup()
|
||||
{
|
||||
@@ -19,8 +19,8 @@ void setup()
|
||||
|
||||
pca9685.setOutputsNotInverted();
|
||||
|
||||
uint16_t time_min = pca9685.getTimeMin();
|
||||
uint16_t time_max = pca9685.getTimeMax();
|
||||
PCA9685::Time time_min = pca9685.getTimeMin();
|
||||
PCA9685::Time time_max = pca9685.getTimeMax();
|
||||
pca9685.setAllChannelsOnAndOffTime(time_min,time_max/4);
|
||||
|
||||
frequency_min = pca9685.getFrequencyMin();
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Constants.h"
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
const uint8_t device_address = 0x40;
|
||||
const size_t output_enable_pin = 2;
|
||||
const PCA9685::DeviceAddress device_address = 0x40;
|
||||
const PCA9685::Pin output_enable_pin = 2;
|
||||
|
||||
const size_t loop_delay = 100;
|
||||
const uint16_t frequency = 200;
|
||||
const uint16_t time_increment = 100;
|
||||
const PCA9685::Frequency frequency = 200;
|
||||
const PCA9685::Time time_increment = 100;
|
||||
|
||||
const uint8_t channel = 0;
|
||||
const PCA9685::Channel channel = 0;
|
||||
}
|
||||
|
||||
@@ -3,22 +3,23 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
#include <Arduino.h>
|
||||
#include <PCA9685.h>
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
extern const uint8_t device_address;
|
||||
extern const size_t output_enable_pin;
|
||||
extern const PCA9685::DeviceAddress device_address;
|
||||
extern const PCA9685::Pin output_enable_pin;
|
||||
|
||||
extern const size_t loop_delay;
|
||||
extern const uint16_t frequency;
|
||||
extern const uint16_t time_increment;
|
||||
extern const PCA9685::Frequency frequency;
|
||||
extern const PCA9685::Time time_increment;
|
||||
|
||||
extern const uint8_t channel;
|
||||
extern const PCA9685::Channel channel;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
PCA9685 pca9685;
|
||||
|
||||
uint16_t time_min;
|
||||
uint16_t time_max;
|
||||
uint16_t off_time;
|
||||
PCA9685::Time time_min;
|
||||
PCA9685::Time time_max;
|
||||
PCA9685::Time off_time;
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
@@ -3,26 +3,26 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Constants.h"
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
const uint8_t device_addresses[DEVICE_COUNT] =
|
||||
const PCA9685::DeviceAddress device_addresses[DEVICE_COUNT] =
|
||||
{
|
||||
0x40,
|
||||
0x41,
|
||||
0x42
|
||||
};
|
||||
const uint8_t device_index = 0;
|
||||
const PCA9685::DeviceIndex = 0;
|
||||
|
||||
const size_t output_enable_pin = 2;
|
||||
const PCA9685::Pin output_enable_pin = 2;
|
||||
|
||||
const size_t loop_delay = 100;
|
||||
const uint16_t frequency = 200;
|
||||
const uint16_t time_increment = 100;
|
||||
const PCA9685::Frequency frequency = 200;
|
||||
const PCA9685::Time time_increment = 100;
|
||||
|
||||
const uint8_t channel = 0;
|
||||
const PCA9685::Channel channel = 0;
|
||||
}
|
||||
|
||||
@@ -3,25 +3,26 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
#include <Arduino.h>
|
||||
#include <PCA9685.h>
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
enum{DEVICE_COUNT=3};
|
||||
extern const uint8_t device_addresses[DEVICE_COUNT];
|
||||
extern const uint8_t device_index;
|
||||
extern const PCA9685::DeviceAddress device_addresses[DEVICE_COUNT];
|
||||
extern const PCA9685::DeviceIndex;
|
||||
|
||||
extern const size_t output_enable_pin;
|
||||
extern const PCA9685::Pin output_enable_pin;
|
||||
|
||||
extern const size_t loop_delay;
|
||||
extern const uint16_t frequency;
|
||||
extern const uint16_t time_increment;
|
||||
extern const PCA9685::Frequency frequency;
|
||||
extern const PCA9685::Time time_increment;
|
||||
|
||||
extern const uint8_t channel;
|
||||
extern const PCA9685::Channel channel;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
|
||||
PCA9685 pca9685;
|
||||
|
||||
uint16_t time_min;
|
||||
uint16_t time_max;
|
||||
uint16_t on_time;
|
||||
PCA9685::Time time_min;
|
||||
PCA9685::Time time_max;
|
||||
PCA9685::Time on_time;
|
||||
|
||||
void setup()
|
||||
{
|
||||
pca9685.setWire(Wire);
|
||||
for (uint8_t device_index=0; device_index<constants::DEVICE_COUNT; ++device_index)
|
||||
for (PCA9685::DeviceIndex=0; device_index<constants::DEVICE_COUNT; ++device_index)
|
||||
{
|
||||
pca9685.addDevice(constants::device_addresses[device_index]);
|
||||
}
|
||||
|
||||
@@ -3,21 +3,21 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Constants.h"
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
const uint8_t device_address = 0x40;
|
||||
const size_t output_enable_pin = 2;
|
||||
const PCA9685::DeviceAddress device_address = 0x40;
|
||||
const PCA9685::Pin output_enable_pin = 2;
|
||||
|
||||
const size_t loop_delay = 100;
|
||||
|
||||
const uint8_t channel = 0;
|
||||
const PCA9685::Channel channel = 0;
|
||||
|
||||
const uint16_t servo_pulse_duration_min = 900;
|
||||
const uint16_t servo_pulse_duration_max = 2100;
|
||||
const uint16_t servo_pulse_duration_increment = 100;
|
||||
const PCA9685::DurationMicroseconds servo_pulse_duration_min = 900;
|
||||
const PCA9685::DurationMicroseconds servo_pulse_duration_max = 2100;
|
||||
const PCA9685::DurationMicroseconds servo_pulse_duration_increment = 100;
|
||||
}
|
||||
|
||||
@@ -3,24 +3,25 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
#include <Arduino.h>
|
||||
#include <PCA9685.h>
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
extern const uint8_t device_address;
|
||||
extern const size_t output_enable_pin;
|
||||
extern const PCA9685::DeviceAddress device_address;
|
||||
extern const PCA9685::Pin output_enable_pin;
|
||||
|
||||
extern const size_t loop_delay;
|
||||
|
||||
extern const uint8_t channel;
|
||||
extern const PCA9685::Channel channel;
|
||||
|
||||
extern const uint16_t servo_pulse_duration_min;
|
||||
extern const uint16_t servo_pulse_duration_max;
|
||||
extern const uint16_t servo_pulse_duration_increment;
|
||||
extern const PCA9685::DurationMicroseconds servo_pulse_duration_min;
|
||||
extern const PCA9685::DurationMicroseconds servo_pulse_duration_max;
|
||||
extern const PCA9685::DurationMicroseconds servo_pulse_duration_increment;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
PCA9685 pca9685;
|
||||
|
||||
uint16_t servo_pulse_duration;
|
||||
PCA9685::DurationMicroseconds servo_pulse_duration;
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Constants.h"
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
const uint8_t device_address = 0x40;
|
||||
const size_t output_enable_pin = 2;
|
||||
const PCA9685::DeviceAddress device_address = 0x40;
|
||||
const PCA9685::Pin output_enable_pin = 2;
|
||||
|
||||
const size_t loop_delay = 8000;
|
||||
const uint16_t frequency = 200;
|
||||
const uint8_t channel = 0;
|
||||
const PCA9685::Frequency frequency = 200;
|
||||
const PCA9685::Channel channel = 0;
|
||||
|
||||
const Example examples[EXAMPLE_COUNT] =
|
||||
{
|
||||
|
||||
@@ -3,28 +3,29 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
#include <Arduino.h>
|
||||
#include <PCA9685.h>
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
extern const uint8_t device_address;
|
||||
extern const size_t output_enable_pin;
|
||||
extern const PCA9685::DeviceAddress device_address;
|
||||
extern const PCA9685::Pin output_enable_pin;
|
||||
|
||||
extern const size_t loop_delay;
|
||||
extern const uint16_t frequency;
|
||||
extern const uint8_t channel;
|
||||
extern const PCA9685::Frequency frequency;
|
||||
extern const PCA9685::Channel channel;
|
||||
|
||||
enum{EXAMPLE_COUNT=4};
|
||||
|
||||
struct Example
|
||||
{
|
||||
double duty_cycle;
|
||||
double percent_delay;
|
||||
PCA9685::Percent duty_cycle;
|
||||
PCA9685::Percent percent_delay;
|
||||
};
|
||||
|
||||
extern const Example examples[EXAMPLE_COUNT];
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Constants.h"
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
const uint8_t device_address = 0x40;
|
||||
const size_t output_enable_pin = 2;
|
||||
const PCA9685::DeviceAddress device_address = 0x40;
|
||||
const PCA9685::Pin output_enable_pin = 2;
|
||||
|
||||
const size_t loop_delay = 8000;
|
||||
const uint16_t frequency = 200;
|
||||
const uint8_t channel = 0;
|
||||
const PCA9685::Frequency frequency = 200;
|
||||
const PCA9685::Channel channel = 0;
|
||||
|
||||
const Example examples[EXAMPLE_COUNT] =
|
||||
{
|
||||
|
||||
@@ -3,28 +3,29 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
#include <Arduino.h>
|
||||
#include <PCA9685.h>
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
extern const uint8_t device_address;
|
||||
extern const size_t output_enable_pin;
|
||||
extern const PCA9685::DeviceAddress device_address;
|
||||
extern const PCA9685::Pin output_enable_pin;
|
||||
|
||||
extern const size_t loop_delay;
|
||||
extern const uint16_t frequency;
|
||||
extern const uint8_t channel;
|
||||
extern const PCA9685::Frequency frequency;
|
||||
extern const PCA9685::Channel channel;
|
||||
|
||||
enum{EXAMPLE_COUNT=4};
|
||||
|
||||
struct Example
|
||||
{
|
||||
uint16_t on_time;
|
||||
uint16_t off_time;
|
||||
PCA9685::Time on_time;
|
||||
PCA9685::Time off_time;
|
||||
};
|
||||
|
||||
extern const Example examples[EXAMPLE_COUNT];
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Constants.h"
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
const uint8_t device_address = 0x40;
|
||||
const size_t output_enable_pin = 2;
|
||||
const PCA9685::DeviceAddress device_address = 0x40;
|
||||
const PCA9685::Pin output_enable_pin = 2;
|
||||
|
||||
const size_t loop_delay = 8000;
|
||||
const uint16_t frequency = 200;
|
||||
const uint8_t channel = 0;
|
||||
const PCA9685::Frequency frequency = 200;
|
||||
const PCA9685::Channel channel = 0;
|
||||
|
||||
const Example examples[EXAMPLE_COUNT] =
|
||||
{
|
||||
|
||||
@@ -3,28 +3,29 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
#include <Arduino.h>
|
||||
#include <PCA9685.h>
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
extern const uint8_t device_address;
|
||||
extern const size_t output_enable_pin;
|
||||
extern const PCA9685::DeviceAddress device_address;
|
||||
extern const PCA9685::Pin output_enable_pin;
|
||||
|
||||
extern const size_t loop_delay;
|
||||
extern const uint16_t frequency;
|
||||
extern const uint8_t channel;
|
||||
extern const PCA9685::Frequency frequency;
|
||||
extern const PCA9685::Channel channel;
|
||||
|
||||
enum{EXAMPLE_COUNT=4};
|
||||
|
||||
struct Example
|
||||
{
|
||||
uint16_t pulse_width;
|
||||
uint16_t phase_shift;
|
||||
PCA9685::Duration pulse_width;
|
||||
PCA9685::Duration phase_shift;
|
||||
};
|
||||
|
||||
extern const Example examples[EXAMPLE_COUNT];
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "Constants.h"
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
const uint8_t device_address = 0x40;
|
||||
const size_t output_enable_pin = 2;
|
||||
const PCA9685::DeviceAddress device_address = 0x40;
|
||||
const PCA9685::Pin output_enable_pin = 2;
|
||||
|
||||
const long baud = 115200;
|
||||
|
||||
const size_t loop_delay = 100;
|
||||
const uint16_t frequency = 200;
|
||||
const uint16_t time_increment = 400;
|
||||
const double epsilon = 0.001;
|
||||
const PCA9685::Frequency frequency = 200;
|
||||
const PCA9685::Time time_increment = 400;
|
||||
const PCA9685::Percent epsilon = 0.001;
|
||||
}
|
||||
|
||||
@@ -3,22 +3,23 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef CONSTANTS_H
|
||||
#define CONSTANTS_H
|
||||
#include <Arduino.h>
|
||||
#include <PCA9685.h>
|
||||
|
||||
|
||||
namespace constants
|
||||
{
|
||||
extern const uint8_t device_address;
|
||||
extern const size_t output_enable_pin;
|
||||
extern const PCA9685::DeviceAddress device_address;
|
||||
extern const PCA9685::Pin output_enable_pin;
|
||||
|
||||
extern const long baud;
|
||||
extern const size_t loop_delay;
|
||||
extern const uint16_t frequency;
|
||||
extern const uint16_t time_increment;
|
||||
extern const double epsilon;
|
||||
extern const PCA9685::Frequency frequency;
|
||||
extern const PCA9685::Time time_increment;
|
||||
extern const PCA9685::Percent epsilon;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7,25 +7,25 @@
|
||||
|
||||
PCA9685 pca9685;
|
||||
|
||||
uint16_t time_min;
|
||||
uint16_t time_max;
|
||||
PCA9685::Time time_min;
|
||||
PCA9685::Time time_max;
|
||||
|
||||
uint8_t channel;
|
||||
PCA9685::Channel channel;
|
||||
|
||||
uint16_t on_time_set;
|
||||
uint16_t off_time_set;
|
||||
uint16_t on_time_get;
|
||||
uint16_t off_time_get;
|
||||
PCA9685::Time on_time_set;
|
||||
PCA9685::Time off_time_set;
|
||||
PCA9685::Time on_time_get;
|
||||
PCA9685::Time off_time_get;
|
||||
|
||||
uint16_t pulse_width_set;
|
||||
uint16_t phase_shift_set;
|
||||
uint16_t pulse_width_get;
|
||||
uint16_t phase_shift_get;
|
||||
PCA9685::Duration pulse_width_set;
|
||||
PCA9685::Duration phase_shift_set;
|
||||
PCA9685::Duration pulse_width_get;
|
||||
PCA9685::Duration phase_shift_get;
|
||||
|
||||
double duty_cycle_set;
|
||||
double percent_delay_set;
|
||||
double duty_cycle_get;
|
||||
double percent_delay_get;
|
||||
PCA9685::Percent duty_cycle_set;
|
||||
PCA9685::Percent percent_delay_set;
|
||||
PCA9685::Percent duty_cycle_get;
|
||||
PCA9685::Percent percent_delay_get;
|
||||
|
||||
void setup()
|
||||
{
|
||||
@@ -67,7 +67,7 @@ void loop()
|
||||
on_time_set = time_min;
|
||||
off_time_set = time_max;
|
||||
}
|
||||
for (uint8_t channel=0; channel < pca9685.getChannelCount(); ++channel)
|
||||
for (PCA9685::Channel channel=0; channel < pca9685.getChannelCount(); ++channel)
|
||||
{
|
||||
Serial << "frequency: " << pca9685.getFrequency() << "\n";
|
||||
Serial << "channel: " << channel << ", on_time_set: " << on_time_set << ", off_time_set: " << off_time_set << "\n";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name=PCA9685
|
||||
version=2.1.4
|
||||
author=Peter Polidoro <peterpolidoro@gmail.com>
|
||||
maintainer=Peter Polidoro <peterpolidoro@gmail.com>
|
||||
version=3.0.2
|
||||
author=Peter Polidoro <peter@polidoro.io>
|
||||
maintainer=Peter Polidoro <peter@polidoro.io>
|
||||
sentence=PCA9685 16-channel 12-bit PWM controller.
|
||||
paragraph=Like this project? Please star it on GitHub!
|
||||
category=Device Control
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// PCA9685.h
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef PCA9685_H
|
||||
#define PCA9685_H
|
||||
@@ -15,80 +15,91 @@ class PCA9685
|
||||
public:
|
||||
PCA9685();
|
||||
|
||||
const static uint8_t CHANNELS_PER_DEVICE = 16;
|
||||
typedef uint16_t Channel;
|
||||
typedef uint8_t ChannelCount;
|
||||
typedef uint8_t DeviceAddress;
|
||||
typedef uint8_t DeviceIndex;
|
||||
typedef size_t Pin;
|
||||
typedef uint16_t Frequency;
|
||||
typedef double Percent;
|
||||
typedef uint16_t Time;
|
||||
typedef uint16_t Duration;
|
||||
typedef uint16_t DurationMicroseconds;
|
||||
|
||||
const static Channel CHANNELS_PER_DEVICE = 16;
|
||||
enum {DEVICE_COUNT_MAX=55};
|
||||
|
||||
// Convenience method when using a single device
|
||||
void setupSingleDevice(TwoWire & wire=Wire,
|
||||
uint8_t device_address=0x40,
|
||||
DeviceAddress device_address=0x40,
|
||||
bool fast_mode_plus=false);
|
||||
|
||||
// Methods for using a single device or multiple devices
|
||||
void setupOutputEnablePin(size_t output_enable_pin);
|
||||
void enableOutputs(size_t output_enable_pin);
|
||||
void disableOutputs(size_t output_enable_pin);
|
||||
void setupOutputEnablePin(Pin output_enable_pin);
|
||||
void enableOutputs(Pin output_enable_pin);
|
||||
void disableOutputs(Pin output_enable_pin);
|
||||
|
||||
uint16_t getFrequencyMin();
|
||||
uint16_t getFrequencyMax();
|
||||
void setToFrequency(uint16_t frequency);
|
||||
uint16_t getFrequency();
|
||||
Frequency getFrequencyMin();
|
||||
Frequency getFrequencyMax();
|
||||
void setToFrequency(Frequency frequency);
|
||||
Frequency getFrequency();
|
||||
void setToServoFrequency();
|
||||
uint16_t getServoFrequency();
|
||||
Frequency getServoFrequency();
|
||||
|
||||
uint8_t getChannelCount();
|
||||
ChannelCount getChannelCount();
|
||||
|
||||
double getDutyCycleMin();
|
||||
double getDutyCycleMax();
|
||||
double getPercentDelayMin();
|
||||
double getPercentDelayMax();
|
||||
void setChannelDutyCycle(uint8_t channel,
|
||||
double duty_cycle,
|
||||
double percent_delay=0);
|
||||
void getChannelDutyCycle(uint8_t channel,
|
||||
double & duty_cycle,
|
||||
double & percent_delay);
|
||||
void setAllChannelsDutyCycle(double duty_cycle,
|
||||
double percent_delay=0);
|
||||
Percent getDutyCycleMin();
|
||||
Percent getDutyCycleMax();
|
||||
Percent getPercentDelayMin();
|
||||
Percent getPercentDelayMax();
|
||||
void setChannelDutyCycle(Channel channel,
|
||||
Percent duty_cycle,
|
||||
Percent percent_delay=0);
|
||||
void getChannelDutyCycle(Channel channel,
|
||||
Percent & duty_cycle,
|
||||
Percent & percent_delay);
|
||||
void setAllChannelsDutyCycle(Percent duty_cycle,
|
||||
Percent percent_delay=0);
|
||||
|
||||
uint16_t getPulseWidthMin();
|
||||
uint16_t getPulseWidthMax();
|
||||
uint16_t getPhaseShiftMin();
|
||||
uint16_t getPhaseShiftMax();
|
||||
void setChannelPulseWidth(uint8_t channel,
|
||||
uint16_t pulse_width,
|
||||
uint16_t phase_shift=0);
|
||||
void getChannelPulseWidth(uint8_t channel,
|
||||
uint16_t & pulse_width,
|
||||
uint16_t & phase_shift);
|
||||
void setAllChannelsPulseWidth(uint16_t pulse_width,
|
||||
uint16_t phase_shift=0);
|
||||
Duration getPulseWidthMin();
|
||||
Duration getPulseWidthMax();
|
||||
Time getPhaseShiftMin();
|
||||
Time getPhaseShiftMax();
|
||||
void setChannelPulseWidth(Channel channel,
|
||||
Duration pulse_width,
|
||||
Duration phase_shift=0);
|
||||
void getChannelPulseWidth(Channel channel,
|
||||
Duration & pulse_width,
|
||||
Time & phase_shift);
|
||||
void setAllChannelsPulseWidth(Duration pulse_width,
|
||||
Duration phase_shift=0);
|
||||
|
||||
void setChannelServoPulseDuration(uint8_t channel,
|
||||
uint16_t pulse_duration_microseconds);
|
||||
void getChannelServoPulseDuration(uint8_t channel,
|
||||
uint16_t & pulse_duration_microseconds);
|
||||
void setAllChannelsServoPulseDuration(uint16_t pulse_duration_microseconds);
|
||||
void setChannelServoPulseDuration(Channel channel,
|
||||
DurationMicroseconds pulse_duration_microseconds);
|
||||
void getChannelServoPulseDuration(Channel channel,
|
||||
DurationMicroseconds & pulse_duration_microseconds);
|
||||
void setAllChannelsServoPulseDuration(DurationMicroseconds pulse_duration_microseconds);
|
||||
|
||||
uint16_t getTimeMin();
|
||||
uint16_t getTimeMax();
|
||||
void setChannelOnAndOffTime(uint8_t channel,
|
||||
uint16_t on_time,
|
||||
uint16_t off_time);
|
||||
void getChannelOnAndOffTime(uint8_t channel,
|
||||
uint16_t & on_time,
|
||||
uint16_t & off_time);
|
||||
void setAllChannelsOnAndOffTime(uint16_t on_time,
|
||||
uint16_t off_time);
|
||||
void setChannelOnTime(uint8_t channel,
|
||||
uint16_t on_time);
|
||||
void getChannelOnTime(uint8_t channel,
|
||||
uint16_t & on_time);
|
||||
void setAllChannelsOnTime(uint16_t on_time);
|
||||
void setChannelOffTime(uint8_t channel,
|
||||
uint16_t off_time);
|
||||
void getChannelOffTime(uint8_t channel,
|
||||
uint16_t & off_time);
|
||||
void setAllChannelsOffTime(uint16_t off_time);
|
||||
Time getTimeMin();
|
||||
Time getTimeMax();
|
||||
void setChannelOnAndOffTime(Channel channel,
|
||||
Time on_time,
|
||||
Time off_time);
|
||||
void getChannelOnAndOffTime(Channel channel,
|
||||
Time & on_time,
|
||||
Time & off_time);
|
||||
void setAllChannelsOnAndOffTime(Time on_time,
|
||||
Time off_time);
|
||||
void setChannelOnTime(Channel channel,
|
||||
Time on_time);
|
||||
void getChannelOnTime(Channel channel,
|
||||
Time & on_time);
|
||||
void setAllChannelsOnTime(Time on_time);
|
||||
void setChannelOffTime(Channel channel,
|
||||
Time off_time);
|
||||
void getChannelOffTime(Channel channel,
|
||||
Time & off_time);
|
||||
void setAllChannelsOffTime(Time off_time);
|
||||
|
||||
void setOutputsInverted();
|
||||
void setOutputsNotInverted();
|
||||
@@ -106,93 +117,93 @@ public:
|
||||
// device_address=0x40 when all device address
|
||||
// hardware select lines are low
|
||||
// cannot use reserved addresses
|
||||
void addDevice(uint8_t device_address);
|
||||
void addDevice(DeviceAddress device_address);
|
||||
void resetAllDevices();
|
||||
|
||||
void addDeviceToGroup0(uint8_t device_address);
|
||||
void removeDeviceFromGroup0(uint8_t device_address);
|
||||
void addDeviceToGroup1(uint8_t device_address);
|
||||
void removeDeviceFromGroup1(uint8_t device_address);
|
||||
void addDeviceToGroup2(uint8_t device_address);
|
||||
void removeDeviceFromGroup2(uint8_t device_address);
|
||||
void addDeviceToGroup0(DeviceAddress device_address);
|
||||
void removeDeviceFromGroup0(DeviceAddress device_address);
|
||||
void addDeviceToGroup1(DeviceAddress device_address);
|
||||
void removeDeviceFromGroup1(DeviceAddress device_address);
|
||||
void addDeviceToGroup2(DeviceAddress device_address);
|
||||
void removeDeviceFromGroup2(DeviceAddress device_address);
|
||||
|
||||
void setSingleDeviceToFrequency(uint8_t device_address,
|
||||
uint16_t frequency);
|
||||
uint16_t getSingleDeviceFrequency(uint8_t device_address);
|
||||
void setAllDevicesToFrequency(uint16_t frequency);
|
||||
void setSingleDeviceToServoFrequency(uint8_t device_address);
|
||||
uint16_t getSingleDeviceServoFrequency(uint8_t device_address);
|
||||
void setSingleDeviceToFrequency(DeviceAddress device_address,
|
||||
Frequency frequency);
|
||||
Frequency getSingleDeviceFrequency(DeviceAddress device_address);
|
||||
void setAllDevicesToFrequency(Frequency frequency);
|
||||
void setSingleDeviceToServoFrequency(DeviceAddress device_address);
|
||||
Frequency getSingleDeviceServoFrequency(DeviceAddress device_address);
|
||||
void setAllDevicesToServoFrequency();
|
||||
|
||||
uint8_t getDeviceChannelCount();
|
||||
ChannelCount getDeviceChannelCount();
|
||||
|
||||
// Use these device address to set more than one device at a time
|
||||
// with the methods below
|
||||
const static uint8_t DEVICE_ADDRESS_ALL = 0x70;
|
||||
const static uint8_t DEVICE_ADDRESS_GROUP0 = 0x71;
|
||||
const static uint8_t DEVICE_ADDRESS_GROUP1 = 0x72;
|
||||
const static uint8_t DEVICE_ADDRESS_GROUP2 = 0x73;
|
||||
const static DeviceAddress DEVICE_ADDRESS_ALL = 0x70;
|
||||
const static DeviceAddress DEVICE_ADDRESS_GROUP0 = 0x71;
|
||||
const static DeviceAddress DEVICE_ADDRESS_GROUP1 = 0x72;
|
||||
const static DeviceAddress DEVICE_ADDRESS_GROUP2 = 0x73;
|
||||
|
||||
void setDeviceChannelDutyCycle(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
double duty_cycle,
|
||||
double percent_delay=0);
|
||||
void setAllDeviceChannelsDutyCycle(uint8_t device_address,
|
||||
double duty_cycle,
|
||||
double percent_delay=0);
|
||||
void setDeviceChannelDutyCycle(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
Percent duty_cycle,
|
||||
Percent percent_delay=0);
|
||||
void setAllDeviceChannelsDutyCycle(DeviceAddress device_address,
|
||||
Percent duty_cycle,
|
||||
Percent percent_delay=0);
|
||||
|
||||
void setDeviceChannelPulseWidth(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
uint16_t pulse_width,
|
||||
uint16_t phase_shift=0);
|
||||
void setAllDeviceChannelsPulseWidth(uint8_t device_address,
|
||||
uint16_t pulse_width,
|
||||
uint16_t phase_shift=0);
|
||||
void setDeviceChannelPulseWidth(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
Duration pulse_width,
|
||||
Duration phase_shift=0);
|
||||
void setAllDeviceChannelsPulseWidth(DeviceAddress device_address,
|
||||
Duration pulse_width,
|
||||
Duration phase_shift=0);
|
||||
|
||||
void setDeviceChannelServoPulseDuration(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
uint16_t pulse_duration_microseconds);
|
||||
void setAllDeviceChannelsServoPulseDuration(uint8_t device_address,
|
||||
uint16_t pulse_duration_microseconds);
|
||||
void setDeviceChannelServoPulseDuration(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
DurationMicroseconds pulse_duration_microseconds);
|
||||
void setAllDeviceChannelsServoPulseDuration(DeviceAddress device_address,
|
||||
DurationMicroseconds pulse_duration_microseconds);
|
||||
|
||||
void setDeviceChannelOnAndOffTime(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
uint16_t on_time,
|
||||
uint16_t off_time);
|
||||
void setAllDeviceChannelsOnAndOffTime(uint8_t device_address,
|
||||
uint16_t on_time,
|
||||
uint16_t off_time);
|
||||
void setDeviceChannelOnTime(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
uint16_t on_time);
|
||||
void setAllDeviceChannelsOnTime(uint8_t device_address,
|
||||
uint16_t on_time);
|
||||
void setDeviceChannelOffTime(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
uint16_t off_time);
|
||||
void setAllDeviceChannelsOffTime(uint8_t device_address,
|
||||
uint16_t off_time);
|
||||
void setDeviceChannelOnAndOffTime(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
Time on_time,
|
||||
Time off_time);
|
||||
void setAllDeviceChannelsOnAndOffTime(DeviceAddress device_address,
|
||||
Time on_time,
|
||||
Time off_time);
|
||||
void setDeviceChannelOnTime(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
Time on_time);
|
||||
void setAllDeviceChannelsOnTime(DeviceAddress device_address,
|
||||
Time on_time);
|
||||
void setDeviceChannelOffTime(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
Time off_time);
|
||||
void setAllDeviceChannelsOffTime(DeviceAddress device_address,
|
||||
Time off_time);
|
||||
|
||||
void setSingleDeviceOutputsInverted(uint8_t device_address);
|
||||
void setSingleDeviceOutputsInverted(DeviceAddress device_address);
|
||||
void setAllDevicesOutputsInverted();
|
||||
void setSingleDeviceOutputsNotInverted(uint8_t device_address);
|
||||
void setSingleDeviceOutputsNotInverted(DeviceAddress device_address);
|
||||
void setAllDevicesOutputsNotInverted();
|
||||
void setSingleDeviceOutputsToTotemPole(uint8_t device_address);
|
||||
void setSingleDeviceOutputsToTotemPole(DeviceAddress device_address);
|
||||
void setAllDevicesOutputsToTotemPole();
|
||||
void setSingleDeviceOutputsToOpenDrain(uint8_t device_address);
|
||||
void setSingleDeviceOutputsToOpenDrain(DeviceAddress device_address);
|
||||
void setAllDevicesOutputsToOpenDrain();
|
||||
void setSingleDeviceOutputsLowWhenDisabled(uint8_t device_address);
|
||||
void setSingleDeviceOutputsLowWhenDisabled(DeviceAddress device_address);
|
||||
void setAllDevicesOutputsLowWhenDisabled();
|
||||
void setSingleDeviceOutputsHighWhenDisabled(uint8_t device_address);
|
||||
void setSingleDeviceOutputsHighWhenDisabled(DeviceAddress device_address);
|
||||
void setAllDevicesOutputsHighWhenDisabled();
|
||||
void setSingleDeviceOutputsHighImpedanceWhenDisabled(uint8_t device_address);
|
||||
void setSingleDeviceOutputsHighImpedanceWhenDisabled(DeviceAddress device_address);
|
||||
void setAllDevicesOutputsHighImpedanceWhenDisabled();
|
||||
|
||||
private:
|
||||
const static uint8_t DEVICE_ADDRESS_MIN = 0x40;
|
||||
const static uint8_t DEVICE_ADDRESS_MAX = 0x7B;
|
||||
const static DeviceAddress DEVICE_ADDRESS_MIN = 0x40;
|
||||
const static DeviceAddress DEVICE_ADDRESS_MAX = 0x7B;
|
||||
uint8_t device_count_;
|
||||
uint8_t device_addresses_[DEVICE_COUNT_MAX];
|
||||
DeviceAddress device_addresses_[DEVICE_COUNT_MAX];
|
||||
|
||||
TwoWire * wire_ptr_;
|
||||
const static long FAST_MODE_PLUS_CLOCK_FREQUENCY = 1000000;
|
||||
@@ -204,21 +215,21 @@ private:
|
||||
const static int DEVICE_INDEX_GROUP0 = -3;
|
||||
const static int DEVICE_INDEX_GROUP1 = -4;
|
||||
const static int DEVICE_INDEX_GROUP2 = -5;
|
||||
int deviceAddressToDeviceIndex(uint8_t device_address);
|
||||
int deviceAddressToDeviceIndex(DeviceAddress device_address);
|
||||
|
||||
const static uint8_t GENERAL_CALL_DEVICE_ADDRESS = 0x00;
|
||||
const static DeviceAddress GENERAL_CALL_DEVICE_ADDRESS = 0x00;
|
||||
const static uint8_t SWRST = 0b110;
|
||||
|
||||
// Can write to one or more device at a time
|
||||
// so use address rather than index
|
||||
template<typename T>
|
||||
void write(uint8_t device_address,
|
||||
void write(DeviceAddress device_address,
|
||||
uint8_t register_address,
|
||||
T data);
|
||||
// Can only read from one device at a time
|
||||
// so use index rather than address
|
||||
template<typename T>
|
||||
void read(uint8_t device_index,
|
||||
void read(DeviceIndex device_index,
|
||||
uint8_t register_address,
|
||||
T & data);
|
||||
|
||||
@@ -238,7 +249,7 @@ private:
|
||||
} fields;
|
||||
uint8_t data;
|
||||
};
|
||||
Mode1Register readMode1Register(uint8_t device_index);
|
||||
Mode1Register readMode1Register(DeviceIndex device_index);
|
||||
|
||||
const static uint8_t MODE2_REGISTER_ADDRESS = 0x01;
|
||||
union Mode2Register
|
||||
@@ -253,54 +264,54 @@ private:
|
||||
} fields;
|
||||
uint8_t data;
|
||||
};
|
||||
Mode2Register readMode2Register(uint8_t device_index);
|
||||
Mode2Register readMode2Register(DeviceIndex device_index);
|
||||
|
||||
void sleep(uint8_t device_index);
|
||||
void wake(uint8_t device_index);
|
||||
void sleep(DeviceIndex device_index);
|
||||
void wake(DeviceIndex device_index);
|
||||
void wakeAll();
|
||||
|
||||
void setPrescale(uint8_t device_index,
|
||||
void setPrescale(DeviceIndex device_index,
|
||||
uint8_t prescale);
|
||||
void getPrescale(uint8_t device_index,
|
||||
void getPrescale(DeviceIndex device_index,
|
||||
uint8_t & prescale);
|
||||
uint8_t frequencyToPrescale(uint16_t frequency);
|
||||
uint16_t prescaleToFrequency(uint8_t prescale);
|
||||
uint8_t frequencyToPrescale(Frequency frequency);
|
||||
Frequency prescaleToFrequency(uint8_t prescale);
|
||||
|
||||
uint8_t channelToDeviceIndex(uint8_t channel);
|
||||
uint8_t channelToDeviceChannel(uint8_t channel);
|
||||
uint8_t channelToDeviceIndex(Channel channel);
|
||||
Channel channelToDeviceChannel(Channel channel);
|
||||
|
||||
void dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(double duty_cycle,
|
||||
double percent_delay,
|
||||
uint16_t & pulse_width,
|
||||
uint16_t & phase_shift);
|
||||
void pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(uint16_t pulse_width,
|
||||
uint16_t phase_shift,
|
||||
double & duty_cycle,
|
||||
double & percent_delay);
|
||||
void dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(Percent duty_cycle,
|
||||
Percent percent_delay,
|
||||
Duration & pulse_width,
|
||||
Time & phase_shift);
|
||||
void pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(Duration pulse_width,
|
||||
Duration phase_shift,
|
||||
Percent & duty_cycle,
|
||||
Percent & percent_delay);
|
||||
|
||||
void pulseWidthAndPhaseShiftToOnTimeAndOffTime(uint16_t pulse_width,
|
||||
uint16_t phase_shift,
|
||||
uint16_t & on_time,
|
||||
uint16_t & off_time);
|
||||
void onTimeAndOffTimeToPulseWidthAndPhaseShift(uint16_t on_time,
|
||||
uint16_t off_time,
|
||||
uint16_t & pulse_width,
|
||||
uint16_t & phase_shift);
|
||||
void pulseWidthAndPhaseShiftToOnTimeAndOffTime(Duration pulse_width,
|
||||
Duration phase_shift,
|
||||
Time & on_time,
|
||||
Time & off_time);
|
||||
void onTimeAndOffTimeToPulseWidthAndPhaseShift(Time on_time,
|
||||
Time off_time,
|
||||
Duration & pulse_width,
|
||||
Time & phase_shift);
|
||||
|
||||
void servoPulseDurationToPulseWidthAndPhaseShift(uint16_t pulse_duration_microseconds,
|
||||
uint16_t & pulse_width,
|
||||
uint16_t & phase_shift);
|
||||
void pulseWidthAndPhaseShiftToServoPulseDuration(uint16_t pulse_width,
|
||||
uint16_t phase_shift,
|
||||
uint16_t & pulse_duration_microseconds);
|
||||
void servoPulseDurationToPulseWidthAndPhaseShift(DurationMicroseconds pulse_duration_microseconds,
|
||||
Duration & pulse_width,
|
||||
Time & phase_shift);
|
||||
void pulseWidthAndPhaseShiftToServoPulseDuration(Duration pulse_width,
|
||||
Duration phase_shift,
|
||||
DurationMicroseconds & pulse_duration_microseconds);
|
||||
|
||||
void setOutputsInverted(uint8_t device_index);
|
||||
void setOutputsNotInverted(uint8_t device_index);
|
||||
void setOutputsToTotemPole(uint8_t device_index);
|
||||
void setOutputsToOpenDrain(uint8_t device_index);
|
||||
void setOutputsLowWhenDisabled(uint8_t device_index);
|
||||
void setOutputsHighWhenDisabled(uint8_t device_index);
|
||||
void setOutputsHighImpedanceWhenDisabled(uint8_t device_index);
|
||||
void setOutputsInverted(DeviceIndex device_index);
|
||||
void setOutputsNotInverted(DeviceIndex device_index);
|
||||
void setOutputsToTotemPole(DeviceIndex device_index);
|
||||
void setOutputsToOpenDrain(DeviceIndex device_index);
|
||||
void setOutputsLowWhenDisabled(DeviceIndex device_index);
|
||||
void setOutputsHighWhenDisabled(DeviceIndex device_index);
|
||||
void setOutputsHighImpedanceWhenDisabled(DeviceIndex device_index);
|
||||
|
||||
const static uint8_t DOES_NOT_RESPOND = 0;
|
||||
const static uint8_t DOES_RESPOND = 1;
|
||||
@@ -325,10 +336,10 @@ private:
|
||||
// Use period instead of frequency to calculate prescale since it is linear
|
||||
// Measured 1620 Hz at prescale value 0x03, 1E6/1620=617
|
||||
// Datasheet says it should be 1526 Hz, 1E6/1526=655
|
||||
const static uint16_t PWM_PERIOD_MIN_US = 617;
|
||||
const static DurationMicroseconds PWM_PERIOD_MIN_US = 617;
|
||||
// Measured 25.3 Hz at prescale value 0xFF, 1E6/25.3=39525
|
||||
// Datasheet says it should be 24 Hz, 1E6/24=41666
|
||||
const static uint16_t PWM_PERIOD_MAX_US = 39525;
|
||||
const static DurationMicroseconds PWM_PERIOD_MAX_US = 39525;
|
||||
const static uint32_t MICROSECONDS_PER_SECOND = 1000000;
|
||||
|
||||
const static uint8_t OUTPUTS_INVERTED = 1;
|
||||
@@ -347,14 +358,14 @@ private:
|
||||
const static uint8_t RESTART_DISABLED = 0;
|
||||
const static uint8_t RESTART_CLEAR = 1;
|
||||
|
||||
const static uint16_t TIME_MIN = 0;
|
||||
const static uint16_t TIME_MAX = 4096;
|
||||
const static Time TIME_MIN = 0;
|
||||
const static Time TIME_MAX = 4096;
|
||||
|
||||
const static uint8_t PERCENT_MIN = 0;
|
||||
const static uint8_t PERCENT_MAX = 100;
|
||||
|
||||
const static uint16_t SERVO_FREQUENCY = 50;
|
||||
const static uint16_t SERVO_PERIOD_MICROSECONDS = 20000;
|
||||
const static Frequency SERVO_FREQUENCY = 50;
|
||||
const static DurationMicroseconds SERVO_PERIOD_MICROSECONDS = 20000;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// PCA9685.cpp
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#include "PCA9685.h"
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
PCA9685::PCA9685()
|
||||
{
|
||||
device_count_ = 0;
|
||||
for (uint8_t device_index=0; device_index<DEVICE_COUNT_MAX; ++device_index)
|
||||
for (DeviceIndex device_index=0; device_index<DEVICE_COUNT_MAX; ++device_index)
|
||||
{
|
||||
device_addresses_[device_index] = GENERAL_CALL_DEVICE_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
void PCA9685::setupSingleDevice(TwoWire & wire,
|
||||
uint8_t device_address,
|
||||
DeviceAddress device_address,
|
||||
bool fast_mode_plus)
|
||||
{
|
||||
setWire(Wire,fast_mode_plus);
|
||||
@@ -25,40 +25,40 @@ void PCA9685::setupSingleDevice(TwoWire & wire,
|
||||
resetAllDevices();
|
||||
}
|
||||
|
||||
void PCA9685::setupOutputEnablePin(size_t output_enable_pin)
|
||||
void PCA9685::setupOutputEnablePin(Pin output_enable_pin)
|
||||
{
|
||||
pinMode(output_enable_pin,OUTPUT);
|
||||
digitalWrite(output_enable_pin,HIGH);
|
||||
}
|
||||
|
||||
void PCA9685::enableOutputs(size_t output_enable_pin)
|
||||
void PCA9685::enableOutputs(Pin output_enable_pin)
|
||||
{
|
||||
digitalWrite(output_enable_pin,LOW);
|
||||
}
|
||||
|
||||
void PCA9685::disableOutputs(size_t output_enable_pin)
|
||||
void PCA9685::disableOutputs(Pin output_enable_pin)
|
||||
{
|
||||
digitalWrite(output_enable_pin,HIGH);
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getFrequencyMin()
|
||||
PCA9685::Frequency PCA9685::getFrequencyMin()
|
||||
{
|
||||
return MICROSECONDS_PER_SECOND / PWM_PERIOD_MAX_US;
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getFrequencyMax()
|
||||
PCA9685::Frequency PCA9685::getFrequencyMax()
|
||||
{
|
||||
return MICROSECONDS_PER_SECOND / PWM_PERIOD_MIN_US;
|
||||
}
|
||||
|
||||
void PCA9685::setToFrequency(uint16_t frequency)
|
||||
void PCA9685::setToFrequency(Frequency frequency)
|
||||
{
|
||||
setAllDevicesToFrequency(frequency);
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getFrequency()
|
||||
PCA9685::Frequency PCA9685::getFrequency()
|
||||
{
|
||||
uint16_t frequency = 0;
|
||||
Frequency frequency = 0;
|
||||
if (device_count_ > 0)
|
||||
{
|
||||
frequency = getSingleDeviceFrequency(device_addresses_[0]);
|
||||
@@ -71,166 +71,166 @@ void PCA9685::setToServoFrequency()
|
||||
setAllDevicesToServoFrequency();
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getServoFrequency()
|
||||
PCA9685::Frequency PCA9685::getServoFrequency()
|
||||
{
|
||||
return SERVO_FREQUENCY;
|
||||
}
|
||||
|
||||
uint8_t PCA9685::getChannelCount()
|
||||
PCA9685::ChannelCount PCA9685::getChannelCount()
|
||||
{
|
||||
return CHANNELS_PER_DEVICE * device_count_;
|
||||
}
|
||||
|
||||
double PCA9685::getDutyCycleMin()
|
||||
PCA9685::Percent PCA9685::getDutyCycleMin()
|
||||
{
|
||||
return PERCENT_MIN;
|
||||
}
|
||||
|
||||
double PCA9685::getDutyCycleMax()
|
||||
PCA9685::Percent PCA9685::getDutyCycleMax()
|
||||
{
|
||||
return PERCENT_MAX;
|
||||
}
|
||||
|
||||
double PCA9685::getPercentDelayMin()
|
||||
PCA9685::Percent PCA9685::getPercentDelayMin()
|
||||
{
|
||||
return PERCENT_MIN;
|
||||
}
|
||||
|
||||
double PCA9685::getPercentDelayMax()
|
||||
PCA9685::Percent PCA9685::getPercentDelayMax()
|
||||
{
|
||||
return PERCENT_MAX;
|
||||
}
|
||||
|
||||
void PCA9685::setChannelDutyCycle(uint8_t channel,
|
||||
double duty_cycle,
|
||||
double percent_delay)
|
||||
void PCA9685::setChannelDutyCycle(Channel channel,
|
||||
Percent duty_cycle,
|
||||
Percent percent_delay)
|
||||
{
|
||||
uint16_t pulse_width;
|
||||
uint16_t phase_shift;
|
||||
Duration pulse_width;
|
||||
Duration phase_shift;
|
||||
dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(duty_cycle,percent_delay,pulse_width,phase_shift);
|
||||
setChannelPulseWidth(channel,pulse_width,phase_shift);
|
||||
}
|
||||
|
||||
void PCA9685::getChannelDutyCycle(uint8_t channel,
|
||||
double & duty_cycle,
|
||||
double & percent_delay)
|
||||
void PCA9685::getChannelDutyCycle(Channel channel,
|
||||
Percent & duty_cycle,
|
||||
Percent & percent_delay)
|
||||
{
|
||||
uint16_t pulse_width;
|
||||
uint16_t phase_shift;
|
||||
Duration pulse_width;
|
||||
Duration phase_shift;
|
||||
getChannelPulseWidth(channel,pulse_width,phase_shift);
|
||||
pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(pulse_width,phase_shift,duty_cycle,percent_delay);
|
||||
}
|
||||
|
||||
void PCA9685::setAllChannelsDutyCycle(double duty_cycle,
|
||||
double percent_delay)
|
||||
void PCA9685::setAllChannelsDutyCycle(Percent duty_cycle,
|
||||
Percent percent_delay)
|
||||
{
|
||||
setAllDeviceChannelsDutyCycle(DEVICE_ADDRESS_ALL,duty_cycle,percent_delay);
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getPulseWidthMin()
|
||||
PCA9685::Duration PCA9685::getPulseWidthMin()
|
||||
{
|
||||
return TIME_MIN;
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getPulseWidthMax()
|
||||
PCA9685::Duration PCA9685::getPulseWidthMax()
|
||||
{
|
||||
return TIME_MAX;
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getPhaseShiftMin()
|
||||
PCA9685::Duration PCA9685::getPhaseShiftMin()
|
||||
{
|
||||
return TIME_MIN;
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getPhaseShiftMax()
|
||||
PCA9685::Duration PCA9685::getPhaseShiftMax()
|
||||
{
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
void PCA9685::setChannelPulseWidth(uint8_t channel,
|
||||
uint16_t pulse_width,
|
||||
uint16_t phase_shift)
|
||||
void PCA9685::setChannelPulseWidth(Channel channel,
|
||||
Duration pulse_width,
|
||||
Duration phase_shift)
|
||||
{
|
||||
uint16_t on_time;
|
||||
uint16_t off_time;
|
||||
Time on_time;
|
||||
Time off_time;
|
||||
pulseWidthAndPhaseShiftToOnTimeAndOffTime(pulse_width,phase_shift,on_time,off_time);
|
||||
setChannelOnAndOffTime(channel,on_time,off_time);
|
||||
}
|
||||
|
||||
void PCA9685::getChannelPulseWidth(uint8_t channel,
|
||||
uint16_t & pulse_width,
|
||||
uint16_t & phase_shift)
|
||||
void PCA9685::getChannelPulseWidth(Channel channel,
|
||||
Duration & pulse_width,
|
||||
Duration & phase_shift)
|
||||
{
|
||||
uint16_t on_time = 0;
|
||||
uint16_t off_time = 0;
|
||||
Time on_time = 0;
|
||||
Time off_time = 0;
|
||||
getChannelOnAndOffTime(channel,on_time,off_time);
|
||||
onTimeAndOffTimeToPulseWidthAndPhaseShift(on_time,off_time,pulse_width,phase_shift);
|
||||
}
|
||||
|
||||
void PCA9685::setAllChannelsPulseWidth(uint16_t pulse_width,
|
||||
uint16_t phase_shift)
|
||||
void PCA9685::setAllChannelsPulseWidth(Duration pulse_width,
|
||||
Duration phase_shift)
|
||||
{
|
||||
setAllDeviceChannelsPulseWidth(DEVICE_ADDRESS_ALL,pulse_width,phase_shift);
|
||||
}
|
||||
|
||||
void PCA9685::setChannelServoPulseDuration(uint8_t channel,
|
||||
uint16_t pulse_duration_microseconds)
|
||||
void PCA9685::setChannelServoPulseDuration(Channel channel,
|
||||
DurationMicroseconds pulse_duration_microseconds)
|
||||
{
|
||||
uint16_t pulse_width;
|
||||
uint16_t phase_shift;
|
||||
Duration pulse_width;
|
||||
Duration phase_shift;
|
||||
servoPulseDurationToPulseWidthAndPhaseShift(pulse_duration_microseconds,pulse_width,phase_shift);
|
||||
setChannelPulseWidth(channel,pulse_width,phase_shift);
|
||||
}
|
||||
|
||||
void PCA9685::getChannelServoPulseDuration(uint8_t channel,
|
||||
uint16_t & pulse_duration_microseconds)
|
||||
void PCA9685::getChannelServoPulseDuration(Channel channel,
|
||||
DurationMicroseconds & pulse_duration_microseconds)
|
||||
{
|
||||
uint16_t pulse_width;
|
||||
uint16_t phase_shift;
|
||||
Duration pulse_width;
|
||||
Duration phase_shift;
|
||||
getChannelPulseWidth(channel,pulse_width,phase_shift);
|
||||
pulseWidthAndPhaseShiftToServoPulseDuration(pulse_width,phase_shift,pulse_duration_microseconds);
|
||||
}
|
||||
|
||||
void PCA9685::setAllChannelsServoPulseDuration(uint16_t pulse_duration_microseconds)
|
||||
void PCA9685::setAllChannelsServoPulseDuration(DurationMicroseconds pulse_duration_microseconds)
|
||||
{
|
||||
setAllDeviceChannelsServoPulseDuration(DEVICE_ADDRESS_ALL,pulse_duration_microseconds);
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getTimeMin()
|
||||
PCA9685::Time PCA9685::getTimeMin()
|
||||
{
|
||||
return TIME_MIN;
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getTimeMax()
|
||||
PCA9685::Time PCA9685::getTimeMax()
|
||||
{
|
||||
return TIME_MAX;
|
||||
}
|
||||
|
||||
void PCA9685::setChannelOnAndOffTime(uint8_t channel,
|
||||
uint16_t on_time,
|
||||
uint16_t off_time)
|
||||
void PCA9685::setChannelOnAndOffTime(Channel channel,
|
||||
Time on_time,
|
||||
Time off_time)
|
||||
{
|
||||
if (channel >= getChannelCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint8_t device_index = channelToDeviceIndex(channel);
|
||||
uint8_t device_channel = channelToDeviceChannel(channel);
|
||||
DeviceIndex device_index = channelToDeviceIndex(channel);
|
||||
Channel device_channel = channelToDeviceChannel(channel);
|
||||
uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
|
||||
uint32_t data = (off_time << BITS_PER_TWO_BYTES) | on_time;
|
||||
write(device_addresses_[device_index],register_address,data);
|
||||
}
|
||||
|
||||
void PCA9685::getChannelOnAndOffTime(uint8_t channel,
|
||||
uint16_t & on_time,
|
||||
uint16_t & off_time)
|
||||
void PCA9685::getChannelOnAndOffTime(Channel channel,
|
||||
Time & on_time,
|
||||
Time & off_time)
|
||||
{
|
||||
if (channel >= getChannelCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint8_t device_index = channelToDeviceIndex(channel);
|
||||
uint8_t device_channel = channelToDeviceChannel(channel);
|
||||
DeviceIndex device_index = channelToDeviceIndex(channel);
|
||||
Channel device_channel = channelToDeviceChannel(channel);
|
||||
uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
|
||||
uint32_t data;
|
||||
read(device_index,register_address,data);
|
||||
@@ -238,70 +238,70 @@ void PCA9685::getChannelOnAndOffTime(uint8_t channel,
|
||||
off_time = (data >> BITS_PER_TWO_BYTES) & TWO_BYTE_MAX;
|
||||
}
|
||||
|
||||
void PCA9685::setAllChannelsOnAndOffTime(uint16_t on_time,
|
||||
uint16_t off_time)
|
||||
void PCA9685::setAllChannelsOnAndOffTime(Time on_time,
|
||||
Time off_time)
|
||||
{
|
||||
setAllDeviceChannelsOnAndOffTime(DEVICE_ADDRESS_ALL,on_time,off_time);
|
||||
}
|
||||
|
||||
void PCA9685::setChannelOnTime(uint8_t channel,
|
||||
uint16_t on_time)
|
||||
void PCA9685::setChannelOnTime(Channel channel,
|
||||
Time on_time)
|
||||
{
|
||||
if (channel >= getChannelCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint8_t device_index = channelToDeviceIndex(channel);
|
||||
uint8_t device_channel = channelToDeviceChannel(channel);
|
||||
DeviceIndex device_index = channelToDeviceIndex(channel);
|
||||
Channel device_channel = channelToDeviceChannel(channel);
|
||||
uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
|
||||
write(device_addresses_[device_index],register_address,on_time);
|
||||
}
|
||||
|
||||
void PCA9685::getChannelOnTime(uint8_t channel,
|
||||
uint16_t & on_time)
|
||||
void PCA9685::getChannelOnTime(Channel channel,
|
||||
Time & on_time)
|
||||
{
|
||||
if (channel >= getChannelCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint8_t device_index = channelToDeviceIndex(channel);
|
||||
uint8_t device_channel = channelToDeviceChannel(channel);
|
||||
DeviceIndex device_index = channelToDeviceIndex(channel);
|
||||
Channel device_channel = channelToDeviceChannel(channel);
|
||||
uint8_t register_address = LED0_ON_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
|
||||
read(device_index,register_address,on_time);
|
||||
}
|
||||
|
||||
void PCA9685::setAllChannelsOnTime(uint16_t on_time)
|
||||
void PCA9685::setAllChannelsOnTime(Time on_time)
|
||||
{
|
||||
setAllDeviceChannelsOnTime(DEVICE_ADDRESS_ALL,on_time);
|
||||
}
|
||||
|
||||
void PCA9685::setChannelOffTime(uint8_t channel,
|
||||
uint16_t off_time)
|
||||
void PCA9685::setChannelOffTime(Channel channel,
|
||||
Time off_time)
|
||||
{
|
||||
if (channel >= getChannelCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint8_t device_index = channelToDeviceIndex(channel);
|
||||
uint8_t device_channel = channelToDeviceChannel(channel);
|
||||
DeviceIndex device_index = channelToDeviceIndex(channel);
|
||||
Channel device_channel = channelToDeviceChannel(channel);
|
||||
uint8_t register_address = LED0_OFF_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
|
||||
write(device_addresses_[device_index],register_address,off_time);
|
||||
}
|
||||
|
||||
void PCA9685::getChannelOffTime(uint8_t channel,
|
||||
uint16_t & off_time)
|
||||
void PCA9685::getChannelOffTime(Channel channel,
|
||||
Time & off_time)
|
||||
{
|
||||
if (channel >= getChannelCount())
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint8_t device_index = channelToDeviceIndex(channel);
|
||||
uint8_t device_channel = channelToDeviceChannel(channel);
|
||||
DeviceIndex device_index = channelToDeviceIndex(channel);
|
||||
Channel device_channel = channelToDeviceChannel(channel);
|
||||
uint8_t register_address = LED0_OFF_L_REGISTER_ADDRESS + LED_REGISTERS_SIZE * device_channel;
|
||||
read(device_index,register_address,off_time);
|
||||
}
|
||||
|
||||
void PCA9685::setAllChannelsOffTime(uint16_t off_time)
|
||||
void PCA9685::setAllChannelsOffTime(Time off_time)
|
||||
{
|
||||
setAllDeviceChannelsOffTime(DEVICE_ADDRESS_ALL,off_time);
|
||||
}
|
||||
@@ -353,7 +353,7 @@ void PCA9685::setWire(TwoWire & wire,
|
||||
|
||||
}
|
||||
|
||||
void PCA9685::addDevice(uint8_t device_address)
|
||||
void PCA9685::addDevice(DeviceAddress device_address)
|
||||
{
|
||||
if ((device_count_ >= DEVICE_COUNT_MAX) ||
|
||||
(device_address < DEVICE_ADDRESS_MIN) ||
|
||||
@@ -378,7 +378,7 @@ void PCA9685::resetAllDevices()
|
||||
wakeAll();
|
||||
}
|
||||
|
||||
void PCA9685::addDeviceToGroup0(uint8_t device_address)
|
||||
void PCA9685::addDeviceToGroup0(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -390,7 +390,7 @@ void PCA9685::addDeviceToGroup0(uint8_t device_address)
|
||||
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::removeDeviceFromGroup0(uint8_t device_address)
|
||||
void PCA9685::removeDeviceFromGroup0(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -402,7 +402,7 @@ void PCA9685::removeDeviceFromGroup0(uint8_t device_address)
|
||||
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::addDeviceToGroup1(uint8_t device_address)
|
||||
void PCA9685::addDeviceToGroup1(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -414,7 +414,7 @@ void PCA9685::addDeviceToGroup1(uint8_t device_address)
|
||||
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::removeDeviceFromGroup1(uint8_t device_address)
|
||||
void PCA9685::removeDeviceFromGroup1(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -426,7 +426,7 @@ void PCA9685::removeDeviceFromGroup1(uint8_t device_address)
|
||||
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::addDeviceToGroup2(uint8_t device_address)
|
||||
void PCA9685::addDeviceToGroup2(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -438,7 +438,7 @@ void PCA9685::addDeviceToGroup2(uint8_t device_address)
|
||||
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::removeDeviceFromGroup2(uint8_t device_address)
|
||||
void PCA9685::removeDeviceFromGroup2(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -450,8 +450,8 @@ void PCA9685::removeDeviceFromGroup2(uint8_t device_address)
|
||||
write(device_address,MODE1_REGISTER_ADDRESS,mode1_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::setSingleDeviceToFrequency(uint8_t device_address,
|
||||
uint16_t frequency)
|
||||
void PCA9685::setSingleDeviceToFrequency(DeviceAddress device_address,
|
||||
Frequency frequency)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -462,9 +462,9 @@ void PCA9685::setSingleDeviceToFrequency(uint8_t device_address,
|
||||
setPrescale(device_index,prescale);
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getSingleDeviceFrequency(uint8_t device_address)
|
||||
PCA9685::Frequency PCA9685::getSingleDeviceFrequency(DeviceAddress device_address)
|
||||
{
|
||||
uint16_t frequency = 0;
|
||||
Frequency frequency = 0;
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index >= 0)
|
||||
{
|
||||
@@ -475,21 +475,21 @@ uint16_t PCA9685::getSingleDeviceFrequency(uint8_t device_address)
|
||||
return frequency;
|
||||
}
|
||||
|
||||
void PCA9685::setAllDevicesToFrequency(uint16_t frequency)
|
||||
void PCA9685::setAllDevicesToFrequency(Frequency frequency)
|
||||
{
|
||||
uint8_t prescale = frequencyToPrescale(frequency);
|
||||
for (uint8_t device_index=0; device_index<device_count_; ++device_index)
|
||||
for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
|
||||
{
|
||||
setPrescale(device_index,prescale);
|
||||
}
|
||||
}
|
||||
|
||||
void PCA9685::setSingleDeviceToServoFrequency(uint8_t device_address)
|
||||
void PCA9685::setSingleDeviceToServoFrequency(DeviceAddress device_address)
|
||||
{
|
||||
setSingleDeviceToFrequency(device_address,SERVO_FREQUENCY);
|
||||
}
|
||||
|
||||
uint16_t PCA9685::getSingleDeviceServoFrequency(uint8_t device_address)
|
||||
PCA9685::Frequency PCA9685::getSingleDeviceServoFrequency(DeviceAddress device_address)
|
||||
{
|
||||
return SERVO_FREQUENCY;
|
||||
}
|
||||
@@ -504,71 +504,71 @@ uint8_t PCA9685::getDeviceChannelCount()
|
||||
return CHANNELS_PER_DEVICE;
|
||||
}
|
||||
|
||||
void PCA9685::setDeviceChannelDutyCycle(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
double duty_cycle,
|
||||
double percent_delay)
|
||||
void PCA9685::setDeviceChannelDutyCycle(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
Percent duty_cycle,
|
||||
Percent percent_delay)
|
||||
{
|
||||
uint16_t pulse_width;
|
||||
uint16_t phase_shift;
|
||||
Duration pulse_width;
|
||||
Duration phase_shift;
|
||||
dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(duty_cycle,percent_delay,pulse_width,phase_shift);
|
||||
setDeviceChannelPulseWidth(device_address,device_channel,pulse_width,phase_shift);
|
||||
}
|
||||
|
||||
void PCA9685::setAllDeviceChannelsDutyCycle(uint8_t device_address,
|
||||
double duty_cycle,
|
||||
double percent_delay)
|
||||
void PCA9685::setAllDeviceChannelsDutyCycle(DeviceAddress device_address,
|
||||
Percent duty_cycle,
|
||||
Percent percent_delay)
|
||||
{
|
||||
uint16_t pulse_width;
|
||||
uint16_t phase_shift;
|
||||
Duration pulse_width;
|
||||
Duration phase_shift;
|
||||
dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(duty_cycle,percent_delay,pulse_width,phase_shift);
|
||||
setAllDeviceChannelsPulseWidth(device_address,pulse_width,phase_shift);
|
||||
}
|
||||
|
||||
void PCA9685::setDeviceChannelPulseWidth(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
uint16_t pulse_width,
|
||||
uint16_t phase_shift)
|
||||
void PCA9685::setDeviceChannelPulseWidth(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
Duration pulse_width,
|
||||
Duration phase_shift)
|
||||
{
|
||||
uint16_t on_time;
|
||||
uint16_t off_time;
|
||||
Time on_time;
|
||||
Time off_time;
|
||||
pulseWidthAndPhaseShiftToOnTimeAndOffTime(pulse_width,phase_shift,on_time,off_time);
|
||||
setDeviceChannelOnAndOffTime(device_address,device_channel,on_time,off_time);
|
||||
}
|
||||
|
||||
void PCA9685::setAllDeviceChannelsPulseWidth(uint8_t device_address,
|
||||
uint16_t pulse_width,
|
||||
uint16_t phase_shift)
|
||||
void PCA9685::setAllDeviceChannelsPulseWidth(DeviceAddress device_address,
|
||||
Duration pulse_width,
|
||||
Duration phase_shift)
|
||||
{
|
||||
uint16_t on_time;
|
||||
uint16_t off_time;
|
||||
Time on_time;
|
||||
Time off_time;
|
||||
pulseWidthAndPhaseShiftToOnTimeAndOffTime(pulse_width,phase_shift,on_time,off_time);
|
||||
setAllDeviceChannelsOnAndOffTime(device_address,on_time,off_time);
|
||||
}
|
||||
|
||||
void PCA9685::setDeviceChannelServoPulseDuration(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
uint16_t pulse_duration_microseconds)
|
||||
void PCA9685::setDeviceChannelServoPulseDuration(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
DurationMicroseconds pulse_duration_microseconds)
|
||||
{
|
||||
uint16_t pulse_width;
|
||||
uint16_t phase_shift;
|
||||
Duration pulse_width;
|
||||
Duration phase_shift;
|
||||
servoPulseDurationToPulseWidthAndPhaseShift(pulse_duration_microseconds,pulse_width,phase_shift);
|
||||
setDeviceChannelPulseWidth(device_address,device_channel,pulse_width,phase_shift);
|
||||
}
|
||||
|
||||
void PCA9685::setAllDeviceChannelsServoPulseDuration(uint8_t device_address,
|
||||
uint16_t pulse_duration_microseconds)
|
||||
void PCA9685::setAllDeviceChannelsServoPulseDuration(DeviceAddress device_address,
|
||||
DurationMicroseconds pulse_duration_microseconds)
|
||||
{
|
||||
uint16_t pulse_width;
|
||||
uint16_t phase_shift;
|
||||
Duration pulse_width;
|
||||
Duration phase_shift;
|
||||
servoPulseDurationToPulseWidthAndPhaseShift(pulse_duration_microseconds,pulse_width,phase_shift);
|
||||
setAllDeviceChannelsPulseWidth(device_address,pulse_width,phase_shift);
|
||||
}
|
||||
|
||||
void PCA9685::setDeviceChannelOnAndOffTime(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
uint16_t on_time,
|
||||
uint16_t off_time)
|
||||
void PCA9685::setDeviceChannelOnAndOffTime(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
Time on_time,
|
||||
Time off_time)
|
||||
{
|
||||
if (device_channel >= getDeviceChannelCount())
|
||||
{
|
||||
@@ -579,18 +579,18 @@ void PCA9685::setDeviceChannelOnAndOffTime(uint8_t device_address,
|
||||
write(device_address,register_address,data);
|
||||
}
|
||||
|
||||
void PCA9685::setAllDeviceChannelsOnAndOffTime(uint8_t device_address,
|
||||
uint16_t on_time,
|
||||
uint16_t off_time)
|
||||
void PCA9685::setAllDeviceChannelsOnAndOffTime(DeviceAddress device_address,
|
||||
Time on_time,
|
||||
Time off_time)
|
||||
{
|
||||
uint8_t register_address = ALL_LED_ON_L_REGISTER_ADDRESS;
|
||||
uint32_t data = (off_time << BITS_PER_TWO_BYTES) | on_time;
|
||||
write(device_address,register_address,data);
|
||||
}
|
||||
|
||||
void PCA9685::setDeviceChannelOnTime(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
uint16_t on_time)
|
||||
void PCA9685::setDeviceChannelOnTime(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
Time on_time)
|
||||
{
|
||||
if (device_channel >= getDeviceChannelCount())
|
||||
{
|
||||
@@ -600,16 +600,16 @@ void PCA9685::setDeviceChannelOnTime(uint8_t device_address,
|
||||
write(device_address,register_address,on_time);
|
||||
}
|
||||
|
||||
void PCA9685::setAllDeviceChannelsOnTime(uint8_t device_address,
|
||||
uint16_t on_time)
|
||||
void PCA9685::setAllDeviceChannelsOnTime(DeviceAddress device_address,
|
||||
Time on_time)
|
||||
{
|
||||
uint8_t register_address = ALL_LED_ON_L_REGISTER_ADDRESS;
|
||||
write(device_address,register_address,on_time);
|
||||
}
|
||||
|
||||
void PCA9685::setDeviceChannelOffTime(uint8_t device_address,
|
||||
uint8_t device_channel,
|
||||
uint16_t off_time)
|
||||
void PCA9685::setDeviceChannelOffTime(DeviceAddress device_address,
|
||||
Channel device_channel,
|
||||
Time off_time)
|
||||
{
|
||||
if (device_channel >= getDeviceChannelCount())
|
||||
{
|
||||
@@ -619,14 +619,14 @@ void PCA9685::setDeviceChannelOffTime(uint8_t device_address,
|
||||
write(device_address,register_address,off_time);
|
||||
}
|
||||
|
||||
void PCA9685::setAllDeviceChannelsOffTime(uint8_t device_address,
|
||||
uint16_t off_time)
|
||||
void PCA9685::setAllDeviceChannelsOffTime(DeviceAddress device_address,
|
||||
Time off_time)
|
||||
{
|
||||
uint8_t register_address = ALL_LED_OFF_L_REGISTER_ADDRESS;
|
||||
write(device_address,register_address,off_time);
|
||||
}
|
||||
|
||||
void PCA9685::setSingleDeviceOutputsInverted(uint8_t device_address)
|
||||
void PCA9685::setSingleDeviceOutputsInverted(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -638,13 +638,13 @@ void PCA9685::setSingleDeviceOutputsInverted(uint8_t device_address)
|
||||
|
||||
void PCA9685::setAllDevicesOutputsInverted()
|
||||
{
|
||||
for (uint8_t device_index=0; device_index<device_count_; ++device_index)
|
||||
for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
|
||||
{
|
||||
setOutputsInverted(device_index);
|
||||
}
|
||||
}
|
||||
|
||||
void PCA9685::setSingleDeviceOutputsNotInverted(uint8_t device_address)
|
||||
void PCA9685::setSingleDeviceOutputsNotInverted(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -656,13 +656,13 @@ void PCA9685::setSingleDeviceOutputsNotInverted(uint8_t device_address)
|
||||
|
||||
void PCA9685::setAllDevicesOutputsNotInverted()
|
||||
{
|
||||
for (uint8_t device_index=0; device_index<device_count_; ++device_index)
|
||||
for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
|
||||
{
|
||||
setOutputsNotInverted(device_index);
|
||||
}
|
||||
}
|
||||
|
||||
void PCA9685::setSingleDeviceOutputsToTotemPole(uint8_t device_address)
|
||||
void PCA9685::setSingleDeviceOutputsToTotemPole(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -674,13 +674,13 @@ void PCA9685::setSingleDeviceOutputsToTotemPole(uint8_t device_address)
|
||||
|
||||
void PCA9685::setAllDevicesOutputsToTotemPole()
|
||||
{
|
||||
for (uint8_t device_index=0; device_index<device_count_; ++device_index)
|
||||
for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
|
||||
{
|
||||
setOutputsToTotemPole(device_index);
|
||||
}
|
||||
}
|
||||
|
||||
void PCA9685::setSingleDeviceOutputsToOpenDrain(uint8_t device_address)
|
||||
void PCA9685::setSingleDeviceOutputsToOpenDrain(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -692,13 +692,13 @@ void PCA9685::setSingleDeviceOutputsToOpenDrain(uint8_t device_address)
|
||||
|
||||
void PCA9685::setAllDevicesOutputsToOpenDrain()
|
||||
{
|
||||
for (uint8_t device_index=0; device_index<device_count_; ++device_index)
|
||||
for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
|
||||
{
|
||||
setOutputsToOpenDrain(device_index);
|
||||
}
|
||||
}
|
||||
|
||||
void PCA9685::setSingleDeviceOutputsLowWhenDisabled(uint8_t device_address)
|
||||
void PCA9685::setSingleDeviceOutputsLowWhenDisabled(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -710,13 +710,13 @@ void PCA9685::setSingleDeviceOutputsLowWhenDisabled(uint8_t device_address)
|
||||
|
||||
void PCA9685::setAllDevicesOutputsLowWhenDisabled()
|
||||
{
|
||||
for (uint8_t device_index=0; device_index<device_count_; ++device_index)
|
||||
for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
|
||||
{
|
||||
setOutputsLowWhenDisabled(device_index);
|
||||
}
|
||||
}
|
||||
|
||||
void PCA9685::setSingleDeviceOutputsHighWhenDisabled(uint8_t device_address)
|
||||
void PCA9685::setSingleDeviceOutputsHighWhenDisabled(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -728,13 +728,13 @@ void PCA9685::setSingleDeviceOutputsHighWhenDisabled(uint8_t device_address)
|
||||
|
||||
void PCA9685::setAllDevicesOutputsHighWhenDisabled()
|
||||
{
|
||||
for (uint8_t device_index=0; device_index<device_count_; ++device_index)
|
||||
for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
|
||||
{
|
||||
setOutputsHighWhenDisabled(device_index);
|
||||
}
|
||||
}
|
||||
|
||||
void PCA9685::setSingleDeviceOutputsHighImpedanceWhenDisabled(uint8_t device_address)
|
||||
void PCA9685::setSingleDeviceOutputsHighImpedanceWhenDisabled(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = deviceAddressToDeviceIndex(device_address);
|
||||
if (device_index < 0)
|
||||
@@ -746,7 +746,7 @@ void PCA9685::setSingleDeviceOutputsHighImpedanceWhenDisabled(uint8_t device_add
|
||||
|
||||
void PCA9685::setAllDevicesOutputsHighImpedanceWhenDisabled()
|
||||
{
|
||||
for (uint8_t device_index=0; device_index<device_count_; ++device_index)
|
||||
for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
|
||||
{
|
||||
setOutputsHighImpedanceWhenDisabled(device_index);
|
||||
}
|
||||
@@ -754,7 +754,7 @@ void PCA9685::setAllDevicesOutputsHighImpedanceWhenDisabled()
|
||||
|
||||
// private
|
||||
|
||||
int PCA9685::deviceAddressToDeviceIndex(uint8_t device_address)
|
||||
int PCA9685::deviceAddressToDeviceIndex(DeviceAddress device_address)
|
||||
{
|
||||
int device_index = DEVICE_INDEX_NONE;
|
||||
if (device_address == DEVICE_ADDRESS_ALL)
|
||||
@@ -787,28 +787,28 @@ int PCA9685::deviceAddressToDeviceIndex(uint8_t device_address)
|
||||
return device_index;
|
||||
}
|
||||
|
||||
PCA9685::Mode1Register PCA9685::readMode1Register(uint8_t device_index)
|
||||
PCA9685::Mode1Register PCA9685::readMode1Register(DeviceIndex device_index)
|
||||
{
|
||||
Mode1Register mode1_register;
|
||||
read(device_index,MODE1_REGISTER_ADDRESS,mode1_register.data);
|
||||
return mode1_register;
|
||||
}
|
||||
|
||||
PCA9685::Mode2Register PCA9685::readMode2Register(uint8_t device_index)
|
||||
PCA9685::Mode2Register PCA9685::readMode2Register(DeviceIndex device_index)
|
||||
{
|
||||
Mode2Register mode2_register;
|
||||
read(device_index,MODE2_REGISTER_ADDRESS,mode2_register.data);
|
||||
return mode2_register;
|
||||
}
|
||||
|
||||
void PCA9685::sleep(uint8_t device_index)
|
||||
void PCA9685::sleep(DeviceIndex device_index)
|
||||
{
|
||||
Mode1Register mode1_register = readMode1Register(device_index);
|
||||
mode1_register.fields.sleep = SLEEP;
|
||||
write(device_addresses_[device_index],MODE1_REGISTER_ADDRESS,mode1_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::wake(uint8_t device_index)
|
||||
void PCA9685::wake(DeviceIndex device_index)
|
||||
{
|
||||
Mode1Register mode1_register = readMode1Register(device_index);
|
||||
mode1_register.fields.sleep = WAKE;
|
||||
@@ -824,13 +824,13 @@ void PCA9685::wake(uint8_t device_index)
|
||||
|
||||
void PCA9685::wakeAll()
|
||||
{
|
||||
for (uint8_t device_index=0; device_index<device_count_; ++device_index)
|
||||
for (DeviceIndex device_index=0; device_index<device_count_; ++device_index)
|
||||
{
|
||||
wake(device_index);
|
||||
}
|
||||
}
|
||||
|
||||
void PCA9685::setPrescale(uint8_t device_index,
|
||||
void PCA9685::setPrescale(DeviceIndex device_index,
|
||||
uint8_t prescale)
|
||||
{
|
||||
sleep(device_index);
|
||||
@@ -838,24 +838,24 @@ void PCA9685::setPrescale(uint8_t device_index,
|
||||
wake(device_index);
|
||||
}
|
||||
|
||||
void PCA9685::getPrescale(uint8_t device_index,
|
||||
void PCA9685::getPrescale(DeviceIndex device_index,
|
||||
uint8_t & prescale)
|
||||
{
|
||||
read(device_index,PRE_SCALE_REGISTER_ADDRESS,prescale);
|
||||
}
|
||||
|
||||
uint8_t PCA9685::frequencyToPrescale(uint16_t frequency)
|
||||
uint8_t PCA9685::frequencyToPrescale(Frequency frequency)
|
||||
{
|
||||
uint16_t period_us = MICROSECONDS_PER_SECOND / frequency;
|
||||
DurationMicroseconds period_us = MICROSECONDS_PER_SECOND / frequency;
|
||||
period_us = constrain(period_us,PWM_PERIOD_MIN_US,PWM_PERIOD_MAX_US);
|
||||
uint8_t prescale = map(period_us,PWM_PERIOD_MIN_US,PWM_PERIOD_MAX_US,PRE_SCALE_MIN,PRE_SCALE_MAX);
|
||||
return prescale;
|
||||
}
|
||||
|
||||
uint16_t PCA9685::prescaleToFrequency(uint8_t prescale)
|
||||
PCA9685::Frequency PCA9685::prescaleToFrequency(uint8_t prescale)
|
||||
{
|
||||
uint16_t frequency = 0;
|
||||
uint16_t period_us = map(prescale,PRE_SCALE_MIN,PRE_SCALE_MAX,PWM_PERIOD_MIN_US,PWM_PERIOD_MAX_US);
|
||||
Frequency frequency = 0;
|
||||
DurationMicroseconds period_us = map(prescale,PRE_SCALE_MIN,PRE_SCALE_MAX,PWM_PERIOD_MIN_US,PWM_PERIOD_MAX_US);
|
||||
if (period_us > 0)
|
||||
{
|
||||
frequency = round((double)MICROSECONDS_PER_SECOND / (double)period_us);
|
||||
@@ -863,38 +863,38 @@ uint16_t PCA9685::prescaleToFrequency(uint8_t prescale)
|
||||
return frequency;
|
||||
}
|
||||
|
||||
uint8_t PCA9685::channelToDeviceIndex(uint8_t channel)
|
||||
uint8_t PCA9685::channelToDeviceIndex(Channel channel)
|
||||
{
|
||||
return channel / CHANNELS_PER_DEVICE;
|
||||
}
|
||||
|
||||
uint8_t PCA9685::channelToDeviceChannel(uint8_t channel)
|
||||
PCA9685::Channel PCA9685::channelToDeviceChannel(Channel channel)
|
||||
{
|
||||
return channel % CHANNELS_PER_DEVICE;
|
||||
}
|
||||
|
||||
void PCA9685::dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(double duty_cycle,
|
||||
double percent_delay,
|
||||
uint16_t & pulse_width,
|
||||
uint16_t & phase_shift)
|
||||
void PCA9685::dutyCycleAndPercentDelayToPulseWidthAndPhaseShift(Percent duty_cycle,
|
||||
Percent percent_delay,
|
||||
Duration & pulse_width,
|
||||
Duration & phase_shift)
|
||||
{
|
||||
pulse_width = round(((double)TIME_MAX * duty_cycle) / (double)PERCENT_MAX);
|
||||
phase_shift = round(((double)TIME_MAX * percent_delay) / (double)PERCENT_MAX);
|
||||
}
|
||||
|
||||
void PCA9685::pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(uint16_t pulse_width,
|
||||
uint16_t phase_shift,
|
||||
double & duty_cycle,
|
||||
double & percent_delay)
|
||||
void PCA9685::pulseWidthAndPhaseShiftToDutyCycleAndPercentDelay(Duration pulse_width,
|
||||
Duration phase_shift,
|
||||
Percent & duty_cycle,
|
||||
Percent & percent_delay)
|
||||
{
|
||||
duty_cycle = (double)(pulse_width * PERCENT_MAX) / (double)TIME_MAX;
|
||||
percent_delay = (double)(phase_shift * PERCENT_MAX) / (double)TIME_MAX;
|
||||
}
|
||||
|
||||
void PCA9685::pulseWidthAndPhaseShiftToOnTimeAndOffTime(uint16_t pulse_width,
|
||||
uint16_t phase_shift,
|
||||
uint16_t & on_time,
|
||||
uint16_t & off_time)
|
||||
void PCA9685::pulseWidthAndPhaseShiftToOnTimeAndOffTime(Duration pulse_width,
|
||||
Duration phase_shift,
|
||||
Time & on_time,
|
||||
Time & off_time)
|
||||
{
|
||||
if (pulse_width == TIME_MIN)
|
||||
{
|
||||
@@ -912,10 +912,10 @@ void PCA9685::pulseWidthAndPhaseShiftToOnTimeAndOffTime(uint16_t pulse_width,
|
||||
off_time = (on_time + pulse_width) % TIME_MAX;
|
||||
}
|
||||
|
||||
void PCA9685::onTimeAndOffTimeToPulseWidthAndPhaseShift(uint16_t on_time,
|
||||
uint16_t off_time,
|
||||
uint16_t & pulse_width,
|
||||
uint16_t & phase_shift)
|
||||
void PCA9685::onTimeAndOffTimeToPulseWidthAndPhaseShift(Time on_time,
|
||||
Time off_time,
|
||||
Duration & pulse_width,
|
||||
Duration & phase_shift)
|
||||
{
|
||||
if (on_time == TIME_MAX)
|
||||
{
|
||||
@@ -939,65 +939,65 @@ void PCA9685::onTimeAndOffTimeToPulseWidthAndPhaseShift(uint16_t on_time,
|
||||
phase_shift = on_time;
|
||||
}
|
||||
|
||||
void PCA9685::servoPulseDurationToPulseWidthAndPhaseShift(uint16_t pulse_duration_microseconds,
|
||||
uint16_t & pulse_width,
|
||||
uint16_t & phase_shift)
|
||||
void PCA9685::servoPulseDurationToPulseWidthAndPhaseShift(DurationMicroseconds pulse_duration_microseconds,
|
||||
Duration & pulse_width,
|
||||
Duration & phase_shift)
|
||||
{
|
||||
phase_shift = 0;
|
||||
pulse_width = (pulse_duration_microseconds * TIME_MAX) / SERVO_PERIOD_MICROSECONDS;
|
||||
}
|
||||
|
||||
void PCA9685::pulseWidthAndPhaseShiftToServoPulseDuration(uint16_t pulse_width,
|
||||
uint16_t phase_shift,
|
||||
uint16_t & pulse_duration_microseconds)
|
||||
void PCA9685::pulseWidthAndPhaseShiftToServoPulseDuration(Duration pulse_width,
|
||||
Duration phase_shift,
|
||||
DurationMicroseconds & pulse_duration_microseconds)
|
||||
{
|
||||
uint16_t period_us = SERVO_PERIOD_MICROSECONDS;
|
||||
DurationMicroseconds period_us = SERVO_PERIOD_MICROSECONDS;
|
||||
pulse_duration_microseconds = (pulse_width * period_us) / TIME_MAX;
|
||||
}
|
||||
|
||||
void PCA9685::setOutputsInverted(uint8_t device_index)
|
||||
void PCA9685::setOutputsInverted(DeviceIndex device_index)
|
||||
{
|
||||
Mode2Register mode2_register = readMode2Register(device_index);
|
||||
mode2_register.fields.invrt = OUTPUTS_INVERTED;
|
||||
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::setOutputsNotInverted(uint8_t device_index)
|
||||
void PCA9685::setOutputsNotInverted(DeviceIndex device_index)
|
||||
{
|
||||
Mode2Register mode2_register = readMode2Register(device_index);
|
||||
mode2_register.fields.invrt = OUTPUTS_NOT_INVERTED;
|
||||
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::setOutputsToTotemPole(uint8_t device_index)
|
||||
void PCA9685::setOutputsToTotemPole(DeviceIndex device_index)
|
||||
{
|
||||
Mode2Register mode2_register = readMode2Register(device_index);
|
||||
mode2_register.fields.outdrv = OUTPUTS_TOTEM_POLE;
|
||||
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::setOutputsToOpenDrain(uint8_t device_index)
|
||||
void PCA9685::setOutputsToOpenDrain(DeviceIndex device_index)
|
||||
{
|
||||
Mode2Register mode2_register = readMode2Register(device_index);
|
||||
mode2_register.fields.outdrv = OUTPUTS_OPEN_DRAIN;
|
||||
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::setOutputsLowWhenDisabled(uint8_t device_index)
|
||||
void PCA9685::setOutputsLowWhenDisabled(DeviceIndex device_index)
|
||||
{
|
||||
Mode2Register mode2_register = readMode2Register(device_index);
|
||||
mode2_register.fields.outne = OUTPUTS_LOW_WHEN_DISABLED;
|
||||
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::setOutputsHighWhenDisabled(uint8_t device_index)
|
||||
void PCA9685::setOutputsHighWhenDisabled(DeviceIndex device_index)
|
||||
{
|
||||
Mode2Register mode2_register = readMode2Register(device_index);
|
||||
mode2_register.fields.outne = OUTPUTS_HIGH_WHEN_DISABLED;
|
||||
write(device_addresses_[device_index],MODE2_REGISTER_ADDRESS,mode2_register.data);
|
||||
}
|
||||
|
||||
void PCA9685::setOutputsHighImpedanceWhenDisabled(uint8_t device_index)
|
||||
void PCA9685::setOutputsHighImpedanceWhenDisabled(DeviceIndex device_index)
|
||||
{
|
||||
Mode2Register mode2_register = readMode2Register(device_index);
|
||||
mode2_register.fields.outne = OUTPUTS_HIGH_IMPEDANCE_WHEN_DISABLED;
|
||||
|
||||
@@ -3,29 +3,31 @@
|
||||
//
|
||||
//
|
||||
// Authors:
|
||||
// Peter Polidoro peterpolidoro@gmail.com
|
||||
// Peter Polidoro peter@polidoro.io
|
||||
// ----------------------------------------------------------------------------
|
||||
#ifndef PCA9685_DEFINITIONS_H
|
||||
#define PCA9685_DEFINITIONS_H
|
||||
|
||||
|
||||
template<typename T>
|
||||
void PCA9685::write(uint8_t device_address,
|
||||
void PCA9685::write(DeviceAddress device_address,
|
||||
uint8_t register_address,
|
||||
T data)
|
||||
{
|
||||
int byte_count = sizeof(data);
|
||||
wire_ptr_->beginTransmission(device_address);
|
||||
wire_ptr_->write(register_address);
|
||||
uint8_t write_byte;
|
||||
for (int byte_n=0; byte_n<byte_count; ++byte_n)
|
||||
{
|
||||
wire_ptr_->write((data >> (BITS_PER_BYTE * byte_n)) & BYTE_MAX);
|
||||
write_byte = (data >> (BITS_PER_BYTE * byte_n)) & BYTE_MAX;
|
||||
wire_ptr_->write(write_byte);
|
||||
}
|
||||
wire_ptr_->endTransmission();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void PCA9685::read(uint8_t device_index,
|
||||
void PCA9685::read(DeviceIndex device_index,
|
||||
uint8_t register_address,
|
||||
T & data)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user