AdSense

Monday, 9 September 2013

Comparison of different lamps

(Deutsche Version) Today I want to compare three lamps which could be suitable as room light. The candidates are:
a) An "old" halogen bulb
b) A helical energy-effective lamp (Link)
c) A COB-LED (Link)

At first the specifications:
a) Power: 40 W
luminous flux: 390 Lum
life time: 2 000 h
price: 2 €

b) Power: 23 W
luminous flux: 1 550 Lum
life time: 10 000 h
price: 8 €

c) Power: 7 W
luminous flux: 560 Lum
life time: >10 000 h (no value on Pollin.de, approximately 25 000 h)
price: 6 € (with heat sink, the LED only costs 3 €)

The first point of comparison is: How much light comes out of how much power? I show the values in Lum/W:
a) 10
b) 67
c) 80
The LED and the energy-effective lamp are clearly winning at this point.

The next point: how much light comes out of how much money? Here are the values in Lum/€:
a) 195
b) 194
c) 95
The LED looses this competition because LEDs are more expensive.

As the most important point of comparison I want to light a room for 5 years. I assume 5000 Lum and 6 hours of light per day, this are about 2000 hours. How many lamps would I need to reach the 5000 Lum?
a) 13
b) 3
c) 9
If you consider the life time, all halogen bulbs have to be switched every year, whilst the energy-effective lamp and the LED survive the whole 5 Jears. This increases the costs for the halogen bulbs by a factor of 5. The prices for the lamps are:
a) 128
b) 26
c) 53
consider: The costs for the LED are 50% for the heat sink. Now i want to examine the power consumption:
a) 1026 kWh
b) 148 kWh
c) 125 kWh
If I assume 20 ct / kWh, the costs for 5 jears are:
a) 205
b) 30
c) 25

The cheapest one is the energy-effective lamp. For the LED: Please note that the costs are basically only 50% because of the heat sinks. Additionally, an LED lasts much longer than an energy-efficient lamp, in the long term, the LED wins this competition because it also has a slightly smaller power consumption.

LED room light - selfmade

(Deutsche Version) At Pollin, there are COB-LEDs for sale (Pollin). The great thing about them is that they don't need any resistor or anything else, you just have to apply the suitable voltage and a heat sink.
560 lm is quite a lot, I will compare different light sources in a different post. The great advantage of LEDs is that they are effective and have a very high life time so maybe the future belongs to LEDs. The only problem with this LED is that the light comes out of a very small area and the LED is very bright and is eventually dangerous for the eye. Therefore, I had to build a lamp shade. I used greaseproof paper. The instructions are very simple, you only should ensure that b > a/2, otherwise there will be a hole in the middle.
Cut along the red edges. Afterwards fold the vertical dottet lines about 90° so the paper makes a closed cylinder. Afterwards, the flaps have to be folded over and the whole thing is some kind of bucket which can be put over the lamp. The final result is the following:

Sunday, 8 September 2013

Read and write SD cards with Arduino

If you want to use your Arduino as a datalogger, you might face the problem where to store the logged data. The best way to deal with it is storing it on a SD card. The data is safe even if the Arduino is powered off, you can connect the card directly to your computer and read the data for example with Matlab oder Excel.

Hardware

On Ebay you can find very cheap SD card modules for Arduino. I bought the module by LC Technology:
Pin mapping is clearly visible. There are pin for voltage supply (+5V, +3.3V and GND) and for SPI-bus which is used to read and write the SD card. The pins in the upper row are connected to the pins in the lower row. SD cards work with a voltage level of 3.3V. The module can be supplied with either 3.3V or 5V (a voltage regulator is included). There is NO level converter for the SPI pins so you MUST NOT connect these pins directly to your Arduino. You would destroy your card.



The module is supplied with 5V by the Arduino. The SPI pins are connected using a level converter:
MOSI to Pin 11
MISO to Pin 12
SCK to Pin 13
CS to Pin 4

I used a bi-directional level converter and converted all of the pins. Both things are technically not necessary. You could use a converter that only converts for 5V to 3.3V (e.g. 74HC4050) and you only have to convert MOSI, SCK and CS. MISO can be connected directly to the Arduino.

When everything is wired correctly, you can put a SD card into the module. The card has to be formated as FAT16 or FAT32. According to the Arduino reference FAT16 is preferred. 

Software

The SD-library for Arduino brings several examples to test your hardware. I chose the example "datalogger" which writes the values of three analog inputs to a txt-file on the SD card.

#include <SD.h>

const int chipSelect = 4;

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop()
{
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ","; 
    }
  }

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  } 
}

In setup()-function a serial connection is established, the command SD.begin(chipSelect) initializes the SD card. The parameter is the pin CS is connected to. If initialization was succesfull we continuer to loop(). Here the values of the analog inputs are read and saved to a string variable. With the command SD.open() the file "datalog.txt" is opened in write mode. If the file was opened succesfull, the value of the string variable is wirtten to the file and the file is closed.

Reading files on the card is pretty easy, too:

  dataFile = SD.open("test.txt");
  if (dataFile) {
    Serial.println("test.txt:");
    
    // read from the file until there's nothing else in it:
    while (dataFile.available()) {
     Serial.write(dataFile.read());
    }
    // close the file:
    data.close();
  } else {
   // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

At first the file is opened with the open()-command. Then it can be read line by line with read() until the end of the file is reached (this is checked with the available()-command). In the end, the file is closed with close().

Friday, 6 September 2013

C# - Global hotkeys which are really global

(Deutsche Version) My music player uses hotkeys. Basically, the work fine. When playing several computer games (e.g. Leauge of Legends), the hotkeys do not work anymore. To solve this problem, I used an implementation from my friend from http://csharp-tricks-en.blogspot.de/ and adapted this implementation a bit. My hotkeys are now in a separate class which is used this way:

KeyHook MyHook = new KeyHook(this, KeyboardHookProcedure);
MyHook.Hook(KeyHook.KeyboardHookProc);

KeyHook.KeyPressed += KeyHook_KeyPressed;
KeyHook.KeyReleased += KeyHook_KeyReleased;


Die KeyHook_KeyPressed und KeyHook_KeyReleased Funktionen sehen folgendermaßen aus:

void KeyHook_KeyPressed(int keyCode, List<int> pressedKeys)
{}


keyCode is simply an integer, which value represents which key is listed here. I added the events KeyPressed and KeyReleased to have a clean solution. Now the code of the class KeyHook:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace anyNamespace
{
    public class KeyHook
    {
        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

        //Declare hook handle as int.
        static int hHook = 0;

        //Declare keyboard hook constant.
        //For other hook types, you can obtain these values from Winuser.h in Microsoft SDK.
        const int WH_KEYBOARD_LL = 13;

        public delegate void KeyPressedEventHandler(int keyCode, List<int> pressedKeys);
        public static event KeyPressedEventHandler KeyPressed;

        public delegate void KeyReleasedEventHandler(int keyCode, List<int> pressedKeys);
        public static event KeyReleasedEventHandler KeyReleased;

        [StructLayout(LayoutKind.Sequential)]
        private class keyboardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        //Import for SetWindowsHookEx function.
        //Use this function to install thread-specific hook.
        [DllImport("user32.dll", CharSet = CharSet.Auto,
         CallingConvention = CallingConvention.StdCall)]
        private static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
        IntPtr hInstance, int threadId);

        //Import for UnhookWindowsHookEx.
        //Call this function to uninstall the hook.
        [DllImport("user32.dll", CharSet = CharSet.Auto,
         CallingConvention = CallingConvention.StdCall)]
        private static extern bool UnhookWindowsHookEx(int idHook);

        //Import for CallNextHookEx.
        //Use this function to pass the hook information to next hook procedure in chain.
        [DllImport("user32.dll", CharSet = CharSet.Auto,
         CallingConvention = CallingConvention.StdCall)]
        private static extern int CallNextHookEx(int idHook, int nCode,
        IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        static extern IntPtr LoadLibrary(string lpFileName);

        //static Form1 View;
        static MainWindow mainWindow;

        const int MOD_SHIFT = 0x0004;

        IntPtr LL = (IntPtr)LoadLibrary("User32");

        public KeyHook(MainWindow _mainWindow, HookProc proc)
        {
            mainWindow = _mainWindow;
            Hook(proc);

        }

        ~KeyHook()
        {
            UnHook();
        }

        HookProc _proc;
        public int Hook(HookProc proc)
        {
            _proc = proc;
            hHook = SetWindowsHookEx(WH_KEYBOARD_LL, _proc, LL, 0);
            return hHook;
        }

        public bool UnHook()
        {
            bool ret = UnhookWindowsHookEx(hHook);
            if (ret)
                hHook = 0;
            return ret;
        }

        public static List<int> pressedKeys = new List<int>();

        public static int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode < 0)
            {
                return CallNextHookEx(hHook, nCode, wParam, lParam);
            }
            else
            {
                keyboardHookStruct MyKeyboardHookStruct = (keyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(keyboardHookStruct));
                if ((MyKeyboardHookStruct.flags & 128) == 128)
                {
                    if (pressedKeys.Contains(MyKeyboardHookStruct.vkCode))
                    {
                        pressedKeys.Remove(MyKeyboardHookStruct.vkCode);
                        if (KeyReleased != null)
                        {
                            KeyReleased(MyKeyboardHookStruct.vkCode, pressedKeys);
                        }
                    }
                }
                if ((MyKeyboardHookStruct.flags & 128) == 0)
                {
                    if (!pressedKeys.Contains(MyKeyboardHookStruct.vkCode))
                    {
                        pressedKeys.Add(MyKeyboardHookStruct.vkCode);
                        if (KeyPressed != null)
                        {
                            KeyPressed(MyKeyboardHookStruct.vkCode, pressedKeys);
                        }
                    }
                }
                return CallNextHookEx(hHook, nCode, wParam, lParam);
            }
        }
    }
}

Monday, 2 September 2013

C# WPF - Invoke

(Deutsche Version) In the previous post there was this problem: I am only allowed to access graphics from the main thread. Unfortunately it can occur that you want to edit something from another thread. The solution for this problem is: invoke. At first a small example which does not work:

void threadActivity()
{
    Thread.Sleep(5000);
    TaskbarItemInfo.ProgressValue = 0.2;
}


After 5 seconds, there will be an error: InvalidOperationException has not been handled. The calling thread cannot acces this object, because the object belongs to another thread. As announced, the solution is called invoke. The new code looks like this:

void threadActivity()
{
    Thread.Sleep(5000);
    Application.Current.Dispatcher.BeginInvoke(new Action(() =>
    {
        TaskbarItemInfo.ProgressValue = 0.2;
    }));
}


After 5 seconds, the progress bar in the task bar will be set to the value 0.2. About the syntax: Everything inside the curly braces is executed in the main thread. Inside the curly braces you can access variables which are also accessible from outside the curly braces. You can also have lots of code in here, but I would recommend to only invoke small code blocks.

C# WPF - Show progress in task bar

(Deutsche Version) Downloading something with firefox will show the progress in the task bar. Realising this is pretty simple. In the window you want to have this, you have to add

<Window.TaskbarItemInfo>
    <TaskbarItemInfo/>
</Window.TaskbarItemInfo>


just in front of the <Grid>. Now you can access TaskbarItemInfo. This could be done like this:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();


        TaskbarItemInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Normal;
 
        Loaded += MainWindow_Loaded;
    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        TaskbarItemInfo.ProgressValue = 0.5;

    }
}


You can use different ProgressStates so the progress bar changes its color. You can also define a symbol for the task bar.

If you want to do all these things from another thread, this will not work. Why is explained in this post. I will only show the solution. Instead of

TaskbarItemInfo.ProgressValue = 0.2

you have to use

Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
    TaskbarItemInfo.ProgressValue = 0.2;
}));

Android - Widget "crashes" when the screen is being rotated

(Deutsche Version) The detailled error is: I have got an widget, when I click on it, I want it to open the corresponding app. This usually works. Sometimes, nothing happens when I click on it, mostly after turning the screen. The reason is: Several things (e.g. rotating the screen) do not call the onUpdate function but only the onReceive function. Because of having the following lines in the onUpdate


Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

remoteViews.setOnClickPendingIntent(R.id.button, pendingIntent);


the MainActivity was started. This did not happen when onReceive was called. Therefore, I had to add these lines to the onReceive function (I had to rename intent in localIntent because onReceive has a parameter Intent intent). Afterwards, everything worked fine.