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

Frequency counting and trying to understand what i'm actually doing


  • Please log in to reply
3 replies to this topic

#1 tracstarr

tracstarr

    Member

  • Members
  • PipPip
  • 14 posts

Posted 04 November 2011 - 08:42 PM

So I'm at a bit of a loss trying to get my humidity sensor working. Basically I have the setup found http://starter-kit.n...umidity-sensor/ which involves a frequency counter. So, I've looked at the arduino code and am trying to figure out how to convert that. My understanding is that the humidity is converted to frequency which i need to read. But, I'm not sure how. Also, does it make a difference if i use 3.3v or 5v to the IC in this case? The datasheets say it will take the input. I assume since i'm only dealing with digital here and that the netduino is 3.3v signals that i'm fine.

#2 Stefan W.

Stefan W.

    Advanced Member

  • Members
  • PipPipPip
  • 153 posts

Posted 04 November 2011 - 09:41 PM

I guess you are referring to the method detailed using the 74hc4060. You can either build a loop that polls the input repeatedly for several seconds and count the number of high-low transitions (or low-high, does not matter), or use an InterruptPort and generate interrupts for each transition, enabling your netduino to do something else while you're counting.
I believe that no discovery of fact, however trivial, can be wholly useless to the race, and that no trumpeting of falsehood, however virtuous in intent, can be anything but vicious.
-- H.L. Mencken, "What I Believe"

#3 tracstarr

tracstarr

    Member

  • Members
  • PipPip
  • 14 posts

Posted 04 November 2011 - 10:46 PM

Yes, sorry, using the 74hc4060.I used the same pins and thus dividing the frequency by 1024.

So as a start here's what i've come up with. Any suggestions or thoughts on how to improve it, or if i'm totally wrong here would be great. Running it will get me a value that's the same every time. If i then blow on the sensor (increasing the humidity) the value decreases. So, something is happening. I should point out that my current room reading is 81, and while i blow on it the value decreases. I would have thought that increasing humidity would increase the frequency.

  public class HumiditySensor : Sensor
    {
        private readonly InterruptPort port;
        private Timer timer;
        private int count = 0;
        private int repeat = 0;
        private bool running = false;

        private readonly int calibration0;
        private readonly int calibration100;
        private const int Seconds = 2;
        private readonly Thermistor tempCompensationSensor;

        public override int Value
        {
            get
            {
                if (!Enabled)
                    return -99999;
                              
                return base.oldValue;
            }
        }

        public override void Update()
        {
            if (!Enabled || running)
                return;
                        
            timer = CreateTimer();
            port.EnableInterrupt();
        }

        public HumiditySensor(string name, Cpu.Pin pin, int calibrationConstZero, int calibrationConst100, Thermistor tempSensor = null)
            : base(name)
        {
            this.calibration0 = calibrationConstZero;
            this.calibration100 = calibrationConst100;
            this.tempCompensationSensor = tempSensor;

            port = new InterruptPort(pin, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
            port.DisableInterrupt();
            port.OnInterrupt += port_OnInterrupt;
        }

        void port_OnInterrupt(uint pin, uint state, DateTime time)
        {
            count++;
        }

        protected override string Conversion(int value)
        {            
            // get the temp from the sensor and compensate
            if (tempCompensationSensor != null)
            {
                var temp = tempCompensationSensor.Value;

                // do something with that here.
               
            }

            return "Not Implemented";
        }

        Timer CreateTimer()
        {
            running = true;
            repeat++;

            if (repeat > (this.AverageOver - 1))
            {
                repeat = 0;

                // final reading check
                return new Timer(_ =>
                                {                                    
                                    port.DisableInterrupt();
                                    timer.Dispose();
                                    count = count / (Seconds*AverageOver);
                                    count += Offset;
                                    OnValueChanged(base.oldValue, count);
                                    running = false;
                                    count = 0;
                                },
                                null, new TimeSpan(0, 0, 0, Seconds).Seconds * 1000, Timeout.Infinite);
            }

            

            return new Timer(_ =>
                        {                            
                            port.DisableInterrupt();
                            timer.Dispose();
                            timer = CreateTimer();
                            port.EnableInterrupt();
                        },
                        null, new TimeSpan(0, 0, 0, Seconds).Seconds * 1000, Timeout.Infinite);
        }

    }

 public abstract class Sensor: ISensorCommonSettings
    {
        protected int oldValue = -11111;

        public AnalogInput Input { get; set; }

        public string Name { get; protected set; }
        public int AverageOver { get;  set; }
        public int IgnoreChangesLessThan { get; set; }
        public int Offset { get; set; }
        public int Interval { get; set; }
        public byte[] GraphColor { get; set; }
        public bool Enabled { get; set; }
        public event ChangedValue ValueChanged;        

        public SensorsEnum SensorId { get; protected set; }

        public virtual int Value
        {
            get
            {
                if (!Enabled)
                    return -99999;

                int total = 0;

                for (int i = 0; i < AverageOver; i++)
                {
                    total += Input.Read();
                    total += Offset;
                }

                return total / AverageOver;
            }
        }

        public Sensor(string name)
        {
            Interval = 1;
            Name = name;
            IgnoreChangesLessThan = 1;
            Offset = 0;
            GraphColor = new byte[3] { 0x44, 0xFF, 0x00 };
            Enabled = true;
            SensorId = SensorsEnum.UNKNOWN;
            AverageOver = 1;
        }

        protected virtual string Conversion(int value)
        {
            return "N/A";
        }

        public virtual void Update()
        {
            if (!Enabled)
                return;

            int newVal = Value; // get the current value

            OnValueChanged(oldValue, newVal);
        }

        protected void OnValueChanged(int oldValue, int newValue)
        {
            this.oldValue = newValue;       

            if (ValueChanged == null)
                return;

            if (!((newValue < oldValue - IgnoreChangesLessThan) || (newValue > oldValue + IgnoreChangesLessThan)))
                return;

            ValueChanged(this, oldValue, newValue, Conversion(newValue), DateTime.Now); // if the value has changed more than the filter value then fire the event            

        }

        
    }

EDIT: Updated class and included my base class for example purposes. I'm now counting on both edges and have changed to use pin 14 which divides by freq/256 for higher accuracy.

I still need to account for calibration values and temperature. Currently only spits out the number.

#4 Stefan W.

Stefan W.

    Advanced Member

  • Members
  • PipPipPip
  • 153 posts

Posted 05 November 2011 - 04:47 AM

You don't need the port.ClearInterrupt(); for edge triggers. Also, I'd use two numbers, one for storing the last valid result and one for counting, so your result stays valid during counting ... also, your class lacks a method for an outsider to read the counter ;)

I would have thought that increasing humidity would increase the frequency.

Increasing humidity increases the capacity of the sensor, and since the time constant of RC circuits is - well - R times C, the time constant increases when C increases. Longer time -> lower frequency.

Edit: forgot to say - so when you want something that scales with humidity, use 1/count (times some constant that you have to determine through calibration).
I believe that no discovery of fact, however trivial, can be wholly useless to the race, and that no trumpeting of falsehood, however virtuous in intent, can be anything but vicious.
-- H.L. Mencken, "What I Believe"




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.