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.
schon mal über Soft-PWM nachgedacht? https://code.google.com/archive/p/rogue-code/wikis/SoftPWMLibraryDocumentation.wiki
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 | SoftwareSerial BTserial(2, 3); // RX | TX |
3 | char *controller; |
4 | int x; |
5 | int y; |
6 | int led; |
7 | int buttonPin = 8; |
8 | int buttonPin2 = 7; |
9 | int potpin; |
10 | int val; |
11 | int buttonState = 0; |
12 | int buttonState2 = 0; |
13 | void setup() { |
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 | void loop() { |
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 | void setup() { |
2 | bluetooth.begin(9600); |
3 | Serial.begin(9600); // set up Serial library at 9600 bps |
4 | pinMode(led, OUTPUT); // IR-LEDs |
5 | pinMode (ledPin, OUTPUT); |
6 | pinMode (buttonpin, OUTPUT); |
7 | md.init(); |
8 | |
9 | }
|
10 | |
11 | void loop() { |
12 | |
13 | if (bluetooth.available()) { |
14 | cmd = bluetooth.read(); |
15 | Serial.println(bluetooth); |
16 | Serial.write(cmd); |
> 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?
:
Bearbeitet durch User
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.
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.