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,

 

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. 

 

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.

 

I have been writing Windows Services for various reasons. I have used the singleton implementation to wrap up a hardware device and collect data from it for example. The other main thing is to create daemons that poll network sensors and collect data and stuff it into a database.

I was stumped for a while about how to 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 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 SensorsDaemonDLL;

namespace DaemonService
{
    public partial class DaemonService : ServiceBase
    {
        private SensorsDaemonClass _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 SensorsDaemonClass();

            _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);
            }
        }
    }
}