Hallo Community!
Ich bin gerade dabei eine Entfernungsmessung mit 2 Ultraschallsensoren
(HC-SR04) zu programmieren. Das Ziel ist es zurzeit noch, dass wenn
einer der beiden Ultraschallsensoren etwas erkennt, das näher als 10cm
ist, soll der angeschlossene DC-Motor stoppen, sonst soll er sich ganz
normal drehen.
Das funktioniert soweit auch ganz gut, nur wenn ich jetzt einen
Standard-Servo in das Programm integriere und auch am Arduino UNO
anschließe, stoppt das Programm und führt keinen Schritt mehr durch. Es
handelt sich hier nur um diese 4 Zeilen:
1
Servomyservo;// create servo object to control a servo
2
intlenken=0;
3
4
myservo.attach(10);// attaches the servo on pin 3 to the servo object
5
myservo.write(100);// attaches the servo on position 100(middle)
Ich habe sonst noch keinen weiteren Code für den Servo eingefügt.
Ich würde mich sehr über Hilfe oder Lösungsvorschlage dazu freuen.
mfg Simon K.
Code:
1
#include<TimerOne.h>
2
#include<Ultrasonic.h>
3
#include<Servo.h>
4
5
6
#define TRIGGER_PIN 7
7
#define ECHO_PIN 6
8
#define TRIGGER_PIN1 5
9
#define ECHO_PIN1 4
10
11
intalle_x_sekunden=1;
12
intx=0;
13
Ultrasonicultrasonic(TRIGGER_PIN,ECHO_PIN);
14
Ultrasonicultrasonic1(TRIGGER_PIN1,ECHO_PIN1);
15
floatcmMsec,inMsec;
16
floatcmMsec1,inMsec1;
17
18
/*Servo myservo; // create servo object to control a servo
19
int lenken = 0;*/
20
21
intfahren=0;
22
23
voidsetup()
24
{
25
Serial.begin(9600);
26
Timer1.initialize(alle_x_sekunden*1000000);
27
Timer1.attachInterrupt(messen);
28
29
pinMode(12,OUTPUT);//Initiates Motor Direction A
30
pinMode(9,OUTPUT);//Initiates Break Channel A
31
32
/*myservo.attach(10); // attaches the servo on pin 3 to the servo object
33
myservo.write(100); // attaches the servo on position 100(middle)*/
34
}
35
36
voidloop(){
37
if(x==0){
38
Timer1.attachInterrupt(messen);
39
}
40
if(x==1){
41
Timer1.attachInterrupt(messen1);
42
}
43
44
if(cmMsec>10){
45
fahren=2;
46
}
47
else{
48
fahren=0;
49
50
}
51
52
switch(fahren){
53
case0:
54
{
55
digitalWrite(9,HIGH);
56
break;
57
}
58
case1:
59
{
60
digitalWrite(12,HIGH);//Establishes forward direction of Channel A
61
digitalWrite(9,LOW);//Disengage the Brake for ChannelA
62
analogWrite(3,125);//Spins the motor on Channel A
63
break;
64
}
65
case2:
66
{
67
digitalWrite(12,HIGH);//Establishes forward direction of Channel A
68
digitalWrite(9,LOW);//Disengage the Brake for ChannelA
69
analogWrite(3,255);//Spins the motor on Channel A
70
break;
71
}
72
}
73
74
}
75
76
voidmessen(){
77
78
longmicrosec=ultrasonic.timing();//funktion, welche die zeit berechnet
79
80
cmMsec=ultrasonic.convert(microsec,Ultrasonic::CM);//rechnet die gemessene Zeit in cm um
81
inMsec=ultrasonic.convert(microsec,Ultrasonic::IN);// Inch
82
Serial.print("MS: ");
83
Serial.print(microsec);
84
Serial.print(", CM: ");
85
Serial.print(cmMsec);
86
Serial.print(", IN: ");
87
Serial.println(inMsec);
88
x=1;
89
90
}
91
92
voidmessen1(){
93
94
longmicrosec1=ultrasonic1.timing();//funktion, welche die zeit berechnet
95
96
cmMsec1=ultrasonic1.convert(microsec1,Ultrasonic::CM);//rechnet die gemessene Zeit in cm um
97
inMsec1=ultrasonic1.convert(microsec1,Ultrasonic::IN);// Inch
Simon K. schrieb:> anschließe, stoppt das Programm und führt keinen Schritt mehr durch. Es> handelt sich hier nur um diese 4 Zeilen:
Es handelt sich nicht NUR um diese 4 Zeilen.
Servos anzusteuern hat mit exaktem Timing zu tun. Hinter exaktem Timing
steckt oft ein Timer.
Die Frage lautet daher: wie erzeugt eigentlich die 'Servo' Klasse ihr
Timing?
Die Chancen stehen nicht schlecht, dass die Servo Klasse dazu einen
Timer einsetzt. Und wenn das dann zufällig auch noch der Timer 1 ist,
dann kannst du hier
1
...
2
Timer1.initialize(alle_x_sekunden*1000000);
3
Timer1.attachInterrupt(messen);
4
...
nicht dein eigenes Süppchen mit dem Timer 1 kochen.
Also: welche Resourcen, sprich 'welchen Timer', benötigt die Servo
Klasse?
In der Servo.h-library ist vermerkt, dass unter anderem auch der Timer1
verwendet wird.. (Screenshot im Anhang)
Habe ich mit dem Arduino Uno sonst eine Möglichkeit, einen 2. Timer zu
verwenden (als Beispiel MsTimer2.h?), um meine Ultraschallsensoren in
genau definierten Zeitabständen einlesen zu können?
Mit dem Hintergedanken, dass der Servo auch in Betrieb genommen wird.
mfg Simon K.
Simon K. schrieb:> verwenden (als Beispiel MsTimer2.h?), um meine Ultraschallsensoren in> genau definierten Zeitabständen einlesen zu können?
Von welcher Genauigkeit sprechen wir, wenn du von 'genau definierte
Zeitabstände' redest.
Eine einfache, Arduino konforme Möglichkeit, für regelmässig
auszuführende Aktionen ist es ja, das ganze an der Arduino 'Systemuhr'
aufzuhängen.
1
unsignedlongpreviousMillis=0;
2
3
voidloop()
4
{
5
6
if(millis()-previousMillis>1000){// alle 1 Sekunde
7
previousMillis=millis();
8
9
// mach was im Sekunden Abstand
10
// ....
11
}
12
13
...
14
}
Die vom if abhängigen Aktionen finden im Sekundenabstand statt, wobei
sich ein eventueller Fehler nicht akkumuliert. D.h. wenn die Aktion mal
um 1 Millisekunde zu spät kommt, kommt die nächste um 1 Millisekunde zu
früh, so dass auf längere Sicht gesehen die Aktion tatsächlich im
Sekundentakt erfolgt.
Wenn dir das reicht, und ich kann mir ehrlich gesagt keinen Grund
vorstellen, warum es so wichtig ist, die Sensoren auf die Mykrosekunde
genau abgefragt werden, dann ist das eine Lösung, in der du überhaupt
keinen Timer brauchst.
D.h. du benutzt implizit schon einen Timer, der steckt in millis()
drinnen. Aber der springende Punkt ist, dass der ins System integriert
ist und sich die Macher der Servo Klasse meines Wissens auch darum
gekümmert haben, da sauber mitzuspielen - ganz im Gegensatz zu deinem
Timer Versuch.
Welcher AVR steckt denn in dem Uno?
Die ATmega haben ja mindestens 3 Timer.
T1 würde ich für die Ultraschallmessung benutzen, da der einen
Capture-Eingang hat. Der läßt sich auch über den ADMUX auf mehrere
Sensoren umschalten.
T0 mit seinen PWM-Ausgängen für die Servos.
Und T2 als Zeitgeber.
Die Nutzung der Hardwareeinheiten hat auch den Vorteil, daß sie sich
nicht durch Programmlaufzeiten gegenseitig stören.