wangzhibo
2026-10-08 220e4fab27b7f419b3e89e2f2d28ae789aac09d7
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__