0.8.1 Arduino I2C Integration doubt

This is where you talk about the EV3 software itself, installation issues, and programming talk.

Moderators: roger, gloomyandy, skoehler

0.8.1 Arduino I2C Integration doubt

Postby esmetaman » Fri May 16, 2014 10:45 pm

Hi,

Recently, Dexter published a LEGO block to communicate with an Arduino board in a easy way. I was testing without any problem and I tried to port the example to LeJOS, but I couldn't.

LEGO Example:

Image

I connect with an I2C device with address: 0x04 in Arduino Side, 4 in LEGO Side.

The Arduino Sketch doesn't use a complex code if you surf on internet to learn to use I2C in Arduino board:

Code: Select all
#include <Wire.h>

#define SLAVE_ADDRESS 0x04
void setup()
{
    Serial.begin(9600);         // start serial for output
    Wire.begin(SLAVE_ADDRESS);
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);
    Serial.println(SLAVE_ADDRESS);
    Serial.println("Ready!");
}
int val,flag=0,index=0;
uint8_t c[]="DEXTERIN";
char buf[8];

void loop(){
}

void receiveData(int byteCount){
    while(Wire.available()>0){
      val=Wire.read();
     
      Serial.print("Reveving...");
      Serial.println((char)val);
      flag=1;
    }
}

// callback for sending data
void sendData(){
  Wire.write(c,8);
  Serial.println("Sending...");
}


In this example if I use the LEGO Block, I see in Arduino Serial monitor a normal output:

Code: Select all
    4
    Ready!
    Reveving...A
    Sending...
    Sending...


So, the hardware side is OK.

Then I did a simple Class to communicate with an Arduino in EV3 but I am having some problems because the brick doesn't connect with the Arduino.

Code: Select all

import lejos.hardware.port.SensorPort;
import lejos.hardware.sensor.I2CSensor;
import lejos.hardware.sensor.SensorConstants;

public class Main {

   static int I2CSlaveAddress = 4;
   static final byte REG_ARDUINO = (byte) 0x20;
   static byte[] buffReadResponse = new byte[8];
   
   public static void main(String[] args) throws InterruptedException {
      
      System.out.println("Arduino Connection Test");
      
      I2CSensor Arduino = new I2CSensor(SensorPort.S1,
            I2CSlaveAddress,
            SensorConstants.TYPE_LOWSPEED);
      
      Thread.sleep(500);

      //Writing
      Arduino.sendData(REG_ARDUINO, buffReadResponse,1);
      
      byte value = 65;
      Arduino.sendData(REG_ARDUINO, value);
      
      System.out.println(buffReadResponse[0]);
      System.out.println(buffReadResponse[1]);
      System.out.println(buffReadResponse[2]);
      System.out.println(buffReadResponse[3]);
      System.out.println(buffReadResponse[4]);
      System.out.println(buffReadResponse[5]);
      System.out.println(buffReadResponse[6]);
      System.out.println(buffReadResponse[7]);
      
      //Reading
      Arduino.getData(REG_ARDUINO, buffReadResponse,1);

      System.out.println(buffReadResponse[0]);
      System.out.println(buffReadResponse[1]);
      System.out.println(buffReadResponse[2]);
      System.out.println(buffReadResponse[3]);
      System.out.println(buffReadResponse[4]);
      System.out.println(buffReadResponse[5]);
      System.out.println(buffReadResponse[6]);
      System.out.println(buffReadResponse[7]);
      
      System.exit(1);
   }
}



I was reading a bit about LeJOS addresses in I2C, and I am not sure where is the problem. I read some stuff about I2C addresses in LeJOS:

Code: Select all
setAddress

@Deprecated
public void setAddress(int addr)
Deprecated. If the device has a changeable address, then constructor of the class should have an address parameter. If not, please report a bug.
Set the address of the port Addresses use the standard Lego/NXT format and are in the range 0x2-0xfe. The low bit must always be zero. Some data sheets (and older versions of leJOS) may use i2c 7 bit format (0x1-0x7f) in which case this address must be shifted left one place to be used with this function.
Parameters:
addr - 0x02 to 0xfe


and I discovered that some projects connect with I2C devices using this way:

http://trandi.wordpress.com/2010/10/18/nxt-lejos-nunchuck/

Code: Select all
private static final int NUNCHUCK_ADDR = 0x52; // 7bit addressing.  It would be 0xA4 in 8bit


But Wire library in Arduino has:

Code: Select all
There are both 7- and 8-bit versions of I2C addresses. 7 bits identify the device, and the eighth bit determines if it's being written to or read from. The Wire library uses 7 bit addresses throughout. If you have a datasheet or sample code that uses 8 bit address, you'll want to drop the low bit (i.e. shift the value one bit to the right), yielding an address between 0 and 127.


http://arduino.cc/en/reference/wire

and at the moment, I can't connect, but I think that it is something related with the Address.

Any help to connect using LeJOS?

Many thanks in advance.

Cheers

Juan Antonio
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
https://github.com/jabrena/livingrobots
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 302
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Re: 0.8.1 Arduino I2C Integration doubt

Postby gloomyandy » Sat May 17, 2014 12:31 pm

Did you try doing what the leJOS comment tells you to do? That is if you have a 7bit address (which it looks like you may have) shift it one bit left (so use an address of 8). What happens then? Also your leJOS code does not seem to match the EV3 code you have. Your leJOS code will perform two writes to the device before issuing a read (the first write will send a byte 0, the second 65), the EV3 code will send just 65, is this what you intend?
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4187
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: 0.8.1 Arduino I2C Integration doubt

Postby lawrie » Sat May 17, 2014 2:33 pm

Hi Juan Antonio,

The Arduino uses 7 bit addresses and the EV3 (and NXT), 8-bit addresses, so if you use address 4 on the Arduino, you should use 8 on the EV3. Also you should use getData to send a byte and receive the response.

So here is a program that works with your Arduino sketch:

Code: Select all
import lejos.hardware.Button;
import lejos.hardware.port.SensorPort;
import lejos.hardware.sensor.I2CSensor;

public class Main {
   static int I2CSlaveAddress = 8;
   static byte[] buffReadResponse = new byte[8];
   
   public static void main(String[] args) throws InterruptedException {   
      System.out.println("Arduino Connection Test");
      I2CSensor arduino = new I2CSensor(SensorPort.S1, I2CSlaveAddress);
     
      while (Button.ESCAPE.isUp()) {
         int id = Button.waitForAnyPress(); 
         if (id == Button.ID_ENTER) { 
            arduino.getData('A', buffReadResponse, buffReadResponse.length);
            System.out.println(new String(buffReadResponse));
         }
      }
      arduino.close();
   }
}


Here is the output from the console:

Code: Select all
4
Ready!
Reveving...A
Sending...


and from the EV3 program:

Code: Select all
Arduino Connection Test
DEXTERIN


I think I will write a blog entry on doing this.

Are you using the Dexter industries Breadboard connector for connecting to the Arduino? I am using half an EV3 cable, some terminal strip, and a couple of 82k resistors.

The EV3 powers the Arduino fine without the USB plugged in, if you do not need the serial console output.
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Re: 0.8.1 Arduino I2C Integration doubt

Postby esmetaman » Sat May 17, 2014 3:05 pm

Hi Lawrie,

Many thanks for the help. The new code run nice.

How to calculate the address for next time?

If I have a I2C Device with address 0x04 how to know that the real value is 8?
I would like to learn that technique. I suppose that it is easy, but I don't know. :)

but fortunately, I know a good address for experiments (leJOS->8 | Arduino-> 0x04)

Yes, it is a very good topic to write in the Blog. On internet exist many references for NXT but for EV3, it is rare topic. Maybe, this is the first example for leJOS on EV3.

Anyway, Although we have this way to integrate a Arduino development with LeJOS, we have pending another natural way... USB side, but... I think to solve some Kernel issues. :)

The for Arduino I use the following combo:

    Arduino One
    Arduino Proto Shield
    Dexter NXTBreadBoard

Image
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
https://github.com/jabrena/livingrobots
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 302
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Re: 0.8.1 Arduino I2C Integration doubt

Postby lawrie » Sat May 17, 2014 3:14 pm

lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Re: 0.8.1 Arduino I2C Integration doubt

Postby lawrie » Sat May 17, 2014 3:16 pm

How to calculate the address for next time?

If I have a I2C Device with address 0x04 how to know that the real value is 8?


Multiply by 2.
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Re: 0.8.1 Arduino I2C Integration doubt

Postby esmetaman » Sat May 17, 2014 3:21 pm

It is supper easy!

and how to do the following calculus?

address = 4 but in Arduino is 0x04. How to calculate the step from 4 to 0x04?

What is the address limit?
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
https://github.com/jabrena/livingrobots
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 302
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Re: 0.8.1 Arduino I2C Integration doubt

Postby esmetaman » Sat May 17, 2014 3:32 pm

Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
https://github.com/jabrena/livingrobots
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 302
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Re: 0.8.1 Arduino I2C Integration doubt

Postby lawrie » Sat May 17, 2014 3:36 pm

address = 4 but in Arduino is 0x04. How to calculate the step from 4 to 0x04?

What is the address limit?


Decimal 4 and hex 4 are the same number!!!

The limit is 254 for the 8-bit version.
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Re: 0.8.1 Arduino I2C Integration doubt

Postby gloomyandy » Sat May 17, 2014 3:56 pm

7 bit addresses are 1-127 (decimal) 0x01-0x7f (hex), 8 bit addresses are 2 -254 (0x02-0xfe) and 8 bit addresses are always even numbers. It is pretty simple really.
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4187
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: 0.8.1 Arduino I2C Integration doubt

Postby esmetaman » Sat May 17, 2014 8:03 pm

Many thanks Lawrie, Andy.

I recognize that I don't like to operate with bytes. :p

Cheers
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
https://github.com/jabrena/livingrobots
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 302
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Re: 0.8.1 Arduino I2C Integration doubt

Postby esmetaman » Wed May 21, 2014 9:16 pm

Hi,

Continued with the Arduino development and now I can receive Arrays of bytes.
But my question is about number accuracy.

One byte is able to store numbers from 0-255 and this kind of values are quite similar when a EV3 brick uses a US Sensor.
RPLIDAR Sensor handle distances greater than 255 cm (1byte) so, do you know a way to send numbers greater than 255?

Cheers
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
https://github.com/jabrena/livingrobots
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 302
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Re: 0.8.1 Arduino I2C Integration doubt

Postby gloomyandy » Wed May 21, 2014 9:29 pm

You will need to use more than one byte per numeric value and then convert the multiple bytes into a short/int and store it in your array. Take a look at the vsrious leJOS drivers there are lots of examples of doing this.
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4187
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Re: 0.8.1 Arduino I2C Integration doubt

Postby esmetaman » Wed May 21, 2014 9:40 pm

Yes,

I had that idea yesterday but I thought that existed some better way, but in that case, I will use another array in Arduino and later will try to compute in EV3 side.
(It is a bit creative way :D)

Using that way, I have to duplicate the number of I2C calls to receive a complete Array of 360 elements with distances from RPLIDAR.

Currently, I use blocks of 30 bytes, but I think that If y try to send directly and array with a length of 360, I receive the following error:

Code: Select all
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
   at java.lang.System.arraycopy(Native Method)
   at lejos.internal.ev3.EV3I2CPort.i2cTransaction(Unknown Source)
   at lejos.hardware.sensor.I2CSensor.getData(Unknown Source)
   at lejos.hardware.sensor.I2CSensor.getData(Unknown Source)
   at Main3.main(Unknown Source)


What is the maximum dimension to send by I2C with the current implementation?

Cheers
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
https://github.com/jabrena/livingrobots
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 302
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Re: 0.8.1 Arduino I2C Integration doubt

Postby gloomyandy » Wed May 21, 2014 10:15 pm

You can find these sorts of things by looking at the source code. If you look at the EV3 i2c implementation:
https://sourceforge.net/p/lejos/ev3/ci/ ... CPort.java

You will see that it uses a constant IIC_DATA_LENGTH. You will find this defined in:
https://sourceforge.net/p/lejos/ev3/ci/ ... tants.java

Which as you can see is defined as 32 bytes. So assuming you use two bytes per value will require 23 i2c operations to obtain the 360 values. The current i2c implementation on the EV3 will read 32 bytes in approx 40mS so to read all 360 values (with two bytes per value) will take 920mS so one full reading per second.

As an alternative you may want to consider connecting the device as a serial device (I assume that an Arduino has a uart?), and connect to it as a uart sensor. You will obviously have to implement the Lego uart protocol in the Arduino, I'm not sure if anyone has done this yet, but the details of the protocol have been published by Lego and are available here:
https://sourceforge.net/p/lejos/ev3sdca ... 8/d_uart.c

Would be cool to have an implementation for something Arduino. Oh and if you do it you could win a prize:
http://www.dexterindustries.com/ev3bounty.html
User avatar
gloomyandy
leJOS Team Member
 
Posts: 4187
Joined: Fri Sep 28, 2007 2:06 pm
Location: UK

Next

Return to EV3 Software

Who is online

Users browsing this forum: No registered users and 2 guests

more stuff