serielle Kommunikation zwischen PC & Arduino

Erstmal ein Hallo und ein großes Lob für dieses klasse Forum. Ich hab hier beim Stöbern schon viele tolle Anregungen und Hilfen gefunden.

In meinem Fall bin ich jetzt aber nicht fündig geworden, also hier gleich mal fix angemeldet ^^

Mein Problem: Ich möchte zwischen einem Arduino (UNO oder Mega, beides vorhanden) und meinem PC über die serielle Schnittstelle kommunizieren. Übertragen möchte ich vom PC Steuerbefehle für angeschlossene Schrittmotoren und empfangen die Werte von Sensoren (Gabellichtschranken, etc.) Auf der PC-Seite bin ich gerade dabei mir ein Programm zu schreiben, alles kein Problem so weit. Im Prinzip klappt das alles, aber ...

Nun zu meinen konkreten Fragen: Was schicke ich am geschicktesten? Gibt es für solche Fälle eine Library oder muss ich mir ein eigenen Protokoll/eine eigene Logik einfallen lassen? (und wenn letzteres, eher Klartext ala 'GetSensor1' 'SetStepper2-Res1/16-Dir0-Step2000' oder nur 0 & 1 in einem gewissen Schema?) Ich steh noch ganz am Anfang und recht unerfahren in dieser Thematik, aber hey, man wächst ja bekanntlich mit seinen Aufgaben. :sweat_smile:

Auch bin ich mir nicht sicher, wie es mit dem Abfragen der Sensoren funktioniert. Der UNO hat ja nun nicht "so viele" Pins zur Verfügung. Kann ich gefahrlos (keine Ahnung, wie ich es sonst umschreiben soll) ein Shiftregister nutzen? Oder würde hier die Abfrage/Auswertung zu lange dauern und die Funktion der Schrittmotoren stören?

Und zu den Schrittmotoren noch eine abschießende Fragen: Bisher nutze ich für erste Experimente ein Steckernetzteil bei 9V & 0,6A (funktioniert zwar, bzw. Motor dreht sich, aber:). Welches Netzteil sollte ich benutzen/wie, bzw. nach welchen Kriterien sollte ich ein Netzteil auswählen? Habt ihr vielleicht Empfehlungen? Sollte ich vielleicht sogar ein altes ATX-Netzteil verwenden (Hatte hier im Forum gelesen, dass ein solches für Schrittmotoren nicht ratsam wäre, aber wieso)?

Gruß Neod

  1. Antwortversuch. Der erste wurde durch einen Timeout zunichte gemacht.

Es gibt die Firmata Bibliothek für die Komunikation zwischen Arduino un Processing. Ich kann Dir aber nichts genaueres sagen. Ansonsten, Ja Du kannst einen String ausdenken mit Befehlen und Paramentern und auf dem Arduino diesen dann entziffern.

Ja, Du kannst mit Schieberegistern Eingänge oder Ausgänge erweitern. Es gibt aber auch Port Expander mit 8 oder 16 Pins die einzeln und unabhängig voneinander als Eingänge oder Ausgänge verwendet werden können. Es gibt sie mit I2C oder SPI Interface.

Abschließende Gegenfrage: Welchen Schrittmotor hast Du und welche Treiberschaltung verwendest Du? Grüße Uwe

Danke Uwe für die schnelle Antwort.

Über Processing hatte ich schon mal was hier im Forum gelesen und die IDE sieht der des Arduino ähnlich, aber dieser Halbsatz auf der Wikipedia-Seite hatte mich dann abgeschreckt: "... und richtet sich vorwiegend an Gestalter, Künstler und Programmieranfänger."

Die Frage zur Kommunikation zielte nicht darauf ab, ob ich einen String/Binärdaten senden kann, sondern eher in die Richtung: - dauert die Übertragung eines Strings wesentlich länger? - ist ein String, der ja auch noch erst auf Arduinoseite verarbeitet werden muss, viell. zu "komplex"? - ist es ratsam eine Art Prüfsumme mitzuschicken um Fehlkommunikation auszuschließen?

Aber die Firmata-Bibliothek schein sehr interessant zu sein, ich glaub, die teste ich dieses Wochenende mal an und vielleicht hat sich damit ein Teil der Kommunikationsproblematik gelöst.

Auch bei dem Shiftregister hab ich mich wohl ungenau ausgedrückt, sorry. (lag sicher an der hinter mir liegenden Nachtschicht :sleeping: ) Ein paar PISO-Shiftregister hatte ich mir bereits besorgt; meine Frage zielte auch hier eher darauf ab, ob das Auslesen des Shiftregisters Probleme beim reibungslosen Betrieb eines Schrittmotors betreiben würde. Schließlich müsste ich ja im Idealfall nach jedem step des Schrittmotors die Sensoren abfragen, ob denn 'irgendwo ein Endstop' ausgelöst hat. Währenddessen dreht sich nüschts, was sich vielleicht ja gravierend auf die rpm auswirken würde/könnte. (meine Befürchtung)

