SERVO Controller

Category : ,

It has been a while since my last post. I have been working on image processing project that use webcam and laser pointer. However, i will keep it for later post.

Probably most of you know what is servo motor ( RC Servo ). It is a close-loop(system) motor and the rotation of the motor controlled by pulse. For example, at frequency 50Hz or 20ms period, given 1.5ms will keep the motor at the center while 1.0ms and 2.0ms will rotate the motor to the left and right respectively. By default, servo motor able to rotate from 0 to 90 degree(for each side). However, you can modify the servo to have full 360 degree of rotation.

Since we need pulse to control it, we must be able to provide PWM signal to the servo. Microcontroller basically could do that either using hardware-based PWM or software-based PWM. My aims today is to create a software-based PWM controller with UI Application. That means i can control the rotation of the servo by dragging the track bar around.


Basically, the apps will send a command to the controller board and the controller will interpret the command and generate required pulse. This is software-based PWM, means the generated pulse come from the algorithm that turn-off and turn-on at certain time. It is different from hardware-base PWM which has dedicated hardware to do the job.
I programmed my controller to generate interrupt every 5us, which means 4000 times of interrupt needed to complete 20ms of period time. Therefore, 1ms pulse equal to 200 and 2ms is equal to 400.

void interrupt() {
  if(PIR1.TMR1IF==1)    // trigger every 5us
  {
  servo0++;             // servo1 counter
  ctr_pwm++;
  if(servo0<=duty0) portb.f0=1;
  else portb.f0=0;
  if(ctr_pwm==4000)          // 20 ms elapse
  {
    servo0=0; ctr_pwm=0;  //clear counter
  }
  //TMR1H = 0xFF;             // Timer1 register value
  //TMR1L = 0xE6;
  PIR1.TMR1IF = 0;            // clear TMR1IF
  }
}
// In the main routine, just override duty0 register to required value, such as
// 1.0ms = 200
// 1.5ms = 300
// 2.0ms = 400

For the PC side, I used Visual Studio Express for application development. The App will communicate with controller through RS232 or serial port. Based on user input, ie the duty cycle, a packet of command will be sent to controller and then decode the message accordingly. The controller the execute the instruction and return acknowledge signal to PC. The routine continue as user gives another input.
// C# codes
    if (trackBar2.Value > 255)
    {
        data = (byte)((trackBar2.Value) >> 8);
        SP.WR_byte(token);
        SP.WR_byte(data);
        SP.WR_byte((byte)trackBar2.Value);
    }
    else
    {
        SP.WR_byte(token);
        SP.WR_byte(0);
        SP.WR_byte((byte)trackBar2.Value);
    }
}



I used trackbar instead of textbox. Just scroll the trackbar and duty cycle changed accordingly. The textbox on the right side of trackbar display the current value of the trackbar. The values shown actually is not in duty cycle format, ie, 0 to 100%, but it is in interrupt number format( 0 to 4000 ).

The codes works perfectly, i can control two servo motor simultaneously. The apps will help me to control and test RC servo motor, as well as reducing developing time of any project that requires servo motor.

However, there is a drawback of using software-based pwm because this method is not efficient. The rate of rising and falling edge of a signal might not accurate as our math’s calculation. Moreover, i believe that interrupt resolution also played an important role here. When i started the project, i choose 10us rather than 5us, but the later gives me more accurate and reliable PWM readings.

Upcoming project

Category :

It has been a while since my last update. quite busy lately. However, for the next coming posts, i will write about

  • Servo motor controller - using sw (software) pwm and controlling the rotation using PC
  • Accelerometer- logging acceleration data from accelerometer and graph drawing based on the data
  • Image processing and motion detector -  using Aforge.net and custom codes that i write myself

Xbee @ 802.15.4 module

Category :

Xbee is an OEM RF module that is works around IEEE 802.15.4 networking protocol. It is simple to configure, low-powered, small, line of sight range up to 100m(Xbee-PRO offers longer range) and very straightforward to use. Xbee have 3 networking topology or modes, unicast, multicast and broadcast.
I made a summary of important features or guides that you should know :
  • Indoor/Urban range: Up to 100 ft (30 m)
  • Outdoor/RF line-of-sight range: Up to 300 ft (90 m)
  • Interface data rate: Up to 115.2 Kbps
  • Networking topology: Point-to-point, point-to-multipoint, & peer-to-peer
  • Filtration options: PAN ID, Channel, and 64-bit addresses
  • Channel capacity XBee: 16 Channels
  • Addressing: 65,000 network addresses available for each channel
  • power supply XBee: 2.8 - 3.4 VDC
  • Interface options: 3V CMOS UART
  • Antenna options: U.FL, Reverse Polarity SMA (RPSMA), chip antenna or wired whip antenna
Xbee 802.15.4 Addressing
 
802.15.4 specification has two basic forms of addressing between the modules, Broadcast and Unicast.
Broadcast means that you send message that will be received by all modules that having the same PAN ID. In order to use a broadcast mode, you need to set DH=0x0000 and DL=0xFFFF and any module within the range will received the same message.

Unicast mode is more reliable method for delivering messages. In unicast mode, a message from one node transmits to another node based on the modules address and the receiving module will return ACK. If not, the host will keep trying to send the message until it receives an ACK.(a total of 4 attempts).

Xbee 802.15.4 comes with 16-bit and 64-bit addressing and is used for sending a Unicast message or data. The module has 2 configurable register that will keep the address information. DH/DL are for destination address register while MY is the source address. SH/SL registers are not configurable and contain unique ID assigned by manufacturer. SH/SL will be used in 64-bit addressing mode.

16-bit addressing
 
In 16-bit addressing, there are 2 register to play with, which are DH/DL and MY. Let’s say you have 2 Xbee modules, Xbee_A and Xbee_B.
--- Two-ways communication --- Xbee_A Xbee_B MY : 0x22 MY : 0x33 DH : 0 DH : 0 DL : 0x33 DL : 0x22
--- One-way communication ( Only Xbee_A transmit data to Xbee_B ) --- Xbee_A Xbee_B MY : 0x22* MY : 0x33 DH : 0 DH : 0* DL : 0x33 DL : 0* * optional
 
64-bit addressing
 
Disable 16-bit addressing by setting MY=0xFFFF or MY=0xFFFE. SH/SL = unique address incorporated by Digi (Device Serial Number) Set DH/DL of the ‘host’ to match SH/SL of the receiving module.
--- Two-ways communication with 64-bit adressing --- Xbee_A Xbee_B DH : 0x22222222 DH : 0x11111111 DL : 0x22222222 DL : 0x11111111 SH : 0x11111111 SH : 0x22222222 SL : 0x11111111 SL : 0x22222222
 
Xbee X-CTU setup


The screenshots of X-CTU from Digi. My Xbee connected to COM10 at baud rate 9600.
 


Click Test/Query button after selecting a correct COM port



Then click modem configuration tab. As you can see, there are a lot of button such as read, write, download, drop-down menu and etc. Click 'READ' button to read configuration from Xbee.

"Write" button used to 'program' or 'update' the module..



For beginner, there are 5 important registers to play with. PAN ID, Channel, MY, DH and DL should be set properly. In this example, I set MY=0x01, DH=0x00 and DL=0x02. PAN ID and CHANNEL of transmitting device MUST be set to MATCH receiving device.



Click on pull-down menu to choose/select appropriate baud rate.



You also can enable/disable API.



After setup all the required properties, test it using terminal window.

Digi have a lot of articles to support Xbee users --> Xbee support
Minimum connection: VDD, VSS, DIN, DOUT
Minimum connection for firmware upgrade: VDD, VSS, DIN, DOUT, RTS, *DTR (*trick : short DTR to ground )
 
Misc
  1. PAN ID and CHANNEL of trasmitting device must match the receiving device.
  2. Xbee also comes with ADC. That’s mean, depend on the project, it’s possible to use ADC with the absent of microcontroller. Data converted then read by receiving Xbee through UART. *allow the module to be connected directly to analog devices like sensors, and send the data in serial form.>
  3. Instead of using X-CTU application, Xbee also comes with API and AT-command sets. API offers a great flexibility of using Xbee. *I believe that X-CTU works on top of the API
  4. Xbee modules require 2.8 – 3.4 (CMOS logic) Vcc input voltage and NOT 5V-tolerant. Please choose correct microcontroller. Vref for ADC MUST not exceed Vcc.

FTDI FTD2XX.DLL Driver

Category :

FTDI D2XX Driver (accessing USB device through a DLL)

            My past projects required two devices to communicate over USB protocol. Just for an example, I have a mobile robot that I can control it via my PC or in other words, I send the command directly from my computer over Bluetooth or Xbee network to my robot. Xbee or Bluetooth transceiver connected to the robot brain( microcontroller) using rs232 protocol. But then, how to connect Bluetooth or Xbee at the other end to PC since most of PCs today are not coming together with comport (serial port)? A simple answer: USB.

FTDI offer a range of products to allow easy interfacing to devices over USB. You can go to their website and look for products that can meets your objective. I have been using 2 types of FTDI IC, which are FT232R (USB UART) and FT245BM (USB FIFO).

The IC comes with a driver that you can download. There are 2 types of drivers, VCP or Virtual COM Port and D2XX. VCP create a virtual serial port (COM port) and allow you to access the USB device in the same way as you access a standard COM port. That’s mean you can simply use HyperTerminal to read/write USB device.

However, that’s not the only way to access the IC. D2XX driver allow you to access USB device through a DLL and it offer flexibility of utilize the IC. So, what you need to know is how to use the DLL.

In this article, I will show an example how to use FTD2XX.DLL in VBA environment. FTD2XX.dll comes with a bunch of pre-defined function and properties. I have a long list of functions and properties of the driver, but i will only copy a part of it here.


Pre-defined constants 
'=========================================================================
    ' FTD2XX Return codes
 '=========================================================================

        Private Const FT_OK = 0
        Private Const FT_INVALID_HANDLE = 1
        Private Const FT_DEVICE_NOT_FOUND = 2
        Private Const FT_DEVICE_NOT_OPENED = 3
        Private Const FT_IO_ERROR = 4
        Private Const FT_INSUFFICIENT_RESOURCES = 5
        Private Const FT_INVALID_PARAMETER = 6
        Private Const FT_INVALID_BAUD_RATE = 7
        Private Const FT_DEVICE_NOT_OPENED_FOR_ERASE = 8
        Private Const FT_DEVICE_NOT_OPENED_FOR_WRITE = 9
        Private Const FT_FAILED_TO_WRITE_DEVICE = 10
        Private Const FT_EEPROM_READ_FAILED = 11
        Private Const FT_EEPROM_WRITE_FAILED = 12
        Private Const FT_EEPROM_ERASE_FAILED = 13
        Private Const FT_EEPROM_NOT_PRESENT = 14
        Private Const FT_EEPROM_NOT_PROGRAMMED = 15
        Private Const FT_INVALID_ARGS = 16
        Private Const FT_OTHER_ERROR = 17


Function Declaration
   '=======================================================================
    ' Declarations for device information functions in FTD2XX.dll:
 '=======================================================================

        Private Declare Function FT_GetNumDevices Lib "FTD2XX.DLL" Alias "FT_ListDevices" (ByRef arg1 As Long, ByVal arg2 As String, ByVal dwFlags As Long) As Integer

        Private Declare Function FT_GetDeviceString Lib "FTD2XX.DLL" Alias "FT_ListDevices" (ByVal arg1 As Byte, ByVal arg2 As String, ByVal dwFlags As Long) As Integer

        Private Declare Function FT_GetDeviceInfo Lib "FTD2XX.DLL" (ByVal lngHandle As Long, ByRef lngFT_Type As Long, ByRef lngID As Integer, ByVal pucSerialNumber As String, ByVal pucDescription As String, ByRef pvDummy As Byte) As Integer
  
    '=======================================================================
    ' Declarations for functions in FTD2XX.dll:
