PCBの注文時に、PCBWAYの担当者さんに連絡したところ、なんと費用の全額をアカウントに入金してくれた(感謝です)。
- 簡潔な説明文(英語、140字以内)
- ガーバーデータ(基板の設計データ、KiCadで出力)
- 説明文(英語、簡単なエディタがある)
- 実物の写真
- 回路図(KiCadにて作成済)
- プログラム(GitHubに登録されていたライブラリのサンプルを改修)
- 部品表(KiCadで作成)
- 使用した設計ツール(KiCad、Arduino IDE)
Wire.setSDA(20);
Wire.setSCL(21);
#define RESET_PIN 22
Encoder 1 | 2 |
---|---|
Encoder 2 | 3 |
Mode Switch (AM/LSB/USB) | 4 |
BANDWIDTH switch | 5 |
Volume Up | 6 |
Volume Down | 7 |
Next Band (Up) | 8 |
Previous Band (Down) | 9 |
Step switch | 10 |
AGC Switch | 11 |
BFO Switch | 14 |
SDA | 20 |
SCL | 21 |
前回までに、プリント基板上の部品の配置が決まると、プリントパターンの配線のステップに進むことができる。プリント基板は複数の層で構成されているが、各層の役割を理解しておく必要がある。基板のベース(ガラスエポキシ樹脂)の次の層は配線層(銅箔の部分、裏表の2層)で、これらの層に対してプリントパターンの配線を行う。銅箔層の上はレジスト層(緑や紫で色付け)で、レジスト層の上にはシルク印刷(部品名の表示など)の層がある。レジスト層については、ハンダ付けする部分にマスク(レジストしない)を定義する必要があるが、フットプリントを適切に選択すれば属性として定義されているので心配ない。
配線の基本方針として、配線層の表面はVCCや信号線、裏面はGNDの配線とすることにした。パターンの配線は、KiCaDの「PCBレイアウトエディタ」で行う。この作業は、各層ごとに表示・非表示を切り替えて行う。表面側の配線は以下のようになった。
裏面側の配線は以下の通り。
VCC、信号線が表面側に通せない場合は裏面を使う。また、同じ面で配線が交差するケースは、「ビア」(白い四角の印)を経由させて、一方を裏側に配線する。
配線パターン以外の銅箔部分は、「べた」(表裏ともGNDとした)にするが、この描画はPCBレイアウトエディタが自動で処理してくれる。「べた」の表裏は、GNDのスルーホールのところで接続しているが、念のためGNDから遠い場所は「ビア」で接続した。パターンの設計は、KiCaDのパターンチェックツールを実施して完了である。最後にピンヘッダーの信号名など、シルク印刷の文字を追加した。
プリント基板の設計情報は、「ガーバー(Gerber)データ」として出力する。ここまで、PCBWAYからお誘いを受けてから8日経過。
PCBWAYのサイトから発注手続きを行う(このサイトが参考になる)。プリント基板の仕様を入力し、注文カートに「ガーバー(Gerber)データ」をZIP化したファイルをアップロードする。配送情報の指定では、送料が高い($13)と感じたが、日本の場合は、「OCS」が推奨とのことなので選択する(今回、国内の配送は、佐川急便に連絡された)。この後、審査にパスすれば発注可能になる。今回は、プロモーションなので、PCBWAYの担当者に連絡を入れたところ、アカウントに費用が振り込まれた。金額は、「OCS」の配送料+見積もり額($5)ピッタリだったので、結局、0円で制作できたことになる。なお、発注してから3時間後に、審査をパスして製造手配したというメールが来た。
この後、発送まで2日、通関、関空経由での配送に7日かかり(関西の大雪で配送遅れあり)、無事入着した。梱包は丁寧で、プリント基板の出来上がりも綺麗である。
早速、部品を実装してみた。ユニバーサル基板では、配線にほぼ1日かかったが、約1時間で完了した。なお、R1からR4は無くても動作する。Y1(Xtal)は、RD5807の変換基板側に実装しているので差し替えるだけである。
ユニバーサル基板をプリント基板に交換して、動作確認。
今回の、配線図とガーバー(Gerber)データは、こちら(Github)に登録した。また、PCBWAYのプロジェクトに登録したので、同じ基板の発注が可能である。
電子工作では、一般にブレッドボード上で試作評価してみて、結果が良ければ、ユニバーサル基板を使って実用版を製作する。ユニバーサル基板は配線の手間がかかって大変なのは承知であるが、多くは一品物なので、わざわざプリント基板を制作することはない。それにプリント基板の制作を発注には万円単位で費用がかると思っていた。
今回は、PCBWAYさんからお誘いがあったので、プリント基板の制作に挑戦してみることにした。費用についてはプロモーションなので補助があるとのことである。一応、ホームページで見積もりしてみた。5cmx7cmのサイズで2層の物は、なんと5$という結果になった。おまけに初めて登録(発注)する場合は5$のクーポンが貰える(結局、タダ?)。
プリント基板の制作は、全く初めて(昔、「エッチング」で製作したことはある)なので、まず、ツールと手順を調べてみた。大まかにいうと、KiCaDというツール(無料で使える)で、配線図を作成し、プリント基板のパターンを設計、それをガーバー(gerber)データにして発注先に渡せば(アップロードする)良いということが分かった。この手順については、こちらに懇切丁寧な記事がある。
現在、KiCaDの最新はV7であるが、より安定しているV6をダウンロードして使い始めた。しかし、前記の記事はV5対応なので、色々と変わっている上に、たまに固まってしまうのであきらめて、V5に変更した。最初に行うのは配線図の作成である。色々パーツ(コンデンサ、抵抗、IC、ピンヘッダーなど)が用意してありそれを並べて、それらの間を配線するという作業であるが、KiCaDは結構クセのあるツールで、作図の操作を会得するまで2日を要した。コツは、どんな部品が用意されているか事前に調べておくこと。作業が早く済む。部品の選択を誤り、やり直しが何度か生じた。
今回は、以前のブログの記事である「週間スケジュール可能なDSPラジオ」をプリント基板化することにした。配線図は以下のようになった。特徴は、I2Cで接続するOLED表示装置とSPIで接続する丸形カラーLCDの両方に対応することである。
KiCadでは、配線図を作成する時に各パーツのプロパティに対して「フットプリント」を定義する。「フットプリント」は、プリント基板上でパーツの実サイズと穴(足)の位置を示している。パーツをプリント基板に取り付ける時に、ピッタリ合わなければいけないので極めて重要である。例えば、U2のXIAO_ESP32C3はメーカーがKiCad用の「フットプリント」を提供している。ただし、KiCad V6用で、今回のV5には取り込めなかった。その際、新規に「フットプリント」を作成するには「フットプリントエディタ」を使用する。今回はサイズとピンの数が同じICの「フットプリント」を流用した。U1のRDA5807については、変換基板を利用するので、サイズ、ピンの数とも合致するDIP ICの「フットプリント」を流用した。
配線図と「フットプリント」が揃ったところで、「ネットリスト」の生成を行う。この「ネットリスト」を「PCBレイアウトエディタ」に取り込むと、「蜘蛛の巣に取り込まれた獲物」の様な「部品が配線によって搦めとられた塊」が現れる。それをほぐすと以下のようになる。
「PCBレイアウトエディタ」上でパーツの配置を決め、プリントパターンを作成する。上のパーツを繋いでいる白い線(配線)は、プリントパータンが出来上がるにつれて消えていく。最終的に、配置は以下のようになった。
左上の赤い十字は基準点((50,50)に設定)である。次のステップは、いよいよプリントパターンの設計である(その2に続く)。
試作を行い、丸形カラー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)が500円位で購入できるようになったので表示装置として利用できないか調べてみることにした。インターネットで調べてみると、レポートはあまり多くない。その中で、このディスプレイの特徴を生かしたデジタル時計の製作例があったので、それを参考に試作してみた。
製作例では、RTC(リアルタイムクロック)モジュールが必須になっているが、RTCモジュールの持ち合わせは無い。以前、Seeed StudioのXIAO ESP32C3を利用して時計を作ったので、RTCの替わりにNTPから時刻を得るのはどうかということで取り組んでみた。
ディスプレイのドライバGC9A01対応のライブラリは幾つかあるが、ここでは「TFT_eSPI」を利用した。ライブラリにはサンプル例が色々あるので動作確認のために幾つか試してみると良い。このサイトが参考になる。確認には「Boing Ball」がお勧めである。
TFT_eSPIは事前に、使用するドライバとMCUに対応するための変更が必要である。ライブラリをインストールした後、「..\Arduino\libraries\TFT_eSPI」の「User_Setup.h」を編集する。
- 「Section 1. Call up the right driver file and any options for it」の個所に、ディスプレイ対応のドライバの定義があるので、「#define ILI9341_DRIVER」の行をコメント化し、「#define GC9A01_DRIVER」の行を「非」コメント化する。
- 「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で見られる。