ilpaso 0 Posted September 9, 2013 Share Posted September 9, 2013 hi, I've a msp430g2253 board powered by a battery. I'd like to read the voltage of the battery. I've found a function online (http://blog.elevendroids.com/2013/06/code-recipe-reading-msp430-power-supply-voltage-level/). uint16_t Msp430_GetSupplyVoltage(void) { uint16_t raw_value; // first attempt - measure Vcc/2 with 1.5V reference (Vcc < 3V ) ADC10CTL0 = SREF_1 | REFON | ADC10SHT_2 | ADC10SR | ADC10ON; ADC10CTL1 = INCH_11 | SHS_0 | ADC10DIV_0 | ADC10SSEL_0; // start conversion and wait for it ADC10CTL0 |= ENC | ADC10SC; while (ADC10CTL1 & ADC10BUSY) ; // stop conversion and turn off ADC ADC10CTL0 &= ~ENC; ADC10CTL0 &= ~(ADC10IFG | ADC10ON | REFON); raw_value = ADC10MEM; // check for overflow if (raw_value == 0x3ff) { // switch range - use 2.5V reference (Vcc >= 3V) ADC10CTL0 = SREF_1 | REF2_5V | REFON | ADC10SHT_2 | ADC10SR | ADC10ON; // start conversion and wait for it ADC10CTL0 |= ENC | ADC10SC; while (ADC10CTL1 & ADC10BUSY) ; raw_value = ADC10MEM; // end conversion and turn off ADC ADC10CTL0 &= ~ENC; ADC10CTL0 &= ~(ADC10IFG | ADC10ON | REFON); // convert value to mV return ((uint32_t)raw_value * 5000) / 1024; } else return ((uint32_t)raw_value * 3000) / 1024; } It works but the first time I call the function it uses the 1.5V reference (Vcc < 3V ) and the second time it uses 2.5V reference (Vcc >= 3V). The real voltage is 3,12V What is wrong? Thank you in advance. Regards ilpaso Quote Link to post Share on other sites
semicolo 39 Posted September 10, 2013 Share Posted September 10, 2013 From the comments, it seems you should use a voltage divider (for example maybe 2 100K resistors), so you have VCC/2 on your analog input. The first try is using the 1.5V internal reference, so it's good for voltage below 3V. If the conversion returns 0x3FF, it means that VCC is >= 3V, so the software switches to the 2.5V reference that allows up to 5V for VCC (but of course you can't go higher than 4V on these chips). Quote Link to post Share on other sites
spirilis 1,265 Posted September 10, 2013 Share Posted September 10, 2013 Shouldn't need a voltage divider, there is an on-demand one built in to the ADC (so power isn't wasted when you're not sampling). Will have to try this code later to see what's wrong. Sent from my Galaxy Note II with Tapatalk 4 Quote Link to post Share on other sites
spirilis 1,265 Posted September 10, 2013 Share Posted September 10, 2013 Try getting rid of ADC10SR. You are running the ADC pretty fast and short so it should need the higher buffer strength available when ADC10SR=0 I think. Sent from my Galaxy Note II with Tapatalk 4 Quote Link to post Share on other sites
Register 3 Posted September 11, 2013 Share Posted September 11, 2013 Hi, Voltage without divider? Is there a way to do the same in energia? Thanks Quote Link to post Share on other sites
semicolo 39 Posted September 11, 2013 Share Posted September 11, 2013 It works but the first time I call the function it uses the 1.5V reference (Vcc < 3V ) and the second time it uses 2.5V reference (Vcc >= 3V). The real voltage is 3,12V What is wrong? So are you asking why it's using the 1.5V reference and then the 2.5V one? But in fact it's working ok? Quote Link to post Share on other sites
semicolo 39 Posted September 11, 2013 Share Posted September 11, 2013 Voltage without divider? Is there a way to do the same in energia? Maybe with analogRead (11), this should set ADC10CTL1 correctly and reset ADC10AE0 completely. Maybe I'll have some time to try it at lunchtime. Maybe there's already a constant for this in energia. Quote Link to post Share on other sites
ilpaso 0 Posted September 11, 2013 Author Share Posted September 11, 2013 Thank you for the replies. It works in Energia but the first time the function uses the 1.5V reference cycle and the second it uses the 2.5V reference cycle and so on. I'll try with analogRead (11) this evening. Quote Link to post Share on other sites
semicolo 39 Posted September 11, 2013 Share Posted September 11, 2013 Ok, then as I explained in my first response, it first tries with 1.5V reference to get a better reading, if it overflows it switches to 2.5V reference. Quote Link to post Share on other sites
semicolo 39 Posted September 11, 2013 Share Posted September 11, 2013 It seems to be working, the following sketch gives me 3.5V with USB VCC void setup() { Serial.begin(9600); // msp430g2231 must use 4800 Serial.println("VCC value:"); analogReference(INTERNAL2V5); } void loop() { long data = map(analogRead(11), 0, 1023, 0, 500); Serial.print (data/100); Serial.print ("."); Serial.println (data%100); // this is wrong if the tens are 0 delay(1000); } Register 1 Quote Link to post Share on other sites
nemetila 12 Posted September 11, 2013 Share Posted September 11, 2013 Based on the MSP430G2553 datasheet, the 1.5V ref requires Vcc>= 2.2V and the 2.5V ref requires Vcc >= 2.9V to operate. If your Vcc is below 2.9V you can't use 2.5V ref. So this code first uses the 1.5V ref to check Vcc. semicolo 1 Quote Link to post Share on other sites
semicolo 39 Posted September 11, 2013 Share Posted September 11, 2013 Makes sense, it'd be hard to generate a 2.5V reference with a 2.4V VCC. Quote Link to post Share on other sites
Register 3 Posted September 12, 2013 Share Posted September 12, 2013 Makes sense, it'd be hard to generate a 2.5V reference with a 2.4V VCC. Not if there a voltage regulator embedded? And why pin 11? Quote Link to post Share on other sites
spirilis 1,265 Posted September 12, 2013 Share Posted September 12, 2013 Not if there a voltage regulator embedded? And why pin 11? Voltage regulators can only lower voltages... For analogRead the value isn't really the Energia pin# but rather the ADC channel (INCH_xx constant), 11 just happens to be an internal "(Vcc-Vss)/2" generated channel used for measuring the MSP430's Vcc voltage. Sent from my Galaxy Note II with Tapatalk 4 Register 1 Quote Link to post Share on other sites
semicolo 39 Posted September 12, 2013 Share Posted September 12, 2013 Well it's possible to generate higher voltages with a dc/dc boost converter for example, I just don't know if it's even possible to embed something like that in a chip without external components and keeping the power usage and costs low. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.