Skip to main content

Messages

This section allows you to view all Messages made by this member. Note that you can only see Messages made in areas you currently have access to.

Messages - arhi

18
Client software / Re: pushing external data into client
want to use the "fancy" file now .. I have a question  -
 - Compressed - does it expect RLE compressed data in the file or?
 - AbsoluteLength - maximum timestamp - but in what units? seconds? milliseconds? microseconds? picoseconds? long integer?
 - cursorX - long int, I assume timestamp in same format as AbsoluteLength?
 - TriggerPosition? same as cursorX ?
 - sample data == <sample value>@<sample number>, sample value is HEX that's clear 1 byte for 8 channels, 4 bytes for 32 channels right? but sample number - wiki states
Quote
The sample number correlates to the absolute time at which the sample was taken.
explain this? is this just the order number or this can be a timestamp? Can this happen? Can it be 64bit long?

thanks
20
Client software / Re: pushing external data into client
hm something is wrong with RAW format ?!

this is what I have on the LA:


this is what my txt display of first 100 states looks like
Code: [Select]
0000000000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000
0000000000000000000010000000100000011000000100000011000000100000011000000100000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

This is what hex of the RAW file looks like:
[attachment=2]

And as you can see it coresponds ok (the hex) with what's on LA display and what's in txt representation

but this is what capture in ols client looks like :(

[attachment=2]

you see both the tracewave and the capture settings I used, channel count 16 so 2 bytes (and this is proper since channels 4+ are all low in whole trace), sample rate irrelevant, depth 4k (that's how many samples I have), sample width 1 (no clue what this is)
22
Client software / Re: pushing external data into client
[quote author="jawi"]For timed data: assuming the time starts at zero, each sample corresponds to the index * sample interval.

For state data it is assuming we start at state 0 and each sample is an increment of the state.[/quote]

so you don't define it in raw file but the way you configure "scan" right?
24
Client software / Re: pushing external data into client
[quote author="jawi"][quote author="arhi"]what is the RAW data format?[/quote]

Just raw bytes: given the sample width (in bytes) and the sample depth, it will combine each pair of bytes into a 16-bit sample value (MSB first).[/quote]

ah so there you can't say the sampling time etc ... just states ... might be easiest one to try for start :D
26
Client software / Re: pushing external data into client
[quote author="jawi"]My knowledge on HPIB/GPIB is as little as the weird-looking connector it's using, so I was wondering what format the data has when you eventually receive it. By glancing through your code, I see it's a ASCII based protocol with some bitpacked numbers. Converting that to the plain OLS format should not be that difficult.
[/quote]

mine knowledge about the HPIB/GPIB was exactly the same until few days ago :D
the hardware layer is complicated (if you ask me, overcomplicated for no reason) but the software layer is fairly simple, you can send addressable packet or a broadcast, and you can receive packets. The packets are some ascii commands you send followed by some binary stream of block data and reply is some block data usually with some ascii header... the problem is that to send/receive you need to use a special hpib libraries that are not properly (at all) documented. That's why I'm using .net as it's the only one I made to send/receive data :D. Most of HPIB applications and libraries revolve around drivers where in driver you say "do this and that" and driver takes care about what to send to hpib and how to parse results, but if you don't have driver and talk to device directly that part is not documented and that's exactly what I use (as no driver for this LA that I could find)

[quote author="jawi"]
I've added (or hacked) support for reading the OLS data file format using the generic device, you can download a CI-build to test it. Currently, it is still device/socket/file based, but we could add additional means rather quickly if desired.[/quote]

thanks, downloaded it, what should I do? change device to generic io and file open project? and then open the file in format described here: https://github.com/jawi/ols/wiki/OLS-data-file-format ? what's the max no of channels I can put in?
27
Client software / Re: pushing external data into client
here's the initial app I wrote to test this maybe this will answer the question

Code: [Select]
using System;
using System.Collections.Generic;
using System.Text;
using Ivi.Visa.Interop; //The HPIB access library

namespace kk2
{
    class Program
    {
        static void Main(string[] args)
        {
            // resource manager and message-based session manager
            ResourceManager rMgr = new ResourceManagerClass();
            FormattedIO488 src = new FormattedIO488Class();
            int i, j, k;
            string inBuffer;
            int hdrlength = 23;
            byte[] b8 = new byte[8];

            // measurement setup
            string srcAddress = "GPIB1::7::INSTR";  // HPIB address of HP1661C (should be a parameter, not hardcoded)
            src.IO = (IMessage)rMgr.Open(srcAddress, AccessMode.NO_LOCK, 2000, null);
            src.IO.Timeout = 2000;
            inBuffer = "";

            // setup clock
            Console.Write("HP1661C at " + srcAddress + " setup..");
            src.IO.Clear();
            src.WriteString(":SYSTEM:HEADER ON", true);
            src.WriteString(":SYSTEM:LONGFORM ON", true);
            src.WriteString("SELECT 1", true);
            Console.WriteLine("done");  // setup BERT
            src.WriteString(":SYSTEM:DATA?", true);
            inBuffer = src.ReadString();
            src.IO.Close();
            k = inBuffer.Length;
            Console.WriteLine();

            if (k < 16)
            { //not even header
                Console.WriteLine("ERROR: we did not even catch a header");
                return;
            }

            hdrlength = inBuffer.IndexOf("DATA      ");
            if (!inBuffer.Substring(hdrlength, 11).StartsWith("DATA      "))
            {
                Console.WriteLine("ERROR: wrong header");
                return;
            }

            int moduleID = (int)inBuffer[hdrlength + 11];
            Console.Write("Module ID: ");
            Console.Write("[0x" + moduleID.ToString("x") + "] ");
            Console.WriteLine(Convert.ToString(moduleID, 2));

            byte lengthD3 = (byte)inBuffer[hdrlength + 12];
            byte lengthD2 = (byte)inBuffer[hdrlength + 13];
            byte lengthD1 = (byte)inBuffer[hdrlength + 14];
            byte lengthD0 = (byte)inBuffer[hdrlength + 15];
            int sectionLength = lengthD0 + lengthD1 * 256 + lengthD2 * 256 * 256 + lengthD3 * 256 * 256 * 256;
            Console.Write("Section length = ");
            Console.WriteLine(sectionLength);

            int instrumentID = (int)inBuffer[hdrlength + 16] * 256 + (int)inBuffer[hdrlength + 17];
            int revisionCode = (int)inBuffer[hdrlength + 18];
            Console.Write("Instrument ID: ");
            Console.Write(instrumentID);
            Console.Write(" Revision ");
            Console.WriteLine(revisionCode);

            int numberPodPairs = (int)inBuffer[hdrlength + 19];
            Console.Write("Number of pod pairs used: ");
            Console.Write(numberPodPairs);
            Console.Write(" [");
            switch (numberPodPairs)
            {
                case 4: // HP 1660C/CS/CP
                    Console.WriteLine("HP 1660C/CS/CP]");
                    break;
                case 3: // HP 1661C/CS/CP
                    Console.WriteLine("HP 1661C/CS/CP]");
                    break;
                case 2: // HP 1662C/CS/CP
                    Console.WriteLine("HP 1662C/CS/CP]");
                    break;
                case 1: // HP 1663C/CS/CP
                    Console.WriteLine("HP 1663C/CS/CP]");
                    break;
            }

            //ANALYZER1 data
            Console.WriteLine();
            Console.WriteLine("-- ANALYZER 1 --");
            Console.WriteLine();
            int a1DataMode = (int)inBuffer[hdrlength + 20];
            Console.Write("Machine1 data mode: ");
            switch (a1DataMode)
            {
                case 0xff:
                    Console.WriteLine("OFF");
                    break;
                case 0:
                    Console.WriteLine("state data without tags");
                    break;
                case 1:
                    Console.WriteLine("state data with all pod pairs assigned (2k memory) and either time or state tags");
                    break;
                case 2:
                    Console.WriteLine("state data with unassigned pod used to store tag data (4k memory)");
                    break;
                case 8:
                    Console.WriteLine("state data at half channel (8k memory with no tags)");
                    break;
                case 10:
                    Console.WriteLine("conventional timing data at full channel");
                    break;
                case 11:
                    Console.WriteLine("transitional timing data at full channel");
                    break;
                case 12:
                    Console.WriteLine("glitch timing data");
                    break;
                case 13:
                    Console.WriteLine("conventional timing data at half channel");
                    break;
                case 14:
                    Console.WriteLine("transitional timing data at half channel");
                    break;
            }

            int a1ListOfPods = 256 * (int)inBuffer[hdrlength + 22] + (int)inBuffer[hdrlength + 23];
            Console.Write("PODs used: ");
            for (i = 1; i < 9; i++)
            {
                if ((a1ListOfPods & (1 << i)) != 0) Console.Write("Pod" + i + ", ");
            }
            Console.WriteLine();

            int a1ChipWithStateData = (int)inBuffer[hdrlength + 24];
            if (a1DataMode == 2)
            {
                Console.WriteLine(" State data is in CHIP" + a1ChipWithStateData + ".");
            }

            int a1MasterChip = (int)inBuffer[hdrlength + 25];
            Console.Write("Master CHIP: ");
            switch (a1MasterChip)
            {
                case 0xff:
                    Console.WriteLine("OFF");
                    break;
                case 0:
                    Console.WriteLine("unused");
                    break;
                case 1:
                    Console.WriteLine("unused");
                    break;
                case 2:
                    Console.WriteLine("POD7 + POD8");
                    break;
                case 3:
                    Console.WriteLine("POD5 + POD6");
                    break;
                case 4:
                    Console.WriteLine("POD3 + POD4");
                    break;
                case 5:
                    Console.WriteLine("POD1 + POD2");
                    break;
            }


            b8[7] = (byte)inBuffer[hdrlength + 32];
            b8[6] = (byte)inBuffer[hdrlength + 33];
            b8[5] = (byte)inBuffer[hdrlength + 34];
            b8[4] = (byte)inBuffer[hdrlength + 35];
            b8[3] = (byte)inBuffer[hdrlength + 36];
            b8[2] = (byte)inBuffer[hdrlength + 37];
            b8[1] = (byte)inBuffer[hdrlength + 38];
            b8[0] = (byte)inBuffer[hdrlength + 39];
            long a1SamplePeriodInPicoSeconds = BitConverter.ToInt64(b8, 0);
            Console.WriteLine("Sample period = " + a1SamplePeriodInPicoSeconds + "ps");

            int a1TagType = (int)inBuffer[hdrlength + 48];
            switch (a1TagType)
            {
                case 0:
                    Console.WriteLine("Tag type: off");
                    break;
                case 1:
                    Console.WriteLine("Tag type: TIME");
                    break;
                case 2:
                    Console.WriteLine("Tag type: STATE");
                    break;
            }

            b8[7] = (byte)inBuffer[hdrlength + 50];
            b8[6] = (byte)inBuffer[hdrlength + 51];
            b8[5] = (byte)inBuffer[hdrlength + 52];
            b8[4] = (byte)inBuffer[hdrlength + 53];
            b8[3] = (byte)inBuffer[hdrlength + 54];
            b8[2] = (byte)inBuffer[hdrlength + 55];
            b8[1] = (byte)inBuffer[hdrlength + 56];
            b8[0] = (byte)inBuffer[hdrlength + 57];
            long a1TriggerOffsetInPicoSeconds = BitConverter.ToInt64(b8, 0);

            Console.WriteLine("Trigger offset = " + a1TriggerOffsetInPicoSeconds + "ps");


            //ANALYZER2 DATA
            Console.WriteLine();
            Console.WriteLine("-- ANALYZER 2 --");
            Console.WriteLine();
            hdrlength += 40;
            int a2DataMode = (int)inBuffer[hdrlength + 20];
            Console.Write("Machine2 data mode: ");
            switch (a2DataMode)
            {
                case 0xff:
                    Console.WriteLine("OFF");
                    break;
                case 0:
                    Console.WriteLine("state data without tags");
                    break;
                case 1:
                    Console.WriteLine("state data with all pod pairs assigned (2k memory) and either time or state tags");
                    break;
                case 2:
                    Console.WriteLine("state data with unassigned pod used to store tag data (4k memory)");
                    break;
                case 8:
                    Console.WriteLine("state data at half channel (8k memory with no tags)");
                    break;
                case 10:
                    Console.WriteLine("conventional timing data at full channel");
                    break;
                case 11:
                    Console.WriteLine("transitional timing data at full channel");
                    break;
                case 12:
                    Console.WriteLine("glitch timing data");
                    break;
                case 13:
                    Console.WriteLine("conventional timing data at half channel");
                    break;
                case 14:
                    Console.WriteLine("transitional timing data at half channel");
                    break;
            }

            int a2ListOfPods = 256 * (int)inBuffer[hdrlength + 22] + (int)inBuffer[hdrlength + 23];
            Console.Write("PODs used: ");
            for (i = 1; i < 9; i++)
            {
                if ((a2ListOfPods & (1 << i)) != 0) Console.Write("Pod" + i + ", ");
            }
            Console.WriteLine();

            int a2ChipWithStateData = (int)inBuffer[hdrlength + 24];
            if (a2DataMode == 2)
            {
                Console.WriteLine(" State data is in CHIP" + a1ChipWithStateData + ".");
            }

            int a2MasterChip = (int)inBuffer[hdrlength + 25];
            Console.Write("Master2 CHIP: ");
            switch (a2MasterChip)
            {
                case 0xff:
                    Console.WriteLine("OFF");
                    break;
                case 0:
                    Console.WriteLine("unused");
                    break;
                case 1:
                    Console.WriteLine("unused");
                    break;
                case 2:
                    Console.WriteLine("POD7 + POD8");
                    break;
                case 3:
                    Console.WriteLine("POD5 + POD6");
                    break;
                case 4:
                    Console.WriteLine("POD3 + POD4");
                    break;
                case 5:
                    Console.WriteLine("POD1 + POD2");
                    break;
            }

            b8[7] = (byte)inBuffer[hdrlength + 32];
            b8[6] = (byte)inBuffer[hdrlength + 33];
            b8[5] = (byte)inBuffer[hdrlength + 34];
            b8[4] = (byte)inBuffer[hdrlength + 35];
            b8[3] = (byte)inBuffer[hdrlength + 36];
            b8[2] = (byte)inBuffer[hdrlength + 37];
            b8[1] = (byte)inBuffer[hdrlength + 38];
            b8[0] = (byte)inBuffer[hdrlength + 39];
            long a2SamplePeriodInPicoSeconds = BitConverter.ToInt64(b8, 0);

            Console.WriteLine("Sample2 period = " + a2SamplePeriodInPicoSeconds + "ps");

            int a2TagType = (int)inBuffer[hdrlength + 48];
            switch (a2TagType)
            {
                case 0:
                    Console.WriteLine("Tag2 type: off");
                    break;
                case 1:
                    Console.WriteLine("Tag2 type: TIME");
                    break;
                case 2:
                    Console.WriteLine("Tag2 type: STATE");
                    break;
            }


            b8[7] = (byte)inBuffer[hdrlength + 50];
            b8[6] = (byte)inBuffer[hdrlength + 51];
            b8[5] = (byte)inBuffer[hdrlength + 52];
            b8[4] = (byte)inBuffer[hdrlength + 53];
            b8[3] = (byte)inBuffer[hdrlength + 54];
            b8[2] = (byte)inBuffer[hdrlength + 55];
            b8[1] = (byte)inBuffer[hdrlength + 56];
            b8[0] = (byte)inBuffer[hdrlength + 57];
            long a2TriggerOffsetInPicoSeconds = BitConverter.ToInt64(b8, 0);

            Console.WriteLine("Trigger2 offset = " + a2TriggerOffsetInPicoSeconds + "ps");

            hdrlength -= 40;

            // -- METADATA --
            int maxRows = 0;
            int validRowsPod8 = (int)inBuffer[hdrlength + 110] * 256 + inBuffer[hdrlength + 111]; if (validRowsPod8 > maxRows) maxRows = validRowsPod8;
            int validRowsPod7 = (int)inBuffer[hdrlength + 112] * 256 + inBuffer[hdrlength + 113]; if (validRowsPod7 > maxRows) maxRows = validRowsPod7;
            int validRowsPod6 = (int)inBuffer[hdrlength + 114] * 256 + inBuffer[hdrlength + 115]; if (validRowsPod6 > maxRows) maxRows = validRowsPod6;
            int validRowsPod5 = (int)inBuffer[hdrlength + 116] * 256 + inBuffer[hdrlength + 117]; if (validRowsPod5 > maxRows) maxRows = validRowsPod5;
            int validRowsPod4 = (int)inBuffer[hdrlength + 118] * 256 + inBuffer[hdrlength + 119]; if (validRowsPod4 > maxRows) maxRows = validRowsPod4;
            int validRowsPod3 = (int)inBuffer[hdrlength + 120] * 256 + inBuffer[hdrlength + 121]; if (validRowsPod3 > maxRows) maxRows = validRowsPod3;
            int validRowsPod2 = (int)inBuffer[hdrlength + 122] * 256 + inBuffer[hdrlength + 123]; if (validRowsPod2 > maxRows) maxRows = validRowsPod2;
            int validRowsPod1 = (int)inBuffer[hdrlength + 124] * 256 + inBuffer[hdrlength + 125]; if (validRowsPod1 > maxRows) maxRows = validRowsPod1;

            // -- DATA --
            Console.WriteLine(" -- DATA -- ");
            int bytesPerRow = 0;
            switch (numberPodPairs)
            {
                case 4: // 18 byte rows
                    bytesPerRow = 18;
                    break;
                case 3: // 14 byte rows
                    bytesPerRow = 14;
                    break;
                case 2: // 10 byte rows
                    bytesPerRow = 10;
                    break;
                case 1: //  6 byte rows
                    bytesPerRow = 6;
                    break;
            }
            int numberOfRows = maxRows; //this is true if neither analyzer is in glitch mode
            if ((a2DataMode == 12) || (a1DataMode == 12)) //glitch mode
            {
                // In the glitch mode, row (x) is the larger of:
                //  1. The highest number of valid rows specified by the bytes in byte positions 101 through 126; or,
                //  2. 2048 + the highest number of valid rows for the pods assigned to the timing analyzer, when one or more glitches are detected.
            }
            Console.WriteLine("DATA matrix " + bytesPerRow + " x " + numberOfRows);

            k = hdrlength + 176;
            int[,] dataPod = new int[bytesPerRow, numberOfRows];

            for (i = 0; i < numberOfRows; i++)
                for (j = 0; j < bytesPerRow; j++)
                    dataPod[j, i] = (int)inBuffer[k++];

            // -- TIME TAG --
            long[,] timeTag = new long[numberPodPairs, numberOfRows];
            for (i = 0; i < numberPodPairs; i++)
                for (j = 0; j < numberOfRows; j++)
                {
                    b8[7] = (byte)inBuffer[k++];
                    b8[6] = (byte)inBuffer[k++];
                    b8[5] = (byte)inBuffer[k++];
                    b8[4] = (byte)inBuffer[k++];
                    b8[3] = (byte)inBuffer[k++];
                    b8[2] = (byte)inBuffer[k++];
                    b8[1] = (byte)inBuffer[k++];
                    b8[0] = (byte)inBuffer[k++];
                    timeTag[i, j] = BitConverter.ToInt64(b8, 0);
                }

            // -- GLITCH DATA --
            Console.WriteLine(" -- GLITCH DATA -- ");
            k = hdrlength + 37040;
            int[,] glitchPod = new int[bytesPerRow, numberOfRows];

            for (i = 0; i < numberOfRows; i++)
                for (j = 0; j < bytesPerRow; j++)
                    glitchPod[j, i] = (int)inBuffer[k++];

            Console.WriteLine();
            Console.WriteLine();

            for (j = 0; j < bytesPerRow; j++)
            {
                for (k = 0; k < 8; k++)
                {
                    for (i = 0; i < 100; i++)
                    {
                        if ((dataPod[j, i] & (1 << k)) != 0)
                        {
                            if ((glitchPod[j, i] & (1 << k)) != 0)
                            {
                                Console.Write("!");
                            }
                            else
                            {
                                Console.Write("1");
                            }
                        }
                        else
                        {
                            if ((glitchPod[j, i] & (1 << k)) != 0)
                            {
                                Console.Write("*");
                            }
                            else
                            {
                                Console.Write("0");
                            }
                        }
                    }
                    Console.WriteLine();
                }
                Console.WriteLine();
            }


            Console.WriteLine();
        }
    }
}
28
Client software / Re: pushing external data into client
[quote author="jawi"]You can start with https://github.com/jawi/ols/wiki/OLS-data-file-format, which is the basic file format used by the OLS client.
[/quote]

thanks will look at it asap

[quote author="jawi"]
Do you have a hint on how the data is received from your 1661C?[/quote]

not sure I understand the question :(
data comes trough HPIB bus. it is a special bus most devices have (logic analyzers, scopes, counters, generators, adc, dac, power supply ...anything that's remotely manageable) that you use to link all the devices and control from single place. originally you'd control all devices trough something called "hp calculator" but nowdays you use LabView and mix virtual equipment with real equipment and real life data :D

To talk to HPIB (or GPIB as it is also called) bus I use HPIB dongle (pretty expensive btw, they are around 200$ second hand, you can get some cheap knockoff's for 100$) and some IVI libraries for .net (that's why I use .net). Every device on the bus have "Address", and you send commands to it and receive answers
30
Client software / Re: pushing external data into client
[quote author="jawi"]Hmm, your data is a little more structured than I anticipated :) [/quote]

it's what I get via hpib/gpib from a device, I just parse it and fill my internal array's :D

So what I get at the end is
 - data (zeroes and ones)
 - glitches (zeroes and ones) that overlay data (still don't know what's classified as glitch nor how to setup machine to collect them but I get the data via hpib)
 - sampling time in picoseconds
 - offsets in picoseconds
 * timestamp for each row of data (one row of data is all bits for one timestamp, on top of 16bits per pod there's also a clock bit no idea how that is used neither :D ) in picoseconds
 * offset for each bit when the trigger happened (so for every row I get the trigger location, don't remember if in picoseconds or #row )
 * some other metadata (how many pods are used, where data is stored etc)

[quote author="jawi"]Also, 128-bits input: seriously?![/quote]

HP1660C/CP/CS is 128bit LA yes, but the one I have is HP1661 and it's only 6 pods so "only" 96 bits :) but since the way I talk to all of the HP166x devices is same

[quote author="jawi"]
I see two ways on solving this:
  • create (or extend the "generic device") a formal wire-protocol that suppliers of data should use to pass data to a socket/pipe/file which the client can read and display. We might even start simple and use the plain OLS file format for that: it might be enough to get started with without the immediate need for a "real" wire-protocol;
  • extend the generic device to allow it to execute a binary executable and parse its stdout.
[/quote]

For start, cause there's lot work I need to do to this client and I'm pressed with time, I think the best would be just for me to generate a binary file you can load so that no changes are made on the client itself (for now). So when this works then we can think about moving forward :D as I'd like to be able to initiate capture (at some point of time in future) from the client as well :) .. now I did not find a way to access HPIB/GPIB from java but if you maybe manage to find a lib that does that it's easy to copy/paste this C# code in to java and have everything inside the client :D ... if not we can always communicate with external exe trough pipes :D