wangrong
2026-08-24 beef6536e7c8dd3f5cbe8f73585611479910bea7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//--------------------------------------------------------------
//-- Oscillator.pde
//-- Generate sinusoidal oscillations in the servos
//--------------------------------------------------------------
//-- (c) Juan Gonzalez-Gomez (Obijuan), Dec 2011
//-- (c) txp666 for esp32, 202503
//-- GPL license
//--------------------------------------------------------------
#ifndef __OSCILLATOR_H__
#define __OSCILLATOR_H__
 
#include "driver/ledc.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
 
#define M_PI 3.14159265358979323846
 
#ifndef DEG2RAD
#define DEG2RAD(g) ((g) * M_PI) / 180
#endif
 
#define SERVO_MIN_PULSEWIDTH_US 500           // 最小脉宽(微秒)
#define SERVO_MAX_PULSEWIDTH_US 2500          // 最大脉宽(微秒)
#define SERVO_MIN_DEGREE -90                  // 最小角度
#define SERVO_MAX_DEGREE 90                   // 最大角度
#define SERVO_TIMEBASE_RESOLUTION_HZ 1000000  // 1MHz, 1us per tick
#define SERVO_TIMEBASE_PERIOD 20000           // 20000 ticks, 20ms
 
class Oscillator {
public:
    Oscillator(int trim = 0);
    ~Oscillator();
    void Attach(int pin, bool rev = false);
    void Detach();
 
    void SetA(unsigned int amplitude) { amplitude_ = amplitude; };
    void SetO(int offset) { offset_ = offset; };
    void SetPh(double Ph) { phase0_ = Ph; };
    void SetT(unsigned int period);
    void SetTrim(int trim) { trim_ = trim; };
    void SetLimiter(int diff_limit) { diff_limit_ = diff_limit; };
    void DisableLimiter() { diff_limit_ = 0; };
    int GetTrim() { return trim_; };
    void SetPosition(int position);
    void Stop() { stop_ = true; };
    void Play() { stop_ = false; };
    void Reset() { phase_ = 0; };
    void Refresh();
    int GetPosition() { return pos_; }
 
private:
    bool NextSample();
    void Write(int position);
    uint32_t AngleToCompare(int angle);
 
private:
    bool is_attached_;
 
    //-- Oscillators parameters
    unsigned int amplitude_;  //-- Amplitude (degrees)
    int offset_;              //-- Offset (degrees)
    unsigned int period_;     //-- Period (miliseconds)
    double phase0_;           //-- Phase (radians)
 
    //-- Internal variables
    int pos_;                       //-- Current servo pos
    int pin_;                       //-- Pin where the servo is connected
    int trim_;                      //-- Calibration offset
    double phase_;                  //-- Current phase
    double inc_;                    //-- Increment of phase
    double number_samples_;         //-- Number of samples
    unsigned int sampling_period_;  //-- sampling period (ms)
 
    long previous_millis_;
    long current_millis_;
 
    //-- Oscillation mode. If true, the servo is stopped
    bool stop_;
 
    //-- Reverse mode
    bool rev_;
 
    int diff_limit_;
    long previous_servo_command_millis_;
 
    ledc_channel_t ledc_channel_;
    ledc_mode_t ledc_speed_mode_;
};
 
#endif  // __OSCILLATOR_H__