Datentransfer via Ethernet und Auslesen über virtuellen seriellen Port

Hallo allerseits,

ich habe schon eine ganze Weile das Forum durchstöbert, aber nur stückchenweise Lösungen für meine Problemstellung gefunden. Diese sieht wie folgt aus:

Messdaten einer Sonde sollen über einen Arduino Mega, mit Ethernet Shield an den angeschlossenen PC übertragen und an einen virtuellen seriellen COM-Port übertragen werden. Dort soll die mitgelieferte Software der Sonde die Daten abgreifen und verarbeiten.

Was wäre euer empfohlenes Vorgehen für mich?

Vielen Dank im Voraus für eure Hilfe!

TheTris:
Was wäre euer empfohlenes Vorgehen für mich?

Da brauchen wir mehr Informationen.

Was ist das für eine Sonde. Poste bitte einen Link des Produktes.

Wozu brauchst du ein Ethernet-Shield ?

Wenn du die Daten an den PC senden willst, und nicht die USB-Schnittstelle verwendest, musst du den Seriellen Port vorher in eine RS232 wandeln, damit du mit dem PC über die serielle Schnittstelle kommunizieren kannst.

Hallo,

dann hole ich etwas weiter aus. Die Sonde die eingebettet werden soll ist eine CTD-Sonde, um im Wasser Kenntnis über Druck, Temperatur und Leitfähigkeit zu haben. Ich arbeite mit zwei weiteren an einem Remotely Operated Vehicle (ROV). Die Ethernet-Verbindung ist, neben der Stromversorgung das einzige Kabel, das zur Oberfläche geht. Eine USB-Verbindung hat sich zuvor bereits nicht bewährt.
Die Sonde übeträgt die Daten über eine RS-232 Schnittstelle.

Es gibt mehrere Produkte zu "serial over Ethernet". Inwieweit die aber Arduinotauglich sind, habe ich nicht geprüft.
Ansonsten würde ich es als UDP-Verbindung zum PC und dort zu seriell sehen.
Was für eine virtuelle serielle Schnittstelle am PC wollt ihr nutzen? Da gibt es ja auch mehrere.

Gruß Tommy

Das hatte ich auch mal vor, aber gar nichts darüber gefunden. Habe es dan über einen seriellen Device Server hardwäremässig gelöst. Z.b. Perle DS1. Gibt aber auch billigere. Teilweise gehen auch usb printserver, wo du den Arduino per usb direkt anstöpselst.

Ich danke euch für eure Antworten. Endschuldigt meine langen Pausen.
Ich habe zu Beginn versucht meine Problemstellung im Ganzen zu schildern, aber ich denke, dass ich mich erstmal von Hürde zu Hürde hangel.

Die Daten kommen über RS-232 zum Arduino. Wenn ich diese Daten seriell übertragen möchte brauche ich dann einen Pegelwandler, da der Arduino mit TTL arbeitet oder erkennt er auch ohne das HIGH/LOW?

Zur Übertragung wollte ich die TX/RX Pins des Arduino verwenden.
Muss ich diese Pins explizit definieren oder würde das beispielsweise auch über "Serial1.read()" funktionieren?

TheTris:
Die Daten kommen über RS-232 zum Arduino. Wenn ich diese Daten seriell übertragen möchte brauche ich dann einen Pegelwandler, da der Arduino mit TTL arbeitet oder erkennt er auch ohne das HIGH/LOW?

Wenn es eine echte RS232 ist, brauchst du einen RS232 zu TTL-Wandler. Z.B. diesen hier o.ä.
RS232 arbeitet mit +/- 12 Volt und kann direkt angeschlossen den Eingang killen.

Zur Übertragung wollte ich die TX/RX Pins des Arduino verwenden.
Muss ich diese Pins explizit definieren oder würde das beispielsweise auch über "Serial1.read()" funktionieren?

Ja, bei einem Mega kannst du die RX1 und TX1 verwenden.

Die Pins sind aber von der Hardware vorgegeben. Je nach Board aber an verschiedenen Pins.

Der Mega hat z.B. 4 serielle Schnittstellen, serial1 bis serial4.

Beim Uno u.a., die nur eine serielle haben, wird diese meist fürs programmieren genommen, und somit sollte nicht gleichzeitig was anderes dranhängen.

Eher Serial und Serial 1 bis Serial3.

Gruß Tommy

Hallo,

ich habe jetzt soweit alles vorbereitet und möchte nun letztendlich die Sensordaten per UDP an den PC senden. Ich probiere mich nun seit einer Weile daran, aber ich steige da irgendwie nicht durch und hoffe auf ein paar Denkanstöße, wie das zu verrichten ist.

Der Sensor liefert folgendes:
Baudrate: 1200
Datenbits: 8
Stopbits: 1
Parität: keine
Signals: GND, TxD

Wie definiere ich die Länge eines Paketes, damit die Datenbits im Ankommen?Oder muss ich das überhaupt tun?
Ich weiß momentan nicht wie ich anfangen soll :confused:

Danke!

Ich fasse mal zusammen, wie ich es bisher versanden habem damit wir nicht aneinander vorvei reden.

Du schließt den Sensor über einen Pegelwandler RS232->TTL an RX1 des MEGA an. OK?

Dann würde ich im Sketch erst mal alles, was Du an Serial1.read() bekommst mit Serial.print() zum PC schicken und dort auf dem seriellen Monitor anschauen.

Wenn da nur Blödsinn raus kommt, kann es sein, dass der Sensor binäre Daten sendet.
Dann gib sie mal mit Serial.print(x,HEX) aus.

Erst wenn das funktioniert, hat es Sinn, sich mit der Netzwerkübertragung zu beschäftigen.

Gruß Tommy

Hallo allerseits,

das mit der seriellen Übertragung hat soweit funktioniert und es macht natürlich Sinn im Kleinen zu starten, bevor man über Ethernet sendet.

Hier wäre der Code dazu. Ich bin gerne offen für Kritik,was man zum Beispiel eleganter machen könnte.

// CTD connected to pin 19
int CTD = 19;

void setup()
{

//set baud rate to 1200
Serial.begin(1200);
Serial1.begin(1200);

//wait for serial port to connect
while (!Serial) 
{ 
  ; 
}
pinMode(CTD, INPUT);
Serial.println("Connected to CTD");
Serial.println("Serielle Kommunikation Test 1.9");
}

void loop()
{
  
if (Serial1.available()) 
{
  
 //read incoming data
int incomingData = Serial1.read();
  Serial.print ("Data: ");
  Serial.println(incomingData, BIN);
}
else
{
  Serial.println("No data");
}
}

Ich möchte nun die Sensordaten via UDP senden, jedoch ist mein Sketch fehlerhaft, da “incomingData” anscheinend nicht deklariert wurde. Ich schaffe es bisher nicht, die Sensordaten in das UDP paket zu “packen”, habt ihr mir da einen Wink in die richtige Richtung?

Hier mein Code:

//Version 1.012

//necessary libraries
#include <SPI.h>
#include <Ethernet2.h>
#include <EthernetUdp2.h>

//Pin settings
#define CTD 19

//Network Settings
byte mac[] = { 0x90, 0xA2, 0xDA, 0x10, 0xEC, 0xAB };  //set MAC Address Ethernet Shield (Backside)
byte ip[]  = { XXX, XXX, X, X };                      //set IP-Address
byte gateway[] = { XXX, XXX, X, X };                  //set Gateway
byte subnet[]  = { 255, 255, 255, 1 };                //set Subnetmask


//local UDP port to listen on
unsigned int localPort = 4000;

//Recipient IP
IPAddress RecipientIP(127, 0, 0, 1);

//Recipient UDP port
unsigned int RecipientPort = 4444;

//Buffer for sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

//EthernetUDP instance
EthernetUDP Udp;



void setup() 
{
   //Start Ethernet
  Ethernet.begin(mac, ip);

  //Start UDP
  Udp.begin(localPort);
  
  //for debug only
  Serial.begin(9600);

  //Serial baud rate for CTD
  Serial1.begin(1200);

  //Version 1.012
Serial.print("Version 1.012");

  //CTD
  pinMode(CTD, INPUT);
}

void loop() 
{

//If CTD is sending
if (Serial1.available())
{
  //read incoming data
  int incomingData = Serial1.read();

  //for debug only
  Serial.print("Data: ");
  Serial.println(incomingData, BIN);
}

//Send UDP packets
int packetSize = Udp.parsePacket();
  if (packetSize) {
    
    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);

    // send to the IP address and port
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(incomingData);
    Udp.endPacket();
  }
}

Dein incomingData ist nur innerhalb des Blocks gültig, in dem es deklariert wurde. Mach mal eine globale Variable daraus.

Gruß Tommy

Das macht natürlich Sinn danke, da die Variable so nur für die Bedingung deklariert wird:)
Ich habe das geändert, jedoch sehe ich mit Wireshark noch immer keine Pakete ankommen. Die RecipientIP ist die in meinem Fall statisch eingestellte des PCs oder? Entschuldigt die vielen Fragen, ich bin wirklich ein Neuling…

Hier ist der veränderte Code:

/Version 1.05

//necessary libraries
#include <SPI.h>
#include <Ethernet2.h>
#include <EthernetUdp2.h>

//Pin settings
#define CTD 19

//Network Settings
byte mac[] = { 0x90, 0xA2, 0xDA, 0x10, 0xEC, 0xAB };  //set MAC Address Ethernet Shield (Backside)
byte ip[]  = { XXX, XXX, X, X };                      //set IP-Address
byte gateway[] = { XXX, XXX, X, X };                  //set Gateway
byte subnet[]  = { 255, 255, 255, 0 };                //set Subnetmask


//local UDP port to listen on
unsigned int localPort = 5568;

//Recipient IP
IPAddress RecipientIP(XXX, XXX, X, X);

//Recipient UDP port
unsigned int RecipientPort = 8888;

//Buffer for sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

//EthernetUDP instance
EthernetUDP Udp;

//CTD data
int incomingData = 0;


void setup()
{
   //Start Ethernet
  Ethernet.begin(mac, ip);

  //Start UDP
  Udp.begin(localPort);

  //for debug only
  Serial.begin(9600);

  //Serial baud rate for CTD
  Serial1.begin(1200);

  //Version 1.012
Serial.print("Version 1.05");

  //CTD
  pinMode(CTD, INPUT);
}

void loop()
{

//If CTD is sending
if (Serial1.available())
{
  //read incoming data
  incomingData = Serial1.read();

  //for debug only
  Serial.print("Data: ");
  Serial.println(incomingData, BIN);
}

//Send UDP packets
int packetSize = Udp.parsePacket();
  if (packetSize) {

    //Debug only
    Serial.print("Packet");
    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);

    // send to the IP address and port
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(incomingData);
    Udp.endPacket();
  }
}

Du willst nur senden, wenn Du ein UDP-Paket empfangen hast? Warum das?

Gruß Tommy