# USB-I2C Adapter JAVA problem



## Bega (21. Jun 2010)

Guten tag. Ich bin grade dabei bezüglich meiner Präsentationsprüfung morgen ein Programm zu schreiben.
Mein Thema ist (quasi) Kommunikation Zwichen Java und einer Seriellen Schnitstelle. Desswgen habe ich mir ein I2c Servo interface und einen passenden USB Adapter dazu bestellt.
Ich habe bisher mit der java comm und der RXTX Bibliothek versucht eine Verbindung aufzubauen, das gelang mir auch. Aber etwas hinzuschicken, wirklich ansprechen konnte ich ihn nochnicht. 
Ich wende mich an euch weil ich das programm heute noch fertig bekommen wollte. (auch wenn es nicht unbedingt Ausschlaggebend für meine note sein wird.)
ich zeig euch hier mal meinen code mit RXTX, vlt findet ihr ja schon auf anhieb etwas falsches:

```
import gnu.io.*;
import java.io.IOException;
import java.io.OutputStream;

public class RXTX {

	int baudrate = 19200;
	int dataBits = SerialPort.DATABITS_8;
	int stopBits = SerialPort.STOPBITS_2;
	int parity = SerialPort.PARITY_NONE;

	public RXTX() {
	}

	public void connect(String portName) throws NoSuchPortException, PortInUseException, IOException, UnsupportedCommOperationException {
		//Port checken
		CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
		System.out.println();
		if (portIdentifier.isCurrentlyOwned()) {
			System.out.println("Error: Port ["+portName+"] is currently in use");
			return;
		} else {
			System.out.println("Success: Port ["+portName+"] is ready");
		}
		//Connect
		SerialPort serialPort = (SerialPort)portIdentifier.open(this.getClass().getName(), 2000);
		OutputStream outputStream = serialPort.getOutputStream();
		serialPort.setSerialPortParams(baudrate, dataBits, stopBits, parity);
		outputStream.write(new byte[]{(byte)0x00});
		serialPort.close();
	}

	public static void main(String[] args) throws NoSuchPortException, PortInUseException, IOException, UnsupportedCommOperationException {
		RXTX rxtx = new RXTX();
		rxtx.connect("COM2");
	}

}
```
Hier noch das Datenblatt des adapters:
http://www.roboter-teile.de/datasheets/usb2i2c.pdf
(das beigelieferte programm kann den Adapter ansprechen was man dann an einer Grünen LED sieht die blinkt bei Datentransfer, desswgen gehe ich davon aus dass, das problem in meinem java code liegt.)

wäre erfreut über eure hilfe, mfg patrick


----------



## tuxedo (21. Jun 2010)

Sehe so spontan keinen Fehler. 
Du sendest ein 0x00 byte... Mehr nicht. Wenn du Infos lesen und schreiben willst, solltest du dir die Befehler dieses Adapters mal genau ansehen. In der Doku ist zu lesen:



> Commands
> The USB-I2C responds to commands sent to it from the PC. There are just three primary
> commands:
> I2CD_CMD (0x53) - This allows you to read or write to I2C devices that do not have
> ...



0x00 steht da nicht dabei. Ich geh mal davon aus dass du schlicht und ergreifend ddie falsche/eine unvollständige Sequenz sendest und gar nix zurück liest...

Was hast du erwartet was passiert wenn du nur 1 byte sendest und dann die Verbindung wieder trennst?

- Alex


----------



## Bega (21. Jun 2010)

Es kam weder eine exception noch eine Reaktion am Adapter. Habe es natürlich auch schon mit anderen zahlen probiert (z.b. 0x01).
Könntest du mir ein Beispiel geben, was ich senden muss, um z.b. die Rote LED aus und ein zu schalten.
Der befehlt ist auf seite 6 zu finden. Bin ehrlich gesagt grad etwas ratlos in der Angelegenheit was ich ihm genau schicken muss damit er reagiert bzw einen befehl aufnimmt.
mfg


----------



## tuxedo (21. Jun 2010)

??? Aber lesen kannst du? Und du weißt auch was I2C ist? Hast du ein I2C Device am Adapter angeschlossen?

Ich geh mal davon aus dass du keins dran hast. Dann kannst du nicht viel tun. Laut Doku würde mit folgender Sequenz die Revision der Firmware des I2C Adapters abfragen:

