ESP32 Sensor+Servo

#6361707
Lesenswert?

- 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
Angehängte Dateien:
Gast #6361722
Lesenswert?

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.
#6361733
Lesenswert?

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
}
Gast #6361739
Lesenswert?

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/
#6361752
Lesenswert?

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?
Gast #6361759
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren