Linker Kit Servomodul

  • Hallöchen zusammen,



    Ich bin neu hier im Forum, beschäftige mich aber schon ein wenig länger mit dem Raspberry Pi. Nun normalerweise fand ich immer alle antworten auf probleme bei meinen Projekten durch Googlen, nur dieses mal konnte ich beim besten willen keine Lösung finden. :wallbash:


    Aber gut gibt es dieses Forum :thumbs1: .


    Nun zu meinem Problemchen:
    Ich habe mir letztens einen Raspi3 geholt und da entdeckte ich Spontan das Linker Kit, und dachte coole sache mir nehme ich gleich dazu. Darauf Kaufte ich das BaseBoard, einen Temp.-Sensor eine Digitalanzeige und ein ServoController.
    Zuhause dann die Ernüchterung, die Doku des Linker Kit ist nicht gerade umfangreich. Vieles muss man mühsam Googlen, und auf den Offiziellen Seiten findet man mehrheitlich C-Code für Adruino.


    Nun arbeite ich an einem Projekt mit dem Servo Controller, dieser kommuniziert via Serieller Verbindung mit dem PI, also Rx/Tx, leider habe ich bisher nie mit der Seriellen verbindung des PIs gearbeitet.
    Die beste info über diesen Controller habe ich bei ELV gefunden, dort gibt es ein deutsches Datenblatt mit einigen Infos. http://files.elv.de/Assets/Pro…/122132_SERVOMODUL_um.pdf


    Daraufhin habe ich mir ein kleines Testscript in Python geschrieben:


    Wenn ich dieses Script auf meinem Pi3 ausführe, wird mir in der Ausgabe angezeigt das eine Verbindung geöffnet wurde, jedoch hängt sich das Script auf wenn es bei der Zeile ser.write('S') angekommen ist.
    Dies trifft aber auch auf alle Read/Write befehle zu, jedesmal ein Hänger, jedoch kein Fehler oder Sonstwas.


    Da ich bisher nie mit Seriellen Verbindungen gearbeitet habe, habe ich weiter gegoogelt aber nach 6 stunden Probieren/Suchen habe ich aufgegeben. Was mir bei meiner suche aber auffiel das bei Verbindungen z.b zwischen zwei PIs das ganze gekreuzt sein muss also Rx -> Tx und Tx -> Rx, dies traute ich mich aber nicht zu Testen.


    Das ganze sieht momentan so aus:
    500x300


    Ich bin wirklich am verzweifeln, ich hoffe jemand kann mir bei meinem Problemchen helfen. :danke_ATDE:


    Liebe grüsse Kintaro

  • ... Was mir bei meiner suche aber auffiel das bei Verbindungen z.b zwischen zwei PIs das ganze gekreuzt sein muss also Rx -> Tx und Tx -> Rx, dies traute ich mich aber nicht zu Testen.


    Das RX mit TX und umgekehrt i.d.R. miteinander verbunden sein müssen liegt in der Natur der Sache, sonst funktioniert es nicht. Man muß halt nur darauf achten, das an die GPIO's des RPi keine 5V o. größer kommt, da die GPIO's des RPi's nicht 5V tolerant ist. Im Zweifelsfall sollte man mit einem Meßgerät nachmessen und bei Bedarf einen Levelshifter verwenden.

  • Hallöchen,
    danke erstmals für die Antworten, ich habs nun mal getestet und Rx/Tx über kreuz verbunden, jedoch der Fehler bleibt gleich und das script hängt sich auf. Irgendwie verwirrend :s


    Grüsse kintaro

  • Bist du sicher, dass das beim write haengt? Ich halte das fuer eher unwahrscheinlich. Beim danach erfolgenden read schon eher. Und dann waere die Frage, ob er gar nichts liest, oder nicht die geforderten 10 Byte.

  • Ja er hängt bei Write, da ich zum testen momentan folgenden code verwende:


    Code
    import serial
    import time
    ser = serial.Serial("/dev/ttyAMA0", baudrate=9600, timeout=3.0)
    print ser
    print 'Starte motor'
    ser.write('S')
    print 'ende'


    Da passiert ja nicht viel mit dem Motor, aber wenn der Befehl abgesendet wurde sollte in der Konsole Ende stehen.

  • Also nachdem ich noch mal den verlinkten Artikel gelesen habe, verstehe ich nicht warum du versuchst, Daten einzulesen. Da schreibt nichts und niemand etwas auf die Schnittstelle. Also wird das read auch nie zurueckkehren.


    Auch die raw-inputs sind nicht das, was du glaubst was sie sind. Wenn du eine 1 fuer den PWM-Kanal schreiben sollt, dann bewirkt raw_input(1) das *nicht*, dass dort ein "\x01"-Byte erzeugt wird. Ich wuesste gar nicht, wie man mit raw_input Byte-Werte im nicht-druckbaren bereich erzeugen will.


    Die raw_inputs muessen also weg. Fuer die 1 musst du "\x01" schreiben.


    Das PWM-Tastverhaeltnis finde ich etwas seltsam erklaert, am Ende scheint es sich einfach um HI/LO eines 16-Bit-Wertes zu handeln. das kannst du in Python zB gut mit dem Modul struct machen:


    Code
    import struct
    wert = 12345
    print struct.pack(">H", wert)


    Also einfach einen wert ausdenken (50% klingt gut, also 32768), und dann einsetzen: struct.pack(">H", wert).


    Last but not least einfach "E" wegschicken, du brauchst auch da kein raw_input.


    Alles in allem laesst sich das ganze auch viel eleganter so machen:


    Code
    ser.write("S{}E".format(struct.pack(">bH", kanal, pwm)))
  • Danke für die Ausfühliche Antwort, ich habe mich ein wenig mit diesem Ansatz beschäftigt, jedoch ist es komisch das selbst jetzt der write nicht ausgeführt wird. Sobald ein write Befehl gesendet wird, hängt das Script. Wenn ich dann nach einer Weile mit CTRL+C abbreche erhalte ich diese meldung:



    Code
    pi@raspberrypi:~ $ python motor.py
    Serial<id=0x76a7bc50, open=True>(port='/dev/ttyAMA0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=3.0, xonxoff=False, rtscts=False, dsrdtr=False)
    Starte motor
    SdE
    ^CTraceback (most recent call last):
     File "motor.py", line 10, in <module>
       ser.write("S{}E".format(struct.pack(">bH", kanal, pwm)))
     File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 475, in write
       n = os.write(self.fd, d)
    KeyboardInterrupt


    Das Board Selbst scheint richtig montiert zu sein, ich kann Module über Analog & GPIO ansteuern und diese machen was sie sollen. Ich habe den Controller über UART angeschlossen, den Motor Direkt an GPIO anschliessen und ihn so zu steuern habe ich mich nicht getraut, da ich gelesen habe das man dies unter keinen umständen tun soll, egal wie Klein der Motor ist.


    Der Motor Schafft 8000U/min und hatt eine Betriebsspannung von 1.5-3v DC, an eine 3v Quelle angschlossen, tut dieser brav seinen Dienst.


    grüsse onekintaro

  • Der Stacktrace ist jetzt erst mal das, was man erwarten wuerde. Was man *nicht* erwartet ist, dass os.write klemmt. Um da Missverstaendnisse auszuraeumen: ob du den UART verkabelt hast oder nicht, hat damit nichts zu tun. Der oettelt auch ohne Anschluesse munter vor sich hin. Empfangen geht dann natuerlich nicht.


    Insofern muss das Problem also PI-seitig sein. Mir fallen auf Anhieb folgende Dinge ein:


    - ein anderer Prozess (zB getty) sitzt auch auf dem UART und verhindert, dass du den nutzt. Ich haette dann eine Fehlermeldung erwartet, aber wer weiss.
    - Flusskontrolle. RTS/CTS/DTS und wie sie alle heissen sorgen ja dafuer, dass der Sender erst sendet, wenn ihm das erlaubt wird. Du solltest also sicherstellen, dass die Flusskontrolle aus ist. An sich benutzt du serial.Serial korrekt, aber vielleicht hauen da auch andere Prozesse/Systemeinstellungen rein.



    Ein guter Weg da weitere Informationen zu gewinnen ist RX und TX auf PI-Seite mit einer Drahtbruecke zu verbinden, damit man gesendete Daten gleich empfaengt. Und dann mit einem Programm wie screen oder minicom zu arbeiten, um mal Zeichen zu verschicken (und zu empfangen). Erst wenn das verlaesslich klappt, kann man dann in Python weiterschrauben.

  • Ich habe es nun mit einer Drahtbrücke versucht, erst auf dem Board dann auch direkt auf dem Pi3, selber Fehler. Jedoch habe ich nun nach etwas googlen noch folgendes gefunden auf der Seite: http://elinux.org/RPi_Serial_Connection


    Quote

    NOTE FOR RASPBERRY PI 3 The raspberry pi 3 has changed things around a bit: ttyAMA0 now refers to the serial port that is connected to the bluetooth. The old serial port is now called ttyS0. So if you have an RPI3, everywhere you see "ttyAMA0" below, you should read "ttyS0".


    Ich werde nun noch die Anleitung auf der Seite befolgen und versuche es nochmal beim pi3 ansonsten versuche ich es noch mit dem Pi2.


    Grüsse kintaro

    Edited once, last by kintaro ().

  • Ich habe nun mithilfe des Pi2 endlich eine Serielle Verbindung zustande bekommen, beim Pi3 habe ich es einfach nicht hinbekommen aber das macht nichts, denn dann kann ich den Pi3 andersweitig verwenden. :thumbs1:


    Mit Folgendem Code und einer Drahtbrücke erhalte ich auch ein Ergebnis:



    ergibt


    Code
    pi@raspberrypi:~ $ python xser.py
    Serial<id=0x769cfaf0, open=True>(port='/dev/ttyAMA0', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)
    Starte motor
    S
    ende


    Nun habe ich ein Wenig an meinem Motor Code gearbeitet und alles wieder verkabelt.
    Aber da ich noch nie wirklich mit "char" Kodierten befehlen gearbeitet habe, habe ich trotz googlen leider nur wenig ahnung was ich da an meinen Controller sende.


    Dieser Testcode sollte den Controller ansprechen, den Kanal 1 Auswählen und dann den Motor drehen lassen und dann wieder ausschalten.
    Der Code wird auch gesendet aber dennoch macht der motor keinen wank :s .



    Grüsse Kintaro

  • Ein paar Anmerkungen:


    - Programmieren ist nicht raten. Der Code, den ich dir gegeben habe, hat schon gepasst. Und einfach mal format um irgendwas rumzuwickeln hilft auch nicht.
    - was du da oben gemacht hast ist *nicht* der Spezifikation entsprechend, hat mindestens mal ein S zu viel.
    - auch ist das zweite Kommando fehlformatiert, es *fehlt* das S
    - Computer zaehlen ab 0. Es kann sein, dass Kanal 1 nicht der erste Kanal, sondern schon der zweite ist - naeheres steht bestimmt in deiner Doku.
    - aehnliches gilt fuer den zweiten Wert, der auf zwei Bytes verteilt wird: der Wertebereich eines (nicht-vorzeichenbehafteten) 16-Bit-Wertes ist 0-65535. Da die PWM von 0-100% geht, und du den Wert 306 angegeben hast, ist das zumindest nicht unwahrscheinlich, dass du dort 0.00466 statt den gewuenschten 50% angegeben hast. Damit ist es auch nicht verwunderlich, wenn six nix bewegt. Auch dieser Wertebereich sollte in der Doku erwaehnt sein.

  • Hallo __deets__,
    Ich glaub ich war gestern ein wenig verpeilt vor lauter Code, mit Python habe ich biser nur sehr wenig gemacht. Ich habe heute nochmal einen neuen Anlauf gewagt und nochmal alles komplett Bereinigt und getestet, ich habe mir auch nochmal alle deine Ratschläge durchgelesen. Rx/Tx haben in jedem Script einwandfrei Funktioniert mit einer Drahtbrücke. Nur die Verbindung zum Controller scheint nicht zu klappen. :s
    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Ich habe heute Scripte in PHP, Python und C++ geschrieben und getestet. PHP wäre mein Favorit, da das ganze Später noch hinter einem Webserver läuft.[/font]
    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Leider wieder alles ohne erfolg, aber evtl. habe ich einfach nicht den Richtigen Controller =( .[/font]
    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Auf dem Controller sind 3 Pins pro Kanal, ich hab aber nur 2 Pin Motoren, angeschlossen an PWM und GND, ich glaube aber ich muss mir doch ne andere Lösung einfallen lassen. =([/font]


    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Das erste Programm was ich heute getestet habe ist ein C++ Script:[/font]



    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Dieses habe ich möglichst ähnlich wie das Beispielscript gehalten, einfach für wiringpi umgeschrieben. Kompiliert, aber nix tut sich.[/font]


    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]2. Script war dann das Python Script, dieses habe ich so verwendet:[/font]


    Und zuletzt das PHP-Testscript, aber auch dies führte nicht zum gewünschten ergebnis:
    [code=php]<?php
    error_reporting(E_ALL);
    ini_set('display_errors', '1');
    include "php_serial.class.php";


    $serial = new phpSerial;
    $serial->deviceSet("/dev/ttyAMA0");
    $serial->confBaudRate(9600);
    $serial->confParity("none");
    $serial->confCharacterLength(8);
    $serial->confStopBits(1);
    $serial->deviceOpen();
    $serial->sendMessage('S');
    $serial->sendMessage(pack("C",1));
    $serial->sendMessage(pack("h",'32768/0xFF'));
    $serial->sendMessage('E');


    $serial->deviceClose();
    echo "I've sended a message! \n\r";
    ?>[/php]


    Ich weiss echt nicht mehr was ich noch versuchen kann. Aber es wird wohl darauf auslaufen das ich einen andern Controller für meine 4 Motoren brauche. :X


    Liebe grüsse
    kintaro

    Edited once, last by kintaro ().

  • Du hast ein fundamentales Thema noch nicht durchstiegen: wie die PWM funktioniert. Du belegst deine zwei Bytes (HI, LO) mit Werten von maximal 450 - das sind immer noch nicht mal 1% des moeglichen Werteraumes. Da passiert an deinem Motoren mal gerade gar nix, die werden hoechsten ueber Stunden ein Grad waermer.


    Warum legst du nicht mal voll Pulle - 0xff, 0xff bzw 0xffff bzw 65535 an? *DANN* kannst du mal schauen, ob etwas passiert oder nicht.


    Meine Bemerkungen bezueglich Kanal 0/1 sehe ich auch nicht umgesetzt, bzw. es fehlt ein Verweis darauf, dass du sichergestellt hast, dass du mit der 1 am richtigen Anschluss bist.


    Last but not least: du wirst auch mit anderen Ansteuerungen aenhliche Probleme haben. Ob die, die du hast, fundamental geeignet ist oder nicht haengt von vielen Dingen ab, die du noch nicht kommuniziert hast.