今回はSTM32での静電容量センサについて紹介します。
環境はこれまで同様、
・STM32F303K8
+SW4STM32(System Workbench for STM32)
+STM32CubeMX(HAL ライブラリ、F3 ver. 1.60)
です。
静電容量センサとは、接点等を使用せずに静電容量を監視することで、
人などの指が触れたかどうかを判断するセンサです。
エレベータのボタンや機器のボタンなどに使用されています。
電極を露出しなくとも、筺体に触れるだけでタッチ操作、
複数電極の組み合わせで旧iPodのようなスクロール操作等が可能になります。
STM32では標準で静電容量センサ機能(TSC:Touch Sensing Controller)が
搭載されているため、使用方法の概要を紹介します。
CubeMX上で「TSC」の項目から設定します。
TSCはセンサグループが分かれており、
グループ毎に設定や読み取り等を行います。
グループ毎に必ずサンプリングキャパシタを接続する必要があります。
サンプリングキャパシタのIOには基準となるコンデンサを接続します。
サンプリングキャパシタの容量を変更することで、
タッチセンサの感度が変わります。
そのため、グループの中で1つはサンプリングキャパシタに接続するため、
グループ内のすべてのIOをタッチセンサで使用できない仕様です。
今回はG1_IO_1にサンプリングキャパシタとして0.1uFの積セラを接続し、
GNDへ落としました。
STM32L152 Discovery、STM32F072 Discoveryのタッチセンサでは
47nFをサンプリングキャパシタとして使用していました。
パラメータ詳細設定ではMax Count Valueが小さいと
上手く値が取得できないため、要注意です。
上記では16383に設定しました。
コードとしては
初期化で
MX_TSC_Init();
while(1)内では
htsc.Init.ChannelIOs = TSC_GROUP1_IO2;//ADD for multi ch read
HAL_TSC_Init(&htsc); //ADD for multi ch read
HAL_TSC_IODischarge(&htsc, ENABLE);
HAL_Delay(1);
if (HAL_TSC_Start(&htsc) != HAL_OK)Error_Handler();
while (HAL_TSC_GetState(&htsc) == HAL_TSC_STATE_BUSY)
{
}
__HAL_TSC_CLEAR_FLAG(&htsc, (TSC_FLAG_EOA | TSC_FLAG_MCE));
if (HAL_TSC_GroupGetStatus(&htsc, TSC_GROUP1_IDX) == TSC_GROUP_COMPLETED){
Value1 = HAL_TSC_GroupGetValue(&htsc, TSC_GROUP1_IDX);
}
htsc.Init.ChannelIOs = TSC_GROUP1_IO4; //ADD for multi ch read
HAL_TSC_Init(&htsc); //ADD for multi ch read
HAL_TSC_IODischarge(&htsc, ENABLE);
HAL_Delay(1);
if (HAL_TSC_Start(&htsc) != HAL_OK)Error_Handler();
while (HAL_TSC_GetState(&htsc) == HAL_TSC_STATE_BUSY)
{
}
__HAL_TSC_CLEAR_FLAG(&htsc, (TSC_FLAG_EOA | TSC_FLAG_MCE));
if (HAL_TSC_GroupGetStatus(&htsc, TSC_GROUP1_IDX) == TSC_GROUP_COMPLETED){
Value2 = HAL_TSC_GroupGetValue(&htsc, TSC_GROUP1_IDX);
}
printf("Value: %d, %d \n\r",Value1,Value2);
HAL_TSC_IODischarge(&htsc, ENABLE);
HAL_Delay(1);
if (HAL_TSC_Start(&htsc) != HAL_OK)Error_Handler();
while (HAL_TSC_GetState(&htsc) == HAL_TSC_STATE_BUSY)
{
}
__HAL_TSC_CLEAR_FLAG(&htsc, (TSC_FLAG_EOA | TSC_FLAG_MCE));
if (HAL_TSC_GroupGetStatus(&htsc, TSC_GROUP1_IDX) == TSC_GROUP_COMPLETED){
Value1 = HAL_TSC_GroupGetValue(&htsc, TSC_GROUP1_IDX);
}
htsc.Init.ChannelIOs = TSC_GROUP1_IO4; //ADD for multi ch read
HAL_TSC_Init(&htsc); //ADD for multi ch read
HAL_TSC_IODischarge(&htsc, ENABLE);
HAL_Delay(1);
if (HAL_TSC_Start(&htsc) != HAL_OK)Error_Handler();
while (HAL_TSC_GetState(&htsc) == HAL_TSC_STATE_BUSY)
{
}
__HAL_TSC_CLEAR_FLAG(&htsc, (TSC_FLAG_EOA | TSC_FLAG_MCE));
if (HAL_TSC_GroupGetStatus(&htsc, TSC_GROUP1_IDX) == TSC_GROUP_COMPLETED){
Value2 = HAL_TSC_GroupGetValue(&htsc, TSC_GROUP1_IDX);
}
printf("Value: %d, %d \n\r",Value1,Value2);
本来、複数のタッチセンサを読み出す場合はDMA等を使用するのが正しい方法ですが、
今回は実験のため、IO設定とHAL_TSC_Initを行うことで
強制的に複数chを読み出しました。
電極部に指を近づけると値が小さくなりました。
電極部のサイズ、配線の引きまわし、
基準となるサンプリングキャパシタ(Cs)などの要素を調整しないと
誤検知なく、反応のよいタッチセンサは難しいと思います。
また、次回、タッチセンサ設計ガイドラインの
データシート[PDF]を参考にしながら、
ここらへんを実験してみたいと思います。