Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   
Forentreff 2012     
Bücher-Shop mit Amazon (Buchkategorien)C++ : Referenzen zu C++ : C++ Builder : Visual C++ : C# : Java : Spieleprogrammierung : Systemprogrammierung Linux : Software-Entwicklung : .NET : Compilertechnik : Algorithmen & Datenstrukturen : Objektorientierung : Entwurfsmuster : UML : eXtreme Programming : Scrum : Projektmanagement : Software-Testing : Datenbanken : Tom DeMarco : Dilbert : User Friendly
C/C++ Forum :: VCL (C++ Builder) ::  TCP Socket     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 14:40:18 10.03.2010   Titel:   TCP Socket            Zitieren

ich habe ein Messgerät mit einem Ethernet-Anschluss. Um das Gerät zu steuern und die Messwerte auszulesen kann dieser verwendet werden. IP und Port hab ich, die stehen im Handbuch. Leider habe ich damit bisher nichts zutun gehabt. Ich nehme an, dass ich eine TServerSocket-Komponente verwenden muss. Oder die TClientSocket? Dort kann man wie ich gesehen hab, den Port festlegen. Wie geb ich die IP bekannt?
Nun müssen an das Gerät 32 Bytes Daten gesendet werden. Daruf hin werden 128 Bytes zurückgesendet. So steht es im Handbuch. Die Messwerte stehen ab Adresse 16 bzw 48. Dazu gibt es auch eine Tabelle mit der relativen Addresse und der Messgröße. Wie sende und empfange ich die Daten? Wie ich gesehen hab gibt es bei TServerSocket auch eine Read- und Write Methode.

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
Th69
Mitglied

Benutzerprofil
Anmeldungsdatum: 25.03.2008
Beiträge: 2256
Beitrag Th69 Mitglied 17:36:29 10.03.2010   Titel:              Zitieren

Verwende eine TClientSocket-Komponente und benutze die Eigenschaften 'Address' (oder alternativ 'Host') sowie 'Port'.

Und über die Methoden der Eigenschaft 'Socket' kannst du dann Daten lesen (ReceiveBuf) und schreiben (SendBuf).
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 11:34:01 11.03.2010   Titel:              Zitieren

