www.mikrocontroller.net

Forum: PC-Programmierung C win32 api Daten Übertragung


Autor: Skaos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo leute,
ich habe folgendes Problem, ich habe ein Messgerät, das die Sicherheit 
von elektrischen Geräten prüft. Ich möchte mit einem C-Programm die 
Ergebnisse an den Pc übertragen. Ich habe dieses Programm geschrieben. 
Ich kann leider die Ergebnisse nicht richtig ausgeben, es kommen einfach 
sinnlosen Zahlen. Wenn ich die Ergebnisse durch den  Hyper-Terminal 
ausgebe, sind diese ganz normal, da ist sogar Text dabei nicht nur 
Zahlen.

#include <stdio.h>

#include <stdlib.h>

#include <windows.h>

#include <conio.h>

int main(void) {



  DCB dcb;

  HANDLE hPort;



  COMMTIMEOUTS cto;

  DWORD dw;

  unsigned char buf[0x100];





  dcb.DCBlength=sizeof(DCB);

  dcb.BaudRate=CBR_9600;

  dcb.ByteSize=8;

  dcb.Parity=NOPARITY;

  dcb.StopBits=ONESTOPBIT;

  cto.ReadIntervalTimeout=50;

    cto.ReadTotalTimeoutConstant=50;

  cto.WriteTotalTimeoutMultiplier=10;

  cto.WriteTotalTimeoutConstant=40;



  hPort=CreateFile( "COM1",GENERIC_READ | GENERIC_WRITE,0, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);



  if (hPort==INVALID_HANDLE_VALUE)

        {

            printf("CreateFile\n"); return 1;

            //printf("Create\n");

        }

      

    while(1)

    {

    if(!ReadFile(hPort, buf, 1, &dw,NULL))

        {

            //error occurred. Report to user.

            //sBuffer[0] = buff;

            //printf("%d\n",sBuffer);

        }

    printf("%d\n",buf[0]);

    }



CloseHandle(hPort);

return 0;

}
 


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>    printf("%d\n",buf[0]);
   printf("%c",buf[0]);

Dein Messgerät schickt dir Text.
Du betrachtest gerade die ASCII Codes dieses Textes. Als Dezimalzahlen 
ausgegeben können die ganz schön verwirrend sein

Autor: Skaos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielen dank ist werde es morgen sofort testen :)
mfg

Autor: Skaos (Gast)
Datum:
Angehängte Dateien:
  • preview image for 1.JPG
    1.JPG
    155 KB, 221 Downloads
  • preview image for 2.JPG
    2.JPG
    122 KB, 317 Downloads

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es gestestet und es funktioniert, leider nicht richtig :(
Die Ausgabe sind sinnlosen ASCII Zeichnen, wie zum Beispiel Smilys.
Ich lade zwei Screenshots hoch, einen mit der Ausgabe auf dem 
HyperTerminal(wie es richtig ist) und den anderen ich in der Console 
bekomme.
Grüße

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht aus als ob die Baudrate nicht stimmt.

Apropos: Wo stellst du die eigentlich ein?
Du befüllst zwar einen DCB, machst aber nichts damit .-)

Autor: Skaos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mhh die Baudrate stimmt 9600. 9600 stelle ich in dem Hyperterminal.
Wenn ich mit dem DCB nichts mache :S, wie kann ich dann etwas machen??

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Skaos schrieb:
> mhh die Baudrate stimmt 9600. 9600 stelle ich in dem Hyperterminal.
> Wenn ich mit dem DCB nichts mache :S, wie kann ich dann etwas machen??

BuildCommDCB(...)
SetCommState(...)

Autor: Edwar Yupanqui (skaos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo danke für die schnelle Antwort, ich habe mein Programm so geändert 
leider bekomme ich immer noch eine falsche Ausgabe... Ich nuetze ich 
BuildCommDCB(...) SetCommState(...)  falsch, ich habe aber auf die msndn 
Seite nicht wirklich vrstanden :(
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
int main(void) {

  DCB dcb;
  HANDLE hPort;
        COMMTIMEOUTS cto;
  DWORD dw;
  unsigned char buf[0x100];
  cto.ReadIntervalTimeout=50;
        cto.ReadTotalTimeoutConstant=50;
  cto.WriteTotalTimeoutMultiplier=10;
  cto.WriteTotalTimeoutConstant=40;
  hPort=CreateFile( "COM1",GENERIC_READ | GENERIC_WRITE,0,   NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

  if (hPort==INVALID_HANDLE_VALUE)
        {
            printf("CreateFile\n"); return 1;
            
        }
        
    GetCommState(hPort, &dcb);
    BuildCommDCB("9600,n,8,1", &dcb);
    while(1)
    {
    if(ReadFile(hPort, buf, 1, &dw,NULL))
        {
            //error occurred. Report to user.
        }
    printf("%s",buf);
    }

CloseHandle(hPort);
return 0;
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Edwar Yupanqui schrieb:
> Hallo danke für die schnelle Antwort, ich habe mein Programm so geändert
> leider bekomme ich immer noch eine falsche Ausgabe... Ich nuetze ich
> BuildCommDCB(...) SetCommState(...)  falsch, ich habe aber auf die msndn
> Seite nicht wirklich vrstanden :(


Entschuldige, aber:
Wie wäre es mit Gehirn einschalten?

In der MSDN ist sogar ein vollständiges Beispiel!


>     GetCommState(hPort, &dcb);
>     BuildCommDCB("9600,n,8,1", &dcb);

Und wo ist der SetCommState?

Set Comm State

so wie "Setzen der Kommunikationsparameter"

Du machst:
   Hole die momentan eingestellten    Get Comm State
   Erzeuge die Werte für ...          Build Comm DCB

aber du setzt sie nirgends. Du aktivierst sie nicht! Nur dadurch, dass 
du einer Variabeln bei dir einen Wert zuweist, stellt sich doch nicht 
die serielle Schnittstelle auf einen neuen Baudratenwert ein. Du musst 
dem Betriebssystem schon sagen: "Schau her. So möchte ich das Ding 
eingestellt haben" - Set Comm State

Autor: Edwar Yupanqui (skaos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok danke für deine Hilfe.
Ich habe aber gerade entdeckt, dass das Programm ohne SetCommState 
funkrtioniert. Ich muss es so ausgeben:  printf("%c",buf[0]);

Warum geht das ohne SetCommState??

Wenn ich SetCommState nutze, wäre es so?
    GetCommState(hPort, &dcb);
    BuildCommDCB("9600,n,8,1", &dcb);
    SetCommState(hPort, &dcb);

danke und tut mir leid für meine dummen Fragen

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Edwar Yupanqui schrieb:

> Warum geht das ohne SetCommState??


Weil 9600, 8N1 zufällig die Standard-Einstellung ist. Kannst du auch 
im Gerätemanager umstellen.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier gibts übrigens super Beispiel-Code:
http://www.codeguru.com/Cpp/I-N/network/serialcomm...

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieser Code beschreibt eine MFC-Klasse. Einerseits ist das C++ (und kein 
C), andererseits ist die MFC nicht mit der kostenlosen Visual Studio 
Express-Variante nutzbar.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richtig, aber die paar MFC-spezifischen Sachen kann man leicht ersetzen. 
Es ging mir eher ums Prinzip, damit dem TE klar wird, die man die DCB 
anwendet, die commstates setzt usw. und in welcher Reihenfolge das 
passiert.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hältst Du das für wirklich wahrscheinlich?

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm....stimmt, er gab sich sehr lernresistent. Naja, man soll die 
Hoffnung nie aufgeben.

Autor: Edwar Yupanqui (skaos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian R. schrieb:
> Hmm....stimmt, er gab sich sehr lernresistent. Naja, man soll die
> Hoffnung nie aufgeben.

Danke für das Beispiel. Jetzt funktioniert mein Programm auch.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich das Programm getestet, da ichso eine Datenübertragung sehr 
interessant finde.
Ich habe sogar ein paar SAchen ergänzt. Bei mir hat alles klapp, außer 
dass ich von der Schleife nicht rauskomme. Weiß vielleicht wie man das 
programmiert??
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
int main(void)
{
  DCB dcb;
  FILE *datei;
  HANDLE hPort;
  COMMTIMEOUTS cto;
  DWORD dw;
  unsigned char buf[0x100];
  cto.ReadIntervalTimeout=50;
  cto.ReadTotalTimeoutConstant=50;
  cto.WriteTotalTimeoutMultiplier=10;
  cto.WriteTotalTimeoutConstant=40;
  hPort=CreateFile( "COM1",GENERIC_READ | GENERIC_WRITE,0,   NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

  if (hPort==INVALID_HANDLE_VALUE)
        {
            printf("CreateFile\n"); return 1;
        }

    GetCommState(hPort, &dcb);
    BuildCommDCB("9600,n,8,1", &dcb);
    SetCommState(hPort, &dcb);

    while(hPort!=NULL)//Ich komme nicht aus der Schleife raus
    {
        ReadFile(hPort, buf, 1, &dw,NULL);
        printf("%c",buf[0]);
        datei=fopen("Messung.txt", "a+");
        fprintf(datei,"%c",buf[0]);
        fclose (datei);
    }
CloseHandle(hPort);

return 0;
}


Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich habe sogar ein paar SAchen ergänzt. Bei mir hat alles klapp, außer
> dass ich von der Schleife nicht rauskomme. Weiß vielleicht wie man das
> programmiert??
dafür musst du aber erstmal sagen, wann das programm aus der schleife 
rauskommen soll. Bei Testendruck, bei einem zeichen was empfangen wird 
order evnetuell nach 5min.

Das öffnen und schliesen der Datei würde ich nicht in der Schleife 
machen.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mhhh ja das habe ich schon versucht.
1. Versucht:
while(hPort!=NULL) //Ich komme nicht aus der Schleife raus
    {
        ReadFile(hPort, buf, 1, &dw,NULL);
        printf("%c",buf[0]);
        if(kbhit())//if (getchar()=='q') break;
    }

2. Versucht

while(hPort!=NULL)//Ich komme nicht aus der Schleife raus
    {
        ReadFile(hPort, buf, 1, &dw,NULL);
        printf("%c",buf[0]);
        if(kbhit())
        {
            taste = getch();
            break;
        }
    }

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na ja.
Was stellst du dir den vor, wann hPort jemals NULL werden soll?

hPort wird nie von alleine NULL! Du hast den Port in Beschlag und 
solange dein Programm läuft und du den seriellen Port nicht schliesst, 
ist er deinem Programm zugeordnet.

Wenn deine Schleife laufen soll, solange ein Sender sendet, musst du mit 
dem sendenden Programm etwas vereinbaren, woraus der Empfänger erkennen 
kann: Das wars, ab jetzt kommen keine Daten mehr.

Wie du das machst: lass deine Phantasie spielen. Das kann sein, dass die 
Gegenstelle ein bestimmtes Zeichen sendet. Das kann sein, dass die 
Übertragung überhaupt nach einem Protokoll abgewickelt wird, das kann 
sein, dass dein Programm in einen Timeout läuft. Irgendwas. Denk dir was 
aus.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Wie du das machst: lass deine Phantasie spielen. Das kann sein, dass die
> Gegenstelle ein bestimmtes Zeichen sendet. Das kann sein, dass die
> Übertragung überhaupt nach einem Protokoll abgewickelt wird, das kann
> sein, dass dein Programm in einen Timeout läuft. Irgendwas. Denk dir was
> aus.

Danke für deine Hilfe, ich habe es geschafft ;). Gibts eventuell 
Verbesserungsvorschläge???
Ich poste mein Programm, falls es vielleicht jemand interessiert.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
//#include <Sleep.h>
int main(void)
{
    DCB dcb;
    FILE *datei;
    HANDLE hPort;
    DWORD dw;
    char zeichen[2000];
    char t[1]=":";
    int i=1;
    int schalter=1;
    unsigned char buf[1];
    hPort=CreateFile( "COM1",GENERIC_READ | GENERIC_WRITE,0,   NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    GetCommState(hPort, &dcb);
    BuildCommDCB("9600,n,8,1", &dcb);
    SetCommState(hPort, &dcb);
    while (hPort!=0)
        {
        ReadFile(hPort, buf, 1, &dw,NULL);
        printf("%c",buf[0]);
        datei=fopen("Messung.txt", "a+");
        fprintf(datei,"%c",buf[0]);
        fclose (datei);
        if(buf[0]==23)break;
        }
    CloseHandle(hPort);

return 0;
}

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> Gibts eventuell Verbesserungsvorschläge???

Naja, da du sämtliche Fehler-Behandlung einfach mal weggelassen hast, 
würde ich da mal ansetzen....

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> Gibts eventuell Verbesserungsvorschläge???

ja der gleiche wie oben schon einmal, nicht ständig die Datei 
"Messung.txt" öffenen und schließen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den Schwachsinn

    while (hPort!=0)
        {

hast du immer noch drinnen

hPort ist ein Handle! Das ist eine Art Kennung, die dir vom 
Betriebssystem gegeben wird und der dir exklusiven Zugang zum Gerät 
'serielle Schnittstelle' gewährt. Mit dem Handle hast du das Gerät in 
Beschlag, solange bis du CloseHandle aufrufst.
hPort KANN in deinem Programm niemals 0 werden!
Damit suggeriert diese Schleife etwas, was einfach nicht stimmt, weil 
der Fall gar nicht eintreten kann!


> ja der gleiche wie oben schon einmal, nicht ständig die Datei
> "Messung.txt" öffenen und schließen.

Das kann sogar sinnvoll sein. Wenn von der seriellen die Daten nur 
tröpfchenweise kommen und man sicher gehen möchte, dass jedes 
einkommende Datum sofort tatsächlich am File landet und nicht erst 
vorher noch in einem Cache rumlungert. Sicher ein flush hätte es 
wahrscheinlich auch getan aber im Falle eines Absturzes möchte ich mich 
nicht unbedint darauf verlassen, das das Filesystem hinter mir 
zusammenräumt.


Das komplette Fehlen jeglicher Fehlerbehandlung wiegt da sehr viel 
schwerer. Und natürlich, dass der Code vor der Veröffentlichung erst mal 
aufgeräumt werden sollte. Was da Includes und Variablen rumlungern, die 
kein Mensch braucht ....

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Sicher ein flush hätte es
> wahrscheinlich auch getan aber im Falle eines Absturzes möchte ich mich
> nicht unbedint darauf verlassen, das das Filesystem hinter mir
> zusammenräumt.

aber beim öffnen und schliesen müssen mehr Änderrungen am Dateisystem 
gemacht werden als beim flush, damit ist das risiko sogar höher das bei 
einem Abstuzt etwas verloren geht.
Außerdem sollte man heute davon ausgehen das die Hardware und das 
Betriebsystem richtig arbeiten. Wenn nur die Anwendung abstützt bleibt 
das Dateisystem auf jeden fall ganz. Man müsste ja auch sonst eventuell 
beachten das der Speicher defekt ist und eine Variable den Inhalt ändert 
ohne das man etaws dafür kann.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> Karl heinz Buchegger schrieb:
>> Sicher ein flush hätte es
>> wahrscheinlich auch getan aber im Falle eines Absturzes möchte ich mich
>> nicht unbedint darauf verlassen, das das Filesystem hinter mir
>> zusammenräumt.
>
> aber beim öffnen und schliesen müssen mehr Änderrungen am Dateisystem
> gemacht werden als beim flush, damit ist das risiko sogar höher das bei
> einem Abstuzt etwas verloren geht.
> Außerdem sollte man heute davon ausgehen das die Hardware und das
> Betriebsystem richtig arbeiten. Wenn nur die Anwendung abstützt bleibt
> das Dateisystem auf jeden fall ganz. Man müsste ja auch sonst eventuell
> beachten das der Speicher defekt ist und eine Variable den Inhalt ändert
> ohne das man etaws dafür kann.

ICh hab's schon lang nicht mehr ausprobiert. Aber wie ist das mit 
heutigen Windows-en. Früher war es so, das man eine Datei, die ein 
Programm zu schreiben offen hatte, nicht auch noch gleichzeitig lesend 
öffnen konnte. Existiert diese Restriktion noch?

(Von daher unter anderem auch die Angewohnheit eine Datei nur solange 
wie unbedingt notwendig offen halten)

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Früher war es so, das man eine Datei, die ein
> Programm zu schreiben offen hatte, nicht auch noch gleichzeitig lesend
> öffnen konnte. Existiert diese Restriktion noch?

Unter den 32-Bit-Versionen von Windows war das noch nie so, da konnte 
das Verhalten durch die Flags gesteuert werden, die der Funktion 
CreateFile übergeben werden.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen dank für eure Vorschläge,

Karl heinz Buchegger schrieb:
> Den Schwachsinn
>
>     while (hPort!=0)
>         {
>
> hast du immer noch drinnen

ich hab jetzt ein boolsches Wert

while(schalter==true)

Christian R. schrieb:
> Naja, da du sämtliche Fehler-Behandlung einfach mal weggelassen hast,
> würde ich da mal ansetzen....

Die Fehler-Behandlung habe ich gerade hinzugefügt
Vielen Dank nochmal für eure Hilfe

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.