PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : i²c auslesen



it03
29.03.2006, 14:29
Hallo,

ich sitze hier vor meinem Programm und will letztendlich einen Servo mit Befehlen vom I²C steuern. Dazu habe ich mir Das I²C-Beispielprogramm vom RN runtergeladen, allerdings startet es zwar und ich kann auch munter Werte eingeben aber ohne Effekt. Wenn ich Beispielsweise bei der SlaveID: 114 die ertsen beiden Bytes mit 23 und 32 beschreiben lasse und mir dann 114 Ausgeben lasse, zeigt er 255 und 255 an...

Ich habe ein Programm geschrieben welches auf dem Controler läuft und einen Wert in eine Adresse schreibt (mittel i2csend) und diese Adresse wird im gleichen Programm wieder ausgelesen(i2creceive). Das funktioniert soweit einwandfrei.

Schön wäre es, wenn ich an einen bestimmten Slave einen Wert angebe (per I²C Beispielprogramm) und dieser dann vom Controler verabreitet wird. Also z.B. gebe ich am Slave 111 die 23 an und mein Programm auf dem Controler (welches ständig den Wert überprüft) erkennt diesen und dreht daraufhin den Servo...)

robo_wolf
29.03.2006, 20:05
Hallo it3,
das klingt alles ein wenig verwirrend.
Es wäre sicher hilfreich, wenn du deinen Code mit postest und darin kommentierst.

### Silvio ###

it03
29.03.2006, 22:49
also um Code geht es eigentlich nicht direkt. Zumindestens nicht um fehlerhaften.

Also ich habe ein Programm welches mit dem Befehli2csend Daten an eine Adresse schickt. Diese Daten können auch mit dem selben Programm ausgelesen werden.
Das Program ansich wird auf den Controler gespielt und läuft dort und gibt Werte über die rs232 Schnittstelle aus.

Jetzt gibt es noch ein anderes Programm zum testen des i2c bus (hier im RN). Dieses soll es ermöglichen über den COM Port über den i2c bus an Andressen zu schreiben. Doch das klappt irgendiwe nicht wirklich. Es wird zwar gestarten und meldet keine Fehler, aber wenn man Daten senden klickt passiert nix, zumindestens kann man sie dann auch nciht wieder auslesen.

Und ich möchte gerne mit diesem Programm Daten an eine Adresse senden und dann soll das Programm auf dem Controller die Adresse auslesen etwas ausführen (zB einen Servo etc.).

Und ich frage mich jetzt warum das Programm aus dem RN nicht richtig funktioniert? Ich ahbe die gleichen Adressen benutzt wie bei dem Programm auf den Controler, nur das ich dise von Hex in Dezimal umgewandelt haben...

robo_wolf
30.03.2006, 09:28
es sind also 2 getrennte Test-Programme.
Das 1. funktioniert und das 2. funktioniert nicht.
Das 2. Programm liest also über den I2C-Bus Daten vom COM-Port?
Es ist praktisch der umgekehrte Fall des 1.Programms?
Oder verstehe ich das falsch?
-> Dateneingabe über RS232 auf I2C zu Servo(oder was auch immer)
Lass mal die I2C-Adressen in Hex-Format.
### Silvio ###

it03
30.03.2006, 12:18
Hm, ich versuche es nocheinmal anders zu erklären:

Folgendes will ich erreichen:
Mit dem vom RN (über Robotikhardware) vertriebenen I2C-PC Adapter und dem dazugehörigen i2c_beispiel Programm (ab jetzt P1 genannt) möchte ich z.b. einen Wert von 5 an das RNBFRA-Borad senden.
Dort soll auf dem MEGA32-Chip ein Programm laufen (ab jetzt P2 genannt) welches den Wert empfängt, und daraufhin einen Servo bis an den Anschalg dreht.
Das würde mir als Test erstmal ausreichen.

Jetzt zu meinem bisherigen Vorgehen:

Mein P2 sieht bisher so aus:
---- Schnipp ----

'################################################# ##
'Servo-Ansteuerung via I2C
'TEST
'################################################# ##


$regfile = "m32def.dat"

'#### Servo-Zeugs ####
Declare Sub Rnb_servob(byval Servonummer As Byte , Byval Position As Byte)
Dim Pos As Byte

'#### I2C-Zeugs ####
Const Writeport_adr = &H7E
Const Readport_adr = &H72

Dim T As Byte , X As Byte , Senddata As Byte
X = 0
Senddata = 5

Config Scl = Portc.0
Config Sda = Portc.1

'#### Sonstiges-Zeugs ####
Dim I As Byte
Dim J As Byte
I = 1
J = 1

$crystal = 8000000
$baud = 9600

Wiederhole:

For I = 1 To 255
'Servo 1 dreht sich zur Kontrolle staendig hin und her
Pos = 1
Call Rnb_servob(1 , Pos)
Wait 1
Pos = 255
Call Rnb_servob(1 , Pos)
Wait 1

Print " "
Print " "

I2creceive Writeport_adr , X
Print "I2c WRITEPORT gelesen, Wert:"
Print X

'Servo 2 soll bei X gleich 3 reagieren
If X = 3 Then
Pos = 127
Call Rnb_servob(2 , Pos)
Wait 1
Pos = 20
Call Rnb_servob(2 , Pos)
Wait 1
Pos = 235
Call Rnb_servob(2 , Pos)
Wait 1
Pos = 127
Call Rnb_servob(2 , Pos)
Wait 1
End If

'Servo 3 soll bei X gleich 5 reagieren
If X = 5 Then
Pos = 255
Call Rnb_servob(3 , Pos)
Wait 50000
Pos = 0
Call Rnb_servob(3 , Pos)
Wait 50000
X = 0
End If


Next I

Goto Wiedehole


Sub Rnb_servob(byval Servonummer As Byte , Byval Position As Byte)
Open "comd.7:9600,8,n,1" For Output As #2
Print #2 , "#s" ; Chr(servonummer) ; Chr(position)
Close #2
End Sub

End---- Schnapp ----

Jetzt sende ich über P1 an die SlaveID 126 (=Hex7E) den Wert 5
Allerdings komme ich so nicht weiter.

Habe ich vielleicht einen fatalen Denkfehler im Programm, oder verstehe ich was am I2C-Bus nicht richtig?
Ich wäre für "DIE" Lösung natürlich dankbar :)

Vielen Dank im Voraus!

robo_wolf
30.03.2006, 16:20
habe mir den Adapter mal angeschaut.
Du nutzt das beliegende Programm als Eingabe für den I2C.
Dein Code war ursprünglich vom RNS1-Servotreiber... oder so..
Der Code ist für den CoController des RNBFRA geschrieben.
Programme für den CoController werden über den ISP2 übertragen.
Die Servos werden bei RNBFRA über den Cocontroller gesteuert.
Die $crystal müssen dann auf =4000000 (4MHz) und
Config Scl = Portd.2
Config Sda = Portd.3
stehen.

und nicht zu vergessen:
$regfile = "2313def.dat" 'AT90S2313

Const Writepowerport_adr = &H72 'I2C Adr PCF 2
Const Readpowerport_adr = &H73 'I2C Adr PCF 2


Diese Befehle wirst du für den I2C-bus brauchen:


I2cinit
I2cstart
I2cwbyte Writepowerport_adr
I2cwbyte I2cdaten
I2cstop

hier noch mehr darüber:
https://www.roboternetz.de/wissen/index.php/I2C

Les dir am besten noch die Anmerkungen zum Cocontroller des RNBFRA durch.
Schreib mal dein Programm daingehend um und probier dann noch mal.
### Silvio ###

Ach noch was WICHTIGES !!!
In der Anleitung steht, das man die Servos beim Programmieren des Cocontrollers abstecken sollte.

it03
12.04.2006, 15:22
Hallo,

nur zur Info:
Also es hat jetzt alles geklappt mit meiner "Demo-Servo-Ansteuerung"
Das Programm läuft, wie bereits in meiner letzten Antwort beschrieben auf dem Hauptcontroller.
Ich habe lediglich die Adressen des Write- und ReadPorts ausgetauscht (Hex7E und Hex7F).
Außerdem hatte ich wohl den Aufruf der i2c-Initialisierungs-Funktions (i2cinit) vergessen.

Wenn es interessiert poste ich mein Demo-Programm (was jetzt auf Eingaben vom i2c_beispiel Programm vom RN funktioniert) als Quellcode sehr gerne hier.

Aber ich habe schon wieder eine neue Frage. Habe dazu einen neuen Thread eröffnet:
https://www.roboternetz.de/phpBB2/viewtopic.php?t=18934

