When to use Serializer.Run() and Serializer.PumpEvents()
Navigates to RoboticsConnection.com Home RoboticsConnection.com HomePage
RoboticsConnection User Forum
Home       Members    Calendar    Who's On
Welcome Guest ( Login | Register )
        



When to use Serializer.Run() and... Expand / Collapse
Author
Message
Posted Saturday, January 19, 2008 5:41 PM


Supreme Being

Supreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme BeingSupreme Being

Group: Administrators
Last Login: Tuesday, September 02, 2008 9:05 AM
Posts: 270, Visits: 400
For those of you who have used the Serializer .NET library, you have probably seen that there are two ways to allow the library to send out events for the various objects as your application is running.  

You can either use:

1.) Serializer.Run(), or

2.) In an infinite loop, call Serializer.PumpEvents()

Serializer.Run()

The Serializer.Run() method is useful if don't need to perform any processing in between events (such has handle button clicks, read joysticks, invoke other methods or interfaces).  Thus, if you have a simple application where all you want to do is print the output of various sensors values to the screen, and you have nothing else to do, then Serializer.Run() is your command.

using RoboticsConnection.Serializer;
using RoboticsConnection.Serializer.Ids;
using RoboticsConnection.Serializer.Sensors;
using RoboticsConnection.Serializer.Components;
using RoboticsConnection.Serializer.Controllers;
using System;

namespace test
{
   class Program
   {
      static Serializer serializer;
      static GP2D12 irSensor;

      static void Main(string[] args)
      {
          serializer = new Serializer();

          // Sign up for the CommunicationStarted event, so we'll know
          // that the library has established communications w/ the board
          serializer.CommunicationStarted += new SerializerEventHandler(serializer_CommunicationStarted);

          // Create some object:
          irSensor = new GP2D12(serializer);
          irSensor.Pin = AnalogPinId.Pin2;
          irSensor.UpdateFrequency = 50;
          irSensor.DistanceChangedThreshold = 0.5;  

          // Sign up to receive events from the GP2D12 object:    
          irSensor.DistanceChanged += new SerializerComponentEventHandler(irSensor_DistanceChanged);

          serializer.StartCommunication();

          // Enter the run loop, which constantly invokes Serializer.PumpEvents()
          // Communication with the serializer board is started and this thread 
          // is blocked until ShutDown() is called (presumably in an event handler).
          // As PumpEvents() gets called internally, event for various objects, e.g. GP2D12
          // will be signalled, and our handlers below will be invoked.
          serializer.Run();
      }

      // This gets invoked once the Serializer object has established communication
      // with the Serializer board:
      static void serializer_CommunicationStarted(Serializer sender)
      {
          Console.WriteLine("Communication Started.");
      }

      // This gets invoked once the GP2D12 distance has changed
      // more than the threshold amount specified above.
      static void irSensor_DistanceChanged(SerializerComponent sender)
      {
          Console.WriteLine("New gp2d12 distance: {0}", irSensor.Distance);
      }

   }
}

Serializer.PumpEvents()

If you want to perform other processing in between events sent out from the Serializer .NET library, then you'll want to set up your own internal loop, whether it be a while(true) { } loop, or a Timer.Tick() handler (via a Windows Form), and invoke Serializer.PumpEvents() within that loop.  Building on the example above you would then have:

using RoboticsConnection.Serializer;
using RoboticsConnection.Serializer.Ids;
using RoboticsConnection.Serializer.Sensors;
using RoboticsConnection.Serializer.Components;
using RoboticsConnection.Serializer.Controllers;
using System;

namespace test
{
   class Program
   {
      static Serializer serializer;
      static GP2D12 irSensor;

      static void Main(string[] args)
      {
          serializer = new Serializer();

          serializer.PortName = "COM11";

          // Sign up for the CommunicationStarted event, so we'll know
          // that the library has established communications w/ the board
          serializer.CommunicationStarted += new SerializerEventHandler(serializer_CommunicationStarted);

          // Create some object:
          irSensor = new GP2D12(serializer);
          irSensor.Pin = AnalogPinId.Pin2;
          irSensor.UpdateFrequency = 50;
          irSensor.DistanceChangedThreshold = 0.5;  

          // Sign up to receive events from the GP2D12 object:    
          irSensor.DistanceChanged += new SerializerComponentEventHandler(irSensor_DistanceChanged);

          serializer.StartCommunication();

          // Enter an infinite run loop, which constantly invokes Serializer.PumpEvents().
          // This is doing the same thing as Serializer.Run(), however, you get a chance to
          // do other tasks in between the call to Serializer.PumpEvents().
          while(true)
          {
              // Do whatever you need to do here, such as set motor speeds, move servos,
              // make navigation decisions, etc.

              // Invoke Serializer.PumpEvents() so that any outstanding events 
              // that need to be triggered occurs.
              Serializer.PumpEvents();
          }

      }

      // This gets invoked once the Serializer object has established communication
      // with the Serializer board:
      static void serializer_CommunicationStarted(Serializer sender)
      {
          Console.WriteLine("Communication Started.");

      }

      // This gets invoked once the GP2D12 distance has changed
      // more than the threshold amount specified above.
      static void irSensor_DistanceChanged(SerializerComponent sender)
      {
          Console.WriteLine("new gp2d12 distance: {0}", irSensor.Distance);
      }

   }
}

Windows Forms...

If you want to build a Windows Form application, and interface the Serializer .NET library, it's really as simple as adding a Timer object (Components ToolBox) to your form...

setting the timer1 Enabled property to false, setting the Interval property to 10 (for example).   If you enable the timer1 Enabled property to True at this point, a race condition exists, and it may attempt to invoke serializer.PumpEvents() in the timer handler before the serializer object exists.

and adding a handler to handle the Tick event...

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using RoboticsConnection.Serializer;
using RoboticsConnection.Serializer.Components;
using RoboticsConnection.Serializer.Controllers;
using RoboticsConnection.Serializer.Ids;
using RoboticsConnection.Serializer.Sensors;

namespace SerializerTestApp
{
    public partial class Form1 : Form
   
{
        private Serializer serializer;
        private PwmDCMotorController motor;
        private GP2D12 ir;

        public Form1()
       
{
            InitializeComponent();
            serializer =
new Serializer();
            serializer.PortName =
"COM1";
            serializer.BaudRate = 19200;
            serializer.Units =
Units.English;
            serializer.CommunicationStarted +=
new SerializerEventHandler(serializer_CommunicationStarted);

            motor = new PwmDCMotorController(serializer);
            motor.DCMotorId =
DCMotorId.DCMotor1;
            motor.Speed = 0;

            ir = new GP2D12(serializer);
            ir.DistanceChangedThreshold = 0.1;
            ir.Pin =
AnalogPinId.Pin0;
            ir.UpdateFrequency = 50;
// 50 msec
            ir.DistanceChanged += new SerializerComponentEventHandler(ir_DistanceChanged);

            serializer.StartCommunication();
        }

        void ir_DistanceChanged(SerializerComponent sender)
       
{
           
Console.WriteLine("Distance Changed: {0}", ir.Distance);
       
}

        void serializer_CommunicationStarted(Serializer sender)
       
{
           
Console.WriteLine("Communication Started");

            // Enable timer, which is disabeld by default...

            timer1.Enabled = true;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            // Set motor speed based on distance of object
            // in front of ir sensor.
            motor.Speed = (int)(ir.Distance * 3.22);
            // Let library signal outstanding events:
            serializer.PumpEvents();
        }
   
}
}

So, every 100 msec, the timer1_Tick() handler is setting the speed of a motor based on the distance of the object in front of the ir sensor.  Since the speed range of the motor is 0 to 100, and the distance range of the GP2D12 is 4 to 31, the ir distance is scaled by a factor of 3.22 so you can use the full motor speed range for this experiement.   In fact, it's just and example...and the logic isn't really that useful, eh?   Notice that even though the motor speed is being set every 100 msec, the internal distance property for the GP2D12 is being set every 50 msec.  When the distance changes more than the specified threshold specified above, then the DistanceChanged event will occur, and the ir_DistanceChanged() handler will be invoked.



Jason Summerour
President,
Summerour Robotics Corporation
Microsoft MVP
www.roboticsconnection.com
Post #4
« Prev Topic | Next Topic »


Reading This Topic Expand / Collapse
Active Users: 0 (0 guests, 0 members, 0 anonymous members)
No members currently viewing this topic.
Forum Moderators: jsummerour

Permissions Expand / Collapse

All times are GMT -8:00, Time now is 8:13pm

Powered By InstantForum.NET v4.1.4 © 2008
Execution: 0.156. 16 queries. Compression Disabled.