Jump to content
Sign in to follow this  
pine

I2C Wire library endTransmission() hang

Recommended Posts

Hi All,

 

I am trying to make an Anduino program to work on the MSP430G2553 using Energia. After testing and debugging the problem seems to be stuck at Wire.endTransmission(). I am using the LP, connecting to an RFID reader.

 

LP1.6->SCL

LP1.7->SDA

 

and have the code below for I2C pull up:

 

pinMode(P1_6, INPUT_PULLUP);
pinMode(P1_7, INPUT_PULLUP);
 

 

 

 

The code is

 

 

 

void SL018::transmitData()
{
 Serial.println("Transmitting 1");
 // wait until at least 20ms passed since last I2C transmission
 while(t > millis());
 t = millis() + 20;

 Serial.println("Transmitting 2");
 // remember which command was sent
 cmd = data[1];

 Serial.println("Transmitting 3");
 // transmit packet with checksum
 Wire.beginTransmission(address);
  
 Serial.println("Transmitting 4");
 for (int i = 0; i <= data[0]; i++)
 {
#if defined(ARDUINO) && ARDUINO >= 100
//  Wire.write(data);
#else
//  Wire.send(data);
#endif
  Serial.println("Transmitting 4a");
  Wire.write(data);
  Serial.println("Transmitting 4b");
 }
 Serial.println("Transmitting 5a");
 Wire.endTransmission();
 Serial.println("Transmitting 5b");

 // show transmitted packet for debugging

}

 

 

 

And the debug statement suggested it hang at Wire.endTransmission():

 

 

 

 
checking...
checking...
ending!
Transmitting 1
Transmitting 2
Transmitting 3
Transmitting 4
Transmitting 4a
Transmitting 4b
Transmitting 4a
Transmitting 4b
Transmitting 5a 

?

And then nothing happen. The reader should be working fine as the LED flashed when the tag is near..

 

 

Any help will be much appreciated. Thanks in advance.
 

Share this post


Link to post
Share on other sites

It's not entirly clear to me from looking at the datasheet if the SL018 is a 5v I/O device or not. The Supply voltage is 5v for sure which probably means that the I/O voltage is also 5v if there is no level translator on the board. The schematics that I found on http://www.stronglink-rfid.com/en/rfid-modules/sl018.html seem to indicate otherwise though. Here they connect 5v to VCC of the SL018 and connect the MSP430 directly to the I2C lines without pull-ups or level translator. What you can try is to see if things will start working when you connect the VCC of the module to 5 volt. 5 Volt is available on the test pins next to the USB connector. TP1 is 5V and TP3 is ground.

 

Do not that if the SL018 puts 5 volt on the I2C lines that this might damage the MSP430.

 

Internal pull-ups will not work and cause problems. You will need external pull-ups as per this post here: http://forum.43oh.com/topic/3554-rtc-problem/?p=31724

 

Remove the internal pull-ups on P1.6 and P1.7 by removing the code below from your Sketch.
The schematics of the SL018 pointed to earlier does imply that no pull-ups are required probably since they are already on the module.
 
pinMode(P1_6, INPUT_PULLUP);
pinMode(P1_7, INPUT_PULLUP);

 

Also make sure you specified the right address in Wire.begin(). If all that is fine then it is probably the pull-ups. The reason that it does not hang earlier than Wire.endTransmission();

 

Please report back if you get it to work on not as this will help others on the forum if they come across similar issues.

Share this post


Link to post
Share on other sites

Arduino is 5v I/O and if you power the AT24C64A from the 3.3v then this is the reverse of Launchpad. Launchpad I/O's are 3.3 volt whereas the sensor in pine's case is 5 volt.

The pull-ups are very important. Without them I2C will not work and most of the time it is either a problem with the pull-ups or a voltage mis-match.

 

As long as the AT24C64A is powered from 3.3 Volt and you have external pull-ups (there are no internal pull-ups in the MSP430 for I2C) this should be straight forward.

 

I would start by making sure that you supply the AT24C64A from the VCC pin on the launchpad and that you add a 10k external pull-up on both SDA and SCK.

Share this post


Link to post
Share on other sites

Without any problem's, I used a couple of other devices - BMP085 Barometric Digital Pressure Sensor, HMC5883L Triple Axis Compass, ADXL345 3-Axis Digital Acceleration of Gravity Tilt.

 

All of these devices use a 1-bit register address.

I think the problems start when I use 2-bit addresses

 

P.S I use 4.7K pullup resistors

Share this post


Link to post
Share on other sites

I think, main problem in the twi.c.

twi_writeTo do not return property errostate.

Please take a look on this example

// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
//
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include <Wire.h>

void setup()
{
  Wire.begin();

  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}


void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 120; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknow error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

On Arduino, this scanner working correctly.

 

On Energia it always return true for all I2C addresses !

Scanning...
I2C device found at address 0x01  !
I2C device found at address 0x02  !
...

...

I2C device found at address 0x76  !
I2C device found at address 0x77  !
done
 

Share this post


Link to post
Share on other sites

I have this flagged as todo in the code although does not explain why it would return 0 (TWI_ERRROR_NO_ERROR). This indeed points to a bug in the code somewhere. I will look at it this week.

/* TODO: This can just as well be an address NACK.
 * Figure out a way to distinguish between ANACK and DNACK */

  twi_error = TWI_ERROR_DATA_NACK;
  __bic_SR_register(LPM0_bits);

 

With that said, I am not sure if this explains why things lock up. Will look at this sometime this week.

Share this post


Link to post
Share on other sites

I have this flagged as todo in the code although does not explain why it would return 0 (TWI_ERRROR_NO_ERROR). This indeed points to a bug in the code somewhere. I will look at it this week.

/* TODO: This can just as well be an address NACK.
 * Figure out a way to distinguish between ANACK and DNACK */

  twi_error = TWI_ERROR_DATA_NACK;
  __bic_SR_register(LPM0_bits);

 

With that said, I am not sure if this explains why things lock up. Will look at this sometime this week.

Thank you.  It seems like pine's and golota's issues are *very* similar to the one I was/am experiencing, so, I look forward to the results...

 

Edit, actually, after reading the datasheet for the Atmel device, it seems pine's issue is *exactly* line mine, save it be I'm using a Microchip device, rather than an Atmel one.

 

Pine, I was able to use the onboard Infomem segments to store some data.  Check the msp_flash example...

Edited by on3pk

Share this post


Link to post
Share on other sites

@@pine, where do I get the SL018+tag? Only one I could find were from China. Getting them from China is going to take to long.

@@energia I got them directly from StrongLink China, ordered online. Their sales rep just replied me for international order it will take 2 to 3 days via express, and they only ship product via express last time. I didnt get the tag from them, using some card from friend and train tickets.

 

Thanks for your help and will try the resistor pull up and i2c address when i get home.

Share this post


Link to post
Share on other sites

It works!

Added two 2k2 resistors for each from LP Vcc to SDA and SCL, and removed the internal pull up code as Energia suggested, no more hang and the reader finally willing to show the tag info! Did not tried the write yet but I believe it should work too.

post-286-0-18888500-1365438518_thumb.jpg
Sorry for the mess, the blue on the breadboard is an Arduino Nano, just to provide 5V for input to the SL018 and nothing else. Another blue one standing is a bluetooth, again nothing to do with this.. The white paper is an ultralite tag, covering most part of the green SL018 standing behind. The green light is from the SL018 when the tag is present.


So.. changes made from the original code:

(1) The ino source file (original for Arduino) used is at
https://raw.github.com/marcboon/RFIDuino/master/SL018/examples/sl018demo/sl018demo.ino

Only thing modified from the above source is

#define TAG 2

in line 18. This is for connecting to P1.0 of LP, receiving signal when a tag is near the reader.


(2) The cpp file at
https://raw.github.com/marcboon/RFIDuino/master/SL018/SL018.cpp
is also modified (various places, for I'm not sure the preprocessor in Energia handling the ARDUINO variable):

From:

#if defined(ARDUINO) && ARDUINO >= 100
//  Wire.write(data[i]);
#else
//  Wire.send(data[i]);
#endif



To:
 

Wire.write(data[i]);



and likewise

From:

#if defined(ARDUINO) && ARDUINO >= 100
//  data[0] = Wire.read();
#else
//  data[0] = Wire.receive();
#endif



To:

  data[0] = Wire.read();


And one more down for a read(), but i guess everyone know what i mean.

Will double check later sorry I'm too tired by now..

Thank you again everyone! Special thanks Energia for reading through the code and insightful advice.

Edited 10 Apr: ok soldered the TP1 test point on the LP to power the SL018, and confirmed the code will not run properly without the resistor pull up. The power line on SL018 is 5v and the sda and scl are pulled up by LP 3.3v.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...