'=======================================================================

       Private Declare Function FT_OpenByIndex Lib "FTD2XX.DLL" Alias "FT_Open" (ByVal intDeviceNumber As Integer, ByRef lngHandle As Long) As Integer

       Private Declare Function FT_OpenBySerialNumber Lib "FTD2XX.DLL" Alias "FT_OpenEx" (ByVal SerialNumber As String, ByVal lngFlags As Long, ByRef lngHandle As Long) As Integer

       Private Declare Function FT_OpenByDescription Lib "FTD2XX.DLL" Alias "FT_OpenEx" (ByVal Description As String, ByVal lngFlags As Long, ByRef lngHandle As Long) As Integer

       Private Declare Function FT_Close Lib "FTD2XX.DLL" (ByVal lngHandle As Long) As Integer

       Private Declare Function FT_Read_String Lib "FTD2XX.DLL" Alias "FT_Read" (ByVal lngHandle As Long, ByVal lpvBuffer As String, ByVal lngBufferSize As Long, ByRef lngBytesReturned As Long) As Integer

       Private Declare Function FT_Write_String Lib "FTD2XX.DLL" Alias "FT_Write" (ByVal lngHandle As Long, ByVal lpvBuffer As String, ByVal lngBufferSize As Long, ByRef lngBytesWritten As Long) As Integer

       Private Declare Function FT_Read_Bytes Lib "FTD2XX.DLL" Alias "FT_Read" (ByVal lngHandle As Long, ByRef lpvBuffer As Byte, ByVal lngBufferSize As Long, ByRef lngBytesReturned As Long) As Integer

       Private Declare Function FT_Write_Bytes Lib "FTD2XX.DLL" Alias "FT_Write" (ByVal lngHandle As Long, ByRef lpvBuffer As Byte, ByVal lngBufferSize As Long, ByRef lngBytesWritten As Long) As Integer

       Private Declare Function FT_ResetDevice Lib "FTD2XX.DLL" (ByVal lngHandle As Long) As Integer

       Private Declare Function FT_GetModemStatus Lib "FTD2XX.DLL" (ByVal lngHandle As Long, ByRef lngModemStatus As Integer) As Integer

       Private Declare Function FT_Purge Lib "FTD2XX.DLL" (ByVal lngHandle As Long, ByVal lngMask As Integer) As Integer

       Private Declare Function FT_SetTimeouts Lib "FTD2XX.DLL" (ByVal lngHandle As Long, ByVal lngReadTimeout As Integer, ByVal lngWriteTimeout As Integer) As Integer

       Private Declare Function FT_GetQueueStatus Lib "FTD2XX.DLL" (ByVal lngHandle As Long, ByRef lngRxBytes As Integer) As Integer

       Private Declare Function FT_SetUSBParameters Lib "FTD2XX.DLL" (ByVal lngHandle As Long, ByVal lngInTransferSize As Integer, ByVal lngOutTransferSize As Integer) As Integer

       Private Declare Function FT_SetBreakOn Lib "FTD2XX.DLL" (ByVal lngHandle As Long) As Integer

       Private Declare Function FT_SetBreakOff Lib "FTD2XX.DLL" (ByVal lngHandle As Long) As Integer

       Private Declare Function FT_GetStatus Lib "FTD2XX.DLL" (ByVal lngHandle As Long, ByRef lngamountInRxQueue As Integer, ByRef lngAmountInTxQueue As Integer, ByRef lngEventStatus As Integer) As Integer

The codes above used to define functions/properties of ftd2xx.dll so that VBE could ‘recognize’ the functions. The word “Alias” allows the functions to be called using another name.
    Private Declare Function FT_OpenByIndex Lib "FTD2XX.DLL" Alias "FT_Open" (ByVal intDeviceNumber As Integer, ByRef lngHandle As Long) As Integer
Instead of calling FT_Open, you could ‘rename’ the function to FT_OpenByIndex. However, it’s up to you either to follow or not. After all the functions have been declared, now, you can start to write your codes/functions.
    Note : in VB6, integer is 16-bit unsigned number  Long is 32-bit unsigned number. Be careful when using the function, if it cannot behave like what you want, please check the data type. I personally prefer to use long rather than integer.

You can start using the device after you ‘open’ the device. There are several ways to open the device. 2 methods that works for me are ‘open by index’ and ‘open by serial number’

Open by index method required the device’s index as a parameter and it will return a handle of the device that will be used later. For an example, if you have 2 FTDI device connected to the PC, the 1st device indexed to 0 and the 2nd device indexed to 1. So, in order to use the 1st device, place 0 as an input parameter.

    FT_OpenByIndex(index, FT_Handle)   ‘ index is  0

How do you know how many device connected to PC? Take a look at your PC or sniff the connected device using “FT_GetNumDevices” function. It will return the number of device connected to your PC.

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Open by index
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    'Public Function OpenDevice(ByVal index As Byte) As Boolean

    '        If FT_GetNumDevices(FT_Device_Count, vbNullChar, FT_LIST_NUMBER_ONLY) <> FT_OK Then

    '              ' no usb device found
    '              MsgBox "No Device Found"
    '              OpenDevice = False

    '        Else

    '            ReDim FT_Handle(FT_Device_Count - 1)
    '            If FT_Device_Count <> 0 Then
    '                If FT_OpenByIndex(index, FT_Handle(index)) <> FT_OK Then
    '                    ' cannot open device [communication error]
    '                    MsgBox "Failed to Open Device"
    '                    OpenDevice = False
    '                Else
    '                'MsgBox ("Success")
    '                OpenDevice = True
    '                End If

    '            Else
    '                OpenDevice = False
    '                MsgBox "No Device Found...."
    '            End If
    '        End If
    'End Function

The second method is using device serial number as an input parameter. This is more powerful technique, yet helps you to open the right device.

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Open by serial number
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' same as open by index but using device's serial number as a reference

    Public Function OpenDevice(ByVal SerNum As String, ByVal DevID As Byte) As Boolean

    If FT_GetNumDevices(FT_Device_Count, vbNullChar, FT_LIST_NUMBER_ONLY) <> FT_OK Then
                  ' no usb device found
                  MsgBox "No Device Found....", vbCritical, "ERROR"
                  OpenDevice = False
    Else
            'ReDim FT_Handle(FT_Device_Count - 1)
            SerNum = Trim(SerNum)
            If FT_Device_Count <> 0 And FT_Handle(DevID) = 0 Then

                If FT_OpenBySerialNumber(SerNum, FT_OPEN_BY_SERIAL_NUMBER, FT_Handle(DevID)) <> FT_OK Then

                    'MsgBox ("failedEX")
                    OpenDevice = False
                Else
                    'MsgBox ("SuccessEX")
                    OpenDevice = True
                End If
            Else
                OpenDevice = False
                MsgBox "No Device(s) Found.... or" & vbCrLf & "ID " & DevID & " has been assigned to other device", vbCritical, "ERROR"
            End If
    End If

    End Function

Before using the function, you need to know the device’s serial number. There is a dedicated function to make your work easy. This function works by getting the number of FTDI driver attached to the PC and then, get the serial number of each device and paste to current active cell.(VBA).

    Public Sub ChDevice()

     Dim TempDevString() As String
     Dim inta As Long  

     If FT_GetNumDevices(FT_Device_Count, vbNullChar, FT_LIST_NUMBER_ONLY) <> FT_OK Then

                  ' no usb device found
                  MsgBox "No Device Found"
                  Exit Sub
     Else
        If FT_Device_Count <> 0 Then
            ReDim TempDevString(FT_Device_Count - 1)
            For inta = 0 To FT_Device_Count - 1
            TempDevString(inta) = Space(16)

                If FT_GetDeviceString(inta, TempDevString(inta), FT_LIST_BY_INDEX Or FT_OPEN_BY_SERIAL_NUMBER) <> FT_OK Then
                   'could not enumerate USB device
                   MsgBox ("Couldn't get Device(s) Serial Number")
                   Exit Sub
                Else
                TempDevString(inta) = Left(TempDevString(inta), InStr(1, TempDevString(inta), vbNullChar) - 1)
                End If
            Next

                ' display device(s) ID
                For inta = 0 To FT_Device_Count - 1
                ActiveCell.Offset(inta, 0).value = TempDevString(inta)
                Next
        Else
                MsgBox "No Device(s) Found", vbCritical, "ERROR"
        End If
     End If
     End Sub
    Note : FTD2XX.dll also has dedicated function to obtain the device(s) descriptions.
Another function that I will cover is FT_READ. There are 2 type of read access or may be more (please check programming guide). Since, I know my incoming data are in array form, I prefer to use FT_READ_BYTE.

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Read
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    Public Function ReadFifo(ByVal index As Byte, ByRef FT_In_Buffer() As Byte, ByVal Read_Count As Long) As Boolean  

    Dim Read_Result As Long    
    ' clear FT_in_buffer before used
      Erase FT_In_Buffer
    ' ReDim FT_In_Buffer(1) As Byte    

            If FT_OK <> FT_Read_Bytes(FT_Handle(index), FT_In_Buffer(0), Read_Count, Read_Result) Then
                'MsgBox ("Error while reading from FIFO1")
                ReadFifo = False
            Else
                If Read_Count <> Read_Result Then
                    'MsgBox ("Error while reading from FIFO2")
                    ReadFifo = False
                Else
                    ReadFifo = True
                End If
            End If    
    End Function

The same thing applied to write access. I keep data in an array (byte type) and then write it to the device.

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Write
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    Public Function WriteFifo(ByVal index As Byte, ByRef FT_Out_Buffer() As Byte, ByVal Write_Count As Long) As Boolean

    Dim Write_Result As Long               

            If FT_OK <> FT_Write_Bytes(FT_Handle(index), FT_Out_Buffer(0), Write_Count, Write_Result) Then
                'cannot write to USB
                'MsgBox ("Error while writing to FIFO")
                WriteFifo = False
            Else
                If Write_Result <> Write_Count Then
                    'some byte missing
                    'MsgBox ("Error while writing to FIFO")
                    WriteFifo = False
                Else
                    WriteFifo = True
                End If
            End If    
    End Function
The simplest function to use is FT_CLOSE as shown below. The function required a handle of a device that will be terminated / closed.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Close
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    Public Function CloseDevice(ByVal index As Byte) As Boolean
            If FT_Close(FT_Handle(index)) <> FT_OK Then
                'MsgBox ("Error : FT_CLOSE")
                CloseDevice = False
                Exit Function
            End If
            FT_Handle(index) = 0    'clear 'old' item
            CloseDevice = True 
    End Function
What if your program/application keeps waiting the incoming data that will never come? The computer will keep waiting or if you lucky, it will give you an error. Therefore, FT_SetTimeouts plays an important role here. You can set device timeouts for read and write access and without having to “waste” your time.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' set times out
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Public Function Set_USB_Device_Timeouts(ByVal index As Byte, ByVal ReadTimeOut As Integer, ByVal WriteTimeout As Integer)

            If FT_OK <> FT_SetTimeouts(FT_Handle(index), ReadTimeOut, WriteTimeout) Then
                ' dont expect sumthing here
            End If
    End Function
These are the basic functions that usually been used but there are still a bunch of functions that have not been discussed. Well, why don’t you give a try☺.

wysiwyg is ! wysiwyg

Category :

I have 2 articles that ready to be published this week. However, due to circumstances, i had to postpone it. The articles are written in doc format, but, since i want to improve my HTML skills, i convert it to HTML form. I use CoffeaCup and LiveWriter as my editor and it does output correct layout. But after publish it here, it's not what i wanted to. 

Just forget about that...the upcoming posts will talk about "Xbee module" and "FTD2XX.dll driver."
 

Microsoft DOT NET

Category :







Microsoft .Net

Recently, a friend of mine bother me with one quick question, "What is .NET or pronounced as dot net?." That was a good question because i had to find a best approach to explain it to him( To be honest, i don't expect another question coming from him ). After explaining it in my way, he started to understand the concept lying behind it.


.NET allow you to use some pre-defined function/features under Windows, such as I/O ports, database interaction, GDI+ and any other API. There are so many versions of .NET framework released to date.

  • .NET Framework 1.0
  • .NET Framework 1.1
  • .NET Framework 2.0
  • .NET Framework 3.0
  • .NET Framework 3.5
  • .NET Framework 4.0

What is .NET?

The .NET Framework is a Microsoft technology that provides features and functions that can be used by programs which run under Microsoft Windows. It provides extra functionality that is not included in the basic operating system. Programs that take advantage of the latest Microsoft technology require the Microsoft .NET Framework to be installed, or they will not work. To run these new applications, you must ensure that an appropriate version of the .NET runtime is installed on your computer. If you are using Microsoft Internet Explorer, this page can tell you which versions of the .NET runtime are currently installed......more


what wiki says about .NET

Serial Port ( RS232 protocol )

Category :




serial port


Serial Port atau lebih popular dengan nama RS232 adalah protocol/interface yang paling banyak digunakan dan popular terutamanya di kalangan pelajar. Rs232 protocol mudah digunakan, incorporated in PC(mostly old PCs), some microcontroller dan tidak memerlukan hardware yg expensive. But today,USB lebih popular kerana mudah, plug n play, and offer higher transfer rates compared to RS232.

I have been using Serial Port for quite some time in a lot of projects. Contohnya, interfacing a robot with external device such as zigbee or bluetooth module. So, i think it's good to write article about serial port/RS232. My objective here is to show the way to write codes to access PC serial port

There are 2 ways to access PC serial port(as far as i know).

  • using mscomm32.ocx
  • .NET object
I prefer the 2nd method because lebih mudah digunakan and i use C#(.NET) a lot. I have written a script in VBA to access serial port from Microsft Excel(using mscomm32.ocx). VBA stand for Visual Basic for Application which is exists in Excel(you probably know it if you're familiar with Excel macro)


.NET component - using C#


If you're familiar with C# or C++ or VB.NET, then it's better jika anda menggunakan .NET component. I will show an example of source code written in C# in this post. First of all, you need to 'define' the component in the project file by a 'using' statement on top of the file.


    using System.IO.Ports;
The above statement will allow you to access serial port component.

    class SerialPortCustom
    {
        SerialPort SP = new SerialPort();      

        public SerialPortCustom()
        {
            SP.BaudRate = 57600;
            SP.Handshake = Handshake.None;
            SP.Parity = Parity.None;
            SP.PortName = " ";
            SP.StopBits = System.IO.Ports.StopBits.One;
            SP.DataBits = 8;
        }
  
 //remaining codes are not displayed ~~~~ 

This is a sample of source code from my past project. I create a class name "SerialPortCustom". This class will handle all the serial port events and function. As you can see, in the class constructor, 6 items were pre-defined. So, my baudrate works at 57600 bps without handshake signal and parity, 1 stop bit and 8 data bits. However, i left portName empty so that i can choose available port later. This just the basic idea how to instantiate .NET serial port component. It is possible if you want to change all the properties in the form later, but you need to write a proper code to handle it.

Next, you must have functions or methods to read data from receive buffer or to write data to transmit buffer. Therefore, you can instantiate event handler for every data received as shown below. However, you can use polling method if your application know the exact time of incoming data/packet.
//instantiate event handler : raised when RX buffer is not empty.
    SP.DataReceived += new SerialDataReceivedEventHandler(SP_DataReceived);
Every data in received buffer will raised the event. Then, it's up to you what you want to do with the data. Just for an example, when the event raised, the method reads up all 4 bytes of the incoming data before calling another function/method as shown below.

 // This event raised if received buffer is full
        public void SP_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {        
            stream_buffer[0] = SP.ReadByte();   //read 1st byte
            stream_buffer[1] = SP.ReadByte();   //read another byte and so on
            stream_buffer[2] = SP.ReadByte();
            stream_buffer[3] = SP.ReadByte();
            parsing_display();   //calling another method
        }
Perhaps you also wants to write something through your serial port. Therefore, you can write a function for that purpose. The codes below is just a simple function that accepts 1 byte of data and transmit through serial port(RS232).

 // "write" method
        public void WR_byte(byte byte_data)
        {   
            argv[0] = byte_data;  // argv[] used to hold the data
            SP.Write(argv, 0, 1);  // transmit 1 byte through serial port (com port)
 }
In conclusion, it is easy to use/work with serial port (RS232) using .NET framework. If you are not familiar with C#, you can write in VB and also C++. I wrote the script in VB.NET once for my final year project purpose. The syntax are different but the concept is just the same. Now, let's move on to the next section.


MSCOMM32.OCX - VBA


Selain menggunakan C#/.NET, it is possible to access serial port directly in Microsoft Excel. What you need is just MSCOMM32.ocx and basic knowledge in VBA. However, several steps required before you can start programming.

You need to register the file first so that your VB editor could recognize the components. Place the file in system32 folder and then click start -> run and paste the command below.
    Regsvr32 "C:\Windows\System32\mscomm32.ocx" 
After you completed the lst step, run Microsoft Excel and open VB editor. Same as C#, 2 methods shall be implemented, either event-based or polling method. Polling method is suitable if you know exact time of incoming data.

First, you need to instantiate the object(class).
    Private SerCom As New MSComm 
Then, you need to set properties of the class such as baud rate, handshaking, and so on.
    With SerCom
         .CommPort = com_number
         .Settings = "57600,M,8,1"
         .Handshaking = comNone
         .InputLen = 8
         .InBufferSize = 8
         .NullDiscard = True
         .InputMode = comInputModeText
         .RThreshold = 1
 End With
Next, you can use buttons to enable/disable serial port operation.
    If SerCom.PortOpen = False Then
     SerCom.PortOpen = True                      ' turn on serial port  
       Else
     ' error handling or any code here 
       End If 
My previous project not required event-based method since i know exactly when the transaction will occur.
    ' a piece of code for read and write

     SerCom.InputLen = 0      
    ' Setting InputLen to 0 causes the MSComm control to read the entire
contents of the receive buffer
chdata = Replace(SerCom.Input, vbCrLf, "") ' get a stream of data from the receive buffer ' the codes also remove carriage return and line feed ' access write Public Sub UART_write(ByVal str As String) SerCom.Output = str + vbCrLf ' place any other codes here End Sub
However, if you choose to use event-based method, you need to declare the event first.
    ' declare an event 
    Private WithEvents SerCom As MSCommLib.MSComm
 
     ' this method raised on any event that you define in it.
     Private Sub SerCom_OnComm() 
     If SerCom.CommEvent = 2 Then
      ' read recieve buffer : code goes here 
     ElseIf SerCom.CommEvent = x Then ' x = Communications events/errors
      ' do something else
     End If
     End Sub
Click here for more details.
MSCOMM32.OCX is a native component or API by Microsoft. However, it helps me a lot when my boss asked me to write a macro that can access serial port.
Most PC manufacturer dumps RS232/COM port for USB. However, you can buy RS232(I/O expansion) card or USB to RS232 converter.

Hello World.......errr, worldwide

Category : , ,



Worldwide Edition


Let's learn how to "say" 'Hello World' in different language:

  • In C language
     int main(void)
     {
        printf("Hello World \n");
     }

  • In C++ language
     using namespace std;
     void main() 
     {
            cout << "Hello World" << endl;
            return 0;
     }

  • In C# language
     using System;
     public class Hello2
     {
         public static void Main()
       {
         Console.WriteLine("Hello, World!");
       }
     }

  • In VB/VBA language
     Module Hello
        MsgBox("Hello, World!") ' Display message on computer screen.
     End Sub

  • In Perl
     #!/usr/local/bin/perl
     print "Hello World\n";

Hello World !!

Category :

hello world


Sudah menjadi lumrah, bila belajar tentang bahasa pengaturcaraan atau programming language , " Hello World " adalah ayat lazim yang selalu digunakan, termasuklah my 1st post. Sedar tak sedar, dah banyak language yang aku dah belajar. Antaranya :

  • C, C++ and C# (the best ever!!)
  • VB -> VBA and .NET
  • Assembly lang ( microcontroller and microprocessor )
  • perl and tcl (scripting language)
  • html and javascript -> beginner (however, both html and javascript are not p.lang)
For more info, you should go to this website or meet my best friend
And since aku seorang yang mudah lupa, personally i think, better for me to share the codes/knowledge here so that, later senang la jugak kalau nak rujuk nanti..