Skip to content

Instantly share code, notes, and snippets.

@jancumps
Created October 19, 2014 19:29
Show Gist options
  • Select an option

  • Save jancumps/c68bdb9a714e4faf18e3 to your computer and use it in GitHub Desktop.

Select an option

Save jancumps/c68bdb9a714e4faf18e3 to your computer and use it in GitHub Desktop.
FuelTank boosterpack monitoring with Arduino and LCD shield (Texas Instruments, element14, SainSmart)
/*
Battery Monitor
Sends queries over i2c to the fueltank boosterpack;
Shows results on lcd
=========================================================================
Contains code from the HelloWorld example of the LiquidCrystal library:
Library originally added 18 Apr 2008
by David A. Mellis
library modified 5 Jul 2009
by Limor Fried (http://www.ladyada.net)
example added 9 Jul 2009
by Tom Igoe
modified 22 Nov 2010
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/LiquidCrystal
=========================================================================
includes code from Peter Oak's FuelTank road test on element14:
http://www.element14.com/community/roadTestReviews/1712
=========================================================================
And this example for the SainSmart keypad:
//==========================================================================
// Author : CYTRON TECHNOLOGIES SDN BHD
// Project : Arduino Duemilanove
// Project description : Project_1: "Hello World" and utilize switch
//==========================================================================
*/
// include the library code:
#include <LiquidCrystal.h>
#include <stdio.h>
#include <Wire.h>
// fuel gauge constants
#define bq27510CMD_CNTL_LSB 0x00
#define bq27510CMD_CNTL_MSB 0x01
#define bq27510CMD_AR_LSB 0x02
#define bq27510CMD_AR_MSB 0x03
#define bq27510CMD_ARTTE_LSB 0x04
#define bq27510CMD_ARTTE_MSB 0x05
#define bq27510CMD_TEMP_LSB 0x06
#define bq27510CMD_TEMP_MSB 0x07
#define bq27510CMD_VOLT_LSB 0x08
#define bq27510CMD_VOLT_MSB 0x09
#define bq27510CMD_FLAGS_LSB 0x0A
#define bq27510CMD_FLAGS_MSB 0x0B
#define bq27510CMD_NAC_LSB 0x0C
#define bq27510CMD_NAC_MSB 0x0D
#define bq27510CMD_FAC_LSB 0x0E
#define bq27510CMD_FAC_MSB 0x0F
#define bq27510CMD_RM_LSB 0x10
#define bq27510CMD_RM_MSB 0x11
#define bq27510CMD_FCC_LSB 0x12
#define bq27510CMD_FCC_MSB 0x13
#define bq27510CMD_AI_LSB 0x14
#define bq27510CMD_AI_MSB 0x15
#define bq27510CMD_TTE_LSB 0x16
#define bq27510CMD_TTE_MSB 0x17
#define bq27510CMD_TTF_LSB 0x18
#define bq27510CMD_TTF_MSB 0x19
#define bq27510CMD_SI_LSB 0x18
#define bq27510CMD_SI_MSB 0x19
#define bq27510CMD_STTE_LSB 0x1A
#define bq27510CMD_STTE_MSB 0x1B
#define bq27510CMD_SOH_LSB 0x1C
#define bq27510CMD_SOH_MSB 0x1D
#define bq27510CMD_CC_LSB 0x1E
#define bq27510CMD_CC_MSB 0x1F
#define bq27510CMD_SOC_LSB 0x20
#define bq27510CMD_SOC_MSB 0x21
#define bq27510CMD_INSC_LSB 0x22
#define bq27510CMD_INSC_MSB 0x23
#define bq27510CMD_ITLT_LSB 0x28
#define bq27510CMD_ITLT_MSB 0x29
#define bq27510CMD_RS_LSB 0x2A
#define bq27510CMD_RS_MSB 0x2B
#define bq27510CMD_OPC_LSB 0x2C
#define bq27510CMD_OPC_MSB 0x2D
#define bq27510CMD_DCAP_LSB 0x2E
#define bq27510CMD_DCAP_MSB 0x2F
#define bq27510_ADR 0x55
// keypad variables
int analogPin = A0;
int adc_key_old;
int adc_key_in;
int NUM_KEYS = 5;
int key=-1;
int adc_key_val[5] ={30, 150, 360, 535, 760 };
// initialize the library with the numbers of the interface pins
// LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
int Volts = 0;
int Amps = 0;
int tarraAmps = 0;
int SOC = 0;
char output[80];
char val[4];
void setup() {
// initialise the battery gauge
setupI2C();
// initialise LCD
setupLCD();
setupKeypad();
}
void loop() {
measure();
delay(2000);
recordKey();
checkNetto();
}
// ===================================================================
// fuel gauge support methods
void setupI2C() {
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
}
int getValue(int port, int cmd)
{
int tmp1=0;
int tmp2 = 0;
int response = 0;
Wire.beginTransmission(port);
Wire.write(byte(cmd));
Wire.endTransmission(true);
// according to all the demos, first reading is unstable so ignore it ??
// Seems yo have to do this twice to get it to work, if you dont is gets screwed up
Wire.beginTransmission(port);
Wire.write(byte(cmd));
// request 2 bytes from slave device port
response = Wire.requestFrom(port, 2);
Wire.endTransmission(true);
while(Wire.available()) // slave may send less than requested
{
tmp1 = Wire.read() ;
tmp2 = Wire.read() ;
}
return transBytes2Int(tmp2, tmp1);
}
/**
* @brief Translate two bytes into an integer
* @param
* @retval The calculation results
*/
unsigned int transBytes2Int(unsigned char msb, unsigned char lsb)
{
unsigned int tmp;
tmp = ((msb << 8) & 0xFF00);
return ((unsigned int)(tmp + lsb) & 0x0000FFFF);
}
void measure(){
Volts = getValue(bq27510_ADR, bq27510CMD_VOLT_LSB );
Amps = getValue(bq27510_ADR, bq27510CMD_AI_LSB);
SOC = getValue(bq27510_ADR, bq27510CMD_SOC_LSB);
showLCDValues();
// send to console for debug purposes
sprintf(output, "mV=%u , brutto mA=%4d, tarra mA=%4d, netto mA=%4d, SOC=%d\n", Volts , Amps, tarraAmps, Amps - tarraAmps, SOC);
Serial.print(output);
}
// ===================================================================
void setupLCD() {
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("mV: %");
lcd.setCursor(0, 1);
lcd.print("mA:");
}
void showLCDOffset() {
lcd.setCursor(9, 1);
if (tarraAmps) {
sprintf(val, "(%4d)", tarraAmps);
} else {
sprintf(val, " ");
}
lcd.print(val);
}
void showLCDValues() {
sprintf(val, "%u", Volts);
lcd.setCursor(4, 0);
lcd.print(val);
sprintf(val, "%3u", SOC);
lcd.setCursor(12, 0);
lcd.print(val);
sprintf(val, "%4d", Amps - tarraAmps);
lcd.setCursor(4, 1);
lcd.print(val);
}
// ========================================================================
void setupKeypad() {
adc_key_old = analogRead(analogPin); // store the unpress key value
}
/*******************************************************************************
* PRIVATE FUNCTION: get_key
*
* PARAMETERS:
* ~ integer
*
* RETURN:
* ~ unsigned int input
*
* DESCRIPTIONS:
* convert the ADC value to number between 0 to 4
*
*******************************************************************************/
int get_key(unsigned int input)
{
int k;
for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
{
return k;
}
}
if (k >= NUM_KEYS)
k = -1; // No valid key pressed
return k;
}
void recordKey() {
adc_key_in = analogRead(analogPin); // read ADC value
adc_key_in = get_key(adc_key_in);
}
void checkNetto() {
if (adc_key_in == 4 ) { // select key pressed
Serial.print("removing tarra from the current measurement\n");
tarraAmps = 0 + Amps;
}
if (adc_key_in == 3 ) { // left key pressed
Serial.print("taking full current measurement\n");
tarraAmps = 0;
}
key = -1;
showLCDOffset();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment