PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : linienfolger deluxe



neo98
03.01.2011, 11:33
ich würde gerne meinen Asuro mit mehr liniensensoren aufrüsten. Nun hab ich mir das folgendermaßen vorgestellt: Ich benutzte den PCF 8574P also Porterweiterung. wie schaff ich es aber, dass er den unterschied schwarz weiß erkennt? ich hab mir überlegt den Fototransistor und einen widerstand an die basis eines transistors zu hängen und den emitter des transistors an GND und den Kollektor an den Port zu hängen. Als Transistor würd ich den BC 337-40 nehmen und den als Fototransistor den STH 300-34. Was für einen Widerstand bräuchte ich dann? Das müsste man doch nach R = 5V(Betriebsspannung) -0,7V / I rechnen oder? Allerdings hab ich keine Plan was ich für I einsetzen soll.

Ich muss zugeben, dass ich von Elektronik wenig versteh. Mach ich hier grad aus einer Maus einen Elefanten? Geht das einfacher?

Valen
03.01.2011, 12:12
Wieso du ein weitere Transistor einbauen möchte ist mir ein Rätsel. Bitte mach einer Bild von deine Vorslag, ich verstehe das ganze was du Vorschlägst auch nicht so. Die Originale Liniensensoren sind auch nur ein Fototransistor das ein Spannungsteiler macht mit ein Widerstand im Serie-schaltung. Du brauchst ein analoge Porterweiterung, nicht ein Digitale Porterweiterung. Vielleicht kannst du ein ADC chip (Analog Digital Konvertierter) mit I2C Kommunikationstelle finden. Aber wenn du I2C ansteuern möchte gleich wie den LCD erweiterung (uber den ADC2 und ADC3 pins) dan kannst du den 2 normale Liniensensoren nicht benutzen. Besser wurde es andere freie Pins auf den Asuro für I2C Kommunikation zu benutzen (zbs. OC2 und INT0(StatusLED Rot) ).

neo98
16.01.2011, 15:26
ich war irgendwie nur auf die digitale variante fixiert. ich hab mir inzwischen den pcf8591 zugelegt und auch zum laufen gebracht wie ich das wollte, nur an meinem programm stimmt noch was nicht, aber das werd ich auch noch hinbekommen. danke nochmal

neo98
07.02.2011, 20:09
Mein Ziel ist es mit den Liniensensoren einen besstimmten Streckenverlauf mit den Linien- und Odometriesensoren abzufahren und die daten an einen PC zu senden der die Strecke aufzeichnet, auswertet und Asuro sagt wie er weiterfahren soll.
Dazu habe ich Asuro über I2C und einem PDF8591 4 Liniensensoren angebaut. Der Aufbau sieht folgendermaßen aus:
http://www.bilder-hochladen.net/files/h9k2-3-jpg.html
http://www.bilder-hochladen.net/files/thumbs/h9k2-3.jpg
http://www.bilder-hochladen.net/files/h9k2-2-jpg.html
http://www.bilder-hochladen.net/files/thumbs/h9k2-2.jpg

Ich hab mir bis jetzt noch nicht die Mühe gemacht mir ein Schaltplanzeichenprogramm zu besorgen, darum hab ich ein Zeichnprogramm bemüht.
http://www.bilder-hochladen.net/files/h9k2-1-jpg.html
http://www.bilder-hochladen.net/files/thumbs/h9k2-1.jpg

Das ist der Code der die Lichtwerte beim Asuro ausliest. Ich verwende die Asuro lib 2.8


#include "asuro.h"
#include "i2c.h"

#define pcf8591_address 0x90

int main(void)
{
unsigned char ret[6];
int i;

Init();
EncoderInit();
InitI2C();
StartI2C(pcf8591_address + WRITE);
WriteI2C(0x4);
StopI2C();
Sleep(40);
StartI2C(pcf8591_address + READ);
ret[0] = ReadI2C(ACK);
while(1)
{
ret[0] = ReadI2C(ACK);
ret[1] = ReadI2C(ACK);
ret[2] = ReadI2C(ACK);
ret[3] = ReadI2C(ACK);
i = 0;
SerWrite(ret, 4);
SerRead(ret, 1, 0);
switch(ret[0])
{
case '1': GoTurn( 50, 0, 100);
GoTurn( 0, 80, 100);
break;
case '3': GoTurn( 50, 0, 100);
GoTurn(0, 240, 100);
break;
}

MotorDir(FWD, FWD);
EncoderSet(0, 0);
while(i == 0)
{
ret[0] = ReadI2C(ACK);
ret[1] = ReadI2C(ACK);
ret[2] = ReadI2C(ACK);
ret[3] = ReadI2C(ACK);

if(ret[0] > ret[1]) {
MotorSpeed(100, 140);
}
else if(ret[0] < ret[1]) {
MotorSpeed(140, 100);
}
else
MotorSpeed(100, 100);

if(encoder[0] > 900 || (ret[0] > 190 && ret[1] > 190))
{
MotorSpeed( 0, 0);
PrintInt((int)encoder[0]);
SerWrite(" ", 1);
i = 1;
}

}

}
StopI2C();
}



Und meine Teststrecke:
http://www.bilder-hochladen.net/files/h9k2-4-jpg.html
http://www.bilder-hochladen.net/files/thumbs/h9k2-4.jpg

Das Programm für den PC (in C mit WinAPI) das ich geschrieben habe ist wohl zulang da mir angezeigt wird, nicht mehr als 20000 zu verwenden. Auf Anfrage kann ich es gern mailen etc.

Die Teststrecke läuft nicht ganz durch, sondern wird durch die "weißen Bereiche"(siehe Bild) unterbrochen. Das ist nötig damit asuro so gut wie möglich in der Spur bleibt und beim Drehen richtig auf die seitenlinie kommt.

Das ganze läugt eigentlich "relativ" gut. Je nachdem wie mein Asuro lust hat.(Magie :-s )
So gibt er zum Beispiel odometrie daten zurück wenn er sich nach goturn gedreht hat, obwohl er dort überhaupt keine Daten senden dürfte. Wenn ich die Lichtwerte beim ersten mal Abfrage stimmt alles, aber danach liefert mir der Asuro meistens nur noch "dummes Zeug". Allerdings bekomme ich troztdem die richtigen Daten, wenn ich nur die lichtwerte auslese und nicht fahre. Wäre echt net wenn sich mal jemand meinen Code/Schaltplan ansehen könnte.

Könnte es auch sein das ich die Batterie zu arg beanspruche und dann falsch gemessen wird?

neo98
19.02.2011, 11:09
falls es jemand interressiert... (oder auch nicht^^)

ich hab das Problem größtenteils gelöst. Ich glaube mein Programm für den Asuro war einfach zu groß (>7,0kB). Deshalb hab ich das ganze etwas anderst aufgezogen:


#include "asuro.h"
#include "i2c.h"

#define pcf8591_address 0x90

int main(void)
{
unsigned char ret[6];
int i;

Init();
EncoderInit();
InitI2C();
MotorDir(FWD, FWD);
while(1)
{
StartI2C(pcf8591_address + WRITE);
WriteI2C(0x4);
StopI2C();
Sleep(40);
StartI2C(pcf8591_address + READ);
ReadI2C(ACK);
ret[0] = ReadI2C(ACK);
ret[1] = ReadI2C(ACK);
ret[2] = ReadI2C(ACK);
ret[3] = ReadI2C(ACK);
i = 0;
SerWrite(ret, 4);
SerRead(ret, 1, 0);
switch(ret[0])
{
case '1': MotorSpeed(150, 0);
while(!(ret[0] < 60 && ret[1] < 60))
{
ret[0] = ReadI2C(ACK);
ret[1] = ReadI2C(ACK);
ReadI2C(ACK);
ReadI2C(ACK);
}
MotorSpeed(0, 0);
break;
case '3': MotorSpeed(0, 150);
while(!(ret[0] < 60 && ret[1] < 60))
{
ret[0] = ReadI2C(ACK);
ret[1] = ReadI2C(ACK);
ReadI2C(ACK);
ReadI2C(ACK);
}
MotorSpeed(0, 0);
break;
}
EncoderSet(0, 0);
while(i == 0)
{
ret[0] = ReadI2C(ACK);
ret[1] = ReadI2C(ACK);
ret[2] = ReadI2C(ACK);
ret[3] = ReadI2C(ACK);

if(ret[0] > ret[1]) {
MotorSpeed(100, 140); //120, 155
}
else if(ret[0] < ret[1]) {
MotorSpeed(140, 100); //155, 120
}
else
MotorSpeed(100, 100); //120, 120


if(encoder[0] > 900 || (ret[0] > 190 && ret[1] > 190))
{
MotorSpeed( 0, 0);
PrintInt((int)encoder[0]);
SerWrite(" ", 1);
i = 1;
}

}
StopI2C();

}
StopI2C();
}

Allerdings hab ich immer noch das Problem das die Abstandswerte vom Asuro nicht zu stimmen scheinen

neo98
19.02.2011, 11:10
und hier noch mein Programm für den PC das den Asuro steuert und den Weg aufzeichnet


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

#define ID_BUTTON_START 1
#define ID_BUTTON_ENDE 2
#define ID_LIST 3
#define ID_TEXT 4
#define RT_RECHTS 1
#define RT_HOCH 2
#define RT_LINKS 3
#define RT_RUNTER 4
#define MAX 3000 //Anzahl der Kartenelementen
#define Start_Punkt 200

static HWND phwndList, hwndHauptfenster, hwndButtonStart, hwndParent;
static int anzahl = 0; //Anzahl der Listenelemente der ListBox
LONG_PTR PrevWndProcEdit;
short Karte[MAX][MAX] = {0}; //[Reihe waagrecht][Spalte Senkrecht]
//Variablen für Com-Schnittstelle
HANDLE hCom;
DCB dcb;
DWORD iBytesWritten, iEvent; //unsigned int
int iAsRichtung, iAsPosition[2] = { Start_Punkt, Start_Punkt}, iAsSchritte, i, j;
RECT rect;
//Variblen für Thread
HANDLE hThread;
DWORD iExitCode;


//Asuro Nachrichten
unsigned char pcMsg[20]; // Nachrichten Puffer

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ChildProcEdit(HWND, UINT, WPARAM, LPARAM);
VOID Thread(PVOID);
void ListBoxAusgabe(char *);
int Init_Com_Schnittstelle();
int Suchen_Umgebung(void);


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Environ");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;

RegisterClass(&wndclass);

hwnd = CreateWindow(szAppName, TEXT("Asuro Interface"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);

ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);

while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(GetExitCodeThread(hThread, &iExitCode) != 0)
if(TerminateThread(hThread, iExitCode) != 0)
ListBoxAusgabe("Thread beendet...");

return msg.wParam;
}



LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND hwndEdit, hwndList, hwndButtonEnde;
static int cxChar, cyChar;
static int cxClient, cyClient;
HDC hdc;
PAINTSTRUCT ps;
int groese = 0;

hwndParent = hwnd;

switch(message)
{

case WM_SIZE:
cxClient = LOWORD(lParam);
cyClient = HIWORD(lParam);
SetWindowPos(hwndList, HWND_TOP, cxChar * 3, cyChar * 10, cxChar * 52, cyChar * (int)((cyClient - cyChar * 10 - 10) /cyChar), SWP_SHOWWINDOW);
SendMessage(hwndList, LB_SETCURSEL, (WPARAM)anzahl, 0); //Sorgt dafür das Listbox das letzte Element anzeigt
break;

case WM_PAINT:

hdc = BeginPaint(hwnd, &ps);
SetViewportOrgEx(hdc, cxChar * 58 + 10 , cyChar * 3 + 10, 0);
MoveToEx(hdc, -10 , -10, NULL);
LineTo(hdc, -10, cyClient - 20 - cyChar * 3 - 10);
LineTo(hdc, cxClient - 20 - cxChar * 58 - 10 , cyClient - 20 - cyChar * 3 - 10);
LineTo(hdc, cxClient - 20 - cxChar * 58 - 10, - 10);
LineTo(hdc, -10, -10);

for(i = 0; i < cyClient - 20 - cyChar * 3; i++)
for (j = 0; j < cxClient - 20 - cxChar * 58; j++)
{
switch(Karte[i][j])
{
case 1:
SetPixel(hdc, j, i, (COLORREF) RGB(0, 0, 0));
break;
case 2:
SelectObject(hdc, GetStockObject(NULL_PEN));
SelectObject(hdc, CreateSolidBrush(RGB(255, 0, 0)));
Ellipse(hdc, j - 3, i - 3, j + 3, i + 3);
}
}
SelectObject(hdc, GetStockObject(NULL_PEN));
SelectObject(hdc, CreateSolidBrush(RGB(255, 0, 0)));
Ellipse(hdc, iAsPosition[1] - 5, iAsPosition[0] - 5, iAsPosition[1] + 5, iAsPosition[0] + 5);




EndPaint(hwnd, &ps);

rect.top = 0;
rect.right = cxClient;
rect.bottom = cyClient;
rect.left = 0;
return 0;

case WM_CREATE:

cxChar = LOWORD(GetDialogBaseUnits());
cyChar = HIWORD(GetDialogBaseUnits());


hwndButtonStart = CreateWindow(TEXT("button"), "Start",
WS_CHILD | WS_VISIBLE | BS_CENTER,
cxChar * 3, cyChar * 3,
cxChar * 20,
cyChar * 3,
hwnd, (HMENU) ID_BUTTON_START,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);

hwndButtonEnde = CreateWindow(TEXT("button"), "Ende",
WS_CHILD | WS_VISIBLE | BS_CENTER,
cxChar * 25, cyChar * 3,
cxChar * 20,
cyChar * 3,
hwnd, (HMENU) ID_BUTTON_ENDE,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);

hwndEdit = CreateWindow(TEXT("edit"), NULL,
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_WANTRETURN,
cxChar * 3, cyChar * 8,
cxChar * 52,
cyChar,
hwnd, (HMENU) ID_LIST,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);
PrevWndProcEdit = SetWindowLongPtr(hwndEdit, GWLP_WNDPROC, (LONG_PTR) ChildProcEdit); //Editfenster bekommt eigene Message-Klasse um Enter abzufangen

hwndList = CreateWindow(TEXT("listbox"), NULL,
WS_CHILD | WS_BORDER | WS_VISIBLE | LBS_NOTIFY | WS_VSCROLL | WS_BORDER,
cxChar * 3, cyChar * 10,
cxChar * 52,
0, //Größe wird bei WM_SIZE eingstellt
hwnd, (HMENU) ID_TEXT,
(HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE),
NULL);
phwndList = hwndList;

return 0;

case WM_COMMAND:
if(HIWORD(wParam) == BN_CLICKED) {
switch(LOWORD(wParam))
{
case ID_BUTTON_START:
hwndHauptfenster = hwnd;
SendMessage(hwndList, LB_RESETCONTENT, 0, 0);
hThread = _beginthread(Thread, 0, NULL);
EnableWindow(hwndButtonStart, FALSE);
return 0;

case ID_BUTTON_ENDE:
if(GetExitCodeThread(hThread, &iExitCode) != 0)
if(TerminateThread(hThread, iExitCode) != 0)
ListBoxAusgabe("Thread beendet...");
if(hCom != NULL)
{
CloseHandle(hCom);
hCom = NULL;
}
EnableWindow(hwndButtonStart, TRUE);
return 0;

}
}
return 0;

case WM_SETFOCUS:
SetFocus(hwndEdit);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}

LRESULT CALLBACK ChildProcEdit(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR befehl[40];
switch(message)
{

case WM_KEYDOWN:
switch(wParam)
{
case VK_RETURN:
GetWindowText(hwnd, befehl, 39);

if(befehl[0] != '\0') {
if(strncmp(befehl, "start", 5) == 0 || strncmp(befehl, "Start", 5) == 0 || strncmp(befehl, "START", 5) == 0)
{
SendMessage(hwndParent, WM_COMMAND, (WPARAM) MAKEWPARAM(ID_BUTTON_START, BN_CLICKED), 0);
SetWindowText(hwnd, "");
//anzahl = SendMessage(phwndList, LB_ADDSTRING, 0, (LPARAM) befehl);
//SendMessage(phwndList, LB_SETCURSEL, (WPARAM)anzahl, 0);
}
else if(strncmp(befehl, "ende", 4) == 0 || strncmp(befehl, "Ende", 4) == 0 || strncmp(befehl, "ENDE", 4) == 0)
{
SendMessage(hwndParent, WM_COMMAND, (WPARAM) MAKEWPARAM(ID_BUTTON_ENDE, BN_CLICKED), 0);
SetWindowText(hwnd, "");
//anzahl = SendMessage(phwndList, LB_ADDSTRING, 0, (LPARAM) befehl);
//SendMessage(phwndList, LB_SETCURSEL, (WPARAM)anzahl, 0);
}
else if(strncmp(befehl, "beenden", 7) == 0 || strncmp(befehl, "Beenden", 7) == 0 || strncmp(befehl, "BEENDEN", 7) == 0
|| strncmp(befehl, "exit", 4) == 0 || strncmp(befehl, "Exit", 4) == 0 || strncmp(befehl, "EXIT", 4) == 0)
{
SendMessage(hwndParent, WM_DESTROY, 0, 0);
}
else
{
anzahl = SendMessage(phwndList, LB_ADDSTRING, 0, (LPARAM) "Falsche Eingabe");
SendMessage(phwndList, LB_SETCURSEL, (WPARAM)anzahl, 0);
SetWindowText(hwnd, "");
}

}
return 1;
}
return 1;
}
return CallWindowProc((WNDPROC) PrevWndProcEdit, hwnd, message, wParam, lParam);
}

