goo blog サービス終了のお知らせ 

齢寿天任せ

写真付きで日記や趣味を書くならgooブログ

週間スケジュールが可能なRDA5807 FM DSPラジオに丸形LCDを取り付けてみた

2023-12-28 12:14:23 | 電子工作

試作を行い、丸形カラーLCDを調査していたが、だいぶ使い方が分かってきたので、以前製作した「週間スケジュールが可能なRDA5807 FM DSPラジオ」の表示装置を、丸形カラーLCDに取り換えたものを新たに製作した。時計とFMラジオの表示を合体して、表示画面は結局以下のようになった。ケースは手元にあった筒形の物を利用した。作成したスケッチはGithubに登録してある。

コントローラ(MCU:Seed Studio XIAO ESP32C3)からの制御インターフェースは、I2CとSPIを利用するので、ESP32C3の入出力ピン数ではギリギリで、操作のボタンスイッチを設ける余裕はない。したがって、操作は全てWiFi経由で行う。

この丸形LCDは、240x240ピクセルなので、表示位置は、x:ヨコ位置、y:タテ位置とすると、左上隅は(0,0)、中心は(120,120)、右下隅は(239,239)となる。なお、実際に表示できる円からはみ出た部分は表示されない。丸形LCDにおいては、円の外周に沿って表示を行う必要があるが、その表示位置を求めるためには三角関数を利用する必要がある。

例えば、半径rの円の外周位置(x,y)を求めるには、以下の図に示した計算を行えばよいことになる。角度θの起点は時計の秒針では、15秒の位置になる。例として、半径r=108の時、20秒(4時)の位置は、x=108*cos30°+120≒94+120=214、y=108*sin30°+120=54+120=174というふうに求められる。

腕時計によくある秒単位の印を表示したい場合は、半径r1の円の内側に半径r2の円を想定し、同じ角度θの位置、(x1,y1)と(x2,y2)を求め、2の点を指定して直線を描けば良い。そうすれば、中心からの放射状の直線の一部として描かれる。

高校の数学の教科書みたいになってしまった。


1.28インチ丸形LCDディスプレイ(GC9A01)とESP32でデジタル時計を試作した

2023-11-24 13:47:06 | 電子工作

1.28インチの丸形LCDディスプレイ(カラー、ドライバはGC9A01)が500円位で購入できるようになったので表示装置として利用できないか調べてみることにした。インターネットで調べてみると、レポートはあまり多くない。その中で、このディスプレイの特徴を生かしたデジタル時計の製作例があったので、それを参考に試作してみた。

製作例では、RTC(リアルタイムクロック)モジュールが必須になっているが、RTCモジュールの持ち合わせは無い。以前、Seeed StudioのXIAO ESP32C3を利用して時計を作ったので、RTCの替わりにNTPから時刻を得るのはどうかということで取り組んでみた。

ディスプレイのドライバGC9A01対応のライブラリは幾つかあるが、ここでは「TFT_eSPI」を利用した。ライブラリにはサンプル例が色々あるので動作確認のために幾つか試してみると良い。このサイトが参考になる。確認には「Boing Ball」がお勧めである。

TFT_eSPIは事前に、使用するドライバとMCUに対応するための変更が必要である。ライブラリをインストールした後、「..\Arduino\libraries\TFT_eSPI」の「User_Setup.h」を編集する。

  1. 「Section 1. Call up the right driver file and any options for it」の個所に、ディスプレイ対応のドライバの定義があるので、「#define ILI9341_DRIVER」の行をコメント化し、「#define GC9A01_DRIVER」の行を「非」コメント化する。
  2. 「Section 2. Define the pins that are used to interface with the display here」の個所に、各MCUごとSPIに対するピンの定義があるのでそれを変更する。まず、ESP8266のピン定義をコメント化する。

// ###### EDIT THE PIN NUMBERS IN THE LINES FOLLOWING TO SUIT YOUR ESP8266 SETUP ######

// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation  ##### comment out to line 176
//#define TFT_MISO  PIN_D6  // Automatically assigned with ESP8266 if not defined
//#define TFT_MOSI  PIN_D7  // Automatically assigned with ESP8266 if not defined
//#define TFT_SCLK  PIN_D5  // Automatically assigned with ESP8266 if not defined

//#define TFT_CS    PIN_D8  // Chip select control pin D8
//#define TFT_DC    PIN_D3  // Data Command control pin
//#define TFT_RST   PIN_D4  // Reset pin (could connect to NodeMCU RST, see next line)
//#define TFT_RST  -1     // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V

次に、XIAO_ESP32C3に対するピン定義を追加する。


// For the XIAO_ESP32C3 module use these #define lines   with GC9A01 display ####
#define TFT_MOSI 10  // SDA
#define TFT_SCLK 8   // SCL
#define TFT_CS   3   // Chip select control pin
#define TFT_DC   5   // Data Command control pin
#define TFT_RST  4   // Reset pin (could connect to Arduino RESET pin)

なお、使用しないピン(BLK)は定義していない。接続の様子を以下に示す。

大元のスケッチは、こちら(Github)にあるが、説明は何もない。2ファイルあり、「fonts.h」はそのまま利用し、「watchESP.ino」を改修した。なお、オープンソースのライセンスが明確ではないため、Githubに載せたり、全体を紹介するのは控えることにする。

改修内容を紹介すると、「setup」においては、RTCに関係するコードと意味不明のコードをコメント化し、Wifiに接続後、NTPを参照して、XIAO_ESP32C3の時刻に設定するコードを追加している。

ここで紹介していない部分(特にwifisyncjst())は、XIAO_ESP32C3による時計の記事(上方にリンクあり)を参照するとよい。WifiのSSIDとPASSWORDは、実際にアクセスする無線LANを設定する。


void setup() {
    Serial.begin(115200);
    Serial.println("");
    delay(10);

    //if (! rtc.begin()) {
    //  Serial.println("Couldn't find RTC");
    //}
    //pinMode(2,OUTPUT);
    //pinMode(0,INPUT_PULLUP);
    //pinMode(35,INPUT_PULLUP);
    //pinMode(13,INPUT_PULLUP);

    //digitalWrite(2,0);

    //ledcSetup(pwmLedChannelTFT, pwmFreq, pwmResolution);
    //ledcAttachPin(5, pwmLedChannelTFT);
    //ledcWrite(pwmLedChannelTFT, 200);
    WiFi.mode(WIFI_STA);
    wifiMulti.addAP(ssid.c_str(), password.c_str());  
    wifiMulti.run();   // It may be connected to strong one

    while (true) {
      if(WiFi.status() == WL_CONNECTED){ break; }  // WiFi connect OK then next step
      Serial.println("WiFi Err");
      WiFi.disconnect(true);
      delay(5000);
      wifiMulti.run();
      delay(1000*60);  // Wait for Wifi ready
    }
    wifisyncjst(); // refer time and day
    WiFi.disconnect(true);  // Connection is no longer needed

    //tft.init();  ####
    tft.begin();  // initialize
    //tft.setRotation(0);
     
    //tft.setSwapBytes(true);  ####
    tft.fillScreen(TFT_WHITE); //#### BLACK
    delay(100);
        
    //img.setSwapBytes(true);
    img.setColorDepth(8);      // Create an 8bpp Sprite of 240x240 pixels
    img.createSprite(240, 240);
    img.fillSprite(TFT_BLACK); // Fill the Sprite with black
    img.setTextColor(TFT_GREEN);        // Green text
    img.setTextDatum(4);
   :
   :
}

「loop」では、XIAO_ESP32C3から時刻を得たのち、もとの「DateTime now」変数に設定するコードを追加している。

又、そのままだと何故か、曜日が1日ずれるためXIAO_ESP32C3の時刻から得た曜日を使っている。


void loop() {  
  rAngle=rAngle-2;
  //DateTime now = rtc.now();   ####
  time_t t = time(NULL);
  tm = localtime(&t);
  d_year = tm->tm_year;
  d_mon  = tm->tm_mon+1;
  d_mday = tm->tm_mday;
  d_hour = tm->tm_hour;
  d_min  = tm->tm_min;
  d_sec  = tm->tm_sec;
  d_wday = tm->tm_wday;

  //DateTime now = DateTime(1110000 + sec1);
  DateTime now = DateTime(d_year, d_mon, d_mday, d_hour, d_min,  d_sec);
  angle=now.second()*6; 
:
:
 //img.drawString(days[now.dayOfTheWeek()],circle,120,2);
 img.drawString(days[d_wday],circle,120,2);
:
:
}

 

とりあえず、手元にあったお菓子の容器に入れてみた。外側の秒表示が回転する。外側の赤い丸印は反時計回りに回転する(ただの飾りだと思われる)。ついでに、紹介しておくと、「volos projects」で検索すると、この種の色々なガジェットがyoutubeで見られる。


週間スケジュールが可能なRDA5807 FM DSPラジオ

2023-10-26 15:02:00 | 電子工作

色々なDSPラジオを製作してきたが、普段、聴く上で面倒なのはラジオ局の選択である。ボリュームで行うのは論外で、プリセット(ボタン)で行うのは許容範囲内であるが、番組の時刻になった時に、ボタンを押すのを忘れ聞き逃すことがある。常々、時刻になったら自動で番組を選択してくれる機能があればと思っていた。そのようなラジオはないので、自分で作ることにした。

求める機能は以下の通りである。

  • 時刻機能(時刻設定は自動)を持つ。
  • 番組の時刻になったら(電源をONして⇒目覚まし機能)該当のラジオ局を自動で選局する(スケジュール機能)。
  • 指定の音量で再生する。
  • 番組が終了したら、電源をOFFする(Sleep機能)。
  • スケジュールの設定は、PCやスマホからブラウザ経由でできる。
  • 最低限の操作(音量調節、選局、電源ON/OFF)はブラウザ経由でできる。

以上の機能は、RDA5807FP(FM DSPラジオ)とSeeed Studio XIAO ESP32C3(WiFi機能あり)を組み合わせることで可能となる。RDA5807FPは、安価であるが性能的には十分である。ワイドFMに対応し、聴きやすい音質で、ステレオをサポートする。XIAO ESP32C3は、サイズが500円硬貨位で、全体をコンパクトにできる。また、Arduino IDEでのプログラミングがサポートされている。RDA5807FPとXIAO ESP32C3は、I2Cで接続する。RDA5807FPは、小口径のスピーカーなら十分駆動できるので、アンプは不要である。全体の、消費電力は微少(0.3W程度)で、24時間電源ONでも大丈夫である。今回、作成したスケッチ(プログラム)と製作に関する情報はGithubに登録してある。

スケジュールは、曜日ごとに週間で設定する。ラジオの番組は、平日、土、日で異なり、毎週ほぼ同じなので、週間スケジュールで十分である。聴きたい番組について、「開始時刻、ラジオ局、番組の長さ(分)、音量、番組終了後に電源OFF(RDA5807FPのみ)するか否か」を設定する。以下に示すのは、ブラウザに表示された週間スケジュールの設定画面である。中央の表に各曜日ごとのスケジュールが表示されている。各エントリの指定項目は上記の通りである。ラジオ局については、”Station List:”の数字を設定する。

スケジュールを変更する方法は、まず各曜日のラジオボタンをクリックする。選択した曜日の設定が上部の入力領域にコピーされるので、それを編集後、”Submit”ボタンをクリックする、これで変更内容が保存される。

上の設定画面の下部”Control Functions”にあるボタンは、それぞれ、音量調節、選局、電源(RD5807FPのみ)をON/OFFするためのものである。

製作したDSPラジオの外観を以下に示す。

手前がXIAO ESP32C3、奥がRDA5807FP。部品数は少ない。口径10センチのスピーカーをRDA5807FPに直接接続している。アンテナは70センチ程のリード線を接続すれば十分受信できる。

OLEDの表示内容を以下に示す。

日付、曜日、時刻、音量、電源(1:ON,0:OFF)、受信周波数の順。

数か月間利用しているが、朝、電源ONした後はノータッチで自動選局してくれるので、大変便利である。

 


ESP32でWiFiとBluetooth(A2DP)は同時に使えるか

2023-09-17 15:20:22 | 電子工作

以前、ESP32によるインターネットラジオを製作したが、これはDACをI2Sで接続し、スピーカーから音を出す物だった。ESP32はWiFiとBluetoothを搭載しているので、それらを同時に使えば、ESP32でインターネットラジオを受信し、それをA2DPでBluetoothスピーカーに送って音を出すことができるはずである(スマホで普通にやってること)。事例がないかを調べて見た。

GithubにESP32を色々な方式のプレイヤーにするコードの実装例があった。その中に、SDカードモジュールを使い、A2DPで接続したBluetoothスピーカーから音を出すプレイヤーと、インターネットラジオを受信し、I2Sで接続したDACから音を出すプレイヤーの例を見つけた。これらを組み合わせれば、所期の目的を達成できそうだと思った。

しかしながら、結論からいうと、WiFiとA2DPを同時に動作させることはできなかった。A2DPを接続するとWiFiが繋がらない。WiFiを接続するとA2DPの接続でリセットエラーになる等、(このケースでは)同時には動作しなかった。

以下は試行錯誤の報告である。実装コード(ライブラリ)は洗練されていて、各種のプレーヤーが簡単に実装できるようになっており、最初の2例は動作を確認したので参考になると思う。

インターネットラジオを受信し、I2Sで接続したDACから音を出すプレイヤー

以下にスケッチを示す。上記の実装例からは、ボリューム(音量)や接続先のURLを変更するコードは省略している。ライブラリは、pschatzmannさんのライブラリを、ZIP形式でダウンロードし、ArduinoIDEのライブラリ管理からインストールする。「*wifi」と「*password」の部分は、利用しているWiFiのものを指定する。DACはUDA1334かPCM5102のモジュールが使える。ESP32との接続方法は、上記のリンク先に記載されている。

なお、ArduinoIDEは1.8.9。ボードマネージャからインストールするESP32ライブラリはEspressif Systemsの2.0.10である(古いとコンパイルエラーになる)。

下記のスケッチ中の、「AudioPlayer player(source, i2s, decoder)」の組み合わせを変えることで、色々なプレーヤーを実装できる。


#include "AudioTools.h"
#include "AudioCodecs/CodecMP3Helix.h"

const char *urls[] = {
  "http://stream.srg-ssr.ch/m/rsj/mp3_128"
};
const char *wifi = "your_ssid";
const char *password = "your_password";

URLStream urlStream(wifi, password);
AudioSourceURL source(urlStream, urls, "audio/mp3");
I2SStream i2s;
MP3DecoderHelix decoder;
AudioPlayer player(source, i2s, decoder);

void setup() {
  Serial.begin(115200);
  AudioLogger::instance().begin(Serial, AudioLogger::Info);

  // setup output
  auto cfg = i2s.defaultConfig(TX_MODE);
  i2s.begin(cfg);

  // setup player
  player.begin();
}

void loop() {
  player.copy();
}

 

A2DPで接続したBluetoothスピーカーから音を出すプレイヤー

以下にスケッチと実験セットを示す。SDカードモジュール(写真ではタテになっている基板。Amazonから200円程度で入手できる)の接続方法は、上記の実装例に記載されている。mp3の楽曲をSDカードにコピーしてセットしておく。複数の曲をコピーした場合は一通り演奏後に停止する(その後は一旦電源を落とさないと「ファイル無」のエラーになる)。スケッチ中の「cfg.name」に、Bluetoothスピーカーのデバイス名を設定する。

なお、SDカードモジュールが手元に無い場合は、ESP32のSPIFFS領域にMP3のファイルを予めコピーしておく方法(プラグインの設定が必要。なお、このプラグインはArduinoIDEのVer2.x.xでは使用できないので注意)で実験できる(実装例はこちら、コピーするデータあり)。


#include "AudioTools.h"
#include "AudioLibs/AudioA2DP.h"
#include "AudioLibs/AudioSourceSDFAT.h"
#include "AudioCodecs/CodecMP3Helix.h"

const char *startFilePath="/";
const char* ext="mp3";
AudioSourceSDFAT source(startFilePath, ext); // , PIN_AUDIO_KIT_SD_CARD_CS);
A2DPStream out;
MP3DecoderHelix decoder;
AudioPlayer player(source, out, decoder);

void setup() {
  Serial.begin(115200);
  AudioLogger::instance().begin(Serial, AudioLogger::Warning);
  // setup output - We send the test signal via A2DP - so we conect to a Bluetooth Speaker
  auto cfg = out.defaultConfig(TX_MODE);
  cfg.name = "bbbbbbbbbb";  // set the device here. Otherwise the next available device is used for output
  cfg.auto_reconnect = true;  // if this is use we just quickly connect to the last device ignoring cfg.name
  out.begin(cfg);

  // setup player
  player.setVolume(0.7);
  player.begin();

}

void loop() {
  player.copy();
}

 

インターネットラジオを受信し、A2DPで接続したBluetoothスピーカーから音を出すプレイヤー(動作せず)

目的のプレイヤーである。実装例にはないが、上の2つを組み合わせれば(入力:インターネットラジオ、出力:Bluetoothスピーカー)実現できるはずである。実装例からの類推で作成したスケッチは以下の通り。

実行したところ、「E (17464) wifi_init_default: netstack cb reg failed with 257」というようなエラーとrebootを繰り返し、動作はしなかった。なお、以下のスケッチをコンパイルすると、プログラムサイズが1.7MBになるので、ArduinoIDEからPartition Schemeのサイズを「No OTA 2MB APP/ 2MB SPIFFS」に変更した。

 


#include "AudioTools.h"
#include "AudioLibs/AudioA2DP.h"
#include "AudioCodecs/CodecMP3Helix.h"
const char *urls[] = {
  "http://cast1.torontocast.com:2170/stream"
};
const char *wifi = "your_ssid";
const char *password = "your_password";

URLStream urlStream(wifi, password);
AudioSourceURL source(urlStream, urls, "audio/mp3");

A2DPStream out;
MP3DecoderHelix decoder;
AudioPlayer player(source, out, decoder);

void setup() {
  Serial.begin(115200);
  AudioLogger::instance().begin(Serial, AudioLogger::Warning);
  // setup output - We send the test signal via A2DP - so we conect to a Bluetooth Speaker
  auto cfg = out.defaultConfig(TX_MODE);
  cfg.name = "bbbbbbbbbb";  // set the device here. Otherwise the next available device is used for output
  cfg.auto_reconnect = true;  // if this is use we just quickly connect to the last device ignoring cfg.name
  out.begin(cfg);

  // setup player
  player.setVolume(0.9);
  player.begin();
}

void loop() {
  player.copy();
}

 


16KEY PADを使用した RDA5807 FM DSPラジオ

2023-07-06 16:13:26 | 電子工作

4x4 keypad(前掲記事)、RDA5807(前掲記事1前掲記事2)、Seeeduino XIAOを組み合わせたFMラジオを製作し、既に半年程利用しているが、とても安定していて、常用しているので紹介する。RDA5807はFM DSPラジオ用のICであり、SOP16ピンサイズであることや、使用部品が少なく済み(特にXtal発信回路にコンデンサが不要なのが良い)、自作派には使い易い。また、安価なのでお勧めである。さらに、ここで組み合わせたXIAOのI2C制御との相性も良い。

これまで複数のラジオを製作してきたが、使う立場で言うと、(特に選局が)ワンタッチで操作できるのが良い。自作であり、汎用にする必要はないので、4x4 keypadを利用して、地域に合わせて1放送局1ボタンにプログラミングしておくのが使い易い。

4x4 keypadと今回のMCP23107を組み合わせる場合、唯一の難点は両者を、8本のリード線で結ぶ(ハンダ付け)必要があり、細かい作業が必要なことである。以前の製作で利用した別の4x4 keypad(制御ICとKeypadが同じ基板に載っている)を利用してみるのも一案かもしれない(この場合、配線は4本で済む)。

今回のスケッチは、こちら(Github)に置いてある。

写真。100均のアクリルケースに格納している。ブレッドボードから、汎用基板に実装し直した。手前がXIAO、奥がRDA5807、その奥は表示用のOLED。アクリルケースの上面にKeypadを配置した。XIAOは、長さが短いので、全体をコンパクトにできるが良い。


MCP23017を使用した4x4Keypad

2023-04-01 13:41:09 | 電子工作

DSPラジオを製作して実際に使ってみると、放送局をプリセットボタンに定義しておいて選局するのが使い勝手が良い。実際に4x4のKeypadを使用した物を製作したが、I2Cインターフェースの調子が悪く、電源を入れてから時間が立つと応答が無くなる現象に悩まされて、いまいちであった。

今回は、別のパーツを組み合わせて4x4のKeypadを実現した。使用したのは、MCP23017(基板付)4x4のKeypad基板(前回よりコンパクト)である。

MCP23017はMCU(マイクロ・コントローラ)のポートの数が足りない時に、ポート数を拡張するためのICである。Arduinoでは、デフォルトでKeypad.hライブラリが用意されていて、4X4のKeypadが使える。ただし、この場合、接続する線が8本、つまりMCU側のポートが8個必要になる。MCUにはXIAOを使う予定なので、そのままでは、ポートが不足する。このMCP23017は、MCUとI2Cインターフェース経由で接続するため、線は2本(電源、グランド線を含めると4本)で済む。MCP23017をサポートするKeypad_MC17.hライブラリは、Keypad.hライブラリを拡張している。

評価のためのコードを以下に示す。コードの冒頭でincludeしたライブラリは、Keypad_MC17.h、Wire.h、Keypad.hである。Arduino IDEのシリアルモニタに、押したキー(customKey)が表示される。


#include 
#include  
#include 
#define I2CADDR 0x20    // keypad IC
#define MIN_ELAPSED_TIME 100
const byte ROWS = 4;
const byte COLS = 4; 
char hexaKeys[ROWS][COLS] = { {'1', '2', '3', 'A'},  {'4', '5', '6', 'B'},  {'7', '8', '9', 'C'},  {'*', '0', '#', 'D'}};
byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad 
byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad 
//Keypad 
customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 
Keypad_MC17 keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS, I2CADDR );
long elapsedButton = millis();
long elapsedPull = millis();
void setup() {
   Serial.begin(9600);
   Wire.begin(); 
   keypad.begin( );
   delay(500);
}
void loop() {
  char customKey = keypad.getKey();  // Check button commands
  if ((millis() - elapsedButton) > MIN_ELAPSED_TIME)  {
    // check if some button is pressed
    if (customKey){
      Serial.println(customKey); 
     if (customKey == 'D') {
        // todo 
     }  else if (customKey == '#') {
        //todo
     }  else if  (customKey == '0') {
       //todo
    }  else;  // and so on 
       elapsedButton = millis();
    } 
   delay(10);
}

MCP23017(基板)とKeypadの間は、適当なコネクタがなかったのでメスのピンヘッダ(4x2)を挿した上、8本のリード線で接続している。Keypadのピン番号{1,2,3,4}(COL)をMCP23017のポート{A7、A6、A5、A4}に接続、Keypadのピン番号{5,6,7,8}(ROW)をMCP23017のポート{A0、A1、A2、A3}に接続する。

I2Cのアドレスは、MCP23017の半田ジャンパーをすべてGND側に接続して、X”20”とした。MCP23017側のI2Cの接続はSDA,SCLの表示がある。なお、場合によっては数KΩのプルアップ抵抗が必要なケースがあるかもしれない。


Seeed Studio XIAO ESP32C3でWifiによる時刻設定が可能な時計の製作

2023-03-04 16:23:32 | 電子工作

Seeed Studio XIAO ESP32C3はESP32互換でWifiが利用できるMCU(マイクロコントローラ)である。外形はSeeed Studio XIAOと同じ大きさ、超小型である。スイッチサイエンスから購入(送料200円)した。Wifiのアンテナが付属していて、I-PEXコネクタで本体に接続するタイプである。余談だが、I-PEXコネクタが極小で、接続に苦労した。

試しに何かWifiを利用したものを作ってみようと考え、NTP(タイムサーバー)から時刻と日付を参照し、XIAOのRTC(リアルタイムクロック)に設定する時計を製作した。

いままで、RTCを内蔵したMCUをいくつか利用してきたが、時刻設定の機能をHW、SWで実現するのが手間な上に、電源OFFの度に設定が必要になるので、時計として利用しようとは思わなかった。それが、インターネットに接続してNTPから時刻と日付を参照できればことは簡単である。時刻を利用した作り物にも展開できる。

NTPから時刻を設定する方法はこちらのサイトを参考にさせて頂いた(感謝)。時刻関係のライブラリ(Timelib.h)はこちら。表示は定番のSSD1306のOLED、ライブラリはライブラリ管理から検索可能(Adafruit版)。

Wifiは、2つのWifiステーションのうち、電波の強い方を自動で選択できるように、WiFiMulti.hライブリを利用した(一つしかない場合は一方を適当に指定すればよい)。

I2Cの接続はデフォールト(SDA:4、SCK:5)でよい。

XIAO ESP32C3にはSleep機能があるので、時刻の更新時以外はスリープさせると、使用電力(十数mA)を節約できる。ただし、スリープさせるとArudionoIDEからスケッチの書き込みができなくなるので要注意である。スリープを有効にするのは、最後の書き込み時のみにする必要がある。なお、スリープを有効にしてしまった後は以下の手順で復旧できる。これは、スケッチの誤りで、XIAO ESP32C3がリセットを繰り返すような場合にも利用できるので覚えておく価値があると思う。

  1. USBを抜く
  2. BOOTボタンを押したままUSBを挿す、押したまま
  3. IDEからスケッチを書き込む
  4. 書き込みが完了したら、BOOTボタンを離す
  5. RESETボタンを押す

本記事のスケッチはこちらを参照のこと。

帆のように見えるのはWifiのアンテナである。シールになっていて貼付けることができる。右側の基板はアンテナの台として利用、XIAOには未接続である。


RDA5807(FM DSPラジオ)のI2S機能を使ってみた

2022-12-05 14:15:19 | 電子工作

RDA5807FP(FM DSPラジオ IC)が使い易く、地域のFM局の受信も安定しているので色々と試している。

RDA5807FPは、I2S経由でディジタル音声信号(ラジオ音声)を出力する機能を持っているのが面白いと思ったので、動作を確認してみた。ここではDAC(ディジタルーアナログ変換)にUDA1334を使用する(現在、スイッチ・サイエンスでは販売終了とのこと)。

RDA5807とUDA1334の基板側の接続は以下の通り。電源はUSBからの5VをVINに、基板のGND同士を接続する(写真を参照のこと)。

ピン1(GPIO1) ー WSEL 
ピン15(GPIO3)ー BCLK 
ピン16(GPIO2)ー DIN

写真では、マイクロ・コントローラ(MCU)として、RP2040‐ZERO (Raspberry Pi Pico相当)を使用している。

RDA5807のI2Sを有効にするには以下の初期化コードを追加する。

Wire.beginTransmission(0x11);
Wire.write(0x04); // REG4
Wire.write(0b10001000); // RDSIEN, De-emphasis 50μs
Wire.write(0b01000000); // I2S Enabled
Wire.endTransmission(); // stop transmitting
Wire.beginTransmission(0x011);
Wire.write(0x06); // REG6
Wire.write(0b00000010); // DATA_SIGNED
Wire.write(0b10000000); // 48KBPS
Wire.endTransmission(); // stop transmitting

上のコードでは、Wireライブラリを利用して、RDA5807のREG4、REG6を直接設定している。RDA5807側のサンプリングレートは最大の48KBPSに設定している。UDA1334はWSEL入力の周波数に自動で対応するようである。

結果として、UDA1334側からもラジオ音声は出力されたが、RDA5807からの出力と比較してみて、音質の違いは明確には認識できなかった。あと、I2S側は音量が調節できないので、後段にアンプを接続する必要がある。

ということで、I2Sを利用しても仕掛けが大掛かりになる割にはメリットがないので、実験にとどめておくことにする。


RDA5807(FM DSPラジオ)をRDA7088の回路で動作させてみた

2022-11-10 13:55:14 | 電子工作

RDA5807FPは、マイクロコントローラ(MCU)で制御するFM DSPラジオICであるが、接続によって、マイクロコントローラなしで動作(RDA7088相当)させることができることを知ったので確認してみた。

きっかけは、AliExpressなどで売られている(とても安価な)FMラジオのDIYキットにおいて、HEX3653の替わりにRDA5807FPが添付されているのを発見したことにある。HEX3653の互換品はRDA7088(データシート)である(どちらがオリジナルであるかは不明)。RDA5807FPのデータシートには、RDA7088モードで動作するとは書かれていない。しかしながら、RDA5807FPは、ピン6をVCC(つまりHIGH)に接続するとRDA7088として動作するのである。

まず、AliExpressから件のDIYキットを購入してみた。確かにRDA5807FPが添付されていた。ただ、このまま組み立てると壊しそうなので、ブレッドボード上にRDA7088相当の回路を構成し、組み込んでみた。なお、事前にピン6と他のGNDに接続するピン間に十分な抵抗値があることは確認済みである(でないと発火するので)。

ちゃんと動作したというが結果である。放送局のSEEK(探索)、ボリュームの増減がタクトスイッチ操作で可能である。また、RDA5807FPの受信品質は、ワイドFM含めて良好で、小型のスピーカーを十分に鳴らせることが分かった。

次に、このRDA5807FPが、マイクロコントローラ制御で動作するかを確認する必要があるが、これは、この後に組んだ回路(ピン6はGNDに接続)で確認済みである。

このRDA7088モードは、どうも「隠し仕様」であるらしい。なお、RDA7088は、RDA5807FPの検査不良品(例えばレジスタが設定できない等)であるかもしれないので、RDA5807FPとして動作する保証はない(念のため)。

件のDIYキットであるが、後日、RDA5807FPを別途購入(安かった)したので、それを組み込んで完成させた。タクトスイッチはケースに収めるため基板の裏側に付けた。なお、動作に必要な部品のみ実装している。


KT0915(AM/SW/FM DSPラジオ)の試作

2022-09-20 14:43:21 | 電子工作

AM/SW/FMが受信できるマイコン制御のDSPラジオ ICは、これが3つ目(AKC6955、Si4732、KT0915)であり、たぶんこれが最後だと思う。KT0915については、期待を込めて試作したが、結論から言うと、試作で終えることにした(残念)。なお、DSPラジオ ICは、色々と種類があって、電子うさぎさんのサイト(日本語のリンクが貼れないので「電子うさぎ DSPラジオ」で検索)を参考にした。

結果のまとめを少々述べることにする。

SW(短波)の受信感度は、Si4732>AKC6955>KT0915の順であった。FMだけなら、KT0915が良い。AKC6955がそれに次ぐ(が製作上の安定度はいまいちで苦労した)。Si4732は、FMについては、音質が良くないのでお勧めではない。AMについては、感度はSWと同じ順番である、ただ、どれも音質は良くない、利用は電波状況が良い場所に限られると思う(筆者の環境は高雑音)。

マイコン(Arduino)用のライブラリは、いずれも、pu2clrさん作の物が利用できる(Si4732とKT0915で利用した)。特にSi4732(Si4735と同じ)の物は完成度が高い(そのまま利用した受信機が売られている程)。

KT0915は、KTマイクロ製、SSOPの16ピン ICである。ピン数が少ないため、部品点数が少なくて済むので、自作向きである。ただ、変換基板に載せるためのハンダ付けは、ほぼ限界である。AKC6955(SSOP、24ピン)で失敗した経験が役に立って、今回は上手くいった。

Arduinoは、Seeeduino XIAOを利用した。pu2clrさん作のKT0915用ライブラリは、GitHubにあるが、ArduinoのIDEのライブラリ管理の検索から「KT0915」で検索するとインストールできる。

試作ではpu2clrさんのGitHubのexamlpesフォルダにあるKT0915_02_OLEDをベースに、少々改変を加えた。詳細は筆者のGitHubを参照して頂きたい。なお、Arduino Pro Miniベースの回路図が前記のexamlpesフォルダにあるが、受信周波数を変更するロータリーエンコーダ(スケッチには存在)が省略されている。試作したスケッチでは、受信周波数の変更はタクトスイッチで行なっている。

さて、評価であるが、FMはリード線程度のアンテナで問題なく受信できた。音質もまずまずである。音量は小音量でスピーカーを鳴らせる程度、やはりアンプが欲しい。AMは、地元に4局(距離は20から30km)あるが、大電力(100㎾と300㎾)の2局(NHK)のみ受信できた。音質は良くない。SW(短波)は、マグネティックループアンテナを使用したが、7MHz帯の北京放送すらまともに受信できなかった(Si4732では同じアンテナで複数局が受信できたのに)。