2020年01月18日

シリアル受信割り込み

以前に紹介したUART I2Cプロトコルブリッジを用いてNode-Red連携をする際に少し戸惑った点があったので対処方法についてお伝えします。

USBシリアル変換IC PL2303SAを用いてNode-Redのserialノードでデータを受信する際にNode-Redの受信ノードが動作せず、シリアルデータを受信してもイベントが発生しない不具合がありました。

node-red.jpg

Teratermでは受信できるものの、Node-RedのSerialノードでは受信してもイベントが発生しませんでした。
他のFTDI製のUSBシリアル変換ICでは受信すると正常にイベントが発生しました。

原因を追ってみるとドライバが古いことが分かり、Windowsの標準ドライバからアップデート、再起動するとUSBシリアル変換IC PL2303SAでも正常に受信することができました。


Driver.jpg

正常に動作確認ができたところでUART I2Cプロトコルブリッジを用いてNode-Redから様々なI2Cデバイスを制御する例について今後、紹介したいと思います。
posted by Crescent at 00:00| Comment(0) | 電子工作 | このブログの読者になる | 更新情報をチェックする

2020年01月11日

Teraterm 16進数送信

前回紹介したUART I2CプロトコルブリッジをTeratermからマクロで制御する際に戸惑ったことがあったので紹介します。

Teratermには16進数で表示、送信する機能があります。ただ、この機能が少し厄介でうまく表示や送信できない制約があります。この制約を知らずになかなかUART I2Cプロトコルブリッジが意図して通りに動かなく試行錯誤してしまいました。


テスト0x00〜0xFFまでをUSBシリアルポートに送信し、ポートを結線してループバックで受信データを表示させます。送信する際のマクロは下記の通りです。

setdebug 2
mpause 500
send $00$01$02$03$04$05$06$07$08$09$0A$0B$0C$0D$0E$0F
send $10$11$12$13$14$15$16$17$18$19$1A$1B$1C$1D$1E$1F
send $20$21$22$23$24$25$26$27$28$29$2A$2B$2C$2D$2E$2F
send $30$31$32$33$34$35$36$37$38$39$3A$3B$3C$3D$3E$3F
send $40$41$42$43$44$45$46$47$48$49$4A$4B$4C$4D$4E$4F
send $50$51$52$53$54$55$56$57$58$59$5A$5B$5C$5D$5E$5F
send $60$61$62$63$64$65$66$67$68$69$6A$6B$6C$6D$6E$6F
send $70$71$72$73$74$75$76$77$78$79$7A$7B$7C$7D$7E$7F
send $80$81$82$83$84$85$86$87$88$89$8A$8B$8C$8D$8E$8F
send $90$91$92$93$94$95$96$97$98$99$9A$9B$9C$9D$9E$9F
send $A0$A1$A2$A3$A4$A5$A6$A7$A8$A9$AA$AB$AC$AD$AE$AF
send $B0$B1$B2$B3$B4$B5$B6$B7$B8$B9$BA$BB$BC$BD$BE$BF
send $C0$C1$C2$C3$C4$C5$C6$C7$C8$C9$CA$CB$CC$CD$CE$CF
send $D0$D1$D2$D3$D4$D5$D6$D7$D8$D9$DA$DB$DC$DD$DE$DF
send $E0$E1$E2$E3$E4$E5$E6$E7$E8$E9$EA$EB$EC$ED$EE$EF
send $F0$F1$F2$F3$F4$F5$F6$F7$F8$F9$FA$FB$FC$FD$FE$FF
mpause 100
setdebug 0
mpause 100


Teratermが日本語設定の場合は下記のように0x7F以降、意図しない送信データを含み、正しく表示もされません。

teraterm-1.jpg


Teratermが英語設定の場合は下記のように意図通りに動作しました。

teraterm-2.jpg

debug modeを有効かしている場合は言語を英語、デフォルトに設定することが必要です。

teraterm-3.jpg

