なごるふ

UnityとかArduinoとか気になったことを

ATTiny85の周波数を校正する

前回の記事はATTiny85とAE-TYBLE16を使ってシリアル通信を試してみました。

通信はできたものの、時々データが破損して文字化けする問題がありました。

調べて見たところ周波数の校正をすることで改善できるようなので、試してみたいと思います。

環境と回路は前回の記事のままなので省略します。

校正値確認

ATTiny85は内蔵されるRC発振器によって8MHzとかの周波数を発生させているようです。

このRC発振器というのは温度によって、ATTiny85では10%まで誤差が生じるとのことで、OSCCALという校正用レジスタを調整することである程度調整が可能になるみたいです。

出荷時に予め校正値が設定されているようなので、以下のテストコードをATTiny85に書き込み、AE-TYBLE16経由で太陽誘電のアプリに出力し確認してみます。

#include <SoftwareSerial.h>
SoftwareSerial bleSerial(3, 4); // RX, TX

void setup()
{
  bleSerial.begin(9600);
}

String str = "";

void loop()
{ 
  while(bleSerial.available())
  {
      char inChar = bleSerial.read();
      if (inChar == '\n' || inChar == '\r')
      {
        if(0 < str.length())
        {
          bleSerial.print("OSCCAL:");
          bleSerial.println(OSCCAL);
          
          bleSerial.println(str);
          str = "";
        }
        break;
      }

      str += inChar;
  }
}

手元のATTiny85では159という数値が設定されていました。

校正値調整

本当は周波数を確認しながら調整したいのですが、手元で確認する術がなかったため、OSCCALの値を増減しながら文字化けが発生しないちょうど良い値を見つけることにします。

動的に精度を確認したいので、特定の文字列を送ると数値が増減するようにコードを書き換えて試してみました。

#include <SoftwareSerial.h>
SoftwareSerial bleSerial(3, 4); // RX, TX

void setup()
{
  bleSerial.begin(9600);
}

String str = "";

void loop()
{ 
  while(bleSerial.available())
  {
      char inChar = bleSerial.read();
      if (inChar == '\n' || inChar == '\r')
      {
        if(0 < str.length())
        {
          int num = atoi(str.c_str());
          if(num == 11)
          {
            OSCCAL--;
          }
          else if(num == 22)
          {
            OSCCAL++;
          }
          
          bleSerial.print("OSCCAL:");
          bleSerial.println(OSCCAL);
          
          bleSerial.println(str);
          str = "";
        }
        break;
      }

      str += inChar;
  }
}

変更した校正値で何度も送受信を試したところ、手元のATTiny85では155くらいがちょうど良さそうでした。

校正

OSCCALは起動毎に初期値にリセットされるみたいなので、setupの中で校正値を指定してあげます。

#include <SoftwareSerial.h>
SoftwareSerial bleSerial(3, 4); // RX, TX

void setup()
{
  bleSerial.begin(9600);

  // 周波数調整(個体差あるので要調整)
  OSCCAL = 155; // Default 159
}

void loop()
{ 
}

これで送信したデータは破損することなく受信できているようです。

さいごに

AE-TYBLE16が返すコマンドは時々おかしい時がありますが、今回は使わないので無視することにします。

次はモータードライバを使ってATTiny85でのDCモーター制御をためしてみようと思います。