Posts for October 2008

Thoughts on Google Chrome

I admit it, I am a fan of the new Google Chrome browser.

This made me chuckle, however:
Google vs Microsoft ... ?

Is Google preparing to dominate the world ?

Making The HTC Touch Diamond Vibrate

One of the minor problems I had when making the Stopwatch for my HTC Touch Diamond, was to make the phone vibrate automatically. It seems there are no managed way of doing this. However, after a bit of googling around, I found out that the vibrator typically can be addressed as a LED object using the Open NET CF Framework. So I decided to throw together a tiny wrapper class around this functionality, so I can use it generally in the future. The most useful thing here, I think, is the ability to have the phone vibrate using a given on-off pattern in a fire-and-forget pattern that works well when programming Compact Framework forms.

This is the simple Vibrator class:

         1: using System;
         2: using System.Threading;
         3: using OpenNETCF.WindowsCE.Notification;
         5:  namespace dr.WM.Common
         6: {
         7:     /// <summary>
         8:     /// Vibrator class. Works on HTC Touch Diamond, not tested anywhere else.
         9:     /// (Mostly, The LED index could be different on other devices.)
         10:     /// </summary>
         11:     public class Vibrator
         12:     {
         13:         /// <summary>
         14:         /// Index of the Vibrator LED.
         15:         /// </summary>
         16:         private const int VibratorLedIndex = 1;
         17:         /// <summary>
         18:         /// LED instance.
         19:         /// </summary>
         20:         private readonly Led led = new Led();
         21:         /// <summary>
         22:         /// Whether the Run thread is allowed to run.
         23:         /// </summary>
         24:         private bool allowRun = false;
         25:         /// <summary>
         26:         /// Starts this instance.
         27:         /// </summary>
         28:         public void Start()
         29:         {
         30:             allowRun = true;
         31:             led.SetLedStatus(VibratorLedIndex,Led.LedState.Blink);
         32:         }
         34:         /// <summary>
         35:         /// Stops this instance.
         36:         /// </summary>
         37:         public void Stop()
         38:         {
         39:             allowRun = false;
         40:             led.SetLedStatus(VibratorLedIndex, Led.LedState.Off);            
         41:         }
         43:         /// <summary>
         44:         /// Starts a vibrating sequence by specifying the vibrate and pause times.
         45:         /// Vibration will run until the Stop method is called.
         46:         /// </summary>
         47:         /// <param name="msVibrate">The vibrate time in milliseconds.</param>
         48:         /// <param name="msPause">The pause time in milliseconds.</param>
         49:         public void StartSequence(int msVibrate, int msPause)
         50:         {
         51:             StartSequence(msVibrate,msPause,0);
         52:         }
         53:         /// <summary>
         54:         /// Starts a vibrating sequence by specifying the vibrate and pause times.
         55:         /// Vibration will run for the specified total time, or until the Stop method is called.
         56:         /// </summary>
         57:         /// <param name="msVibrate">The vibrate time in milliseconds.</param>
         58:         /// <param name="msPause">The pause time in milliseconds.</param>
         59:         /// <param name="totalLength">The total time to vibrate.</param>
         60:         public void StartSequence(int msVibrate, int msPause, int totalLength)
         61:         {
         62:             allowRun = true;
         63:             ThreadPool.QueueUserWorkItem(Run,
         64:                                          new RunState
         65:                                              {VibrateTime = msVibrate, PauseTime = msPause, TotalTime = totalLength});
         66:         }
         68:         /// <summary>
         69:         /// Thread worker for a vibrating sequence.
         70:         /// </summary>
         71:         /// <param name="state">The state.</param>
         72:         private void Run(object state)
         73:         {
         74:             long begin = Environment.TickCount;
         75:             RunState runState = (RunState)state;
         76:             while(allowRun && (runState.TotalTime <= 0 || Environment.TickCount - begin < runState.TotalTime))
         77:             {
         78:                 led.SetLedStatus(VibratorLedIndex, Led.LedState.Blink);
         79:                 Thread.Sleep(runState.VibrateTime);
         80:                 led.SetLedStatus(VibratorLedIndex, Led.LedState.Off);
         81:                 Thread.Sleep(runState.PauseTime);
         82:             }
         83:         }
         85:         /// <summary>
         86:         /// Helper for passing vibration state to the worker thread.
         87:         /// </summary>
         88:         private struct RunState
         89:         {
         90:             public int VibrateTime { get; set; }
         91:             public int PauseTime { get; set; }
         92:             public int TotalTime { get; set; }
         93:         }
         94:     }
         95: }

Please note that this might (propably) will not work on other devices, since the vibrator might not be on the same LED index. One could refactor the class and make a couple of vibrator on/off virtual protected methods, and call these from the Start / Stop methods. That way, it could be easy to make the class general enough for use on other devices, you would just need to implement the start and stop operations. However, there might be an easier way of doing this using an unmanaged API (actually I hope there is, since collecting info about all types of devices in order to figure out how to fire the vibrator, seems as an unfeasible task).

It seems that the Klaxon Open-Source alarm clock for Windows Mobile has just been made Open Source. I think I will have a look at the source to see whether my way of using the vibrator is feasible, or the Klaxon author uses a better approach ;-)

A Stopwatch for Windows Mobile

I have got a new mobile phone, a HTC Touch Diamond. Besides the fact that it has a sleek design and is much easier to work with when reading email and browsing the web than my old phone.

However, that it is not the only reason for buying the Diamond. Another, very important reason, is that it runs Windows Mobile 6.1 - and therefore I can write my own programs for it using pretty much the same toolset as I use for any other .NET program. Granted, there are stuff missing in the Compact Framework compared to the full-blown framework (Expression trees anyone ?), but it is normally quite easy to find alternatives, and the Compact Framework does make it quite easy to program the device.

My first application for the Touch is a simple Stopwatch program. I wrote it, because there was no stopwatch and/or timer program on the Touch when I got it, so why not write my own ;-) The application it is quite simple, but I learned quite a deal about the device and the Compact Framework while developing it. It essentially relies on the Environment.TickCount counter to measure time, so it might not be 100% accurate - but for my needs (such as heating pizza's), it is quite sufficient.

If anyone's interested, you may download the source from here. If you want to compile it, you will need a copy of the OpenNET CF Framework, because I needed to use some parts of it for making the phone vibrate when the alarm goes off. (It could be replaced with some P/Invoke calls, but i got lazy ;-)

The application itself has the following features:

  • Simple stopwatch
  • Timer with alert (vibration and sound)
  • Configurable alarm sound (only .wav files, sorry).
  • Settings are remembered (stored in Application Data)