nxt and arduino i2c help

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
Post Reply
photon-1
Posts: 14
Joined: 02 Dec 2010, 14:29
Location: London, Uk
Contact:

nxt and arduino i2c help

Post by photon-1 »

Hi,
I was wandering if anyone could help with making an I2C connection between the nxt and arduino.

I know mattallen37 already wrote a library for it but I thought it was a bit too complicated for what I think should be a simple? task of sending information from the nxt and recieving it on the arduino via I2C, especially since the wire library has already been written for such a purpose.
http://mattallen37.wordpress.com/arduino-libraries/

So here is my attempt to perform a simple? master send, slave receive operation.

I have used the 82k resistors required for the sda and scl lines and I used port 1 on the nxt.

I have borrowed code from these examples which show communication between 2 arduinos, and tried to recreate the master arduino code in nxc;
http://arduino.cc/en/Tutorial/MasterReader
http://arduino.cc/en/Tutorial/MasterWriter

I got a bit confused along the way as to how to use some of the functions. I have put some of my questions and problems within stars in the code ******* but I'll repost them here;

1. which of the statements/groups of statements below is best or correct to use in this case?
SetSensorLowspeed(S1);
// this sets the specified port to SENSOR_TYPE_LOWSPEED_9V, so I assume I shouldn't use it since I didnt connect to the 9v line on the nxt?
OR
SetSensorLowspeed(S1, false);
// I assume the false in the above statment just means, I didn't connect the arduino to the 9V line so I'm not using 9v to power it?
OR
SetSensorType(S1, SENSOR_TYPE_LOWSPEED);
SetSensorMode(S1, SENSOR_MODE_RAW);
ResetSensor(S1); // must do this if you change a sensor type or mode

2. when using I2CWrite;
what is the device register for arduino I2C communication? I did find something about TWI being the register but I believe I need a value for its address or something so I can input it here?
anyways, for now I just put 0 and this leads to the following;
this doesn't work:
byte outbuffer[]={2, 0, 1}; // device address = 2, device register = 0 (dont know what it should be), data to send = 1
rtncode1=I2CWrite(S1, 0, outbuffer);
// I get the error; error parsing expression: outbuffer
// considering this is what the API reference says we should do, why doesn't it work?

BUT this compiles fine, why?:
rtncode1=I2CWrite(S1, 0, 1)

NXC CODE

Code: Select all

int rtncode1;
int rtncode2;
sub send_data();
task keep_alive();
task do_stuff();

task main()
{
  //schedule tasks
  Precedes(keep_alive,do_stuff);

 //******question; which of the statements/groups of statements below is best or correct to use in this case?******
 //initialise arduino port
 //SetSensorLowspeed(S1);         // this sets the specified port to SENSOR_TYPE_LOWSPEED_9V,
                                  // I think it also uses the default mode as RAW
                                  // it calls ResetSensor to perform the InvalidDataField reset loop
 // OR
 // SetSensorLowspeed(S1, false);
 // OR
  SetSensorType(S1, SENSOR_TYPE_LOWSPEED);
  SetSensorMode(S1, SENSOR_MODE_RAW);
  ResetSensor(S1);  // must do this if you change a sensor type or mode

  Wait(6000);       // wait a little 6 secs for the arduino to be ready to start receiving
  TextOut(0, LCD_LINE1, "nxt ready");
}

task keep_alive()
{
 while(1)
 {
  //do nothing
 }
}

task do_stuff()
{
 //byte outbuffer[]={2, 0, 1};   // *******problem; what is the device register for writing datat to the arduino?
 send_data();                  // I just put 0 because i didn't know what else to put
}                              // device address = 2 and data to send = 1*********

sub send_data()
{
 TextOut(0, LCD_LINE2, "sending");

 //rtncode1=I2CWrite(S1, 0, outbuffer);  // ******problem, I'm not sure how to use IsCWrite because; it gives the error;
                                       		      // error parsing expression: outbuffer****
 rtncode1=I2CWrite(S1, 0, 1)           // ******this compiles fine, why??******
 rtncode2=I2CCheckStatus(S1);

 NumOut(0, LCD_LINE3, rtncode1);
 NumOut(0, LCD_LINE4, rtncode2);
}
result of running the above code:
nxt ready
sending
0
32

ARDUINO CODE

Code: Select all

#include <Wire.h>
#define LEDpin 13                 // Built in LED

void setup() 
{
  Serial.begin(9600);             // start serial for output
  pinMode(LEDpin, OUTPUT);        // initialize LED pin
  blinkLED13();                   // blink built in LED to indicate the program has booted
                                  // also gives time 3 secs for nxt to initialise port for I2C
  Wire.begin(2);                  // join i2c bus with address #2
  Wire.onReceive(read_data);      // register event
  Serial.println("Arduino ready");
}

void loop()
{
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void read_data(int howMany)  // **not sure what the point of howMany is?**
{
 Serial.println("receiving");
 
 int x = Wire.read();        // receive data
 Serial.println(x);          // print the data
}

void blinkLED13()
{
  digitalWrite(13, LOW);          // set the LED off
  delay(1000);                    // wait for a second
  digitalWrite(LEDpin, HIGH);     // set the LED on
  delay(1000);                    // wait for a second
  digitalWrite(13, LOW);          // set the LED off
  delay(1000);                    // wait for a second
}
result of running the above code:
LED blinks
Arduino ready

Clearly the read_data function never runs and the arduino doesn't recieve anything
photon-1
Posts: 14
Joined: 02 Dec 2010, 14:29
Location: London, Uk
Contact:

Re: nxt and arduino i2c help

Post by photon-1 »

thanks in advance for any help you can give.
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: nxt and arduino i2c help

Post by mattallen37 »

My Arduino library creates a register system. It certainly isn't necessary for NXT > Arduino communications, but I find it very useful.

Remember that the address for the wire library uses bits 0-6, and NXC uses bits 1-7. So, address 0x02 on the arduino would be address 0x04 in NXC (although IIRC my NXTI2C arduino library automatically multiplies the address by 2 so that they match).
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
pepijndevos
Posts: 175
Joined: 28 Dec 2011, 13:07
Location: Gelderland, Netherlands
Contact:

Re: nxt and arduino i2c help

Post by pepijndevos »

photon-1 wrote:I have used the 82k resistors required for the sda and scl lines and I used port 1 on the nxt.
Wait, what? I thought these where supposed to be 4.7K pullups?
-- Pepijn
http://studl.es Mindstorms Building Instructions
photon-1
Posts: 14
Joined: 02 Dec 2010, 14:29
Location: London, Uk
Contact:

Re: nxt and arduino i2c help

Post by photon-1 »

Thanks mattallen37. I will try to go through your library and example to try and understand it and use it, although, it would be useful if you had some nxt code to go with the arduino code.

It would be easier though, if I could understand the basic operations required for the communication so that I could ask for general help as opposed to coming back to matt everytime I can't get something to work with his library.

So if anyone can help with the code I was trying to write, that would be very useful.
pepijndevos wrote:
Wait, what? I thought these where supposed to be 4.7K pullups?
From the research I've done, I've only seen people use either 82k or 33k. Lego recommend 82k but I think because the arduino has built in ones, some people experiment with lower values altough I'm not entirely sure if thats why.

Thanks.
mattallen37
Posts: 1818
Joined: 02 Oct 2010, 02:19
Location: Michigan USA
Contact:

Re: nxt and arduino i2c help

Post by mattallen37 »

As for the value of the pullups, they should be around 82k. On most I2C buses you would use 2k2 to 10k, but the NXT has "protection" resistors that make it necessary to use pullups with a much higher resistance. If you used something like 4k7, the NXT wouldn't be able to pull the lines low enough.

As for my library, all you have to do is run the setup function. After that is done, you can access the "registers" by reading from or writing to the "I2CBuf" array.

As for the NXT side you just read and write like with any other I2C slave, except you always must give the length (address, register, length, data 1, data 2 ... data n).

Attached is my NXC I2C library, which includes functions for reading from and writing to an Arduino using my library.
MyI2C lib.nxc
(2.07 KiB) Downloaded 310 times
Matt
http://mattallen37.wordpress.com/

I'm all for gun control... that's why I use both hands when shooting ;)
photon-1
Posts: 14
Joined: 02 Dec 2010, 14:29
Location: London, Uk
Contact:

Re: nxt and arduino i2c help

Post by photon-1 »

thanks alot matt...

after looking at your nxc library I figured out what I was doing wrong with my code. I haven't programmed in a while so I made some mistakes; in particular I didn't pass the buffer to the function i used to send the data and i didn't even design the function to recieve the buffer. I sorted that out and was able to get a message across to the arduino successfully.

However, my buffer only has 2 values;

byte outbuffer[]={4, 1}; where 4 = the arduino address and 1 = the value I'm sending.
i.e. I'm using the function like so;
byte outbuffer[]={byte address, byte data[]}

This is sufficient for my purposes for now however I am curious as to how to use the register parameter. i.e.

byte outbuffer[]={byte address, byte register, byte data[]}

I suspect I would get the answer if I go through your arduino library in detail but if you could give a quick explanation as to why you would even want to use registers in the first place?

Thanks.
photon-1
Posts: 14
Joined: 02 Dec 2010, 14:29
Location: London, Uk
Contact:

Re: nxt and arduino i2c help

Post by photon-1 »

aahh never mind, I think I have the answer to my question; my guess is you could have a register for different devices connected to the arduino which would make them a bit easier to manipulate.

Thanks ALOT for the help anyways.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest