動作環境
Ubuntu 18.04 LTS
display module: gen4-uLCD-35DT
Workshop 4 IDE v4.5.0.17 (on Windows 10 Pro)
MCU: STM32F446 Nuclero-64
STM32CubeIDE v1.0.1 (on Ubuntu 18.04 LTS)
概要
- gen4-uLCD-35DTをserial slaveとして使用
- 4列7行の文字列を表示する
- タッチ検知をして(x,y)座標を2列目までに表示する
- タッチ検知の応答表現としてコントラスト変化によるブリンクとする
- テキストや図形の再描画処理をしなくていい
- 1. コンスラスト落とす
- 2. 100mec delay
- 3. コンストラスト戻す
準備
IDEによるプロジェクト作成は下記の手順に基づく。
通信速度はWorkshop 4 IDEにて115200bpsとした。
-
Changing baud rate on Gen4-uLCD-35DCT-CLB
- > by clicking on File, Options and Serial, you will see the baudrate at 9600...
実装
シリアルタスクは下記のように実装した。
ディレイのタイミングや変数名、構造については最適化しているわけではない。
main.c
/* USER CODE END Header_StartSerialTask */
void StartSerialTask(void const * argument)
{
/* USER CODE BEGIN StartSerialTask */
static int table[7][4] = {0};
/* Infinite loop */
disp_clear(&huart1);
disp_setToLandscape(&huart1);
int atouch;
int xtouch = 0;
int ytouch = 0;
disp_touchDetection(&huart1);
disp_touchSet(0, &huart1); // ENABLE
for(;;)
{
atouch = 0;
for(int loop=0; loop < 10; loop++) {
if (loop != 9) {
osDelay(10);
atouch = disp_touchGet_state(&huart1);
if (atouch > 0) {
xtouch = disp_touchGet_xpos(&huart1);
ytouch = disp_touchGet_ypos(&huart1);
// blink to show up touch detection
disp_setContrast(7, &huart1);
osDelay(100);
disp_setContrast(15, &huart1);
}
osDelay(100); // msec
continue;
}
disp_expandWidth(2, &huart1);
disp_expandHeight(2, &huart1);
char szbuf[30] = {0}; // TODO: 0c > define this in a different place
for(int ypos=0; ypos < 7; ypos++) {
sprintf(szbuf, "%05d %05d %05x %05x", xtouch, ytouch, table[ypos][2], table[ypos][3] );
disp_moveCursor(0, ypos * 2, &huart1);
disp_putStringl(&huart1, szbuf, strlen(szbuf));
}
osDelay(100); // msec
}
}
/* USER CODE END StartSerialTask */
}
disp_XXX()
disp_XXX()はgen4-uLCD-35DTのシリアル通信仕様に基づいて実装している。
一部を紹介する。
STM32_serial.c
void disp_touchDetection(UART_HandleTypeDef *huartPtr)
{
char txbuf[20] = {0};
char rxbuf[20] = {0};
int pos=0;
txbuf[pos++] = 0xFE; // cmd
txbuf[pos++] = 0x6A;
txbuf[pos++] = 0x00; // x1
txbuf[pos++] = 0x00;
txbuf[pos++] = 0x00; // y1
txbuf[pos++] = 0x00;
txbuf[pos++] = 0x00; // x2
txbuf[pos++] = 0x64;
txbuf[pos++] = 0x00; // y2
txbuf[pos++] = 0x64;
HAL_UART_Transmit(huartPtr, (uint8_t *)txbuf, pos, 1000);
HAL_UART_Receive(huartPtr, (uint8_t *)rxbuf, 1, 100);
}
void disp_touchSet(int mode, UART_HandleTypeDef *huartPtr)
{
char txbuf[20] = {0};
char rxbuf[20] = {0};
int pos=0;
txbuf[pos++] = 0xFE; // cmd
txbuf[pos++] = 0x69;
txbuf[pos++] = 0x00; // mode
txbuf[pos++] = mode;
HAL_UART_Transmit(huartPtr, (uint8_t *)txbuf, pos, 100);
HAL_UART_Receive(huartPtr, (uint8_t *)rxbuf, 1, 100);
}
int disp_touchGet_state(UART_HandleTypeDef *huartPtr)
{
char txbuf[20] = {0};
char rxbuf[20] = {0};
int pos=0;
txbuf[pos++] = 0xFE; // cmd
txbuf[pos++] = 0x68;
txbuf[pos++] = 0x00; // mode
txbuf[pos++] = 0x00;
HAL_UART_Transmit(huartPtr, (uint8_t *)txbuf, pos, 300);
HAL_UART_Receive(huartPtr, (uint8_t *)rxbuf, 3, 100);
return rxbuf[2] > 0; // touch (>0)
}
動作状況
x=31, y=172のタッチをした後の状況。
タッチ検知した後に暗くなり、100msec後に元の明るさに戻る。
その後、下記のように座標値が更新される。
備考
- 抵抗型タッチディスプレイ
- Calibrationが必要
- Calibrationをしていない
- 右側と下側の検知がされない