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

Button click logging


  • Please log in to reply
16 replies to this topic

#1 meterMan

meterMan

    Member

  • Members
  • PipPip
  • 25 posts

Posted 17 January 2012 - 10:53 PM

Hi Guys, I received a Netduino starter kit today from Oomlout. Its a great little gizmo for learning electronics and programming. I stumbled across this after lurking on the Raspberry Pi forum. Didn't want to step into C with the Arduino so it was refreshing to see a .net microframework variant (im a Microsoft fanboy). Just working through the accompanying experiments guide has given me a good rounding in resistors, transistors and other basic components that i didn't have before. Although already I feel like I should have got the Plus version with the SD card slot and ethernet. The plan is to play around with data logging, by interfacing with a SD card slot, or perhaps even a Zigbee radio to throw data to a remote location. Also not having a real time clock is always going to be a limitation when logging data. (Although I know there are third party shields that can plug in to give me RTC and SD slot) Anyway, what i would like to do is record how many button clicks there are within, say, a 5 minute interval. And store that value somewhere. How would I do this?

#2 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 18 January 2012 - 05:03 AM

Hello MeterMan.
Recording an event and log it on a SD is trivial, unless you don't need high precision on timing.

Here is an example, but *I DIDN'T TRIED IT*...
Be sure to add these "using" clauses:



using System.IO;
using System.Text;

Then try to play around this base:



    public class Program
    {
        private const TimeSpan Interval = TimeSpan.FromTicks(TimeSpan.TicksPerMinute * 5);
        private static int _counter;
        private static Timer _timer;


        public static void Main()
        {
            //create and start the timer
            _timer = new Timer(
                TimerTick,
                null,
                Interval,
                Interval);

            //provide your own logic to increment the counter

            //example: using the onboard button
            var sw = new InterruptPort(
                Pins.ONBOARD_SW1, 
                true, 
                Port.ResistorMode.PullUp, 
                Port.InterruptMode.InterruptEdgeLow);

            sw.OnInterrupt += new NativeEventHandler(sw_OnInterrupt);

            //block the program flow, otherwise the application will end
            Thread.Sleep(Timeout.Infinite);
        }


        static void sw_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            _counter++;
        }


        private static void TimerTick(object state)
        {
            WriteData(_counter);
            _counter = 0;
        }


        private static void WriteData(int data)
        {
            var fileName = @"\\SD\\root\MyTextFile.txt";

            //open the specified file for append, and as a stream
            using (FileStream stream = File.Open(fileName, FileMode.Append))
            {
                //convert the given data to string, then to a byte array
                string text = data.ToString();
                byte[] buffer = Encoding.UTF8.GetBytes(text);

                //write the buffer onto the file stream
                stream.Write(buffer, 0, buffer.Length);
            }
        }
    }

It's far to be perfect, but it should be a good point where start from.
Cheers
Biggest fault of Netduino? It runs by electricity.

#3 meterMan

meterMan

    Member

  • Members
  • PipPip
  • 25 posts

Posted 18 January 2012 - 07:48 PM

Thanks very much. Could you provide a bit more about using the Timer? What is TimerCallBack and how do i use it?

#4 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 19 January 2012 - 05:22 AM

Oh, well...the "Timer" class is such a proxy for firing events at a certain interval. Let's see the details:

public Timer (
    TimerCallback callback,     	
    Object state,     	
    TimeSpan dueTime,
    TimeSpan period)



The first parameter is the TimerCallback delegate. A delegate is much like a definition of a method signature, or -if you like better- the definition of the target of a function-pointer (that's improper, but my fellow understands better, since is a C/C++ programmer).
Bear in mind that the C# is a strongly-typed programming language, so you can't do anything that won't be strictly under control.
So, the TimerCallback represents the signature of the method which handles the events fired by the timer itself. Note that the name of the method hasn't any relevance, but the types involved do.
In my snippet I didn't explicitly used the TimerCallback delegate as often is used. The typical form is as follows:

_timer = new Timer(
    new TimerCallback(TimerTick),
    null,
    Interval,
    Interval;
The "state" parameter is a commodity argument to pass in the event handler. It's worthwhile to point out that the handler runs is a different thread other than the others running. So, the very best practice would be to pass data from/to the timer handler through the "state" parameter.

Finally there are two intervals: dueTime and period. The first one is actually the period which has to elapse from the timer activation to the *first* event firing. Instead, the "period" is related to the interval that should observed for all the further events.

Again, it's important to remember that the timer is a mechanism running in a dedicated thread, at low-level. So, the threading system doesn't know about the upper C# management, and the user should take in account that.
So, there are just two important things to avoid to be forgotten:
  • the event handler is running in a different, reserved thread other than the rest of the application, and
  • once you don't need the timer instance anymore, you should Dispose it.
I'm using this pattern to dispose effectively the timer instances:

_timer.Change(Timeout.Infinite, Timeout.Infinite); //this stops the timer
_timer.Dispose();

This ensures the correct deletion of the timer. Note that there's no way to guarantee that an extra-spurious event can't be fired. This might happen especially when the timer intervals are short. Thus, you should apply some other prevention mechanism, such a flag or else.

Hope it helps.
Cheers
Biggest fault of Netduino? It runs by electricity.

#5 meterMan

meterMan

    Member

  • Members
  • PipPip
  • 25 posts

Posted 19 January 2012 - 01:22 PM

Thanks again. Timers and timercallback confuse the hell out of me. Im going to play around with this and see if I can make something happen.

#6 meterMan

meterMan

    Member

  • Members
  • PipPip
  • 25 posts

Posted 19 January 2012 - 07:57 PM

Ok, im almost there. The only problem im having now is that when i press the button it seems to increment the counter by more than 1. If i repeatedly tap the button it increments very high quite quickly.

#7 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 19 January 2012 - 10:59 PM

The only problem im having now is that when i press the button it seems to increment the counter by more than 1.

You may get some ideas by searching the forum for "bounce" and "debounce", this problem has been already discussed several times and there are working code samples...

#8 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 20 January 2012 - 04:14 AM

I've created the AutoRepeatInputPort just for this purpose.
The class goal is as a helper for a pushbutton input. It acts as debouncer, whereas auto-repeater if needed.
Hope that could help.
Cheers
Biggest fault of Netduino? It runs by electricity.

#9 meterMan

meterMan

    Member

  • Members
  • PipPip
  • 25 posts

Posted 23 January 2012 - 04:26 PM

Where exactly do I find the class? Your link only shows the sample code...

#10 Stefan

Stefan

    Moderator

  • Members
  • PipPipPip
  • 1965 posts
  • LocationBreda, the Netherlands

Posted 23 January 2012 - 04:30 PM

Where exactly do I find the class? Your link only shows the sample code...

Click on the big download-button @ http://netmftoolbox....ol/BrowseLatest ;)
"Fact that I'm a moderator doesn't make me an expert in things." Stefan, the eternal newb!
My .NETMF projects: .NETMF Toolbox / Gadgeteer Light / Some PCB designs

#11 ItsDan

ItsDan

    Advanced Member

  • Members
  • PipPipPip
  • 101 posts

Posted 23 January 2012 - 04:57 PM

Also depending on what you have the interrupt detecting you may be recording constantly when the button is pressed instead of just when it changes to high.
Follow the adventures of the Box of Crappy Surplus

Total BOCS Traveled Distance: 9708 miles | States Visited: 5
Track the Box

#12 meterMan

meterMan

    Member

  • Members
  • PipPip
  • 25 posts

Posted 23 January 2012 - 05:02 PM

Thanks Stefan, can't believe I missed that! On a different note, I have a button and an LED. When I press the button, the LED goes on, and when I release it goes off. How would I go about starting a stopwatch class when the button is clicked, and stopping when released? Ive been trying all sorts of logic and can't seem to get anywhere. I already have the stopwatch class code from somewhere on this forum.

#13 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1768 posts
  • LocationVenezia, Italia

Posted 23 January 2012 - 05:25 PM

What's the purpose of the stopwatch? EDIT: I mean: how do you think to use it?
Biggest fault of Netduino? It runs by electricity.

#14 CW2

CW2

    Advanced Member

  • Members
  • PipPipPip
  • 1592 posts
  • LocationCzech Republic

Posted 23 January 2012 - 07:37 PM

How would I go about starting a stopwatch class when the button is clicked, and stopping when released?

private static InterruptPort button;

public static void Main()
{
  button = new InterruptPort(Pins.ONBOARD_SW1, true, ResistorModes.PullUp, InterruptModes.InterruptEdgeBoth);
  button.OnInterrupt += button_OnInterrupt;

  Thread.Sleep(Timeout.Infinite);
}        

static void button_OnInterrupt(uint data1, uint data2, DateTime time)
{
  // data2 is the pin state
  if(data2 == 1)
  {
    // Button pressed
    stopwatch.Start(); // or StartNew()
  }
  else
  {   		
    // Button released
    stopwatch.Stop();
  }
}

You can also use the time parameter passed to the interrupt handler, it contains the time at which the event occured.

#15 mutsop

mutsop

    Advanced Member

  • Members
  • PipPipPip
  • 30 posts

Posted 24 January 2012 - 07:55 AM

Aha now I understand why the pushbutton fires several times! thanks for bringing up this post :)

#16 meterMan

meterMan

    Member

  • Members
  • PipPip
  • 25 posts

Posted 24 January 2012 - 04:33 PM

Good stuff all. How do I write to the SD Card? The example code above doesn't work for me. Filestream is not recognised. Are you sure those are the right references to use it?

#17 meterMan

meterMan

    Member

  • Members
  • PipPip
  • 25 posts

Posted 24 January 2012 - 04:39 PM

I've put together the Adafruit data logging shield. I think my soldering is OK but im not expert. I've imported the references NETMF.io.dll. Everytime I go to debug i get System.NotSupportedException error. Ive tried a few different SD cards and im sure thats not the issue. How do I check that Ive constructed the shield properly?




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.