PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : I2C Kommunikation RNBFRA <-> Avisaro-WLAN-Modul



it03
12.04.2006, 15:21
Hallo Roboternetz!

Ich habe mal wieder eine Frage an Euch:

Ich möchte gerne eine Steuerung eines Roboters über WLAN ermöglichen.
Dazu habe ich ein RNBFRA, welches die Steuerung der Servos übernimmt und ein WLAN-Modul von Avisaro (I2C-Ausführung).

Um zunächst zu testen, ob die Kommunikation über den I2C-Bus überhaupt funktioniert, probiere ich jetzt schon eine halbe Ewigkeit damit rum, doch leider komme ich alleine mal wieder nicht weiter.

Bisher habe ich folgendes Ausprobiert:
RNBFRA per I2C am PC-Adapter (von Robotikhardware.net) plus Avisaro-Modul per I2C am PC-Adapter.
Da der PC-Adapter den I2C-Bus ja nur durchschleift (logisch bei einem Bus) sollte also die Kommunikation zwischen RNBFRA und Avisaro-Modul problemlos funktionieren.
Um das zu Testen, habe ich auf das RNBFRA (Hauptcontroller AT Mega32)
das Beispiel-Programm (Slave Receiver) zu TWI aus dem RN-Wiki geladen, leicht modifiziert und die entsprechenden Adressen abgeändert.
Dieses gibt die aktuellen Werte der gelesenen Slave-Adresse per Schleife an die RS232-Schnittstelle aus, damit ich per Telnet überprüfen kann, ob ich Werte verändern kann.
Jetzt habe ich mit dem i2c_beispiel-Programm (liegt beim PC->I2C Adapter bei) z.B. zunächst Werte an die Adresse der Server-Ansteuerung geschickt und anschließend wieder ausgelesen. Soweit hat alles geklappt.

Sobald ich eines der Master-Programme (Receiver oder Transmitter) auf den Hauptcontroller lade, funktioniert das ic2_beispiel-Programm nicht mehr, dies kommt meines Erachtens da her, dass das i2c_beispiel ebenso wie der Hauptcontroller als I2C-Master fungieren möchte.

Meine Schlußfolgerung bis hierher war folgendes:
Da die Konstellation i2c_beispiel-Programm (Master) plus Hauptcontroller (Slave) -> Servos funktioniert, und das Avisaro-Modul laut Avisaro nur als Slave fungiert, muss ich ja auch mit dem i2c_beispiel-Programm die Werte des Avisaro-Moduls setzen/lesen können.
Leider bekomme ich aber in der Hinsicht kein Feedback vom i2c_beispiel-Programm, es gibt als gelesene Bytes nur 255 zurück und lässt sich auch nicht durch senden anderer Bytes verändern.
Daraus habe ich geschlossen, dass das Avisaro-Modul vielleicht nicht mit der Art zurecht kommt, wie das i2c_beispiel-Programm die Bytes sendet, da in der Beschreibung des Avisaro-Moduls die Kommunikation sehr detailreich geschildert ist.

Meine Idee nun:
Ich lade das Master Receiver/Transmitter-Programm auf den Hauptcontroller und lasse Werte über Telnet ausgeben. So kann ich zumindest mal per Bascom-Programm genauere I2C-Befehle an das Avisaro-Modul senden als das i2c_beispiel-Programm.
Die Adresse meines Avisaro-Moduls ist auf 101 (Hex65) eingestellt.
Ich versuchte nun als erstes den aktuellen Wert zu lesen, über Telnet eine Ausgabe zu machen, den Wert zu verändern und anschließend erneut zu lesen um die kontrollieren, ob alles geklappt hat.
Code folgt hier:

' TWI Testprogramm

$regfile = "M32def.dat" ' the used chip
$crystal = 8000000 ' frequency used
$baud = 9600 ' baud rate

Declare Sub Twi_send_byte(byval Slave As Byte , Zeichen As Byte)
Declare Function Twi_read_byte(byval Slave As Byte) As Byte

Dim Twi_control As Byte ' Controlregister lokale kopie
Dim Twi_status As Byte
Dim Twi_data As Byte

Dim X As Byte
Dim Error As Byte ' Fehlermerker

' TWI init
Twcr = &B00000100 ' erstmal nur TWI aktivieren
Twsr = 0 ' Status und Prescaler Register
Twbr = 72 ' Bit Rate Register, 100kHz

' Startausgabe
Print "TWI Master/Receiver Transmitter"

' Hauptschleife
Do
'2 Sekunden warten
Waitms 2000
'Den Wert zum Slave senden

X = Twi_read_byte(&H7f)

' Ausgabe, damit wir sehen was geschehen ist
Print "Rec-------------vorher----------------"
Print X ;
Print " Error : " ;
Print Hex(error)


Call Twi_send_byte(&H7e , B)

' Ausgabe, damit wir sehen was geschehen ist
Print "Trans----------------------------------------------"
Print B ;
Print " Error : " ;
Print Hex(error) ' error status Ausgeben

X = Twi_read_byte(&H7f)

' Ausgabe, damit wir sehen was geschehen ist
Print "Rec----------nachher---------------"
Print X ;
Print " Error : " ;
Print Hex(error)

