Servosteuerung per Potentiometer

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Ich wünsche einen angenehmen Abend!

    Ich habe mir ein neues Projekt vorgenommen, welches mich nun bereits einige Nächte beschäftigt.
    Das Ansteuern von Servo-Motoren mit einem Potentiometer über das Raspberry.
    Zum umwandeln der analogen Signale in digitale Signale verwende Ich dieses Kerlchen: http://www.conrad.de/ce/de/product/…t=detview1&rb=1
    Ein Script, mit welchem Ich die Signale einlese und per "Print" Befehl in Python ausgeben kann, habe Ich bereits geschrieben.
    Mein Problem ist nun, dass Ich es einfach nicht schaffe, den Servo mit diesen Signalen zu steuern.

    Hier mein Script:

    ---------------------------------
    [font="Menlo"]import time[/font]
    [font="Menlo"]import RPi.GPIO as GPIO[/font]
    [font="Menlo"]import os[/font]

    [font="Menlo"]GPIO.setmode(GPIO.BCM)[/font]
    [font="Menlo"]GPIO.setwarnings(False)[/font]
    [font="Menlo"]SERVO_MAX = 14.5[/font]
    [font="Menlo"]SERVO_MIN = 2.5[/font]
    [font="Menlo"]GPIO.setup(4, GPIO.OUT)[/font]

    [font="Menlo"]p = GPIO.PWM(4, 50)[/font]
    [font="Menlo"]p.start(2.5)[/font]

    [font="Menlo"]HIGH = True [/font]
    [font="Menlo"]LOW = False[/font]

    [font="Menlo"]def getAnalogData(adCh, CLKPin, DINPin, DOUTPin, CSPin):[/font]
    [font="Menlo"] GPIO.output(CSPin, HIGH)[/font]
    [font="Menlo"] GPIO.output(CSPin, LOW)[/font]
    [font="Menlo"] GPIO.output(CLKPin, LOW)[/font]

    [font="Menlo"] cmd = adCh[/font]
    [font="Menlo"] cmd |= 0b00011000[/font]


    [font="Menlo"] for i in range(5):[/font]
    [font="Menlo"] if (cmd & 0x10:( [/font]
    [font="Menlo"] GPIO.output(DINPin, HIGH)[/font]
    [font="Menlo"] else:[/font]
    [font="Menlo"] GPIO.output(DINPin, LOW)[/font]
    [font="Menlo"] GPIO.output(CLKPin, HIGH)[/font]
    [font="Menlo"] GPIO.output(CLKPin, LOW)[/font]
    [font="Menlo"] cmd <<= 1[/font]


    [font="Menlo"] adchvalue = 0[/font]
    [font="Menlo"] for i in range(11):[/font]
    [font="Menlo"] GPIO.output(CLKPin, HIGH)[/font]
    [font="Menlo"] GPIO.output(CLKPin, LOW)[/font]
    [font="Menlo"] adchvalue <<= 1[/font]
    [font="Menlo"] if(GPIO.input(DOUTPin)):[/font]
    [font="Menlo"] adchvalue |=0x01[/font]
    [font="Menlo"] time.sleep(0.05)[/font]
    [font="Menlo"] return adchvalue[/font]

    [font="Menlo"]CH = 0[/font]
    [font="Menlo"]CLK = 18[/font]
    [font="Menlo"]DIN = 24[/font]
    [font="Menlo"]DOUT = 23[/font]
    [font="Menlo"]CS = 25[/font]


    [font="Menlo"]GPIO.setup(CLK, GPIO.OUT)[/font]
    [font="Menlo"]GPIO.setup(DIN, GPIO.OUT)[/font]
    [font="Menlo"]GPIO.setup(DOUT, GPIO.IN)[/font]
    [font="Menlo"]GPIO.setup(CS, GPIO.OUT)[/font]

    [font="Menlo"]while True:[/font]
    [font="Menlo"]------ ab hier (Bis zur nächsten [/font][font="Menlo"]Markierung) habe Ich einen Schnipsel, welchen Ich verwenden kann/könnte oder auch nicht. Damit müsste es eigentlich machbar sein, doch reichen meine Kenntnisse dafür noch nicht ganz aus. [/font]

    [font="Menlo"] p = getAnalogData(CH, CLK, DIN, DOUT, CS)[/font]
    [font="Menlo"] if lastp != p:[/font]
    [font="Menlo"] val = (1023 - pot) * (SERVO_MAX - SERVO_MIN) / 1024 + SERVO_MIN[/font]
    [font="Menlo"] pot.setp(0, 0, val)[/font]
    [font="Menlo"] lastp = p[/font]

    [font="Menlo"]------[/font]
    [font="Menlo"] print getAnalogData(CH, CLK, DIN, DOUT, CS)[/font]

    [font="Menlo"]---------------------------------[/font]

    Der Servo (Modelcraft Y-3009) ist an Pin 7 (GPIO 4) angeschlossen.
    Mit Strom wird das ganze (noch) über den Pi versorgt.
    Als Sprache wollte Ich auch weiterhin Python(2.7) verwenden

    Meine Frage lautet nun, ob mir jemand dabei aushelfen könnte.
    Oder zumindest Tipps geben könnte, da Ich immerhin auch selbst daran arbeiten und auch lernen möchte.
    Vielen Dank schon einmal im Voraus!

    Einmal editiert, zuletzt von MrBorgBotik (19. August 2015 um 08:39)

  • Hallo MrBorgBotik,

    herzlich Willkommen in unserem Forum!

    Zu einer funktionierenden Lösung gehört neben einem ausreichend fehlerfreien Programm auch eine fehlerfreie Schaltung. Kannst Du die einmal posten?

    Zum anderen kann ich Dich nur warnen, die Spannungsversorgung eines Motors direkt vom Raspberry Pi zu beziehen. Je nach Schaltung (deswegen meine Frage dazu) verbrutzelst du den RPi...

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (19. August 2015 um 09:00)

  • Hallo MrBorgBotik,

    hast Du unterhalb des Potis noch Strippen vom Abgrefer über den Steg auf die untere Hälfte des Steckbrettes verlegt?

    Falls nicht, hat das längere Kabel auf der unteren Hälfte desw Steckbrettes außer einer Antennenfunktion keine weitere...

    Ist das so beabsichtigt?

    Wo ist der Motor?

    Abgesehen davon, dass der Motor über GPIO4 angeschlossen ist (welche anderen Anschlüsse sind noch beteiligt?), wird in der Software der GPIO4 nicht weiter verwendet (außer einmal als Ausgang geschaltet worden zu sein).


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (19. August 2015 um 13:46)

  • Hallo Andreas

    danke für die Schnelle Antwort!

    Ja klar habe Ich das getan, sonst würde Ich nicht einmal die Signale des Paris auslesen können.

    Der motor ist nicht auf dem Bild zu sehen, da es ja nicht von mir stamm.
    Es sind exakt die Anschlüsse verwendet wurden, welche auf dem Bild zu sehen sind.

    Dass GPIO4 nur einmal aus Ausgang gesetzt wurde und nicht noch einmal erwähnt wird rührt daher, da Ich nun nicht weiß wie Ich damit weiter umgehen soll.
    Ich habe halt ein Script-Schnipsel mit eingefügt, mit welchem Ich selbst schon einmal versucht habe zu arbeiten. Habe aber schnell gemerkt, dass mir ein Fehler unterlaufen sein muss, weshalb Ich mich nun an das Forum gewendet habe.

    Ich benötige halt Unterstützung beim Ausgeben der Werte auf GPIO4.
    Um die Werte in den Winkel des Servos umzurechnen sollte dies hier ja funktionieren: "[font="Menlo"]val = ([/font][font="Menlo"]1023[/font][font="Menlo"] - pot) * (SERVO_MAX - SERVO_MIN) / [/font][font="Menlo"]1024[/font][font="Menlo"] + SERVO_MIN[/font]"


    Grüße

    MrBorgBotik


  • hast Du unterhalb des Potis noch Strippen vom Abgrefer über den Steg auf die untere Hälfte des Steckbrettes verlegt?
    Falls nicht, hat das längere Kabel auf der unteren Hälfte desw Steckbrettes außer einer Antennenfunktion keine weitere...

    Ich glaube nicht, besser ich weiß, dass da keine Kabel verlegt werden müssen. Schließlich ist das Bild von mir. Würde man auch merken, wenn man sich die Bauform Trimmer liegend anschaut :angel:
    Automatisch zusammengefügt:


    Der Servo ist, wie bereits erwähnt, an GPIO 4 angeschlossen.
    Die Spannungsversorgung muss fürs Erste einmal darüber funktionieren. Doch ist mir bewusst, dass es nicht die beste Variante ist, weshalb Ich demnächst umsteigen werde. :)

    Hast Du die Spannungsversorgung für den Servo etwa direkt am GPIO oder den Steuereingang? Oder meinst du die Spannungsversorgung des AD-Wandlers?

  • Hallo raspiprojekt

    Das ist korrekt! Ich verwende allerdings nicht den gleichen Poti, das hätte Ich direkt dazu schreiben sollen!

    Ich versorge den AD-Wandler und den Servo über den 3,3V (AD-Wandler) und den 5V Ausgang (Servo) des Raspberrys.

    An sich funktioniert ja auch alles wie es soll. Ich kann mir auch die Werte des Potis (0-1023) per "print" ausgeben lassen. Es geht mir einzig darum, dass Ich den Servo nicht ansteuern kann. :helpnew:
    Dafür wollte Ich den Schnipsel (weiter unten im Script) als Vorlage verwenden, doch funktioniert das nicht. :(


    Grüße

    MrBorgBotik

  • Hallo Jörg, hallo MrBorgBotik,

    das ist aber auch nicht so leicht erkennbar - die meisten Potis haben drei Anschlüsse nebeneinander...

    Die Frage ist halt, ob der TE einen Baustein in der von Dir vorgegebenen Bauart oder einen anderen verwendet hat.

    Deswegen ja auch die Frage an Dich, MrBorgBotik, WELCHE SCHALTUNG hast DU verwendet - nicht: Welches Tutorial hast Du verwendet?


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (19. August 2015 um 14:59)

  • Hallo Andreas

    Ich habe exakt die gezeigte Schaltung von raspiprojekt verwendet. Nur halt, dass Ich einen anderen Poti verwende, welcher allerdings korrekt angeschlossen ist.
    Sonst könnte Ich mir ja auch nicht die Werte ausgeben lassen.
    Und wie Ich den Servo angeschlossen habe, habe Ich ja bereits erklärt.
    Wenn noch etwas fehlt, einfach sagen. :)

    Grüße

    MrBorgBotik

  • Naja ... technische Daten zum Servo sind natürlich mal wieder keine zu bekommen ...
    Wie steuerst Du den Servo genau an?
    Bei Python kann ich leider nichts beisteuern, nur so viel:
    Modellbau-Servos werden i.d.R. über PWM mit einer Frequenz von 50 Hz und Pulsweiten zwischen 1 ms (Vollausschlag links) und 2 ms (Vollausschlag rechts) angesteuert.
    Aufgrund der kapazitiven Last und des unbekannten Strombedarfs ist es keine gute Idee, einen Servo über die Boardspannung des RPi zu versorgen (zudem steht beim Servo was von 6 bis 7,4 V).
    Software-PWM kann funktionieren, muss aber nicht (Linux ist halt kein RT-OS) - dadurch ist jittern (flattern) möglich. Am besten mit einer passenden Library (z.B. -> pigpio <- ) probieren.

    cu,
    -ds-

  • [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Hallo dreamshader [/font]

    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Wie Ich den Servo mit den eingelesenen Signalen ansteure ist ja meine Frage. Ich weiß es nicht. [/font]

    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Ein Script zur einfachen Ansteuerung eines Servos habe Ich hier:[/font]

    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"][font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]-----------[/font][font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]------------------[/font][/font]

    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"][font="Menlo"]import RPi.GPIO as GPIO[/font]
    [/font]
    [font="Menlo"]import time[/font]


    [font="Menlo"]GPIO.setmode(GPIO.BOARD)[/font]

    [font="Menlo"]GPIO.setup(7, GPIO.OUT)[/font]


    [font="Menlo"]p = GPIO.PWM(7, 50)[/font]

    [font="Menlo"]p.start(7.5)[/font]


    [font="Menlo"]try:[/font]

    [font="Menlo"] while True:[/font]

    [font="Menlo"] time.sleep(0.1)[/font]

    [font="Menlo"] p.ChangeDutyCycle(7.5)[/font]

    [font="Menlo"] time.sleep(0.1)[/font]

    [font="Menlo"] p.ChangeDutyCycle(10.5)[/font]

    [font="Menlo"] time.sleep(0.1)[/font]

    [font="Menlo"] p.ChangeDutyCycle(12.5)[/font]

    [font="Menlo"] time.sleep(0.1)[/font]

    [font="Menlo"] p.ChangeDutyCycle(10.5)[/font]

    [font="Menlo"] time.sleep(0.1)[/font]

    [font="Menlo"] p.ChangeDutyCycle(7.5)[/font]

    [font="Menlo"] time.sleep(0.1)[/font]


    [font="Menlo"]except KeyboardInterrupt:[/font]


    [font="Menlo"] p.stop()[/font]


    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"][font="Menlo"] GPIO.cleanup()[/font]
    -----------------------------[/font]

    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Das stellt auch absolut kein Problem dar. Funktioniert auch reibungslos. (Bis auf die Reibung welche durch die mechanischen Bauteile entsteht ;) ) [/font]
    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Der Servo von Modelcraft nimmt 4,8 bis 6 V. [/font]


    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]Grüße[/font]

    [font="Source Sans Pro, Tahoma, Helvetica Neue, Arial, sans-serif"]MrBorgBotik [/font]

  • Zu Pfuiton kann ich, wie schon erwähnt, nix sagen ...

    Nach meinem Verständnis müsste der Wert folgendermassen berechnet werden:

    Code
    (ADC-Wert / 1023.0) * ((Vollausschlag rechts) - (Vollausschlag links)) + Vollausschlag links

    Mehr kann ich jetzt dazu aber nicht beitragen ...

    cu,
    -ds-

  • Ich habe es nun damit versucht:

    ---------------------------------------

    [font="Menlo"]import time[/font]
    [font="Menlo"]import RPi.GPIO as GPIO[/font]
    [font="Menlo"]import os[/font]

    [font="Menlo"]GPIO.setmode(GPIO.BCM)[/font]
    [font="Menlo"]GPIO.setwarnings(False)[/font]
    [font="Menlo"]SERVO_MAX = (14.5)[/font]
    [font="Menlo"]SERVO_MIN = (2.5)[/font]
    [font="Menlo"]GPIO.setup(4, GPIO.OUT)[/font]

    [font="Menlo"]servo = GPIO.PWM(4, 50)[/font]
    [font="Menlo"]servo.start(2.5)[/font]

    [font="Menlo"]HIGH = True [/font]
    [font="Menlo"]LOW = False[/font]

    [font="Menlo"]def getAnalogData(adCh, CLKPin, DINPin, DOUTPin, CSPin):[/font]
    [font="Menlo"] GPIO.output(CSPin, HIGH)[/font]
    [font="Menlo"] GPIO.output(CSPin, LOW)[/font]
    [font="Menlo"] GPIO.output(CLKPin, LOW)[/font]

    [font="Menlo"] cmd = adCh[/font]
    [font="Menlo"] cmd |= 0b00011000[/font]


    [font="Menlo"] for i in range(5):[/font]
    [font="Menlo"] if (cmd & 0x10:( [/font]
    [font="Menlo"] GPIO.output(DINPin, HIGH)[/font]
    [font="Menlo"] else:[/font]
    [font="Menlo"] GPIO.output(DINPin, LOW)[/font]
    [font="Menlo"] GPIO.output(CLKPin, HIGH)[/font]
    [font="Menlo"] GPIO.output(CLKPin, LOW)[/font]
    [font="Menlo"] cmd <<= 1[/font]


    [font="Menlo"] adchvalue = 0[/font]
    [font="Menlo"] for i in range(11):[/font]
    [font="Menlo"] GPIO.output(CLKPin, HIGH)[/font]
    [font="Menlo"] GPIO.output(CLKPin, LOW)[/font]
    [font="Menlo"] adchvalue <<= 1[/font]
    [font="Menlo"] if(GPIO.input(DOUTPin)):[/font]
    [font="Menlo"] adchvalue |=0x01[/font]
    [font="Menlo"] time.sleep(0.05)[/font]
    [font="Menlo"] return adchvalue[/font]

    [font="Menlo"]CH = 0[/font]
    [font="Menlo"]CLK = 18[/font]
    [font="Menlo"]DIN = 24[/font]
    [font="Menlo"]DOUT = 23[/font]
    [font="Menlo"]CS = 25[/font]


    [font="Menlo"]GPIO.setup(CLK, GPIO.OUT)[/font]
    [font="Menlo"]GPIO.setup(DIN, GPIO.OUT)[/font]
    [font="Menlo"]GPIO.setup(DOUT, GPIO.IN)[/font]
    [font="Menlo"]GPIO.setup(CS, GPIO.OUT)[/font]

    [font="Menlo"]while True:[/font]
    [font="Menlo"] p = getAnalogData(CH, CLK, DIN, DOUT, CS)[/font]
    [font="Menlo"] lastp = p[/font]
    [font="Menlo"] if lastp != p:[/font]
    [font="Menlo"] val = (p / 1023.0) * (SERVO_MAX - SERVO_MIN) + SERVO_MIN[/font]
    [font="Menlo"] servo.setPWM(0, 0, val)[/font]
    [font="Menlo"]# servo.stop()[/font]
    [font="Menlo"]# servo.start(val)[/font]

    [font="Menlo"]print getAnalogData(CH, CLK, DIN, DOUT, CS) [/font]

    ---------------------------------------

    Doch bezweckt habe Ich damit wieder nur, dass er Servo vor sich her zuckt. :helpnew:
    Ich weiß einfach nicht weiter.
    Ich könnte darauf wetten, dass es einzig ein minimaler Fehler ist, der dort drin steckt.

    Gruß

    MrBorgBotik

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!