Jump to content
43oh

Simple battery tester Arduino code


Recommended Posts

Hi all,

I am new to MSP430 (and basically, topics on this forum) and I will probably ask some stupid questions, but I have to ask them anyway :D

I just got myself a Launchpad, and I want to run this project http://nostarch.s3.amazonaws.com/arduino_project6.pdf

using Energia.

 

My questions are:

1) If I copy the Arduino code, change the connected pins in the code from D2,D4 and D6 to 6,7 and 8 base on this reference (P1.4, P1.5, P2.0) http://energia.nu/img/LaunchPadMSP430G2553-V1.5.jpg and connect it, will it work?

2) Do I have to use 3 x 560 Ohm & 1 x 2,2k Ohm resistors, as shown od the Arduino schematics? ATM (writing these words) I have

only the board, I have to buy LEDs and resistors and a prototype board so I can't test anything yet.

3) I wanted to use the MSP430G22553 20-pin device. Is it ok?

 

I have the Rev.1.5 Launchpad. 

Link to post
Share on other sites

The code should work as is. The thing you might need to adjust is the factor of 0.0048 when calculating the effective voltage.

 

As for the resistors: The 560 ohm ones you will need something in the ballpark, i.e. anything from 330 to 1K should be fine. Not sure what the 2.2k resistor is good for.. I think anything in that range should work too.

 

The MSP430G2553 is perfectly capable for this kind of project.

Link to post
Share on other sites

Re the factor 0.0048, from the article:

 

 

 

The maximum voltage that can be read is 5 V, so we divide 5 by 1,024 (the number of possible values), which equals 0.0048. Therefore, if  analogRead() returns 512, then we multiply that reading by 0.0048, which equals 2.4576 V.

 

With the LaunchPad voltage around 3.4V, the factor should be 0.0033.

Link to post
Share on other sites

Well, I'm doing something wrong...

30rsoiv.png

The top led is red, the middle is yellow, the bottom is green.

This is what I've got, but the board is ignoring the battery (I've got one, not two), by blinking the green & yellow leds even if no battery is connected at all.

I just don't understand :/

 

This is the code I'm using:

const int newLED = 11; // green LED 'new'
const int okLED = 12;  // yellow LED 'ok'
const int oldLED = 13; // red LED 'old'

int analogValue = 0;
float voltage = 0;
int ledDelay = 2000;

void setup()
{
  pinMode(newLED, OUTPUT);
  pinMode(okLED, OUTPUT);
  pinMode(oldLED, OUTPUT);
}

void loop()
{
  analogValue = analogRead(0);
  voltage = analogValue*0.0033;
  
  if (voltage >= 0.8)
  {
    digitalWrite(newLED, HIGH);
  }
  else if (voltage < 0.8 && voltage > 0.4)
  {
    digitalWrite(okLED, HIGH);
  }
  else if (voltage <= 0.4)
  {
    digitalWrite(oldLED, HIGH);
  }
  else
  {
    digitalWrite(newLED, LOW);
    digitalWrite(okLED, LOW);
    digitalWrite(oldLED, LOW);
  }
}

Any advice, please?

Link to post
Share on other sites

You need to connect the battery ground to the LaunchPad GND to give everything the same point of reference.

 

If that doesn't work, try first a small sample program that blink the LEDs without measuring the battery.

 

When that works, I'd suspect the conversion from analogValue to voltage. Personally I'd try to avoid going via float altogether as it comes with a lot of overhead (memory and performance). I'd use constants to precalculate the various values, something along these lines:

 

#define VOLTAGE_0_8 (int(1024.0 / 3.4 * 0.8))
#define VOLTAGE_0_4 (int(1024.0 / 3.4 * 0.4))
..
if (analogValue > VOLTAGE_0_8)
..

 

This way, the calculation happens at compile time and the comparison at run-time only uses integers. You could also directly fill in the values (241 and 120 respectively) but this way someone reading the source can see how you came up with those numbers.

Link to post
Share on other sites

k2ziau.png

Ok, I've got the GND connected, but still the LEDs don't seem to react to the battery :/

The red led is LOW, the yellow and green HIGH.

 

This is the code now:

#define VOLTAGE_0_8 (int(1024.0 / 3.4 * 0.8))
#define VOLTAGE_0_4 (int(1024.0 / 3.4 * 0.4))

const int newLED = 11; // green LED 'new'
const int okLED = 12;  // yellow LED 'ok'
const int oldLED = 13; // red LED 'old'

int analogValue = 0;
float voltage = 0;
int ledDelay = 2000;

void setup()
{
  pinMode(newLED, OUTPUT);
  pinMode(okLED, OUTPUT);
  pinMode(oldLED, OUTPUT);
}

void loop()
{
  analogValue = analogRead(0);
  //voltage = analogValue*0.0033;
  
  if (analogValue >= VOLTAGE_0_8)
  {
    digitalWrite(newLED, HIGH);
  }
  else if (analogValue < VOLTAGE_0_8 && analogValue > VOLTAGE_0_4)
  {
    digitalWrite(okLED, HIGH);
  }
  else if (analogValue <= VOLTAGE_0_4)
  {
    digitalWrite(oldLED, HIGH);
  }
  else
  {
    digitalWrite(newLED, LOW);
    digitalWrite(okLED, LOW);
    digitalWrite(oldLED, LOW);
  }
}
Link to post
Share on other sites

Here's something cooked up using the LP built-in LED's. LP is powered by USB connection. Voltage is sensed on pin P1.7 / 15 / A7.

 

Only RED led lights if voltage is 1/3 of ADC scale or less, both RED and GREEN LED's light if voltage is between 1/3 and 2/3, and only GREEN led lights if voltage is above 2/3 ADC scale. Also prints the ADC value to the serial port for monitoring in a terminal window.

 

Note- a pull-down resistor (10K-100K) should be installed between P1.7 and ground in order to bring the ADC to 0 if no battery is connected, otherwise noise / jitter on the ADC can cause random fluctuations and false readings. Also, note the use of nested if...then...else; when the first condition is satisfied, no other tests are done, so if the first fails, the second is tested and if that fails the final else is what happens.

 

// Change these to change thresholds:
#define VOLTAGE_HIGH 684 // (1024 / 3) * 2
#define VOLTAGE_LOW 342  // (1024 / 3) * 1


int analogValue = 0;

void setup()
{
  analogReference(DEFAULT);    // use VCC as reference
  pinMode(A7, INPUT);          // A7 = P1.7 / PIN 15
  pinMode(RED_LED, OUTPUT);    // = P1.0
  pinMode(GREEN_LED, OUTPUT);  // = P1.6
  Serial.begin(9600);          // start serial port @ 9600
}

void loop()
{ 
  // read ADC port:
  analogValue = analogRead(A7);

  // write value to serial port:
  Serial.println(analogValue);

  // compare value to thresholds:
  if (analogValue >= VOLTAGE_HIGH)
  // voltage is above highest threshold:
  {
    // turn GREEN LED ON; RED LED OFF
    digitalWrite(GREEN_LED, HIGH);
    digitalWrite(RED_LED, LOW);
  }
  else if (analogValue >= VOLTAGE_LOW)
  // voltage is below highest threshold,
  // but is above minimum threshold
  {
    // turn both LED's on:
    digitalWrite(RED_LED, HIGH);
    digitalWrite(GREEN_LED, HIGH);
  }
  else   {
    // voltage is below minimum threshold so
    // turn RED LED on and GREEN LED off
    digitalWrite(RED_LED, HIGH);
    digitalWrite(GREEN_LED, LOW);
  }  
  // wait a moment before continuing
  delay(500);
}
Link to post
Share on other sites

I didn't have much time in the past few days, but now I'm back to the project. 

 

Note- a pull-down resistor (10K-100K) should be installed between P1.7 and ground in order to bring the ADC to 0 if no battery is connected, otherwise noise / jitter on the ADC can cause random fluctuations and false readings. Also, note the use of nested if...then...else; when the first condition is satisfied, no other tests are done, so if the first fails, the second is tested and if that fails the final else is what happens.

 

I don't understand how it should be connected... I've modified a bit my board, looks like this now:

jjs0hx.png

Those 5 resistors are 2,2k Ohm each. Also, I'm printing voltage from the input pin to serial (with no battery plugged), and getting readings like

Voltage=0.38
Voltage=0.41
Voltage=2.11
Voltage=0.36
Voltage=0.39
Voltage=2.09

...and like so. I've also added the line "analogReference(DEFAULT);" in setup. I guess I'll just test a 100k resistor, hopefully it'll help.

Link to post
Share on other sites

In your diagram, you have the 'battery' connected to P1.0- make sure you remove the jumper to the RED LED at the edge of the board.

 

 

One option is (R1, R2 = 10K-100K; R3, R4, R5 = 1K):

post-26656-0-99734400-1394108900_thumb.png

 

You could simplify it, removing two current limiting resistors, since you will have only one LED on at any time:

post-26656-0-22623500-1394109146_thumb.png

 

And like I mentioned, you need to pull the ADC / analog input down to ground or you may get noise that causes the reading to jump around.

The resistor divider in the schematics above, R2 will do that for you.

 

Anyone, feel free to correct me. :D

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.

×
×
  • Create New...