Series: Tried Using Touch Panel TFT Display GT-SP with Arduino
Analog Meter Background Image Settings and Display Switching

Table of Contents
DownloadDownload sample project & program (for GT Design Studio & Arduino)
Hello everyone, I’m @kissaten, a beginner in electronics. In this series, I’m explaining the process of connecting a 7-inch touch display (GT-SP series “GTWV070S3A00P”) to an Arduino and working on various projects.
In this article, we will expand on the previous customization of the analog meter by implementing a system that changes the background image when the meter value reaches a specific range.
Analog Meter Configuration
In this implementation, we will use background images for the analog meter panel to create a more polished design. Additionally, we will introduce measures to ensure that circular meter images appear correctly on displays with non-square pixel aspect ratios. Below are the specific settings used.
Needle Configuration
- Value Range: 0–160
- Needle Properties:
- Needle Type: Square<3>
- Needle Length: 80
- Needle Length2: -37
- Needle Width: 2
- Needle Center Size: 0
- Needle Color:
- Needle Color and Needle Center Color: White
Meter Panel Configuration
Two background images are registered in the Image Panel. These images are switched based on the Contents Selects (CNTS_SEL) property.
- Image0: When Contents Selects (CNTS_SEL) = 0 (Normal State)
- Image1: When Contents Selects (CNTS_SEL) = 1
In the program, the meter value is determined based on the potentiometer’s reading. If the value is 100 or below, Image0 (normal state) is displayed. If the value is 101 or above, Image1 (alert state) is displayed.
Aspect Ratio Adjustment for 7-Inch Displays
The GT-SP 7-inch TFT display does not have a square pixel aspect ratio. If a perfectly circular meter image is created on a PC and displayed on this screen, it will appear horizontally stretched. Follow these steps to adjust the aspect ratio for both the meter image and the needle.
You can determine if aspect ratio adjustment is required by checking the Pixel Pitch value in the display’s hardware specifications. If the Pixel Pitch ratio is 1:1, no adjustment is needed.
Adjusting the Meter Image Aspect Ratio
On the 7-inch display, the vertical-to-horizontal ratio is approximately 1:0.93 (precisely, 0.1926:0.1790). For example, if you create a 400 × 400 px circular meter image, follow these steps to adjust it:
- Open the image in an image editing tool.
- Resize the image to 400 px height × 371 px width.
- Save and register the adjusted image in GT Design Studio.
Before Adjustment (left) / After Adjustment (right)
Adjusting the Needle Aspect Ratio
The meter’s needle also requires aspect ratio correction. In GT Design Studio, adjust the following property:
- Property Name: Aspect X/Y
- Value: 93
Text Configuration
A text label is placed at the center of the analog meter.
Set Text0 Align X to “CENTER<1>” to align the text to the right.
Font: Use “Melete” as referenced in previous articles.
Set the font Properties to “Melete Medium”, Height to “28” and Size to “16”.
Overall Configuration
To match the meter design, we change the background color.
In the properties of PAGE_0, set Back Color to black (#000000).
Arduino Program
The following Arduino program controls the analog meter based on the potentiometer’s value. It changes the background image when the value reaches a specific threshold and displays the current value as text.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
#include <string.h> // ピン設定 | Pin assignments #define GT_DTR 4 // DTR #define GT_DSR 6 // DSR #define GT_TRDY 7 // TRDY <--未使用 | Disused void setup() { // ピンの設定 | Pin setting pinMode(GT_DTR, INPUT); pinMode(GT_DSR, OUTPUT); pinMode(GT_TRDY, INPUT); digitalWrite(GT_DSR, LOW); // シリアル通信の初期化 | Serial communication initialization Serial.begin(38400); // 38400bps Baud rate Serial.setTimeout(100); // Serial timeout // メーターの最小値と最大値を設定する | Set min and max values for meter setMeterRange(0, 160); } void loop() { // センサーから値を読み取る | Read value from sensor int sensorValue = analogRead(A0); // センサーの値を0~160の範囲にマッピングし、制限内に収める | Map the sensor value to the range 0-160 and constrain within limits int meterValue = constrain(map(sensorValue, 0, 1023, 160, 0), 0, 160); // メーターの値をGT-SPに送信 | Send meter value to GT-SP sendMeterValue(meterValue); // メーターの字背景画像を変 | Change background image of the meter updateMeterBackground(meterValue); // GT-SP上のテキストオブジェクト(オブジェクトNo.2)に値を表示 | Display the value in the text object (Object No.2) on GT-SP gtsp_ObjPrpSet_string(2, 0x40, String(meterValue)); delay(100); // Wait for 100 milliseconds } // GT-SPのメーターの最小値と最大値を設定 | Set min and max values for meter on GT-SP void setMeterRange(int minValue, int maxValue) { gtsp_ObjPrpSet_val(0, 0x1E, 4, minValue); // Set minimum value gtsp_ObjPrpSet_val(0, 0x1F, 4, maxValue); // Set maximum value } // GT-SPに値を送信 | Send value to GT-SP void sendMeterValue(int value) { gtsp_ObjPrpSet_val(0, 0x10, 4, value); } // メーターの字背景画像を変更 | Change background image of the meter void updateMeterBackground(int value) { if (value <= 100) { Serial.println("Switching to Image0 (CNTS_SEL = 0)"); gtsp_ObjPrpSet_val(0, 0x14, 1, 0); // CNTS_SEL = 0: Background Image0 } else { Serial.println("Switching to Image1 (CNTS_SEL = 1)"); gtsp_ObjPrpSet_val(0, 0x14, 1, 1); // CNTS_SEL = 1: Background Image1 } } /********************** GT-SP関数 | Function for GT-SP **********************/ //////////////////////////////////////////////////// // オブジェクト制御コマンド-プロパティ読み出し(数値用)| Read property value (for Value) //////////////////////////////////////////////////// unsigned long gtsp_ObjPrpRead_val(int obj, int prp, int ln) { unsigned long val; gt_print("CMD"); // コマンドヘッダ | Command header gt_put(0xd4); // オブジェクト-プロパティ設定コマンド | Object-Property Setting gt_put(obj >> 0); // オブジェクトNo. 下位バイト | Object No. Lower byte gt_put(obj >> 8); // オブジェクトNo. 上位バイト | Object No. Upper byte gt_put(prp >> 0); // プロパティNo. 下位バイト | Property No. Lower byte gt_put(prp >> 8); // プロパティNo. 上位バイト | Property No. Upper byte gt_put(ln >> 0); // データ長 最下位バイト | Data length Least significant byte gt_put(ln >> 8); // データ長 下位バイト | Data length second byte gt_put(ln >> 16); // データ長 上位バイト | Data length third byte gt_put(ln >> 24); // データ長 最上位バイト | Data length Most significant byte // プロパティデータ受信 | Property data received while (Serial.available() == 0) {} val = gtsp_signal_read_val(); return val; } //////////////////////////////////////////////////// // データ受信(文字列用)| Receive data from GT-SP (for String) //////////////////////////////////////////////////// String gtsp_signal_read() { byte res_dl[4] = ""; unsigned long dl; char res_data_char[255] = ""; if (Serial.find("RESb", 4)) { Serial.readBytes(res_dl, 4); // データ長抽出 | Data-length extraction dl = (unsigned long)(res_dl[0] + (res_dl[1] << 8) + (res_dl[2] << 16) + (res_dl[3] << 24)); // データ長変換 | Data length Serial.readBytes(res_data_char, dl); // データ抽出 | Read data Serial.print("Received data: "); for (unsigned int i = 0; i < dl; i++) { Serial.print(res_data_char[i], HEX); Serial.print(" "); } Serial.println(); return String(res_data_char); // String type conversion, return } return ""; } //////////////////////////////////////////////////// // 1byte送信 | Send byte to GT-SP //////////////////////////////////////////////////// void gt_put(unsigned char onebyte) { while (digitalRead(GT_DTR) == HIGH) {} // busycheck Serial.write(onebyte); } //////////////////////////////////////////////////// // 文字列送信 | Send String to GT-SP //////////////////////////////////////////////////// void gt_print(String val) { int val_i; // 文字列を1文字ずつ送信 | Send string per one byte for (val_i = 0; val_i < val.length(); val_i++) { while (digitalRead(GT_DTR) == HIGH) {} // busycheck Serial.print(val.substring(val_i, val_i + 1)); } } |
DownloadDownload sample project & program (for GT Design Studio & Arduino)
Understanding the Program
setMeterRange(0, 160)
This function defines the display range of the GT-SP analog meter. In this case, it is set from 0 to 160, ensuring the meter operates within this range in response to the potentiometer’s movement.
int meterValue = constrain(map(sensorValue, POT_MIN, POT_MAX, 160, 0), 0, 160)
This line maps the potentiometer’s analog reading (sensorValue) to the 0–160 range using the map() function. The direction of mapping is reversed to align the potentiometer’s rotation with the needle movement.
The constrain() function ensures that the value remains within the 0–160 range, preventing out-of-bounds display errors.
sendMeterValue(meterValue)
This function transmits the potentiometer’s value to the GT-SP analog meter. Internally, gtsp_ObjPrpSet_val() is used to send the value to property 0x10 of object No.0, enabling real-time meter updates.
updateMeterBackground(meterValue)
This function switches the background image based on the meter value.
- meterValue <= 100: Background image Image0 (Blue)
- meterValue > 100: Background image Image1 (Red)
It modifies GT-SP property CNTS_SEL (No. 0x14) to switch between the images.
gtsp_ObjPrpSet_string(2, 0x40, String(meterValue))
This function updates the GT-SP text object (No.2) with the current meter value as a string, providing a clear numerical display.
Conclusion
In this project, we learned how to use a potentiometer to control a GT-SP analog meter and dynamically switch its background image based on specific value thresholds. This approach enhances the meter’s visual clarity and usability.
In the next article, we will explore GT Design Studio’s graph tools for additional display enhancements.