This is a virtual frequency scanning interferometer implementation for measuring the index homogeneity and surface figure of an optical substrate. This code implements the technique described by Leslie Deck with the Zygo corporation. Here is a link to the original paper by Deck:

https://www.osapublishing.org/ao/abstract.cfm?uri=ao-42-13-2354

This is a way to build an interferometer using a frequency scanning source, where phase shifting is not necessary.

This is not an example of excellent programming, but of the implementation of a tricky physics and mathematical system. I wrote this long ago, and write much better software every day.

FYI, this is rather old, it was written in 2008... I have updated it so you can download it and compile and run in Visual Studio 2017.

 

https://github.com/rettconsulting/Interferometer

 

interferometer

A tilt hydrometer is this little device that acts as a bluetooth low energy beacon, ie, it acts like Apple's iBeacon doodas. So you don't have to pair to the device to read it. It just spews out data every second or so, and if you are listening, you can receive the data. 

 

https://kvurd.com/blog/tilt-hydrometer-ibeacon-data-format/

https://tilthydrometer.com/

 

This device has a battery, an accelerometer, and a thermometer. So, based on the angle that it floats in a liquid, using the accelerometer and gravity, it can tell you the specific gravity of the liquid, and of course the temperature. Good for brewing beer! But also good for other things, such as monitoring various process fluids in a production plant. Think CNC coolant, polishing slurry, etc. 

So, how do you read these things in Windows 7? What, you have learned that the bluetooth low energy stack is only implemented in Windows 10? You like linux, but you have a bunch of Win7 machines running all of the stuff in your plant?

Fear not. Thanks to Wouter Huysentruit, who has written a BLE stack that runs fine in Windows 7. You can download Visual Studio Community Edition 2017, and start developing C# .NET apps on Windows 7 that read iBeacon devices. Great!

 

https://github.com/huysentruitw/win-beacon

 

I bought the Pluggable BT Radio Dongle and the thing works right out of the box. Just plugin in the dongle, switch to the WinUSB driver, get the source code from github, open the solution, and run it. Voila! Also, you can make your BLE dongle act as an iBeacon device (transmitter) as well. 

I wrote a little wrapper that makes an object which references the win-beacon package that fires off an event that you can subscribe to from a parent class or app that looks about like so:

 

 

Hello,

 

This github is pretty much in its infancy as I have been doing other things since I was motivated to start it.

 

I am in the process of creating an open source, GPL-3.0 licensed repository so I can share some of my various labors and problem solving source code. 

 

The most interesting project is a virtual demonstration of Fourier-Transform Phase-Shifting Interferometry. 

 

See the original paper by Leslie L. Deck of the Zygo corporation:

https://www.zygo.com/library/papers/AO_42_13_2354.pdf

 

This is written in C++ about 10 years ago. It is not an example of great coding skills, but of the implementation of a tricky physical / mathematical system.

 

https://github.com/rettconsulting

 

This will include:

 

  • Fourier-transform frequency-scanning interferometry
  • iBeacon receiver / transmitter for Win7 as a simple wrapper for win-beacon.
  • C# image processing library. I have written and re-written many functions, so I need to get it all together in one library. 
  • Other stuff.

 

Windows Services are useful for various reasons. Using the singleton implementation to wrap up a hardware device has proven very useful to collect data for example. Another main use is to create daemons that poll network sensors and collect data and stuff it into a database.

What if your daemon has a rare bug that you cannot replicate consistently? Well, as tech support always tells you to reboot as a first line of defense. How can you get a service to restart itself? Why would I want to do this you ask? Well for the sensor daemon for example, it spins up a bunch of threads that have different drivers. I had a problem where some extremely rare bug was crashing my service, and I could not figure out how to debug it.

Now that I am more wise I would probably go in and improve exception handling and logging and maybe figure it out... But easier just to restart the thing, to kill all the threads, and spin them back up again.

