AdSense

Saturday, 31 August 2013

Read acceleration sensor MPU-6050 with ATMega 16A

(Deutsche Version) In this post, I will show how to read the values of an MPU-6050 with an ATMega 16A. For the usage of I2C on the ATMega, I use this implementation.

If you want to use a Raspberry PI instead of an ATMega, see this post.

At first, I wrote two functions which can read from a register respectively write to a register:

void TWIM_WriteRegister(char reg, char value)
{
    TWIM_Start(addr, TWIM_WRITE); // set device address and write mode
    TWIM_Write(reg);
    TWIM_Write(value);
    TWIM_Stop();
}

char TWIM_ReadRegister(char reg)
{
    TWIM_Start(addr, TWIM_WRITE);
    TWIM_Write(reg);
    TWIM_Stop();

    TWIM_Start(addr, TWIM_READ); // set device address and read mode
    char ret = TWIM_ReadNack();
    TWIM_Stop();
    return ret;
}


As a second step, I wrote two functions which read the acceleration and gyro data from the Sensor. Please note that you have to disable the sleep mode, this can be done by using TWIM_WriteRegister(107, 0).

double MPU6050_ReadAccel(int axis)//x = 0; y = 1; z = 2
{
  char reg = axis * 2 + 59;
  char AFS_SEL = TWIM_ReadRegister(28);
  double factor = 1<<AFS_SEL;
  factor = 16384/factor;
  int val = 0;
  double double_val = 0;
  char ret = 0;

  ret = TWIM_ReadRegister(reg);
  val = ret << 8;

  ret = TWIM_ReadRegister(reg+1);  
  val += ret;

  if (val & 1<<15)
  val -= 1<<16;

  
  double_val = val;

  double_val = double_val / factor;

  return double_val;
}

double MPU6050_ReadGyro(int axis)//x = 0; y = 1; z = 2
{
  char reg = axis * 2 + 67;
  char FS_SEL = TWIM_ReadRegister(27);
  double factor = 1<<FS_SEL;
  factor = 131/factor;
  int val = 0;
  double double_val = 0;
  char ret = 0;

  ret = TWIM_ReadRegister(reg);
  val = ret << 8;

  ret = TWIM_ReadRegister(reg+1);  
  val += ret;

  if (val & 1<<15)
  val -= 1<<16;



  double_val = val;
 
  double_val = double_val / factor;

  return double_val;
}


The values for the gyrometer are in degrees per second and in units of g for the accelerometer, further information is provided in the Register Map, especially at the explaination of FS_SEL and AFS_SEL: http://www.invensense.com/mems/gyro/documents/RM-MPU-6000A.pdf

Thursday, 29 August 2013

Header image depending on the time of day

I created a homepage where I wanted to change the header image depending on the time of day. In the daytime I wanted an image of a building by day, in the nighttime an image of the same building by night.

This can be done pretty easy with PHP.

At first the current time hast to be  stored in variable:

$time = date("G", time())

time() function returns the UNIX timestamp of the server. The UNIX timestamp is the number of seconds since 01.01.1979 at 1 AM. To get the timestamp to a "readable" format we use the date() function. The format is chose with the first paramter. "G" delivers the the hours without leading zero. A lot of other formats are possible, you can find them on this website.

The current hour is saved in the variable called $time. It is important to know that time is stored in UTC (coordinated universal time). I needed MEZ (or MESZ) so I had to add one (two) hours.

Now the header image can be chosen according to the current time:

if ($time > 7 && $time < 21 ) {
   $path = "http://yourserversdomain.de/images/header_day.jpg";
 }

else {
    $path = "http://yourserversdomain.de/images/header_night.jpg";
}

If the number of hours is greater than 7 and less than 21 (it is between 8:00 and 20:59) the path of the "day image" is stored to the variable $path - else the path of the "night image".


Then the image is embedded using HTML:

<img src="<?php echo $path; ?>" width="123" height="456" alt="" />


Of course you could also use this method for creating images depending on the weekday or the season.

Wednesday, 28 August 2013

Arduino code on ATtiny

As you can read in my last posts I am working at a remite control at the moment. For this purpose the "normal" ATmega8 isn't the best choice (too big, too expensive, 5V supply voltage). So the project is based on an ATtiny, but I still want to use the features and the libraries of the Arduino IDE. How you can use the IDE to programm an ATmega8 can be read in my first post on this blog. It was pretty easy because Arduino supports the ATmega8 out of the box.
For the ATtiny, a few more steps have to be taken. With the following instructions you can add the ATtiny45, ATtiny85, ATtiny24, ATtiny44 and ATtiny84 to the Arduino IDE.

First of all you have to download this file. The containing folder "attiny" must be copied to the folder "hardware" in your Arduino installation. It should look like this: "C:\Programs\Arduino\hardware\attiny".


The folder contains the file "boards.txt". It contains the information to the used "boards" (fuse settings, clock frequency,...) - in our case it's only the ATiny. Only the "boards" listed in this file will appear in the IDE. The file only includes the settings for the use of the internal clock source. For an external clock source, you have to adapt the settings. In this case it's important so set the correct fuses, otherwise you will have timing problems.

Now you have to tell the IDE the pin settings of your ATTiny. The folder "variants" in the archive you just downloaded  contains the subfolders "tiny8" and "tiny14". In these folders you can find a file named "pins_arduino.h" which specifies the pin mapping of the Tiny. In the file you can also see which pin of the ATtiny has which "Arduino function". For ATTiny24/44/84 this would be for example



                                          +-\/-+
                                VCC  1|    |14  GND
                      (D 10)  PB0  2|    |13  AREF (D  0)
                       (D  9)  PB1  3|    |12  PA1  (D  1)
                                 PB3  4|    |11  PA2  (D  2)
    PWM  INT0  (D  8)  PB2  5|    |10  PA3  (D  3)
       PWM        (D  7)  PA7  6|    |9   PA4  (D  4)
       PWM        (D  6)  PA6  7|    |8   PA5  (D  5)        PWM
                                          +----+

When you start the Arduino IDE, you should see the ATtiny under "Tools-Board":

From now on, it's business as usual. Depending on the used ATiny, there might be some restrictions, e.g. with interrupts. Furthermore your have to use a programmer like the USBasp to programm the Tiny.

These instructions are also valid for every other ATtiny (and ATmega) - you just have to find the right "pins_arduino.h" or create it for yourself.

C# WPF - DataBinding

(Deutsche Version) DataBindings in WPF are very powerful and useful. Today, I will explain the basics. The basic idea is: I have a display element and a variable (technically: field). When I change my variable, I want the display element to change and vice versa, so the variable will change if the display element changes (e.g. a text is entered into a TextBox). At first the XAML part of the code:

<TextBox Name="InputText" Grid.Row="0" Text="{Binding BindingText, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></TextBox>
<TextBlock Name="OutputText" Grid.Row="1" Text="{Binding BindingText, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"></TextBlock>


As a next step, I need an object to which I am doing the DataBinding. In my case, this is the class "AnyClass" which containt the field "BindingText". I could also simply use MainWindow.xaml.cs. To define the object to which the bining should be, you have to do the following:

AnyClass anyClass = new AnyClass();
InputText.DataContext = anyClass;
OutputText.DataContext = anyClass;


I could also do this.DataContext = anyClass;, this would have the same effect but I want to show different possibilities how to do DataBinding. I also could also create the field "BindingText" in MainWindow.xaml.cs and then do this.DataContext = this;.

Now I want to face the class AnyClass. At first a short introduction to fields. A field can be used just like a variable but it cannot hold values directly. The minimum field would be this:

public string BindingText
{
    get { return _BindingText; }
    set { _BindingText = value; }
}
private string _BindingText = "";


This is a field. The get and set parts can do lots of funny things like checking the input, throw events, and everything else.

Now I will show the class AnyClass which is the last missing part for the DataBinding:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataBindingExample
{
    public class AnyClass : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public string BindingText
        {
            get { return _BindingText; }
            set
            {
                _BindingText = value;
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("BindingText"));
                }
            }
        }
        private string _BindingText = "<empty>";
    }
}


By calling PropertyChanged, the display element gets the information that there is a new variable value and refreshes the displayed value. This should cover the basics for DataBinding. If there are further questions, I will answer them in the comments.

 A post about this topic who also covers converters can be found on C# Tips and Tricks.

Friday, 23 August 2013

A music player with C#

(Deutsche Version) There are a lot of music players on this world. Every player has its advantages and disadvantages. Until now, I was not able to find the "perfect" music player. Therefore I wrote my own music player which can be downloaded here. A bit about the handling: At first, a folder has to be specified as music library. Then, by clicking on "Refresh Library", all music files in this directory are laoded. Hotkeys were very important for me, so I implemented them (see below). I will present two important parts of the music player: Playing music with WPF and using Hotkeys. By the way, you can find a basic introduction to WPF here: C# Tips and Tricks.

Playing music

Hence I use WPF, playing music is very simple: In my xaml file, I have a MediaElement:

<MediaElement Height="10" Width ="10"  LoadedBehavior="Manual" Name="mediaElement1" VerticalAlignment="Top" />

The MediaElement is invisible. To play music, you have to execute the following code:

mediaElement1.Source = new Uri(pathToMediaFile);
mediaElement1.Play();


This is the whole magic for playing music. You can now do several things like registering to events so you know when the actual song has finished playing (to start the next song).

Hotkeys

Note: By now I use a "better" implementation of the hotkeys which you can find here.

Using hotkeys is pretty simple. At first, you have to add several lines into the program:

[DllImport("User32.dll")]
private static extern bool RegisterHotKey(
    [In] IntPtr hWnd,
    [In] int id,
    [In] uint fsModifiers,
    [In] uint vk);

[DllImport("User32.dll")]
private static extern bool UnregisterHotKey(
    [In] IntPtr hWnd,
    [In] int id);

private HwndSource _source;
private const int HOTKEY_ID = 9000;

