I2C Schnittstelle des Arduino mit Python ansteuern

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Mätti
User
Beiträge: 7
Registriert: Freitag 28. Dezember 2018, 04:57

Hey Leute,

ich würde gerne ein Adafruit MCP4725 A0 DAC mit dem Arduino über die I2C Schnittstelle ansteuern um einen Motor langsamer laufen zu lassen. Mit der PWM versaut mir das gewackel die Messung! An sich wäre das ja auch ganz einfach, aber ich steuere den Arduino von meinem LapTop aus mit einem (bisschen amateurhaft selbst geschriebenen) Pythonprogramm und dafür gibt es, soweit ich das sehen konnte, keine Beispiele im Internet.
Hat jemand von euch ne Ahnung, wie ich das machen kann?

Ich bin gespant auf eure Meinungen!
LG Martin
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wofür genau gibt es keine Beispiele? Wenn du den arduino schon steuerst über Python, dann hast du den Teil doch. Und für den DAC gibt es auch arduino Code. Was also genau ist dir unklar?

Jenseits davon: ich bin deinem Vorhaben gegenüber skeptisch. Ein DAC erzeugt eine wohl definierte Ausgangsspannung. Die ist aber üblicherweise NICHT zum treiben eines Motors geeignet. Du brauchst da mindestens noch eine Leistungsstufe.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Eins vorweg: Auf dem Arduino läuft kein Python, auch kein MicroPython. Dafür hat der Controller zu wenig Speicher.

Hinter einem Analogausgang steckt keine Leistung.
Die Ausgänge schaffen einen Strom von 25 mA. Das ist etwas wenig.
(Datenblätter lesen ist wichtig)

Du kannst entweder einen Motor via PWM ansteuern, wirst dafür aber eine H-Brücke benötigen: https://www.sparkfun.com/products/14451
Funktionen: via PWM Geschwindigkeit regeln, Linkslauf, Rechtslauf, Standby, bremsen
Ein weiterer Vorteil ist, dass die Betriebsspannung von der Steuerspannung unabhängig ist.
D.h. du kannst auch einen 12V Motor betreiben. Die 12V musst du aber dann der H-Brücke zur Verfügung stellen.

Die Alternative wäre ein Servo, den du auch via PWM ansteuerst.
Der Unterschied besteht darin, dass der Duty-Cycle die Ziel-Position vorgibt.
Diese lassen sich aber nicht rotatorisch Betreiben. Sehr genau sind sie auch nicht.

Eine weitere Alternative wäre ein Schrittmotor. Schrittmotoren lassen sich sehr genau positionieren.
Ich setze z.B. für unsere Neuentwicklung Servo-Motoren von https://www.henschel-robotics.ch/ ein.
Die sind zwar teuer, aber die Ansteuerung ist sehr einfach und zweckmäßig. (0.1° Genauigkeit)

Es gibt aber auch bezahlbare Schrittmotoren ohne Controller. Den Controller muss man sich dann natürlich extra kaufen.
Für den Arduino gibt es auch eine Schrittmotorkarte. Andere Hersteller haben das Layout etwas geändert und bieten den
Arduino mit integriertem Schrittmotor-Controller an. Letztendlich ist nur eine Leistungsstufe vorgeschaltet. Die Logik
macht weiterhin der Controller selbst.

Zuvor habe ich Motoren von Nanotec eingesetzt, die sich aber entweder nur via PWM ansteuern lassen oder
irgendein Protokoll unterstützen, dass eher in der Industrie-Automatisierung Anwendung findet.

Mit dem Arduino kannst du definitiv ein sauberes PWM-Signal erzeugen. Ich weiß nur nicht, wie es aussieht, wenn der Duty-Cycle geändert wird.
Das kann das Signal sehr hässlich aussehen. Ist auch hörbar aufgrund des angeschlossenen Motors.

Für Servos und Schrittmotoren gibt es für den Arduino Bibliotheken. Das hat aber nichts mit Python zu tun.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Mätti
User
Beiträge: 7
Registriert: Freitag 28. Dezember 2018, 04:57

Hallo ihr Zwei, vielen Dank für eure sehr qualifizierten Kommentare, das ist mir tatsächlich alles bekannt und ich beherzige das auch, aber der Kern des Problems bleibt. Vielleicht habe ich meine Frage nicht ganz präzise gestellt!

Mein Arduino hat nur Firmata auf seinem Speicher, sonst nichts, alles andere mache ich von meinem Computer aus mit einem Python Programm, Python läuft also nicht auf dem Arduino, sondern auf dem Computer und sendet nur Befehle an den Arduino.

Der Motor wird natürlich nicht direkt an den DAC angeschlossen, das wäre wahrscheinlich der Tod für den Arduino, oder den DAC, das mach ich nicht, da ist noch ein geeignetes Bauteil dazwischen.

Ein Schrittmotor ist für meine Anwendung nicht geeignet und löst auch nicht das Problem, dass die PWM mir die Messung versaut! Auch eine Glättung des PWM Signals hab ich schon versucht, das Hilft aber nicht!

Ich brauche als einen Python Code, der dem Firmata im Arduino sagt, es solle doch bitte den I2C verwenden!
Unten findet Ihr Beispielcode und einen Screenshot vom aktuellen Programm, leider kann ich euch nicht den ganzen Code zeigen, da es ein Forschungsprojekt ist, aber vielleicht reicht euch das ja.

Vielen Dank nochmal und liebe Grüße
Martin


Import für die Kommunikation mit dem Arduino

Code: Alles auswählen

	from pyfirmata import Arduino, util

	iterator = util.Iterator(ardu)	
	iterator.start()	
Momentan benutzter Code für die Motordrehung, leider nur 100% Geschwindigkeit möglich, da sonst PWM

Code: Alles auswählen

	pinA1 = ardu.get_pin('d:8:o')		
	pinA2 = ardu.get_pin('d:11:o')
	speedA = ardu.get_pin('d:9:p')

	pinA1.write(0)					#Einstellung für den Uhrzeigersinn
	pinA2.write(1)					#Einstellung für den Uhrzeigersinn
	speedA.write(1)					#Einstellung für den Uhrzeigersinn
Screenshot vom Programm
Bild
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Mätti: Also vorweg: das ist nicht so ganz meine Baustelle, auch wenn ich privat seit dem Raspi deutlich mehr mit Hardware gemacht habe als früher. Aber mir ist das Problem immer noch nicht klar. Und ich vermute ich bin nicht der einzige dem „[…], dass die PWM mir die Messung versaut“ nicht genug Erklärung ist. Welche Messung? Was und warum misst Du denn da? Und wie wird das durch die I2C gelöst? Wofür soll die benutzt werden?
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Fragezeichen die Blackjack hat stellen sich mir auch. Das eine PWM prinzipiell einer wie auch immer gearteten analogen Ansteuerung unterlegen sein soll kann ich mir nicht so recht erklären. Da fehlt noch einiges an Hintergrund.

Wir dem auch sei: laut https://github.com/firmata/protocol/blob/master/i2c.md musst du eben entsprechend deinem DAC sysex Nachrichten erstellen. pyfirmata kann sysex.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Mach mal ein Foto vom Versuchsaufbau. Vielleicht verstehen wir dann besser was du meinen könntest. Ich hab bisher auch nur geraten.
Was willst du denn mit dem Motor antreiben?
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Mätti
User
Beiträge: 7
Registriert: Freitag 28. Dezember 2018, 04:57

Hallo ihr Drei,
es geht um eine Leitfähigkeitsmessung, aber im Nanoampere Bereich, die PWM Schwankungen beeinflussen trotz Schirmung, Erdung und Faradaykäfig die Messung zu stark, als dass Aussagekräftige Messwerte gewonnen werden können (Rauschen 3-10 Fach des Messwertes).
Über den I2C Port vom Arduino kann ein DAC-Modul gesteuert werden, dass einen analoges Signal ausgibt und somit das Rauschen vermeidet.
Was ich Messe und warum sollte für die Frage keine Rolle spielen, da ich nicht nach anderen Lösungen suche, sondern nur nach einem Code für die Kommunikation zwischen Python auf meinem Computer und dem I2C am Arduino. Ich darf euch leider keine genaueren Infos geben, da es ein Forschungsprojekt ist, das Setup und was ich schlussendlich mit dem Analogsignal anfange ist ja aber auch für die Frage eigentlich irrelevant.
@_deets_ Vielen Dank, das geht schon in die richtige Richtung.


Hier die für die Frage relevante Schaltung ;-)
Bild
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn es in die richtige Richtung geht- was fehlt dann? Die Dokumentation des Protokolls ist finde ich ziemlich gut, und mit Oszilloskop oder Logik analyser sollte sich auch schnell prüfen lassen, wo es hakt, wenn der DAC nicht tut. Für adafruit gibt es ja üblicherweise auch Code, den du wegen Firmata natürlich nicht 1:1 benutzen Kannst - aber der Anleitung ist.
narpfel
User
Beiträge: 643
Registriert: Freitag 20. Oktober 2017, 16:10

