Tuesday, July 29, 2008

c# windows form store global data

Using the following Class, you can store somethings you need cross forms.
Pretty handy sometimes instead of using Setting in C#. Setting creates visible config file
and it's pretty slow to read and write.



class GlobalData
{
private static GlobalData _instance = new GlobalData();
private string _formString = "";

static GlobalData()
{
}

public static GlobalData GetInstance()
{
return _instance;
}

public string TokenString
{
get
{
return _formString;
}
set
{
_formString = value;
}
}
}



Friday, July 25, 2008

An Extensive Examination of Data Structures Using C# 2.0

The following tutorial is even better than the books that I read before.
http://msdn.microsoft.com/en-us/library/ms364091%28VS.80%29.aspx

c# useful function Array Copy

Sometimes, you wanted to copy part of an array to another array. Use the following method, it can handle all
sorts of copy, and don't need to worry the source array and destination array length.

Array.Copy(Array sourceArray, long sourceIndex, Array destinationArray, long destinationIndex, long length);
// Summary:
// Copies a range of elements from an System.Array starting at the specified
// source index and pastes them to another System.Array starting at the specified
// destination index. The length and the indexes are specified as 64-bit integers.
//
// Parameters:
// destinationIndex:
// A 64-bit integer that represents the index in the destinationArray at which
// storing begins.
//
// sourceIndex:
// A 64-bit integer that represents the index in the sourceArray at which copying
// begins.
//
// length:
// A 64-bit integer that represents the number of elements to copy. The integer
// must be between zero and System.Int32.MaxValue, inclusive.
//
// destinationArray:
// The System.Array that receives the data.
//
// sourceArray:
// The System.Array that contains the data to copy.
//

c# serial port data download

I recently posted a link to very good tutorial on communication with serial port using .Net c#.

In terms of the structure, the tutorial demonstrate the way to send command, and register SerialDataReceivedEventHandler
to handle DataReceived event.

The point I want to make is because it is a separate thread, if you wanted to change UI in that thread, Invoke delegate functions.
In addition, communication with serial port will involve CRC checking. So, before you do any thing to the data, check it.
Normally, you might need to send multiple commands to the port. You should send it by sequence, and send it before the previous command is handled. For example, check all the data is correctly received. If there are missing or error data, or even timeout, Resend the request command again. Finally, If you wanted to save data onto disk, You don't have to use asynchronous method, because the data received is very small, and in Windows, you won't enhance the performance of IO if your data block is less than 64K.

The final trick, don't use Thread.Sleep() in your GUI. Since you need to wait until the previous command is handled, doesn't mean you have to stuck in an infinite loop, or call Sleep to hang your GUI. You can simply create a timer to perform the checking and sending.


Thursday, July 24, 2008

c# Asynchronous read write file

Quite often, you need to perform IO in .Net.
It is very useful that when coding windows form application, you perform asynchronous actions. Nobody like a freezing UI.
http://www.devsource.com/c/a/Using-VS/Making-Asynchronous-File-IO-Work-in-NET-A-Survival-Guide/



static void asyncWrite()
{
byte[] data = new byte[BUFFER_SIZE];
FileStream fs = new FileStream("writetest.dat", FileMode.Create,
FileAccess.Write, FileShare.None, 1, true);
try
{
// initiate an asynchronous write
Console.WriteLine("start write");
IAsyncResult ar = fs.BeginWrite(data, 0,
data.Length, null, null);
if (ar.CompletedSynchronously)
{
Console.WriteLine("Operation completed synchronously.");
}
else
{
// write is proceeding in the background.
// wait for the operation to complete
while (!ar.IsCompleted)
{
Console.Write('.');
System.Threading.Thread.Sleep(10);
}
Console.WriteLine();
}
// harvest the result
fs.EndWrite(ar);
Console.WriteLine("data written");
}
finally
{
fs.Close();
}
}



c# CRC16 ccitt

While working with serial port, I was required to perform crc checking on data that I received.
I used the following code.



using System;
using System.Collections.Generic;
using System.Text;

namespace SerialPortTerminal
{
public enum InitialCrcValue { Zeros, NonZero1 = 0xffff, NonZero2 = 0x1D0F }

public class Crc16Ccitt
{
const ushort poly = 4129;
ushort[] table = new ushort[256];
ushort initialValue = 0;

public ushort ComputeChecksum(byte[] bytes)
{
ushort crc = this.initialValue;
for (int i = 0; i < bytes.Length; i++)
{
crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
}
return crc;
}

public byte[] ComputeChecksumBytes(byte[] bytes)
{
ushort crc = ComputeChecksum(bytes);
return new byte[] { (byte)(crc >> 8), (byte)(crc & 0x00ff) };
}

public Crc16Ccitt(InitialCrcValue initialValue)
{
this.initialValue = (ushort)initialValue;
ushort temp, a;
for (int i = 0; i < table.Length; i++)
{
temp = 0;
a = (ushort)(i << 8);
for (int j = 0; j < 8; j++)
{
if (((temp ^ a) & 0x8000) != 0)
{
temp = (ushort)((temp << 1) ^ poly);
}
else
{
temp <<= 1;
}
a <<= 1;
}
table[i] = temp;
}
}
}
}





C# convert between int and byte array

BitConverter is a native way of converting int and byte[]. In fact, converting byte array into float(single in C#), double, Int16,Int32 etc....

For example:
int tmp = 10;
byte[] b = BitConverter.GetBytes(tmp);

// convert to float
byte[] b = new byte[4];
BitConverter.ToSingle(b, 0);

Depending on how you want the byte[] to be converted, BitConverter has whole lot functions to do that.Only to remember, if you are about to convert 8 bit byte array, you can simply cast it to int.

One interesting thing is that when you wanted to receive bytes from network, you might need to worry about big endian and little endian issue. I saw some hard solutions, but found a simple way of doing it.

byte[] receiveBytes = receivingUdpClient.Receive(ref RemoteIpEndPoint);
Array.Reverse(receiveBytes);

Enjoy

Tuesday, July 22, 2008

.Net C# serial port

http://msmvps.com/blogs/coad/archive/2005/03/23/SerialPort-_2800_RS_2D00_232-Serial-COM-Port_2900_-in-C_2300_-.NET.aspx

The above sample code is one of the best tutorial I have ever find discussing serial port programming using .Net. I recently been asked to download data from device through serial port.
To start with, I used the demo example to send simple command to the device and see whether the response is what I expected. Then I start working on my own application. Enjoy.

Windows Fomr ----- Datagridview with collapse function

After a lot of digging, I realise the easiest way to create collapse function in datagridview is by using a + or - icon and implement the algorithm myself.
The custom control is either too complected or not I want. Just use an image and it solves all problems.

Windows From ----- Only one instance of the program can be started

Don't want user to start your application twice ? Use the code below:

static void Main()
{
bool instanceCountOne = false;

using (Mutex mtex = new Mutex(true, "MYApplication", out instanceCountOne))
{
if (instanceCountOne)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

using(login l = new login())
{
if (l.ShowDialog() == DialogResult.OK)
{
l.Dispose();

if (Properties.Settings.Default.from_database == true && Properties.Settings.Default.Start_CommitChanges == true)
{
Connecter c = new Connecter();
commit_changes(c);
}

Application.Run(new GUI());
}
else
{
l.Dispose();
//MessageBox.Show("Login Cancelled.");
}
}

mtex.ReleaseMutex();
}
else
{
MessageBox.Show("An application instance is already running");
}
}
}