2017年02月20日

デジタルシグマ型ADC読込

今回はデルタシグマ型ADC(SDADC)について紹介させて頂きます。

デルタシグマ型ADC(SDADC)は、
一般的な内臓の逐次比較型に比べ、
変換速度は遅いものの、ノイズが少なく、高分解能にAD変換できる特徴があります。

・デルタシグマ型ADC(SDADC)
16bit
16.6 ksps @マルチチャンネル変換
50 ksps @1チャンネル変換
差動信号入力可

・逐次比較型ADC
12bit
最大1Msps
シングル信号のみ


今回はSTM32F373に内臓のSDADCを使用してみました。
HALライブラリで公開されているサンプルは1chのみですが、
2ch読み込みを実験してみました。




環境はSDADC内臓の373シリーズ
・STM32F373CC
 +SW4STM32(System Workbench for STM32)
 +STM32CubeMX(HAL ライブラリ、F3 ver. 1.60)
です。


◆CubeMXの設定としては、
PB1→SDADC1_AIN5P
PB2→SDADC1_AIN4P


CubeMXで自動生成される初期化関数は下記の通りです。
static void MX_SDADC1_Init(void)
{

  SDADC_ConfParamTypeDef ConfParamStruct;

  hsdadc1.Instance = SDADC1;
  hsdadc1.Init.IdleLowPowerMode = SDADC_LOWPOWER_NONE;
  hsdadc1.Init.FastConversionMode = SDADC_FAST_CONV_DISABLE;
  hsdadc1.Init.SlowClockMode = SDADC_SLOW_CLOCK_DISABLE;
  hsdadc1.Init.ReferenceVoltage = SDADC_VREF_VDDA;
  if (HAL_SDADC_Init(&hsdadc1) != HAL_OK)
  {
    Error_Handler();
  }


  ConfParamStruct.InputMode = SDADC_INPUT_MODE_SE_ZERO_REFERENCE;
  ConfParamStruct.Gain = SDADC_GAIN_1;
  ConfParamStruct.CommonMode = SDADC_COMMON_MODE_VSSA;
  ConfParamStruct.Offset = 0;
  if (HAL_SDADC_PrepareChannelConfig(&hsdadc1,
                      SDADC_CONF_INDEX_0,
                      &ConfParamStruct) != HAL_OK)
  {
    Error_Handler();
  }

  if (HAL_SDADC_PrepareChannelConfig(&hsdadc1,
                     SDADC_CONF_INDEX_1,
                     &ConfParamStruct) != HAL_OK)
  {
    Error_Handler();
  }

}


◆割り込み関数
追加する割り込み処理として下記の関数を追加します。
void HAL_SDADC_InjectedConvCpltCallback(SDADC_HandleTypeDef *hsdadc)
{
     int16_t tmp=HAL_SDADC_InjectedGetValue(hsdadc,
                      (uint32_t *) &Channel);
    if(Channel==5)InjectedConvData=tmp;       //PB1
    else if(Channel==4)InjectedConvData2=tmp;  //PB2
}



◆define例として

#define SDADC_RESOL           (uint32_t) 65535
#define SDADC_INIT_TIMEOUT    30
#define SDADC_CAL_TIMEOUT     4*30720
#define SDADC_VREF2            (float) 3.300
#define SDADC_GAIN            (uint32_t) 1 

◆グローバル変数

 float inputVoltage = 0;
 int16_t ConvData = 0;
 uint32_t Channel = 0;

 float inputVoltage2 = 0;
 int16_t ConvData2 = 0;
 uint32_t Channel2 = 1;

mainコード内の例として、

MX_SDADC1_Init();
初期化実行後、詳細設定とキャリブレーション、割り込み開始を実行します。

