Jump to content
Forum sending old emails Read more... ×
Sign in to follow this  
RobG

Universal Panel Meter

Recommended Posts

...Any chance you would be willing to share project code for newbsauce like me?

Yes, the code will be posted once it's finished, but it's pretty much the same thing as this one.

 

...I have one question. While working on my meter I noticed that the ADC on the MSP430 has an habit of influencing the "measured" circuit with its impedance. For example in my case a simple voltage divider that brings 0-20V to 0-3.3V is influenced by the ADC input impedance in quite nasty ways.

I do not see anything special in the input channel circuits you have in the schematics that would deal with this issue. Or am I missing something obvious as a novice that I am :) ?

ADC10 has ~2k input resistance and ~27pF capacitance (in series) and this has to be taken into account when designing voltage divider. You have to make sure that the sample time is long enough for the capacitor to be charged to within 1/2 LSB.

What values do you use for your divider?

Share this post


Link to post
Share on other sites

I used initially a 51k/10k divider .. but then as you said I've read the MSP430G2553 data sheet and realised that the input resistance says is around 1K and 27pF capacitance. So I switched to a 4.7K/1k divider which seems to be doing it just right 0-20V becomes a 0-3.5 ish . With these values thing are looking much more normal.

 

To that extent the 1K figure in the data sheet is not exactly true .. (if you look at the TI data sheet for MSP430G2553 @ page 37 says Ri = 1000 ohm) .. from where did you got the approx 2K figure?

 

I am leaning towards using an high impedance precision opamp on inputs ... something like CA3130 or TLE2141.

Share this post


Link to post
Share on other sites

BTW , sorry Rob I feel like I hijacked this thread.

 

Yes it is always recommended .. but if you choose to save few cents for an opamp :) ... a divider is good.

 

BTW, I definitely have the circuits wired right, reading and all code right but I am still puzzled why is the input resistance influencing voltage on this chip. For a sanity check I used an arduino to do the same thing, the measured voltage doe not get influenced in any way. Also as per the equivalent schematic given by TI of the ADC pin Ri should not influence the voltage in any way ... this thing is very weird and contradicts all I know about electronics :)

 

Here is an equivalent input circuit as I have it now:


Vin --+      /--------
     |      | MSP430
     4.7K   |
     |    A1| 
     +------|-Ri/2k--+--ADC sampler
     |      |        |
  1k      |      Ci/27pf
     |      |        |
GND --+      |        |
            \        |
                    GND

 

Now as the schematic with the equivalent shows Ri is decoupled from GND by Ci, therefore it should not influence the input voltage on the divider in any way. That is what theory says ... Now do you have any idea why the MSP430 is doing this. I even changed few chips to make sure is not a bad one .. all do the same.

 

Any idea , good sense says it should work this way with no issues.

Share this post


Link to post
Share on other sites

Here it is .. nothing fancy about it.

 

WDTCTL = WDTPW + WDTHOLD; // Disable watchdog

BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;

/* Set all pins - note that P1.1/BIT1 is set in analog mode by ADC_init() */
P1DIR = 0x00;
P1OUT = 0x00;

      /* init ADC */ 
ADC10CTL0 &= ~ENC; //disable first to make the ADC is in a known state before setup
ADC10CTL0 = SREF_0 + ADC10SHT_2 + ADC10ON + ADC10IE; // Use Vcc/Vss for Up/Low Refs, 16 x ADC10CLKs, turn on ADC with interrupts
ADC10CTL0 &= ~REFOUT;
ADC10CTL1 = INCH_1 + SHS_0 + ADC10SSEL_0 + ADC10DIV_7 + CONSEQ_0; // A1 input, use ADC10CLK div 1, single channel mode, ADC10CLK/16
ADC10AE0 |= BIT1; // Enable ADC input on P1.1
__enable_interrupt();

    // main loop  ---------------------------------------------------
   while(1) {
              delayMiliseconds(1);
	ADC10CTL0 |= ENC + ADC10SC; // start a new conversion
	__bis_SR_register(CPUOFF + GIE); //LPM0 with interrupts continue on interrupt 
	ADC10CTL0 &= ~ENC;
	volts = ADC10MEM * 0.003519062; // 		
	// doing something with volts here 
             delayMiliseconds(998); //make one measurement per second
    }

delays and the interrupt


inline void delayMicroseconds(unsigned int time) {
TACCR0 = time - 1; // Upper limit of count for TAR
TACTL = MC_1 | ID_0 | TASSEL_2 | TACLR; // Set up and start Timer A
while ((TACTL & TAIFG) == 0) {
} // doing nothing
TACTL &= (~TAIFG); // Clear overflow flag
}

inline void delayMilliseconds(unsigned int delay) {
while (delay > 60) {
	delayMicroseconds(60000);
	delay -= 60;
}
if (delay)
	delayMicroseconds((delay << 10) - (delay << 4) - (delay << 3));
}

#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void) {
__bic_SR_register_on_exit(CPUOFF);// Return to active mode
}

Share this post


Link to post
Share on other sites

I really like the look of the display. Do you have the font or the code shared Rob?

My quick & dirty variable bench power supply needs a display for both current and voltage and your project seems to fit very well.

Thanks

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×