0x5A für das einleiten eines USB-I2C Commands
0x01 für das Abfragen des Revision
0x00 einfach ein leeres byte
0x00 einfach ein leeres byte

Antwort:

1 einzelnes Byte das die Revision der Firmware wiederspiegelt.

Man kann anscheinend auch die rote LED des Adapters ausschalten und die I/O Leitungen als digitale Eingänge benutzen:

0x5A für das einleiten eines USB-I2C Commands
0x10 Sets I/O pins high/low
0x0E Steuerbyte
0x00 einfach ein leeres byte

Als Antwort wird hier auch ein byte zurück kommen.

Genaueres findet sich in der von dir verlinkten Doku. So, mehr lese ich für dich jetzt nicht. --> RTFM :rtfm:

- Alex


----------



## dhachim (21. Jun 2010)

Uff, wenn dein Thema nicht Java wäre, würde ich dir jetzt zu C oder Dasic raten  
Aber wie Tuxedo schon geschrieben hat, 0x00 bewirkt nix, wenn du es schickst. 

Im Umgang mit Hardware muss man erst mal lernen, die Datenblätter zu lesen, und zu verstehen. 
Aber spannend isses allemal. Wenn du fertig bist mit dem Projekt würde mich das Ergebnis interessieren. 
Hab mit Java noch nix gemacht in dem Bereich.


----------



## Bega (21. Jun 2010)

Nochmals vielen Dank für die Antworten.

Der von mir oben gepostete Java Code funktioniert also einwandfrei (bis auf den Inhalt des byte[]-arrays, hier müsste rein: (byte)0x5A,(byte)0xC2,(byte)0x0E,(byte)0x00 -> Rote LED aus), das einzige Problem war die Ansprechung mit dem 0x5A. Tuxedo, hast recht. Lesen sollte gelernt sein, leider sind meine Englischkenntnisse nich ausreichen um das komplette Datenblatt zu verstehen und daher hast du mir mit deinen Beispiel sehr weitergeholfen (vielleicht war ich aber auch nur zu unkonzentriert, bis morgen musst das ganze stehn) - Die rote LED war danach aus.

Dhachim, das Java Projekt soll später ein "ferngesteuertes" Auto steuern, desswegen werde ich die Klasse noch in die richtigen Eventhandler einbinden und fertig.

Nun gibt es allesdings ein neues Problem:
An meinem I2C Bus hängt ein SD21 (Servocontroler mit I2C Interface), mir ist aus dem Datenblatt allerdings nicht ersichtlich, wie man dies genau ansteuert. Ich würd wenn es nicht allzu viel umstände macht, euch bitten, nochmals in das Datenblatt zu gucken und mir zu sagen mit welchen anweisungsparametern man den Servo befehligt. Aus den Datenblättern kann ich leider nicht herausfinden, ob man nun dennoch den 0x5A Befehl benutzen muss oder nicht.
Aktuell habe ich es mit (byte)0x5A,(byte)0xC2,(byte)63,(byte)63 probiert (Verzweiflungstat).
C2 steht im Datenblatt der Servosteuerung: http://www.roboter-teile.de/datasheets/sd21.pdf

Ich hoffe es ist nicht zu viel arbeit, mir hilfe es.

Danke, Bega


----------



## dhachim (22. Jun 2010)

okay lets have a look inside.
Using the I2C Bus 

http://www.robotikhardware.de/download/sd21.pdf hilft beim Verstehen. 

zuerst: 0x55


> I2C_CMD (0x55) - This allows you to read or write to internally registered devices such as
> EEPROM's or our own range of modules.


Dann ist wichtig: 0xC2 (wohin willst du schreiben)


> Address
> The SD21 Servo module is located at address 0xC2 on the I2C bus.



nun Welches Servo/ Byte:
(#Servo*3) -2  

dann wieviele Bytes will man senden:
0x02

Was soll geschrieben werden:
(byte) (ServoPosition & 0xff)  Lowbyte der Position
(byte) (ServoPosition >>8) HighByte der Position


Also:

```
byte[0]=0x55;
byte[1]=0xC2;
byte[2]=(int #Servo*3) -2 ;
byte[3]=0x02;
byte[4]=(byte) (int ServoPosition & 0xff)
byte[5]=(byte) (int ServoPosition >>8)
```
sollte es tun. Natürlich ohne Gewähr.


----------

