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