Aus deinem Perl-Quelltext:
$ob->write_settings
Ist das nicht eine Methode? Dann muß es heißen:
$ob->write_settings()
Ok. Hier mein C#-Arduino-Kommunikations-Programm.
-Es ist zugeschitten auf das oben gepostete Arduino-Programm.
-Es ist ein einfaches Konsolenprogramm, das sich den Arduino-Port selbst sucht.
-Im Projektmappenexplorer von Visual-Studio:
- Rechtsklick auf das Projekt im Projektexplorer
- Hinzufügen -> Verweis
- Haken bei System.Management hinzufügen (Framework)
--- Hauptprogramm ---
--- ConnectionManager ---Code:using System; using System.IO.Ports; using System.Linq; using System.Threading; namespace ConnectToArduino { class Program { static void Main(string[] args) { #region --- Start --- ConnectionManager manager = new ConnectionManager(); SerialPort arduinoPort; if (manager.SerialPorts.Count > 0) { arduinoPort = manager.SerialPorts.ElementAt(0).Value; Console.WriteLine("Arduino found: {0}\n", manager.SerialPorts.ElementAt(0).Key); } else { Console.WriteLine("No Arduino found!"); Console.WriteLine("<Press Key to exit program>"); Console.ReadKey(); return; } try { arduinoPort.Open(); } catch (Exception) { Console.WriteLine("Port already open!"); Console.WriteLine("<Press Key to exit program>"); Console.ReadKey(); return; } #endregion #region --- Send and Receive --- arduinoPort.Write("1"); Thread.Sleep(100); Console.WriteLine("Response from Arduino after sending \"1\": {0}", arduinoPort.ReadLine()); Thread.Sleep(1000); arduinoPort.Write("0"); Thread.Sleep(100); Console.WriteLine("Response from Arduino after sending \"0\": {0}", arduinoPort.ReadLine()); Console.WriteLine("<Press Key to exit program>"); Console.ReadKey(); #endregion #region --- End Program --- try { arduinoPort.Close(); } catch (Exception){ return; } #endregion } } }
Code:using System.Collections.Generic; using System.Diagnostics; using System.IO.Ports; using System.Linq; using System.Management; namespace ConnectToArduino { public sealed class ConnectionManager { public Dictionary<string, SerialPort> SerialPorts { get; private set; } public ConnectionManager() { FindArduinoDevices(); } private void FindArduinoDevices() { var dict = new Dictionary<string, SerialPort>(); try { foreach (ManagementObject device in new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_SerialPort").Get()) { if (!device["PNPDeviceID"].ToString().Contains("VID_2341")) continue; var port = new SerialPort(); var config = device.GetRelated("Win32_SerialPortConfiguration") .Cast<ManagementObject>().ToList().FirstOrDefault(); port.PortName = device["DeviceID"].ToString(); port.BaudRate = (config != null) ? int.Parse(config["BaudRate"].ToString()) : int.Parse(device["MaxBaudRate"].ToString()); dict.Add(device["Description"].ToString(), port); } SerialPorts = dict; } catch (ManagementException mex) { Debug.WriteLine(@"An error occurred while querying for WMI data: " + mex.Message); } } } }
Geändert von Sisor (28.09.2014 um 20:38 Uhr)
Hallo,
ist der Thread hier beendet? Ich kenn mich in den Foren noch nicht so gut aus. Ich hätte da vielleicht eine Antwort,
auf jeden Fall aber ein Problem mit dem Arduino und Perl.
Gruß Jürgen
Hallo,
der Thread und auch das Problem besteht noch.
Leider habe ich auch bis jetzt keine Zeit dafür gehabt.
Gruß.
Hallo,
ich hab einen Antennenrotor gebaut den ich via Arduino und Perl steuere.
Ich greife auf den Steuerrechner(Dachboden) via ssh von meinem Shack zu.
Das ganze funktioniert sehr gut bis auf ein kleines Problem das ich am Ende beschreibe.
Als erstes mein Lösungsanzatz, nicht relevater Code lasse ich weg und
ich habe versucht die einzelenen Aktionen in Funktionen zu packen.
Arduino
RS232 init:
RS232 einlesen:Code:void setup () { Serial.begin (9600); }
Mit der Methode wir ASCII eingelesen. In meinem Fall
3 Ziffern die dann in Zahlen gewandelt werden um dann eine
3-stellige Zahl zu werden. Beispiel: wenn 1 gesendet wird
kommt eine ASCII 49 die durch -48 zur 1 wird. Siehe ASCII-Tabelle
RS232 ausgeben:Code:/* Sollwinkel via serieller Schnittstelle Empfangen Sollwinkel muss 3-Stellig + LF uebertragen werden */ void Empfangen(){ int count = 0; // eingehende Byte zaehlen beschleunigung=true; // => 1x bei neuem Winkel Motor in der Regelschleife hochfahren schleichgang=false; boolean ok = true; while(ok){ if (Serial.available () > 0){ incomingByte = Serial.read (); data_in[count] = incomingByte; count++; if (incomingByte == 10){ // dez 10 = Zeilenende ok=false; } } } }
Perl via LinuxCode:/*Info an serielle Schnittstelle senden*/ void RS232OUT(){ Serial.println("Winkel liegt an. Done"); delay(10); }
Ich denke man kann den Code leicht in die Windows-Welt umsetzen.
RS232 init:
an Arudino senden:Code:use Device::SerialPort; # init globale Variablen my $port = Device::SerialPort->new("/dev/ttyACM0"); my $PeilungSoll=""; my $VonArduino="";
von Arduino empfangen:Code:sub senden{ my $Var=shift @_; $port->write($Var); # via RS232 senden return(1); }
Nun zu meinem Problem. Auf der Werkbank "hundert" mal geteste.Code:sub empfangen{ my $Input=""; my $OK=0; until($OK){ sleep(1); $Input = $port->lookfor(); # von RS232 lesen if ($Input) { $OK=1; $port->lookclear; # Buffer loeschen? } } return($Input); }
Jetzt hab ich die Steuerung auf dem Dachboden und bediene den Rotor
von einem anderen Raum. Die Rechner sind via Netzkabel verbunden.
Es kommt zu sporadischem hägenbleiben bei meinem Perlprogramm.
Nach einem Durchlauf soll der Arduino "ferig melden". Perl wartet
in einer Schleife auf diese Meldung. Ich denke der Arduino liefert nicht.
Ich sehe meinen Rotor ist in Position. Der Motor ist aus. Nun müsste via
RS232 die Meldung vom Arduino kommen und mein Perlprogramm wieder
in die Eingabe springen, tut es aber nicht immer.
Viel Text, aber man muss ja die Sachlage einigermaßen genau schlidern.
Hat jemand eine Rat?
Gruß
Geändert von California_EV (12.10.2014 um 22:30 Uhr)
Lesezeichen