ja ok, das ist klar. Die Frage ist nun was ich senden muss. Folgendes steht im Handbuch:
Schreiben Sie 32 Bytes zu dem Gerät. Falls sie nichts steuern, müssen alle Bytes den Wert 0 enthalten. Falls Sie beispielsweise Messungen auslösen wollen, müssen Sie einen Wert(in der Regel 80), in Byte 14 und 15 (Zählung beginnt bei 0) schreiben und das entsprechende Bit (laut Tabelle) für die Messstelle von 0 auf 1 ändern.
Lesen Sie 128 bytes vom Gerät. Werten Sie Byte 12 und 13 (Lebenszähler) aus. Wenn sich dieser während 5 Minuten nicht ändert, geben Sie einen Alarm aus. Dieser Zähler erhöht sich alle paar Sekunden und kann auch benutzt werden um die Busanbindung zu testen.
Werten SIe Byte 5 (Fehlerbits) aus. Bei unbestätigtem Fehler (Bit5.2) ist gesetzt) den Betreiber alarmieren.
Lesen Sie die Messwerte ab Adresse 16. Diese Werte sind als vorzeichenbehaftete 16-Bit-Integer gespeichert und müssen gegebenfalls durch einen Faktor dividiert werden. (da gibts eine Tabelle mit Nr. (1-30), relative Adresse (byte), Messstelle und Einheit.

Nun möchte ich erst mal eine Einzelmessung auslösen.Dazu muss ich von den 32 Bits bestimmte Bits setzen. Wie mach ich das? Ich nehm an mit dem Befehl SendBuf();

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
witte
Mitglied

Benutzerprofil
Anmeldungsdatum: 08.01.2008
Beiträge: 1295
Beitrag witte Mitglied 12:45:44 11.03.2010   Titel:              Zitieren

BTW: Ich würde dir empfehlen das Senden als auch Empfangen in jeweils einer Klasse zu implementieren. Der Sender hat als Member das zu sendende 32-byte-Array, welches im Konstruktor auf 0 gesetzt wird ("Falls sie nichts steuern, müssen alle Bytes den Wert 0 enthalten."). Dann würde ich alle Operationen kapseln: MessungenAuslösen() bekommt einen enum für den Messtyp, die Funktion setzt dann 14b und 15b und versendet dann das Array. Dazu die Methode Send welches dann das Array über den Socket verschickt. Alternativ könnte man sich auch eine Fabrik vorstellen welche je nach Anfragetyp ein vorkonfiguriertes 32b-Array erstellt. Die Empfängerklasse dito mit TestHeartbeat(), LeseMesswert() ...
witte
Mitglied

Benutzerprofil
Anmeldungsdatum: 08.01.2008
Beiträge: 1295
Beitrag witte Mitglied 12:50:29 11.03.2010   Titel:              Zitieren

rudpower schrieb:
Nun möchte ich erst mal eine Einzelmessung auslösen.Dazu muss ich von den 32 Bits bestimmte Bits setzen. Wie mach ich das? Ich nehm an mit dem Befehl SendBuf();
SendBuf() wird nur die Daten übertragen und nicht die bits setzten. Du baust dir ein 32byte-Array, setzt dort die entsprechenden bits und verschickst es zum Messgerät und liest im return 128 byte vom Messgerät. Zum Setzen der bits kannst du die bitweisen Logikoperatoren verwenden & | usw oder einzelne Bytes direkt setzen.

Edit: und beachte die Endianness des Messgerätes wenn du shorts etc. schreiben willst (byte 14 + 15 für den Messtyp)


Zuletzt bearbeitet von witte am 12:52:33 11.03.2010, insgesamt 1-mal bearbeitet
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 14:12:41 11.03.2010   Titel:              Zitieren

wie bau ich den das 32Byte array auf? und welchen Typ nehm ich da? ich nehm mal an das ich ein char array nehm also
C/C++ Code:
char send[32]={};
C/C++ Code:
char send[32]={};
C/C++ Code:
char send[32]={};

wie setze ich jetzt die einzelnen Bits?
Was genau gibt die Funktion zurück? Hab gesehen das es ein integer-wert ist. Was ist mit Endianness gemeint?

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.


Zuletzt bearbeitet von rudpower am 09:45:04 12.03.2010, insgesamt 1-mal bearbeitet
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 10:03:56 12.03.2010   Titel:              Zitieren

kann man das vll. so machen?

C/C++ Code:
char send[32]={0};
send[14] = 0x50; //den int-Wert 80 in das 15.Byte schreiben
send[15] = 0x50; //den int-Wert 80 in das 16.Byte schreiben
C/C++ Code:
char send[32]={0};
send[14] = 0x50; //den int-Wert 80 in das 15.Byte schreiben
send[15] = 0x50; //den int-Wert 80 in das 16.Byte schreiben
C/C++ Code:
char send[32]={0};
send[14] = 0x50; //den int-Wert 80 in das 15.Byte schreiben
send[15] = 0x50; //den int-Wert 80 in das 16.Byte schreiben


bin jetzt grad dabei die Klasse zu erstellen. Kann ich nicht eine Klasse für das Messgerät schreiben und die Sendemethoden und Empfangsmethoden in diese Klasse schreiben?
Zitat:

welches im Konstruktor auf 0 gesetzt wird
wie initialisier ich eigentlich ein Array in der Konstruktorliste?
C/C++ Code:
meineKlasse::meineKlasse() : send[32](0) {} //so gehts ja nicht
C/C++ Code:
meineKlasse::meineKlasse() : send[32](0) {} //so gehts ja nicht
C/C++ Code:
meineKlasse::meineKlasse() : send[32](0) {} //so gehts ja nicht

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.


Zuletzt bearbeitet von rudpower am 12:09:38 12.03.2010, insgesamt 3-mal bearbeitet
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 13:06:46 12.03.2010   Titel:              Zitieren

habs mal versucht mit der Klasse:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Awi
{
private:
   unsigned char send[SENDBYTES];
   unsigned char rec[RECBYTES];
   TClientSocket* ClientSocket;
   const enum Messkanal {alle=0x0,K1=0x1,K2=0x2,K3=0x4,K4=0x8,K5=0x10,K12=0x3,
       K13=0x5,K14=0x6,K123=0x7,K23=0x9,K24=0xA,K124=0xB,K34=0xC,K134=0xD,K234=0xE,
      K1234=0xF}; // K14 steht zB für Kanal 1 und 4
public:
    Awi();
    ~Awi();
    MessungAusloesen(enum Messkanal);
};

Awi::Awi()
{
    memset(send,0,SENDBYTES); // Initialisierung des Arrays mit 0-Bits
}

Awi::~Awi()
{
    //TODO: Hier Ihren Quelltext einfügen
}

Awi::MessungAusloesen(enum Messkanal)
{
    send[14] = 0x50;
   send[15] = 0x50;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Awi
{
private:
unsigned char send[SENDBYTES];
unsigned char rec[RECBYTES];
TClientSocket* ClientSocket;
const enum Messkanal {alle=0x0,K1=0x1,K2=0x2,K3=0x4,K4=0x8,K5=0x10,K12=0x3,
K13=0x5,K14=0x6,K123=0x7,K23=0x9,K24=0xA,K124=0xB,K34=0xC,K134=0xD,K234=0xE,
K1234=0xF}; // K14 steht zB für Kanal 1 und 4
public:
Awi();
~Awi();
MessungAusloesen(enum Messkanal);
};

Awi::Awi()
{
memset(send,0,SENDBYTES); // Initialisierung des Arrays mit 0-Bits
}

Awi::~Awi()
{
//TODO: Hier Ihren Quelltext einfügen
}

Awi::MessungAusloesen(enum Messkanal)
{
send[14] = 0x50;
send[15] = 0x50;
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Awi
{
private:
   unsigned char send[SENDBYTES];
   unsigned char rec[RECBYTES];
   TClientSocket* ClientSocket;
   const enum Messkanal {alle=0x0,K1=0x1,K2=0x2,K3=0x4,K4=0x8,K5=0x10,K12=0x3,
       K13=0x5,K14=0x6,K123=0x7,K23=0x9,K24=0xA,K124=0xB,K34=0xC,K134=0xD,K234=0xE,
      K1234=0xF}; // K14 steht zB für Kanal 1 und 4
public:
    Awi();
    ~Awi();
    MessungAusloesen(enum Messkanal);
};

Awi::Awi()
{
    memset(send,0,SENDBYTES); // Initialisierung des Arrays mit 0-Bits
}

Awi::~Awi()
{
    //TODO: Hier Ihren Quelltext einfügen
}

Awi::MessungAusloesen(enum Messkanal)
{
    send[14] = 0x50;
   send[15] = 0x50;
}


Kann man das so machen?
Wollte im Konstruktor in der Initialisierungsliste eigentlich das TClientSocket Objekt erzeugen, aber er kannte den Typ nicht.
C/C++ Code:
Awi::Awi() : ClientSocket(new TClientSocket) // das funktioniert nicht
{
    memset(send,0,SENDBYTES); // Initialisierung des Arrays mit 0-Bits
}
C/C++ Code:
Awi::Awi() : ClientSocket(new TClientSocket) // das funktioniert nicht
{
memset(send,0,SENDBYTES); // Initialisierung des Arrays mit 0-Bits
}
C/C++ Code:
Awi::Awi() : ClientSocket(new TClientSocket) // das funktioniert nicht
{
    memset(send,0,SENDBYTES); // Initialisierung des Arrays mit 0-Bits
}


Fehlermeldung: [C++ Fehler] Unit2.cpp(13): E2285 Keine Übereinstimmung für 'TClientSocket::TClientSocket()' gefunden

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
akari
Moderator

Benutzerprofil
Anmeldungsdatum: 27.11.2004
Beiträge: 11271
Beitrag akari Moderator 13:54:21 12.03.2010   Titel:              Zitieren

Hallo

Die Fehlermeldung sagt aus, das es keinen parameterlosen Konstruktor von TClientSocket gibt. Schau in der Builder-Hilfe nach, welcher Parameter noch benötigt wird, und was du daraus schließen kannst.

bis bald
akari

_________________
In der nächsten Version wird alles besser!
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 14:13:09 12.03.2010   Titel:              Zitieren

owner wird als Parameter erwartet. Da das ja eine Klasse ist weiss ich gar nicht was ich da eintrage. Bei einer Formularanwendung ist ja immer die Form selbst der Eigentümer. Wie ist es hier wo ich keine Form hab sondern eine Klasse schreibe?

Das mit dem enum funktioniert bei mir so auch nicht.
C/C++ Code:
Awi::MessungAusloesen(enum Messkanal)
{
    send[14] = 0x50;
    send[15] = 0x50;
    send [19] = Messkanal; // das funktioniert so nicht
}
C/C++ Code:
Awi::MessungAusloesen(enum Messkanal)
{
send[14] = 0x50;
send[15] = 0x50;
send [19] = Messkanal; // das funktioniert so nicht
}
C/C++ Code:
Awi::MessungAusloesen(enum Messkanal)
{
    send[14] = 0x50;
    send[15] = 0x50;
    send [19] = Messkanal; // das funktioniert so nicht
}

Beim Aufruf der Methode soll als Parameter zB "alle" eingegeben werden und er weist automatisch send[19] den Ausdruck 0x5 zu.

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.


Zuletzt bearbeitet von rudpower am 14:18:42 12.03.2010, insgesamt 1-mal bearbeitet
akari
Moderator

Benutzerprofil
Anmeldungsdatum: 27.11.2004
Beiträge: 11271
Beitrag akari Moderator 14:26:34 12.03.2010   Titel:              Zitieren

Hallo

rudpower schrieb:
owner wird als Parameter erwartet. Da das ja eine Klasse ist weiss ich gar nicht was ich da eintrage. Bei einer Formularanwendung ist ja immer die Form selbst der Eigentümer. Wie ist es hier wo ich keine Form hab sondern eine Klasse schreibe?

Du kannst statt einem konkreten Owner-Objekt auch NULL übergeben, dann wird das erstellte Objekt nicht automatisch gelöscht. Sondern du must selber die TClientSocket-Instanz löschen, nachdem du sie nicht mehr brauchst. Spätestens der Destruktor von Awi sollte das also machen.

Zitat:

Das mit dem enum funktioniert bei mir so auch nicht.
C/C++ Code:
Awi::MessungAusloesen(enum Messkanal)
{
    send[14] = 0x50;
    send[15] = 0x50;
    send [19] = Messkanal; // das funktioniert so nicht
}
C/C++ Code:
Awi::MessungAusloesen(enum Messkanal)
{
send[14] = 0x50;
send[15] = 0x50;
send [19] = Messkanal; // das funktioniert so nicht
}
C/C++ Code:
Awi::MessungAusloesen(enum Messkanal)
{
    send[14] = 0x50;
    send[15] = 0x50;
    send [19] = Messkanal; // das funktioniert so nicht
}

Beim Aufruf der Methode soll als Parameter zB "alle" eingegeben werden und er weist automatisch send[19] den Ausdruck 0x5 zu.

Die Deklaration des Parameters im Konstruktor ist nicht ganz richtig :
C/C++ Code:
Awi::MessungAusloesen(Messkanal mk)
{
    send[14] = 0x50;
    send[15] = 0x50;
    send [19] = mk;
}
C/C++ Code:
Awi::MessungAusloesen(Messkanal mk)
{
send[14] = 0x50;
send[15] = 0x50;
send [19] = mk;
}
C/C++ Code:
Awi::MessungAusloesen(Messkanal mk)
{
    send[14] = 0x50;
    send[15] = 0x50;
    send [19] = mk;
}

Ansonsten : "Funktioniert nicht" ist keine ausreichende Fehlerbeschreibung

bis bald
akari

_________________
In der nächsten Version wird alles besser!


Zuletzt bearbeitet von akari am 14:27:12 12.03.2010, insgesamt 1-mal bearbeitet
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 09:48:12 15.03.2010   Titel:              Zitieren

ok beim Aufruf der Methode MessungAuslosen muss ich nun den enum Parameter angeben. Nun will ich zum Beispiel alle als Parameter eintragen, damit der charWert 0x0 genommen wird. Das man o_Awi->MessungAusloesen(alle); nicht schreiben kann war mir klar. Wie trag ich jetzt das enum dort ein?

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
witte
Mitglied

Benutzerprofil
Anmeldungsdatum: 08.01.2008
Beiträge: 1295
Beitrag witte Mitglied 11:15:41 15.03.2010   Titel:              Zitieren

Versuche mal Awi::alle.

* Awi::Messkanal sollte dann public sein.
* Du kannst enums auch zusammensetzen. Du musst nicht für jede Combo ein Eintrag erzeugen:

C/C++ Code:
    Awi a;
    a.MessungAusloesen(Awi::K1 | Awi::K2);
C/C++ Code:
Awi a;
a.MessungAusloesen(Awi::K1 | Awi::K2);
C/C++ Code:
    Awi a;
    a.MessungAusloesen(Awi::K1 | Awi::K2);


Zuletzt bearbeitet von witte am 11:23:45 15.03.2010, insgesamt 1-mal bearbeitet
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 11:25:40 15.03.2010   Titel:              Zitieren

dann kommt die Meldung: "Zugriff auf 'Awi::alle' nicht möglich". Macht denn so ein enum hier überhaupt Sinn?

Edit: grad zu spät gelesen. Ich versuch das mal... danke für die Hilfe

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.


Zuletzt bearbeitet von rudpower am 11:26:56 15.03.2010, insgesamt 1-mal bearbeitet
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 14:31:33 15.03.2010   Titel:              Zitieren

kompilieren lässt sich der Code jetzt fehlerfrei. Nur das Gerät macht nichts wenn ich die Messung starte. In dem Anwendungsbeispiel vom handbuch steht ja das ich in Byte 14 und 15 den Integer-Wert 80 schreiben soll. Warscheinlich muss ich da wohl doch ein int-Array nehmen. Vielleicht will er aber auch den binären Code. Hab ich auch schon probiert aber das Gerät macht nichts. IP und Port sind richtig, da ich das Gerät unter dieser Ip auch Problemlos anpingen kann. Ändere ich den Port gibts auch einen Socket Error. Also wird das richtig sein.

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
witte
Mitglied

Benutzerprofil
Anmeldungsdatum: 08.01.2008
Beiträge: 1295
Beitrag witte Mitglied 15:21:59 15.03.2010   Titel:              Zitieren

Tja, da wird dir wohl keiner helfen können da wir die Doku und das Gerät nicht kennen. Ich würde mit dem Debugger prüfen ob die Daten vor dem Verschicken korrekt gesetzt sind. Du solltest auch erst mal einfachste Operationen ausführen und die Fehlerquellen einzugrenzen (was passiert beispielsweise wenn nur leere bytes gesendet wurden? Antwortet das Gerät?).
Zitat:
steht ja das ich in Byte 14 und 15 den Integer-Wert 80 schreiben soll
Klar, probier doch mal nur in einem Byte den Wert zu schreiben.
Viel Erfolg.
akari
Moderator

Benutzerprofil
Anmeldungsdatum: 27.11.2004
Beiträge: 11271
Beitrag akari Moderator 15:28:33 15.03.2010   Titel:              Zitieren

Hallo

Für den Fall, das du nicht weißt wie du einzelne Bytes/Bits setzten kannst : Hier ist eine Übersicht zum Thema Bitoperatoren.

bis bald
akari

_________________
In der nächsten Version wird alles besser!
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 00:14:07 16.03.2010   Titel:              Zitieren

ja das bekomm ich noch hin :)
Nein das Gerät antwortet leider auch nicht wenn ich nur Null Bytes sende. Werd mich morgen mal mit dem Hersteller in Verbindung setzen. Habs mal mit der TClientSocket Komponente versucht und bei Service "ftp" eingegeben. Dann bekomm ich plötzlich Werte in den einzelnen Bytes. Da dies immer die gleichen sind, denk ich mal das es die falschen sind. Was hat es mit der Service Eigenschaft auf sich?

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.


Zuletzt bearbeitet von rudpower am 09:03:15 16.03.2010, insgesamt 1-mal bearbeitet
DocShoe
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.04.2008
Beiträge: 1608
Beitrag DocShoe Mitglied 10:34:50 16.03.2010   Titel:              Zitieren

Installier´ mal nen Netzwerk Sniffer (Wireshark, Microsoft Net Mon, etc) und guck dir an, was über die Leitung geht. Vielleicht gibt´s sogar ein Tool des Messgerätherstellers, das einige Demofunktionen des Messgeräts abruft, dann kannst du dir die Pakete genau angucken.
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 13:05:01 16.03.2010   Titel:              Zitieren

habs mir mal mit dem Debugger angeschaut und mal einfach flg. gesendet:

Button Ereignis:
C/C++ Code:
ClientSocket->Active=true;
char send[32]={0};
char rec[0]={0};
ClientSocket->Socket->SendBuf(send,32);
ClientSocket->Socket->ReceiveBuf(rec,128);
C/C++ Code:
ClientSocket->Active=true;
char send[32]={0};
char rec[0]={0};
ClientSocket->Socket->SendBuf(send,32);
ClientSocket->Socket->ReceiveBuf(rec,128);
C/C++ Code:
ClientSocket->Active=true;
char send[32]={0};
char rec[0]={0};
ClientSocket->Socket->SendBuf(send,32);
ClientSocket->Socket->ReceiveBuf(rec,128);


Schau ich mir das Array mit dem Debugger an, steht da was drin. Hab noch was erkannt, dass die Messwerte immer 2Byte Wörter sind (vorzeichenbehaftet). Diese solen ab Adresse 16 bzw 48 stehen. So sieht die Tabelle aus:
Nr.: relative Adresse (byte): Messgröße: Messstelle: Einheit:
1 16 Kohlendioxid 1 %
2 18 Sauerstoff 1 1/100%
...
man sieht bei der Adresse schon das es immer 2 Byte sind.
Nun muss ich das noch umwandeln.

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 15:02:53 16.03.2010   Titel:              Zitieren

wie initialisiere ich das Array am besten mit 0-Bytes? Ist das mit memset ok? Normal kenn ich ja char send[32]={0};
Ich hab aber send in der Klasse im Header deklariert. Wie initialisier ich nun das Array im Konstruktor? send[32]={0}; geht jeden Falls nicht. Mit einer for-Schleife geht ja auch aber vll geht ja auch einfacher.

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.


Zuletzt bearbeitet von rudpower am 15:04:08 16.03.2010, insgesamt 1-mal bearbeitet
akari
Moderator

Benutzerprofil
Anmeldungsdatum: 27.11.2004
Beiträge: 11271
Beitrag akari Moderator 15:11:30 16.03.2010   Titel:              Zitieren

Hallo

Da dürfte memset das kürzeste sein, und auch schneller als eine Schleife. Da char ja ein POD ist, brauchst du dir um nichtaufgerufene Konstruktoren von char keine Sorgen machen.

bis bald
akari

_________________
In der nächsten Version wird alles besser!
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 15:15:40 16.03.2010   Titel:              Zitieren

blöd gefragt: was ist ein POD?

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
akari
Moderator

Benutzerprofil
Anmeldungsdatum: 27.11.2004
Beiträge: 11271
Beitrag akari Moderator 15:20:54 16.03.2010   Titel:              Zitieren

Hallo

Plain Old Datatype : Ein Datentyp der genauso wie in C behandelt wird : also z.B. int, bool, float, C-Arrays, aber auch struct, wenn es keine Methoden und nur Datenelemente besitzt, die selber PODs sind. Vorteil : Diese Datentypen brauchen keine Konstruktoren und können z.B. mit memset auf 0 gesetzt werden, auch in Form eines Arrays. Bei einem std::vector<std::string> dürfte man das nicht machen.

bis bald
akari

_________________
In der nächsten Version wird alles besser!
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 16:41:28 16.03.2010   Titel:              Zitieren

ah ok alles klar. Ich hab immer elementare Datentypen dazu gesagt.

Hab ein paar Probleme mit dem Auslesen der Messwerte. Mit dem Debugger kann ich die Daten bereits mit der Ausdrucksüberwachung sehen. Nun will ich sie noch ausgeben können als AnsiString zB in ein Editfeld oder Memo. Ich zeig einfach mal meine Klasse:

C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class c_Awi{
   private:
      unsigned char send[32];
      unsigned char rec[128];
      TClientSocket* socket;
   public:
    c_Awi(AnsiString IP, int Port);
    ~c_Awi();
    char* ReceiveData(int Adresse);
};
c_Awi::c_Awi(AnsiString IP, int Port):socket(new TClientSocket(NULL)) {
   memset(send,0,32);
   memset(rec,0,128);
   socket->Host = IP;
   socket->Port = Port;
    socket->Active = true;
}
//---------------------------------------------------------------------------
c_Awi::~c_Awi() {delete socket;}
//---------------------------------------------------------------------------
//in dieser Methode wollt ich eigentlich das Feld angeben, das dann ausgegeben werden soll. Ich denke das muss ich anders machen:

char* c_Awi::ReceiveData(int Adresse) {
    socket->Socket->SendBuf(send,32);
   socket->Socket->ReceiveBuf(rec,128);
   return &rec[Adresse];
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class c_Awi{
private:
unsigned char send[32];
unsigned char rec[128];
TClientSocket* socket;
public:
c_Awi(AnsiString IP, int Port);
~c_Awi();
char* ReceiveData(int Adresse);
};
c_Awi::c_Awi(AnsiString IP, int Port):socket(new TClientSocket(NULL)) {
memset(send,0,32);
memset(rec,0,128);
socket->Host = IP;
socket->Port = Port;
socket->Active = true;
}
//---------------------------------------------------------------------------
c_Awi::~c_Awi() {delete socket;}
//---------------------------------------------------------------------------
//in dieser Methode wollt ich eigentlich das Feld angeben, das dann ausgegeben werden soll. Ich denke das muss ich anders machen:

char* c_Awi::ReceiveData(int Adresse) {
socket->Socket->SendBuf(send,32);
socket->Socket->ReceiveBuf(rec,128);
return &rec[Adresse];
}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class c_Awi{
   private:
      unsigned char send[32];
      unsigned char rec[128];
      TClientSocket* socket;
   public:
    c_Awi(AnsiString IP, int Port);
    ~c_Awi();
    char* ReceiveData(int Adresse);
};
c_Awi::c_Awi(AnsiString IP, int Port):socket(new TClientSocket(NULL)) {
   memset(send,0,32);
   memset(rec,0,128);
   socket->Host = IP;
   socket->Port = Port;
    socket->Active = true;
}
//---------------------------------------------------------------------------
c_Awi::~c_Awi() {delete socket;}
//---------------------------------------------------------------------------
//in dieser Methode wollt ich eigentlich das Feld angeben, das dann ausgegeben werden soll. Ich denke das muss ich anders machen:

char* c_Awi::ReceiveData(int Adresse) {
    socket->Socket->SendBuf(send,32);
   socket->Socket->ReceiveBuf(rec,128);
   return &rec[Adresse];
}


und hier meine Formklasse:
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class TForm1 : public TForm {
__published:
    TMemo *Memo;
private:   
    c_Awi* o_Awi; //hier meine Deklaration
public:   
    __fastcall TForm1(TComponent* Owner);
    __fastcall ~TForm1();
};
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner), o_Awi(new c_Awi("192.168.0.37",2080)) {} //hier erzeug ich mein Objekt in der Konstruktorliste
//---------------------------------------------------------------------------

__fastcall TForm1::~TForm1() {delete o_Awi;}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class TForm1 : public TForm {
__published:
TMemo *Memo;
private:
c_Awi* o_Awi; //hier meine Deklaration
public:
__fastcall TForm1(TComponent* Owner);
__fastcall ~TForm1();
};
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner), o_Awi(new c_Awi("192.168.0.37",2080)) {} //hier erzeug ich mein Objekt in der Konstruktorliste
//---------------------------------------------------------------------------

__fastcall TForm1::~TForm1() {delete o_Awi;}
C/C++ Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class TForm1 : public TForm {
__published:
    TMemo *Memo;
private:   
    c_Awi* o_Awi; //hier meine Deklaration
public:   
    __fastcall TForm1(TComponent* Owner);
    __fastcall ~TForm1();
};
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner), o_Awi(new c_Awi("192.168.0.37",2080)) {} //hier erzeug ich mein Objekt in der Konstruktorliste
//---------------------------------------------------------------------------

__fastcall TForm1::~TForm1() {delete o_Awi;}


Da ja ein Messwert immer aus 2 Byte (also 2 Feldelementen besteht) muss ich diese dann noch irgendwie kombinieren. Aber erst mal wollt ich die einzelnen Felder auslesen können

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
witte
Mitglied

Benutzerprofil
Anmeldungsdatum: 08.01.2008
Beiträge: 1295
Beitrag witte Mitglied 17:40:21 16.03.2010   Titel:              Zitieren

* Du kannst mal BinToHex() anschauen um die Dtaen roh auszugeben.
* Du kannst zwei Bytes die zusammen einen Wert bilden beispielsweise so zusammensetzen:
C/C++ Code:
 int value = (rec[14] << 8) + rec[15];
C/C++ Code:
int value = (rec[14] << 8) + rec[15];
C/C++ Code:
 int value = (rec[14] << 8) + rec[15];

Allerdings musst du die Endianness klären, also welches Byte höherwertig ist.
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 09:49:06 17.03.2010   Titel:              Zitieren

ist mein code oben soweit erst mal ok?

Laut Handbuch gilt das Big Endian Format. Das höherwertige Bit steht an niederen Adresse. In Feld 50 steht zB 0x80 und in Feld 51 steht 0x08. Wie komm ich nun an den Messwert 21.8? (Der steht auf der Anzeige des Geräts, daher kenn ich den)

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 11:02:39 17.03.2010   Titel:              Zitieren

habe erfahren das ich so auf den Wert komme:
8*256+80 also (rec[50]*256 + rec[51])/100 oder ((rec[50]<<8)+rec[51])/100
warum 256? Wie sieht das Beispiel bitweise aus, also was passiert hier in Binärschreibweise? Hab leider keine Erfahrungen mit dem BigEndianFormat.

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 12:26:25 17.03.2010   Titel:   Receive Buf -> Socket Verbindung scheint sich zu trennen            Zitieren

Kann jetzt auf die Werte zugreifen. Habe noch das Problem, dass wenn ich die Methode ReceiveBuf aufrufe sich die Socket-Verbindung danach wieder trennt. Somit kann ich die Werte nicht aktualisieren. Hab eine Variable erstellt um die Active-Eigenschaft des Sockets zu prüfen. Immer wenn ich Messdaten empfange ist die Verbindung wieder getrennt. Ist das normal? Ich öffne die Verbindung im Konstruktor der Klasse wo ich mein TClientSocket Objekt erzeuge mit: meinSocketObjekt->Active=true; Dann sollte die Verbindung eigentlich offen bleiben bis ich das Objekt wieder delete. Das mach ich erst im Destruktor.

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.


Zuletzt bearbeitet von rudpower am 12:11:16 18.03.2010, insgesamt 2-mal bearbeitet
rudpower
Mitglied

