Hallo
Ich habe ein Timer-Problem. Für meinen Roboter verwende ich ein Arduino
Uno zusammen mit einem Pololu VNH5019 Motortreiber. Da ich über den
Atmega328p per PWM noch einen Servo steuern will, bin ich mit einem
Timer-Konflikt konfrontiert. Ich habe mit zusärtlichem Code (siehe
Anhang)versucht, für den Servo den Timer 2 zu verwenden, doch es will
nicht funktionieren. Der Servo zuckt nur nervös herum (auch ohne Last)
und reagiert nicht auf meine Steuersignale. Ich habe den Servo bereits
(ohne ein Motorshield) erfolgreich angesteuert. Zudem wird der Servo
nicht über VDD des Arduino Uno, sondern unabhängig gespiesen.
Hat jemand eine Idee, wo der Fehler liegt?
Ich danke Euch schon jetzt für Inputs!
Typische Arduino Kacke halt. Da wird halt eine Ressource mehrfach
benötigt. Mit Arduino Bordmitteln lässt sich das nicht lösen. Da musst
du raus aus deiner Arduino Welt. Sorry.
Wenn die Servoroutine schonmal funktioniert hat, dann wird vermutlich
die nicht gezeigte Motorroutine sie beeinflussen.
Sei es, sie benutzt auch T2 oder verzögert andere Interrupts sehr lange.
Die nicht gezeigte Bluetooth-Routine könnts aber auch sein.
Danke für eure Inputs! Ich habe inzwischen mich dazu entschieden, die
Servo-Steuerung separat einem kleinen Arduino Mini Board zu überlassen,
das ich noch rumliegen hatte. Das heisst, ich habe den RX vom
RF-Empfäneger-Modul auf beide Boards geführt. Das Uno bekommt 'A' bis
'T' für den switch cmd (Motor- und LED-Steuerung) und das "Mini" den
Servo-Winkel von 0-180 Grad. Doch leider funktioniert mein Plan noch
nicht, denn der Servo zuckt immer noch planlos rum. Alle restlichen
Steuersignale kommen korrekt an. Ich weiss nicht wie ich die
Character-Signale von den Integer sauber trennen kann..
Im Anhang sind Code vom Sender und vom Empfänger für den Servo.
Laurin E. schrieb:> val = bluetooth.read();> if (val >= '0' && val <= '180'){
Ob das unter C++ geht, hab ich meine Zweifel (kann nur C), unter C geht
das auf keinen Fall.
Unter C sind Variablen und Strings völlig verschieden. Man braucht
Funktionen (itoa, atoi, sprintf, sscanf) zur Umwandlung.
Und vor allem braucht man ein Protokoll, wenn die UART mehr als ein Byte
übertragen soll. Sonst weiß der Empfänger nicht, wann ein Kommando
anfängt und wann es aufhört.
Ich habe mich inzwischen mal auf die Servosteuerung beschränkt, um zu
testen, ob der Servo ohne die restlichen Steuersignale, also ohne den
switch case, läuft.
Was mir ein "Serial.println" nach bluetooth.read liefert erklärt wohl,
weshalb ich ein Signal-Chaos habe.
Der Serial Monitor zeigt Zeichen wie "´1" oder "Œ1" und sonstige
kyrillisches Zeugs. Hat jemand ne Erklärung warum nicht "val", also der
Winkel (0-180), der Senderseitig korrekt gemappt wird (per Serial.print
überprüft), ankommt?
Sender-Code:
1
#include <SoftwareSerial.h>
2
SoftwareSerialBTserial(2,3);// RX | TX
3
char*controller;
4
intx;
5
inty;
6
intled;
7
intbuttonPin=8;
8
intbuttonPin2=7;
9
intpotpin;
10
intval;
11
intbuttonState=0;
12
intbuttonState2=0;
13
voidsetup(){
14
pinMode(buttonPin,INPUT);
15
pinMode(buttonPin2,INPUT);
16
pinMode(potpin,INPUT);
17
Serial.begin(9600);
18
BTserial.begin(9600);
19
controller="0";
20
}
21
22
voidloop(){
23
x=analogRead(A0);
24
y=analogRead(A1);
25
led=analogRead(A2);
26
buttonState=digitalRead(buttonPin);
27
buttonState2=digitalRead(buttonPin2);
28
val=analogRead(A3);
29
val=map(val,0,1023,0,180);
30
BTserial.write(val);
31
}
Empfänger-Code:
1
voidsetup(){
2
bluetooth.begin(9600);
3
Serial.begin(9600);// set up Serial library at 9600 bps
> Serial.println(bluetooth);
Das sieht mir sehr seltsam aus. Die Variable bluetooth kann man nicht
printen, das ist ein Zeiger.
Was willst du denn hier ausgeben?
Hallo Achim
Ja Du hast natürlich recht. Es sollte Serial.println(cmd) sein. Das Ziel
mit dem Serial.print war, dass ich sehe was für Zeichen beim Empfänger
ankommen. Jetzt sehe ich auch, dass ein Zahlen-Wert zwischen 0 und 180
ankommt, wie ich es wollte. Das sehr Seltsame ist aber, dass die Motoren
und Relais, welche vom switch case Befehle bekommen (folgt weiter im
loop) auch reagieren wenn ich z.B. den Wert 55 (Grad) sende. Dies obwohl
im switch case nur Buchstaben von 'A' bis 'T' vorkommen. Hast Du eine
Erklärung dafür?
Danke und Grüsse
Laurin
Laurin E. schrieb:> BTserial.write(val);
Da würde ich mal vermuten, daß es alle Ziffern dumpf hintereinder sendet
und man nicht den einen Wert von dem nächsten unterscheiden kann. Es
fehlt nämlich ein Protokoll.
Laurin E. schrieb:> Dies obwohl> im switch case nur Buchstaben von 'A' bis 'T' vorkommen.
Ehrlich gesagt, macht mich das ganz konfus, daß man unter C++ Werte,
Zeichen und Strings bunt durcheinander würfeln kann. Ich sehe daher in
Deinem Code überhaupt nicht durch.
Auch kenne ich die Deklarationen von bluetooth.read, Serial.println usw.
nicht. Man kann daher nur grob mutmaßen, was Du von den Funktionen
erwartest. Aber ob sie das auch tun?
Ich mag die Ordnung in C, daß alle Typen verschieden sind und nur dann
ineinander umgeformt werden, wenn ich es explizit hinschreibe oder ich
krieg ne Warnung vor den Latz geknallt.
In C würde man ein char-Array anlegen dort hinein mit sprintf einen
Kennbuchstaben, den Wert und ein Paketendezeichen (z.B. '\n')
reinschreiben und es dann versenden.
Der Empfänger würde alle Bytes prüfen, bis er den Kennbuchtsaben erkennt
und dann weiter in ein char-Array einlesen, bis er das Paketende
erkennt. Dann würde er das char-Array per atoi in den Wert zurück
wandeln und ihn dann der PWM übergeben.
Aber in C++: keine Ahnung.
Ich hab da so meine Zweifel, ob C++ wirklich Deine Gedanken lesen kann,
was Du gerade für einen Argumenttyp auszuwerten wünschst.
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang