Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
Balkonkraftwerk Speicher und Wechselrichter Tests und Tutorials

 
Zeile 1: Zeile 1:
 
'''Datenaustausch zwischen Roboter und PC via WLAN'''  
 
'''Datenaustausch zwischen Roboter und PC via WLAN'''  
Erfahrungsbericht:
+
 
 +
Ein Erfahrungsbericht:
  
 
Im folgenden Bericht möchte ich auf die Möglichkeit eingehen, wie man Daten zwischen PC und Roboter via WLAN auszutauschen kann.  
 
Im folgenden Bericht möchte ich auf die Möglichkeit eingehen, wie man Daten zwischen PC und Roboter via WLAN auszutauschen kann.  
Zeile 19: Zeile 20:
  
  
Beschreibung Komponenten:
+
''Beschreibung Komponenten:''
  
 
1) Das WLAN Modul der Firma Avisaro wird über den I2C Bus auf Seiten des Roboters angesprochen, dabei war es mir wichtig, die vorhandenen Routinen zu nutzen, die mit dem RP6 Roboter mit geliefert werden. Das WLAN Modul ist per Default als Slave konfiguriert mit der I2C Adresse 73. Somit müssen die I2C Master Routinen auf den Roboter benutzt werden. Die Frequenz der I2C Busses habe ich auf 100KHz gelassen. Das WLAN Modul kann auch, via Clock Stretching, mit höherer Frequenz angesprochen werden  
 
1) Das WLAN Modul der Firma Avisaro wird über den I2C Bus auf Seiten des Roboters angesprochen, dabei war es mir wichtig, die vorhandenen Routinen zu nutzen, die mit dem RP6 Roboter mit geliefert werden. Das WLAN Modul ist per Default als Slave konfiguriert mit der I2C Adresse 73. Somit müssen die I2C Master Routinen auf den Roboter benutzt werden. Die Frequenz der I2C Busses habe ich auf 100KHz gelassen. Das WLAN Modul kann auch, via Clock Stretching, mit höherer Frequenz angesprochen werden  
Zeile 36: Zeile 37:
  
  
Funktionsbeschreibung:
+
''Funktionsbeschreibung:''
  
  
PC Seite:
+
'''PC Seite:'''
  
Serielle Schnittstelle / Emulations-Software
+
''Serielle Schnittstelle / Emulations-Software''
 
Das PC Programm schreibt / ließt Daten von und einfach zu einer seriellen Schnittstelle und nicht direkt auf den PC WLAN Adapter.
 
Das PC Programm schreibt / ließt Daten von und einfach zu einer seriellen Schnittstelle und nicht direkt auf den PC WLAN Adapter.
 
Die serielle Schnittstelle wird durch die xxx Software emuliert übernimmt das Schreiben und Lesen der Daten auf den PC WLAN Adapter. Somit vereinfacht sich die Kommunikation von und zum WLAN Adapter wesentlich, da sich die Kommunikation auf lesen und schreiben zur serielle Schnittstelle beschränkt. Hier zu gibt es jede Menge Beispiele im Netz, oder auf der MSDN Webseite bei Microsoft wie eine serielle Schnittstelle unter Windows XP angesprochen wird.
 
Die serielle Schnittstelle wird durch die xxx Software emuliert übernimmt das Schreiben und Lesen der Daten auf den PC WLAN Adapter. Somit vereinfacht sich die Kommunikation von und zum WLAN Adapter wesentlich, da sich die Kommunikation auf lesen und schreiben zur serielle Schnittstelle beschränkt. Hier zu gibt es jede Menge Beispiele im Netz, oder auf der MSDN Webseite bei Microsoft wie eine serielle Schnittstelle unter Windows XP angesprochen wird.
Zeile 47: Zeile 48:
 
Die Standardmäßige Einstellung der seriellen Schnittstelle ist, 9600 Boud, 8 Datenbits, 1 Stopbit, No Parity. Es ist an dieser Stelle sehr hilfreich sich den Logfile der Emulations Software anzusehen, da die Parameter der seriellen Schnittestelle herausgeschrieben wird und man sofort erkennt, ob das Mobul erfolgreich connected wurde.
 
Die Standardmäßige Einstellung der seriellen Schnittstelle ist, 9600 Boud, 8 Datenbits, 1 Stopbit, No Parity. Es ist an dieser Stelle sehr hilfreich sich den Logfile der Emulations Software anzusehen, da die Parameter der seriellen Schnittestelle herausgeschrieben wird und man sofort erkennt, ob das Mobul erfolgreich connected wurde.
  
 
+
''
Programm auf dem PC
+
Programm auf dem PC''
 
Zur Erstellung der PC seitigen Software habe ich Borland C++ benutzt. Die Routinen im Sourcecode sind wie bereits beschrieben vom MSDN kopiert und angepasst worden.
 
Zur Erstellung der PC seitigen Software habe ich Borland C++ benutzt. Die Routinen im Sourcecode sind wie bereits beschrieben vom MSDN kopiert und angepasst worden.
 
Ich möchte hier nicht so tief auf die Beschreibung des Codes eingehen, dass kann man im angehängten SourceCode viel besser sehen. Das Programm besteht eigentlich nur aus einer lesenden Routine, die Daten aus der seriellen Schnittstelle ausliest und auf dem Bildschirm in einer DOS-Box darstellt. Senden von Daten an den Roboter ist auch möglich und als Funktion hinterlegt.
 
Ich möchte hier nicht so tief auf die Beschreibung des Codes eingehen, dass kann man im angehängten SourceCode viel besser sehen. Das Programm besteht eigentlich nur aus einer lesenden Routine, die Daten aus der seriellen Schnittstelle ausliest und auf dem Bildschirm in einer DOS-Box darstellt. Senden von Daten an den Roboter ist auch möglich und als Funktion hinterlegt.
Zeile 54: Zeile 55:
  
  
Netzwerk:
+
'''Netzwerk:'''
  
WLAN:
+
''WLAN:''
 
Das WLAN-Netz wurde von mir mit den Standardparametern aufgesetzt. Ich habe nur die IP Adresse, die SSID und den Kanal angepasst. WEP / WAP  Verschlüsselung ist möglich und kann via Webpage auf dem WLAN Modul auf dem Roboter eingestellt werden (siehe Dokumentation)   
 
Das WLAN-Netz wurde von mir mit den Standardparametern aufgesetzt. Ich habe nur die IP Adresse, die SSID und den Kanal angepasst. WEP / WAP  Verschlüsselung ist möglich und kann via Webpage auf dem WLAN Modul auf dem Roboter eingestellt werden (siehe Dokumentation)   
 
   
 
   
  
  
Roboter Seite:
+
'''Roboter Seite:'''
  
WLAN Modul:
+
''WLAN Modul:''
 
Das WLAN Modul wird über den I2C Bus angesprochen, die I2C Adresse habe ich behalten, da die Adresse 73 von keinem anderen I2C Device genutzt wird.  
 
Das WLAN Modul wird über den I2C Bus angesprochen, die I2C Adresse habe ich behalten, da die Adresse 73 von keinem anderen I2C Device genutzt wird.  
 
Wichtig war für mich die fertigen Routinen, die mit den RP6 Liebararies geliefert werden, zu benutzen. Dadurch musste ich keine extra Funktionen entwickeln die den Lese / Schreibzugriff auf den I2C Bus ausführen. Allerdings ist zu beachten, dass bei schreibenden Zugriffen auf das WLAN Modul die I2C Adresse um ein Bit verschoben werden muss. Das Bit 0 muss mit einer Null gefüllt werden ( Adr<<1 )
 
Wichtig war für mich die fertigen Routinen, die mit den RP6 Liebararies geliefert werden, zu benutzen. Dadurch musste ich keine extra Funktionen entwickeln die den Lese / Schreibzugriff auf den I2C Bus ausführen. Allerdings ist zu beachten, dass bei schreibenden Zugriffen auf das WLAN Modul die I2C Adresse um ein Bit verschoben werden muss. Das Bit 0 muss mit einer Null gefüllt werden ( Adr<<1 )
Zeile 89: Zeile 90:
  
 
/*  ********  Globale Variablen  ********  */
 
/*  ********  Globale Variablen  ********  */
 
 
char            *gszPort;           
 
char            *gszPort;           
 
HANDLE         hCom = NULL;
 
HANDLE         hCom = NULL;
Zeile 109: Zeile 109:
 
         gszPort = string;   
 
         gszPort = string;   
 
         hCom = CreateFile(gszPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
 
         hCom = CreateFile(gszPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
 
 
         if (hCom == INVALID_HANDLE_VALUE)
 
         if (hCom == INVALID_HANDLE_VALUE)
 
         {
 
         {
Zeile 116: Zeile 115:
 
return 0;
 
return 0;
 
}
 
}
 
 
dcb.DCBlength = sizeof(DCB);
 
dcb.DCBlength = sizeof(DCB);
 
     GetCommState(hCom, &dcb);
 
     GetCommState(hCom, &dcb);
       
+
        if (!BuildCommDCB("baud=9600 parity=N data=8 stop=1", &dcb))  
        if (!BuildCommDCB("baud=9600 parity=N data=8 stop=1", &dcb))  
+
{
{
+
 
       hCom = NULL;
 
       hCom = NULL;
 
             printf ("\n\n \a Error kann Portparameter nicht setzen e.g. 9600 Boud");
 
             printf ("\n\n \a Error kann Portparameter nicht setzen e.g. 9600 Boud");
Zeile 134: Zeile 131:
 
return 0;
 
return 0;
 
         }
 
         }
 
+
      ct.ReadIntervalTimeout   = MAXDWORD;
      ct.ReadIntervalTimeout         = MAXDWORD;
+
    ct.ReadTotalTimeoutConstant   = 0;
    ct.ReadTotalTimeoutConstant   = 0;
+
    ct.ReadTotalTimeoutMultiplier     = 1;
    ct.ReadTotalTimeoutMultiplier   = 1;
+
    ct.WriteTotalTimeoutConstant   = 250;
    ct.WriteTotalTimeoutConstant   = 250;
+
    ct.WriteTotalTimeoutMultiplier   = 1;
    ct.WriteTotalTimeoutMultiplier   = 1;
+
      if(!SetCommTimeouts(hCom, &ct))
 
+
{
      if(!SetCommTimeouts(hCom, &ct))
+
{
+
 
       CloseHandle(hCom);
 
       CloseHandle(hCom);
 
       hCom = NULL;
 
       hCom = NULL;
Zeile 156: Zeile 151:
 
'''Senden von Daten an die serielle Schnittstelle'''
 
'''Senden von Daten an die serielle Schnittstelle'''
  
/* *********** Senden der Daten an Serielle Schnittstelle ***** */
+
/* *********** Senden der Daten an Serielle Schnittstelle ***** */
void sende_cmd_start (BYTE cmd[10], int howmuch) // Datenbytes und Anzahl wieviele Bytes gesendet warden sollen  
+
void sende_cmd_start (BYTE cmd[10], int howmuch) // Datenbytes und Anzahl wieviele Bytes gesendet warden sollen  
 
{      
 
{      
DWORD  n;
+
DWORD  n;  
           
+
 
   WriteFile(hCom, &cmd, howmuch, &n, NULL);             
 
   WriteFile(hCom, &cmd, howmuch, &n, NULL);             
 
}
 
}
Zeile 172: Zeile 166:
  
  
Von der serielle Schnittstelle Daten auslesen  
+
'''Von der serielle Schnittstelle Daten auslesen'''
 
+
 
+
  
 
/* **** Endlos Schleife des Hauptprogramms **** */
 
/* **** Endlos Schleife des Hauptprogramms **** */
if (hCom != NULL)
+
if (hCom != NULL)
{
+
{
  while(CommFlag) // Bearbeiten solange das COM Port offen ist
+
  while(CommFlag)     // Bearbeiten solange das COM Port offen ist
      {     
+
  {     
        ReadFile(hCom, &cmd, 9, &n, NULL);     // Daten aus der seriellen Schnittstelle auslesen, hier 9 Bytes
+
    ReadFile(hCom, &cmd, 9, &n, NULL); // Daten aus der Schnittstelle auslesen, hier 9 Bytes
       
+
    if(n) // Wenn Daten ausgelesen wurden, sichern im Feld  data_in
if(n) // Wenn Daten ausgelesen wurden, sichern im Feld  data_in
+
    { // Daten gesichert für weitere Verarbeitung
        { // Daten gesichert für weitere Verarbeitung
+
        data_in[0] = cmd[0];
              data_in[0] = cmd[0];
+
        data_in[1] = cmd[1];   
              data_in[1] = cmd[1];   
+
        data_in[2] = cmd[2];   
              data_in[2] = cmd[2];   
+
        data_in[3] = cmd[3];   
              data_in[3] = cmd[3];   
+
        data_in[4] = cmd[4];   
              data_in[4] = cmd[4];   
+
        data_in[5] = cmd[5];  
              data_in[5] = cmd[5];  
+
        data_in[6] = cmd[6];
              data_in[6] = cmd[6];
+
        data_in[7] = cmd[7];     
              data_in[7] = cmd[7];     
+
        data_in[8] = cmd[8];               
              data_in[8] = cmd[8];               
+
      }         
}         
+
  }
        }
+
}
        }
+
 
+
  
  
Zeile 205: Zeile 195:
  
  
Beim verlassen des Programms serielle Schnittstelle schließen
 
  
 +
'''Beim verlassen des Programms serielle Schnittstelle schließen'''
  
 
/*  ************ Port schliessen ******* */
 
/*  ************ Port schliessen ******* */
Zeile 228: Zeile 218:
  
 
''Auszug aus dem Hauptprogramm:''
 
''Auszug aus dem Hauptprogramm:''
I2CTWI_initMaster(100);                                 // Initialize the TWI Module for Master operation
+
I2CTWI_initMaster(100);     // Initialize the TWI Module for Master operation
                                      // with 100kHz SCL Frequency
+
            // with 100kHz SCL Frequency
 
I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);  // Register the event hand
 
I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);  // Register the event hand
 
  
  
Zeile 237: Zeile 226:
 
while(true)  
 
while(true)  
 
{
 
{
behaviourController();       // Aufruf der Haupt-Controll-Funktion
+
  behaviourController();       // Aufruf der Haupt-Controll-Funktion
task_RP6System();             // Abfrage des ADC, ACS, IRCOMM usw...
+
  task_RP6System();             // Abfrage des ADC, ACS, IRCOMM usw...
     
+
  if (getStopwatch1() > 200)
if (getStopwatch1() > 200)
+
  {
      {
+
      task_commandProcessor();  // Abfrage ob ein Commando gesendet wurde
        task_commandProcessor();  // Abfrage ob ein Commando gesendet wurde
+
      setStopwatch1(0);  
       
+
  }   
        setStopwatch1(0);  
+
  task_I2CTWI();                // Call I2C Management routine
      }   
+
         
+
task_I2CTWI();                // Call I2C Management routine
+
 
}
 
}
 
return 0;
 
return 0;
Zeile 260: Zeile 246:
  
  
Lesen von Daten von der WLAN Karte bereitgestellt über den I2C Bus
+
'''Lesen von Daten von der WLAN Karte bereitgestellt über den I2C Bus'''
 
+
  
 
// **** Comandos von PC über WLAN Karte einlesen
 
// **** Comandos von PC über WLAN Karte einlesen
 
 
void task_commandProcessor(void)
 
void task_commandProcessor(void)
 
{
 
{
 
   uint16_t    size;
 
   uint16_t    size;
 
   uint8_t    messageBuf [100];  
 
   uint8_t    messageBuf [100];  
 
 
 
   size = 0;  
 
   size = 0;  
 
 
 
   if(!I2CTWI_isBusy())
 
   if(!I2CTWI_isBusy())
 
   {     
 
   {     
      I2CTWI_readBytes (73<<1 | 1, &messageBuf[0],  38); // Daten von der  WLAN Karte einlesen  
+
      I2CTWI_readBytes (73<<1 | 1, &messageBuf[0],  38); // Daten von WLAN Karte einlesen  
// Hier werden  einfach mal 38 Byte eingelesen
+
// Hier werden  einfach mal 38 Byte eingelesen
          size = messageBuf[0]<<8 | messageBuf[1];     // Ermitteln wie viel tatsächlich Byte gesendet wurden
+
      size = messageBuf[0]<<8 | messageBuf[1]; // Ermitteln wie viel tatsächlich Byte gesendet                      
            // Diese Funktion muss noch optimiert werden
+
                                                //wurden
                  //  In dem Feld messageBuf [2]  bis  messageBuf[size]  befinden sich die Daten von PC gesendet  
+
            // Diese Funktion muss noch optimiert werden
 +
    //  In dem Feld messageBuf [2]  bis  messageBuf[size]  befinden sich die Daten von PC gesendet  
 
   }
 
   }
 
}
 
}
Zeile 290: Zeile 273:
  
  
Senden von Daten an die WLAN Karte über den  I2C Bus
+
'''Senden von Daten an die WLAN Karte über den  I2C Bus'''
 
+
  
 
// Mit folgender Routine können eine belibige Anzahl, hier 9 Byte, an die WLAN Karte gesendet werden  
 
// Mit folgender Routine können eine belibige Anzahl, hier 9 Byte, an die WLAN Karte gesendet werden  
 
// Daten im Feld „buffer“ zur WLAN Karte senden via  I2C  Bus   
 
// Daten im Feld „buffer“ zur WLAN Karte senden via  I2C  Bus   
 
+
if (!I2CTWI_isBusy ())             // Daten über I2C an WLAN senden  
if (!I2CTWI_isBusy ())             // Daten über I2C an WLAN senden  
+
    I2CTWI_transmitBytes (73<<1, &buffer[0], 9);  
        I2CTWI_transmitBytes (73<<1, &buffer[0], 9);  
+
 
        
 
        
  
  
  
 
 
 
 
 
 
 
 
Public Licence
 
 
 
  This program is free software: you can redistribute it and/or modify
 
  it under the terms of the GNU General Public License as published by
 
  the Free Software Foundation, either version 3 of the License, or
 
  (at your option) any later version.
 
  
 
   This program is distributed in the hope that it will be useful,
 
   This program is distributed in the hope that it will be useful,
Zeile 322: Zeile 288:
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
   GNU General Public License for more details.
 
   GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public License
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

Version vom 22. Februar 2008, 19:41 Uhr

Datenaustausch zwischen Roboter und PC via WLAN

Ein Erfahrungsbericht:

Im folgenden Bericht möchte ich auf die Möglichkeit eingehen, wie man Daten zwischen PC und Roboter via WLAN auszutauschen kann. Meine Wahl viel auf das Embedded WLAN Modul der Firma Avisaro. Das Modul kann, je nach Auslieferungszustand via CAN Bus, I2C Bus, SPI oder auch über RS232 Schnittstelle mit dem Roboter kommunizieren. Ich habe mich für die Modulversion mit I2C Bus entschieden.


Eingesetzte Software / Hardware

- Roboter RP6 der Firma AREXX ( www.arexx.com ) - Borland 6 C++ Compiler auf dem PC ( www.borland.com ) - PC OS ist Windows XP home - Emulations- Software der Firma HWgroup ( www.hw-group.com ) - WLAN Adapter der Firma Avisaro ( www.avisaro.de ) - Einfacher WLAN Router von D-Link


Beschreibung Komponenten:

1) Das WLAN Modul der Firma Avisaro wird über den I2C Bus auf Seiten des Roboters angesprochen, dabei war es mir wichtig, die vorhandenen Routinen zu nutzen, die mit dem RP6 Roboter mit geliefert werden. Das WLAN Modul ist per Default als Slave konfiguriert mit der I2C Adresse 73. Somit müssen die I2C Master Routinen auf den Roboter benutzt werden. Die Frequenz der I2C Busses habe ich auf 100KHz gelassen. Das WLAN Modul kann auch, via Clock Stretching, mit höherer Frequenz angesprochen werden

2) Die Software HW VSP3 „virtual serial port“ der Firma HW-Group wird auf der PC Seite eingesetzt, um die Kommunikation zur PC WLAN Karte zu vereinfachen.

3) Es ist Möglich eine Peer zu Peer Verbindung zwischen PC und WLAN Modul aufzubauen. Ich habe aber die Lösung via WLAN Router gewählt. Das WLAN Modul ist Standardmäßig auf die IP Adresse 192.168.0.70 konfiguriert. Auf die Konfiguration des WLAN Moduls via Weboberfläche möchte ich hier nicht eingehen und verweise hiermit auf die mitgelieferte Dokumentation.

Wichtig sind nur folgende Parameter: - Netzwerksetup als TCP Server - I2C-Bus No ACK




Funktionsbeschreibung:


PC Seite:

Serielle Schnittstelle / Emulations-Software Das PC Programm schreibt / ließt Daten von und einfach zu einer seriellen Schnittstelle und nicht direkt auf den PC WLAN Adapter. Die serielle Schnittstelle wird durch die xxx Software emuliert übernimmt das Schreiben und Lesen der Daten auf den PC WLAN Adapter. Somit vereinfacht sich die Kommunikation von und zum WLAN Adapter wesentlich, da sich die Kommunikation auf lesen und schreiben zur serielle Schnittstelle beschränkt. Hier zu gibt es jede Menge Beispiele im Netz, oder auf der MSDN Webseite bei Microsoft wie eine serielle Schnittstelle unter Windows XP angesprochen wird.

Ist das WLAN Modul auf dem Roboter im Netzwerk mit seiner IP Nummer erkannt worden, dann kann via der Emulationssoftware ein COM Port zugewiesen werden  z.B. COM 3. 

Die Standardmäßige Einstellung der seriellen Schnittstelle ist, 9600 Boud, 8 Datenbits, 1 Stopbit, No Parity. Es ist an dieser Stelle sehr hilfreich sich den Logfile der Emulations Software anzusehen, da die Parameter der seriellen Schnittestelle herausgeschrieben wird und man sofort erkennt, ob das Mobul erfolgreich connected wurde.

Programm auf dem PC Zur Erstellung der PC seitigen Software habe ich Borland C++ benutzt. Die Routinen im Sourcecode sind wie bereits beschrieben vom MSDN kopiert und angepasst worden. Ich möchte hier nicht so tief auf die Beschreibung des Codes eingehen, dass kann man im angehängten SourceCode viel besser sehen. Das Programm besteht eigentlich nur aus einer lesenden Routine, die Daten aus der seriellen Schnittstelle ausliest und auf dem Bildschirm in einer DOS-Box darstellt. Senden von Daten an den Roboter ist auch möglich und als Funktion hinterlegt.


Netzwerk:

WLAN: Das WLAN-Netz wurde von mir mit den Standardparametern aufgesetzt. Ich habe nur die IP Adresse, die SSID und den Kanal angepasst. WEP / WAP Verschlüsselung ist möglich und kann via Webpage auf dem WLAN Modul auf dem Roboter eingestellt werden (siehe Dokumentation)


Roboter Seite:

WLAN Modul: Das WLAN Modul wird über den I2C Bus angesprochen, die I2C Adresse habe ich behalten, da die Adresse 73 von keinem anderen I2C Device genutzt wird. Wichtig war für mich die fertigen Routinen, die mit den RP6 Liebararies geliefert werden, zu benutzen. Dadurch musste ich keine extra Funktionen entwickeln die den Lese / Schreibzugriff auf den I2C Bus ausführen. Allerdings ist zu beachten, dass bei schreibenden Zugriffen auf das WLAN Modul die I2C Adresse um ein Bit verschoben werden muss. Das Bit 0 muss mit einer Null gefüllt werden ( Adr<<1 )

Schwieriger ist der lesenden Zugriff auf das Modul, dazu muss die Adresse ebenfalls um ein Bit verschoben werden und das Bit 0 auf EINS gesetzt werden ( Adr<<1 | 1 ). Wichtig: Im Normalfall adressiert man, als ersten Schritt, ein I2C Device und das zu lesende Register von dem man die Daten abholen möchte. Anschließend greift man lesend auf das zuvor adressierte Register des I2C Devices zu. Will man lesend auf das WLAN Modul zugreifen, so habe ich festgestellt, dass man direkt lesend auf die I2C Adresse zugreifen kann, ohne das Device vorher, durch einen Schreibzugriff , zu adressieren. Die ersten zwei Byte, der abgeholten Daten, sind die Länge / Size der auf dem WLAN Modul bereitgestellten Daten. Somit kann man einfach feststellen wie viele Daten aus dem Device ausgelesen werden müssen. Alle Daten müssen aus dem Device abgeholt werden. Siehe auch SourceCode Beispiele. Die verwendeten Software-Routinen werden mit dem RP6 Roboter mitgeliefert. Ebenso der verwendete AVR Compiler und dessen Libraries.