protected override void OnSourceInitialized(EventArgs e)
{
    base.OnSourceInitialized(e);
    var helper = new WindowInteropHelper(this);
    _source = HwndSource.FromHwnd(helper.Handle);
    _source.AddHook(HwndHook);
    RegisterHotKey();
}

protected override void OnClosed(EventArgs e)
{
    _source.RemoveHook(HwndHook);
    _source = null;
    UnregisterHotKey();
    base.OnClosed(e);
}

private void UnregisterHotKey()
{
    var helper = new WindowInteropHelper(this);
    UnregisterHotKey(helper.Handle, HOTKEY_ID);
}

private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    const int WM_HOTKEY = 0x0312;
    switch (msg)
    {
        case WM_HOTKEY:
            OnHotKeyPressed(wParam.ToInt32());
            break;
    }
    return IntPtr.Zero;
}


As a next step, I defined the three hotkeys I need:

private void RegisterHotKey()
{
    var helper = new WindowInteropHelper(this);
    const uint VK_RIGHT = 0x27;
    const uint VK_LEFT = 0x25;
    const uint VK_SPACE = 0x20;
    const uint MOD_ALT = 0x0001;
    const uint MOD_CTRL = 0x0002;

    if (!RegisterHotKey(helper.Handle, HOTKEY_ID+2, MOD_CTRL + MOD_ALT, VK_RIGHT))
    {
        // handle error
    }
    if (!RegisterHotKey(helper.Handle, HOTKEY_ID+1, MOD_CTRL + MOD_ALT, VK_LEFT))
    {
        // handle error
    }
    if (!RegisterHotKey(helper.Handle, HOTKEY_ID, MOD_CTRL + MOD_ALT, VK_SPACE))
    {
        // handle error
    }
}


Finally, I need a function which executes the desired actions when a hotkey is pressed:

private void OnHotKeyPressed(int key)//9000 = space, 9001 = left, 9002 = right
{
    //System.Console.Write("KeyPressed! {0}\n", key);
    switch (key)
    {
        case 9000: if (playing) { pause(); } else { play(); }
            break;
        case 9001: back();
            break;
        case 9002: next();
            break;
        default:
            break;
    }
    // do stuff
}


Please note: If you have a hotkey registered, e.g. "AltGr" + "0", this key combination is only available for my program. So in this example, I could not write } anymore (I have a german keyboard layout) as long as my program is opened.

Wednesday, 21 August 2013

PHP - Make chat on own server "safe"

(Deutsche Version) Realising a chat with PHP is not difficult. After a short time one should recognize that this chat can also execute HTML code (e.g. images). This means that PHP code can be executed, too. This is a huge security issue, anyone could format the hard drive of the server or anything else.

To prevent any execution of code, you can do the following: Before displaying the chat message, replace every < Symbol with the HTML equivalent. This is &lt;. In PHP this can be realised this way: $chatMessage = str_replace("<", "&lt;", $chatMessage);. Now no PHP and HTML code can be executed anymore. If you want to allow several HTML tags (image, link), you could try to detect this and then not replace the < Symbol.

Arduino as logic analyzer

As promised in my "Home Automation" postings I am going to explain how to use your Arduino Uno as a logic analyzer.

Firt of all you have to download the required software für the Arduino. it can be found here. Depending on the sampling rate you need (2/4 MHz or 1 MHz) you have to choose the correct sketch and upload it to your Arduino. You also have to download the file "ols.profile-agla.cfg" - we will need it later.


After having uploaded the sketch to the Arduino, you can start the serial monitor, switch to 115200 Baud and send 1 or 2 via serial connection to your Arduino. If you receive some kind of status report, everything works fine.


For the next step we will need a software which displays the logged data on the computer. We will use the tool "Logic Sniffer". It's written in Java, so it can be used with Windows and Linux. Download the latest version and unzip it. Copy the file "ols.profile-agla.cfg" to the folder "plugins" and start the programm with "run.bat" or "run.sh". 

You should see the user interface:
Click "Capture"-"Begin capture" - the following window is opened:
Here you have to set the COM-Port of your Arduino, set the correct baude rate and choose Arduino as "Device type". Click "Show devive metadata" to see if everything works as planned.
In the tab "Acquisition" you can set details like sampling rate and so on.
In "Triggers" tab you can enable the triggers. If you tick a channel in "Mask" row, it will be started by a trigger. If "Value" is ticked, it will be triggered by a HIGH signal, otherwise a LOW signal. With "Before/After ratio" you can decide which period before and after the trigger is logged. In the example we will log 5% of the time BEFORE and 95% of the time AFTER the trigger signal.

Now you can connect the signal you want to analyze to the Arduino. Channel 0 is connected to pin 8, channel 1 is pin 9 and so so. 6 channels are supported.


When everything is prepared, you can click the "Capture" button. You should see your signal on the screen:

Of course this logic analyzer isn't as good as the "big" (and expensive) ones. The biggest problem is the limited memory. Only short signals with low sampling rates can be analyzed. But for small projects it should be enough.