Visualizing Serial Data with JXChart

JXChart is a PC-based UART data visualization tool designed to display serial communication data as real-time graphs. It facilitates the observation and logging of data streams by rendering them into curves.

To use JXChart, you need a PC with serial port functionality, or a USB-to-serial adapter. The software supports data exchange via standard RX (receive) and TX (transmit) operatinos.

Communicasion Protocols

JXChart supports data transmission through several defined protocols:

Protocol 1: Data with Checksum

This protocol structures data packets as follows: HEAD (2 bytes) + CMD (1 byte) + LENGTH (1 byte) + DATA (N bytes) + CS (1 byte)

  • HEAD: Fixed at 0x4A 0x58.
  • CMD: Specifies the data type. Examples include:
    • 0x01: Unsigned 1-byte integer
    • 0x02: Unsigned 2-byte integer
    • 0x03: Unsigned 4-byte integer
    • 0x04: Signed 1-byte integer
    • 0x05: Signed 2-byte integer
    • 0x06: Signed 4-byte integer
    • 0x07: Signed 2-byte integer (MSB indicates sign)
    • 0x08: Signed 3-byte integer (MSB indicates sign)
    • 0x09: Signed 5-byte integer (MSB indicates sign)
    • 0x0A: 3-byte floating-point
    • 0x0B: 4-byte floating-point
  • LENGTH: The total number of bytes in the DATA field.
  • DATA: Contains the channel identifier (1 byte) and the corresponding numerical value.
  • CS: The checksum, calculated by summing HEAD, CMD, LENGTH, and DATA byte-by-byte, taking the lower 8 bits of the sum, and then inverting the result.

For instance, to send the unsigned 2-byte integer value 10000 to channel 1 (CMD 0x02):

// Data packet structure: HEAD (2) + CMD (1) + LENGTH (1) + DATA (3: Channel + Value) + CS (1)
// Example: Sending 10000 (0x2710) to channel 1
unsigned char packet[] = {0x4A, 0x58, 0x02, 0x03, 0x01, 0x27, 0x10, 0x00};

// Calculate Checksum
unsigned char checksum = 0;
for (size_t i = 0; i < sizeof(packet) - 1; ++i) {
    checksum += packet[i];
}
packet[sizeof(packet) - 1] = ~checksum;

// Assuming 'serialPort' is an object for serial communication
// serialPort.write(packet, sizeof(packet));

An Arduino example for this:

void setup() {
    Serial.begin(9600);
}

void loop() {
    // Sending 10000 to channel 1 (2-byte unsigned integer)
    char send_buffer[8] = {0x4A, 0x58, 0x02, 0x03, 0x01, 0x27, 0x10, 0x00};
    char calculated_cs = 0;

    for (int i = 0; i < sizeof(send_buffer) - 1; i++) {
        calculated_cs += send_buffer[i];
    }
    send_buffer[sizeof(send_buffer) - 1] = ~calculated_cs;

    Serial.write(send_buffer, sizeof(send_buffer));
    delay(1000);
}

Protocol 2: ASCII Transmission

This method involves sending data as ASCII characters. For example, to send the value 12345 to channel CH1:

Format: {CH1,12345}

Numerical values must be converted to thier ASCII representations.

Arduino example:

void setup() {
    Serial.begin(9600);
}

void loop() {
    Serial.print("{CH1,"); // Start of packet and channel identifier
    int value = 12345;
    Serial.print(value);
    Serial.println("}"); // End of packet
    delay(1000);
}

Direct serial write example:

// Sending "{CH1,12345}" as ASCII
char ascii_packet[] = "{CH1,12345}";
// serialPort.write(ascii_packet, sizeof(ascii_packet) - 1);

Protocol 3: Fixed Header and Footer

For simpler data transmission without checksums or ASCII conversion, this protocol uses fixed header and footer markers.

Format: HEADER + CHANNEL_ID + VALUE + FOOTER

Example: Sending the integer 10000 to channel 11:

void setup() {
    Serial.begin(9600);
}

void loop() {
    // Sending 10000 to channel 11 (2-byte integer)
    // Header: {0xA1, 0xA1, 0xA1}, Channel: 11, Value: 10000 (0x2710), Footer: {0xB1, 0xB1, 0xB1}
    char packet[] = {0xA1, 0xA1, 0xA1, (char)11, (char)0x27, (char)0x10, 0xB1, 0xB1, 0xB1};
    Serial.write(packet, sizeof(packet));
    delay(1000);
}

Tags: serial communication Data Visualization JXChart UART Embedded Systems

Posted on Mon, 26 Oct 2026 16:52:25 +0000 by KingIsulgard