PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Com1 mit C



Devil
21.07.2008, 20:22
Hallo,

ich bin auf der verzweifelten suche nach einer Möglichkeit den Com1 von mein PC zu proggen. ich möchte nur drei byte über ihn an ein servoboard senden, aber leider finde ich nichts wie man das realiesieren könnte. Ich haffe ihr könnt mir weiterhelfen.

MfG Jan.

p_mork
21.07.2008, 22:04
Hier im Wiki steht was dazu: https://www.roboternetz.de/wissen/index.php/Network_Controller/PC_Praxis#Network_Controller.2FPC_RS232_mit_Window s

MfG Mark

robocat
21.07.2008, 22:10
guck mal hier (nur den code):
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=32523

gruesse

Devil
23.07.2008, 12:28
Danke für eure schnelle unt gute Wieterhilfe!!!

Die beiden Seiten hab ich leider nicht gefunden.. ist mir schon fast peinlich das ich gefragt habe.

Habe trotzdem noch ein paar fragen:

Auf der wiki Seite fehlen irgendwie die lib die man einfügen muss damit man die Funktionen überhaupt benutzen kann und ich weiß leider nicht wechle es sind (also z.b. die #include<stdio.h>) oder musss man das wie bei dem BCC dardrüber machen?
außerdem irritiert mich die funktion zum senden von Bytes.

WriteFile(hFile, Buffer, Count, &dwCount, 0);

hFile bekommt er oben aus der anderen Funktion,
Buffer sind die zu sendenen Daten,
Count die max. Anzahl der zu sendenen Byte`s,
dwCount die tatsächlich gesendeten Byte`s,

So ich möchte drei zahlen über den Port senden und nun komm ich mit der Funktion zum senden durcheinander:

Also ich vermute das ich dann in Count = 3 setzen muss weil ich drei Byte senden wil, aber wo schreibe ich jetzt meine Zahlen rein die ich senden will? In Buffer kann ich doch nur eine zahl schreiben oder ist das ein Array? Und woher soll ich vorher wissen wieviel Bytes er wirklich sendet (dwCount)?

Bei dem Code von Robocat sieht das ja auch wieder ganz anders aus.

Wenn ich es richtig verstanden habe ist das der Teil wo du Zahlen sendest die du als ASCII-Code interpretierst und dir so ein Wort "bastelst":

sprintf(string,"%c%c%c%c%c",255,86,120,120,86);

Und ich verstehe nicht ganz was du in der while-schleife machst. Ich vermute das du da (weil run = 1) endlos Daten liest und die dann auf dem Bildschirm ausgibts. Lieg ich da riechtig?

Leider kann ich noch nicht ausprobieren ob ich es richtig verstehe da meine Bestellung noch nicht da ist.....

MfG Jan

oratus sum
24.07.2008, 11:07
Nimm doch einfach ein Terminalporgramm. Wieso rackerst du dich damit ab?

Devil
24.07.2008, 11:30
Ich galube das ich ein Terminalprogramm nicht benutzen kann, weil ich die werte die gesendet werden sollen erst unter einem C-Programm ausgerechnet werden. Ich möchte über den Port ein Servocontroalboard ansteuern welches ein kleinen Roboterarm steuert und die inverse-kinematik ist halt in C geschrieben. Brauchte also eine lösung wie ich die Werte dann in das servoboard bekomme vom PC und was ich eben auf die schnelle zu Terminalprogramme gefunden habe, war das man die werte selber eingeben muss.
Wenn das auch anders geht sag mir bitte wie, da ich davon null Ahnung habe.

MfG Jan

robocat
24.07.2008, 14:14
Auf der wiki Seite fehlen irgendwie die lib...
es sind windows api funktionen, man muss also windows.h einbinden.

...woher soll ich vorher wissen wieviel Bytes er wirklich sendet (dwCount)?
dwCount wird von der funktion "ausgefüllt". man kann damit prüfen, ob wirklich alle bytes versendet worden sind.

sprintf(string,"%c%c%c%c%c",255,86,120,120,86);
string ist ein char array, das mit sprintf gefüllt wird. genauso würdest du deine 3 bytes da reinschreiben und versenden. es ginge natürlich auch string[0]=65; um den bytewert 65 (ASCII "A") an die erste stelle im array zu schreiben.

Und ich verstehe nicht ganz was du in der while-schleife machst. Ich vermute das du da (weil run = 1) endlos Daten liest und die dann auf dem Bildschirm ausgibts. Lieg ich da riechtig?
genau, da werden endlos einzelne bytes gelesen und ausgegeben. wenn du nur daten senden willst, braucht dich das erstmal nicht zu kümmern.

um mit der seriellen schnittstelle schon ein wenig spielen zu können, könntest du hinten am PC rx und tx verbinden. wenn man daten sendet, sollte man sie dann sofort wieder einlesen können.

wenn du mehr zu windows api funktionen wissen willst, solltest du dir eine api referenz (zB hier http://win32assembly.online.fr/files/win32api.zip) besorgen. oder du guckst immer auf die microsoft msdn seite.

gruesse von der katz

Devil
26.07.2008, 16:31
Hallo robocat,

ich habe mal ein bischen mit dein C-Code rumgespielt und bin auf einige Probleme gestoßen, aber erstmal hier wie er jetzt bei mir aussieht:


// free code for reading gns9810 gps mouse attached to COM1 port done by robocat
// compiler: bcc32, platform: xp

#include <stdio.h>
#include <windows.h>


int main(void)
{
HANDLE port;
DCB dcb;
unsigned long dwNum;
unsigned char c, string[6];

port=CreateFile("COM1", // hier com-port einstellen
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL); // serielle Schnittstelle öffnen

if(!port)
{
printf("failed to open port!\n");
getch();
exit(1);
}

if(!GetCommState(port, &dcb))
{
CloseHandle(port);
printf("failed to get port!\n");
getch();
exit(1);
}

dcb.DCBlength=sizeof(dcb);
dcb.BaudRate = CBR_38400;
dcb.ByteSize = 8; // 8 Datenbits
dcb.Parity = 0; // kein Paritätsbit
dcb.StopBits = ONESTOPBIT; // 1 Stoppbit
dcb.fBinary = TRUE;
dcb.fParity = 0;
dcb.fNull=TRUE;

if(!SetCommState(port, &dcb))
{
CloseHandle(port);
printf("failed to set port!\n");
getch();
exit(1);
}

sprintf(string,"%c%c%c%c%c",255,86,120,120,86);
if(WriteFile(port,string,5,&dwNum,NULL))printf("init ok!\n");

while(run)
{
ReadFile(port,&c,1,&dwNum,NULL);
printf("%c",c);

}

CloseHandle(port); // serielle Schnittstelle schließen
return(0);
}


Wenn ich diesen nun laufenlasse mit verbundener RxD und TxD Leitung kommen nicht wie ich dachte die zahlen 255,86,120,120,86, sonder immer nur die ganze zeit "V". Dann dachte ich das das an dem %c liegen muss und habe es durch ein %i ersetzt damit er die zahlen auch als zahlen immt und es kam nur "ö".
Jetzt weiß ich nicht wie ich da meine zahlen senden soll für das Micro-Servoboard von Robotikhardware.

kannst du mir vll nochmal weiterhelfen?

MfG Jan

NumberFive
01.08.2008, 08:35
Warum sprintf ?




BYTE* Buffer = new BYTE[5];
Buffer = [55,86,120,120,86];
if(WriteFile(port,Buffer,5,&dwNum,NULL))
{
if(dwNum == 5)
{
// Alle Bytes geschrieben
}
}



Nach dem Init würde ich das noch machen

// Puffer leer mach was da jetzt drin ist sollte schrott sein
PurgeComm(port,PURGE_TXCLEAR);
PurgeComm(port,PURGE_RXCLEAR);

@robocat
Liest du die GPS Mouse über das NEMA Protoll aus ?
Wenn ja wie fägst du das Hüpfen der Geopos bei stand ab ?

Gruß

robocat
01.08.2008, 10:25
@Devil:
das mit den verbundenen tx und rx leitungen habe ich selbst noch nicht ausprobiert. kann also leider nichts dazu sagen.

@NumberFive:
stimmt, es geht ohne sprintf kürzer und eleganter. da war ich wohl blind auf allen augen bzw habe meine c grundlagen nicht ordentlich gelernt. danke für den hinweis.
die maus lese ich zwar über nmea mit einem alten psion handheld aus, lasse aber die koordinaten so wie sie sind. je nach satellitenzahl variiert die position um bis zu einige meter, aber um notfalls einen geocache zu heben, reicht es eigentlich aus. man könnte einen mittelwert aus 2-3 messungen bilden. war es das, was du gemeint hast?

gruesse

NumberFive
03.08.2008, 05:32
Ich würde das so fern möchglich mal mit zwei PC's Testen. den du hast jetzt das Problem das du zwei mal eigene Software hast und so nicht aus schließen kannst wo das problem ligt senden oder empfangen. also einfach mal eine Drei draht verbindung zwischen zwei PC's machen und auf einer seite ein Terminal Programm laufen lassen.

Oder sende mir die exe und ich probiere es hier mal aus kann aber dauern habe im moment nicht so viel zeit.

@Robocat:
https://www.roboternetz.de/phpBB2/viewtopic.php?p=388684#388684
den habe ich mal eröffnet nicht das diese Thread 2 Themen hat.
Sicher die position durch ein Array zu jagen währe möcglich ist das aber elegant ? Bitte in dem Anderen Thread anworten.

Gruß

NumberFive
17.08.2008, 07:38
So anbei das Einfaches Programm um drei Byt per RS232 raus zu schreiben einfach geht es Glaube ich nicht. Fehlerfängen sind nur Kommentare.




#include "stdafx.h"

HANDLE g_hCom = INVALID_HANDLE_VALUE; // Variable in der das Handle für den Port ist

static const char *CP[]={"COM1","COM2","COM3","COM4","COM5","COM6"};

bool OpenRS232(int portnr,long baud, char bytes, char parity, char stopbit);
void SetServoPos(BYTE nServoNr,BYTE nServoPos);

int main(int argc, char* argv[])
{
// Hauptroutine
// Com1 mit 9600,8,N,1
if(OpenRS232(0,9600,8,NOPARITY,ONESTOPBIT))
{
SetServoPos(7,254); // 7. Servo ganz rechts

Sleep(200); //Warten 200 milisec

SetServoPos(7,0); // 7. Servo ganz links
//RS232 Port wieder Frei geben.
CloseHandle(g_hCom);
}
else
{
//Fehler beim Öffnen des Ports.
}
return 0;
}

bool OpenRS232(int portnr,long baud, char bytes, char parity, char stopbit)
{
DCB dcb; // Konfig Strucktur RS232 unter windows
BOOL res = false;

g_hCom = CreateFile(CP[portnr], GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

if(g_hCom==INVALID_HANDLE_VALUE)
{
// Kann den Port nicht Öffnen
return false;
}

// Aktuelle Konfig auslesen
res=GetCommState(g_hCom, &dcb);
if(!res)
{
// Da ist was schief gegangen
return false;
}

// Werte Ändern
dcb.fBinary = TRUE;
dcb.BaudRate = baud;
dcb.ByteSize = bytes;
dcb.Parity = parity;
dcb.StopBits = stopbit;
dcb.fParity = (dcb.Parity != NOPARITY);

// Konfig schreiben
res=SetCommState(g_hCom, &dcb);
if(!res)
{
// Da ist was schief gegangen
return false;
}
return true;
}

void SetServoPos(BYTE nServoNr,BYTE nServoPos)
{
BYTE ServoBefehl[3];
ServoBefehl[0] = 255;
ServoBefehl[1] = nServoNr;
ServoBefehl[2] = nServoPos;

unsigned long sendet = 0;

if(!WriteFile(g_hCom, &ServoBefehl[0], 3, &sendet, NULL))
{
//Fehler bei Schreiben auf dem Port
}
if(sendet != 3)
{
// Nicht alle Bytes geschrieben
}
}


die Zeile #include "stdafx.h" muss eventuell durch #include <windows.h> ersetzt werden. Dann sollte sich das Teil mit jedem Compiler übersetzen lassen.

Funktion:
Öffen der RS232 (COM1) und dann Dreibyt senden und nach 200 Millisek wieder drei byte und dann RS232 Freigeben.

Gruß

NumberFive
17.08.2008, 08:01
Anbei das Dev-C++ Projekt.

Aber irgend wie ist die entstehen exe ganz schön groß ok mit dem gcc kenne ich mich nicht aus.

Gruß

Devil
17.08.2008, 20:18
Irgendwie lässt sich leider das Programm nicht copilieren. Zeigt ne ganze reihe an fehlern auf. Werd mich morgen nochmal näher damit beschäftigen.
Danke für deine hilfe.

MfG Jan

NumberFive
18.08.2008, 04:16
Hä ? das habe ich mit Dev -C++ kompliert. du Arbeits doch unter windows oder ? Welche version von Dev- C++ welche meldungen kommen den ?

Gruß

NumberFive
20.08.2008, 06:15
Gestern Abend habe wir das Problem gefunden Compiler neu Installation und dann konnte er den Source Kompilieren. war wohl ein drucheinander bei den Header.

Gruß