Visual basic Express SerialPort control

prtsoft

New member
VB 2005 express has a serial port control. It allows setting of baud, parity, stop bits etc just like mscomm. It has Write, writeline, and read methods. Can I use this control to control a USB 633? I'd like to be able to use the buttons independent of CC2. My Project is a standalone (project box attached to computer solely via USB) project for copying MP3s from a computer to a USB stick. The software is all written, I need only to interface with the LCD and it's buttons.

Thank you,

PRTSoft
http://prtsoft.com
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 

Heffo

New member
Yes, it will work perfectly. I have written a class in C# using the same control to run my 635.
 

Heffo

New member
Not Really, it's pretty straight forward. I just borrowed a file from Microsoft (which in turn was borrowed from the CrystalFontz Forums :D) and made a couple of tiny tweaks to make it friendlier to my application..

Here is the C# file, it shouldn't be too hard to port to VB.NET...
Code:
/*
 * Copyright (C) 2003 Microsoft Corporation
 * All rights reserved.
 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
 * MERCHANTIBILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 * Date: December, 2003
 * Author: Duncan Mackenzie
 * http://www.duncanmackenzie.net
 * Requires the 1.1 version of the .NET Framework
 *
 */
using System;
using System.Diagnostics;

namespace cf63x
{

    /// borrowed from https://forum.crystalfontz.com/showthread.php?threadid=1517
    /// <summary>
    /// Summary description for CRC.
    /// </summary>
    public class CRC16
    {
        private CRC16()
        {
        }

        private static uint[] crcLookupTable =
	{
		0x00000,0x01189,0x02312,0x0329B,0x04624,0x057AD,0x06536,0x074BF,
		0x08C48,0x09DC1,0x0AF5A,0x0BED3,0x0CA6C,0x0DBE5,0x0E97E,0x0F8F7,
		0x01081,0x00108,0x03393,0x0221A,0x056A5,0x0472C,0x075B7,0x0643E,
		0x09CC9,0x08D40,0x0BFDB,0x0AE52,0x0DAED,0x0CB64,0x0F9FF,0x0E876,
		0x02102,0x0308B,0x00210,0x01399,0x06726,0x076AF,0x04434,0x055BD,
		0x0AD4A,0x0BCC3,0x08E58,0x09FD1,0x0EB6E,0x0FAE7,0x0C87C,0x0D9F5,
		0x03183,0x0200A,0x01291,0x00318,0x077A7,0x0662E,0x054B5,0x0453C,
		0x0BDCB,0x0AC42,0x09ED9,0x08F50,0x0FBEF,0x0EA66,0x0D8FD,0x0C974,
		0x04204,0x0538D,0x06116,0x0709F,0x00420,0x015A9,0x02732,0x036BB,
		0x0CE4C,0x0DFC5,0x0ED5E,0x0FCD7,0x08868,0x099E1,0x0AB7A,0x0BAF3,
		0x05285,0x0430C,0x07197,0x0601E,0x014A1,0x00528,0x037B3,0x0263A,
		0x0DECD,0x0CF44,0x0FDDF,0x0EC56,0x098E9,0x08960,0x0BBFB,0x0AA72,
		0x06306,0x0728F,0x04014,0x0519D,0x02522,0x034AB,0x00630,0x017B9,
		0x0EF4E,0x0FEC7,0x0CC5C,0x0DDD5,0x0A96A,0x0B8E3,0x08A78,0x09BF1,
		0x07387,0x0620E,0x05095,0x0411C,0x035A3,0x0242A,0x016B1,0x00738,
		0x0FFCF,0x0EE46,0x0DCDD,0x0CD54,0x0B9EB,0x0A862,0x09AF9,0x08B70,
		0x08408,0x09581,0x0A71A,0x0B693,0x0C22C,0x0D3A5,0x0E13E,0x0F0B7,
		0x00840,0x019C9,0x02B52,0x03ADB,0x04E64,0x05FED,0x06D76,0x07CFF,
		0x09489,0x08500,0x0B79B,0x0A612,0x0D2AD,0x0C324,0x0F1BF,0x0E036,
		0x018C1,0x00948,0x03BD3,0x02A5A,0x05EE5,0x04F6C,0x07DF7,0x06C7E,
		0x0A50A,0x0B483,0x08618,0x09791,0x0E32E,0x0F2A7,0x0C03C,0x0D1B5,
		0x02942,0x038CB,0x00A50,0x01BD9,0x06F66,0x07EEF,0x04C74,0x05DFD,
		0x0B58B,0x0A402,0x09699,0x08710,0x0F3AF,0x0E226,0x0D0BD,0x0C134,
		0x039C3,0x0284A,0x01AD1,0x00B58,0x07FE7,0x06E6E,0x05CF5,0x04D7C,
		0x0C60C,0x0D785,0x0E51E,0x0F497,0x08028,0x091A1,0x0A33A,0x0B2B3,
		0x04A44,0x05BCD,0x06956,0x078DF,0x00C60,0x01DE9,0x02F72,0x03EFB,
		0x0D68D,0x0C704,0x0F59F,0x0E416,0x090A9,0x08120,0x0B3BB,0x0A232,
		0x05AC5,0x04B4C,0x079D7,0x0685E,0x01CE1,0x00D68,0x03FF3,0x02E7A,
		0x0E70E,0x0F687,0x0C41C,0x0D595,0x0A12A,0x0B0A3,0x08238,0x093B1,
		0x06B46,0x07ACF,0x04854,0x059DD,0x02D62,0x03CEB,0x00E70,0x01FF9,
		0x0F78F,0x0E606,0x0D49D,0x0C514,0x0B1AB,0x0A022,0x092B9,0x08330,
		0x07BC7,0x06A4E,0x058D5,0x0495C,0x03DE3,0x02C6A,0x01EF1,0x00F78
	};

        public static uint CalculateCRC(byte[] data, int offset, int length)
        {
            uint newCrc = 0x0FFFF;
            for (int i = offset; i < length; i++)
            {
                uint lookup = crcLookupTable[(newCrc ^ data[i]) & 0xFF];
                newCrc = (newCrc >> 8) ^ lookup;
            }
            return (~newCrc);
        }
    }
}
 

prtsoft

New member
Not Really, it's pretty straight forward. I just borrowed a file from Microsoft (which in turn was borrowed from the CrystalFontz Forums :D) and made a couple of tiny tweaks to make it friendlier to my application..

Here is the C# file, it shouldn't be too hard to port to VB.NET...
Thanks, I can handle that.
 
Last edited:

akweb

New member
Visual Basic CRC

Did anyone ever have any luck getting CRC to work in VB.NET (or Express 2005)?
 

Heffo

New member
If you like, I could compile the C# CRC code into a class library and post it here, then you could use the class lib from VB.NET
 

akweb

New member
That would be great, but I'm trying to learn how to send commands to the CFA-631 with VB.NET. I think my problem is getting the CRC portion to work. While your library would work, I'd like to know how to do it in coded. At this point, I'm just trying to send commands to it using "hardcoded" CRCs (taken from the 631 Wintest program), but unable to do so. I have some VB6 ActiveX controls I wrote for various displays and I'm trying to port them over to VB.NET.

Any code samples in VB.NET would get me on the right path.

Thanks!

AK
 

Heffo

New member
Unfortunately I don't have any VB.NET code, I deal in C# myself. Although the C# code posted above would be very easily converted.
 

DanielM

New member
Does anyone have a c# project that they could post? I really do not understand how to put everything together to send the command to the lcd(specifically the 635)

Thanks
Daniel M
www.kvsdm.com
 

Heffo

New member
I'll write a tutorial on how to simply communicate with the 635 in C# now and post it shortly. The code I have is pretty complicated since it uses threads and queues to manage the connection to the display, and it gets a bit tricky to follow in places.
 

DanielM

New member
Thanks Heffo. That'll be great.

I am programmer by profession(early in my career) but only have experience programming web and windows apps.

I tried using the system.io.ports in .net 2.0 but i am missing where in the lifecycle the crc comes into play, or how serialport.write sends the byte array including the correct packet structure.

My short term goal is to make some webservices for personal use to update the lcd on a remote computer.
Long term goal I would like to be able to tap into the obd II interface on my car to read diagnostic information and/or eventually be able to build my on digital gauges(just starting with pic microcontrollers).
 

DanielM

New member
Can someone tell me what I'm doing wrong?
Code:
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] System;[/SIZE]
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] System.Collections.Generic;[/SIZE]
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] System.IO.Ports;[/SIZE]
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] System.Text;[/SIZE]
[SIZE=2][COLOR=#0000ff]namespace[/COLOR][/SIZE][SIZE=2] ConsoleApplication1[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]class[/COLOR][/SIZE][SIZE=2][COLOR=#2b91af]LCD[/COLOR][/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#2b91af]SerialPort[/COLOR][/SIZE][SIZE=2] Port = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2][COLOR=#2b91af]SerialPort[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#a31515]"COM3"[/COLOR][/SIZE][SIZE=2], 115200, [/SIZE][SIZE=2][COLOR=#2b91af]Parity[/COLOR][/SIZE][SIZE=2].None, 8, [/SIZE][SIZE=2][COLOR=#2b91af]StopBits[/COLOR][/SIZE][SIZE=2].One);[/SIZE]
[SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]struct [/COLOR][/SIZE][SIZE=2][COLOR=#2b91af]PACKET_STRUCT[/COLOR][/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#2b91af]Byte[/COLOR][/SIZE][SIZE=2] command, data_length;[/SIZE]
[SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#2b91af]Byte[/COLOR][/SIZE][SIZE=2][] data;[/SIZE]
[SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]uint[/COLOR][/SIZE][SIZE=2] crc;[/SIZE]
[SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][SIZE=2] PACKET_STRUCT([/SIZE][SIZE=2][COLOR=#2b91af]Byte[/COLOR][/SIZE][SIZE=2][] byteArray, [/SIZE][SIZE=2][COLOR=#2b91af]Byte[/COLOR][/SIZE][SIZE=2] c, [/SIZE][SIZE=2][COLOR=#2b91af]Byte[/COLOR][/SIZE][SIZE=2] length)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]command = c;[/SIZE]
[SIZE=2]data_length = length;[/SIZE]
[SIZE=2]data = byteArray;[/SIZE]
[SIZE=2]crc = [/SIZE][SIZE=2][COLOR=#0000ff]uint[/COLOR][/SIZE][SIZE=2].MinValue;[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]#region[/COLOR][/SIZE][SIZE=2] CRC[/SIZE]
[SIZE=2][COLOR=#0000ff]private [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]uint[/COLOR][/SIZE][SIZE=2][] crcLookupTable =[/SIZE]
[SIZE=2]{//copied and pasted from above post by heffo};[/SIZE]
[SIZE=2][COLOR=#0000ff]#endregion[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]static [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]uint[/COLOR][/SIZE][SIZE=2] CalculateCRC([/SIZE][SIZE=2][COLOR=#0000ff]byte[/COLOR][/SIZE][SIZE=2][] data, [/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] offset, [/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] length)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]uint[/COLOR][/SIZE][SIZE=2] newCrc = 0x0FFFF;[/SIZE]
[SIZE=2][COLOR=#0000ff]for[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] i = offset; i < length; i++)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]uint[/COLOR][/SIZE][SIZE=2] lookup = crcLookupTable[(newCrc ^ data[i]) & 0xFF];[/SIZE]
[SIZE=2]newCrc = (newCrc >> 8) ^ lookup;[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2] (~newCrc);[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]public [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Send_Packet([/SIZE][SIZE=2][COLOR=#0000ff]ref [/COLOR][/SIZE][SIZE=2][COLOR=#2b91af]PACKET_STRUCT[/COLOR][/SIZE][SIZE=2] packet)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]byte[/COLOR][/SIZE][SIZE=2][] linear_array = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]byte[/COLOR][/SIZE][SIZE=2][26];[/SIZE]
[SIZE=2]linear_array[0] = packet.command;[/SIZE]
[SIZE=2]linear_array[1] = packet.data_length;[/SIZE]
[SIZE=2][COLOR=#0000ff]for[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] index = 0; index < packet.data_length - 1; index++)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]linear_array[index + 2] = packet.data[index];[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]packet.crc = CalculateCRC(linear_array, 0, packet.data_length + 2);[/SIZE]
[SIZE=2]linear_array[packet.data_length + 2] = ([/SIZE][SIZE=2][COLOR=#2b91af]Byte[/COLOR][/SIZE][SIZE=2])packet.crc;[/SIZE]
[SIZE=2]linear_array[packet.data_length + 3] = ([/SIZE][SIZE=2][COLOR=#2b91af]Byte[/COLOR][/SIZE][SIZE=2])packet.crc;[/SIZE]
[SIZE=2]Port.Open();[/SIZE]
[SIZE=2][COLOR=#0000ff]for[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] index = 0; index < packet.data_length + 3; index++)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]Port.Write(linear_array, 0, 1);[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]Port.Close();[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][SIZE=2] LCD()[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#2b91af]PACKET_STRUCT[/COLOR][/SIZE][SIZE=2] outgoing = [/SIZE][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#2b91af]PACKET_STRUCT[/COLOR][/SIZE][SIZE=2]();[/SIZE]
[SIZE=2]outgoing.command = 0x06;[/SIZE]
[SIZE=2]outgoing.data_length = 0;[/SIZE]
[SIZE=2]outgoing.data = [/SIZE][SIZE=2][COLOR=#0000ff]null[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2]Send_Packet([/SIZE][SIZE=2][COLOR=#0000ff]ref[/COLOR][/SIZE][SIZE=2] outgoing);[/SIZE]
 
[SIZE=2]}[/SIZE]
 
[SIZE=2]}[/SIZE]
[SIZE=2]}[/SIZE]
Code:
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] System;[/SIZE]
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] System.Collections.Generic;[/SIZE]
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] System.Linq;[/SIZE]
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] System.Text;[/SIZE]
[SIZE=2][COLOR=#0000ff]namespace[/COLOR][/SIZE][SIZE=2] ConsoleApplication1[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]class [/COLOR][/SIZE][SIZE=2][COLOR=#2b91af]Program[/COLOR][/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Main([/SIZE][SIZE=2][COLOR=#0000ff]string[/COLOR][/SIZE][SIZE=2][] args)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#2b91af]LCD[/COLOR][/SIZE][SIZE=2] LCD = [/SIZE][SIZE=2][COLOR=#0000ff]new [/COLOR][/SIZE][SIZE=2][COLOR=#2b91af]LCD[/COLOR][/SIZE][SIZE=2](); [/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]}[/SIZE]
I run a command prompt to just try and clear the screen but the lcd is not clearing?
 
Last edited:

Heffo

New member
Thanks for posting your code, I made a couple of tweaks to your Send_Packet routine to fix your handling of the CRC.

You needed to convert the result from the CRC calculation, into an unsigned short (16bit, unsigned integer), then get the raw bytes of the value and put into your linear_array. The modified code below should do the job for you.

As a side note, it would be wise to open the serial port in the class constructor, or via an open method, then close it in a destructor of some kind, or a close method, so you aren't continually opening and closing the port every time you send a packet.

You are also missing the return packets and SCAB/Keypad reports the way it is now.

Code:
public void Send_Packet(ref PACKET_STRUCT packet)
{
    byte[] linear_array = new byte[26];
    byte[] crc_bytes;

    linear_array[0] = packet.command;
    linear_array[1] = packet.data_length;

    Array.Copy(packet.data, 0, linear_array, 2, packet.data_length);
    //for (int index = 0; index < packet.data_length - 1; index++)
    //{
    //    linear_array[index + 2] = packet.data[index];
    //}

    packet.crc = CalculateCRC(linear_array, 0, packet.data_length + 2);
    
    crc_bytes = BitConverter.GetBytes((ushort)packet.crc);
    Array.Copy(crc_bytes, 0, linear_array, packet.data_length + 2);
    //linear_array[packet.data_length + 2] = (Byte)packet.crc;
    //linear_array[packet.data_length + 3] = (Byte)packet.crc;

    Port.Open();

    Port.Write(linear_array, 0, packet.data_length + 4);
    //for (int index = 0; index < packet.data_length + 3; index++)
    //{
    //    Port.Write(linear_array, 0, 1);
    //}

    Port.Close();
}
*Edit : I also fixed the Port.Write so you didn't do all the looping!
 
Last edited:

DanielM

New member
Thanks again Heffo

I get a "No overload for method copy takes 4 arguments at this line
right below
crc_bytes = BitConverter.GetBytes((ushort)packet.crc);
Code:
[SIZE=2][COLOR=#2b91af]Array[/COLOR][/SIZE][SIZE=2].Copy(crc_bytes,0, linear_array, packet.data_length + 2);[/SIZE]
Also what happens when packet.data is empty (isn't the data null on a clear screen command?)
 

Heffo

New member
Aah, sorry.. that should have been...

Array.Copy(crc_bytes,0, linear_array, packet.data_length + 2, 2);
 

DanielM

New member
Since packet.data is null i get a ArgumentNullException : value cannot be null parameter name:source

on the first array.copy call.
 

Heffo

New member
Also what happens when packet.data is empty (isn't the data null on a clear screen command?)
Well, if the data length is 0 then the data section of the packet will not be included..

I fixed up the routine again so it doesn't try to copy null data

Code:
public void Send_Packet(ref PACKET_STRUCT packet)
{
    byte[] linear_array = new byte[26];
    byte[] crc_bytes;

    linear_array[0] = packet.command;
    linear_array[1] = packet.data_length;

    if(packet.data_length > 0)
    {
        Array.Copy(packet.data, 0, linear_array, 2, packet.data_length);
    }
    //for (int index = 0; index < packet.data_length - 1; index++)
    //{
    //    linear_array[index + 2] = packet.data[index];
    //}

    packet.crc = CalculateCRC(linear_array, 0, packet.data_length + 2);
    
    crc_bytes = BitConverter.GetBytes((ushort)packet.crc);
    Array.Copy(crc_bytes, 0, linear_array, packet.data_length + 2, 2);
    //linear_array[packet.data_length + 2] = (Byte)packet.crc;
    //linear_array[packet.data_length + 3] = (Byte)packet.crc;

    Port.Open();

    Port.Write(linear_array, 0, packet.data_length + 4);
    //for (int index = 0; index < packet.data_length + 3; index++)
    //{
    //    Port.Write(linear_array, 0, 1);
    //}

    Port.Close();
}
 
Top