2017年2月27日月曜日

HDC1000をArduinoで使って不快指数計を作る ブレッドボードで実験

ブレッドボード図


HDC1000


温度、湿度が分かれば不快指数が出せるので、秋月で売っているHDC1000というI2C接続の温湿度モジュールを使って、不快指数計を作ってみる。HDC1000は以前7Seg LEDを使って実験したことがある。

Nokia 5110


表示器には不快指数のアイコンを表示できたらな~と思って、aitendoで売っているSPI接続のグラフィックLCDのLCD5110を使ってみた。これもArduinoやNucleoで何度か実験したことがある。

HDC1000は動作電圧が3V~5Vなのでそのまま5V駆動のArduino Unoで使えるが、Nokia 5110は3.3V駆動なので、74HC4050を使ってSPI信号の5V->3.3Vの電圧の変換を行った。(参考:http://dad8893.blogspot.jp/search?q=74HC4050

Nokia5110のライブラリには、Rinky-Dink ElectronisさんのLCD5110_Basic Library を使った。最初は色々なLCDに対応しているu8glibを使ってみたが、LCD5110_Basicは5110のスリープ・モードに対応しているのでこちらにした。

スリープ機能


電池駆動させようと思ったので、消費電力節約のために、AVRのSleep機能を使って見た。使い方は「初心者だけど、一歩ずつ Arduino 超小型マイコン電子工作」さんの記事を参考にした。

オルタナティブのタクトスイッチでスリープモードからの復帰、モーメンタリのスイッチでスリープ有り/無しのモードを切り替える。

自作の簡易電流計で測定したら、

動作時:約44mA
スリープ時:約12mA

となった。Arduinoボード上にLEDがついているのでこれの消費電流がそこそこあるのかもしれない。

HDC1000はI2Cのコマンドを送信しないとスリープモードに入るようなので(←ちゃんとは確認していないです)プログラムでは特には何もしていない。

Arduinoのスケッチ

HDC1000_Thermometer.ino

/*
 * HDC100_Thermometer
 * 
 * 2017.02.26
 * 
 */

#include <Wire.h>
#include <LCD5110_Basic.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>

#define HDC1000_ADDRESS 0x40 /* or 0b1000000 */
#define HDC1000_RDY_PIN A3   /* Data Ready Pin */

#define HDC1000_TEMPERATURE_POINTER     0x00
#define HDC1000_HUMIDITY_POINTER        0x01
#define HDC1000_CONFIGURATION_POINTER   0x02
#define HDC1000_SERIAL_ID1_POINTER      0xfb
#define HDC1000_SERIAL_ID2_POINTER      0xfc
#define HDC1000_SERIAL_ID3_POINTER      0xfd
#define HDC1000_MANUFACTURER_ID_POINTER 0xfe

#define HDC1000_CONFIGURE_MSB 0x10 /* Get both temperature and humidity */
#define HDC1000_CONFIGURE_LSB 0x00 /* 14 bit resolution */

#define WAKEUP_PIN     2
#define SLEEP_MODE_PIN 3
#define BACK_LIGHT_PIN 7

#define WAKEUP_PERIOD 5

LCD5110 myGLCD(8,9,10,11,12);

bool isSleepMode = true;
int count;

extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];

void setup() {
  // Sleep Mode
  pinMode(WAKEUP_PIN, INPUT_PULLUP);
  pinMode(SLEEP_MODE_PIN, INPUT_PULLUP);

  // LCD Power
  pinMode(BACK_LIGHT_PIN, OUTPUT);
  digitalWrite(BACK_LIGHT_PIN, HIGH);

  // LCD
  myGLCD.InitLCD();

  // HDC1000
  Wire.begin();
  pinMode(HDC1000_RDY_PIN, INPUT);
  delay(15); /* Wait for 15ms */
  configure();

  Serial.begin(9600);
  Serial.print("Manufacturer ID = 0x");
  Serial.println(getManufacturerId(), HEX);
  Serial.println();
}

float calcDiscomfort(float temperature, float humidity) {
  return 0.81 * temperature + 0.01 * humidity * (0.99 * temperature - 14.3) + 46.3;
}

void loop() {
  float temperature, humidity, discomfort;
 
  getTemperatureAndHumidity(&temperature, &humidity);
  discomfort = calcDiscomfort(temperature, humidity);
  Serial.print("Temperature = ");
  Serial.print(temperature);
  Serial.print(" degree, Humidity = ");
  Serial.print(humidity);
  Serial.print("%, Discomfort = ");
  Serial.println(discomfort);

  myGLCD.clrScr();
  myGLCD.setFont(BigNumbers);
  myGLCD.printNumF(temperature, 1, RIGHT, 0);
  myGLCD.setFont(MediumNumbers);
  myGLCD.printNumF(humidity, 1, LEFT, 32);
  myGLCD.printNumF(discomfort, 0, RIGHT, 32);
  myGLCD.setFont(SmallFont);
  if (isSleepMode) {
    myGLCD.print("SLP", LEFT, 0);
  } else {
    myGLCD.print("CON", LEFT, 0);
  }

  delay(1000);

  // Check Sleep Mode
  isSleepMode = digitalRead(SLEEP_MODE_PIN);

  // Sleep
  if (isSleepMode) {
    count++;
    if (count >= WAKEUP_PERIOD) {
      Serial.println("Sleep mode start!!");
      count = 0;
  
      sleepAndWakeup(WAKEUP_PIN);
    }
  }
}

//-----------------------------------------------------------------------------------------------
// Sleep Mode
//-----------------------------------------------------------------------------------------------
void wakeup() {
  Serial.println("Wakeup!!");
}

int sleepAndWakeup(int interruptNo) {
  Serial.println("sleepAndWake Process start!!");
  if (digitalRead(WAKEUP_PIN) == LOW) {
    Serial.println("WAKEUP_PIN Low Level");
  } else {
    Serial.println("WAKEUP_PIN High Level");
  }
  Serial.println("sleep enable");
  delay(100);

  // Sleep
  digitalWrite(BACK_LIGHT_PIN, LOW);
  myGLCD.enableSleep();
  attachInterrupt(digitalPinToInterrupt(interruptNo), wakeup, FALLING);
  noInterrupts();
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  interrupts();
  sleep_cpu();

  // Wakeup
  sleep_disable();
  detachInterrupt(digitalPinToInterrupt(interruptNo));
  digitalWrite(BACK_LIGHT_PIN, HIGH);
  myGLCD.disableSleep();
  
  return 0;
}

//-----------------------------------------------------------------------------------------------
// HDC1000
//-----------------------------------------------------------------------------------------------
void configure() {
  Wire.beginTransmission(HDC1000_ADDRESS);
  Wire.write(HDC1000_CONFIGURATION_POINTER);
  Wire.write(HDC1000_CONFIGURE_MSB);
  Wire.write(HDC1000_CONFIGURE_LSB);
  Wire.endTransmission();
}

int getManufacturerId() {
  int manufacturerId;

  Wire.beginTransmission(HDC1000_ADDRESS);
  Wire.write(HDC1000_MANUFACTURER_ID_POINTER);
  Wire.endTransmission();

  Wire.requestFrom(HDC1000_ADDRESS, 2);
  while (Wire.available() < 2) {
    ;
  }

  manufacturerId = Wire.read() << 8;
  manufacturerId |= Wire.read();

  return manufacturerId;
}

void getTemperatureAndHumidity(float *temperature, float *humidity) {
  unsigned int tData, hData;

  Wire.beginTransmission(HDC1000_ADDRESS);
  Wire.write(HDC1000_TEMPERATURE_POINTER);
  Wire.endTransmission();

  while (digitalRead(HDC1000_RDY_PIN) == HIGH) {
    ;
  }

  Wire.requestFrom(HDC1000_ADDRESS, 4);
  while (Wire.available() < 4) {
    ;
  }

  tData = Wire.read() << 8;
  tData |= Wire.read();

  hData = Wire.read() << 8;
  hData |= Wire.read();

  *temperature = tData / 65536.0 * 165.0 - 40.0;
  *humidity = hData / 65536.0 * 100.0;
}


Arduinoで書き込んだAVRを生で使う


Arduinoはプログラムを書くのが楽でいいんだが、そのまま使うとお金もかかるし場所も取るのでArduinoからATMega328Pを取り外して、Fuse Bitを書き換えて内蔵RCクロックで動作するようにして動くかどうか試してみた。

Arduino Unoは外付け水晶振動子で16MHzで動いているが、Fuse Bitで内蔵RC1MHzに設定してやると遅~いスピードで動作するようだ。

Arduino Unoで使う場合のFuse Bit

h: D6
l: FF
e: 05

内蔵RC(1MHz)で使ったFuse Bit

h: D9
l: 62
e: ff(←書き込み時)

I2C、SPIの通信速度もあるので、もうちょっと検証が必要。

Arduinoから取り外してクロック数が少ない内蔵RCをクロックとして使えば消費電流も少なくて済むし3.3V駆動もできるので電池で使うにはよさそう。

3.3V駆動できれば、LCDのロジックレベル変換用に使っている74HC4050も不要になる。

メモ:

Sleep時にはLCDのバックライトだけでなく、AVR以外の電源をバッサリ切るようにする?⇛復帰時にデバイスの初期化をし直さないとだめ?

外部電源(3.3V)が使える場合は、UART通信できるようにしておく?⇛3.3VLDO+USBシリアル変換

Arduino Pro mini(8MHz)も参考にする?

2017年2月25日土曜日

LME49600ヘッドホンアンプ Ver.2 ケース内配線

電源周りの配線を少し整理してみた。


ポップ音対策

電源スイッチの近くに並列にコンデンサを入れれば?と思ったのだが、そもそもデカップリング・コンデンサで電源まわりに並列にコンデンサが入っている。逆に電源ラインのパワースイッチの後に直列にインダクタを入れたら?と思ってやってみた。

参考「Wikipedia: 突入電流-主な対策

10uH(ESR:0.12Ω程度)のインダクタを正負ともに挟んで入れてみたが、ポップ音は改善されなかった。

一応出力波形をとっておいた。(ヘッドホンをつないで測定)

電源電圧: +6.37V/-6.37V

インダクタなし

ch1:R-channel ch2:L-channel

インダクタあり

波形で見るとなんとなく良くなっているように見えるが、スイッチのON/OFFのタイミングでようすは異なり、電源をON/OFFしたときにブチる。

ポップ音対策はWebを見て回った限り、遅延回路を作ってリレーで出力のON/OFFを切り替えないとだめなようだ。

ケースにつけていたパイロットランプ用のLEDをつかえるようにする


基板上にLEDの電流制限抵抗を入れてケースにつけているLEDが点灯するようにしてみた。

回路図

基板図

Github:
https://github.com/ryood/LME49600_HPA_V2

2017年2月21日火曜日

16桁x2行のキャラクタLCD(HD44780互換)のフォントの互換性

以前、aitendoのキャラクタLCDは上位バイトがおかしいというようなことを書きましたが、Arduinoでテストしたところ秋月、共立、aitendoのものでほとんど差異はなかった。

ブレッドボード図


左が秋月、右がaitendo

ロータリーエンコーダーで文字コードを選択して、キャラクタLCDに表示する。2系統用意して、同一のロータリーエンコーダーで2系統とも同じ文字コードを選択できるようにした。

ロータリーエンコーダーの読み取りがずれるので、タクトスイッチを押すと0x00に戻るようにした。

Arduinoのスケッチ LCD_FontTest.ino

/*
   LCD RS pin to digital pin 12
   LCD Enable pin to digital pin 11
   LCD D4 pin to digital pin 5
   LCD D5 pin to digital pin 4
   LCD D6 pin to digital pin 3
   LCD D7 pin to digital pin 2
   LCD R/W pin to ground
   LCD VSS pin to ground
   LCD VCC pin to 5V
   10K resistor:
   ends to +5V and ground
   wiper to LCD VO pin (pin 3)

   RotaryEncoder A 9
   RotaryEncoder B 8
   RotaryEncoder C GND

   TactSW 10
*/

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

const int clearBtn = 10;
const int RE_A = 9;
const int RE_B = 8;

uint8_t charCode = 0x00;

// Rotary Encoderの読み取り akizuki/Alps
int readRE()
{
  static uint8_t index;
  int retVal = 0;
  index = (index << 2) | (digitalRead(RE_B) << 1) | (digitalRead(RE_A));
  index &= 0b1111;
  switch (index) {
  // 時計回り
  case 0b0111:  // 01 -> 11
    retVal = 1;
    break;
  // 反時計回り
  case 0b1101:  // 11 -> 01
    retVal = -1;
    break;
  }
  delay(1);  // (とりあえず)チャタリング防止
  return retVal;
}

void setup() {
  pinMode(clearBtn, INPUT_PULLUP);
  pinMode(RE_A, INPUT_PULLUP);
  pinMode(RE_B, INPUT_PULLUP);

  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("LCD Char Font");

  delay(1000);
  lcd.clear();
}

void loop() {
  if (digitalRead(clearBtn) == 0) {
    charCode = 0;
  }
  charCode += readRE() * 16;

  lcd.home();
  lcd.print(charCode, HEX);
  lcd.print(":");
  lcd.print(charCode + 15, HEX);
  lcd.print("      ");
  
  lcd.setCursor(0, 1);
  for (int i = 0; i < 16; i++) {
    lcd.write(charCode + i);
  }
}

0x00~0x0Fで表示されるキャラクタは違うが(←ユーザー指定フォント用?)、秋月共立aitendoとも秋月のDATASHEETに記載されているフォントが表示された。


秋月の16桁x2行のキャラクタLCD(HD44780)をブレッドボードで使いやすくしてみる 製作編

せっかく、なのでよくあるHD44780互換のキャラクタLCDの一列ピンのものと差し替えられるようにしてみた。

回路図

基板図

一般的なLCDのピン配列と互換にしようと思うと配線が交差して配線しにくいので簡単なところだけはんだ面で配線して、残りはジュンフロン線を使って成り行きで配線することにした。

また、DB0(P7)~DB3(P10)はほとんど使わないので(だいたい4bitモードで使う)配線しないことにした。

部品面(LCDを載せた)

部品面(LCDなし)

はんだ面

こういう配線の仕方でも、Eagleで配線しておくと、Ealgeの基板エディタの「show」ツール(ツールバーの「目」のマーク)を使うと、つながっているポイントがハイライト表示されるので、Eagleで作図しておくと便利だ。


ブレッドボードに載せて表示させたところ

Github:
https://github.com/ryood/Akizuki_LCD1602

Eagleのパーツ:
https://github.com/ryood/EAGLE_Library内のAK_SC1602

メモ:


買ってから全然使っていなくて、なんとかブレッドボードでも気軽に使えるようにしてみようと思ってやってみたが、結構めんどくさい(^q^;

素直にaitendoやamazonの中華製の方がコスパはいい。

2017年2月19日日曜日

秋月の16桁x2行のキャラクタLCD(HD44780)をブレッドボードで使いやすくしてみる構想

秋月で売られているキャラクタ表示のLCD をもう少し使いたくなったので考えてみた。

ぴゅんぴゅん2号で使ってみたのだが、ピン配列が鬼すぎてブレッドボードやユニバーサル基板上に載せると収まりが悪すぎて、最近は一列にピンが出ているaitendoのを使うようになっていた。

だがしかし、aitendoのLCDは英語(7bit)ならいいのだが、8bit目を入れると文字が何かわからない表示になってしまって、HD44780コンパチブルとは言いにくい。

<追記:2017.02.21>
参考「16桁x2行のキャラクタLCD(HD44780互換)のフォントの互換性
</追記>

秋月のLCDを1列配線にするように考えてみたが、わざとブレッドボードで使いにくくしてるのか?と思うぐらい複雑な配線になってしまった。





2017年2月16日木曜日

LME49600ヘッドホンアンプ Ver.2 LME49720のノイズ対策にアルミ・ケースに入れてみた。

随分前に作って全然使っていないしょぼいステレオ・アンプをばらして、ケース(Takachi YM-150)だけ再利用してLME49600HPAの基板を格納してみた。


もともと開けていた穴を再利用しているので見てくれは悪い。


LME49720をつかってiPad 3で再生した場合のノイズ


金属ケースに収めたので、多少よくなっているかも?と思ったが、やはりiPadがWifiアクセスするタイミングでノイズが乗る。

以前作ったchumoy(非反転増幅回路一発)にLME49720を入れて同様にテストしてみた。



やはりLME49720だとWifiアクセス中にノイズが乗る。ボリュームを完全に絞ってもノイズが出るので、音声入力系からのノイズではなく、とんでもないところからノイズを拾っているような気がする。

LME49600HPAもChumoyも電池駆動で、iPadもバッテリ駆動にして試している。

chumoyでもOPA2134にするとノイズは乗らない。

LME49720のDATASHEETを見ると
■ スルーレート ± 20V/μs (typ)
■ ゲイン帯域幅積 55MHz (typ)
と高スペックなのでこの辺が関係してるんだろうか?

OPA2604はノイズが乗らず
GBW 20MHz
Slew Rate 25V/us
MUSE8920はノイズが乗る
GBW 11MHz
Slew Rate 25V/us
OPA2134もOPA2604もFET入力だし、入力インピーダンスの高いFET入力のOPAMPだと必ずノイズが乗るというわけでもなさそうだ。

こだわると深みにはまりそうなので一旦保留(^q^;

メモ:


使い回しのケースですが、常用できそうなので、これと同じケースでトランスを使った電源を作る方向で考える。(電池がもったいないですし)

入力ジャックだけ接地タイプのものを使ってケースにアースしてるつもりだが、導通を再確認。調べてみるとアルマイトは絶縁らしいので削らないとだめ?

<追記:2017.02.18>
ジャックの取付用に開けた穴の断面で導通しているようで、ケースにアースされていました。
</追記>

入力ボリューム調整用に使っているPOTがスイッチ付きにやつなので、オーディオ・グレードの(安めの)POTを仕入れて交換。

ケースにつけているLEDが未使用なので、スイッチのON/OFFで点灯するようにする。両電源なのでV+/V-の間につければいいのか?

電源スイッチのON/OFFでのポップ音がひどいので、対策を考える。スイッチに並列にコンデンサを入れたら改善する?

PCM2704を使ったDACをつなぐことも考えておく。

2017年2月14日火曜日

mbed InterruptInのテスト

割り込み入力のInterruptInは「Nucleo F401REでmbedのInterruptInが動作しない。」でスイッチの割込みを試してみたが、外部信号で割込みをかけるテストをしてみた。


自作の「矩形波だけのファンクションジェネレータ」で矩形波を出力して、割込みをかけた。

main.cpp

#include "mbed.h"
#include "rtos.h"

DigitalOut led(LED1);

InterruptIn Int1(PC_4);

void flip()
{
    led = !led;
}
    
int main()
{
    printf("InterruptIn_Test2\n");
    Int1.rise(&flip);
    
    while(1) {
        Thread::wait(1);
    }
}

割り込み信号のRising Edgeで割り込みをかけ、LEDを反転させている。


ch1:割込み信号 ch2:LEDへの出力

Int1.fall(&flip); としてFalling Edgeも試したが動作した。


ベースマシン ファームウェアのメンテ mbed-rtosのRevisionとOscController Classの分離

mbedとmbed-rtosのRevision

今回、ファームウェアをいじる前に

mbed Rev 121
mbed-rtos Rev 117

で、コンパイルするとコンパイル・エラーが発生してしまった。

mbed-rtosのHistoryを見ると、最新のRevisionは

Rev.123 Configure RTOS to behave as it did before 5.0
Rev.122 Remove mbed_lib.json to fix crashes

となっている。

mbed OS 5がリリースされたころに2.0のmbed-rtosがらみでかなり混乱した。

参考:「ベースマシンの全体をつないでmbedでつまずく。

Rev.122の「mbed_lib.json」という文言もどこかで見た記憶がある。

改善されてるのかも?と思って

mbed Rev 135
mbed-rtos Rev 123

にしてコンパイルすると、Warningは大量に出るが、無事コンパイルでき動作もOKだった。

今後はこのバージョンで開発続行する予定。

OscControllerの分離


DCOの制御をSequeceSenderクラスで行っていたのを、OscControllerというクラスを新たに作って分離した。

mbed repository
https://developer.mbed.org/users/ryood/code/BaseMachine/ Revison 22

2017年2月11日土曜日

LME49600ヘッドホンアンプ Ver.2 iPadで使ったときのノイズ問題

USB Audio I/Fで出力していま製作中のLME49600HPAで聴いている分には良かった気がしたのだが、iPad 3につないで再生してみると猛烈ににノイズが乗ってしまって、愕然とした。

ちょっとしたノイズではなくて、ギュルギュル~とかブチブチっとか、もう完全にアウトなわけです(TqT;

ヘッドホンをHPAを介さずに直接iPad 3に接続するとこのようなノイズは出ないので、正直敗北宣言しようかと。

また、やり直しか~と思って一晩寝て起きて、いろいろ調べてみると

  • USB Audio I/Fでは問題なくて、iPad 3につないだときにノイズが出る。
  • 曲の切り替わりあたりでジージーノイズが発生後、ギュルギュルノイズ。
  • 曲はiPad 3のローカル・ファイルから再生しているのではなく、WifiのSamba経由で拾ってきている。

変換プラグが原因?かと思ってケーブルを作製


iPad 3のオーディオ出力端子は3.5φのステレオ・ミニプラグで、いま作製中のHPAは6.3φのステレオ・標準プラグにしている。このタイプのケーブルは作っていなかったので、持ってる中では一番信頼性の高いcanareのステレオ・ミニプラグ同士のケーブルに、ステレオ・ミニ→ステレオ・標準変換プラグをかまして接続していた。


変換プラグが怪しいのかも?と思ったが、普通のステレオ・ミニプラグに使える太さの2芯のシールドケーブルの手持ちが無かったので、断線したヘッドホンのケーブル(Sony MDR-CD900STのやつ)から使えそうな部分だけ切り出して、ストックしてあったプラグでステレオ3.5φ<->6.3φのシールドケーブルを作った。

※ちなみに、画像のステレオ・ミニ<->ステレオ・ミニのケーブルで使っているプラグはcanareのF-11F-12というもので、φ6mmのケーブルが使えて、作りも頑丈。値段も400円ぐらいでおすすめです。


↑ケーブルの被覆が劣化していてベチョベチョになっている(^q^;

オーディオ用途の音量調節用のPOTは品質の高いものを使うべきか?


試作なので、手持ちにあった50kΩ/AカーブのやっすいPOTを使っていた。これが曲者で、入力が無音(ほぼ0V?)の場合でもPOTの位置によってノイズが乗っていた。定量的に調べたわけではないが、耳で聴いていてわかるレベルのノイズだ。

これを、2回路Aカーブで手持ちにあったAlps製の10kΩ/Aのものを使うようにしてみた。(と言っても200円ぐらいのもの)


↑ぐちゃぐちゃしてますが、ケースの前面の入力端子はバイパスしてAlps製のPOT(胴体が緑色)を経由して入力しています。

50kΩから10kΩに入力インピーダンスが下がるので、出力側の駆動力が必要になるが。。。

ヘッドホンアンプの入力インピーダンス


いやそもそもiPadのヘッドホン出力から音声信号を受けいているのだから、普通は32Ωぐらいは駆動できるはずだよな。

実は、iPad 3のオーディオ出力はヘッドホンを想定していてある程度電流をながして使うことを想定してチューニングしているのでは?

と思って、DACとうを搭載していない市販のアナログ入力のポタアンを調べてみると、共立の「オペアンプ切り替え可能 ポータブルヘッドフォンアンプ」という製品を見つけた。

仕様をみると、なんと入力インピーダンスは100Ωになっている。

実験


以上で改良できるかもと思って実験したところ、確かに曲間の(Wifiアクセス中と思われる)ノイズは減ったし、ギュルギュルノイズは出なくなった。

だがしかし、曲間のノイズは依然として発生している。

OPAMPを差し替えて音質チェックしてみるか~と思って、増幅&DCオフセット・サーボに使っているOPAMPのLME49720をオーディオ用途で困ったらコレと言われている(←自分の中では)OPA2134に差し替えると、完全に耳に聴こえるノイズはなくなった(@@;

メモ:


入力ボリュームと並列に抵抗を入れると入力インピーダンスを調整できる。試しにやってみたが、100ΩのRを入れて100Ω//10kΩ=99Ωの入力インピーダンスでもLME49720ではノイズは乗る。

LME49720でchumoy構成のHPAと比較してみる?

ハンダの使用感 日本アルミット、Kester、goot

今まで使ってみたハンダの使用感をまとめておきます。音質とうは比較していないので作業性のみです。

goot SE-06008

電子工作を始めた頃に、ホームセンターで購入してそのままリピートして使い続けてきた。チップ部品用と書いてあるが、ユニバーサル基板やプリント基板でスルーホールの部品でも、特に問題なくはんだ付けできる。6.3φのフォンプラグとう大きめの端子でもジュルジュル送り込んでやれば使える。

10年前に使ったものを今見ても経年劣化しているようすも特にない。

所感としてはオーソドックスで使いやすく、\787@共立と値段も安い。

Kester44 1.0φ 

去年の正月に買った共立の福袋に入っていた。エレキ・ギターの中のはんだ付けにはこれを使っている人が多いと思う。

かなり溶けやすくて、1.0φと太く、ヤニも大量に入っているので、ユニバーサル基板で使うと細かいところのはんだ付けがしにくい。

はんだ付け後にヤニでベタベタになるので、個人的には基板で使うのには向いていないと思う。あんまり使っていないが、大きめの端子類のはんだ付けの作業性は良いと思う。

日本アルミット KR-19 RMA(0.8mm) 

「NASA航空宇宙産業の必需品」という胡散臭いうたい文句で、秋月でも\1,250と高いので、最近やっと使いはじめてみた。

信頼性はまだわからないが、作業性はgootの2割り増しぐらいな感じだ。溶けやすいのにヤニでベタることも少ない。表面実装部品を手ハンダしたり、ユニバーサル基板でチマチマ配線するのにはかなり有効だと思う。

ハンダが回ったタイミングできっちりテカってくれるので、はんだ付け作業も楽しくなる。

欠点としてはちょっと高い。と、言ってもKester44と同程度ですが。

同じ値段で、「世界最高の品質」と銘打っているKR-19というタイプもある。今使ってるのが少なくなってきたら試してみるつもりです。

フルカワエレクトロンさんの記事も読んでいてなかなか興味深いです。


左がgoot、右が日本アルミット

共立の福袋に入っていた金、プラチナ、銀入りのハンダはもったいなくてまだ使っていない(^q^;

2017年2月9日木曜日

JASRACと囲碁とAI

JASRACが楽曲の著作権を主張しているそうだが、楽曲は例えばCDなら48kHz/16bitの組み合わせに過ぎない。

1サンプルは48kHzの逆数の約20.83us。

1分の楽曲(ピコ太郎より長い)を考えると、

60s / 20.83us = 2,880,460(サンプル)

これに16bitを乗算するので

2,880,460 * 2^16

通りの組み合わせになる。

天文学的数字に見えるが、もはやそうでもない。関数電卓で計算できる範囲だ。

囲碁はコンピュータが人間に勝てるとは思えないと言われていたが、Alpha Goで一転した。

囲碁の棋譜を見ればわかるが、碁盤の19x19の着手点の中の一つを選ぶ作業を白黒交互に300手ぐらい繰り返しているだけだ。

同じ着手点に打つ場合やコウなどの禁止ルールを無視して300手で考えると

(19 * 19) ^ 300 = 361 ^ 300

これは普通の関数電卓ではエラーになってしまって計算できない。

この莫大な選択肢の中で正解(神の手)に一番近い解答を出している世界のトップ・プロ棋士がAlpha Goに負けてしまっている。

囲碁は大事なところで一手間違うと負けるが、楽曲で大事な1bitはあるのだろうか。

はたしてカラオケや音楽教室で音符をなぞることが著作者の権利を侵害しているのかどうか。

※今考えただけなので間違ってるかもしれません。

2017年2月8日水曜日

PSoC 4 Prototyping KitのUSB接続を外付けにして書き込みしやすくる。

PSoC 4 Prototyping Kitは600円@秋月で安くていいのだが、USB端子的な端子の接触が甘くて、パソコンとのUSBの接続がうまくいかない場合が多い。

PSoC 4 Prototyping Kitは「I2CをやるためにPSoC 4 Prototyping Kitを使ってみた」で書いた通り、ボード上のタクトスイッチを押しながらUSBを抜き差しするとプログラミングモードになるのだが、USBの認識で失敗することが多い。

接続に失敗するとパソコンの再起動が必要となり、かなり困るので、mini-USBのDIP化キットとモーメンタルのタクトスイッチを使って接続しやすくすることを考えてみた。

まず、USB-Serial Bridgeの部分を折って、本体と切り離して本体とつなぐホールにピンヘッダをはんだ付けする。

USB端子的なところに線材をはんだ付けして線材の逆側をブレッドボード/ピン・ソケットに挿せるように加工する。いつもやっているようにQIピンを圧着して、熱収縮チューブで導体の露出部分をカバーした。

GND、D+、D-だけでよく、VBUS(プラス電源)は逆側のピンヘッダの方から供給する。


配線図


配線は大して手間ではないので、毎回ブレッドボードで組むことにする。

ブレッドボード上のタクトスイッチで電源をオフにして、PSoC 4 Prototyping Kit上のタクトスイッチを押しながら電源をオンにすると、プログラミング・モードに入る。

PSoC 4 Prototyping Kit上のタクトスイッチを押さない状態で電源オン/オフすれば通常モードで起動する。

プログラミングされるPSoC Prototyping Kitとは、P4.0(RX)/P4.1(TX)の2線だけ(と電源のVDD/GND)なので回路に組み込んだ状態でもP4.0/P4.1にアクセスできればプログラミングできると思う。

LME49600ヘッドホンアンプ Ver.2 でけた(と思いたい)

Ver.1は、おそらくはんだ付けが甘いせいで動作が不安定だったので、基板設計をやり直して再びユニバーサル基板で組んでみた。主な変更点は、

  • 2層目(ジャンパ)を部品面で配線する。
  • デカップリング・コンデンサに、あまり特性が良くなさそうなタンタル電解ではなくオーディオ用のアルミ電解を使用。
  • デカップリング・コンデンサに使っていた0.1uFのフィルムコンデンサを小型の積層セラミックコンデンサに変更。(配線の都合上)

回路図

基板図

部品面(LME49600を外した状態)

部品面(LME49600を挿入した状態)

ハンダ面

仮のケースに収納


別記事に記載しますが、Ver.1は糸ハンダにKester44の1mmを使っていて、今回はalmit KR-19RMAAの0.8mmをつかっている。作業性は断然almitの方がよかった。

部品面のジャンパー線はブレッドボードのジャンパー線に使えるタイプの単芯のビニル線(H-PVC 0.65mm)で、あらかじめ幅をあわせて作っておいて、抵抗等背の低い部品をはんだ付けするときに一緒に配線した。

基板へのはんだ付け作業だけで1日4時間程度で2日かかった。(それ以外は寝てるか、酒飲んで荒れてるかだった)

出力波形


自作のPCM5102を使ったファンクションジェネレータの1kHzのサイン波を入力して、無負荷の時と、47Ωの負荷抵抗を入れた場合の出力波形をオシロで見てみた。

増幅、DCキャンセル・サーボ用のOPAMPにはNJM4580を使用した。


入出力端子類はバイパスして測定。

電源電圧:+6.43V -6.45V

無負荷時

ch1:R-Channel ch2:L-Channel

47Ω負荷時

同、拡大

出力電圧の低下はほとんどない。怪しそうなノイズも乗っていない(と思う)。

WaveSpectra+WaveGeneでTHD、THD+Nの測定


WaveGeneで1kHzのサイン波を生成してUSB Audio I/FのTASCAM US-144MKII(96kHz/24bit)のPHONEから出力し、出力が約500mVp-pになるようにPHONEの出力ボリュームを調節。

LoopBack/LME49600HPAの出力をUS-144MKIIのMIC/LINE(入力インピーダンス15kΩ)に入力して、WaveSpectraのRMS表示値が-20dBになるように入力ボリュームを調節して、THD、THD+Nを測定してみた。

LME49600HPAは3倍増幅なので、入力レベルを合わせると、LoopBackがAudio I/FのUS-144MKIIの入力部での増幅、LME49600HPAはNJM4580での増幅+LME49600でのバッファリングの差になる。

入出力波形

ch1:入力 ch2:出力

ch1(入力)が504.0mv(p-p)、ch2(出力)が1.460v(p-p)となっているので約3倍の増幅。

LoopBack(-20dB)

THD   0.00670%
THD+N 0.02085%

LME49600HPA/NJM4580使用(-20dB)

THD   0.00588%
THD+N 0.01831%

LoopBackの場合より、LME49600HPAの方が、THD、THD+Nの値が良くなっている。

LoopBack(-30dB)

US-144MKIIの入出力ボリュームをそのままにしてLME49600HPAを外してLoopBackさせたもの。


THD   0.00312%
THD+N 0.04588%

THDはLME49600HPAを通した場合より良い。NJM4580の歪分かな?増幅前なのでノイズ・フロアはLME49600HPAを通した場合の方が良い。

WaveSpectra+WaveGeneで周波数特性を見てみる。


WaveGeneのユーザー波形で「FLATSWEEP_032768.WAV」を指定し、WaveSpectraのFFT設定でサンプルデータ数32768、窓関数なし(矩形)を指定。

LoopBack

LME49600HPA

周波数特性は差がない。←可聴帯域では劣化なし

Github:
https://github.com/ryood/LME49600_HPA_V2

メモ:


今回もまた出来たばっかりなので、正確な判断は出来ていないと思うが、やはりクラシックよりEDMの方が聴いていて気持ちいい。計測結果を見ると特に変なところもなさそうなので、LME49600をこの回路構成で使うとEDMに向いているのかもしれない。

電源電圧±6V、コンデンサでACカップリングしていなくて、LME49600のスピード(スルーレート)がチートレベルに速く、駆動力も十分なので、USB Audio I/Fのヘッドホン出力よりも低域の締りが良くなっているのが顕著にわかるのかも。

もしくはおっさん耳がさらに劣化してクラシックの高域(空気感)がよくわからなくなっているのか、使っているヘッドホン(SONY MDR-CD900ST)のドライバが経年劣化しているのか。

そのうち、OPAMPを差し替えたり、以前作ったchumoyと比較したりしてもう少し測定してみる予定。

2017年2月2日木曜日

LME49600ヘッドホンアンプ Ver.2 基板設計

LME49600ヘッドホンアンプの基板設計をやり直した。ジャンパをポリウレタン線をハンダ面で這わすのではなく、太めの線材を部品面で配線する。

回路図

基板図

部品並べ(LME49600を外した状態)

部品並べ(LME49600を挿入した状態)