BDCoDE 0 Posted March 26, 2013 Share Posted March 26, 2013 Hi, I'm trying to build a simple Li ion battery capacity tester using this article. The code compiles fine until line 40, where it comes to interrupt handler. What should I use instead? Here is the code where I get errors: ISR(TIMER1_OVF_vect) { TCNT1=0x0BDC; x=!x; measure(); } void setup() { pinMode(LED, OUTPUT); TIMSK1=0x01; // enabled global and timer overflow interrupt; TCCR1A = 0x00; // normal operation page 148 (mode0); TCNT1=0x0BDC; // set initial value to remove time error (16bit counter register) TCCR1B = 0x04; // start timer/ set clock Serial.begin(256000); }; I saw this topic, but I never used assembler before and I don't understand anything there. Quote Link to post Share on other sites
semicolo 39 Posted March 26, 2013 Share Posted March 26, 2013 Not sure about this one since I'm quite new to energia myself. But the sole goal of this interrupt routine is to get fixed intervals so you could get away with delays in the loop. Something like: void loop() { measure(); delay(1000); } Plus the rest to control the led. Also unless you're using an external serial adapter, the LP onboard serial converter allows 9600bps maximum. Quote Link to post Share on other sites
BDCoDE 0 Posted March 26, 2013 Author Share Posted March 26, 2013 So I can use void loop() { measure(); delay(1000); } instead of this? ISR(TIMER1_OVF_vect) { TCNT1=0x0BDC; x=!x; measure(); } But what about the rest. Do you know where I can find the constants Energia uses? P.S Thanks for serial converter advise Quote Link to post Share on other sites
semicolo 39 Posted March 26, 2013 Share Posted March 26, 2013 Yes and remove all the timer stuff from setup So something like this // Very simple Arduino Lithium-ion battery capacity tester // from electronicsblog.net #define LED 13 #define resistor 6.9 float capacity=0, value,voltage,current, time=0; void measure (void) { value= analogRead(0); voltage=value/1024*5.0; current = voltage/resistor; capacity=capacity+current/3600; time++; Serial.print("Voltage= "); Serial.print(voltage); Serial.print("V Current= "); Serial.print(current); Serial.print("A Capacity= "); Serial.print(capacity); Serial.print("Ah "); Serial.print("Discharging time= "); Serial.print(time); Serial.print("s "); Serial.print("\n"); } boolean x=false; void setup() { pinMode(LED, OUTPUT); Serial.begin(9600); }; void loop () { digitalWrite(LED, x); x=!x; measure(); delay(1000); }; BDCoDE 1 Quote Link to post Share on other sites
semicolo 39 Posted March 26, 2013 Share Posted March 26, 2013 For energia constants look into the sources/energia web site/forums Quote Link to post Share on other sites
BDCoDE 0 Posted March 26, 2013 Author Share Posted March 26, 2013 Ok, I'll try it now. Thank you very much Quote Link to post Share on other sites
roadrunner84 466 Posted March 26, 2013 Share Posted March 26, 2013 Your code is ATmega specific (you're directly addressing the timer peripheral of the Arduino), and hence cannot be run at the MSP430/launchpad. You could translate this code to work for the Launchpad. Preferably, abstraction layers hide this platform specific code from you, in this case it didn't happen. #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER1_OVF_vect(void) { x=!x; measure(); } void setup() { pinMode(LED, OUTPUT); // I don't know the ATmega timers, but I will be assuming your timer clock is running at 1MHz and interrupts every 0x10000-0x0BDC = 62500 microseconds (every 62.5 milliseconds) _BIS_SR(GIE); // enabled global interrupt; TACTL0 = TAIE; // enabled timer overflow interrupt; TACTL0 |= MC_1; // normal operation page 366 (mode up); TACCR0 = 62500 - 1; // set overflow value to remove time error (16bit counter register) TACTL0 |= TASSEL_2 + TACLR; // start timer/ reset clock Serial.begin(256000); }; Oh. I see the timer is supposed to interrupt every second, let's rewrite the code a tiny bit: #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER1_OVF_vect(void) { x=!x; if(x) // the interrupt is kicked twice per second, but measure() will be called only half of those times; so once per second { measure(); } } void setup() { pinMode(LED, OUTPUT); TACTL0 = TAIE + MC_3 + TASSEL_2 + TACLR; // Set timer to up mode on SMCLK/8 (125kiHz) TACCR0 = 62500 - 1; // set overflow value to remove time error (16bit counter register) _BIS_SR(GIE); // enabled global interrupt; Serial.begin(256000); }; BDCoDE 1 Quote Link to post Share on other sites
BDCoDE 0 Posted March 26, 2013 Author Share Posted March 26, 2013 Hi, roadrunner84. When I use your code i get this error. batt_tester.cpp: In function 'void setup()': batt_tester.cpp:50:5: error: 'TACTL0' was not declared in this scope Preferably, abstraction layers hide this platform specific code from you, in this case it didn't happen. Is it something like inline assembler? Quote Link to post Share on other sites
roadrunner84 466 Posted March 26, 2013 Share Posted March 26, 2013 Oh, my bad! it sgould be TACTL instead of TACTL0. The TACCR0 should stay as is. No this is not inline assembler, it's just writing to fixed memory locations. BDCoDE 1 Quote Link to post Share on other sites
BDCoDE 0 Posted March 26, 2013 Author Share Posted March 26, 2013 Successfully compiled now. Thanks P.S Get some problems under testing. Here is the schematic I used. R1 = 5 x 68ohm 1/4W conecteted in parallel. And here is the full source code: // Very simple Arduino Lithium-ion battery capacity tester // from electronicsblog.net #define resistor 13 float capacity=0, value,voltage,current, time=0; void measure (void) { value= analogRead(7); voltage=value/1024*5.0; current = voltage/resistor; capacity=capacity+current/3600; time++; Serial.print("Voltage= "); Serial.print(voltage); Serial.print("V Current= "); Serial.print(current); Serial.print("A Capacity= "); Serial.print(capacity); Serial.print("Ah "); Serial.print("Discharging time= "); Serial.print(time); Serial.print("s "); Serial.print("\n"); } boolean x=false; #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER1_OVF_vect(void) { x=!x; measure(); } void setup() { pinMode(GREEN_LED, OUTPUT); // I don't know the ATmega timers, but I will be assuming your timer clock is running at 1MHz and interrupts every 0x10000-0x0BDC = 62500 microseconds (every 62.5 milliseconds) _BIS_SR(GIE); // enabled global interrupt; TACTL = TAIE; // enabled timer overflow interrupt; TACTL |= MC_1; // normal operation page 366 (mode up); TACCR0 = 62500 - 1; // set overflow value to remove time error (16bit counter register) TACTL |= TASSEL_2 + TACLR; // start timer/ reset clock Serial.begin(256000); }; void loop () { digitalWrite(GREEN_LED, x); }; Quote Link to post Share on other sites
roadrunner84 466 Posted March 26, 2013 Share Posted March 26, 2013 I see that loop() only updates the LED, move the line digitalWrite(LED, x); to just after x = !x; and your loop() can be empty, maybe write LPM3; in the loop instead to save power. Quote Link to post Share on other sites
BDCoDE 0 Posted March 26, 2013 Author Share Posted March 26, 2013 Like this? #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER1_OVF_vect(void) { x=!x; digitalWrite(GREEN_LED, x); measure(); } void setup() { pinMode(GREEN_LED, OUTPUT); // I don't know the ATmega timers, but I will be assuming your timer clock is running at 1MHz and interrupts every 0x10000-0x0BDC = 62500 microseconds (every 62.5 milliseconds) _BIS_SR(GIE); // enabled global interrupt; TACTL = TAIE; // enabled timer overflow interrupt; TACTL |= MC_1; // normal operation page 366 (mode up); TACCR0 = 62500 - 1; // set overflow value to remove time error (16bit counter register) TACTL |= TASSEL_2 + TACLR; // start timer/ reset clock Serial.begin(256000); }; void loop () { LPM3; }; I'm using Terminal v1.9b on COM3 (9600,8,Parity =none,Stop bits =1,Handshaking =none) I cant get anything displayed and the resistors get hot. Am I doing it wrong? Quote Link to post Share on other sites
roadrunner84 466 Posted March 26, 2013 Share Posted March 26, 2013 __interrupt void TIMER1_OVF_vect(void) { x=!x; digitalWrite(GREEN_LED, x); if(x) { measure(); } } like this. The resistor is supposed to get hot (I think), because 68 ohwm 5 times parallel is abot 13 ohms. 3.7V / 13 ohms = 272mA. 272mA * 3.7V = 1.007 watt of power you're "burning". Quote Link to post Share on other sites
BDCoDE 0 Posted March 26, 2013 Author Share Posted March 26, 2013 Well, now the LED is ON, before it wasn't. But I still can't get anything in terminal. Is the schematic right when I use "value= analogRead(7);" ? Quote Link to post Share on other sites
semicolo 39 Posted March 26, 2013 Share Posted March 26, 2013 Don't forget to use Serial.begin(9600); 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.