Hallo zusammen,
Ich habe 2 Servos an GIPO 26 & 25 angeschlossen, soweit funktioniert auch alles.
Folgenden Code habe ich gefunden und modifiziert…
#define TIMER_WIDTHa 16
#define channela 1
#define channelb 2
#define pina 26
#define pinb 25
#define USMIN 1200 // This is the rounded 'minimum'
#define USMAX 8700 // This is the rounded 'maximum'
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
int SRV_a_pos;
boolean SRV_a_moveFoward;
long SRV_a_nextWakeUp;
int SRV_b_pos;
boolean SRV_b_moveFoward;
long SRV_b_nextWakeUp;
void setup() {
Serial.begin(115200);
ledcSetup(channela, SERVO_FREQ, TIMER_WIDTHa); // channel 1, 50 Hz, 16-bit width
ledcSetup(channelb, SERVO_FREQ, TIMER_WIDTHa); // channel 2, 50 Hz, 16-bit width
ledcAttachPin(pina, channela); // GPIO 26 assigned to channel 1
ledcAttachPin(pinb, channelb); // GPIO 25 assigned to channel 2
// init the compontent’s states
SRV_a_pos = USMIN;
SRV_a_moveFoward = true;
SRV_a_nextWakeUp = millis();
SRV_b_pos = USMIN;
SRV_b_moveFoward = true;
SRV_b_nextWakeUp = millis();
}
void loop() {
long currentTime = millis();
long nextWakeUpSRV_a = SRV_a_doStep(currentTime);
long nextWakeUpSRV_b = SRV_b_doStep(currentTime);
}
/* ** SERVO_a ** */
long SRV_a_doStep(long currentMillis) {
if(currentMillis>SRV_a_nextWakeUp) {
if(SRV_a_moveFoward) {
SRV_a_pos += SRV_a_getIncrement();
if(SRV_a_pos>USMAX) {
SRV_a_moveFoward = false;
SRV_a_pos = USMAX;
}
} else {
SRV_a_pos -= SRV_a_getIncrement();
if(SRV_a_pos<USMIN) {
SRV_a_moveFoward = true;
SRV_a_pos = USMIN;
}
}
Serial.print("Servo A pos "); Serial.println(SRV_a_pos);
ledcWrite(channela, SRV_a_pos); // sweep servo 1
SRV_a_nextWakeUp = currentMillis + 1;
}
return SRV_a_nextWakeUp;
}
int SRV_a_getIncrement() {
return 1;
}
/* ** SERVO_b ** */
long SRV_b_doStep(long currentMillis) {
if(currentMillis>SRV_b_nextWakeUp) {
if(SRV_b_moveFoward) {
SRV_b_pos += SRV_b_getIncrement();
if(SRV_b_pos>USMAX) {
SRV_b_moveFoward = false;
SRV_b_pos = USMAX;
}
} else {
SRV_b_pos -= SRV_b_getIncrement();
if(SRV_b_pos<USMIN) {
SRV_b_moveFoward = true;
SRV_b_pos = USMIN;
}
}
Serial.print("Servo B pos "); Serial.println(SRV_b_pos);
ledcWrite(channelb, SRV_b_pos); // sweep servo 2
SRV_b_nextWakeUp = currentMillis + 1;
}
return SRV_b_nextWakeUp;
}
int SRV_b_getIncrement() {
return 5;
}
Nun mein Problem beide Servos Flattern manchmal. Servoa bei USMAX mehr.
Ich vermute es hängt mit den Timern des ESP32 oder dem Timing zusammen.
An den SG90 Servos kann es nicht liegen mit "for" laufen sie sauber, die Unterbrechung kann ich aber nicht gebrauchen.
Was habe ich falsch gemacht und was kann ich ändern?
Habe auch schon an TaskScheduler.h gedacht.
Nen Test Sketch habe ich auch geschrieben, Servoa Flattert am ende bei USaMAX genau so wie bei dem anderen Sketch. Aber nicht immer, ich bin bissel Ratlos... nen Oszi habe ich nicht um zu schauen was für Flanken kommen.
Die Prio 1,2,3 Tasks erst mal nicht beachten, die laufen nur mit.
Vielleicht hat auch dazu jemand eine Idee?
#define _TASK_SLEEP_ON_IDLE_RUN
#define _TASK_PRIORITY
#define _TASK_WDT_IDS
#define _TASK_TIMECRITICAL
#include <TaskScheduler.h>
Scheduler r, hpr;
// Callback methods prototypes
void tCallback1();
void tCallback2();
void tCallback3();
void tCallback40();
void tCallback50();
#define TIMER_WIDTHa 16
#define channela 1
#define channelb 2
#define pina 26
#define pinb 25
#define USaMIN 2000 // This is the rounded 'minimum'
#define USaMAX 6000 // This is the rounded 'maximum'
#define USbMIN 1200 // This is the rounded 'minimum'
#define USbMAX 8700 // This is the rounded 'maximum'
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
//Servo SRV_servo;
int SRV_a_pos;
boolean SRV_a_moveFoward;
long SRV_a_nextWakeUp;
int SRV_b_pos;
boolean SRV_b_moveFoward;
long SRV_b_nextWakeUp;
// Tasks
Task t1(0, TASK_FOREVER, &tCallback1, &r); //adding task to the chain on creation
Task t2(0, TASK_FOREVER, &tCallback2, &r);
Task t3(0, TASK_FOREVER, &tCallback3, &r);
Task t4(0, TASK_FOREVER, &tCallback40, &hpr); //adding task to the chain on creation
Task t5(0, TASK_FOREVER, &tCallback50, &hpr); //adding task to the chain on creation
void tCallback1() {
Scheduler &s = Scheduler::currentScheduler();
Task &t = s.currentTask();
Serial.print("Task: "); Serial.print(t.getId());Serial.print(":\t");
Serial.print(millis()); Serial.print("\tStart delay = "); Serial.println(t.getStartDelay());
if (t.getId() == 3) Serial.println();
}
void tCallback2() {
Scheduler &s = Scheduler::currentScheduler();
Task &t = s.currentTask();
Serial.print("Task: "); Serial.print(t.getId());Serial.print(":\t");
Serial.print(millis()); Serial.print("\tStart delay = "); Serial.println(t.getStartDelay());
if (t.getId() == 3) Serial.println();
}
void tCallback3() {
Scheduler &s = Scheduler::currentScheduler();
Task &t = s.currentTask();
Serial.print("Task: "); Serial.print(t.getId());Serial.print(":\t");
Serial.print(millis()); Serial.print("\tStart delay = "); Serial.println(t.getStartDelay());
if (t.getId() == 3) Serial.println();
}
void tCallback40() {
Scheduler &s = Scheduler::currentScheduler();
Task &t = s.currentTask();
Serial.print("Task: "); Serial.print(t.getId());Serial.print(":\t");
Serial.print(millis()); Serial.print("\tStart delay = "); Serial.println(t.getStartDelay());
if (t.getId() == 3) Serial.println();
if(SRV_a_moveFoward) {
SRV_a_pos += SRV_a_getIncrement();
if(SRV_a_pos>USaMAX) {
SRV_a_moveFoward = false;
SRV_a_pos = USaMAX;
}
} else {
SRV_a_pos -= SRV_a_getIncrement();
if(SRV_a_pos<USaMIN) {
SRV_a_moveFoward = true;
SRV_a_pos = USaMIN;
}
}
Serial.print("Servo A pos "); Serial.println(SRV_a_pos);
ledcWrite(channela, SRV_a_pos); // sweep servo 1
}
int SRV_a_getIncrement() {
return 10;
}
void tCallback50() {
Scheduler &s = Scheduler::currentScheduler();
Task &t = s.currentTask();
Serial.print("Task: "); Serial.print(t.getId());Serial.print(":\t");
Serial.print(millis()); Serial.print("\tStart delay = "); Serial.println(t.getStartDelay());
if (t.getId() == 3) Serial.println();
if(SRV_b_moveFoward) {
SRV_b_pos += SRV_b_getIncrement();
if(SRV_b_pos>USbMAX) {
SRV_b_moveFoward = false;
SRV_b_pos = USbMAX;
}
} else {
SRV_b_pos -= SRV_b_getIncrement();
if(SRV_b_pos<USbMIN) {
SRV_b_moveFoward = true;
SRV_b_pos = USbMIN;
}
}
Serial.print("Servo B pos "); Serial.println(SRV_b_pos);
ledcWrite(channelb, SRV_b_pos); // sweep servo 2
}
int SRV_b_getIncrement() {
return 50;
}
void setup () {
Serial.begin(115200);
Serial.println("Scheduler Priority Test");
t4.setId(40);
t5.setId(50);
r.setHighPriorityScheduler(&hpr);
r.enableAll(true); // this will recursively enable the higher priority tasks as well
ledcSetup(channela, SERVO_FREQ, TIMER_WIDTHa); // channel 1, 50 Hz, 16-bit width
ledcSetup(channelb, SERVO_FREQ, TIMER_WIDTHa); // channel 2, 50 Hz, 16-bit width
ledcAttachPin(pina, channela); // GPIO 26 assigned to channel 1
ledcAttachPin(pinb, channelb); // GPIO 25 assigned to channel 2
SRV_a_pos = USaMIN;
SRV_a_moveFoward = true;
SRV_b_pos = USbMIN;
SRV_b_moveFoward = true;
}
void loop () {
r.execute();
}
Wenn ich ehrlich bin gefällt mir der TaskScheduler schon besser