t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

ヘッドフォンアンプについて疑問に思ったこと

こんなタイトルなのに申し訳ないけども、今回はヘッドフォンアンプのレビューとかそういう話ではない。
私自身は音楽を聴くのに別売りのヘッドフォンアンプなんて付けないので、ポータブルアンプを店頭で見たときは素直な感想として「なんじゃこりゃ?」と思ったものである。

ざっと調べると、ヘッドフォンの音がハイパワーで高音質になるとか謳われていて当時はへぇそうなのかと思ったんだけど、最近オペアンプについて学習を始めて疑問が出てきた。

以下はオペアンプを使った反転増幅回路で、信号発生器から出力された正弦波を反転させて増幅させるという実験。

黄色が元の波形で、青が反転増幅された波形である。(反転はまぁ今回の話とは関係ない)

波形を眺めていて思ったんだけど、アンプって基本的に入力信号を増幅してるだけなので、ハイパワーは分かるとして高音質ってのはおかしくないかということに気づいた。基本的には入力される波形が歪んでいれば、出力波形も歪んだまま増幅されるはずなのだ。

それで色々考察したところ以下の条件なら高音質に感じるということがありうると結論づけた。

A) 元の音源に乘っているノイズをヘッドフォンアンプでカットしてくれる
⇒つまり波形の再現度は落ちてるが、音的には心地よくなる可能性あり。
 ただ、ノイズが乘ってればの話だし、そんな良い機能があるなら具体的にアピールしてるはずなので、書いてなければ多分違う。
B) DAC機能を指して高音質と謳っている
⇒これが一番可能性が高い。後述。
C) 再生機器側で音量を絞って増幅をアンプに任せた場合の話をしている
⇒個人的な経験として、再生機器(Raspberry Pi)を最大音量にしてスピーカーに繋ぐと音割れしてしまったことがある。そこで再生機器側は音割れしないレベルまで絞って、外付けアンプで増幅したらいい感じになった。これもありうるけど、アンプを推す記事見ると再生機器からの出力は最大が良いと書かれてるので多分これじゃない。
D) 音が良くなったと感じるのは気のせい
⇒つまり単なるプラシーボ。これも有力候補。


DACはDigital to Analog Converterのことを指す。
パソコンや音楽プレイヤーの中には音楽はデジタル形式で保存されている。どういうことかというと、レコーディングされた音波は等間隔でサンプリングされて、平たく言えばその座標がデジタルデータとして記録されているのだが、スピーカー等で鳴らすときは必ずアナログ信号に戻される。

アナログ信号は音波がそのまま電圧波形になるので電源ノイズなどで電圧に変動があればモロに影響を受けて音質が劣化する。一方でデジタル信号は実際はHighとLowの2値で表されるため、通信の途中で変形してもHighかLowかの識別さえできれば問題なくデータが復元できる。

つまりデジタル信号で処理されているうちは、よほどのことが無ければデータが劣化しないという話である。

先ほど述べたとおり、結局スピーカー等で鳴らすときは必ずアナログ信号に戻さなければならないのだが、再生機器側の音声処理がショボいと波形が忠実に再現できないことがあるので、電源等の各種ノイズを考慮した高品質なヘッドフォンアンプ側でアナログに戻してあげることで歪みを極力抑えるということをしていると思われる。

なお普通のヘッドフォンジャック等から出ている信号は既にデジタルからアナログに戻されている為、DAC機能で高音質と謳っている製品であればジャックの接続ではなくてUSB接続か何かだと思う。

ジャック接続の製品で音がよくなるっていうのは、たぶん気のせい。
まぁ音の好みは人それぞれなので、波形の再現度が下がった結果として好みの音に聞こえるということも無くはないかもしれない。本人が満足してるならそれはそれで良い買い物なんじゃないかと思う。

オーディオマニアには本当に技術的に詳しい人もいれば、主観と経験のみで良し悪しを語る方もいる。メーカーも製品を売りたいので嘘にならない範囲で絶妙な謳い文句を書く。まぁ高音質ってのも主観なので書いて嘘にはならないんだろうな。入力波形再現度99.999%とか書いちゃうと測定できてしまうのでアレだけど「高音質」と書かれてそうでもないなと思っても耳とか好みの問題と言われればそれまでだし。てな感じで、ちゃんと根拠があるものから迷信めいたものまで混然一体となってオーディオ沼を形成しているんだろうなと思った。

まぁ多少の誇張があってもプラシーボ効果が発動すれば元は取れてるのかもしれない。

今回は高音質という部分について疑問を感じたので書いてみたが、ハイパワーという部分はちょっと調べたら必要性を理解できた。世にはノイズが乘りにくいようにインピーダンス(交流抵抗)を高くしたヘッドフォンがあるらしい。抵抗が大きいということは電圧を十分に上げてやらないと音が出にくいということなので、インピーダンスが高いヘッドフォンでそこそこの音量で聴きたい場合はそもそもアンプが必要らしい。ということでアナログ接続のアンプが無意味だと言いたいわけではないので誤解されないよう付け加えておいた。

以上。

Arduino コイル巻き機プロジェクトの打ち切りと失敗からの学び

以前から何週かかけてチマチマと進めていたArduinoコイル巻き機プロジェクトについて、打ち切りを決断したのでその夢の跡というか、残骸を書き残しておく。

まずは前回から少し進化してOLEDディスプレイを備えたバージョンであるが、これは正常に動作していた。
OLEDをつけたのに7セグを残したのは、OLEDを動作中に更新しようとするとi2c通信が遅くてモーターの回転がカクカクするため。設定画面はOLEDとして、カウントダウンは引き続き7セグに任せることにした。

さて、見て分かるとおりケーブルがもじゃもじゃで液晶も7セグも固定されてないので、極めて使いづらい。
上の写真は何とかケーブルに癖をつけながらカメラのほうを向くように格闘して取った。この数秒後に7セグは台から滑り落ちる。

これを、こんな風に綺麗にアルミケースに収めていい感じにした。

そして動かしてみた。

液晶にちょっと横線入ってしまっててどこかで壊したと思われるんだけどまぁ仕方ない。
じゃあ何が問題かというと。。肝心のステッピングモーターが回らない!
リニアアクチュエーターは温度を測ると90℃だったので通電はしてる。NEMA17も保持トルクは来てて手で回転させようとしても回らない。
惜しいところまでいってるはずなんだけど原因が分からない。結線を間違えたのか、どこかショートしてるのかもパット見は不明。

てことで、諦めた。

別にコイル巻き機を作って何をするって訳でもなくて、どちらかといえば一通り組み上げるという経験を得ることが目的だったので、その意味ではこのプロジェクトは一概に完全失敗とも言えないのではないか。と、自分に言い聞かせておく。
動くに越したことはないけどここからの挽回って割と面倒くさいし、仕事でもないので納得したところでやめていいかなと。


さて、今回の製作に当たっては主にアルミの角穴加工のスキルが身に付いた。
鉄鋼ドリルで穴を空けてタケノコドリルで丸穴を広げたら、そこからニブラーという道具でアルミを噛み切っていく。

ひと噛みが2×6ミリくらいなので多少は時間がかかるけどサクサク切れるのでOLED表示器程度の穴であれば余裕。

あとはヤスリがけ。手持ちのヤスリがこの時点では1本しかなかったので横幅がギリギリだったが、だいぶ歪んだので、ちゃんと細いヤスリも用意しておくべきだった。

てことでこちらのヤスリを購入。Amazonレビューを見て回ってたんだけど海外製の安いのは酷評されてることが多く、ツボサンという日本のヤスリ専門の会社のが良さげだったのでこちらを購入。

中目と細目も買ったら1万円飛んだけど使い勝手はすこぶる良くて、ストレスなくサクサク削れる。


さて、ケース内にはArduino UNOがギリギリ縦に収まった。

これ実はArduinoのハット型ユニバーサル基盤で、上の表示器やボタンと干渉させないために下側にモータードライバを乗せてマイコンのチップが無いほうの隙間を使って収納する形式にしている。

正直もう少し余裕のあるケースだったらこんな苦肉の策を使わなくて済んだんだけど、今回はまさにそういうスキルを獲得したかったので挑戦してみた。

最終的な中身はこんな感じになった。

そして全部つなぐとこうなる。

まぁ、肝心のモーターが回らなかったんだけども。

さて今回得られた学びとしては、ちゃんとパーツごとに単体テストできる形で組むのが良いということと、部品ごとのスペア交換を簡単にできないとダメということ。電源をACアダプタからとったり、同じArduino Unoでもテストに使ったものと今回では若干環境が違うにも拘わらず、理論上は同じ配線をするだけなので失敗は無いと思い込んでいた。
ひょっとしたらモータードライバーの故障かもしれないんだけど、スペースの都合でがっつりハンダ付けしてるし、足曲げまでしてるのでもう取り外してテストもできない。

あとは配線をちゃんと混乱しないように整理することが重要だと思う。今回は途中で頭が混乱したタイミングでExcel管理を始めたんだけど次に何かつくるときは先に何色を何番につないで用途が何でということをちゃんと管理しておきたい。


さて、今回の作成では外部配線にD-Subを使った。シリコンハウスに売られていたのは知ってたんだけど、RS-232Cとかの機器修理用で細々と需要が残っているだけだと思っていたら意外と電子工作で使われているらしくて採用してみた。
普段はD-SUBをRS-232C(9ピン)とかVGA(15ピン)の専用という認識でいたけど、それらは単にRS-232CやVGAという通信規格がコネクタにD-SUB規格を採用しているだけであって、D-SUB自体はただの汎用コネクタらしい。

正直いまどきD-Subなんてと思っていたけども、コネクタ部の機械的強度が確保できるので使いやすくてはんだ付けも楽なので今回の工作で考えを改めた。
D-Sub、なくなると困る。

あと電源まわりについて、今回はモーターを動かすのでケーブルやコネクタの許容電流を調べまわった。
真似する人は多分いないと思うんだけど、いちおうちゃんと調べた方が安全なので注意喚起も兼ねて、私はちゃんと調べましたと書いておくことにする。

ケーブルはAWG28というかなり細めのものを使っているが、メーカーサイトを見ると許容電流3Aと書いてあったのでセーフ。
耐熱被膜で融解温度が高いため3Aでも安全ということだと思う。他のメーカー見てるとAWG28だと1.7Aまでだったり、色々と違うので調べないとまずい。デュポンコネクタも私が買ったのAmazonの購入履歴から製品情報をあたると3Aまでセーフと書いてあった。
パネル付きのDCジャックはマル信の普及品の許容電流が0.5Aしかないので秋月電子で容量の大きいものを購入。プラグのほうは4Aまで対応してるのに謎すぎる。

そもそも日本製より中華製の方が許容電流が大きいのも謎だったんだけど、以下を見て解決した。
akizukidenshi.com

要するに2.1ミリジャックは日本は小型家電用、中国では大型家電に多く使われるので、設計上の違いが出るらしい。なるほど。

ということでツラツラと書き綴ったけども、今回のプロジェクトはこれで打ち切り。
また何か作りたくなったときに今回の経験が活きるはず。

以上。

Arduinoでステッピングモーターを使った自動コイル巻き機の試作

今回はArduinoで自動コイル巻き機を試作したのでご紹介。

巻きあがりのクオリティはこんな感じ。

折り返しのタイミング設定をミスって左端がちょっとダブついてしまったが全体的にかなり密に巻けているのでいい感じ。

動作の様子を動画に収めてみた。(音無し動画)
youtu.be

構成はこんな感じ。

巻き数指定用のボタンはピン数の節約のため5V・GNDのほかにはアナログInput 1つで対応している。
これは抵抗を使った分圧回路で、押されたボタンによって電流の経路が変わるのでアナログInputの電圧が変動する。したがってアナログInputに印加される電圧を計ればどのボタンが押されたのか判別できるという仕組み。

こちらのサイトを参考にさせていただいた。感謝。
synapse.kyoto

当初コイル巻き機を思いついた際はコイル芯となるボルトを回転させるモーターはレゴモーターを想定していた。

なぜかというと、細いモーターシャフトからボルトをがっちり掴むようなものを作る案が無かったから。
レゴなら歯車からブロックパーツに繋げて、最終的に3Dプリントしたアダプタを咬ませればなんとかなる。

ただそれだとレゴマインドストーム本体からモーターを動かす必要があり、Arduinoとの連携が面倒くさい。ボタンで回転検知する方式で考えていたけど、結局シャフトカプラーやシャフトフランジというパーツを知ったことでボルトホルダーの課題が解決し、最終的にNema17という規格のステッピングモーターに落ちついた。

今回使ったのもの。

あとインサートナットの挿入補助具として六角スペーサー類。

意外と真鍮のM3ネジの出番が多かった。

その他、ボルトの反対側の軸受け用にダウエルピンとベアリングを買ったけど、意外と片側だけでしっかりホールド出来てしまったのでいまのところ余らしている。仕上げの段階では使おうと思う。

ボルトホルダーはこんな感じでモデル&スライス。

プリントしたものにインサートナットを差し込む。その際、ネジ付きの六角スペーサーをねじ込んだ状態でハンダゴテで挿し込むと1発で上手く行った。

このあたりのテクニックは以下の記事を参考にさせていただいた。感謝。
burariweb.info

あとはフランジにダウエルピンを挟んで3Dプリントパーツをネジ止め。

木の端材にタケノコドリルで9ミリ穴を空けてボールベアリングをはめ込んで反対側の軸受けとする。

こんな感じで作ってみた。まぁ今回の試作では右だけでホールド出来てしまったんだけども。

さてこちらは前回紹介したリニアスライディングテーブル。

これも結構曲者で、スライド部についてるのは謎の突起のみ。また座面の固定用と思われる穴はスライド用のガイドが邪魔をしてネジが入らず、知恵の輪状態。仕方ないので別途固定具をモデリングして印刷した。

スライド部は木片に穴をあけて突起に挿し込む作戦。

このままだとグラつくしハズレそうということで、上から別の固定具を被せる。

ほんとに被せてるだけだけど、うまく固定できた。


さて、機械部分はそんなところで、あとは配線とコーディング。

まずは7セグ稼働用の部分だけど、配線はこんな感じで電源は別としてデータ通信にはコントローラーがA0のみ、表示器がD2・D3・D4ピンを使う形。

コードはこんな感じ。
7セグモジュール用にライブラリ「LEDDisplay74HC595」を別途zipで入手して導入している。
このコードは巻き数設定のテスト部分なので実際にはモーター駆動ではなくてカウントダウンタイマーになっている。

#include <LEDDisplay74HC595.h>
const int sclkPin = 2;
const int rclkPin = 3;
const int dioPin = 4;
int digits[] = {0,0,0,0};
int cnt = 0;

LEDDisplay74HC595 ledDisplay(sclkPin, rclkPin, dioPin);

void setup() {
  ledDisplay.refresh(0,0);
}


int judge_button_from_voltage(int voltage) {
  switch(voltage) {
    case 0 ... 300:   return -1;
    case 301 ... 550: return 0;
    case 551 ... 700: return 1;
    case 701 ... 780: return 2;
    case 781 ... 850: return 3;
    default:          return -9;
  }
}

void loop() {
  while(analogRead(0)>850){ledDisplay.refresh(cnt, 0);}

  int button = judge_button_from_voltage(analogRead(0));
  if(button>=0){
    if(digits[button]<9){digits[button]++;}else{digits[button]=0;}
    cnt = digits[0]+digits[1]*10+digits[2]*100+digits[3]*1000;
  }

  while(analogRead(0)<850){ledDisplay.refresh(cnt, 0);}

  if(button==-1){
    cnt = count_down(cnt);
    int val = cnt;
    for(int i=0;i<=3;i++){
      digits[i] = (val % 10);
      val /= 10;
    }
    while(analogRead(0)<850){ledDisplay.refresh(cnt, 0);}
  }
}

int count_down(int n){
  unsigned long time;
  while(n>0){
    time = millis();
    while(millis()-time <= 1000){
      ledDisplay.refresh(n,0);
      if(analogRead(0)<850){
        return n;
      }
    }
    n = n - 1;
  }
  return n;
}

面倒くさいのが7セグの扱い。
基本的に1桁ずつ順番に高速に表示を切り替えることで人間の目では複数桁が表示されているように見えるが、プログラム中にDalayなどの待ち時間を入れてしまうとその間は切替が行われないので1桁しか表示されなくなってしまう。

つまり1秒ごとのカウントダウンを作るのも、普通なら1秒のDelayを入れるところ、7セグを使うせいで待ち時間もリフレッシュ命令を出し続けるという処理になっている。

あとは緊急停止用に何らかのボタンが押されるとカウントダウンが止まるようにanalogRead命令も出している。実際にはモーターを動かすので緊急停止処理は必須だ。


次にモーター制御の配線。
配線図作成ソフトfritzingにリニアスライドテーブルが無かったのでどちらも普通のステッピングモーターの図を使用。

まぁ難しいことはモータードライバーがやってくれるので配線はそこまでややこしくならなかった。

コードはこんな感じ。ほんとはクラス使ってステッピングモーターをオブジェクト化したかったけどCPPに詳しくなくてややこしそうだったので今回は構造体で妥協した。

typedef struct {
  uint8_t step_pin;
  uint8_t direction_pin;
} Stepper;

const Stepper linear_actuator{6,7};
const Stepper bolt_rotator{8,9};
const int enable_pin = 5;

int Speed = 800;
int cnt = 0;
int flag = HIGH;

void setup(){
  pinMode(linear_actuator.step_pin,OUTPUT);
  pinMode(linear_actuator.direction_pin,OUTPUT);
  pinMode(bolt_rotator.step_pin,OUTPUT);
  pinMode(bolt_rotator.direction_pin,OUTPUT);
  pinMode(enable_pin,OUTPUT);

  digitalWrite(linear_actuator.direction_pin,LOW);
  digitalWrite(enable_pin,LOW);
  slide(85);
  digitalWrite(enable_pin,HIGH);
  digitalWrite(linear_actuator.direction_pin,HIGH);
  cnt = 0;
}

void rotate() {
  for (int s=1; s <=8; s++){
    for(int i=1; i<=24; i++){
      digitalWrite(bolt_rotator.step_pin,HIGH);
      delayMicroseconds(Speed);
      digitalWrite(bolt_rotator.step_pin,LOW);
      delayMicroseconds(Speed);
    }
      digitalWrite(bolt_rotator.step_pin,HIGH);
      digitalWrite(linear_actuator.step_pin,HIGH);
      delayMicroseconds(Speed);
      digitalWrite(bolt_rotator.step_pin,LOW);
      digitalWrite(linear_actuator.step_pin,LOW);
      delayMicroseconds(Speed);
  }
}

void slide(double millimeter) {
  //8 step
  int steps = 4 * millimeter * 10;
    for (int s=1; s <=steps; s++){
       digitalWrite(linear_actuator.step_pin,HIGH);
       delayMicroseconds(Speed);
       digitalWrite(linear_actuator.step_pin,LOW);
       delayMicroseconds(Speed);
    }
}

void loop() {
  digitalWrite(enable_pin,LOW);
  digitalWrite(linear_actuator.direction_pin,flag);
  rotate();
  digitalWrite(enable_pin,HIGH);
  cnt++;
  if(cnt>=80/0.2){cnt=0;flag=!flag;}
}

Nema17が一周する間にリニアスライダーが0.2ミリ移動するコードになっていて、エナメル線の径が0.2ミリなので理論上は隙間なくコイルが巻かれることになる。まぁ、まさかそんなにうまくいかないと思ってたので冒頭で紹介したような精度が出たのは正直驚いた。


さて、別々に開発したコントローラーとモーター制御を融合させたのが次のコード。

//|IO|>
#include <LEDDisplay74HC595.h>
const int sclkPin = 2;
const int rclkPin = 3;
const int dioPin = 4;
int digits[] = {0,0,0,0};
int cnt = 0;
LEDDisplay74HC595 ledDisplay(sclkPin, rclkPin, dioPin);
//<|IO|

//|Stepper|>
typedef struct {
  uint8_t step_pin;
  uint8_t direction_pin;
} Stepper;

const Stepper linear_actuator{6,7};
const Stepper bolt_rotator{8,9};
const int enable_pin = 5;

int Speed = 800;
int cnt2 = 0;
int flag = HIGH;
//<|Stepper|

//|IO|>
int judge_button_from_voltage(int voltage) {
  switch(voltage) {
    case 0 ... 300:   return -1;
    case 301 ... 550: return 0;
    case 551 ... 700: return 1;
    case 701 ... 780: return 2;
    case 781 ... 850: return 3;
    default:          return -9;
  }
}
//<|IO|


//|Stepper|>
void rotate() {
  for (int s=1; s <=8; s++){
    for(int i=1; i<=24; i++){
      digitalWrite(bolt_rotator.step_pin,HIGH);
      wait_withRefresh();
      digitalWrite(bolt_rotator.step_pin,LOW);
      wait_withRefresh();
    }
      digitalWrite(bolt_rotator.step_pin,HIGH);
      digitalWrite(linear_actuator.step_pin,HIGH);
      wait_withRefresh();
      digitalWrite(bolt_rotator.step_pin,LOW);
      digitalWrite(linear_actuator.step_pin,LOW);
      wait_withRefresh();
  }
}

void wait_withRefresh(){
  unsigned long time = micros();
  while(micros()-time <= Speed){
    ledDisplay.refresh(cnt,0);
  }
}

void slide(double millimeter) {
  //8 step
  int steps = 4 * millimeter * 10;
    for (int s=1; s <=steps; s++){
       digitalWrite(linear_actuator.step_pin,HIGH);
       wait_withRefresh();
       digitalWrite(linear_actuator.step_pin,LOW);
       wait_withRefresh();
    }
}
//<|Stepper|


void setup() {
  ledDisplay.refresh(0,0);

  //|Stepper|>
  pinMode(linear_actuator.step_pin,OUTPUT);
  pinMode(linear_actuator.direction_pin,OUTPUT);
  pinMode(bolt_rotator.step_pin,OUTPUT);
  pinMode(bolt_rotator.direction_pin,OUTPUT);
  pinMode(enable_pin,OUTPUT);

  digitalWrite(linear_actuator.direction_pin,LOW);
  digitalWrite(enable_pin,LOW);
  slide(85);
  digitalWrite(enable_pin,HIGH);
  digitalWrite(linear_actuator.direction_pin,HIGH);
  cnt2 = 0;
  //<|Stepper|
}

void loop() {
  while(analogRead(0)>850){ledDisplay.refresh(cnt, 0);}

  int button = judge_button_from_voltage(analogRead(0));
  if(button>=0){
    if(digits[button]<9){digits[button]++;}else{digits[button]=0;}
    cnt = digits[0]+digits[1]*10+digits[2]*100+digits[3]*1000;
  }

  while(analogRead(0)<850){ledDisplay.refresh(cnt, 0);}

  if(button==-1){
    count_down(&cnt);
    int val = cnt;
    for(int i=0;i<=3;i++){
      digits[i] = (val % 10);
      val /= 10;
    }
    while(analogRead(0)<850){ledDisplay.refresh(cnt, 0);}
  }
}

int count_down(int *n){
  unsigned long time;
  while(*n>0){
    stepping();
    ledDisplay.refresh(*n,0);
    if(analogRead(0)<850){
      return 0;
    }
    *n = *n - 1;
  }
  return 0;
}

//|Stepper|>
void stepping() {
  digitalWrite(enable_pin,LOW);
  digitalWrite(linear_actuator.direction_pin,flag);
  rotate();
  digitalWrite(enable_pin,HIGH);
  cnt2++;
  if(cnt2>=40/0.2){cnt2=0;flag=!flag;}
}
//<|Stepper|

これもモーターの移動中に7セグのリフレッシュが必要だったり、けっこう面倒くさいコードになったけどとりあえずうまく動いてくれた。
心地よい達成感とともに眠気が襲ってきたのでそろそろ筆をおこうと思う。

最後の方かなり雑な紹介になったけども、眠たくて気の利いた締めも思いつかないのでこれにて。

Arduinoでリニアアクチュエーター(D8-MOTOR80)を動かす

現在、自動コイルワインダーを作ろうと思って色々と試作中である。

一応、巻き自体は自動化できてすこぶる快適だが、巻き線カウンターはまだ非稼働で、巻き位置の調整も手動である。

ということで、こんなものを買ってみた。

※厳密にいえばCNCシールドは私が買ったものと違うが、類似品というか完コピ品なのでどれでも同じ。
 ただしドライバーはA4988のものを選択する。DRV8255という上位互換もあるけど結線がA4988と異なり情報も少ないので私からはおススメしない。

それで買ったはいいんだけど最初上手く動かせなくて仕方ないので自分で作ろうと思い試作してみた。

同じサイズの3枚の木片の同じ位置に穴を空け、タミヤのミニ四駆シャフト2本とM3寸切りボルトを差し込だ構造。
両サイドの木片は土台に固定し、真ん中の木片にはナットを埋め込んで瞬間接着剤で固定。土台には固定せず浮かせておく。
そうすると寸切りボルトを回転させたときにナットの付いた真ん中の木片が左右にスライドするという仕組み。
あとはシャフトカプラ(3mm-5mm)という部品で寸切りボルトとステッピングモーターの軸を固定すれば完成。

で、できたのはいいけどこれのために準備していた28BYJ-48というステッピングモーターが減速ギア入りのものだったらしく、あまりに遅すぎたのでボツ。

ちょうどそのころ購入したリニアアクチュエーターのモーターが型番D8-MOTOR80というものであることが判明し、作例が見つかったので再チャレンジすることになった。

参考にさせていただいたサイト↓
zenn.dev

結線はこんな感じで、Arduinoと結合したときにUSB端子が左に向く方角からみて、左上がX軸用なのでここにドライバを差し込んで、そのすぐ右隣りの4つの端子にリニアアクチュエーターのケーブルを上から黒・青・赤・黄の順で繋ぐ。(追記:リセットボタン付近にあるEN/GNDはジャンパーで導通させておく。ちなみにここがHIGHだとモーターへの電源供給が止まり、LOWだと供給される仕組みのようだ。後述の放熱はEnableピンの電圧操作で使うときだけ通電させることで解決できた。)

※モーターに付いているケーブルは恐らくEH端子かXH端子かPH端子だと思われるけど判別できなかったので切り落としてデュポンコネクタを圧着した。

左下の青い端子台はモーター用の電源を繋ぐところで、逆説すると恐らくドライバが壊れるので注意。

あとはArduinoでコードを記載。
前述のサイトのコードを参考に書いてみた。

int Speed = 500;

const int step_pin = 2;
const int direction_pin = 5;

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

  pinMode(step_pin,OUTPUT);
  pinMode(direction_pin,OUTPUT);

  digitalWrite(direction_pin,HIGH);
}

void slide(double millimeter) {
  int steps = 4 * millimeter * 10;
    for (int s=1; s <=steps; s++){
       digitalWrite(step_pin,HIGH);
       delayMicroseconds(Speed);
       digitalWrite(step_pin,LOW);
       delayMicroseconds(Speed);
    }
}

void loop() {
  if(Serial.available()){
    byte buf;
    while (1) {
      if(Serial.available()){
         buf = Serial.read();
      }
      if(buf == 'A'){ 
        digitalWrite(direction_pin,HIGH);
        slide(1);
      } else if(buf == 'B'){
        digitalWrite(direction_pin,LOW);
        slide(1);
      }
    }
  }
}

whileループの中でslide関数にミリメートル指定、0.1mm単位で値を渡すとその距離スライドする仕組み。
計算としては、ステップ角18°なので、360°/18°=1周あたり20ステップ。ネジ山のピッチが0.5mmなので1周0.5mm/20ステップ = 1ステップあたり0.025mm移動。ということで4ステップで0.1ミリの移動。引数がミリメートル単位なので10を掛けて1が指定されると1ミリ進むようにして、実際slide関数の利用時に0.1mm単位で指定可能になっている。

検証で使うときはArduinoエディタからシリアルモニタを起動して、AやBを入力するとその分進む。
たとえばAAAAAAAAAABBBBBBBBBBと入れると左に1センチ動いた後、右に1センチ戻るという動作になる。

0.1ミリ単位で正確に動作しているのでさすがステッピングモーター。
本当は0.025ミリ単位で動けるけどどのみち機構の方がそんな精度でない気がするのでやめておいた。

さて、実際に動かしてみて気づいたのが発熱が結構すごいということ。
9Vで動作中に触ってしまい指に軽微な火傷を負ってしまった。

一応放射温度計で計ってみたが35℃と表示される。金属表面だからそのままでは放射率が低すぎてまともに計測できないのだ。

そこでこんなものを調達。

到着。

塗装。くせぇ。。

1個のために塗装ブース引っ張りだすのも面倒なのでベランダに段ボールを置いて塗装したんだけどベランダで防毒マスク着けるのも不審者感丸出しなので自重した。通報されたらいやだし。

割と綺麗に仕上がった。

そんで計測してみると5.5V時は約60℃、9V時は約100℃に達することが分かった。

動作温度80℃って書いてたので100℃はちょっとヤバめ。
どうやら稼働中よりも停止中の保持トルクの方が電流が強いように見えるので、この後の課題として待機中はモーターへの給電を止めるような制御を考えたいと思う。

まぁとりあえずコイルワインダー作りの役者は揃った。
いつも見通しが立ったら満足してしまうのでいつ作るかは不明だけど興味関心が維持できれば近々作るやもしれない。

まぁ作ったあと使う予定もノープランなんだけども。

以上。

コンデンサの充放電波形をアナログオシロで観測するのに苦労した話

最近オシロスコープの使い方も少し分かってきたのでコンデンサの充放電波形を見てみることにした。

最初に考えたのはこういう回路。

スイッチが左に繋がっている間は電源からコンデンサに充電され、、右に繋げるとコンデンサが放電してLEDが光るという仕組み。
これでコンデンサの両端の電圧をオシロで測ればアッサリと波形が見えると期待したわけだが、全然ダメだった。

調べてみると、アナログオシロでそもそも単発信号を見ようってのは無理があるようだ。
アナログオシロは周期的な信号のうちトリガーによってタイミングよく何度も描画しているので線が見えるという仕組みなので、単発信号だと点が一瞬で移動しておしまいということになる。

ということは、機械的スイッチではなく半導体スイッチを使って電気パルスによって切り替えなければならない。
そこで困ったのが今回やりたいことがON-ONスイッチであるということだ。

ON-OFFならトランジスタのベース・エミッタ間にパルスを流すことで実現できるが、2回路を切り替えるような挙動はどうすればよいのか。

ということで、NOT回路を活用しようとしたのがこちらの。。。

うん。部分消しができなかったのでこうなった。

波形を見てみるとこんな感じ。

放電はそれっぽいけど充電がどうなってんのこれ。

回路シミュレーターで等価回路を作ってみたところ、2つ目のトランジスタのベースが常にON。

つまり失敗である。

色々調べてみると、ベース・エミッタ間にベース抵抗の10倍の抵抗を設けることで、微弱電流でベースが意図せずONになる事象を防げるということが分かった。そして描いてみたのがこちら。

そして実行してみるとこんな感じ。

なんか突入電流が目立っている。

更に調べると、普通のトランジスタではなくMOSFETを使うと良いということも分かった。
MOSFETとは、Metal Oxide Semiconductor Field Effect Transistorの略で、電界効果トランジスタの一種。
電流じゃなくて電圧で制御するトランジスタである。充電がちょっとイイ感じになってきた。

ただON-ON回路として完璧かというと微妙なところ。
このNOT回路は「電気は流れやすい方により多く流れる」という原理で成立しているのだが、流れにくい方にも流れることは流れるのだ。
完璧に作るにはMOSFETの逆の部品が欲しい。
つまり普段は導通し、ゲートに電圧をかけたら不動通になる部品である。

そんで調べたら。。あった。。
てかこれもMOSFET。PチャネルMOSFETというらしい。んで今まで単なるMOSFETだと思ってたのはNチャネルMOSFET。なんだそういうことか。
またトランジスタにNPN型・PNP型の2種類があることは知っていたし、MOSFETにNとPがあることは知っていた。
でも説明を見ても普通はNチャネルだけで十分だとか、あとは機構のややこしい説明ばかりでイマイチ分かって無かったのだ。

そしてN型・P型を組み合わせたのがこちらの回路。

こういうN形とP型の特性を組み合わせたロジックをCMOSといって、Complementary(補完的な) MOSの略。
CMOSの由来は知っていたものの何が補完的なのか意味は分かってなかったが、自分で作ってみて納得した。確かに、相互の特性が逆で補完しあってる。

このP型MOSFET、省電力用はあまり流通しておらず、Amazonでもかなり先になりそうなので秋月電子でZVP2106Aという製品をポチった。
逆にN型MOSFETは2N7000が定番で流通量も多い。Amazonでも翌日配達が多い。

MOSFETは小型・集積化しやすいというわりに流通してるのは電源スイッチング用のゴツいのばかりで普通のトランジスタのようなタイプはかなり少ないようだ。集積化しやすいというのは本当でICとかLSIに微細化されたMOSFETが搭載される一方で、単品としては電源のスイッチング用など大電力と二極化している様子である。

さて、実際に回路を組んでみたのがこちら。

波形はこのとおり、教科書的な綺麗な充放電波形が観測された。

完全に我流なので正しい測定方法なのかどうかは分からない。
そもそもデジタルオシロで単発波形を見れば1発解決だった可能性も高い。ただこういう試行錯誤とか回り道をしたおかげで得られる知識の幅も広がったと思うので、無駄ではなかったと思う。

以上。

電子回路の実験用にトグルスイッチをアルミケースに入れてみた。

電子回路実験をしていて以外と面倒に感じるのがトグルスイッチの準備。

配線むき出しとかブレッドボード直刺しの小さいタイプとかでもいいんだけど、配線が切れたり足が折れたりという心配があって意外とストレスになる。

頻繁に操作する部分なのでもっと大雑把に扱いたい。

一応、ナイフスイッチはがあるんだけどOFF操作に両手を要するのが面倒だ。

そこで今回はON-ONトグルスイッチをアルミケースに入れて汎用スイッチ化することにした。

完成品はこんな感じ。

黒端子と、トグルスイッチが倒れている方向の赤端子が繋がるようになっている。

中身はこんな感じ。

穴開ける際にスイッチと端子の干渉を考えてなくて、危なかった。

赤線がクロスしているけど、トグルスイッチの仕組みとしては倒した向きと逆が通電するようになってるのでこれは仕方ない。

使った部品は以下の3点と、タカチ電機工業 TS型傾斜アルミケース TS-1S。

スイッチは2回路2接点。実際は1回路2接点で足りるんだけど近くのホームセンターで調達したのがコレだった。

ちなみにトグルスイッチはちょっとややこしいので電子工作初めたばかりの方はパーツ屋いく前に極と投について調べておくと良いと思う。
switch-labo.nkkswitches.co.jp

私は最初ON-OFFのイメージしかなかったのでなんで端子こんなに!?!?と混乱した覚えがある。
端子2つのタイプってほとんど選択肢なくて困った。


アルミケースの加工は、丸穴を空けるだけならすこぶる簡単。中学校の図工くらいのノリで出来る。

道具はこんな感じ。

アルミをケースの穴開け位置に木の端材を下敷きにしてポンチを当て、ハンマーで軽く叩くと窪むので、そこに鉄鋼用ビットを挿した電動ドライバーで穴を空ける。そのあとタケノコドリルでパーツが刺さる大きさになるまで穴を広げるだけ。
VesselのUSB充電式のハンディドライバー(電ドラボール)で十分だった。
私が持ってるのは普通の電ドラボールで、280回転/分で電動トルク2N(手動は10Nまで)。

同じ様な見た目でハイスピードタイプと電ドラボールプラスというのがあるけど、使ったことはないので私からは気軽におススメはできない。
ハイスピードタイプは1200回転/分だけどトルクが0.4Nしかないので、ノーマルタイプの1/5しかパワーが出せない。タケノコドリルのように穴が大きくなると接触面積が増えて厳しいと思う。木ネジもノーマルがおススメ。

電ドラボールプラスはUSB-Cになってるのが嬉しい。スピードは3段階調整式だけど、トルクと比例してしまうので低速で高トルクは出せない。これが吉と出るか凶と出るかってとこかな。高速だと勢い余ってネジ穴を舐めやすいので速けりゃいいってものでもない。このあたりは使ってみないと何とも言えないところ。

さて、ドライバーの紹介が長くなってしまったが、最後にテストの様子。


※普通はLEDに抵抗が必要。これは定電流LEDという特殊な代物なので直接5Vを突っ込んでいる。

ということで2023年、一発目の取り組みはアルミケース加工だった。
これ以上ないほどシンプルな作品ではあるが、ここから今後もちょくちょくアルミケースの出番が出てくるかなと思う。
角穴とかもそのうち挑戦してみたいと思う。

以上

使ってみて分かったラグ板のメリット~ダイオードブリッジによる実験用全波整流回路

今回はオシロスコープで全波整流波形を観測するためのダイオードブリッジ回路を作ってみた。

参考にしたのはグーグル検索で見つけたこのPDF
http://chtgkato3.med.hokudai.ac.jp/kougi/ME_practice/MEpractice7p.pdf

どうやら北海道大学医学部の医用工学概論実習のPDFらしい。
内部用のように思えたけどまぁ検索ヒットするから気にしないことにする。

そこで見つけたのがラグ板。

電子パーツ屋で見たことがあるんだが、正直そのときは何に使うものなのか検討も付かなかった。
パーツの足を挿すには穴がデカイし、ブレッドボードみたいに端子同士が繋がってる訳でもない。

色々調べるとどうやら真空管アンプ自作界隈にはわりと馴染みがある代物らしく、ユニバーサル基盤が登場している現在でも現役だそうだ。

kinsmen0411.livedoor.blog


何で今回わざわざ使うことにしたかというと、ラグ板のメリットとして配線が表で完結するので回路を追いやすく、ブログの説明のような用途にうってつけだと考えた為。
大きめの穴も実際に使ってみて納得。複数部品の足をまとめて入れる為だった。


てことで実際の使用例を示す。

まず前回作った半波整流回路がこちら。ダイオード1個と負荷抵抗1個なので回路ってほどのものではない。

これをラグ板に置き換えたのがこちら。

これだけだとまぁ元の方が分かりやすく思える人もいるだろうけど、強度的な問題とかで元のやり方だと回路が複雑になると早々に破綻する。
ラグを端子代わりにできるのでしつかりクリップできて安定感は抜群。

平滑用コンデンサは容量を取り換えて色々実験するのでとりあえず挿し込むだけ。ラグがしっかりしているおかげで空中配線より断然楽だ。

次は全波整流。

回路はこんな感じになっている。

半波整流ではダイオードでマイナス分を捨てることで直流にしていたが全波整流ではダイオードを4つ使ってマイナスをプラスに変換することで直流にしている。回路は複雑になるが電力ロスが減って効率の良い直流変換ができるという理屈だ。

やはりラグ板だと回路が見えるので理解しやすい。金具が大きいのでハンダ付けも結構楽だ。
場所をとるのが若干デメリットではあるけど、昭和レトロ感があって割と気に入った。


さて、正弦波を加えてみると、このとおり山が連なったような波形が出力された。

そこにコンデンサを差し込む。(極性を間違えないよう注意)

すると、割と良い感じに平滑された。

コンデンサの平滑はこんな感じの仕組みになっている。

ダイオードブリッジで得られた直流は電圧の強弱が激しいのでこうやってコンデンサで平滑してやることで電圧が安定した綺麗な直流を取り出すことができた。

ちなみにまだ少し波打ってるが、より容量の大きいコンデンサを使うともっと真っすぐな線になる。

てことで話変わったけど、ラグ板はなかなかいいぞ。

以上。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。