if (HAL_SDADC_AssociateChannelConfig(&hsdadc1,
                SDADC_CHANNEL_4|SDADC_CHANNEL_5,
                SDADC_CONF_INDEX_0) != HAL_OK)
       {
                  printf("ERROR:  HAL_SDADC_AssociateChannelConfig");
       }

   
       if (HAL_SDADC_InjectedConfigChannel(&hsdadc1,
               SDADC_CHANNEL_4|SDADC_CHANNEL_5,
               SDADC_CONTINUOUS_CONV_ON) != HAL_OK)
       {
                printf("ERROR:  HAL_SDADC_InjectedConfigChannel");
       }


      if (HAL_SDADC_SelectInjectedTrigger(&hsdadc1,
              SDADC_SOFTWARE_TRIGGER) != HAL_OK)
    {
              printf("ERROR:  HAL_SDADC_SelectInjectedTrigger");
    }

  
    if (HAL_SDADC_CalibrationStart(&hsdadc1,
              SDADC_CALIBRATION_SEQ_2) != HAL_OK)
    {
              printf("ERROR:  HAL_SDADC_CalibrationStart");
    }

  
    if (HAL_SDADC_PollForCalibEvent(&hsdadc1,
              HAL_MAX_DELAY) != HAL_OK)
    {
           printf("ERROR:  HAL_SDADC_PollForCalibEvent");
    }

 
    if (HAL_SDADC_InjectedStart_IT(&hsdadc1) != HAL_OK)
    {
         printf("ERROR:  HAL_SDADC_InjectedStart_IT");
    }


while関数内では
 inputVoltage = (((ConvData + 32768) * SDADC_VREF2)
              / (SDADC_GAIN * SDADC_RESOL));
 inputVoltage2 = (((ConvData2 + 32768) * SDADC_VREF2)
              / (SDADC_GAIN * SDADC_RESOL));

 printf("SDADC PB1:%d %1.3f, PB2:%d %1.3f\n\r",
                                 ConvData,
                                 inputVoltage,
                                 ConvData2,
                                 inputVoltage2);
 HAL_Delay(300);



可変抵抗をつけて実際に読み込んでみました。

SDADC.png


確かに値は安定して変化しているようです。

今回は差動入力でなく、シングル入力ですが、
値としては差動として読み込まれるようで、
0V入力で-32768、3.3入力で32768となりました。

温度計など大きく値がぶれない処理によいと思います。

タグ:STM32 HAL 部品
posted by Crescent at 13:16| Comment(0) | TrackBack(0) | ナレッジ | このブログの読者になる | 更新情報をチェックする

2017年02月15日

Grove RTCモジュール

今回はI2C接続のGrove RTCモジュールについてご紹介します。


電池ボックス付きで使いやすく、
Groveコネクタを介して簡単に接続ができます。

CR1225というリチウム電池の入手性が非常に悪いですが、
CR1220と若干の容量差があるものの、厚みの差だけのため、使用可能です。

CR1220は100均等でも買えるため、CR1220を使用しました。
CR1220の方が.数mm厚さが薄いため、容量が少ないようです。



今回は普通にI2C接続でSTM32F303K8と接続しました。
STM32の32ピンパッケージはVBAT端子が付いていないため、
RTC機能はありますが電源OFF時の時刻保持等ができません。

ということで外付けでRTCを使用することにしました。




普通に接続して、時刻を設定、読込しようとしましたが、
最初、思ったように動作しませんでした。


GroveRTCモジュールはDS1307という
MAXIMのRTCチップ(PDF)を使用しています。

良く良くデータシートを見ると、
電源電圧が4.5V~となっており、
Seed秋月のサイトの仕様と違います・・・
上記サイトでは3.3V~使用できるとありますが・・・


VCCを3.3Vに接続して電池をセットしてI2Cで設定、読込しようとすると
DS1307からまったく応答がありません。

なぜか電池を外すとDS1307と通信できて、設定、読込ができます。
電池を外して動作してもRTCとしては使い物になりません。


データシート通りにVCCに5Vを供給して電池をセットすると
DS1307と通信できて、設定、読込ができました。


やはり、GroveRTCモジュールはVCC=3.3VではRTCとして使えないようです。
プルアップ抵抗等をいじったりしてみましたが、駄目でした・・・



ということでVCCへ5Vを給電して、
STM32F303K8と接続しました。

なお、STM32F303K8のI2Cはプルアップ無効で
FTfピンのため、5V耐圧として直接接続して使用可能です。



コード例

#define DS1307ADDR    0xD0
#define Ds1307SecondRegAddress   0x00
#define Ds1307DateRegAddress     0x04
#define Ds1307ControlRegAddress  0x07

typedef struct
{
  uint8_t sec;
  uint8_t min;
  uint8_t hour;
  uint8_t weekDay;
  uint8_t date;
  uint8_t month;
  uint8_t year;
}rtc_t;

void RTC_Init(void)
{

    HAL_I2C_Mem_Write(    &hi2c1,
                        DS1307ADDR,
                        Ds1307ControlRegAddress,
                        I2C_MEMADD_SIZE_8BIT,
                        0x00, 1, 1000);
}


void RTC_SetDateTime(rtc_t *rtc)
{
    uint8_t data[7];
    data[0]=rtc->sec;
    data[1]=rtc->min;
    data[2]=rtc->hour;
    data[3]=rtc->weekDay;
    data[4]=rtc->date;
    data[5]=rtc->month;
    data[6]=rtc->year;

    HAL_I2C_Mem_Write(    &hi2c1,
                        DS1307ADDR,
                        Ds1307SecondRegAddress,
                        I2C_MEMADD_SIZE_8BIT,
                        data, 7, 1000);

}

void RTC_GetDateTime(rtc_t *rtc)
{

    uint8_t data[7];
    HAL_I2C_Mem_Read(    &hi2c1,
                        DS1307ADDR,
                        Ds1307SecondRegAddress,
                        I2C_MEMADD_SIZE_8BIT,
                        (uint8_t*)&data, 7, 1000);
    rtc->sec=data[0];
    rtc->min=data[1];
    rtc->hour=data[2];
    rtc->weekDay=data[3];
    rtc->date=data[4];
    rtc->month=data[5];
    rtc->year=data[6];

}


main関数内

 RTC_Init();

  /* USER CODE END 2 */
  rtc.hour = 0x13; //  13:12:00
  rtc.min =  0x12;
  rtc.sec =  0x00;

  rtc.date = 0x12; //17/2/12
  rtc.month = 0x02;
  rtc.year = 0x17;
  rtc.weekDay = 5;
  RTC_SetDateTime(&rtc)


 while (1)
  {
 
      RTC_GetDateTime(&rtc);
      printf("Y/M/D H:M:S    -> %2x/%2x/%2x    %2x:%2x:%2x    \n\r",
              (uint16_t)rtc.year,(uint16_t)rtc.month,(uint16_t)rtc.date,
              (uint16_t)rtc.hour,(uint16_t)rtc.min,(uint16_t)rtc.sec);
      HAL_Delay(300);

  }


RTC1307.png


時刻を一度、セットしてから、
RTC_SetDateTime(&rtc)をコメントアウトしたプログラムを書き込んで、
上記のように電池で保持されることを確認できました。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 部品 | このブログの読者になる | 更新情報をチェックする

2017年02月10日

部品販売開始

今回はSWITCH SCIENCEの委託販売による
部品販売開始についてお知らせします。


GitHubで公開している変換基板の販売を
SWITCH SCIENCEで開始しました。


Crescentのデバイス開発時に合わせて設計した変換基板です。
17/2/10から販売開始する基板は下記の2点です。


IMG_4286-2.jpg

ProjectionBallなどで使用しているエンコーダ基板です。

ProjectionBallでは世代によってAS5048A、AS5047Dと異なりますが、

今回、販売の基板はエラー角が小さいAS5048Aを採用しました。


AMS社製磁気エンコーダAS5048Aを

2.54 mmピッチへ変換する基板です。

専用のネオジム磁石を同梱(φ8mm x h2)。

3.3 V電源及びSPIインタフェースのピンが出ています。

他のピンは基板上のパット及びチップ抵抗のパターンからアクセス可能です。

光学式に比べ、磁気式はホコリやゴミ等への耐性が強く、調整が容易です。

また、SPIインタフェースのため、

Arduino等と接続してロボット等への組込が簡単に行えます。





IMG_4278-3.jpg

Nucleo等の評価ボードが発売されていない

48ピンIC STM32F373 LQFP48を2.54 mmピッチへ変換した基板です。

5列両側の一般的なブレッドボードで両側に1つ空きが出るサイズです。

32ピンではRAMサイズやピン数が足りないが、

64ピンでは多すぎるという方にお勧めです。
※mbedには対応していません。



他にも設計中の基板含めて随時、販売製品を追加する予定です。



よろしくお願いいたします。



posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 部品 | このブログの読者になる | 更新情報をチェックする

2017年02月06日

静電容量センサ

今回はSTM32での静電容量センサについて紹介します。


環境はこれまで同様、
・STM32F303K8
 +SW4STM32(System Workbench for STM32)
 +STM32CubeMX(HAL ライブラリ、F3 ver. 1.60)
です。


静電容量センサとは、接点等を使用せずに静電容量を監視することで、
人などの指が触れたかどうかを判断するセンサです。

エレベータのボタンや機器のボタンなどに使用されています。
電極を露出しなくとも、筺体に触れるだけでタッチ操作、
複数電極の組み合わせで旧iPodのようなスクロール操作等が可能になります。


STM32では標準で静電容量センサ機能(TSC:Touch Sensing Controller)が
搭載されているため、使用方法の概要を紹介します。


CubeMX上で「TSC」の項目から設定します。

TSCはセンサグループが分かれており、
グループ毎に設定や読み取り等を行います。


tsc-setting.png


グループ毎に必ずサンプリングキャパシタを接続する必要があります。
サンプリングキャパシタのIOには基準となるコンデンサを接続します。
サンプリングキャパシタの容量を変更することで、
タッチセンサの感度が変わります。
そのため、グループの中で1つはサンプリングキャパシタに接続するため、
グループ内のすべてのIOをタッチセンサで使用できない仕様です。


今回はG1_IO_1にサンプリングキャパシタとして0.1uFの積セラを接続し、
GNDへ落としました。

STM32L152 DiscoverySTM32F072 Discoveryのタッチセンサでは
47nFをサンプリングキャパシタとして使用していました。


tsc-cubemx.png

パラメータ詳細設定では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);


本来、複数のタッチセンサを読み出す場合はDMA等を使用するのが正しい方法ですが、
今回は実験のため、IO設定とHAL_TSC_Initを行うことで
強制的に複数chを読み出しました。




tsc-setting2.png



電極部に指を近づけると値が小さくなりました。


電極部のサイズ、配線の引きまわし、
基準となるサンプリングキャパシタ(Cs)などの要素を調整しないと
誤検知なく、反応のよいタッチセンサは難しいと思います。



また、次回、タッチセンサ設計ガイドラインの
データシート[PDF]を参考にしながら、
ここらへんを実験してみたいと思います。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 電子工作 | このブログの読者になる | 更新情報をチェックする

2017年02月01日

2月参加イベント紹介

2月参加予定のイベントについて紹介させていただきます。


◆プレミアムインセンティブショー(ギフトショー)

2月8日(水)、9日(木)、10日(金)
@東京ビックサイト 西3・4ホールで開催の
特別企画ロボットワールドExpoが開催されます。

特別企画ロボットワールドExpoの展示ブースで
ProjectionBallを使用した展示を行います。

協力会社の展示のため、
Crescentによる説明等はありません。
また、展示されない場合もあります。




◆デブサミ2017

2月16日(木)、17日(金)
@目黒雅叙園で開催の
2日目 17日(金)のみ
技術系同人誌即売コーナー「DevBooks」が開催されます。

「親方Project」にて最新版の
ProjectionBallを使用した展示を行う予定です。




よろしくお願いいたします。

posted by Crescent at 00:00| Comment(0) | TrackBack(0) | お知らせ | このブログの読者になる | 更新情報をチェックする