Initially, I used windows tasks externally to run a batch file, that called "net stop service" then "net start service". This worked fine, until the IT department changed some security or group policy. This caused those commands to fail randomly. The evidence in the task scheduler history showed that on occasion for some unknown reason cmd.exe would return error code 2 (file not found). Hmm.

So I revisited the thought, how do I have the service restart itself. Duh, you insert a timer... I tested this out and it works fine. 

Update: I changed to a System.Threading.Timer because the System.Timers.Timer eats up exceptions... Now the timer will pass the exception on, and they will end up in the Windows Application log.

This also shows an example of how to write to the Windows Application log. 

 

using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using DaemonDLL;

namespace DaemonService
{
    public partial class DaemonService : ServiceBase
    {
        private DaemonClass _daemon;

        private readonly System.Threading.Timer _timer;

        private EventLog _eventLog;

        private int _delay = 15 * 60 * 1000; // 15 minutes

        private int _monitorWait = 30 * 1000; // 30 seconds

        private object _guard = new object();


        public DaemonService()
        {
            InitializeComponent();

            _eventLog = new EventLog();
            if (!EventLog.SourceExists("DaemonService"))
            {
                EventLog.CreateEventSource("DaemonService", "Application");
            }
            _eventLog.Source = "DaemonService";
            _eventLog.Log = "Application";

            _daemon = new DaemonClass();

            _timer = new System.Threading.Timer(Timer_Elapsed);
        }

        public void Timer_Elapsed(object sender)
        {
            if (Monitor.TryEnter(_guard, _monitorWait))
            {
                try
                {

                    _timer.Change(Timeout.Infinite, Timeout.Infinite);

                    try
                    {
                        _daemon.Stop();
                    }
                    catch (Exception ex)
                    {
                        _eventLog.WriteEntry("DaemonService(): Timer_Elapsed(): Stop(): Exception: " + ex.Message + " " + DateTime.Now);
                    }

                    try
                    {
                        _daemon.Start();
                    }
                    catch (Exception ex)
                    {
                        _eventLog.WriteEntry("DaemonService(): Timer_Elapsed(): Start(): Exception: " + ex.Message + " " + DateTime.Now);
                    }

                    _timer.Change(_delay, Timeout.Infinite);

                    _eventLog.WriteEntry("DaemonService(): Service Restarted Automatically (15min intervals)! " + DateTime.Now);

                }
                catch { }
                finally { Monitor.Exit(_guard); }
            }
            else
            {
                _eventLog.WriteEntry("DaemonService(): Timer_Elapsed(): Could Not Enter Monitor!?! " + DateTime.Now);
            }
        }

        protected override void OnStart(string[] args)
        {
            if (Monitor.TryEnter(_guard, _monitorWait))
            {

                try
                {
                    _daemon.Start();
                    _timer.Change(_delay, Timeout.Infinite);
                }
                catch (Exception ex)
                {
                    _eventLog.WriteEntry("DaemonService(): OnStart(): Exception: " + ex.Message + " " + DateTime.Now);
                }
                finally
                {
                    _eventLog.WriteEntry("DaemonService(): Service Started!  " + DateTime.Now);
                    Monitor.Exit(_guard);
                }
            }
            else
            {
                _eventLog.WriteEntry("DaemonService(): OnStart(): Could Not Enter Monitor!?! " + DateTime.Now);
            }
        }

        protected override void OnStop()
        {
            if (Monitor.TryEnter(_guard, _monitorWait))
            {
                try
                {
                    _timer.Change(Timeout.Infinite, Timeout.Infinite);
                    _daemon.Stop();
                }
                catch (Exception ex)
                {
                    _eventLog.WriteEntry("DaemonService(): OnStop(): Exception: " + ex.Message);
                }
                finally
                {
                    _eventLog.WriteEntry("DaemonService(): Service Stopped!  " + DateTime.Now);
                    Monitor.Exit(_guard);
                }
            }
            else
            {
                _eventLog.WriteEntry("DaemonService(): OnStop(): Could Not Enter Monitor!?! " + DateTime.Now);
            }
        }
    }
}