Benutzerprofil
Anmeldungsdatum: 04.11.2009
Beiträge: 525
Beitrag rudpower Mitglied 15:58:22 18.03.2010   Titel:   SendBuf/SendReceive            Zitieren

kan es vielleicht sein, dass das Gerät die Verbindung nach SendBuf oder SendReceive automatisch trennt? Gibt es vielleicht eine Alternative zu SendBuf/SendReceive?

_________________
Computer dienen uns zur Lösung von Problemen, die wir ohne sie nicht hätten.
akari
Moderator

Benutzerprofil
Anmeldungsdatum: 27.11.2004
Beiträge: 11271
Beitrag akari Moderator 16:09:49 18.03.2010   Titel:              Zitieren

Hallo

Wenn das Gerät wirklich selber die Verbindung trennt, dann liegt es nicht am TSocket. Dann must du nach jeder Trennung eben die Verbindung neu öffen (Active = true) oder eine neue Socket-Instanz erstellen.

bis bald
akari

_________________
In der nächsten Version wird alles besser!


Zuletzt bearbeitet von akari am 16:10:15 18.03.2010, insgesamt 1-mal bearbeitet
C/C++ Forum :: VCL (C++ Builder) ::  TCP Socket   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info, www.c-sar.de, www.c-plusplus.net und www.baeckmann.de enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.