Detect power loss on VIN - Netduino Plus 2 (and Netduino Plus 1) - Netduino Forums
   
Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Detect power loss on VIN


Best Answer slackbits, 31 May 2013 - 04:49 AM

I finally found some time to respond to this for future googlers.  I changed up my Google search and substituted Arduino for Netduino, which yielded more results.  

 

Key Pieces of Information:


    [*]The VIN on the Netduino will output the voltage that is put in through the barrel input.  So if you have a 9V power supply it will be ~9V.  When the ND is only powered by USB, there will be ~0V coming out of VIN.  So that gives something to look for to detect the change.  This is different from the Arduinos which output voltage for both USB and external power supplies.
    [*]Any of the analog inputs can measure the incoming volts. NOTE: the analog inputs allow a maximum of 3.3V - another difference from the Arduino which has a max of 5V.
    [*]Placing a voltage divider between VIN and an analog input will allow the voltage to be within safe limits for a analog input.  The formula is Vout = (VIN * R2) / (R1 + R2), where VIN is the voltage in -> connected to a resistor R1 -> connected to a resistor R2 -> connected to Ground.  Vout is "generated" at the connection between R1 & R2 - which is the lower voltage.
    [/list]

    I chose R1 = 6.8K ohm and R2 = 1K ohm so that the ratio is close to 1/8th.  This was based on the fact that the Arduino will output 5V even when powered by USB and would be easier to check for a voltage > 1.  (5/8 < 1 and 9/8 > 1)  Since the Netduino does not have this issue, it should be able to be bumped up.

     

    That being said, I am getting higher numbers on the 9V, but they are not reading as > 1.  Using a voltmeter connected to VIN and ground it is around 8V give or take.

     

    Here is some interesting numbers that I am getting from the sample program below and am still trying to figure out:

    5 Averages from above program

    Reading from A0 with nothing connected: .016, .023, .036, .005, .038

    Reading from A0, VIN connected, USB power: .003, .007, .005, .002, .0032

    Reading from A0, VIN connected, 9V power: .904, .903, .902, .899, .900

     

    Future Enhancements:


      [*]From my searches, it looks like a 3.3V Zener diode would limit the Vout to 3.3V no matter what the Vin is, making sure to never put more current than allowed into the analog input
      [*]Figure out how to get a digital port to read power or no power and skip the whole polling and averaging of samples.  It is either on or off - which is what I actually want.   I believe that any voltage over 2.2V should trigger the digital input to read as a 1 
      [/list]

       

      Circuit: (Since I can't use images, it will have to be text)

       

      VIN----R1---------R2--------GND

                          |

                          |

                         A0

       

       

      In case it is needed, on a bread board you have 3 rows (which should have some space between each row...):

      Row 1: Wire from VIN, R1 

      Row 2: R1, R2, Wire to A0

      Row 3: R2, Wire to Ground

       

      Sample Code:

      using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.NetduinoPlus;using System.Collections;namespace NetduinoTestApp{    public class Program    {        //There are 1024 values that the ADC can read from the analog port (0-1023).        //This sets the maximum value that can be read (e.g. 3.3V        private const int MAX_VALUE = 1023;        private const float ANALOG_REF = 3.30f; //The maximum value the analog port can handle        private const int NUM_SAMPLES = 5;        private const float VOLTS_PER_COUNT = ANALOG_REF / MAX_VALUE; //Defines a constant to map ADC values to Volts        public static void Main()        {            ArrayList items = new ArrayList();            int[] adcDigitalRead = new int[NUM_SAMPLES];            int adcDigitalSum = 0;            float adcAnalogAvg = 0;            // write your code here            using (SecretLabs.NETMF.Hardware.AnalogInput port_A0 = new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A0))            {                //Initialize Array                adcDigitalRead[0] = port_A0.Read();                for (int i = 1; i < adcDigitalRead.Length; i++)                {                    adcDigitalRead[i] = adcDigitalRead[0];                }                                while (true)                {                    //Read multiple values and average them together                    for (int i = 1; i < adcDigitalRead.Length; i++)                    {                        adcDigitalRead[i] = port_A0.Read();                    }                    adcDigitalSum = 0;                    for (int i = 0; i < adcDigitalRead.Length; i++) { adcDigitalSum += adcDigitalRead[i]; }                    adcAnalogAvg = ((float)adcDigitalSum / (float)adcDigitalRead.Length) * VOLTS_PER_COUNT;                    Debug.Print("Averaged Volts: " + adcAnalogAvg.ToString());                    Debug.Print(" ");                    Thread.Sleep(5000);                }            }        }    }}
      Go to the full post


  • Please log in to reply
8 replies to this topic

#1 slackbits

slackbits

    New Member

  • Members
  • Pip
  • 2 posts

Posted 25 May 2013 - 07:10 PM

Hi all, I am fairly new to this stuff. From what I have found on Google, the barrel power input, VIN, and USB can be connected at the same time. If the power disconnects from VIN, then the Netduino will automatically switch over to USB power. Is there an event or way to detect this when it happens? Is there a way to tell the current power source? While I will admit I do not know how to read schematics, it does not look like there is any input connected from the VIN_COMP_LOGIC to the processor. Any help would be much appreciated.

#2 slackbits

slackbits

    New Member

  • Members
  • Pip
  • 2 posts

Posted 31 May 2013 - 04:49 AM   Best Answer

I finally found some time to respond to this for future googlers.  I changed up my Google search and substituted Arduino for Netduino, which yielded more results.  

 

Key Pieces of Information:


    [*]The VIN on the Netduino will output the voltage that is put in through the barrel input.  So if you have a 9V power supply it will be ~9V.  When the ND is only powered by USB, there will be ~0V coming out of VIN.  So that gives something to look for to detect the change.  This is different from the Arduinos which output voltage for both USB and external power supplies.
    [*]Any of the analog inputs can measure the incoming volts. NOTE: the analog inputs allow a maximum of 3.3V - another difference from the Arduino which has a max of 5V.
    [*]Placing a voltage divider between VIN and an analog input will allow the voltage to be within safe limits for a analog input.  The formula is Vout = (VIN * R2) / (R1 + R2), where VIN is the voltage in -> connected to a resistor R1 -> connected to a resistor R2 -> connected to Ground.  Vout is "generated" at the connection between R1 & R2 - which is the lower voltage.
    [/list]

    I chose R1 = 6.8K ohm and R2 = 1K ohm so that the ratio is close to 1/8th.  This was based on the fact that the Arduino will output 5V even when powered by USB and would be easier to check for a voltage > 1.  (5/8 < 1 and 9/8 > 1)  Since the Netduino does not have this issue, it should be able to be bumped up.

     

    That being said, I am getting higher numbers on the 9V, but they are not reading as > 1.  Using a voltmeter connected to VIN and ground it is around 8V give or take.

     

    Here is some interesting numbers that I am getting from the sample program below and am still trying to figure out:

    5 Averages from above program

    Reading from A0 with nothing connected: .016, .023, .036, .005, .038

    Reading from A0, VIN connected, USB power: .003, .007, .005, .002, .0032

    Reading from A0, VIN connected, 9V power: .904, .903, .902, .899, .900

     

    Future Enhancements:


      [*]From my searches, it looks like a 3.3V Zener diode would limit the Vout to 3.3V no matter what the Vin is, making sure to never put more current than allowed into the analog input
      [*]Figure out how to get a digital port to read power or no power and skip the whole polling and averaging of samples.  It is either on or off - which is what I actually want.   I believe that any voltage over 2.2V should trigger the digital input to read as a 1 
      [/list]

       

      Circuit: (Since I can't use images, it will have to be text)

       

      VIN----R1---------R2--------GND

                          |

                          |

                         A0

       

       

      In case it is needed, on a bread board you have 3 rows (which should have some space between each row...):

      Row 1: Wire from VIN, R1 

      Row 2: R1, R2, Wire to A0

      Row 3: R2, Wire to Ground

       

      Sample Code:

      using System;using System.Net;using System.Net.Sockets;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.NetduinoPlus;using System.Collections;namespace NetduinoTestApp{    public class Program    {        //There are 1024 values that the ADC can read from the analog port (0-1023).        //This sets the maximum value that can be read (e.g. 3.3V        private const int MAX_VALUE = 1023;        private const float ANALOG_REF = 3.30f; //The maximum value the analog port can handle        private const int NUM_SAMPLES = 5;        private const float VOLTS_PER_COUNT = ANALOG_REF / MAX_VALUE; //Defines a constant to map ADC values to Volts        public static void Main()        {            ArrayList items = new ArrayList();            int[] adcDigitalRead = new int[NUM_SAMPLES];            int adcDigitalSum = 0;            float adcAnalogAvg = 0;            // write your code here            using (SecretLabs.NETMF.Hardware.AnalogInput port_A0 = new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A0))            {                //Initialize Array                adcDigitalRead[0] = port_A0.Read();                for (int i = 1; i < adcDigitalRead.Length; i++)                {                    adcDigitalRead[i] = adcDigitalRead[0];                }                                while (true)                {                    //Read multiple values and average them together                    for (int i = 1; i < adcDigitalRead.Length; i++)                    {                        adcDigitalRead[i] = port_A0.Read();                    }                    adcDigitalSum = 0;                    for (int i = 0; i < adcDigitalRead.Length; i++) { adcDigitalSum += adcDigitalRead[i]; }                    adcAnalogAvg = ((float)adcDigitalSum / (float)adcDigitalRead.Length) * VOLTS_PER_COUNT;                    Debug.Print("Averaged Volts: " + adcAnalogAvg.ToString());                    Debug.Print(" ");                    Thread.Sleep(5000);                }            }        }    }}


#3 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 724 posts
  • LocationBerkshire, UK

Posted 31 May 2013 - 06:01 AM

Hi Slackbits, Welcome to the forums. Sorry no one replied to your first post. I think the only thing left to say is that the inputs are 5V tolerant. So whilst you can't measure a voltage above 3.3V, you will get a fullscale reading. Yes, since you just need an ON/OFF signal, you can use a digital IO. You will be able to use an interrupt (event) too. The strange readings you recorded will occur when the analogue inputs are left to float, but you added a potential divider, so there must be some current leaking from other places in the power circuit when the barrel is not connected. It might be worth pulling all the other analogue inputs low using a resistor - this can also help clean up the voltage readings. Good bit of detective work and thanks for feeding back your answer to the forum. Have fun - Paul EDIT: Looks like I was wrong to say the analogue inputs are 5V tolerant. The pins are 5V tolerant when they are configured as digital IO, but once they are set to analogue they are not. I hope I have not used up all my luck! See discussions below.

#4 ziggurat29

ziggurat29

    Advanced Member

  • Members
  • PipPipPip
  • 244 posts

Posted 31 May 2013 - 12:36 PM

...I think the only thing left to say is that the inputs are 5V tolerant. So whilst you can't measure a voltage above 3.3V, you will get a fullscale reading. Yes, since you just need an ON/OFF signal, you can use a digital IO. You will be able to use an interrupt (event) too. ...

Paul, don't forget, the analog pins are not 5v tolerant.  Only the digital pins are 5v tolerant.



#5 cutlass

cutlass

    Advanced Member

  • Members
  • PipPipPip
  • 78 posts
  • LocationNew England. :)

Posted 01 June 2013 - 03:28 AM

Paul, don't forget, the analog pins are not 5v tolerant.  Only the digital pins are 5v tolerant.

Very true!  I know that first hand. :)

 

Also, the code that you showed has a minor miscalculation. 

The line
private const int MAX_VALUE = 1023;

should be:

private const int MAX_VALUE = 1024;

 

 

See:

http://forums.netdui...etduino-plus-2/



#6 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 724 posts
  • LocationBerkshire, UK

Posted 01 June 2013 - 05:37 PM

Paul, don't forget, the analog pins are not 5v tolerant.  Only the digital pins are 5v tolerant.

 

Very true!  I know that first hand. :)

 

Hmmm.

 

Looking at the data sheet for the SAM7X512, the absolute maximum voltage rating for input pins is -0.3V to +5.5V.

(Section 38.1 Absolute Maximum Ratings).

It does not distinguish between digital and analogue inputs - hence until now, I have assumed that 5V is OK for the analogue inputs.

 

Later in the data sheet at section 38.7 ADC Characteristics, it does say the maximum input to the ADC is VADVREF.

But, since VADVREF could actually be less than 3.3V, I don't think that this is indicating a voltage where damage might occur, I think this is just indicating the expected range to get the full scale reading of 1023.

 

One other thing to throw in, is that these pins are dual purpose: digital or analogue inputs.

e.g. Analogue input 0 is connected to the ARM pin "PB27/AD0".

 

Having said all that, it sounds like you (cutlass) have had some damage using 5V on the analogue inputs.

Is that true?

Was is permanent?

 

Paul



#7 ziggurat29

ziggurat29

    Advanced Member

  • Members
  • PipPipPip
  • 244 posts

Posted 01 June 2013 - 06:06 PM

Perhaps I am assuming that the OP is using the STM32-based boards!  I sometimes forget about the Atmel ones.



#8 cutlass

cutlass

    Advanced Member

  • Members
  • PipPipPip
  • 78 posts
  • LocationNew England. :)

Posted 01 June 2013 - 10:10 PM

Hmmm.

 

Looking at the data sheet for the SAM7X512, the absolute maximum voltage rating for input pins is -0.3V to +5.5V.

(Section 38.1 Absolute Maximum Ratings).

It does not distinguish between digital and analogue inputs - hence until now, I have assumed that 5V is OK for the analogue inputs.

 

Later in the data sheet at section 38.7 ADC Characteristics, it does say the maximum input to the ADC is VADVREF.

But, since VADVREF could actually be less than 3.3V, I don't think that this is indicating a voltage where damage might occur, I think this is just indicating the expected range to get the full scale reading of 1023.

 

One other thing to throw in, is that these pins are dual purpose: digital or analogue inputs.

e.g. Analogue input 0 is connected to the ARM pin "PB27/AD0".

 

Having said all that, it sounds like you (cutlass) have had some damage using 5V on the analogue inputs.

Is that true?

Was is permanent?

 

Paul

Paul,

Hi!

 

If a pin is in analog-mode, and the input is around 3.6-4+v, it will fry the chip.  My chip now gets very hot after having power for ~5 seconds.  I didn't even get the power supply very high, since the chip stopped sending data back to the PC.  I was seeing how high the voltage had to be before the ADC noise quieted out.  I was being slow and careful not to go over 5V.  I never got near 5V. :-P

 

 

From the thread:

http://forums.netdui...n-on-tolerance/

(I also added that info to my analog example thread)

 

 

Summary:

When a pin is in ADC mode (PC0-PC5 ; pins 8,9,10,11, 24,25), the voltage limits are as follows:

Low: -0.3v

High: +3.6v (3.3v + 0.3v)

 

 

The data sheet is here:

http://www.st.com/st.../DM00037051.pdf

 

The N+2 uses a 64pin STM32F405RG

 

From the data sheet:

 

ADC voltage input specs:

page: 105:

VIL Input low level voltage

Min Vin Low

VIL VSS–0.3v

(VSS is ground.  So, the minimum voltage is -0.3v)

 

Max Vin High
VIH TTa/TC(2) I/O input high level voltage  VDD+0.3

See Note2

2.TTa = 3.3V tolerant I/O directly connected to ADC; TC = standard 3.3V I/O.

 

 

ADC Characteristics:

Table 67

pages: 124,125

 

 

ADC equivalent input schematic:

page: 127

 

Good Luck!



#9 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 724 posts
  • LocationBerkshire, UK

Posted 02 June 2013 - 05:54 AM

Thanks for clarifying that. Looks like I have been lucky not to have had an accident up to now!




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.