12/30/11

Nikon D40 Intervalometer

Is it possible to create time lapse pictures with Nikon D40... yes...


You can find results here:

result1
result2

You are a software engineer... you can do anything... it is just a matter of time ;)

10/23/11

C# Custom Performance Counters - First Performance Counter

Table of content:

I. C# Custom Performance Counters - Introduction
II. C# Custom Performance Counters - First Performance Counter

1. Creating a custom Performance Counters and Performance counters category.

You can create your own Performance category and Performance counters. To achieve this goal you can use Visual Studio tools, or .NET System.Diagnostics objects. In this post I’ll describe counters and category creation in a code using
using System.Diagnostics;

First of all you need to make a counters collection:

CounterCreationDataCollection collection = new CounterCreationDataCollection();

Then you need to create performance counter

CounterCreationData counter = new CounterCreationData();
counter.CounterName = "CountsPerSecond";
counter.CounterHelp = "CountsPerSecond";
counter.CounterType = PerformanceCounterType.RateOfCountsPerSecond32);
collection.Add(counter);

And place it into the category. As the category type you can use SingleInstance and MultiInstance. Multi instance is very usefull when dealing with multithread application. I will describe this in a next post.

if (!PerformanceCounterCategory.Exists("TestCategory"))
{
    PerformanceCounterCategory.Create("TestCategory", "This is test category", PerformanceCounterCategoryType.SingleInstance, collection);
}

Here is the complete code:

using System.Diagnostics;

namespace PerformaceCountersTest
{
    class Program
    {
        static void Main(string[] args)
        {
            CounterCreationDataCollection collection = new CounterCreationDataCollection();

            CounterCreationData counter = new CounterCreationData();
            counter.CounterName = "CountsPerSecond";
            counter.CounterHelp = "CountsPerSecond";
            counter.CounterType = PerformanceCounterType.RateOfCountsPerSecond32);
            collection.Add(counter);

            if (!PerformanceCounterCategory.Exists("TestCategory"))
            {
                 PerformanceCounterCategory.Create("TestCategory", "This is test category", PerformanceCounterCategoryType.SingleInstance, collection);
            }

        }
    }
}

When you run this code, you should see a new category with one counter in Windows performance tool:

If you don't know how to use Windows Performance tool, please look at the
C# Custom Performance Counters part I- Introduction


2. Using the performance counters in a code.

When we have defined the performance counters, it is time to use it.

First of all we need to create an instance of a counter and invoke method Increment()

PerformanceCounter countsPerSec = new PerformanceCounter("TestCategory", "CountsPerSecond", false);
countsPerSec.Increment();

Now it's time to test it:

using System.Diagnostics;

namespace PerformaceCountersTest
{
    class Program
    {
        static void Main(string[] args)
        {
            PerformanceCounter countsPerSec = new PerformanceCounter("TestCategory", "CountsPerSecond", false);

            for (int i = 0; i < 100; i++)
            {
                countsPerSec.Increment();

                int sleep = 1000 - i * 10;
                Console.WriteLine(sleep);
                System.Threading.Thread.Sleep(sleep);
            }
        }
    }
}

If you setup the Performance tool to watch at your performance counter, you should get a result like this:
3. Test application.

Here is the test application code:

PerformanceCounterCreator class
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace PerformaceCountersTest
{
    class PerformanceCounterCreator
    {

        CounterCreationDataCollection collection = new CounterCreationDataCollection();

        public PerformanceCounterCreator()
        {
        }

        public void addPerformaceCounter(String name, String description, PerformanceCounterType type)
        {
            CounterCreationData counter = new CounterCreationData();
            counter.CounterName = name;
            counter.CounterHelp = description;
            counter.CounterType = type;
            collection.Add(counter);
        }

        public void createCategory(String categoryName,String categoryHelp, bool force)
        {
            if (PerformanceCounterCategory.Exists(categoryName))
            {
                if (force)
                {
                    PerformanceCounterCategory.Delete(categoryName);
                    PerformanceCounterCategory.Create(categoryName, categoryHelp, PerformanceCounterCategoryType.SingleInstance, collection);
                }
            }
            else
                PerformanceCounterCategory.Create(categoryName, categoryHelp, PerformanceCounterCategoryType.SingleInstance, collection);

        }
    }
}

Main program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace PerformaceCountersTest
{
    class Program
    {
        static void Main(string[] args)
        {
            PerformanceCounterCreator creator = new PerformanceCounterCreator();

            creator.addPerformaceCounter("CountsPerSecond", "CountsPerSecond", PerformanceCounterType.RateOfCountsPerSecond32);

            creator.createCategory("TestCategory","This is test category", true);

            //Create counter instance.
            PerformanceCounter countsPerSec = new PerformanceCounter("TestCategory", "CountsPerSecond", false);

            for (int i = 0; i < 100; i++)
            {
                countsPerSec.Increment();

                int sleep = 1000 - i * 10;
                Console.WriteLine(sleep);
                System.Threading.Thread.Sleep(sleep);
            }

        }
    }
}

4. References:
http://www.codeproject.com/KB/dotnet/perfcounter.aspx

http://msdn.microsoft.com/en-us/library/system.diagnostics.performancecountertype.aspx

C# Custom Performance Counters - Introduction

Table of content:

I. C# Custom Performance Counters - Introduction
II. C# Custom Performance Counters - First Performance Counter

1. Introduction

There is a moment in software engineer life when it is time to check application performance. At this certain point you will ask yourself “How can I do it?”. Answer is not simple because you can do it in a very different way. You can of course find any 3rd party application which will measure some things for you. You can make some kind of log file and insert some performance data to it, or you can use .NET System.Diagnostics namespace.

In this article I’ll focus on System.Diagnostics. I’m not saying it is the best approach, I’ll just describe some elements of it and you can decide if it suits your needs or not.

2. Where I can find Performance counters in Windows.

In Windows you can find some predefined performance counters. Just open Control Panel -> Administrative Tools -> Performance
There you can find some predefined counters on a chart.
You can of course add some additional predefined counters to the chart. Just press button marked red on the previous image and choose a Performance Object (performance category), some counters and instances.
If you would like to save some performance counters to look at the offline, you can save data to a file.

Just choose Performance Logs and Alerts -> Counter Logs.
Then press Action -> New Log Settings…  and type a name
In the next form
Press Add Counters and choose whatever you wish.


I’ve choose % Processor Time. Press Add and close when you finish.
On the Log Files sheet choose the log file type. I usually use the comma delimited file. It is easy to process in Excel for example. Set the interval on a General sheet and Schedule (if you like) to setup start and stop time for measurements.

Press OK to finish your job.

You should see the log file in location mentioned in “”Current log file name”.









5/7/11

AVRStudio and Ubuntu [ENG]

Hello there!!!

Here you can find a simple tutorial which shows how to install AVRStudio 4.18 on Ubuntu 10.04 and use a ZL16PRG programmer to connect to a laboratory device.

1. We need to download AVRStudio from website

http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725

2. Let's install AVRStudio using Wine.

3. After connecting ZL16PRG to USB port we should be able to see it in a system.

lsusb 
we should find our device
Bus 003 Device 020: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC 

4. Next step is to connect our USB device to Wine COM1 port.

In my case I was able to find my USB device in:
/dev/serial/by-id/usb-FTDI_USB__-__Serial-if00-port0

Now it's time to male a link between USB device and COM1 on Wine.

ln -s /dev/serial/by-id/usb-FTDI_USB__-__Serial-if00-port0 ~/.wine/dosdevices/com1

5. Right now we can test if everything works fine:



Have a nice programming :)

Used links:
https://help.ubuntu.com/community/Mount/USB
http://ubuntuforums.org/showthread.php?t=553256

AVRStudio na Ubuntu [PL]

Witam serdecznie.

Oto prosty tutorial jak zainstalować AVRStudio 4.18 pod Ubuntu 10.04 i podłączyć układ za pomocą programatora ZL16PRG.

1. Ściągamy AVRStudio ze strony producenta:

http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725

2. Instalujemy AVRStudio używając Wine (z moich doświadczeń wynika, że działa)

3. Po podpięciu Programatora ZL16PRG powinniśmy mieć nowe urządzenie USB.

sprawdźmy:
lsusb 
powinniśmy znaleźć takie urządzenie:
Bus 003 Device 020: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC 

4. Podepnijmy nasze urządzenie USB do COM1 na Wine.

W moim przypadku urządzenie USB znajdowało się w:
/dev/serial/by-id/usb-FTDI_USB__-__Serial-if00-port0
Podepnijmy więc USB pod COM1 w Wine tworząc link:

ln -s /dev/serial/by-id/usb-FTDI_USB__-__Serial-if00-port0 ~/.wine/dosdevices/com1

5. Podłączmy się pod układ za pomocą programatora



Wygląda na to, że wszystko gra. Miłego pisania aplikacji :)

Linki zewnętrzne:
https://help.ubuntu.com/community/Mount/USB
http://ubuntuforums.org/showthread.php?t=553256

4/30/11

Ruby 1.9.1 - Change JPG image name using EXIF information.

Recently I got a lot of images from a trip. Pictures I've received were from a different cameras.

I wanted to create a chronological photo gallery.

Unfortunately when I copied the files, I realized that all of them have the same date and time and different prefixes.

Fortunately I've noticed that all images I got, contains EXIF JPG information.

That is why I've created a ruby script, which changes images names, using Date Time, taken from EXIF information.

To read EXIF information use ruby exifr gem.

gem install exifr

Here is a code. Enjoy!

require 'rubygems'
require 'exifr'

inputDir = ARGV[0]
prefix = ARGV[1].nil? ? "IMG" : ARGV[1]

if (ARGV.length >= 1) 
 Dir.glob("#{inputDir}/*.jpg",File::FNM_CASEFOLD).each() {|file|

  timeTaken = EXIFR::JPEG.new(file).date_time

  if (timeTaken.nil? & !EXIFR::JPEG.new(file).exif.nil?)
   timeTaken = EXIFR::JPEG.new(file).exif.date_time_original
  end
  
  if (timeTaken.nil?)
   timeTaken = File.mtime(file)
  end


  if (!timeTaken.nil?)
   filename = "#{inputDir}/#{prefix}_#{timeTaken.strftime('%Y%m%d_%H%M%S')}.JPG"

   puts "RENAME: #{file} -> #{filename}"
   if(!File.exist?(filename))
    File.rename(file,filename)
   else
    puts "ERROR: FILE #{filename} ALREADY_EXISTS!!!!"
   end
  else
   puts "ERROR: Can't get time for #{file}"
  end

 }
else
 puts "JPG_RENAME.rb #IMAGES_FOLDER [FILE_NAME_PREFIX]"
end
Latest version gan be found here https://bitbucket.org/chesti/jpgrename

2/26/11

C#- Change form language at runtime.

Recently I was trying to create multi language application in C#.

I found a lot of useful information in net.

You can always create a resource file and use it for localization:

Localization with resource file.
It's quite simple, but you always need to change text properties in form constructor... Not useful if we have a lot of forms.

Better solution is to localize your form in a designer.
Localization in Designer
It is easier to localize forms and all code is created by designer.

But how we can change language at run time? All procedures described before enables localization changing when new form is created.

I'll describe language change at run time in case when forms are localized using Designer.

In order to change application language we need to:
1. set a proper CultureInfo

            mCI = new CultureInfo(language);
            Thread.CurrentThread.CurrentCulture = mCI;
            Thread.CurrentThread.CurrentUICulture = mCI;

If you want to know all possible CultureInfos you can check it by:
CultureInfo[] a = CultureInfo.GetCultures(CultureTypes.AllCultures);

2. Take Form ComponentResourceManager.

ComponentResourceManager resources = new ComponentResourceManager(inputForm.GetType());

3. Change language.
using System.Globalization;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;

public void ApplyLanguageToForm(Form inputForm, string language)
        {
            CultureInfo mCI = new CultureInfo(language);
            Thread.CurrentThread.CurrentCulture = mCI;
            Thread.CurrentThread.CurrentUICulture = mCI;

            ComponentResourceManager resources = new ComponentResourceManager(inputForm.GetType());
            foreach (Control c in inputForm.Controls)
            {
                resources.ApplyResources(c, c.Name, mCI);
            }
        }

Unfortunately in this approach, you need to iterate through all controls, menus, labels etc... Code above iterates just through controls, so some of your form elements will not be changed.

In my opinion best approach is to use reflection.

4. Using reflection to change language at run time.

Unfortunately I haven't found any complete solution, but reflection simplifies code.

I've attached class which changes all controls placed on form, any drop down items, menu strips, or owned forms. Please notice that in ApplyLanguageToForm you can pass active form. If it's a modal dialog form, all owner controlls will be reloaded.

Here is an example of how it works:








And code of LanguageChange class:

using System;
using System.Collections;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;

namespace Lang
{
    public class LanguageChange
    {
        private CultureInfo mCI = null;

        public void ChangeLanguage(string language)
        {
            mCI = new CultureInfo(language);
            Thread.CurrentThread.CurrentCulture = mCI;
            Thread.CurrentThread.CurrentUICulture = mCI;
        }

        public void ApplyLanguageToForm(Form inputForm)
        {
            Form mainForm = inputForm;
            while (mainForm.Owner != null)
            {
                mainForm = mainForm.Owner;
            }
            ApplyLanguage(mainForm, null);
        }

        private void ApplyLanguage(object value, ComponentResourceManager resources)
        {
            if (value is Form)
            {
                resources = new ComponentResourceManager(value.GetType());
                resources.ApplyResources(value, "$this");
            }
            Type type = value.GetType();

            foreach (PropertyInfo info in type.GetProperties())
            {
                switch (info.Name)
                {
                    case "Items":
                    case "DropDownItems":
                    case "Controls":
                    case "OwnedForms":

                        if (info.PropertyType.GetInterface("IEnumerable") != null)
                        {
                            IEnumerable collection = (IEnumerable)info.GetValue(value, null);
                            if (collection != null)
                            {
                                foreach (object o in collection)
                                {
                                    PropertyInfo objNameProp = o.GetType().GetProperty("Name");
                                    ApplyResourceOnType(resources, o, objNameProp);
                                }

                            }
                        }
                        break;
                    case "ContextMenuStrip":
                        object obj = (object)info.GetValue(value, null);
                        if (obj != null)
                        {
                            ApplyLanguage(obj, resources);
                            resources.ApplyResources(obj, info.Name, mCI);
                        }
                        break;
                    default:
                        break;
                }
            }

        }

        private void ApplyResourceOnType(ComponentResourceManager resources, object o, PropertyInfo objNameProp)
        {
            switch (o.GetType().Name)
            {
                case "ComboBox":
                    for (int i = 0; i < ((ComboBox)o).Items.Count; i++)
                    {
                        ((ComboBox)o).Items[i] = resources.GetString(GetItemName(o, objNameProp, i), mCI);
                    }
                    break;
                case "ListBox":
                    for (int i = 0; i < ((ListBox)o).Items.Count; i++)
                    {
                        ((ListBox)o).Items[i] = resources.GetString(GetItemName(o, objNameProp, i), mCI);
                    }
                    break;
                // Other classes with string items
                default:
                    if (objNameProp != null)
                    {
                        string name = objNameProp.GetValue(o, null).ToString();
                        ApplyLanguage(o, resources);
                        resources.ApplyResources(o, name, mCI);
                    }
                    break;
            }
        }

        private string GetItemName(object o, PropertyInfo objNameProp, int i)
        {
            string name = String.Format("{0}.{1}",
                objNameProp.GetValue(o, null).ToString(),
                "Items");
            if (i != 0) name = String.Format("{0}{1}", name, i);
            return name;
        }
    }
}

1/4/11

SVN DB on portable device. UBUNTU

Recently I wanted to start a new project with version control. This will be a personal project so I don't want to use any SVN server. That is why I was looking for a way to create an SVN repository on my portable USB drive.

I've found a lot of "how to create a portable source control..." but most of them were about GIT.
Why I'm not using GIT? Because I know SVN and I do not want to learn how to use GIT... for now.

[UPDATE 2012-12-19]GIT solved all issues I had with SVN. To make a dongle repository just create a bare GIT repository there and push your changes from PC.
I stopped using SVN

If you still want to use SVN here you have it:

I assume that you have SVN installed on your ubuntu.

  1. Create repository on portable device.
  2. I'll create repository on PORTABLE_DEVICE in folder SVN_REPO/TEST_REPO
    svnadmin create /media/PORTABLE_DEVICE/SVN_REPO/TEST_REPO That is all. Repository is created and ready to use.
  3. Lets use repository.
  4. First checkout your repository from file (DB on your portable device) to any directory on your PC.
    svn checkout file:///media/PORTABLE_DEVICE/SVN_REPO/TEST_REPO
    Create project files and add them to repository.  svn add testFile1  svn add testFile2  svn commit -m "test commit"
    You can checkout your repository from file (DB placed on portable device) on any PC. TortoiseSVN can be used to checkout your portable repository and track changes on Windows.
  5. Summary
  6. Now you can track changes in your code on portable device.