Zu deiner Gegenfrage: Aktuell verwende ich als Treiber: Pololu A4988 und A4988 Black Edition Und als Schrittmotor: Einen SY42STH47-1206A (NEMA17) mit 4 V / 1,2 A und 200 Schritte pro Umdrehung

[u]Edit:[/u] Noch zwei Fragen zu Schrittmotoren: - Kann ich die maximale RPM ermitteln, abgesehen durch 'TryAndError'? - Wie "mach" ich eine Rampe? Fange ich mit einem langen Delay zwischen den Schritten an und verkürze einfach das Delay, oder gibt es da eine Art Faustformel?

Gruß Neod

Strings sind schwieriger zu handhaben. Du musst diese dann zerlegen (z.B. mit strtok(), strstr(), strchr() oder strcspn + strcpy()) und die Teile mit Funktionen wie strcmp() vergleichen. Und andere Teile in Integer wandeln. Wenn du dich mit C String Handling auskennst ok, aber für Anfänger ist das eher abschreckend und es ist generell fehleranfällig, auch wenn man genau weiß was man machen muss.

EDIT: TextFinder ist vielleicht noch eine Option für String Parsen, aber für diesen Fall auch mehr Aufwand als es sein müsste: http://playground.arduino.cc/Code/TextFinder

Außerdem landen alle String Literale auf dem Arduino standardmäßig im RAM! Viele String Literale (die du als Vergleichswerte brauchst) im Programm fressen schon relativ viel. Das lässt sich aber auch leicht umgehen, wenn man die entsprechenden PROGMEM Konstanten und _P Funktionen verwendet. Dann werden die nichts ins RAM kopiert, sondern bleiben im Flash. Das vergleicht z.B. einen String im Flash mit einem Array: strcmp_P(PSTR("String im Flash"), bufffer)...

Wobei das nicht unbedingt sein muss, aber es kann relevant werden wenn du noch was anderes RAM intensives wie Ethernet machst. Ansonsten hast du aber mit 2kB RAM genug :) Von den Arduino String Objekten kann man nur abraten, da das durch den dynamischen Speicher noch mehr RAM frisst.

Wenn du aber Kommandos als Zahlen überträgst entfällt das alles und du kannst viel einfacher Vergleichen. Du legst auf beiden Seiten eine Listen von const Variablen oder enums an, die die Kommandos enthalten. z.B. enum commands { SET_STEPS, SET_DIRECTION }; oder const byte SET_STEPS = 0; const byte SET_DIRECTION = 1;

Dann kannst du ein Byte aus der seriellen Schnittstelle auslesen und einfach mit einem sprechenden Wort vergleichen. In der Realität steckt da einfach eine Integer Konstante dahinter. Aber deren Wert ist für dich meistens egal. Du weißt dann auch anhand des Kommandos, wie viele Bytes du danach noch einlesen musst, z.B. für die Nummer des Motors oder die Anzahl de Schritte.

Pass aber auf, dass er die Konstanten (vor allem bei enums) nicht in mehreren Bytes überträgt, sonst stimmt eventuell die Anzahl der Bytes die du ausließt nicht. In C reicht da ein Cast auf Byte. In Java oder C# sind enums typ-gebundener, aber man kommt auch an den Wert. Oder eben einzelne Variablen für jedes Kommando.

neod: Zu deiner Gegenfrage: Aktuell verwende ich als Treiber: Pololu A4988 und A4988 Black Edition Und als Schrittmotor: Einen SY42STH47-1206A (NEMA17) mit 4 V / 1,2 A und 200 Schritte pro Umdrehung

[u]Edit:[/u] Noch zwei Fragen zu Schrittmotoren: - Kann ich die maximale RPM ermitteln, abgesehen durch 'TryAndError'? - Wie "mach" ich eine Rampe? Fange ich mit einem langen Delay zwischen den Schritten an und verkürze einfach das Delay, oder gibt es da eine Art Faustformel? Gruß Neod

Maximale RPM aus dem Datenblatt. Da gibt es ein Diagramm des max Drehmoments in Funktion der Schritte /Sekunde bezogen auf Strom oder Spannungsansteuerung. Das gilt für konstante Stepzahl. http://www.robotikhardware.de/download/schrittmotor_po1206a.pdf ist das Diagramm bezogen auf eine Versorgungsspannung von 24V, Halbschritte und Stromsteuerung mit 1,2A.

Du kannst kein delay() verwenden wenn Du zwischendurch die Endschalter abfragen willst. Ansonsten ja, Du mußt die Ansteuerfrequenz langsam erhöhen (Pausen zwischen den Schritte verkleinern).

Grüße Uwe