I2C SCl frequency

This is where you talk about the NXJ hardware related topics such as the brick, sensors, LEGO pieces, etc.

Moderators: 99jonathan, roger, imaqine

I2C SCl frequency

Postby jgiacomo » Tue May 13, 2008 8:17 am

Hi everybody;

I want to add some sensors which need I2C communication. I can see that the SCL frequency is by 10KHz when I use the Multi-Sensitivity Acceleration Sensor or a RFID reader.

How can I do if I want to work on a sensor which has a SCL frequency by 100Khz ?

Thanks for any answer...
$ John.N-Y $
jgiacomo
New User
 
Posts: 21
Joined: Tue Apr 08, 2008 7:16 am

Postby gloomyandy » Tue May 13, 2008 9:45 pm

Hi,
I think the actual speed is 9600! Unfortunately that is what you are stuck with... The i2c implementation in the NXT is a software only one (actually it is driven by one of the hardware timers), which makes it tricky to operate at high speed. It may be possible to increase the speed but this may stop existing devices from working! I don't have access to any high speed i2c devices so I don't have any real way of testing this... Does the device have to operate at this speed? Most i2c devices are clocked by the master (in this case the nxt).....

All the best

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3893
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Postby jgiacomo » Wed May 14, 2008 7:05 am

Thank y ou for your answer Andy.

I've made tests on a RFID reader but it doesn't work with the NXT: there is no acknowledge by the slave to the master after the REQB command.

So, I used a software to test the RFID reader (which runs perfectly) and tried to see on an oscilloscope what was send on SDA: I send exactly the same thing from the NXT to the RFID reader.

The only difference I saw was the SCL frequency (as I wrote on the previous post).

So that's why I thought that the reason why the RFID doesn't work is the SCL frequency.

But, when I read the documentation on the RFID (060132-1 by elektor), it seems to work with the SCL frequency of the NXT.
$ John.N-Y $
jgiacomo
New User
 
Posts: 21
Joined: Tue Apr 08, 2008 7:16 am

Postby gloomyandy » Wed May 14, 2008 7:45 am

Hi,
Interesting... Is the request that you are having problems with an i2c read or a write? One thing that is a little odd about the Lego i2c implementation is that on read requests an extra stop operation is inserted when peforming a read request. This seems to be required by the Lego ultrasonic sensor but is not standard i2c. It could be that this is causing you a problem. Also which sensor port are you using? You may want to avoid port 4 as this has extra hardware attached to it which may upset some devices. If you can capture anything odd happening on a scope I'll try and work out what is going on.

It is possible that the device just does not like operating at this low speed...

Oh one other thing have you tried talking to the device using the standard Lego firmware?

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3893
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Postby jgiacomo » Wed May 14, 2008 7:58 am

Thank you again for your answer Andy.

I'm having problem with I2C write, I use port 1 and I only talk with the leJOS firmware.

Here is the Java class of my RFID:

Code: Select all
package lejos.nxt;

/**
 * Test for a RFID sensor
 * using I2C protocol
 *
 */
public class RFIDSensor extends I2CSensor {
   byte[] buf = new byte[1];
   byte[] buf2 = new byte[2];
   
   private static byte I_O_FRAME = 0x01;   
   
   
   
   //CRC_B sur deux octets est calculé automatiquement
   
   
   public RFIDSensor(I2CPort port)
   {
      super(port);
      port.setType(TYPE_LOWSPEED_9V);
      super.setAddress(0x50);
      
   }
   
   public int set_rfid_APf(byte valeur) {      
      buf[0] = valeur;
      int ret = sendData(I_O_FRAME,buf, 1);
      return ret;
   }
   
   public int set_rfid_AFI(byte valeur) {      
      buf[0] = valeur;
      int ret = sendData(I_O_FRAME,buf, 1);
      return ret;
   }
   
   public int set_rfid_PARAM(byte valeur) {      
      buf[0] = valeur;
      int ret = sendData(I_O_FRAME,buf, 1);
      return ret;
   }
   
   public int getSthg() {      
      int ret = getData(I_O_FRAME, buf, 1);      
      return ret;
   }
   
   /*
   public int get_rdif_flag() {      
      int ret = getData(GET_RFID_FLAG, buf, 1);   
      return ret;
   }
   
}



And here the test:

Code: Select all
import lejos.nxt.*;

public class TestRFID{

   private static byte APf = 0x05;
   private static byte AFI = 0x00;
   private static byte PARAM = 0x00;
   
   public static byte [] buf = new byte[1];
   
    byte reply=0;
    int rfid_tag;

   public static void main(String[] args) throws Exception {
      RFIDSensor RFID = new RFIDSensor(SensorPort.S1);
      
      RFID.set_rfid_APf(APf);
      RFID.set_rfid_AFI(AFI);
      RFID.set_rfid_PARAM(PARAM);

      while(!Button.ESCAPE.isPressed()) {   
         
         // reply=RFID.new_rfid_data();
         // if(reply){      
            
         
            int ret=RFID.getData(0x01,buf,1);
            LCD.drawString("RFID Tag:",4, 0);
            LCD.drawInt(ret, 6,5,1);
            //LCD.drawInt(3, 8, 2);
            LCD.drawString("Test:",1, 3);
            LCD.drawInt(RFID.getSthg(), 3, 4);
            LCD.refresh();
            Thread.sleep(500);
      }
      
   }

}

I've no answer from the slave.

When I read the SDA I see on the scope the 0x50 address. But no ACK...

Is it really a low speed problem? ..

Thanks for help.
Last edited by jgiacomo on Wed May 14, 2008 10:08 am, edited 1 time in total.
$ John.N-Y $
jgiacomo
New User
 
Posts: 21
Joined: Tue Apr 08, 2008 7:16 am

Postby gloomyandy » Wed May 14, 2008 9:53 am

Hi,
A couple of questions....

Have you got the address right? 0x50 is an unusual i2c device address they are normally smaller numbers. 0x50 sounds more like an internal register address. If you can point me at a spec for the device on the web I can check this. The setAddress call sets the device address, the internal register addresses to read/write are what you pass into the sendData call.

Are you sure you want to set the type as TYPE_LOWSPEED_9V. This will supply 9V on the power out pins from the nxt. Most devices will need 5V not 9V..... The only device I know of that needs this is the Lego Ultrasonic sensor, which uses the 9V supply to drive the Ultrasonic transducer....

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3893
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Postby jgiacomo » Wed May 14, 2008 10:03 am

I've set the type as TYPE_LOWSPEED but it didn't work. so, I changed it to TYPE_LOWSPEED_9V.

But you're right, I've to set the type as TYPE_LOWSPEED.

Here you can find the documentation of my RFID reader:

http://www.alldatasheet.com/datasheet-p ... /CR14.html

or here:

www.st.com/stonline/products/literature/ds/11922.pdf

I hope this will help you.
$ John.N-Y $
jgiacomo
New User
 
Posts: 21
Joined: Tue Apr 08, 2008 7:16 am

Postby Chrigi » Wed May 14, 2008 4:56 pm

Hi,

I'm working on a class for the RFID Sensor from http://www.codatex.com/. Actually I can read one Byte from the Sensor, but getVersion, getProductID and other things doesnt work.

Here is my code for that. The comment is in german, but I can translate it for you if you want?
Perhaps its help you.

Code: Select all
import lejos.nxt.*;
/**
 *
 * @author Christian Käslin
 * Class for RFIDSendor
 */
public class RFIDSensor extends I2CSensor{

   byte[] buf = new byte[1]; //buffersize 1 byte for Data from Sensor
   private static final byte hardwireAddress = 0x02; //Eigentlich 4 aber in Lejos ist es 2
         
   /**
    * Constructor for RFIDSensor
    * @param port Portnumber at NXT
    * @throws InterruptedException
    */
   public RFIDSensor(I2CPort port) throws InterruptedException {
      super(port);
      this.setAddress(hardwireAddress);
      port.setType(port.TYPE_LOWSPEED_9V);
      port.setMode(port.MODE_RAW);
   }
   
   /**
    * getStatus  Funktioniert noch NICHT!
    * @return
    */
   public int getStatus()
   {
      getData(0x32, buf, 1);
      
      return buf[0];
   }
   
   /**
    * Funktion zum lesen der Transponder Nummern
    *
    * Funktioniert zum Teil: Es kann nur ein Byte ausgelesen werden.
    * Die anderen werden danach gelöscht.
    * @return
    */
   public String read()
   {
      String transNr = "";
      this.sendData(0x41, (byte) 0x01);
      try {
         Thread.sleep(250);
      } catch (InterruptedException e) {
      }
      
         getData(0x42,buf,1);
         transNr += decimalToHex(buf[0]);
         /*getData(0x43,buf,1);
         transNr += decimalToHex(buf[0]);
         getData(0x44,buf,1);
         transNr += decimalToHex(buf[0]);
         getData(0x45,buf,1);
         transNr += decimalToHex(buf[0]);
         getData(0x46,buf,1);
         transNr += decimalToHex(buf[0]);*/
      
      return transNr;
   }
   
   public static String decimalToHex(int number){
      int remain=0;
      String output="";
      while(number > 15){
      remain = number % 16;
      output = output + translate(remain);
      number = number / 16;
      }

      output += translate(number);
      char[] hex = output.toCharArray();
      
      String transponderHex;
      
      if(hex.length == 2)
      {
         transponderHex = ""+hex[1]+""+hex[0];
      }
      else
      {
         transponderHex = "0"+hex[0];
      }

      return transponderHex;
      }

      public static String translate(int digit){
      if(digit==10)
      return "A";
      else if(digit==11)
      return "B";
      else if(digit==12)
      return "C";
      else if(digit==13)
      return "D";
      else if(digit==14)
      return "E";
      else if(digit==15)
      return "F";
      else return "" + digit;

      }

}


And here is the use.

Code: Select all
import lejos.nxt.*;


public class RFID {

   /**
    * @param args
    */
   //main Method
   public static void main(String[] args) throws InterruptedException  {
      
      //RFIDSensor initialisieren
      RFIDSensor rfid = new RFIDSensor(SensorPort.S1);
      
      //Status abfragen, funktioniert noch NICHT!!!
      LCD.drawInt(rfid.getStatus(), 1, 1, 1);
      
      //Transponder Lesen
      LCD.drawString(rfid.read(), 1, 3);
      LCD.drawString("RFID Transponder", 1, 1);
      Thread.sleep(2000);      
   }
}
Chrigi
New User
 
Posts: 10
Joined: Sun Jul 01, 2007 4:46 am

helllo

Postby gloomyandy » Wed May 14, 2008 8:46 pm

Hi,
I've had a quick look at the specs and it looks to me as if the addresses that you are using are ok. However I'm not sure that you are writing the data to the device in the correct format. It seems to me that when you write data to the device I_O_BUFFER then the format of the data needs to be
<data len n><byte 1><byte 2><byte n>
Also all of the bytes that make up a command must be sent in a single i2c write operation. So they all need to be sent using a single sendData call.

From what I can see this device should work with the nxt. But yhe way this device uses i2c is different from the other Lego sensors I've used, so it may be more sensitive to the way the nxt does i2c. However trying to work out what may be going wrong without having access to the device is rather tricky so I probably can't help much more.

Hope this helps

Andy
User avatar
gloomyandy
leJOS Team Member
 
Posts: 3893
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

thanks

Postby jgiacomo » Sat May 17, 2008 8:15 am

Thank you all for your answer. You don't need to translate Chirigi, it's OK. I will follow your advices on Monday.
I'll tell you my progress.

Thank you again.

Best regards.
$ John.N-Y $
jgiacomo
New User
 
Posts: 21
Joined: Tue Apr 08, 2008 7:16 am


Return to NXJ Hardware

Who is online

Users browsing this forum: No registered users and 2 guests

more stuff