Motorshield und Servo gleichzeitig steuern (Timer 1)

OP #5148258
Lesenswert?

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!
Angehängte Dateien:
OP #5148634
Lesenswert?

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

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

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);
OP #5152182
Lesenswert?

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

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.

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