Jump to content
43oh

TimerSerial and ADC Problem


Recommended Posts

My understanding is that using TimerSerial the following should print the 2 statements. And it does work as expected, printing both strings.

mySerial.begin();
mySerial.print("Write something\n");
mySerial.end();
mySerial.begin();
mySerial.print("Write something else\n");

The following code does not work as expected.

mySerial.begin();
mySerial.print("Write something\n");

adc_value = analogRead(pin);
mySerial.print(adc_value, DEC);

mySerial.end();
mySerial.begin();
mySerial.print("Write something else\n");

adc_value = analogRead(pin);
mySerial.print(adc_value, DEC);

 

I expected both adc_value's to be the same, but they're not. The first is correct, the second is wrong. The strings do print correctly.

 

This is using 0101E0006 on a 2553 on a Rev. 1.4 Launchpad with the crystal installed.

 

Am I missing something, or have I stumbled across another bug?

 

Thanks,

George

Link to post
Share on other sites

Hey, energia,

 

A simple program to read and print the raw adc_value from TEMPSENSOR

#include 

uint32_t adc_value;

TimerSerial mySerial;

void setup(){
 mySerial.begin();
 analogReference(INTERNAL1V5);
}

void loop(){
 delay(5000); // delay to open monitor

 mySerial.print("\nWrite something\n");

 adc_value = analogRead(TEMPSENSOR);
 mySerial.print(adc_value, DEC);

 mySerial.end();
 mySerial.begin();
 mySerial.print("\nWrite something else\n");

 adc_value = analogRead(TEMPSENSOR);
 mySerial.print(adc_value, DEC);

 mySerial.print("\n");
}

 

The output from looping through the program 4 times:

Write something
74
Write something else
746

Write something
74
Write something else
747

Write something
76
Write something else
761

Write something
76
Write something else
755

Thanks for looking into this,

George

Link to post
Share on other sites

Found the bug. Below is the patch. The issue is that end() is not waiting for all bits to be transmitted.

Thanks for the report! Reporting issues helps us a lot with getting all the bugs out. Keep it up!

 

The 2553 also has a Hardware serial implementation available. The ASCIITable example under File->Examples->4.Communications is a good example to use.

 

Removing the end() and then begin() from the Sketch works around the issue. end() and then begin() are not needed.

 

--- a/hardware/msp430/libraries/TimerSerial/TimerSerial.cpp
+++ b/hardware/msp430/libraries/TimerSerial/TimerSerial.cpp
@@ -63,6 +63,9 @@ void TimerSerial::begin()

void TimerSerial::end()
{
+        while (TACCTL0 & CCIE) {
+               ; // wait for previous xmit to finish
+       }
       P1SEL = ~TX_PIN;        // P1 functions select to default
       P1DIR = ~TX_PIN;        // Input
}

Link to post
Share on other sites

Thanks for the fix. It solved the problem in the sample code.

 

And thanks for the tip about Hardware Serial; I hadn't considered this.

I was using TimerSerial begin() and end() to work around the conflict between TimerSerial and PWM using analogWrite. Hardware Serial seems to solve that problem.

 

Thanks,

George

Link to post
Share on other sites
  • 3 weeks later...

Hi. I can't compile your sketch using MSP430G2231, I get the following error:

 

C:\Users\Dani\Desktop\energia-0101E0006\hardware\msp430\libraries\TimerSerial\TimerSerial.cpp: In static member function 'static void TimerSerial::RxIsr()':

C:\Users\Dani\Desktop\energia-0101E0006\hardware\msp430\libraries\TimerSerial\TimerSerial.cpp:205:16: error: 'TA0IV_TACCR1' was not declared in this scope

 

Best Regards

Link to post
Share on other sites

You could replace TimerSerial::RxIsr with this code:

 

//Timer A1 interrupt service routine
__attribute__((interrupt(TIMERA1_VECTOR)))
void TimerSerial::RxIsr(void)
{
   static unsigned char rxBitCnt = 8;
   static unsigned char rxData = 0;
   // reading TAIV auto-resets the interrupt flag
   volatile uint16_t reset_TAIV = TAIV; (void) reset_TAIV;

   TACCR1 += TICKS_PER_BIT;            // Setup next time to sample
   if (TACCTL1 & CAP) {                // Is this the start bit?
       TACCTL1 &= ~CAP;                // Switch capture to compare mode
       TACCR1 += TICKS_PER_BIT_DIV2;   // Sample from the middle of D0
   }
   else {
       rxData >>= 1;
       if (TACCTL1 & SCCI) {           // Get bit waiting in receive latch
           rxData |= 0x80;
       }
       rxBitCnt--;
       if (rxBitCnt == 0) {            // All bits RXed?
           store_rxchar(rxData);       // Store in ring_buffer
           rxBitCnt = 8;               // Re-load bit counter
           TACCTL1 |= CAP;             // Switch compare to capture mode
           TACCR1 += TICKS_PER_BIT;    // account for the stop bit
       }
   }
}

 

The header file for the msp430g2231.h changed between msp430-gcc version 4.5.3 and 4.6.3 breaking the original code. But to be honest unless you run your msp430g2231 chip at 16MHz, you aren't going to be able to send and receive at the same time. There just aren't enough cycles when you add all the code abstraction overhead.

 

-rick

Link to post
Share on other sites

well, it's a bit weird, but it's working :mrgreen:

 

i haven't learnt how to count in symbols yet, but the program compiles and run :D

 

#include 

TimerSerial mySerial;

void setup()  
{
 mySerial.begin();
}

void loop()
{
 if (mySerial.available()){
  mySerial.write(analogRead(7));
 }
  delay(1000);
}

 

terminal output:

 

 

Link to post
Share on other sites

That output is expected.. Note that you are using TimerSerial.write(). As per API documentation (http://arduino.cc/en/Serial/Write) this will write the bytes binary data to the serial port. If you want something that is readable for us mere humans then use print or println. Also, you seem to want to trigger a read when a character is received from the serial port. Note that you will have to read the buffer otherwise TimerSerail.available() will always return true. Below is a slightly modified version which works for me:

 

#include 

TimerSerial mySerial;

void setup()  
{
 mySerial.begin();
}

void loop()
{
 if (mySerial.available()){
   mySerial.read(); // do a dummy read to empty the buffer.
   mySerial.println(analogRead(10));
 }
  delay(1000);
}

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...