Anfängerprobleme / serielle Schnittstelle

Hallo Forum,

ich bin, was Arduinos angeht eher ein DAU…

Den folgenden Sketch habe ich mir mit Hilfe einiger Beispiele / Bibliotheken aus dem Web “zusammengestümpert”.
Und bitte, bevor jetzt Kommentare in der Art von “Arbeite dich da erst mal ein…” kommen, das ist meine Art mich einzuarbeiten.
Lineares Lernen liegt mir halt nicht, ich springe lieber ins kalte Wasser.
Falls dennoch jemand helfen möchte, hier der Sketch:

#include "FlySkyIBus.h"
#include <Streaming.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_DCMotor *VL = AFMS.getMotor(1);
Adafruit_DCMotor *VR = AFMS.getMotor(2);
Adafruit_DCMotor *HL = AFMS.getMotor(3);
Adafruit_DCMotor *HR = AFMS.getMotor(4);

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define LENKSERVOMIN  225 
#define LENKSERVOMAX  435
#define TILTSERVOMIN  180 
#define TILTSERVOMAX  425 
#define PANSERVOMIN  90 
#define PANSERVOMAX  400 
#define SCHEINWERFERMIN 1500 
#define SCHEINWERFERMAX 4000 

uint8_t lenkservo = 15; // ohne Markierung
uint8_t camtiltservo = 0; // Markierung 1 / I
uint8_t campanservo = 1; // Markierung 2 / II
uint8_t ledtiltservo = 2; // Markierung 3 / III
uint8_t ledpanservo = 3; // Markierung 4 / IV
uint8_t scheinwerfer = 7; // Markierung 7 / VII Rot = Signal!

void setup() {
  
  Serial.begin(115200);
  IBus.begin(Serial1);
  AFMS.begin(); 
  pwm.begin();
  pwm.setPWMFreq(60); 
  
}

void loop() 
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  
  // Abfrage IBUS und Mapping wo nötig > Anfang
  IBus.loop();
  int ch_1 = map(IBus.readChannel(0), 1000, 2000, LENKSERVOMIN, LENKSERVOMAX); // Lenkung
  int ch_2 = map(IBus.readChannel(1), 1000, 2000, TILTSERVOMIN, TILTSERVOMAX); // Kamera "tilt" (Testservo)
  int ch_3 = map(IBus.readChannel(2), 1000, 2000, 0, 255); // Mototsteuerung "Gas"
  int ch_4 = map(IBus.readChannel(3), 1000, 2000, PANSERVOMIN, PANSERVOMAX); // Kamera "pan" (Testservo)
  int ch_5 = IBus.readChannel(4); // Schalter "A" ==> Funktion armed / disarmed (Failsafeüberwachung)
  int ch_6 = IBus.readChannel(5); // Schalter "B" ==> Wahlshalter Kamera Pan / Tilt; Scheinwerfer Pan / Tilt; Beide Pan / Tilt
  int ch_7 = IBus.readChannel(6); // Schalter "C" ==> Wahlschalter Motorsteuerung Vorwärts / Release / Rückwärts
  int ch_8 = map(IBus.readChannel(7), 1000, 2000, SCHEINWERFERMIN, SCHEINWERFERMAX); // Poti ==> Helligkeit Scheinwerfer
  // Abfrage IBUS und Mapping wo nötig < Ende

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


  // Motorsteuerung > Anfang
  if (ch_5 == 1000 && ch_7 == 1000){
  VL->run(FORWARD);
  VL->setSpeed(ch_3);
  VR->run(FORWARD);
  VR->setSpeed(ch_3);
  HL->run(FORWARD);
  HL->setSpeed(ch_3);
  HR->run(FORWARD);
  HR->setSpeed(ch_3);
  }
  else if (ch_5 == 1000 && ch_7 == 2000){
  VL->run(BACKWARD);
  VL->setSpeed(ch_3);
  VR->run(BACKWARD);
  VR->setSpeed(ch_3);
  HL->run(BACKWARD);
  HL->setSpeed(ch_3);
  HR->run(BACKWARD);
  HR->setSpeed(ch_3);
  }
  else{ 
    VL->run(RELEASE);
    VR->run(RELEASE);
    HL->run(RELEASE);
    HR->run(RELEASE);
    }
  // Motorsteuerung < Ende

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  // Servosteuerung > Anfang
  pwm.setPWM(lenkservo, 0, ch_1);
  
  
  if (ch_6 == 1000){  
  pwm.setPWM(camtiltservo, 0, ch_2);
  pwm.setPWM(campanservo, 0, ch_4);
  pwm.setPWM(scheinwerfer, 0,0);
  }
  else if (ch_6 == 1500){
  pwm.setPWM(ledtiltservo, 0, ch_4+30);
  pwm.setPWM(ledpanservo, 0, ch_2);
  if (ch_5 == 1000)
  pwm.setPWM(scheinwerfer, 0, ch_8);
  else if (ch_5 == 2000)
  pwm.setPWM(scheinwerfer, 0,0);
  }
  else if (ch_6 == 2000){
  pwm.setPWM(camtiltservo, 0, ch_2);
  pwm.setPWM(campanservo, 0, ch_4);
  pwm.setPWM(ledtiltservo, 0, ch_4+30);
  pwm.setPWM(ledpanservo, 0, ch_2);  
  if (ch_5 == 1000)
  pwm.setPWM(scheinwerfer, 0, ch_8); 
  else if (ch_5 == 2000)
  pwm.setPWM(scheinwerfer, 0,0); 
  }
  
  // Servosteuerung < Ende

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
  // Debugging / Monitor
  Serial << ch_1 << "  /  " << ch_2 << "  /  " << ch_3 << "  /  " << ch_4 << "  /  " << ch_5 << "  /  " << ch_6 << "  /  " << ch_7 << "  /  " << ch_8  << endl;
  
}

(Es geht hier um den Versuch einer, bisher sehr rudimentären, Steuerung eines UGV’S)

Folgende Probleme treten auf:
Der Arduino (Mega 2560 Clone) hängt sich immer wieder auf, warum?
Woran könnte das liegen?
Probleme mit dem Timing?
Die Baudrate ist vorgegeben (Die IBus Abfrage scheint sonst nicht zu funktionieren)

So bald ich den Arduino vom USB trenne geht gar nichts mehr.
Stromversorgung funktioniert aber über Vin problemlos (gemessen).
LED leuchten, aber sonst funktioniert dann nichts mehr.
Die USB-Verbindung sollte zu diesem Zeitpunkt doch keine Auswirkung auf den Programmablauf haben?

Wahrscheinlich habe ich da bloß einen Knoten im Kopf, eventuell ist ja jemand bereit mir bei der Lösung zu helfen.

Mit fragendem Gruß
Kistenschieber

Ok, mit Motor links/rechts wirst Du wohl auch nicht das Inkasso-Unternehmen meinen, Welches bei Google an Stelle Nr. 1 kommt.

IBUS scheint eine Art Summen-Signal-Auswertung zu sein.
Weiter scheinst Du einen 4-Rad-Antrieb zu benutzen.

Du bist in Deinem Sketch äußerst sparsam mit Kommentaren - und ich habe keine Lust, mir bei jeder 2.ten Zeile oben die Infos zu erscrollen, was Du Damit nun meinen könntest.

Was heißt:‘hängt sich auf’ und 'Vin habe ich gemessen?
Auf welchem Pin bekommt der Arduino welche Spannung und woher?
USB UND externe Spannung ist nämlich keine so gute Idee.

MfG

Kistenschieber:
...
Und bitte, bevor jetzt Kommentare in der Art von "Arbeite dich da erst mal ein..." kommen, das ist meine Art mich einzuarbeiten.
Lineares Lernen liegt mir halt nicht, ich springe lieber ins kalte Wasser.
Falls dennoch jemand helfen möchte, ...

Hi!

Wenn Du lieber in kleinen Portionen lernst und Dir Wissen Stück für Stück aneignen möchtest, wirf mal einen Blick auf meine Textchen. Vielleicht hilft das.

Gruß

Gregor

Hallo postmaster-ino,

UGV ==> Unbemanntes Landfahrzeug – Wikipedia

Das war gemeint und sieht bei mir im Moment so aus.

Das IBus Signal kommt von einem Empfänger wie er auch für Dronen (Quadcopter z.B.) Verwendung findet.
Die Bibliothek die das Ganze für den Arduino nutzbar macht sieht so aus:
(Stammt nicht von mir, bei Interesse Siehe hier)

/*
 * Simple interface to the Fly Sky IBus RC system.
 */

#include <inttypes.h>

class HardwareSerial;
class Stream;

class FlySkyIBus
{
public:
  void begin(HardwareSerial& serial);
  void begin(Stream& stream);
  void loop(void);
  uint16_t readChannel(uint8_t channelNr);

private:
  enum State
  {
    GET_LENGTH,
    GET_DATA,
    GET_CHKSUML,
    GET_CHKSUMH,
    DISCARD,
  };

  static const uint8_t PROTOCOL_LENGTH = 0x20;
  static const uint8_t PROTOCOL_OVERHEAD = 3; // <len><cmd><data....><chkl><chkh>
  static const uint8_t PROTOCOL_TIMEGAP = 3; // Packets are received very ~7ms so use ~half that for the gap
  static const uint8_t PROTOCOL_CHANNELS = 10;
  static const uint8_t PROTOCOL_COMMAND40 = 0x40; // Command is always 0x40

  uint8_t state;
  Stream* stream;
  uint32_t last;
  uint8_t buffer[PROTOCOL_LENGTH];
  uint8_t ptr;
  uint8_t len;
  uint16_t channel[PROTOCOL_CHANNELS];
  uint16_t chksum;
  uint8_t lchksum;
};

extern FlySkyIBus IBus;

Was die Kommentare angeht, ich dachte (wirklich) die wären üppig…
(Für meine Verhältnisse definitiv)

Zu hängt sich auf:
Soll heißen die Programmausführung stoppt. Es passiert schlicht gar nichts mehr, die Ausgabe (LED’s, serieller Monitor) werden statisch, frieren ein.
Das passiert scheinbar immer dann, wen die Servos in Aktion sind, aber es passiert nicht ständig, das macht die Geschichte natürlich nicht einfacher.

Interessant in diesem Zusammenhang ist, das die Ausgabe der vom IBus empfangenen Werte in einem Beispielscript problemlos funktioniert.
Hier spielt das Zusammenspiel mit dem Rest meines Sketches wohl eine entscheidende Rolle.
Wenn ich nur wüsste welche…

Zur Spannungsversorgung:
An Vin liegen über das Motorsteuerungsshield 12V an.
Wenn ich die 5V Pins am Arduino messe komme ich auf ziemlich exakt 4,9irgendwas V.

Zu USB und “Fremdspannung”:
Ich dachte das wäre kein Problem?
Gibt es eine Alternative um die Ausgabe am USB Port während eines Funktionstests zu überwachen?
(Dafür müssen die 12V anliegen)

Nochmal konkret zur Hardware.
Verwendet werden folgende Komponenten:
Arduino Mega2560 R3 (Clone)
Motorshield (Clone)
Servo “Shield”
IBus Empfänger

Außerdem verschiedene Servos, 4 Motoren (12V)…
Die Servos beziehen ihre Energie über das Shield, das über einen eigenen Stepdown Wandler am Akku (3S) hängt.
Der Empfänger bezieht seinen Strom parasitär vom Arduino (5V und Gnd), das Signal geht an Pin 19 / RX1

Wenn ich noch irgendwas hilfreiches an Informationen liefern kann, bitte ich um Nachricht.

Ach so und Danke natürlich das du überhaupt geantwortet hast und zur Hilfe bereit bist.

Gruß
Kistenschieber

Hallo gregorss,

danke dir, mir fällt es halt leichter mich durch die Bearbeitung von konkreten Problemstellungen in Themen einzuarbeiten.

Und ja, das ist nicht immer der ideale Weg, ich weiß...

Die Seiten sehen auf jeden Fall interessant aus, sind gebookmarked.

Gruß
Kistenschieber

Wo wird die Baud-Rate von Serial1 eingestellt?

VIN und USB gehen zusammen, da ist Elektronik dazwischen. Problematisch könnte es sein, den Arduino als “Kraftwerk” für den IBus Empfänger zu verwenden.

Für ein autonomes Fahrzeug ist der Längsregler im Arduino, der 7V x Strom in Wärme umwandelt, Energieverschwendung. Ein StepDown wäre effizienter, da kannst Du dann auch den Empfänger dranhängen. Dann aber ein USB-Kabel ohne +5V-Verbindung nutzen oder Lötbrücke auf dem Mega trennen.

Nach Deiner Fehlerbeschreibung tippe ich auf eine ungenügende Stromversorgung. Das ist und bleibt der Klassiker. Versorge testweise die Servos getrennt.

Alternativ könnte auch der I2C-Bus blockieren, möglicherweise durch ungenügende Terminierung und/oder zu lange Kabel.

Kistenschieber:
danke dir, mir fällt es halt leichter mich durch die Bearbeitung von konkreten Problemstellungen in Themen einzuarbeiten.
Und ja, das ist nicht immer der ideale Weg, ich weiß...

„Learning by doing“ ist eigentlich immer leichter, als theoretisches Zeug zu büffeln.

Mir liegt asynchrone Kommunikation eher als ein direktes Gespräch. Über das nachdenken zu können, was ich sagen möchte, ist oft nötig -- besonders wenn ich mal wieder mit Konzentrationsproblemen zu kämpfen habe.

Gruß

Gregor

Hi agmue,

Die Baudrate stelle ich in meinen Sketch hier ein:

void setup() {
  
  Serial.begin(115200);

In der IBus Bibliothek habe ich diesbezüglich keine anpassbaren Parameter gefunden.
Tests mit verschiedenen anderen Baudraten brachten auch nur “Datensalat”.

Die Servos laufen bereits über eine eigene Stromversorgung, Stepdown am “Servoshield” direkt aus dem 3S LiPo gespeist.
Der Akku liefert definitiv genug “Saft”, der ist für diese Anwendung eher der Overkill.
Ich würde am ehesten vermuten das In der I2C Kommunikation das Problem liegt.
Nur wie finde ich das raus?

Gruß
Kistenschieber

Hallo,

ich denke du must da mal ein paar Seriel.print einbauen, die Dir irgendwas anzeigen, damit Du feststellen kannst wo es hängen bleibt.

Kistenschieber:
Die Baudrate stelle ich in meinen Sketch hier ein:

void setup() {

Serial.begin(115200);

Ja, für Serial, aber nicht für Serial1. Serial ist für den seriellen Monitor, Serial1 für den IBus Empfänger. Eine Standard-Baudrate ist mir nicht bekannt, welche Du für den IBus Empfänger benötigst, weiß ich nicht.

  Serial1.begin(9600);

Kistenschieber:
Ich würde am ehesten vermuten das In der I2C Kommunikation das Problem liegt.
Nur wie finde ich das raus?

Ganz viele Ausgaben auf den seriellen Monitor schicken und schauen, wann er einfriert.

Das kalte Wasser ist kalt!

Update:

@agmue: eiskalt...

Ich habe die Stromversorgung überarbeitet, der Mega verfügt jetzt über einen eigenen Stepdown der direkt aus dem 3S LiPo gespeist wird.

Funktioniert schon besser, aber noch nicht perfekt. (Die "Hänger" sind viel seltener)
Allerdings mucken die Servos immer noch hin und wieder, das scheint wohl an der Kommunikation über I2C zu liegen.
Da setze ich dann noch mal an, ich bleibe am Ball.

Ich wollte mich aber schon mal für eure Hilfe bedanken, manchmal braucht es halt eine "Schups" in die richtige Richtung.

Gruß
Kistenschieber

Kistenschieber:
... manchmal braucht es halt eine "Schups" in die richtige Richtung.

Im Schubsen sind wir hier ziemlich gut :slight_smile:

Komm einfach ab und zu vorbei und lies ein bisschen mit. Hier schnappt man immer wieder gute Sachen auf.

Gruß

Gregor

Kistenschieber:
.....
Funktioniert schon besser, aber noch nicht perfekt. (Die "Hänger" sind viel seltener)
Allerdings mucken die Servos immer noch hin und wieder, das scheint wohl an der Kommunikation über I2C zu liegen.
Da setze ich dann noch mal an, ich bleibe am Ball.
.....

Was genau macht dein I2C-Bus ?

Der mag es nicht, wenn die Pullup-Widerstände fehlen oder zu groß sind.
Auch dürfen die Leitungen nicht zu lang sein und ungeschirmt an Störquellen vorbei gelegt sein.

HotSystems:
Der mag es nicht, wenn die Pullup-Widerstände fehlen oder zu groß sind.

Ja, auch noch eine Idee. Der originale Mega 2560 hat welche mit 10 kOhm drauf, die könnten beim Mega 2560 Clone fehlen. Oder die 10 kOhm sind zu groß, dann dürfen da noch externe dran (um 4,7 kOhm).