Forum: Mikrocontroller und Digitale Elektronik Motorshield und Servo gleichzeitig steuern (Timer 1)


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Laurin E. (wildatheart)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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!

von Cyblord -. (cyblord)


Bewertung
-2 lesenswert
nicht lesenswert
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.

von Thomas V. (Gast)


Bewertung
0 lesenswert
nicht lesenswert

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Laurin E. (wildatheart)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht 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.

von Laurin E. (wildatheart)


Bewertung
0 lesenswert
nicht 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);

von Achim S. (achim_kaarst)


Bewertung
0 lesenswert
nicht lesenswert
> 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
von Laurin E. (wildatheart)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

von Peter D. (peda)


Bewertung
0 lesenswert
nicht 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

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

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.