1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-26 07:02:15 +03:00

Support multiple tone(), analogWrite(), and Servo (#4640)

Remove and rewrite all the parts of the core/libraries using TIMER1
and consolidate into a single, shared waveform generation interrupt
structure.  Tone, analogWrite(), Servo all now just call into this
shared resource to perform their tasks so are all compatible
and can be used simultaneously.

This setup enables multiple tones, analogWrites, servos, and stepper
motors to be controlled with reasonable accuracy.  It uses both TIMER1
and the internal ESP cycle counter to handle timing of waveform edges.
TIMER1 is used in non-reload mode and only edges cause interrupts.  The
interrupt is started and stopped as required, minimizing overhead when
these features are not being used.

A generic "startWaveform(pin, high-US, low-US, runtime-US)" and
"stopWaveform(pin)" allow for further types of interfaces.  Minimum
high or low period is ~1 us.

Add a tone(float) method, useful when working with lower frequencies.

Fixes #4321.  Fixes 4349.
This commit is contained in:
Earle F. Philhower, III
2018-06-07 18:38:58 -07:00
committed by GitHub
parent ea4720b03e
commit ebda795f34
12 changed files with 599 additions and 840 deletions

View File

@ -1,6 +1,6 @@
/*
Servo.h - Interrupt driven Servo library for Esp8266 using timers
Copyright (c) 2015 Michael C. Miller. All right reserved.
Original Copyright (c) 2015 Michael C. Miller. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@ -23,13 +23,6 @@
// The servos are pulsed in the background using the value most recently
// written using the write() method.
//
// This library uses timer0 and timer1.
// Note that timer0 may be repurposed when the first servo is attached.
//
// Timers are seized as needed in groups of 12 servos - 24 servos use two
// timers, there are only two timers for the esp8266 so the support stops here
// The sequence used to sieze timers is defined in timers.h
//
// The methods are:
//
// Servo - Class for manipulating servo motors connected to Arduino pins.
@ -58,15 +51,7 @@
#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds
// NOTE: to maintain a strict refresh interval the user needs to not exceede 8 servos
#define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer
#define MAX_SERVOS (ServoTimerSequence_COUNT * SERVOS_PER_TIMER)
#if defined(ESP8266)
#include "esp8266/ServoTimers.h"
#else
#if !defined(ESP8266)
#error "This library only supports esp8266 boards."
@ -76,6 +61,7 @@ class Servo
{
public:
Servo();
~Servo();
uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure
uint8_t attach(int pin, uint16_t min, uint16_t max); // as above but also sets min and max values for writes.
void detach();
@ -85,9 +71,11 @@ public:
int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release)
bool attached(); // return true if this servo is attached, otherwise false
private:
uint8_t _servoIndex; // index into the channel data for this servo
bool _attached;
uint8_t _pin;
uint16_t _minUs;
uint16_t _maxUs;
uint16_t _valueUs;
};
#endif