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 To Voltage Conversion with Netduino - Software or Hardware Suggestion?

frequency voltage FVC lm331 pulse detection frequency to voltage threading

  • Please log in to reply
12 replies to this topic

#1 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 28 January 2014 - 08:25 PM

Hey Guys,

 

I'm wondering if anyone has done some frequency to voltage stuff with a Netduino with or without any additional hardware.

 

I've gotta detect and display the frequency from an input in the range of 10Hz-350Hz. Or a period range of 75mS to 2.5mS appx. 

 

Was thinking about running a while loop for something like 100mS and detecting the signal pulses via interrupts and calculating the time difference and then displaying the data appropriately. Rinse and repeat. 

 

Then, I was reading about processing speeds of netduino and thought that a frequency to voltage IC might reduce the load on the Netduino and make things a little faster. With that I do a simple analog read and then display my data. I was looking at the TI LM331 Frequency Voltage Converter. While they claim easy to use, I'm not exactly sure that I understand exactly how to use it. Seems like I need some additional hardware (Resistors and Caps) to tune the circuit for my frequency range?(Also I was reading in the document that FVC mode is not "fast")

 

Any thoughts or ideas on the best way to accomplish this? Should I just keep it in software? Any hardware examples.

 

Also, what's the best way in netmf to run while loop for a specific amount of time. Also, If I put a 100mS loop into a thread, it will run in 5 sections, right? Unless, this is the only thread running, right?

 

 

Thanks!



#2 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 29 January 2014 - 08:16 AM

Hello.

First off, the LM331 is a voltage-to-frequency and not vice versa: I think that won't fit your deal.

Secondly, is the input signal squared? I mean "boolean"...if not, you'd need an input stage that "squares" a sine wave, for instance.

 

If you are not scared about a little extra hardware  connected to the Netduino, you may have a good precision frequency meter without any problem regarding the inaccuracy of the managed framework.

Simply consider a counter clocked by the desired signal. Now, consider a time-window of just one second, for instance. At t=0 the counter is reset, then the input signal clocks up to a certain value: at t=1s the count reached is the frequency you need to know.

 

Hope it helps.


Biggest fault of Netduino? It runs by electricity.

#3 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 29 January 2014 - 03:27 PM

Hello.

First off, the LM331 is a voltage-to-frequency and not vice versa: I think that won't fit your deal.

Secondly, is the input signal squared? I mean "boolean"...if not, you'd need an input stage that "squares" a sine wave, for instance.

 

If you are not scared about a little extra hardware  connected to the Netduino, you may have a good precision frequency meter without any problem regarding the inaccuracy of the managed framework.

Simply consider a counter clocked by the desired signal. Now, consider a time-window of just one second, for instance. At t=0 the counter is reset, then the input signal clocks up to a certain value: at t=1s the count reached is the frequency you need to know.

 

Hope it helps.

 

Thanks for the reply and the idea. Regarding the LM331, there is some Frequency to Voltage circuits starting on the bottom of page 9 in the datasheet.

 

The input signal may or may not be squared. I'm actually waiting to get a scope on the signal, but I'm expecting it to be square.

 

The counter idea seems like it would work. Do you have any suggestions for the counter hardware? Also, I'd like to have a near instant response of the frequency display on the Netduino. Something in the order of 100mS or so for sampling time.



#4 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 30 January 2014 - 12:10 AM

On a side, I decided to play around and do a software frequency calculation using the interrupt method and capturing two interrupts and subtracting the DateTime values from each to calculate the period. I'm using a PWM pin connected directly to an Interrupt port. I also have a 10k potentiometer hooked up to let me control the frequency from 50hz - 350hz.

 

It seems to be working.

 

Here's the code I'm using(is the the correct way?):

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.Netduino;namespace NetduinoApplication1{    public class Program    {        static PWM PWMpin = null;        static double Freq;        static DateTime time;        static DateTime T1;        static DateTime T2;        static long Period;        static TimeSpan TS;        static InterruptPort sensor = null;        static AnalogInput Potentiometer = null;        static int intercount;        public static void Main()        {            //init pins            PWMpin = new PWM(PWMChannels.PWM_PIN_D3, 250, .5, false);            PWMpin.Start();            Potentiometer = new AnalogInput(AnalogChannels.ANALOG_PIN_A0);            var milli = System.DateTime.Now.Millisecond;            Debug.Print(milli.ToString());            Thread.Sleep(100);            milli = System.DateTime.Now.Millisecond;            Debug.Print(milli.ToString());            sensor = new InterruptPort(Pins.GPIO_PIN_A3, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeHigh);            sensor.DisableInterrupt();            sensor.OnInterrupt += new NativeEventHandler(sensor_OnInterrupt);            intercount = 0;            TS = new TimeSpan();            while (true)            {                PWMpin.Frequency = ReadPinToFrequency(Potentiometer);                intercount = 0;                sensor.EnableInterrupt();                while (intercount < 2)                {                     }                sensor.DisableInterrupt();                Period = T2.Ticks - T1.Ticks;                Freq = 1 / (Period*0.0000001);//Ticks to Seconds to Hz                Debug.Print("   Period:" + Period.ToString()+ " ticks");                Debug.Print("       Frequency: " + Freq.ToString("f2")+"Hz");            }        }        static void sensor_OnInterrupt(uint data1, uint data2, DateTime time)        {            intercount++;            if (intercount == 1)            {                T1 = time;            }            else if (intercount==2) //edit from just "else"             {                T2 = time;            }        }        static double ReadPinToFrequency(AnalogInput InputPin)        {            int raw;            double rawToFreq;            raw = InputPin.ReadRaw();            rawToFreq = raw/11.7;            Debug.Print("Pot Value: "+ raw.ToString());            if (rawToFreq<50) rawToFreq=50;            Debug.Print(" PWM Frequency: " + rawToFreq.ToString("f2"));            return rawToFreq;        }    }}

The interesting thing is, when I change the line rawToFreq = raw/11.7 to something like "=raw" then I quickly run out of memory in the debugger. Why is that? It seems like much higher frequencies can be measured... I wonder if the interrupts are causing this. I have DisableInterrupt; Is that enough?



#5 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 30 January 2014 - 12:44 PM

I believe that a too tight interrupt triggering cause an internal mess. I noticed something similar in the past.

 

Anyway, here is a possible way:

http://www.nxp.com/d...eet/PCF8593.pdf

It is a real-time clock chip, but it should be used as pulse counter, so no other parts but the chip itself. The actual value may be read via I2C.

 

I think it would be hard to read reliably the frequency value at a 100ms rate, though. The shorter is the rate, the higher is the error due to the managed framework timing inaccuracy.

How accurate do you need the frequency value, in percent?


Biggest fault of Netduino? It runs by electricity.

#6 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 30 January 2014 - 09:15 PM

I believe that a too tight interrupt triggering cause an internal mess. I noticed something similar in the past.

 

Anyway, here is a possible way:

http://www.nxp.com/d...eet/PCF8593.pdf

It is a real-time clock chip, but it should be used as pulse counter, so no other parts but the chip itself. The actual value may be read via I2C.

 

I think it would be hard to read reliably the frequency value at a 100ms rate, though. The shorter is the rate, the higher is the error due to the managed framework timing inaccuracy.

How accurate do you need the frequency value, in percent?

 

Interesting. I was searching for counter I2C chip and not much came back. That looks good. I also plan on using a DS1307 as part of my project. 

 

So for this chip as an example, I feed the pulse into the oscillator pin 1, hook up v+ and ground and the reset and i2c. Read the counts via i2c and then reset the chip?

 

Also, I intend on using the DS1307 as I expand my project as well. I could use the memory on it to store settings.

Accuracy I need is probably something along the lines of +-1%



#7 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 31 January 2014 - 04:42 AM

Nah!...If you need 1% you won't have with managed code.

At this point I'd suggest to use a tiny MCU instead the counter. Watch at this, for instance:

http://www.hobbytron.../arduino-attiny

I've seen small boards (just a stamp) using the AT-Tiny microcontroller, which is a little-bother of the AVR (Arduino). The size is the same (8 pin DIP), so you may connect easily to the Netduino.

Doing so, you may do whatever you want, and forget any issue related to the managed code.


Biggest fault of Netduino? It runs by electricity.

#8 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 31 January 2014 - 04:33 PM

Now we're talking! I'm into this idea. Attiny85..I've got a duemillanova that I can use...Seems like a cleaner solution, IMO.

 

I like this one:

Posted Image

 

So, the compatible arduino code is also listed here too:

http://highlowtech.org/?p=1695

 

So I could use PulseIn() and then ShiftOut()... What would the code look like on the Netduino to make them communicate correctly? Any examples?

 

Thanks!!



#9 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 31 January 2014 - 06:03 PM

Honestly, I never used the ATtiny, but the normal Arduino. The little-bro looks like a subset of internal components that the classic AVR has. So, from the programming perspective, I believe there's a minimal difference.

Probably the hardest task is making the chip communicate with the PC, that is uploading the program and testing it.

http://www.atmel.it/...5_Datasheet.pdf

 

For the frequency meter function, I think you have several ways...

Using the 8-bit counter (section 11), which does the dirty job for you: on every pulse the logic counts up, and all you have to do is calculating the frequency sampling the counter's value on every 100ms. That is, if you read N in the counter, the actual frequency will be N*10.

That's very simple to do, but it's also clear that you can't reach the 1% of accuracy goal.

 

Measuring the wave period with the same 8-bit counter, but fed by the system clock. Of course, you have to manage some software-extension to the counter itself, in order to achieve, let' say, 16-bits. So, whereas the longest period is 100ms (10Hz), the counter shouldn't overflow the 64k available ticks. If the counter is clocked at 500k, for instance, should be fine.

By the way, when the input frequency is 350Hz, its period is about 3ms. Since the clock is, as supposed, 500kHz, the counter should reach a value of about 1500. In this case the accuracy of 1% is guaranteed.

 

About the data exchange with the Netduino, I think the serial (section 15) would be fine.

 

Hope it helps.

Let me know!


Biggest fault of Netduino? It runs by electricity.

#10 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 01 February 2014 - 10:18 PM

Mario Thanks!

 

I've started to play with this and am somewhat stuck at the communication from Arduino to Netduino.

 

First, I'm using pulseIn() with the Arduino and getting error +-.6% for the frequency. I'm very cool with that error. pulseIn() returns a 32bit uLong, so I break that up into a Byte Array with 4 slots and do some bit shifting to get the array correctly setup.

 

Now, the Arduino has shiftOut which is some software implemented SPI(I think). It has a Latch, Clock, and Data output pins. Seeing that Netduino GPIO are 5v tolerant, I can directly hook these up, but wondering what is the right/best/easiest way to read the bytes into the Netduino. I'm a little lost at this point.

 

But things are looking good so far...I've got some ATtiny85 chips on order and going to build the programmer circuit this week.

 

Thanks!!!

 

Edit:

 

Here's the Arduino shiftOut code:

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val){      uint8_t i;      for (i = 0; i < 8; i++)  {            if (bitOrder == LSBFIRST)                  digitalWrite(dataPin, !!(val & (1 << i)));            else                        digitalWrite(dataPin, !!(val & (1 << (7 - i))));                              digitalWrite(clockPin, HIGH);            digitalWrite(clockPin, LOW);                  }}

Wondering how to sync the clock pin toggle without interrupts..then I'm back at the same problem... Maybe shiftout won't work? Is there another interface in Netduino?



#11 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 02 February 2014 - 04:38 AM

At a glance...

The pulseIn function measures the high or low period (upon the parameter), but not the whole period: are you sure on the duty cycle?

The shiftOut function manages kinda SPI as master, but the Netduino does not support the SPI as slave. I'd rely on the ATtiny USI interface which allows you to transfer data as a UART (I'd choose that), as I2C-slave or SPI-slave.

Remember that the Netduino is far slower than an Arduino: either you slow the ATtiny a lot (plus tedious sync'ing), or you leverage some hardware component already present in both the chips.

Ciao


Biggest fault of Netduino? It runs by electricity.

#12 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 02 February 2014 - 05:47 PM

Regarding pulseIn: Yea, I realized that after initially testing it was only half the time with a 50% duty cycle PWM in, so I multiplied by two and got the correct period/frequency. It's probably not the correct function for my purpose as you say regarding input duty cycle and I only want to measure time between pulses, but it does show speed ability to read the frequency range I'm looking for which is hopeful. I'll need to test the actual signal.

 

I did a little research on I2C slave with arduino and the ATtiny and found quite a few links and forks in the code/drivers.

 

These seem to be a good start(I've sifted through a lot of articles)

 

 

I will keep  updating this thread with my progress. Once I get this ATtiny setup with I2C slave, I'll attempt to hook it up to the Netduino.

 

Thanks!



#13 gismo

gismo

    Advanced Member

  • Members
  • PipPipPip
  • 110 posts

Posted 12 February 2014 - 11:06 PM

Well, I jumped into the ATtiny85 chip head first. I was pretty excited about it. Small investment, got a few chips and the USBTinyISP AVR programmer. For a few bucks more, I got a completely soldered stand-alone unit and breakout board for testing. Simple.

 

Anyway, got deep into the ATTiny85, and needed to get into the Timers beneath Arduino. I figured that out and got the Tiny to count from an external signal/pulse and factor in overflows in case there was more than 255 pulses. I was excited. Now I need to Attiny85 to communicate with Netduino. The wall I ran into was that Timer0, the one counting, is also the same pin for the serial clock(USI) which is used by I2C and SPI(an 1-wire) Was maybe thinking of another way to get the data out and into Arduino. Maybe ADC, but then there's not enough resolution to get the accuracy that I want. So I'm looking for a possible work around. I'm looking at moving up to an ATtiny84 which has a few more pins and which Timer0 and the USI clock are on different pins which means I could communicate better.

 

Lastly, I'm circling back to the Netduino after exploring the lower levels of the AVR and tweaking the tiny chip to my needs. After scanning the datasheet, it seems that the Netduino mcu is more than capable for what I want if I can get deeper into the chip. I've made another thread to discuss that potential.

 

I'll post some updates if I get an ATTiny84 or the 85 to work.







Also tagged with one or more of these keywords: frequency, voltage, FVC, lm331, pulse detection, frequency to voltage, threading

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.