robo_wolf
14.04.2006, 10:51
Hallo it03,
poste doch bitte mal dein Demo-Programm.
### Silvio ###

it03
26.04.2006, 10:23
Hi,

hier ist unser Code:



'################################################# ##
'Servotest Prg
'################################################# ##


$regfile = "m32def.dat"

Declare Sub Rnb_servob(byval Servonummer As Byte , Byval Position As Integer)


'i2c-Test
Const Writepowerport_adr = &H7E 'I2C Adr PCF 2
Const Readpowerport_adr = &H7F 'I2C Adr PCF 2
Dim I2cdaten As Byte 'Datenbyte aus PCF8574
Dim T As Byte , Senddata As Byte
Dim X As Integer
Dim Y As Integer
X = 128
Y = 128
Senddata = 23
Config Scl = Portc.0 'Ports fuer IIC-Bus
Config Sda = Portc.1
'i2c-Test ENDE

Dim I As Byte
Dim J As Byte
Dim Con As Byte
J = 1
Dim Pos As Byte

$crystal = 8000000 'Quarzfrequenz
$baud = 9600

I2cinit

I2cstart
I2cwbyte &H74 'Schreibbefehl an PCF3 schicken
' Led´s ein ,Motorendstufen ein, Port-Peripherie ein, RBN-Bus Sleep Modus aus (also Peripherie aktiv)
I2cwbyte &B00000010 'Datenbyte an PCF3
I2cstop


Wiederhole:

Waitms 100


I2creceive Readpowerport_adr , Con
I2csend Writepowerport_adr , 0


If Con = 0 Then
X = X
Y = Y
End If

If Con = 1 Then
X = X - 50

If X <= 0 Then

X = 0
End If
End If

If Con = 2 Then


X = X - 10
If X <= 0 Then

X = 0
End If
End If

If Con = 3 Then


X = X - 1
If X <= 0 Then
X = 0
End If

End If

If Con = 10 Then
X = 128
End If

If Con = 13 Then
X = X + 50
If X >= 255 Then
X = 255
End If
End If

If Con = 12 Then
X = X + 10
If X >= 255 Then
X = 255
End If
End If

If Con = 11 Then
X = X + 1
If X >= 255 Then
X = 255
End If
End If


If Con = 200 Then
Y = Y + 10

If Y >= 255 Then
Y = 255
End If

End If






If Con = 210 Then
Y = Y - 10

If Y <= 0 Then
Y = 0
End If



End If


If Con = 220 Then
Y = 128


End If


If Con = 230 Then
Y = 80

End If

If Con = 100 Then
Call Rnb_servob(2 , 255)
Waitms 1000
Call Rnb_servob(2 , 128)
Waitms 1500
Call Rnb_servob(2 , 1)
Waitms 1000
End If


Call Rnb_servob(1 , X)
Call Rnb_servob(2 , Y)



'I2csend &H74 , 10100010
'I2csend Readpowerport_adr , 12
'I2cstart 'generate start
'I2cwbyte Writepowerport_adr 'send slave address
'I2cwbyte 1 'send address of EEPROM
'I2cwbyte 3 'send a value
'I2cstop
'Print "I2c gelesen, Wert1:" 'generate stop
'Print X
'I2creceive &H74 , X
Print "X ="
Print X

'I2csend &H74 , &B11000010
'Waitms 10000

'I2creceive &H74 , X
Print "Con ="
Print Con

Print "Y ="
Print Y

'Con = 0


'I2csend &H74 , 01000010 'wait 10 mS because that is the time that the chip needs to write the data
'Print "1000ms gewartet"
'
'
'I2cstart
'I2cwbyte Writepowerport_adr
'I2cwbyte 1
'I2cstart
'I2cwbyte Readpowerport_adr 'generate repeated start
'I2crbyte X , Nack
'I2cstop
'Print "I2c gelesen, Wert2:"
'Print X
'If X = 12 Then Goto Test
'I2creceive Readpowerport_adr , X
'Print "I2c READPORT gelesen, Wert:"
'Print X


Goto Wiederhole


Sub Rnb_servob(byval Servonummer As Byte , Byval Position As Integer)
Open "comd.7:9600,8,n,1" For Output As #2
Print #2 , "#s" ; Chr(servonummer) ; Chr(position)
Close #2
End Sub

End