6/21日曜日の夕方、日本では部分日食が見られるようだ。
台湾では金環食になるとのこと。
出力先が単純な負荷ではなく、電池などの場合、逆接続が破壊的な結果につながることがあるので、保護回路としてダイオードが使われることがある。でも、ダイオードの順方向電圧降下もロスだから低減したいときの保護回路のメモを記録。
すごく前に鉛電池への充電回路で友人からこんなのあるよって言われたものである。
回路図はこのようなもの。1Ωから右が負荷だと思ってください。PMOSとNPNトランジスタ、ダイオードで構成されます。電圧が高い場合、MOSFETのゲート保護が必要なのでこれは別途考えてください。
V2に今10Vが設定されていますが、-20Vから+20Vまで電圧掃引するようにシミュレーションすると下のようになります。1Ωに流れる電流が緑。黄土色はMOSFETの発熱です。
V2が負の電圧の際には電流が出力されませんが、電圧が正になると電流が流れるようになります。MOSFETのゲート電圧、BJTのVBEの都合、ゼロクロスしませんがので理想ダイオードにはなりません。ただ回路の保護回路としては十分な性能ではないでしょうか。
注意点としては「逆流阻止」ではないため、バッテリーからの逆流電流は流れてしまいます。上記12Vで電流がゼロになって、それ以上の電圧はV2からV1に電流が流れています。
6/8から6/10の3日間の連続測定データを気象庁のデータと比較してみた。
自宅測定は測定値+3hPaを標高補正としている(実際には温度などを加味する必要があるがとりあえず無視する。
結果的にはMPL3115A2の精度はかなりよいことがわかる。自宅の標高を国土地理院の地図で確認すると2Pa程度の気圧減少になると思うのだが、それを加味するとセンサーの偏差は1hPaとなる。
データシートでは±0.4kPa(=4hPa)が誤差なので十分許容できる値である。
こんなに精度高いと面白いね。
測定期間を延長してみた。6/14
6/20 3時くらい、追記
6/25追記
去年のGWに車中泊ツーリング(車)で四国を回ったとき、社内で100Vがほしいなと思って道中で購入した車載インバーター。
車両の12Vから100Vに変換してデジカメの充電をするのが目的だったのでぶっちゃけなんでも良かったし、150Wも出力はいらなかった。買ってから気がついたが空冷のファンがついている。
このファンが、嫌なノイズを出すのだ。静かなファンにしてほしい。とはいえ、もう買ったのでファンを自分で交換できるのか確認する。
蓋をあける。外観でギザギザしているからてっきり金属かとおもったら、プラスチックでできていて、凹凸はただの模様だった。トランスの横にあるアルミのヒートシンクに低圧MOSFETがついている。そして、手前側には高圧のMOSFETが4つ。ヒューズはブレードのものが直付け。
肝心のファン。
12V 0.06Aで40mm×40mm×20mmのもの。類似品で静かなものに変更すればきっといいだろう。
ばらしたついでに中身を見ていく。
ICF KA7500BD スイッチング電源制御のICのようだ。FairchildのKA7500Bと同等だろうか。SMPS(Switching Mode Power Supply)のICとある。
AZ7500BP 多分上で示したICと同じ機能の部品。なぜだろうか。裏の配線は追ってないからわからない。
低圧MOSFET
75V 80Aという代物。
高圧?MOSFET
JCS630CA 200V 9A、出力側の制御かな。
入力にはヒューズが直付けで搭載。傾いているが、機能としては十分だろう。
当初のファンのうるささの解消のためにはファンの換装が必要だろう。思ったよりも密度の低い基板なのでファンの換装はそれほど難しくはあるまい。
MPL3115A2を使う上での注意点をまとめる。またArdunoでデータを送出してパソコン側ではProcessingというソフトでデータを受信し、テキストファイルに保存する。
MPL3115A2は上のように実装、ちょっとホコリがたまっちゃった。奥に見える基盤は5VのArduinoと3.3VのMPL3115A2のレベルシフタ。
Arduino側プログラム
#include
#include
#define OverSample 128.0 //デジタルフィルタの定数として
#include "SparkFunMPL3115A2.h" //どこかから適当に手に入れてくれ
//Create an instance of the object
MPL3115A2 myPressure;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
float Altitude = 0;
float Ondo = 0;
float Pressure = 0;
float tempAltitude = 0;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
//timer割り込み設定
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= (1 <
OCR1A = 312500-1;
TIMSK1 |= (1 <
lcd.clear();
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("Hello! Wait!");
lcd.setCursor(0,1);
lcd.print("OverSample:");
lcd.print(OverSample);
Wire.begin(); // Join i2c bus as Master
myPressure.setModeBarometer(); // Measure pressure in Pascals from 20 to 110 kPa
myPressure.setOversampleRate(7); // Set Oversample to the recommended 128
myPressure.enableEventFlags(); // Enable all three pressure and temp event flags
}
void loop(){
myPressure.begin(); // Get sensor online
//はじめに10回くらい測定を読み捨ててみる。意味があるかはわからない。初期値が怪しいときがあるので。
for(int i = 0; i
Pressure = myPressure.readPressure();
Ondo = myPressure.readTemp();
}
while(1){
float ReadPressure; //読み取った圧力
float ReadOndo; //読み取った温度、Tempは別で定義があるようなのでOndoにしています。
ReadPressure = myPressure.readPressure();
ReadOndo = myPressure.readTemp();
Pressure = Pressure * (OverSample-1)/OverSample + ReadPressure/OverSample;
Ondo = Ondo* (OverSample-1)/OverSample + ReadOndo/OverSample;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(Ondo, 1);
lcd.print("C ");
lcd.print(Pressure, 1);
lcd.print("Pa");
lcd.setCursor(0,1);
lcd.print(ReadOndo, 2);
lcd.print(" ");
lcd.print(ReadPressure, 2);
Serial.print(ReadOndo,3);
Serial.print("\t");
Serial.println(ReadPressure,2);
}
}
ISR(TIMER1_COMPA_vect) {
digitalWrite(13, !digitalRead(13)); //特に意味もなくLEDを光らせる
}
液晶モニタにも表示させているのでLCDのライブラリと書き込みを使っています。
液晶画面には上のように表示しています。
Processing側プログラム
import processing.serial.*;
PrintWriter file;
Serial myPort; // set Serial port to
String inString; // string to read from serial port
int lf = 10; // ASCII \n
int UpDate = 0; //set 1 when minute changed while serial interrupt
int DataCount = 0;
int TempMin;
double OndoSummary =0; //倍精度にしないと気圧の有効数字が怪しい気がした(温度は大丈夫だと思うが)
double PressureSummary =0; //同上
void setup() {
file = createWriter("balomatic_tester"+nf(year(),4)+nf(month(),2)+nf(day(),2)+"_"+nf(hour(),2)+nf(minute(),2)+".log");
size(200,200);
printArray(Serial.list());
myPort = new Serial(this,Serial.list()[1], 9600); //list()[1]の数値はArduinoの接続先に依存します。
myPort.bufferUntil(lf);
TempMin = minute();
}
void draw() {
if(UpDate == 1){
UpDate = 0;
String now;
now = nf(year(),4)+"/"+nf(month(),2)+"/"+nf(day(),2)+" "+nf(hour(),2)+":"+nf(minute(),2)+":"+nf(second(),2)+"\t";
file.print(now);
file.print(nf((float)(OndoSummary/DataCount),2,3));
file.print("\t");
file.println(nf((float)(PressureSummary/DataCount),2,3));
file.flush();
OndoSummary = 0;
PressureSummary = 0;
DataCount = 0;
}
}
void serialEvent(Serial p) {
inString = p.readString(); //read String from Serial Port
String SplitedData[];
SplitedData = split(inString, "\t"); //Split data to temperature and pressure(or altitude)
OndoSummary += float(SplitedData[0]); //temperature summary like \Sigam(temperature)
PressureSummary += float(SplitedData[1]); //pressure summary like \Sigma(pressure)
DataCount++; //Average temperature or
String now;
now = nf(year(),4)+"/"+nf(month(),2)+"/"+nf(day(),2)+" "+nf(hour(),2)+":"+nf(minute(),2)+":"+nf(second(),2)+"\t";
print(now);
print(nf(float(SplitedData[0]),2,3));
print("C ");
print(nf(float(SplitedData[1]),6,2));
print("Pa ");
print(nf(DataCount,3,0));
print(" ");
print(nf((float)(OndoSummary/DataCount),2,3));
print(" ");
println(nf((float)(PressureSummary/DataCount),2,3));
// file.print(now + inString);
if(TempMin != minute()){
UpDate=1;
TempMin = minute();
}
}
void keyPressed(){
println(key);
if(key == 'f'){
file.flush(); //fキーを押したらファイルに書き込み(もうほとんどいらない)
}
else if(key == 'q'){
file.flush();
file.close(); //qキーを押したらファイルに書き出して、ファイルを閉じてプログラムストップ
exit();
}
}
とりあえずこんな感じで動いているようです。
日毎にデータファイルを分けてもいいかもしれません。