Sourcecode für den PC:

Initialisieren der seriellen Schnittstelle:

  1. include <windows.h>
  2. include <string.h>
  3. include <stdio.h>
  4. include <conio.h>
  5. include <commctrl.h>


/* ******** Globale Variablen ******** */ char *gszPort; HANDLE hCom = NULL; DCB dcb; COMMTIMEOUTS ct; bool CommFlag; bool ReadOnly; char string[100]; BYTE data_in[100], data_out; int k, m; DWORD n; BYTE buff[100];


/* ************* COM Port initialisieren ************** */

     int setup_Com_Port ()
     {
        	gszPort = string;  
        	hCom = CreateFile(gszPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
        	if (hCom == INVALID_HANDLE_VALUE)
        {
           	printf ("\n\n \a Error Initialise Port");

CommFlag = false; return 0; } dcb.DCBlength = sizeof(DCB);

   	 GetCommState(hCom, &dcb);
        if (!BuildCommDCB("baud=9600 parity=N data=8 stop=1", &dcb)) 

{

     		hCom = NULL;
           	printf ("\n\n \a Error kann Portparameter nicht setzen e.g. 9600 Boud");

CommFlag = false;

   	 }
   	 if(!SetCommState(hCom, &dcb)) 

{

     		CloseHandle(hCom);
     		hCom = NULL;
           	printf ("\n\n \a Cannot set comm state  BCD.\n");

CommFlag = false; return 0;

        }
     	 ct.ReadIntervalTimeout 	   = MAXDWORD;
   	 ct.ReadTotalTimeoutConstant 	   = 0;
   	 ct.ReadTotalTimeoutMultiplier     = 1;
   	 ct.WriteTotalTimeoutConstant 	   = 250;
   	 ct.WriteTotalTimeoutMultiplier    = 1;
     	 if(!SetCommTimeouts(hCom, &ct))

{

     		CloseHandle(hCom);
     		hCom = NULL;
           	printf ("\n \a Cannot set comm timeouts.\n");

CommFlag = false;

           	return 0;
   	}
        	return 0;
   }


Senden von Daten an die serielle Schnittstelle

/* *********** Senden der Daten an Serielle Schnittstelle ***** */ void sende_cmd_start (BYTE cmd[10], int howmuch) // Datenbytes und Anzahl wieviele Bytes gesendet warden sollen { DWORD n;

  	WriteFile(hCom, &cmd, howmuch, &n, NULL);             

}