@Mätti: Hast du bedacht, dass der Motor selbst unter Umständen auch relativ viel Interferenz erzeugen kann? Und im Nanoampèrebereich kann man auch schon mit Triboelektrizität Probleme bekommen, wenn man Pech hat.

Es gibt auch Labornetzteile, die sich per Computer steuern lassen.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Hab ich das jetzt so richtig verstanden, dass dein Motor rauschen auf das Analog Eingangssignal gibt (ein Grundrauschen ist immer vorhanden).
Muss die Messung mit dem Motor synchronisiert sein? Ohne Motor hast du kein Rauschen auf dem Eingang?
Am besten ein Oszilloskop anschließen und mal das Signal des Motors und der Messung gleichzeitig beobachten.

Wie ist die Spezifikation des Motors? Typ, Betriebsspannung, Stromaufnahme

Unsere Neuentwicklung (Radar 24GHz) wird auch (noch) mit einem DC Motor angetrieben. Das Signalprocessing macht ein mini pc, der Antrieb wird dediziert durch einen Raspberry PI gesteuert und bekommt gleichzeitig Daten vom elektronischen Kompass. Ich bin so vorgegangen, weil ich mit dem I2C auf dem mini PC noch ein Display und einen LED-Stripe ansteuern musste. Eine große Befürchtung, die ich hatte, dass das Signal vom Motor die Messung komplett versaut, da ich die Signale mit einer Samplingkarte umwandle und auch selbst ein Ausgangssignal für den Transceiver generiere. Leistungen, die über andere Leitungen gehen und zufällig parallel mit den Messleitungen liegen, können das Signal beeinflussen. Da mein Motor nur max 500mA benötigt, hält sich das in Grenzen.

Das eine ist Physik und das Problem was du beschrieben hast könnte man auch mit der Software zu tun haben.
Man sollte auch nicht vernachlässigen, dass das Firmata Protokoll ggf. den PWM Ausgang versauen könnte.
Bei zu vielen Kommandos hintereinander gerät der Controller ins "Stocken".

Hast du die Möglichkeit nach mehr Geld zu fragen oder musst du das Projekt aus eigener Tasche finanzieren?
Der einfachste weg für dich wäre es einen zweiten Arduino-Controller zu nehmen, der direkt für den Motor die passenden Leistungs-Ausgänge bereit stellt.
Die Kommunikation kannst du dann Seriell via Rx und Tx betreiben. Der erste Controller auf dem Foto wäre dann der Master und der Controller mit dem Motor wäre der Slave.
(Die Wörter Master/Slave soll man aufgrund PC nicht mehr verwenden, ich mache es trotzdem! )

Falls du das begründen musst: Der Motor beeinflusst die Messung, ergo sollten die Signale physisch voneinander getrennt und abgeschirmt sein.

Ob das wirklich so ist, wissen wir noch nicht.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Mätti
User
Beiträge: 7
Registriert: Freitag 28. Dezember 2018, 04:57

Hallo ihr drei,
am Motor und liegt es nicht, das sind sehr teure Dinger aus der Schweiz, alles getestet und auch mit dem Oszi angeschaut, es liegt definitiv an der PWM, weshalb ich diese umgehen will mittels der I2C Schnittstelle. Ich will nicht mein ganzes Setup ändern oder sonst noch etwas, ich möchte nur in meinem Programm die aktuelle Motorsteuerung so umschreiben, dass sie nicht mehr über einen PWM Ausgang läuft, sondern über die I2C und den daran hängenden DAC. Genau an der Stelle komme ich nicht weiter, da ich keine Code-Beispiele im Internet finde, wie Python über Firmata dem Arduino sagen kann, was er am I2C ausgeben soll.

@_deets_ der Hinweis mit sysex hat mir ein wenig erkentnis gebracht, aber ich werde aus der Dokumentation absolut nicht schlauer. Ich kenne mich leider nicht gut genug damit aus, als dass mir das helfen würde. Wenn du das verstanden hast, könntest du mir dann vielleicht mit einem Beispiel Code auf die Sprünge helfen?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Code: Alles auswählen

ardu.send_sysex(0x76, [adresse, 0, MCP4726_CMD_WRITEDAC, obere_bits, untere_bits])
wobei du das Kommando und die Berechnung der Bits hier nachschlagen kannst

https://github.com/adafruit/Adafruit_MC ... CP4725.cpp
Mätti
User
Beiträge: 7
Registriert: Freitag 28. Dezember 2018, 04:57

Hey _deets_,

vielen Dank, ich werde das im neuen Jahr mal ausprobieren, sieht auf den ersten Blick sinnvoll aus!
Euch allen einen guten Rusch und n frohes neues Jahr

LG Martin
Antworten