- ESP32 - 4x IR Sensor (lm393) - 2x Servo (SG90) - 2x DC Motoren - 1X Adafruit 16-Kanal (PCA9685) Hallo zusammen, habe folgendes Problem: Versuche mit 4XSensoren und 2XServo Pan/Tilt nachzumachen, soweit funktionert das ohne Probleme. Jedoch wenn ich das als Webserver laufen lasse funktioniert das nicht ,bin am zweifeln und weiss nicht woran es liegt. Das ganze ist einen kleiner roboter der über Wifi gesteuert wird und soll sein Kopf nach links/rechts/oben und unten bewegen je nach sensor aktivität. Hoffe da kann jemand helfen. INO sind gepackt im Anhang
Andrea I. schrieb: > Jedoch wenn ich das als Webserver laufen > lasse funktioniert das nicht Was genau funktioniert nicht?
Die reaktion der sensoren ist unterschiedlich, im Serial wird es zwar angezeigt aber es bewegt sich nur ein Servo, Servo1(links und rechts) funktioniert aber Servo2(oben und unten) nicht.
Dann reduziere dein Programm auf ganz kleine Demos, die nur jeweils eine Funktion durchtesten. Wenn das klappt, baue es schrittweise zusammen, bis es wieder nicht funktioniert. Dann weist du, in welchem Schritt der Fehler steckt. Was die vielen String-Konstanten angeht: beschäftige dich mal mit dem F() Makro, sonst belegst du sehr viel Platz im ohnehin knappen Stack.
Stefan ⛄ F. schrieb: > Was die vielen String-Konstanten angeht: beschäftige dich mal mit dem > F() Makro, Auf dem ESP32? Du sollst auch lesen, nicht nur posten. leo
So klappt es
1 | #include <Adafruit_PWMServoDriver.h> |
2 | Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); |
3 | #define I2C_SDA 22
|
4 | #define I2C_SCL 21
|
5 | |
6 | #define SERVOMIN 1100
|
7 | #define SERVOMAX 3000
|
8 | |
9 | //Sensor pins
|
10 | const int IR_O = 39; |
11 | const int IR_U = 36; |
12 | const int IR_L = 35; |
13 | const int IR_R = 34; |
14 | |
15 | int posA = 40; |
16 | int posB = 60; |
17 | int stepsize = 2; |
18 | |
19 | void setup() { |
20 | Serial.begin(115200); |
21 | Wire.begin(I2C_SDA, I2C_SCL); |
22 | pinMode (IR_O, INPUT); |
23 | pinMode (IR_U, INPUT); |
24 | pinMode (IR_L, INPUT); |
25 | pinMode (IR_R, INPUT); |
26 | pwm.begin(); |
27 | pwm.setPWMFreq(50); |
28 | }
|
29 | |
30 | void loop() { |
31 | bewegung(); |
32 | }
|
33 | |
34 | void bewegung() { |
35 | int statusSensor_O = digitalRead(IR_O); |
36 | int statusSensor_U = digitalRead(IR_U); |
37 | int statusSensor_R = digitalRead(IR_R); |
38 | int statusSensor_L = digitalRead(IR_L); |
39 | |
40 | if (statusSensor_O == 0){ |
41 | Serial.println("Oben") ; |
42 | posA = posA + stepsize; |
43 | pwm.setPWM(4, 0, pulseWidth(posA)); |
44 | delay(10); |
45 | if (posA > 150){ |
46 | posA = 150; |
47 | }
|
48 | }
|
49 | |
50 | if (statusSensor_U == 0){ |
51 | Serial.println("Unten") ; |
52 | posA = posA - stepsize; |
53 | pwm.setPWM(4, 0, pulseWidth(posA)); |
54 | delay(10); |
55 | if (posA < 40){ |
56 | posA = 40; |
57 | }
|
58 | }
|
59 | |
60 | if (statusSensor_L == 0){ |
61 | Serial.println("Links") ; |
62 | posB = posB + stepsize; |
63 | pwm.setPWM(2, 0, pulseWidth(posB)); |
64 | delay(10); |
65 | if (posB > 120){ |
66 | posB = 120; |
67 | }
|
68 | }
|
69 | |
70 | if (statusSensor_R == 0){ |
71 | Serial.println("Rechts") ; |
72 | posB = posB - stepsize; |
73 | pwm.setPWM(2, 0, pulseWidth(posB)); |
74 | delay(10); |
75 | if (posB < 10) { |
76 | posB = 10; |
77 | }
|
78 | }
|
79 | }
|
80 | |
81 | int pulseWidth(int angle){ |
82 | int pulse_wide, analog_value; |
83 | pulse_wide = map(angle, 0, 180, SERVOMIN, SERVOMAX); |
84 | analog_value = int(float(pulse_wide) / 1000000 * 50 * 4096); |
85 | return analog_value; |
86 | }
|
:
Bearbeitet durch User
Die berechneten Werte von pulseWidth() könntest du mal seriell ausgeben und kontrollieren. Auch in der Funktion setMotorsXY() könnten Debug Meldungen dabei helfen, nachzuvollziehen, was die Funktion bzw. ob sie das tut, was sie soll. Die Schleife > while (client.connected()) { ...} blockiert deine Loop für lange Zeit. Eventuell löst da sogar der Watchdog aus. Ich würde da mal mindestens ein yield() einfügen. Besser wäre, das Programm mittels Zustandsautomaten so umzuschreiben, dass es überhaupt keine blockierenden Warteschleifen hat, also auch keine delay(). Deine Methode, einzelne Zeichen in der String Variable "header" zu sammeln, halte ich für ziemlich problematisch. Damit riskierst du, den Heap zu fragmentieren, so dass das Ding nach kurzer Laufzeit abstürzt. Da dies der einzige String ist, mit dem du das machst, hast du vermutlich noch Glück. Komplexere Anwendungen würden Dir aber mit hoher Wahrscheinlichkeit auf die Nase fallen. Lies dir dazu mal das durch: https://cpp4arduino.com/2018/11/21/eight-tips-to-use-the-string-class-efficiently.html Und das: https://www.mikrocontroller.net/articles/Heap-Fragmentierung Und das: https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/
Andrea I. schrieb: > So klappt es Gut. Dann teste jetzt den Webserver ohne die Motoren anzusteuern. Kannst ja mit Textmeldungen ausgeben, welche die Funktion bestätigen.
Danke Stefan für den Ansatzt, Habe ich alles ausprobiert und dies step by step eingebaut, der Webserver läuft ,habe extra noch drei Buttons eingebaut um das über Wifi zu bedienen, hab auch ein sensor nach den anderen abgebaut bzw. vertauscht. Die bewegungen Links+Rechts klappt nur halt Oben+Unten leider nicht. Du sagst mit der > while (client.connected()) { ...} könnte konflikte geben? wie würdest du das machen bzw. wie könnte man das machen?
Andrea I. schrieb: > wie würdest du das machen bzw. wie könnte man das machen? Füge da einen yield() ein oder delay(1) ein, dadurch wird etwas Zeit an das Betriebssystem abgegeben. Und versuche mal, die String Variable durch ein char[] mist fester Größe zu ersetzen. Dann musst du natürlich auch die C Funktionen der <string.h> benutzen, die mit char[] operieren.
So habe ich das verstanden
1 | while (client.connected()) { |
2 | delay(1); |
3 | if (client.available()) {......... |
------------------------------------------
1 | //statt
|
2 | client.println |
3 | |
4 | //das?
|
5 | const unsigned char client[]PROGMEM = {........ |
Das mit dem Delay ist gut. Deine Printlines sollst du mit dem F() Makro machen. client.println(F("was auch immer")); Ist viel kompakter, als mit PROGMEM herum zu fummeln.
- delay blockiert die bedienung für die DC-Motoren. - client.println(F("was auch immer")); habe es abgeändert jedoch sind keine änderungen bei den sensoren.
1 | while (client.connected()) { |
2 | delay(1); |
3 | if (client.available()) { |
Baue ganz viele debug Meldungen ein um den Ablauf und die Variablen zu kontrollieren.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.