Von der serielle Schnittstelle Daten auslesen

/* **** Endlos Schleife des Hauptprogramms **** */ if (hCom != NULL) {

 while(CommFlag) 			    // Bearbeiten solange das COM Port offen ist
 {     
    ReadFile(hCom, &cmd, 9, &n, NULL); // Daten aus der Schnittstelle auslesen, hier 9 Bytes
    if(n) 			// Wenn Daten ausgelesen wurden, sichern im Feld  data_in
    {				// Daten gesichert für weitere Verarbeitung
        data_in[0] = cmd[0];
        data_in[1] = cmd[1];  
        data_in[2] = cmd[2];  
        data_in[3] = cmd[3];  
        data_in[4] = cmd[4];  
        data_in[5] = cmd[5]; 
        data_in[6] = cmd[6];
        data_in[7] = cmd[7];    
        data_in[8] = cmd[8];              
     }        
 }

}





Beim verlassen des Programms serielle Schnittstelle schließen

/* ************ Port schliessen ******* */

  Sleep (5);
  CloseHandle(hCom);
  hCom = NULL;
  gotoxy (2,32);
  printf ("\n  Port %s geschlossen ", string);
  printf ("\n\n Programm beendet ");
  return 0;





Sourcecode für den RP6 Roboter:

Auszug aus dem Hauptprogramm: I2CTWI_initMaster(100); // Initialize the TWI Module for Master operation // with 100kHz SCL Frequency I2CTWI_setTransmissionErrorHandler(I2C_transmissionError); // Register the event hand


// *********************** Main loop ************************************ while(true) {

  behaviourController();        	// Aufruf der Haupt-Controll-Funktion
  task_RP6System();             	// Abfrage des ADC, ACS, IRCOMM usw...
  if (getStopwatch1() > 200)
  {
      task_commandProcessor();   	// Abfrage ob ein Commando gesendet wurde
      setStopwatch1(0); 
  }  
  task_I2CTWI();                // Call I2C Management routine

} return 0;






Lesen von Daten von der WLAN Karte bereitgestellt über den I2C Bus

// **** Comandos von PC über WLAN Karte einlesen void task_commandProcessor(void) {

  uint16_t    	size;
  uint8_t    	messageBuf [100]; 
  size = 0; 
  if(!I2CTWI_isBusy())
  {    
     I2CTWI_readBytes (73<<1 | 1, &messageBuf[0],  38); 	// Daten von WLAN Karte einlesen 

// Hier werden einfach mal 38 Byte eingelesen

     size = messageBuf[0]<<8 | messageBuf[1];  // Ermitteln wie viel tatsächlich Byte gesendet                        
                                               //wurden
           					// Diese Funktion muss noch optimiert werden
   //  In dem Feld messageBuf [2]  bis  messageBuf[size]  befinden sich die Daten von PC gesendet 
  }

}





Senden von Daten an die WLAN Karte über den I2C Bus

// Mit folgender Routine können eine belibige Anzahl, hier 9 Byte, an die WLAN Karte gesendet werden // Daten im Feld „buffer“ zur WLAN Karte senden via I2C Bus if (!I2CTWI_isBusy ()) // Daten über I2C an WLAN senden

   I2CTWI_transmitBytes (73<<1, &buffer[0], 9); 
     



 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

LiFePO4 Speicher Test