void ListBoxAusgabe(char *text)
{
anzahl = SendMessage(phwndList, LB_ADDSTRING, 0, (LPARAM) text);
SendMessage(phwndList, LB_SETCURSEL, (WPARAM) anzahl, 0);
}

int Init_Com_Schnittstelle(void)
{
int fehler;
GetLastError(); //Errorpuffer leeren
hCom = CreateFile("COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

fehler = GetLastError();

if(fehler == ERROR_FILE_NOT_FOUND) //Gerät ist nicht angeschlossen
{
ListBoxAusgabe("Gerät nicht gefunden... (angeschlossen?)");
if(hCom != 0)
{
CloseHandle(hCom);
hCom = 0;
}
return 1;
}
else if(fehler == ERROR_ACCESS_DENIED) //Gerät wird von einem anderen Programm benutzt
{
ListBoxAusgabe("Gerät wird schon benutzt...");
if(hCom != 0)
{
CloseHandle(hCom);
hCom = 0;
}
return 1;
}
else if(fehler != 0) //Abfangen anderer Fehler
{
ListBoxAusgabe("Fehler...");
if(hCom != 0)
{
CloseHandle(hCom);
hCom = 0;
}
return 1;
}

dcb.DCBlength = sizeof(DCB);

GetCommState(hCom, &dcb);
dcb.BaudRate = 2400;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fOutX = 0;
dcb.fInX = 0;

SetCommState(hCom, &dcb);
SetCommMask(hCom, EV_RXCHAR);

return 0;

}


VOID Thread(PVOID pvoid)
{
int status;
char szBuffer[40];
unsigned char *ptr;

for(i = 0; i < MAX; i++)
for(j = 0; j < MAX; j++)
Karte[i][j] = 0;

InvalidateRect(hwndHauptfenster, NULL, TRUE);

ListBoxAusgabe("Thread gestartet...");
ListBoxAusgabe("Com-Schnittstelle wird initialisiert...");

status = Init_Com_Schnittstelle();
switch(status)
{
case 1:
ListBoxAusgabe("Thread wird beendet...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();

default:
ListBoxAusgabe("Mit Gerät verbunden...");
break;
}

/////////////////////////////////////////////////////////////////////////////////////////
//Warten auf Daten vom Untergrund
ListBoxAusgabe("Warten auf Daten vom Untergrund...");


if(WaitCommEvent(hCom, &iEvent, NULL) != 0)
{
if(iEvent & EV_RXCHAR)
{
Sleep(500);//Damit alle Daten empfangen werden, bevor sie ausgelesen werden
if(ReadFile(hCom, &pcMsg, 4, &iBytesWritten, NULL)== 0)
ListBoxAusgabe("Fehler");

if(iBytesWritten == 4)
ListBoxAusgabe("Daten vollständig erhalten...");
}
}
else
{
ListBoxAusgabe("Fehler beim auslesen...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
//////////////////////////////////////////////////////////////////////////////////
//Kontrolle der empfangenen Daten
wsprintf(szBuffer, "Lichtwerte: %d %d %d %d", (int) pcMsg[0], (int) pcMsg[1], (int) pcMsg[2], (int) pcMsg[3]);
ListBoxAusgabe(szBuffer);
////////////////////////////////////////////////////////////////////////////////////////
//Daten auswerten

for(i = 0; i < 4; i++)
if(((int)pcMsg[i]) < 120)
{
pcMsg[i] = '1';
}
else
pcMsg[i] = '0';


iAsPosition[0] = iAsPosition[1] = 200; //Nullpunkt festlegen
Karte[iAsPosition[0]][iAsPosition[1]] = 1;
iAsRichtung = RT_RECHTS;
if(!(pcMsg[0] == '1' || pcMsg[1] == '1' || pcMsg[2] == '1'))
{
ListBoxAusgabe("Asuro befindet sich nicht auf einer Linie...");
ListBoxAusgabe("Thread wird beendet...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
if(pcMsg[0] == '1' || pcMsg[1] == '1')
Karte[iAsPosition[0]] [iAsPosition[1] + 1] = 2;

if(pcMsg[2] == '1')
Karte[iAsPosition[0] + 1][iAsPosition[1]] = 2;

if(pcMsg[3] == '1')
Karte[iAsPosition[0] - 1][iAsPosition[1]] = 2;

InvalidateRect(hwndHauptfenster, NULL, TRUE);

ListBoxAusgabe("Daten ausgewertet...");


///////////////////////////////////////////////////////////////////////////////////////
//Algorithmus
while(1)
{

ListBoxAusgabe("Abzweigungen suchen und Übertragung vorbereiten...");

status = Suchen_Umgebung();

if(status == 0)
{
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}

ListBoxAusgabe("Übertragung der Daten...");

if(WriteFile(hCom, &pcMsg, 1, &iBytesWritten, NULL) == 0 || iBytesWritten != 1)
{
ListBoxAusgabe("Richtung konnte nicht gesendet werden...");
ListBoxAusgabe("Thread wird beendet...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}


switch(iAsRichtung)
{
case RT_RUNTER:
ListBoxAusgabe("Richtung gesendet...(runter)");
break;
case RT_RECHTS:
ListBoxAusgabe("Richtung gesendet...(rechts)");
break;
case RT_LINKS:
ListBoxAusgabe("Richtung gesendet...(links)");
break;
case RT_HOCH:
ListBoxAusgabe("Richtung gesendet...(hoch)");
break;
}
ListBoxAusgabe(" ");

ListBoxAusgabe("Warte auf Daten...");

if(WaitCommEvent(hCom, &iEvent, NULL) != 0)
{
if(iEvent & EV_RXCHAR)
{
Sleep(1000);
if(ReadFile(hCom, &pcMsg, 8, &iBytesWritten, NULL) == 0 && iBytesWritten > 6)//("Anzahl Schritte", " ", "vorne", "vorne", "rechts", "links")
{
ListBoxAusgabe("Fehler bei ReadFile()...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}

}
}
else
{
ListBoxAusgabe("Fehler beim auslesen...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
ListBoxAusgabe("Daten erhalten...");

ptr = strchr(pcMsg, ' ');
if(ptr == NULL)
{
ListBoxAusgabe("Fehler...(kein Leerzeichen vorhanden)");
ListBoxAusgabe("Thread wird beendet...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}
//////////////////////////////////////////////////////////////////////////////////
//Kontrolle der empfangenen Daten für Benutzer
wsprintf(szBuffer, "%d Schritte; Lichtwerte: %d %d %d %d", iAsSchritte, *(ptr + 1), *(ptr + 2), *(ptr + 3), *(ptr + 4));
ListBoxAusgabe(szBuffer);
//////////////////////////////////////////////////////////////////////////////////


sscanf(pcMsg, "%d ", &iAsSchritte);
//iAsSchritte = iAsSchritte / 2; //Zum verkleinern der Darstellung
iAsSchritte += 30; //Ausgleichswert durch Kurven
ListBoxAusgabe("Daten in Karte eintragen...");

for(i = 1; i < 5; i++)
if(*(ptr + i) < 120)
{
*(ptr + i) = '1';
}
else
*(ptr + i) = '0';

if(iAsRichtung == RT_RECHTS)
{
for(i = 0; i < iAsSchritte; i++)
Karte[iAsPosition[0]][iAsPosition[1] + i] = 1;
iAsPosition[1] += iAsSchritte;

if(*(ptr + 2) == '1' || *(ptr + 1) == '1')
Karte[iAsPosition[0]][iAsPosition[1] + 1] = 2;
else if(*(ptr + 3) == '1')
Karte[iAsPosition[0] + 1][iAsPosition[1]] = 2;
else if(*(ptr + 4) == '1')
Karte[iAsPosition[0] - 1][iAsPosition[1]] = 2;

}
if(iAsRichtung == RT_RUNTER)
{
for(i = 0; i < iAsSchritte; i++)
Karte[iAsPosition[0] + i][iAsPosition[1]] = 1;
iAsPosition[0] += iAsSchritte;

if(*(ptr + 2) == '1' || *(ptr + 1) == '1')
Karte[iAsPosition[0] + 1][iAsPosition[1]] = 2;
else if(*(ptr + 3) == '1')
Karte[iAsPosition[0]][iAsPosition[1] - 1] = 2;
else if(*(ptr + 4) == '1')
Karte[iAsPosition[0]][iAsPosition[1] + 1] = 2;
}
if(iAsRichtung == RT_LINKS)
{
for(i = 0; i < iAsSchritte; i++)
Karte[iAsPosition[0]][iAsPosition[1] - i] = 1;
iAsPosition[1] -= iAsSchritte;

if(*(ptr + 2) == '1' || *(ptr + 1) == '1')
Karte[iAsPosition[0]][iAsPosition[1] - 1] = 2;
else if(*(ptr + 3) == '1')
Karte[iAsPosition[0] - 1][iAsPosition[1]] = 2;
else if(*(ptr + 4) == '1')
Karte[iAsPosition[0] + 1][iAsPosition[1]] = 2;
}
if(iAsRichtung == RT_HOCH)
{
for(i = 0; i < iAsSchritte; i++)
Karte[iAsPosition[0] - i][iAsPosition[1]] = 1;
iAsPosition[0] -= iAsSchritte;

if(*(ptr + 2) == '1' || *(ptr + 1) == '1')
Karte[iAsPosition[0] - 1][iAsPosition[1]] = 2;
else if(*(ptr + 3) == '1')
Karte[iAsPosition[0]][iAsPosition[1] + 1] = 2;
else if(*(ptr + 4) == '1')
Karte[iAsPosition[0]][iAsPosition[1] - 1] = 2;
}

InvalidateRect(hwndHauptfenster, &rect, TRUE);

if(*(ptr + 1) == '0' && *(ptr + 2) == '0' && *(ptr + 3) == '0' && *(ptr + 4) == '0')
{
ListBoxAusgabe("Strecke ist zuende...");
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}


ListBoxAusgabe("Daten auswerten...");


}
CloseHandle(hCom);
hCom = NULL;
EnableWindow(hwndButtonStart, TRUE);
_endthread();
}

int Suchen_Umgebung(void) //Gibt zurück ob sich Asuro links oder rechtsrum drehen muss
{
if(Karte[iAsPosition[0]][iAsPosition[1] + 1] == 2) //rechts geht es weiter
{
ListBoxAusgabe("Nach rechts geht es weiter...");
if(iAsRichtung == RT_RECHTS)
{
pcMsg[0] = '0';
}
else if(iAsRichtung == RT_RUNTER)
{
pcMsg[0] = '3';
}
else //if(iAsRichtung == RT_HOCH)
{
pcMsg[0] = '1';
}
iAsRichtung = RT_RECHTS;
return 1;
}
else if(Karte[iAsPosition[0] + 1][iAsPosition[1]] == 2) //runter geht es weiter
{
ListBoxAusgabe("Nach unten geht es weiter...");
if(iAsRichtung == RT_RECHTS)
{
pcMsg[0] = '1';
}
else if(iAsRichtung == RT_RUNTER)
{
pcMsg[0] = '0';
}
else if(iAsRichtung == RT_LINKS)
{
pcMsg[0] = '3';
}
iAsRichtung = RT_RUNTER;
return 1;
}
else if(Karte[iAsPosition[0]][((iAsPosition[1] - 1) < 0) ? 0 : (iAsPosition[1] - 1)] == 2) //links geht es weiter
{
ListBoxAusgabe("Nach links geht es weiter...");
if(iAsRichtung == RT_RUNTER)
{
pcMsg[0] = '1';
}
else if(iAsRichtung == RT_LINKS)
{
pcMsg[0] = '0';
}
else
{
pcMsg[0] = '3';
}
iAsRichtung = RT_LINKS;
return 1;
}
else if(Karte[((iAsPosition[0] - 1) < 0) ? 0 : (iAsPosition[0] - 1)][iAsPosition[1]] == 2) //hoch geht es weiter
{
ListBoxAusgabe("Nach oben geht es weiter...");
if(iAsRichtung == RT_RECHTS)
{
pcMsg[0] = '3';
}
else if(iAsRichtung == RT_LINKS)
{
pcMsg[0] = '1';
}
else
{
pcMsg[0] = '0';
}
iAsRichtung = RT_HOCH;
return 1;
}
else
{
ListBoxAusgabe("Keine weiteren Punkte in unmittelbarer Nähe...");
return 0;
}

}