0x7Fまでは正しく動作するため、制約に気づきづらく余計に試行錯誤してしまいました。
posted by Crescent at 00:00| Comment(0) | ナレッジ | このブログの読者になる | 更新情報をチェックする

2020年01月04日

UART I2Cプロトコルブリッジ

あけましておめでとうございます。
2020年も電子工作をはじめとした活動を発信していきたいと思います。

以前からシリアル変換ブリッジIC(I2C/SPII2C/Uart)を紹介しましたが、今回はUARTからI2Cを制御できるUART I2CプロトコルブリッジSC18IM700を紹介します。

SC18IM700を使用するとUARTからI2Cデバイスを制御することができます。SC18IM700がI2Cデバイスマスタとなって様々なI2Cデバイスを制御することができます。

UARTをUSBシリアル変換アダプタに接続すればパソコンのTeraterm等からI2Cデバイスを制御することが可能となります。

また、スピードは期待できないものの、SC18IM700は汎用GPIOの8つを利用することも可能です。


プロトコルブリッジSC18IM700とUSBシリアル変換IC PL2303SAを組み合わせてUSB-I2C変換アダプタを作成してみました。

I2CUSB_1.jpg

I2CUSB_2.jpg

I2CにGrove互換コネクタを搭載することで様々なGroveデバイスを制御することができます。特にTeratermはマクロ機能があるため、マクロ機能を活用することで簡易なドライバ作成ができます。ちょっとしたI2Cセンサのアドレス確認や動作確認、部品の出荷テスト等でパソコン単体でセンサを接続する際の治具として活躍できそうです。

試作基板の動作確認して問題なければteratermのサンプルプログラムをいくつか準備して販売したいと思います。
追記 2/7からスイッチサイエンスにて販売を開始しました。
posted by Crescent at 00:00| Comment(0) | 電子部品 | このブログの読者になる | 更新情報をチェックする

2019年12月28日

磁気エンコーダMLX90316

Melexis社製の14bit磁気エンコーダMLX90316を試食してみました。

先日紹介した3線式SPI通信を使用して磁石の角度情報を読み込んでみました。
結論から言うとMLX90316はダイヤルといったインターフェース向けのエンコーダでモータ制御にはあまり向いていないようです。

Arduinoのサンプルプログラムでは動作しますが、STM32マイコンのSPI通信で実装すると思うように位置情報が読み込めない不具合に遭遇しました。原因を追うとデータシートにその答えがありました。

MLX90316_1.jpg
 MLX90316データシートP.33から抜粋

データシートをよく見るとt1が最小2.3usということで最大クロックは300kHz程度です。さらにt2で1バイトごとに10us以上待機する必要があり、SPI通信で連続してバイトの読み書きができません。また、t5でCS=1状態で300us以上待機する必要があることが書かれています。数MHzのクロックで通信できるSPI通信のメリットがありません。

つまり、位置データ読み込みは数msに1回程度しか読み込めないということになります。MLX90316の仕様でSPI通信対応ということで細かい部分を見逃していました…

CubeMX上でClock Phaseを2Edgeに設定し、SPIのプリスケーラを256に設定してSPIのボーレートを31.25Kbit/sに設定すると正常に位置情報を読み込むことが確認できました。

MLX90316_2.jpg


 uint8_t sdata[4];
 uint8_t rdata[8];
 uint16_t dat[4];

 uint16_t res;
 uint8_t halres; 
 sdata[0]=0xAA;
 sdata[1]=0xFF;


 SPI_1LINE_TX(&hspi1);
 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET);
 halres=HAL_SPI_Transmit(&hspi1,sdata,2,0x1000);
 if(halres !=HAL_OK) printf("Transmit Err:%d \n\r",halres);
 SPI_1LINE_RX(&hspi1);
 halres=HAL_SPI_Receive(&hspi1,rdata,8,0x1000);
 if(halres !=HAL_OK) printf("Receive Err:%d \n\r",halres);
 HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);
 dat[0] = (rdata[0]<<8) + rdata[1];

 if((dat[0]&0x03)==2){
   // Err Data
  if ( dat[0] & (1 << 4)) {
   //printf("Magnetic Field is Too Strong!\n\r");
  }
  else if ( dat[0] & (1 << 5)){
   //printf("Magnetic Field is Too Weak!\n\r");
  }
 }
 else if((dat[0]&0x03)==1){
  res=(dat[0]>>2);//16bit Angle Data
  printf("RES: %d \n\r",res);
 }



MLX90316_SPI_Wide.jpg




磁気エンコーダをモータ制御として使用する場合、少なくとも1msに1回、理想は100usに1回読み込みたいのでMLX90316の仕様は満足しないことが分かりました。ダイヤルといったインターフェース向けのエンコーダとしては低コストかつシンプルなコマンドで通信できるため、非常によいと思いました。

14bi磁気エンコーダとして癖がなく、高速な処理に対応しているのはやはりAMS社のAS5048Aが個人的にベストな磁気エンコーダだと改めて思いました。
posted by Crescent at 00:00| Comment(0) | 電子部品 | このブログの読者になる | 更新情報をチェックする

2019年12月21日

STM32マイコン UART受信時必須処理

STM32マイコンでUARTの受信をする際に必須となるエラー処理について紹介します。

UARTの送信は一方的にマイコンから送るだけのため、そこまで大変ではありません。一方、受信は調歩同期方式ならではのエラー(フレーミング、バッファ オーバーラン エラー等)が発生するため、エラー処理を入れないとUARTの受信処理の安定性が悪化します。

更に厄介なのがSTM32マイコンのHALライブラリではUARTの受信割込みやDMA転送を使用した際に受信エラーが発生すると以降の受信処理が行われません。コマンドをUARTで処理する場合、受信エラー以降の受信が行われず、応答なし状態となっていまいます。

受信処理を継続して行うためにはエラー処理を加える必要があります。



実装としてはエラーが発生するとHAL_UART_ErrorCallbackが呼び出されます。
※設定によりますが、HAL_UART_ErrorCallbackが呼び出されないエラーがあったため、HAL_UART_ErrorCallback内でクリアせずにwhile内等でのクリア処理に変更しました。

UARTのエラーフラグを確認してクリアするHAL_UART_Abort関数を実行して受信処理を再開させます。
なお、HAL_UART_Abort関数は割込みを解除する関数ですが、各種エラーをクリアさせる機能も入っています。個々のエラーフラグだけをクリアするだけでは再開できないことが多々あるため、HAL_UART_Abort関数でレジスタをクリアさせる方法が確実です。



 if(huart->Instance==USART1){
  if (  __HAL_UART_GET_FLAG(&huart1, UART_FLAG_ORE) ||
    __HAL_UART_GET_FLAG(&huart1, UART_FLAG_NE) ||
    __HAL_UART_GET_FLAG(&huart1, UART_FLAG_FE) ||
    __HAL_UART_GET_FLAG(&huart1, UART_FLAG_PE) ){
     HAL_UART_Abort(&huart1);
     HAL_UART_Receive_DMA(&huart1, (uint8_t*)&UART_Data, 1);//DMAの場合
     //HAL_UART_Receive_IT(&huart1, (uint8_t*)&UART_Data, 1);//割込みの場合
  }
 }


上記処理をmain.cのwhile内等に配置することでエラー処理することができます。


以前に通常の処理ではうまく受信できるがタイミングによって受信できなくなるといった不具合に悩まされました。原因がフレーミングエラーと分かりました。電源投入直後のノイズ等でエラーが発生してしまったようです。上記の処理を加えることでエラー時に処理を再開させ、安定して通信を継続できるようになりました。

※一部HALライブラリ依存があったため、修正しました
posted by Crescent at 00:00| Comment(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする