Til Bertel

Tags:    c++ database locking timestamping samtidighed transaktion

Hej bertel
Jeg er kommet vidre med dette project: http://www.udvikleren.dk/thread.php?techid=1&f=1&t=660
Det var min computer der var noget galt med den gad ikke køre programmene du lavede til mig men da jeg formaterede og prøvede fik jeg lystet til at lyse og slukke hver gang jeg trykkede på enter! Men nu er spørgsmålet kan du hjælpe mig med at lære at forstå at lave programmer til serial porten så jeg selv kan lære det??? Kan du f.eks hjælpe mig med at forstå følgende program som vi lavede sidst:

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

void SetTimeOut(HANDLE Port, int sec)
{
COMMTIMEOUTS commtimeouts;
GetCommTimeouts(Port, &commtimeouts);
commtimeouts.ReadIntervalTimeout = 1000*sec;
commtimeouts.ReadTotalTimeoutMultiplier = 10;
commtimeouts.ReadTotalTimeoutConstant = 1000*sec;
SetCommTimeouts(Port, &commtimeouts);
}

void Tx(HANDLE Port, const char *data)
{
DWORD Dummy;
WriteFile(Port, data, strlen(data), &Dummy, 0);
WriteFile(Port, "\\r\\n", 2, &Dummy, 0);
}

void Rx(HANDLE Port)
{
char Buffer[128];
DWORD Length, i;

ReadFile(Port, Buffer, 128, &Length, 0);

for(i = 0; i < Length; i++)
if(Buffer != '\\r')
printf("%c", Buffer);
}

int main(void)
{
DCB dcb;
HANDLE ComPort = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);

GetCommState(ComPort, &dcb);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutxCtsFlow = 1;
SetCommState(ComPort, &dcb);
SetTimeOut(ComPort, 1);

int Counter = 0;
while(1)
{
if(Counter & 1)
dcb.fRtsControl = RTS_CONTROL_ENABLE;
else
dcb.fRtsControl = RTS_CONTROL_DISABLE;
printf("Counter: %d\\n", Counter);
SetCommState(ComPort, &dcb);
Counter++;
getchar();
}

CloseHandle(ComPort);

return 0;
}






49 svar postet i denne tråd vises herunder
0 indlæg har modtaget i alt 0 karma
Sorter efter stemmer Sorter efter dato
Jeg har programmeret comporten fra siden du startede i vuggestuen, og C og C++ lige så længe, et eller ander har der hængt ved.

Ja, du kan godt programmere et modem og lege med det. Hvis du har en mobil kan du sansynligvis forbinde den med et kabel eller en infra rød port. Så kan man sende og læse SMS'er, ændre i telefonbogen osv.

Jeg lavede et lille testprogram til at måle tider, det giver en urimelig høj nøjagtighed:

Fold kodeboks ind/udKode 


Jeg samler ikke på point.



Jeg har faktisk et com kabel til en nokia 3310 liggende og jeg har også en nokia 3310 liggende! Er det bare sådan noget jeg skal begynde at øve mig med??? Er det så det samme programmring jeg er ved at lære eller er det noget andet hvor kan jeg lære om det???

Hmm jeg har lavet følgende kode:

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

void SetTimeOut(HANDLE Port, int MSec)
{
COMMTIMEOUTS commtimeouts;
GetCommTimeouts(Port, &commtimeouts);
commtimeouts.ReadIntervalTimeout = MSec;
commtimeouts.ReadTotalTimeoutMultiplier = 1;
commtimeouts.ReadTotalTimeoutConstant = MSec;
SetCommTimeouts(Port, &commtimeouts);
}

void Rx(HANDLE Port)
{
char Buffer[128];
DWORD Length = 0;
DWORD ErrorType = 0;


ReadFile(Port, Buffer, 128, &Length, 0);
ClearCommError(Port, &ErrorType, 0);
if(Length || ErrorType)
float end = clock();
cout << "Du har sat de to ledninger sammen 1 gang";


}

void Rx1(HANDLE Port)
{
char Buffer[128];
DWORD Length = 0;
DWORD ErrorType = 0;


ReadFile(Port, Buffer, 128, &Length, 0);
ClearCommError(Port, &ErrorType, 0);
if(Length || ErrorType)
float end = clock();
cout << end;
system("pause");


}


int main(void)
{
DCB dcb;
HANDLE ComPort = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);

GetCommState(ComPort, &dcb);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fErrorChar = TRUE;
dcb.fParity = TRUE;
dcb.Parity = ODDPARITY;
dcb.fAbortOnError = TRUE;
dcb.fOutxCtsFlow = 1;
SetCommState(ComPort, &dcb);
SetTimeOut(ComPort, 1);


Rx(ComPort);
Rx1(ComPort);


CloseHandle(ComPort);

return 0;
}


Men når jeg starter programmet slutter det med det samme det er meningen at når jeg tilslutter de to ledninger så begynder den at tælle og når jeg så sætter dem sammen igen så viser den hvor lang tid der er gået hvad tror du der er galt???



Koden er en udbygning af denne:
http://home20.inet.tele.dk/midgaard/snip/modem.html

Hvis du tilslutter din mobil og kører koden (du skal nok ændre COM2 til COM1) så burde du kunne se at mobilen svarer OK.

Jeg skal lige have bootet den anden PC så skal jeg nok kikke på det andet problem.



En lettere forbedret version:

Fold kodeboks ind/udKode 


ReadFile returnerer ved timeout, så du er nødt til at lave en loop der kører ReadFile der er modtaget data eller der er opstået en fejl.

QueryPerformanceCounter har bedre opløsning.



Jeg bruger dev-cpp
Når jeg har compilet det kommer der et vindue op der hedder compiler and linker output og der står bare denne linie:
C:\\DEV-C_~1\\Lib\\\\libmingw32.a(main.o)(.text+0x8e): undefined reference to `WinMain@16'

hmm hvad tror du det er for en fejl???



Heyy nu virkede det jeg prøvede bare at compille det en gang til fatter ikke hvad der var galt men nu virker det!



Jeg har bare stadig et lille problem og det er at når jeg sætter de to ledninger sammen så skriver den først det den skal skrive og så udskriver den allerede med det samme hvor lang tid det tog selvom jeg ikke satte ledningerne sammen anden gang jeg tror det er fordi at f.eks når det var med prikker så lavede den 2 prikker af gangen kan jeg gøre noget ved dette???



Den fejl du fik tyder på at den troede at du ville lave en Windows app.

Det andet problem er at når du sætter ledningerne sammen bliver der skabt og afbrudt kontakt flere gange. Den eneste løsning jeg har fundet er at ignorere den anden event hvis den kommer for hurtig efter den første (ca. 30 ms er en rimelig grænse). Hvis du har en rigtig kontakt er problemet sansynligvis mindre. Man kan også lave et filter med en kondensator og en modstand.



Hvordan laver jeg det med den skal vente i 30 ms i dette program:

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

void SetTimeOut(HANDLE Port, int MSec)
{
COMMTIMEOUTS commtimeouts;
GetCommTimeouts(Port, &commtimeouts);
commtimeouts.ReadIntervalTimeout = MSec;
commtimeouts.ReadTotalTimeoutMultiplier = 1;
commtimeouts.ReadTotalTimeoutConstant = MSec;
SetCommTimeouts(Port, &commtimeouts);
}
unsigned int Start, End;

void Rx(HANDLE Port)
{
char Buffer[128];
DWORD Length = 0;
DWORD ErrorType = 0;
do
{
ReadFile(Port, Buffer, 128, &Length, 0);
ClearCommError(Port, &ErrorType, 0);
}
while(Length == 0 && ErrorType == 0);
Start = clock();
std::cout << "Du har sat de to ledninger sammen 1 gang" << std::endl;
}

void Rx1(HANDLE Port)
{
char Buffer[128];
DWORD Length = 0;
DWORD ErrorType = 0;
do
{
ReadFile(Port, Buffer, 128, &Length, 0);
ClearCommError(Port, &ErrorType, 0);
}
while(Length == 0 && ErrorType == 0);
End = clock();

std::cout << "Delay: " << (double )(End - Start)/CLOCKS_PER_SEC << std::endl;
system("pause");
}


int main(void)
{
DCB dcb;
HANDLE ComPort = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);

GetCommState(ComPort, &dcb);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fErrorChar = TRUE;
dcb.fParity = TRUE;
dcb.Parity = ODDPARITY;
dcb.fAbortOnError = TRUE;
dcb.fOutxCtsFlow = 1;
SetCommState(ComPort, &dcb);
SetTimeOut(ComPort, 1);


Rx(ComPort);
Rx1(ComPort);

CloseHandle(ComPort);

return 0;
}




Hvordan laver jeg det med den skal vente i 30 ms i dette program:

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

void SetTimeOut(HANDLE Port, int MSec)
{
COMMTIMEOUTS commtimeouts;
GetCommTimeouts(Port, &commtimeouts);
commtimeouts.ReadIntervalTimeout = MSec;
commtimeouts.ReadTotalTimeoutMultiplier = 1;
commtimeouts.ReadTotalTimeoutConstant = MSec;
SetCommTimeouts(Port, &commtimeouts);
}
unsigned int Start, End;

void Rx(HANDLE Port)
{
char Buffer[128];
DWORD Length = 0;
DWORD ErrorType = 0;
do
{
ReadFile(Port, Buffer, 128, &Length, 0);
ClearCommError(Port, &ErrorType, 0);
}
while(Length == 0 && ErrorType == 0);
Start = clock();
std::cout << "Du har sat de to ledninger sammen 1 gang" << std::endl;
}

void Rx1(HANDLE Port)
{
char Buffer[128];
DWORD Length = 0;
DWORD ErrorType = 0;
do
{
ReadFile(Port, Buffer, 128, &Length, 0);
ClearCommError(Port, &ErrorType, 0);
}
while(Length == 0 && ErrorType == 0);
End = clock();

std::cout << "Delay: " << (double )(End - Start)/CLOCKS_PER_SEC << std::endl;
system("pause");
}


int main(void)
{
DCB dcb;
HANDLE ComPort = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);

GetCommState(ComPort, &dcb);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fErrorChar = TRUE;
dcb.fParity = TRUE;
dcb.Parity = ODDPARITY;
dcb.fAbortOnError = TRUE;
dcb.fOutxCtsFlow = 1;
SetCommState(ComPort, &dcb);
SetTimeOut(ComPort, 1);


Rx(ComPort);
Rx1(ComPort);

CloseHandle(ComPort);

return 0;
}



I Rx1() kan du beregne tiden med:

End = clock();
doubble diff = (double )(End - Start)/CLOCKS_PER_SEC;

Og så fortsætte i loopen indtil diff er større end 0.03 (diff er i sekunder):
while(Length == 0 && ErrorType == 0 && diff < 0.03);



t