Loop

End


' Unterprogramme


' TWI send_byte
' sendet ein Byte und schliesst die Übertragung ab
Sub Twi_send_byte(slave As Byte , Zeichen As Byte)
Error = 0 ' Fehler zurücksetzen

' Startbedingung
Twcr = &B10100100 ' TWINT | TWSTA | TWEN

' warten bis TWINT gesetzt ist
Gosub Twi_wait_int

' wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben
If Twi_status = &H08 Or Twi_status = &H10 Then
Twdr = Slave And &HFE ' slave adresse + Write
Twcr = &B10000100 ' TWINT löschen, Byte senden

' warten bis TWINT gesetzt ist
Gosub Twi_wait_int

' Slave hat sich gemeldet
If Twi_status = &H18 Or Twi_status = &H20 Then
Twdr = Zeichen ' Daten
Twcr = &B10000100 ' TWINT löschen, Byte senden

' warten bis TWINT gesetzt ist
Gosub Twi_wait_int

' Zeichen wurden gesendet
If Twi_status = &H28 Or Twi_status = &H30 Then
Error = 0 ' kein Fehler
Else
Error = Twi_status ' Fehler
End If

Else
' kein slave
Error = Twi_status ' Fehler
End If

' Stopbedingung kommt hier immer im Ablauf, egal welcher Status
Twcr = &B10010100 ' TWINT löschen, Stop senden

Else
' Bus belegt, wird er wieder freigegeben
Twcr = &B10000100 ' TWINT löschen, Bus freigeben
Error = Twi_status ' Fehler
End If

End Sub


' warten bis TWINT gesetzt ist, status auslesen
Twi_wait_int:
Do
Twi_control = Twcr And &H80
Loop Until Twi_control = &H80

Twi_status = Twsr And &HF8 ' status

' status nur zu Debugzwecken ausgeben, weil Bus sehr langsam wird !
' Print "Err " ; Hex(twi_status)
Return


' Unterprogramme Receive


' TWI read_byte
' holt ein Byte und schliesst die Übertragung ab
Function Twi_read_byte(slave As Byte) As Byte
Error = 0 ' Fehler zurücksetzen

Twi_read_byte = 0 ' Wert vorbelegen

' Startbedingung
Twcr = &B10100100 ' TWINT | TWSTA | TWEN

' warten bis TWINT gesetzt ist
Gosub Twi_wait_int

' wenn Zugriff auf den Bus erlaubt, Slaveadresse ausgeben
If Twi_status = &H08 Or Twi_status = &H10 Then
Twdr = Slave Or &H01 ' slave adresse + Read
Twcr = &B10000100 ' TWINT löschen, Byte senden

' warten bis TWINT gesetzt ist
Gosub Twi_wait_int

' Slave hat sich gemeldet
If Twi_status = &H7F Then
Twcr = &B10000100 ' TWINT löschen, Byte senden
' kein ACK (TWEA=0) senden, weil wir nur ein Byte lesen wollen

' warten bis TWINT gesetzt ist
Gosub Twi_wait_int

' ein Byte wurde empfangen
If Twi_status = &H58 Or Twi_status = &H50 Then
Twi_read_byte = Twdr ' Daten lesen
Error = 0 ' kein Fehler
Else
Error = Twi_status ' Fehler
End If

Else
' kein slave
Error = Twi_status ' Fehler
End If

' Stopbedingung kommt hier immer im Ablauf, egal welcher Status
Twcr = &B10010100 ' TWINT löschen, Stop senden

Else
' Bus belegt, wird er wieder freigegeben
Twcr = &B10000100 ' TWINT löschen, Bus freigeben
Error = Twi_status ' Fehler
End If

End Function



Return
Allerdings läuft das Programm nur bis zu Ausgabe "TWI Master/Receiver Transmitter" und scheint dann zu hängen.

Folgende Fragen habe ich nun:
Wie bekomme ich die Kommunikation zwischen Avisaro-Modul und Hauptcontroller hin?
Funktioniert das überhaupt so, wie ich mir das denke?
Habe ich überhaupt die richtigen Schlußfolgerungen gemacht?

Ich zweifel gerade mal an mir selbst :)

Vielen, vielen Dank im Voraus für eure Hilfe oder wengistens fürs Anschauen!
//it03

robo_wolf
13.04.2006, 21:07
Hallo it03,
ich glaube das Problem liegt an der Dauerschleife des Mega32.
Dieser durchläuft eine Endlosschleife und bearbeitet die Anfragen des Beispielprogramms(PC) nicht.


Dein Gedanke ist doch, die Servos mit der WLAN Karte zu steuern.
Dein Programm mit den Servos funktioniert ja(anderes Thema).
Nun würde ich an deiner Stelle das Gleiche mit dem WLAN-Modul probieren.
Schicke an das WLAN-Modul Werte und lese diese mit dem WLAN an dem PC über Hyperterminal aus.
Und dann umgekehrt.
Schreibe ein Programm für den Mega32, welches die WLAN Karte abfragt und gebe über Hyperterminal Werte ein und z.B. über die LEDs oder gleich an die Servos aus.

### Silvio ###