Arduino Micro Code Creating a Few Errors When Run On Teensy 3.1?

Status
Not open for further replies.

solardude

Well-known member
Ok I have created some code on the Arduino Micro to read data from a fuel gauge chip and it works fine on the Arduino Micro.

Micro Good.png

When I run this code on the Teensy 3.1 I have a few numbers that do not calculate right and I'm assuming it has to do with the Teensy 3.1 handling things a little bit differently some how. Here is the serial readings I get when I run the same code on the Teensy 3.1,

Most readings are the same as the Arduino Micro provides but the "Power Input / -Output" , "Average Current Draw", "Standby Current Consumption" are all reading way high for some reason. Any ideas?

Teensy Wrong.png

Here is my code for this:

Code:
#include <Wire.h>                                                                          // Wire library for communicating over I2C
#define BQ34Z100 0x55                                                                      // This is the I2C address of the 


unsigned int soc, voltage, remain_cap, TTE, TTF, STE, Cycles, SOH, AvaliableCap, FLAGS, AvailableEnergy, FullChgCap, ChipTemp;
int avg_current, batt_temp, StandbyCurrent, PassedCharge, SelfDischargeCurrent , AveragePower;
float power_draw;




// ~~ Status Functions~~

// State of Charge, a percent value of the battery's total charge
void readSOC()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x02);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x03);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  soc = high1 + low;
}

// The battery's remaining capacity in mAh
void readRemainingCapacity()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x04);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x05);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  remain_cap = high1 + low;
}

void readVoltage()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x08);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x09);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  voltage = high1 + low;

}

void readAverageCurrent()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x0a);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x0b);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  avg_current = high1 + low;
}


void readBattTemp()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x0c);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x0d);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  batt_temp = high1 + low;
  
  batt_temp = 0.1*batt_temp;          // Each bit is 0.1K, so we have a value in Kelvins
  batt_temp = batt_temp - 273.15;      // Convert to degrees Celsius
}

// Time To Empty - The amoutn of time until the battery is empty. 
void readTTE()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x18);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x19);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  TTE = high1 + low;
}

// Time Till Fully Charged Reading. 
void readTTF()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x1a);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x1b);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  TTF = high1 + low;
}


// Time Till Fully Charged Reading. 
void readSTE()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x1e);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x1f);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  STE = high1 + low;
}


// Battery Liftime Cycles
void readCycles()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x2c);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x2d);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  Cycles = high1 + low;
}

// Battery State of Health
void readSOH()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x2e);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x2f );
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  SOH = high1 + low;
}

float PowerDraw(float volt, float current)
{
  volt = volt/1000.0;
  current = current/1000.0;
  float power = volt*current;
  return power;
}


void readAvaliableCap()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x16);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x17);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  AvaliableCap = high1 + low;
}

void readStandbyCurrent()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x1c);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x1d);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  StandbyCurrent = high1 + low;
}

void readAvailableEnergy()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x24);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x25);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  AvailableEnergy = high1 + low;
}


void readAveragePower()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x26);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x27);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  AveragePower = high1 + low;
  
 
}


void readPassedCharge()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x34);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x35);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  PassedCharge = high1 + low;
}

void readSelfDischargeCurrent()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x38);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x39);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  SelfDischargeCurrent = high1 + low;
}



void readFLAGS()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x0e);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x0f);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  FLAGS = high1 + low;
}


void readFullChgCap()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x16);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x17);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  FullChgCap = high1 + low;
}


void readChipTemp()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x2a);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x2b);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  ChipTemp = high1 + low;
  ChipTemp = 0.1*ChipTemp;          // Each bit is 0.1K, so we have a value in Kelvins
  ChipTemp = ChipTemp - 273.15;      // Convert to degrees Celsius
}



void setup()
{
  Serial.begin(9600);
  
  Wire.begin();
}



void loop()
{
 readSOC();
 Serial.print("Battery State of Charge: ");
 Serial.print(soc);
 Serial.println("%");
 
 power_draw = PowerDraw(voltage,avg_current);
 Serial.print("Power Input & -Output: ");
 Serial.print(power_draw);
 Serial.println(" W");
 
 readVoltage();
 Serial.print("Battery Pack Voltage: ");
 Serial.print(voltage *0.001);
 Serial.println(" V");

 readAverageCurrent();
 Serial.print("Average Current Draw: ");
 Serial.print(avg_current * 0.001);
 Serial.println(" A");
 
 readRemainingCapacity();
 Serial.print("Remaining Capacity: ");
 Serial.print(remain_cap * 0.001);
 Serial.println(" Ah");
 
   readFullChgCap();
 Serial.print("Full Charge Capacity : ");
 Serial.print(FullChgCap * 0.001);
 Serial.println(" Ah");
 
 readAvailableEnergy();
 Serial.print("Avaliable Energy : ");
 Serial.print(AvailableEnergy * 0.001);
 Serial.println(" Wh");
 
 readPassedCharge();
 Serial.print("Total Power Transferred : ");
 Serial.print(PassedCharge * 0.001);
 Serial.println(" Ah");
 
 readTTE();
 Serial.print("Time Till Empty: ");
 Serial.print(TTE /60.0);
 Serial.println(" Hours ");
 
 readTTF();
 Serial.print("Time Till Full: ");
 Serial.print(TTF /60.0);
 Serial.println("Hours");
 
 readSTE();
 Serial.print("Standby Time Till Empty: ");
 Serial.print(STE /1440);
 Serial.println("Days");
 
 readStandbyCurrent();
 Serial.print("Standby Current Consumption : ");
 Serial.print(StandbyCurrent);
 Serial.println("mA");
 
 readCycles();
 Serial.print("Battery Cycles: ");
 Serial.print(Cycles);
 Serial.println("");
 
 readSOH();
 Serial.print("Battery Health Percentage: ");
 Serial.print(SOH);
 Serial.println("");
 
 readChipTemp();
 Serial.print("Chip Temperature : ");
 Serial.print(ChipTemp * 9.0/ 5.0 + 32.0);
 Serial.println(" F");

 
 Serial.println("");
 Serial.println("");
 Serial.println("");
 Serial.println("");
 
 readAveragePower();
 Serial.print("Average Discharge Power : ");
 Serial.print(AveragePower * 10 * 0.0001 );
 Serial.println(" W");
 
 readSelfDischargeCurrent();
 Serial.print("SelfDischargeCurrent : ");
 Serial.print(SelfDischargeCurrent);
 Serial.println(" mAh");


 readBattTemp();
 Serial.print("Battery Temperature: ");
 Serial.print(batt_temp * 9.0/ 5.0 + 32.0); 
 Serial.println(" F");
 
  readFLAGS();
 Serial.print("Flags : ");
 Serial.print(FLAGS);
 Serial.println("");

 
 Serial.print("\r\n");
  
 delay(1000);
}
 
Could be code that wasn't written to be portable between AVR 16 bit integers and ARM 32 bit. Easily fixed. But you need to supply more specifics, otherwise we'd have to pore over the code line by line.
 
Last edited:
The figures for "Power Input / -Output" , "Average Current Draw", "Standby Current Consumption" look odd in the original picture too - are they really meant to be negative consumption (i.e. representing generation of power)? It's possible that the calculated values for these were exceeding the storage size in the micro and wrapping around to negative values...and the larger sized ints in the teensy have enough space to fit the calculated values properly (no more wrap around).

I'd check the actual value of the bytes read though, and make sure that the high/low bytes haven't been accidentally reversed for the current/power parts - because if the Micro was wrapping around the Teensy values would be the real result of the calculation - and those results also look very wrong. Could even be a unit issue - as a gut feel estimate, 65mA would make a lot more sense than 65A for a gauge (though the other is possible for cranking/engine current if that's what it's meant to be reading) - are the values representing microAmps instead of milliAmps? (Note: I'm not that familiar with cars, so apologies if the above is inaccurate).
 
Last edited:
Could be code that wasn't written to be portable between AVR 16 bit integers and ARM 32 bit. Easily fixed. But you need to supply more specifics, otherwise we'd have to pore over the code line by line.

Thanks for the quick reply.

Ok here are the specific functions that are returning incorrect numbers compared to the Arduino Micro which the code was build around.

Issue #1.

I'm calling this function that works fine in Arduino but not on the Teensy 3.1 . Here is the code:

Code:
int  avg_current


void readAverageCurrent()
{
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x0a);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int low = Wire.read();
  
  Wire.beginTransmission(BQ34Z100);
  Wire.write(0x0b);
  Wire.endTransmission();
  
  Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  avg_current = high1 + low;
}


void loop()

{
readAverageCurrent();
 Serial.print("Average Current Draw: ");
 Serial.print(avg_current * 0.001);
 Serial.println(" A");

}
With the above function on the Arduino Micro I get a returned number via the Serial Port of -0.30

The Teensy 3.1 returns 65.24 which looks to be the maximum positive value for the signed int


Any ideas? The numbers and readings are working perfectly on the Arduino Micro. I'm just taking the readings from a fuel gauge that are 1 milliamp per byte and doing simple math to get it to read out in Amps to keep it easier to read.

All help is greatly appreciated.
 
Last edited:
The figures for "Power Input / -Output" , "Average Current Draw", "Standby Current Consumption" look odd in the original picture too - are they really meant to be negative consumption (i.e. representing generation of power)? It's possible that the calculated values for these were exceeding the storage size in the micro and wrapping around to negative values...and the larger sized ints in the teensy have enough space to fit the calculated values properly (no more wrap around).

I'd check the actual value of the bytes read though, and make sure that the high/low bytes haven't been accidentally reversed for the current/power parts - because if the Micro was wrapping around the Teensy values would be the real result of the calculation - and those results also look very wrong. Could even be a unit issue - as a gut feel estimate, 65mA would make a lot more sense than 65A for a gauge (though the other is possible for cranking/engine current if that's what it's meant to be reading) - are the values representing microAmps instead of milliAmps? (Note: I'm not that familiar with cars, so apologies if the above is inaccurate).

Thanks for chiming in here.

This is being used with a 10 Amp Hour single 3.2v battery cell that is being used to charge devices via a USB port. So the current readings are anywhere from -7 to + 7 amps, or -7000 milliamps.

The reading returned from the fuel gauge works perfect on the Arduino Micro so I'm assuming it has to do with the way the Teensy 32bit coding is handling the numbers. Its working fine for most of the readings but not only on a few readings like: Average Current , Standby Current Consumption.

The Power Input & -Ouput reading is just the Votage reading x the average current reading which provides wattage. So if the Average Current reading was correct the Power Input & - Output Reading would be correct also.
 
The Teensy 3.1 returns 65.24 which looks to be the maximum positive value for the signed int
That suggests that the device isn't wired correctly and the Teensy is just reading all ones, all the time.
Do you have pullup resistors on the two I2C lines? IIRC on the Teensy3.1 you must have 4.7k pullups on both SDA and SCL.
It's also always worth trying an I2C scanner first just to make sure that the device is being seen.

Pete
 
That suggests that the device isn't wired correctly and the Teensy is just reading all ones, all the time.
Do you have pullup resistors on the two I2C lines? IIRC on the Teensy3.1 you must have 4.7k pullups on both SDA and SCL.
It's also always worth trying an I2C scanner first just to make sure that the device is being seen.

Pete

Everything is working just fine except for 2 function calls. Look at the serial feedback screenshots between the arduino vs the teensy 3.1. Communication is ok.
 
I guess I just need to figure out what the difference is between AVR 16 bit integers and ARM 32 bit.

Also would this need to be different since the Teensy 3.1 is a 32bit device?

Code:
 Wire.requestFrom(BQ34Z100,1);
  
  unsigned int high = Wire.read();
  
  unsigned int high1 = high<<8;
  
  soc = high1 + low;

I guess specifically the unsigned int high1 = high<<8; part of the code?
 
PROBLEM SOLVED!

I dug alittle deeper into the forum looking for the difference between 16 bit & 32 bit Integers and found a easy solution posted by Paul that solved my problem also.

I just had to declare the integers as 16 bit instead of 32bit by adding uint16_t & int16_t instead of unsigned int & int.
 
Status
Not open for further replies.
Back
Top