Pages: 1 [2]   Go Down
Author Topic: Wire.endTransmission(); Causes Problems in the Code!  (Read 2535 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 1
Posts: 282
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I believe I need to add I2C pull-up resistors on the SDA (A4) and SCL (A5) lines. What size resistors should I tie between each line and Vdd (+)? I’m assuming 4.7K ohms for the MAX17043G+U IC. Is that correct?

UPDATE:  I just tried tying SDA and SCL to Vdd (+) with 4.7K ohm resistors, then tried a 100K ohm resistors when the prior didn't work.  Still same output and noise of usb reset... Agh! smiley-cry

Does the alert pin (D3) need to be supplied with Vdd (+) and used with a resistor? I see it is labeled an input in the example code.
« Last Edit: January 05, 2013, 01:23:39 pm by encryptor » Logged

peace*&^

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 496
Posts: 19047
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for that advice, however I just tried the same approach without the LiPo shield attached and I'm still getting the same error/bouncing noise.

With no shield attached, what alert pin?
Logged


Offline Offline
Sr. Member
****
Karma: 1
Posts: 282
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For the c2i bus communication on SDA (A4) SCL (A5), wouldn't it require that I put the battery shield back on after uploading the required software?  Should I expect Wire.endTransmission(); to complete without having stacked the board onto of the Arduino Uno?  Does someone agree with myself that I may need to tie SDA and SCL to Vdd (+) using a 4.7K resistor?  The alert pin D3 is on the Li Power shield to alert when battery power source drops below 32%.
Logged

peace*&^

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 496
Posts: 19047
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You said initially that Wire.endTransmission(); caused the USB reset, even with nothing attached to the Arduino. I am trying to get past that point for you. Does that happen or not?
Logged


Offline Offline
Sr. Member
****
Karma: 1
Posts: 282
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You said initially that Wire.endTransmission(); caused the USB reset, even with nothing attached to the Arduino. I am trying to get past that point for you. Does that happen or not?

Yes that is true.  However, I just got past this whole issue now.  For the USB reset (noise) not to happen I need the SDA and SCL lines tied to Vdd (+5v) and use of a 4.7K resistor on each line.  This is just using the Arduino Uno R3 board and no other boards stacked.

Now that this is working, I'm going to introduce more of the original code.  Currently, I'm stuck at the following while loop in the i2cRead16 function.  Any help here?

Code:
  while (Wire.available() < 2)
     ;


ORIGINAL CODE:
Code:
/* LiPower Shield Example Code
  by: Jim Lindblom
  SparkFun Electronics
  date: 1/3/12
 
*/
#include <Wire.h>

#define MAX17043_ADDRESS 0x36  // R/W =~ 0x6D/0x6C

// Pin definitions
int alertPin = 2;  // This is the alert interrupt pin, connected to pin 2 on the LiPower Shield

// Global Variables
float batPercentage;
//float batVoltage;
//int alertStatus;

void setup()
{
  pinMode(alertPin, INPUT);
  digitalWrite(alertPin, HIGH);
 
  Serial.begin(9600);  // Start hardware serial
 
 
  Serial.println("Start Wire.begin() (i2c bus) in 5 seconds");
  delay(5000);
  Wire.begin();  // Start I2C
  Serial.println("Wire.begin() has executed");
 
 
  Serial.println("Start configMax in 5 seconds");
  delay(5000);
  configMAX17043(32);  // Configure the MAX17043's alert percentage
  Serial.println("configMax function has executed");
 
 
  Serial.println("Start qsMAX17043 in 5 seconds");
  delay(5000);
  qsMAX17043();  // restart fuel-gauge calculations
  Serial.println("qsMAX17043 function has executed");
}

void loop()
{
  Serial.println("Start percentMAX17043() in 5 seconds");
  delay(5000);
  batPercentage = percentMAX17043();
  Serial.println("percentMAX17043 function has executed");
 
  //batVoltage = (float) vcellMAX17043() * 1/800;  // vcell reports battery in 1.25mV increments
  //alertStatus = digitalRead(alertPin);
  delay(3000);
  Serial.print(batPercentage, 2);  // Print the battery percentage
  Serial.println(" % battery life");
  // Serial.print(batVoltage, 2);  // print battery voltage
  // Serial.println(" battery's voltage");
  // Serial.print("Alert Status = ");
  // Serial.println(alertStatus, DEC);
  Serial.println();
  delay(1000);
}

/*
vcellMAX17043() returns a 12-bit ADC reading of the battery voltage,
as reported by the MAX17043's VCELL register.
This does not return a voltage value. To convert this to a voltage,
multiply by 5 and divide by 4096.
*/
/*
unsigned int vcellMAX17043()
{
  unsigned int vcell;
 
  vcell = i2cRead16(0x02);
  vcell = vcell >> 4;  // last 4 bits of vcell are nothing
 
  return vcell;
}
*/

/*
percentMAX17043() returns a float value of the battery percentage
reported from the SOC register of the MAX17043.
*/
float percentMAX17043()
{
  unsigned int soc;
  float percent;
 
  Serial.println("made it inside percentMAX17043 function");
  Serial.println("wait 5 seconds to call i2cRead16(0x04)");
  delay(5000);
 
  soc = i2cRead16(0x04);  // Read SOC register of MAX17043
  percent = (byte) (soc >> 8);  // High byte of SOC is percentage
  percent += ((float)((byte)soc))/256;  // Low byte is 1/256%
 
  return percent;
}


/*
configMAX17043(byte percent) configures the config register of
the MAX170143, specifically the alert threshold therein. Pass a
value between 1 and 32 to set the alert threshold to a value between
1 and 32%. Any other values will set the threshold to 32%.
*/

void configMAX17043(byte percent)
{
  if ((percent >= 32)||(percent == 0))  // Anything 32 or greater will set to 32%
    i2cWrite16(0x9700, 0x0C);
  else
  {
    byte percentBits = 32 - percent;
    i2cWrite16((0x9700 | percentBits), 0x0C);
  }
}


/*
qsMAX17043() issues a quick-start command to the MAX17043.
A quick start allows the MAX17043 to restart fuel-gauge calculations
in the same manner as initial power-up of the IC. If an application's
power-up sequence is very noisy, such that excess error is introduced
into the IC's first guess of SOC, the Arduino can issue a quick-start
to reduce the error.
*/
void qsMAX17043()
{
  Serial.println("made it inside qsMAX17043 function");
  Serial.println("wait 5 seconds to call i2cWrite16(0x4000, 0x06)");
  delay(5000);
 
  i2cWrite16(0x4000, 0x06);  // Write a 0x4000 to the MODE register
 
  Serial.println("you've made it thru i2cWrite16(0x4000, 0x06)");
  delay(5000);
}

/*
i2cRead16(unsigned char address) reads a 16-bit value beginning
at the 8-bit address, and continuing to the next address. A 16-bit
value is returned.
*/

unsigned int i2cRead16(unsigned char address)
{
  int data = 0;
 
  Serial.println("you've made it inside i2cRead16 function");
 
  Serial.println("wait 5 seconds to begin transmission");
  delay(5000);
  Wire.beginTransmission(MAX17043_ADDRESS);
  Serial.println("beginTransmission has completed");
 
  Serial.println("wait 5 seconds to write to buffer");
  delay(5000);
  Wire.write(address);
  Serial.println("write to buffer has completed");
 
  Serial.println("wait 5 seconds to end transmission");
  delay(5000);
  Wire.endTransmission();
  Serial.println("you've made it past Wire.endTransmission()");
 
  //stuck here right now!!!
 
  Serial.println("wait 5 seconds to requestFrom 17043 address 2 bytes");
  delay(5000);
  Wire.requestFrom(MAX17043_ADDRESS, 2);
  Serial.println("you've made it past requestFrom 17043 address 2 bytes");
 
  Serial.println("wait 5 seconds to enter while(Wire.available()<2)");
  delay(5000);
  while (Wire.available() < 2)
    ;
  Serial.println("you've made it past while(Wire.available()<2)");
 
  Serial.println("wait 5 seconds to call Wire.read()");
  delay(5000);     
  data = ((int) Wire.read()) << 8;
  data |= Wire.read();
  Serial.println("you've made it past Wire.read()");
 
  Serial.println("wait 5 seconds to return data");
  delay(5000);
  return data;
  Serial.println("you've made it past return data");
}


/*
i2cWrite16(unsigned int data, unsigned char address) writes 16 bits
of data beginning at an 8-bit address, and continuing to the next.
*/
//              0x9700 = 38656, 0x0C is the config register (memory)
void i2cWrite16(unsigned int data, unsigned char address)
{
  Serial.println("made it inside i2cWrite16 function");
  Serial.println("wait 5 seconds to begin transmission");
  delay(5000);
 
  Wire.beginTransmission(MAX17043_ADDRESS);
 
  Serial.println("beginTransmission has completed");
  Serial.println("wait 5 seconds to write to buffer");
  delay(5000);
 
  Wire.write(address);
  Wire.write((byte)((data >> 8) & 0x00FF));
  Wire.write((byte)(data & 0x00FF));
  Serial.println("write to buffer has completed");
 
  Serial.println("wait 5 seconds to end transmission");
  delay(5000);
 
  Wire.endTransmission();
  Serial.println("you've made it past Wire.endTransmission()");
}

OUTPUT:
Quote
Start Wire.begin() (i2c bus) in 5 seconds
Wire.begin() has executed
Start configMax in 5 seconds
made it inside i2cWrite16 function
wait 5 seconds to begin transmission
beginTransmission has completed
wait 5 seconds to write to buffer
write to buffer has completed
wait 5 seconds to end transmission
you've made it past Wire.endTransmission()
configMax function has executed
Start qsMAX17043 in 5 seconds
made it inside qsMAX17043 function
wait 5 seconds to call i2cWrite16(0x4000, 0x06)
made it inside i2cWrite16 function
wait 5 seconds to begin transmission
beginTransmission has completed
wait 5 seconds to write to buffer
write to buffer has completed
wait 5 seconds to end transmission
you've made it past Wire.endTransmission()
you've made it thru i2cWrite16(0x4000, 0x06)
qsMAX17043 function has executed
Start percentMAX17043() in 5 seconds
made it inside percentMAX17043 function
wait 5 seconds to call i2cRead16(0x04)
you've made it inside i2cRead16 function
wait 5 seconds to begin transmission
beginTransmission has completed
wait 5 seconds to write to buffer
write to buffer has completed
wait 5 seconds to end transmission
you've made it past Wire.endTransmission()
wait 5 seconds to requestFrom 17043 address 2 bytes
you've made it past requestFrom 17043 address 2 bytes
wait 5 seconds to enter while(Wire.available()<2)
« Last Edit: January 05, 2013, 11:32:48 pm by encryptor » Logged

peace*&^

Offline Offline
Sr. Member
****
Karma: 1
Posts: 282
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a gut feeling that the lipo battery must be plugged onto the Li Power shield when requestFrom(addy, quantity) is called, so that 2 bytes of diagnostics on the battery can be retrieved.  Does anyone agree?  smiley
« Last Edit: January 06, 2013, 09:34:11 am by encryptor » Logged

peace*&^

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 631
Posts: 50182
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Would anyone agree?
Only if you actually want a response.
Logged

Offline Offline
Sr. Member
****
Karma: 1
Posts: 282
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

haha!  Does anyone agree?
Logged

peace*&^

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 631
Posts: 50182
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you are going to talk to an I2C device, of course it needs to be connected.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 496
Posts: 19047
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
Wire.requestFrom(MAX17043_ADDRESS, 2);
...
  delay(5000);
  while (Wire.available() < 2)
    ;

The test for available there is unnecessary. Wire.requestFrom returns the number of bytes received. If it is less than 2, looping is not going to change that, however it will hang your program. You need something like:

Code:
if (Wire.requestFrom(MAX17043_ADDRESS, 2) != 2)
  {
  // error, no resonse
 
  }
else
  {
  // read data
  }

If you do not the have the I2C device connected then the library will get a NAK and the number of bytes returned will be zero.
Logged


Pages: 1 [2]   Go Up
Jump to: