2017年02月26日

Maker Faire Bay Area 2017 参加決定

今回は5月開催のイベントについてご紹介させていただきます。

17年5月19日~21日にアメリカベイエリアで開催の
に参加することが決定しました。

Bay AreaはMaker Faire発祥の地です。


2月上旬に申し込みを行ってから、
2月22日早朝にアクセプトメールが届きました。
知り合いでも22日前後数日でメールが順次送信されているようです。

mfb.PNG


Maker Faire Bay Area 2017では
ProjectonBallの他、現在開発中のデバイスも展示する予定です。
Crescentのデバイスが初めて海外での展示になります。

トラブルなく展示できるか非常に心配ですが・・・


特に以前に日本で開催されたTech in Asia Tokyoという
海外の方の来場者が多いイベントでは非常に受けが良かったので、
Maker Faire Bay Area 2017も楽しみです。



新しい市場やコミュニティーなど開拓できればと考えています。


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

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) | 電子工作 | このブログの読者になる | 更新情報をチェックする