日々の記録

ほどよく書いてきます。

MPL3115A2の測定値をArduinoで読み取りProcessingで保存する。

2020年06月07日 13時57分19秒 | AVR

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();
  }
}

とりあえずこんな感じで動いているようです。

日毎にデータファイルを分けてもいいかもしれません。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

MOSFETのVg

2020年05月04日 19時22分38秒 | AVR

2SK4017をモータードライバに使っていたのだが使っていて挙動がおかしいと思ったフシがあってちょっと調べてみた。

変な挙動というのはMOSFETがONになっているはずなのにVDSが0Vにならないとか、MOSFETをONにしている期間でOFFになってしまっていたりということが見られた。これはゲート電圧がギリギリアウトかなと思って調べたら、アウトだったと思う。

結局の所Vgが2.5Vかそれよりも高いくらいなのだが、電源が3.3V、下の図だと3Vしかなく、十分にMOSFETをONにできていなかったのではという疑問。

データシートを見ても3Vじゃ1Aくらいしか流せないようだ。

コメント (3)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

DCモーター回転数制御のトライ

2020年05月02日 22時35分04秒 | AVR

さて、モーター回転中の電圧から回転数をセンシングしようというものだが、まずはモーターを別のモーターで回転させながら発生電圧を調べる。

一定電圧ではないので、山あり谷ありの波形だが、最大電圧はこのような感じになっている。6600rpmくらいで2Vくらいの起電力が発生するようだ。
マブチのRE-140RAは3スロット2ブラシなので、1回転6パルスを前提として回転数を算出しています。

電圧波形について、次のPWM回路で調べると、V1とGNDの間の電圧は

このような感じです。波形がギザギザするのはモーターの整流子の都合かと思います。上記の回転数の電圧変化はボトムの電圧を見ています。

マイコン側のプログラムとしては

MOSFETがONのときはADC読まない(読んでもそのまま捨てる)。MOSFETがOFFのタイミングでADC実施をいう方法が良さそう。
図にすると、下のようにPWMのカウンタ(TCNT0)が0-255までカウントする間に、PWM用のOCCR0Bレジスタと、OCCR0Aレジスタの値を少し変更しておき、
OCCAR0AとTCNT0が一致したらADC開始、TCNT0のリセットでADC終了というようなものがいいかと思っている。

OCCR0AはADCを開始したら250などに設定し、TCNT0のオーバーフローを待たずにADC変換やめてもいいと思う。

電圧は上記のようにフラフラ不安定なので上記の回路のようにLPFを使うか、デジタルでフィルタを入れるかして最小値を読むような方法がいいかなと思っている。

コメント (4)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

マイコンのサイズ

2020年04月16日 00時12分18秒 | AVR

ATTiny10は大変小さく、0.1uFの積層セラミックコンデンサですらこのサイズ。

モーター制御は120Hzで行こうと思うので次は実装に移りたいと思います。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

ATTiny10で遊ぶ

2020年04月13日 01時19分54秒 | AVR

AVRマイコンにはATTiny10というとても小さなマイコンがある。

ATTiny13Aと比較してもこのサイズ。小さい。8ピンのDIPがATTiny13Aで、その上の6pinのものがATTiny10です。

米粒マイコンとも呼ばれるように米粒と比較してもこの通り、偽りなしのサイズ。

 

ゴールはマブチモーターのブラシモーターをPWMで駆動するところ。

0.1uFのコンデンサは回路図では遠いですが、パスコンなのでマイコン近くへの配置が必要です。
実験してわかったけど電解コンデンサ省いたら長い配線のせいかスイッチONの瞬間に電源電圧の低下がありました。

ダイオードとRCフィルタが必要かどうかは微妙なところ(プロトタイプはダイオードもRCフィルタもなしで動かした)。

小さいままプロトタイプ作ってと思いましたが、小さいままでは試作時に都合が悪いので、DIPサイズに大きくしてブレッドボードで実験。

 

PWMの周波数ははじめにモーターが6000rpm=100Hzで回っていたら1回転で60回くらいスイッチングすればいいかなとか適当に考えて6kHz以上とおもったが、これくらいの周波数だとモーターから可聴域のキーンというノイズがでるのでNG。16kHzもちょっと聞こえるからダメだね。

最終的にはマイコンクロック4MHzでPWMのカウンタ範囲を0-128として31kHzでスイッチング実施。MOSFETのゲート充電時間が気になるけど、これは2SK3510で1us~2usくらいだったのでまあいいでしょう。最終的なMOSFETは友人のおすすめIRLML6344TRPBFTRというInternational Rectifierのゲート電圧0.8Vでonになるものを採用予定。2SK3510はゲート電荷150nC@VGS=10Vで、IRのは6.8nC@VGS=4.5Vと1/10以下なので、速度は問題になるまい。


2SK3510を使ったときのゲート電圧変化、4V弱でMOSFETがONになるための領域が見える。ゲート電圧0Vから0.75usくらいで充電が終わるがまあ、2usくらい充電にかかると思っておけば良かろう。

次は2SK4017を使ったもの。横軸の時間が一桁違うが、150ns程度で立ち上がっているので、十分に高速だろう。

当然だが、電流容量の大きなMOSFETはゲート電荷も多いので、駆動により多量の電流が必要になる。

 

ちょっと苦労した点
・内蔵クロックのプリスケーラー設定
 ATTiny10は8MHzの内蔵クロックを8分周した1MHzで動くのが基本なのだが、これ以外の分周にするには一回CCPというレジスタを変更する必要がある。
 CCP=0xD8; の命令の直後に
 CLKPSR = 0b00000001; などとプリスケーラー変更の命令を書けばいいのだが、何を勘違いしたのかD8が8bit変数であるにも関わらず、
 なぜか2桁だから16bitだとおもってしまい、どうやって8bitのCCPに16bitの値を放り込むのかと考えてしまった。

その他の実験が必要だった箇所
・モーターは回転するのに必要な最低限の電力があるので、単純にADCの値をPWMにすると感度ない領域が出てしまう。
・マブチRE-140RAの場合5V電源でPWMするときはDuty > 50%じゃないと回転しない感じです。回り始めるのに最低限エネルギーが必要な様子。そりゃそうか。
・モーター駆動の逆起電圧、電流を戻すためにダイオードが必要かと思ったが、モーターが回っている限りでは逆起電圧は気にしなくて良さそう。
 回転してないけどスイッチングしているときは逆起電圧大きくなりそうだと思ったがMOSFETは現状壊れていない(たまたま大丈夫な可能性もあるのでブレーキになってしまっても
 ダイオードは入れておきたい、と思っている。ブレーキ嫌ならツェナーダイオードかな)。

表面実装のマイコンは小さくていいのだが、プログラムの確認などを行う途中ではブレッドボートが使えるくらいのサイズがほしいと思った(実際変換基盤を使った)。
MOSFETのゲート、VRなどが書き込み端子に接続されているとそもそも書き込みができないケースがあった(インピーダンスが低くなる為)ので配線を外すなどが臨機応変に必要だった。

プロトタイピングは終わったのでまた後日最終形態に持っていくこととする。

 

さて、プロトタイピングが終わっていなかったので再考である。

モーターはリアクタンスがでかいのでスイッチングで動かすときは低周波のほうがむしろいいということで、CPUクロックと分周比で0-255カウントしたときのPWM周波数を求めた。
CPUクロック1MHzが出荷時のデフォルトである。

クロック
[MHz]
分周比
1/1 1/8 1/64 1/256 1/1024
8 31250 3906 488 122 30.5
4 15625 1953 244 61.0 15.3
2 7813 977 122 30.5 7.6
1 3906 488 61 15.3 3.8

CPU=1MHzで1/8分周比くらいの490Hzがちょうどいいくらいでしょうか。
PWMが61Hzでもモーターの慣性力があるのであまり気にならないかな。ためしてみましょう。

もしくはモーター上流をDC-DCコンバーターのようにしてモーターにチョッパした矩形電圧を打ち込むのではなく、整流された電圧を供給するか。でも、部品が増えますね。

コメント (6)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

GoPro買った

2017年08月02日 00時33分34秒 | AVR

GoPro SESSIONなるものを購入。ヘルメットに取り付けて走ってみた。

コメント (1)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

移動平均という名のLPF

2017年06月14日 23時02分23秒 | AVR

センサーなどのノイズを程よく除去するにはローパスフィルター(LPF)が有効である。

デジタル通信するセンサーの場合はアナログのLPFは使えないので、デジタルのLPFを使うことになる。

 

センサから出てくる値をxとして、現在保有している平均値をSとすると

S=S*0.9 + 0.1x

といった具合でLPFが実装できる。

浮動小数点演算は小さなマイコンには重い作業なので

32倍の値をS2とでもしておき、

S2=( S2 - (S2>>5) + x )

S=S>>5

といった値を吐き出すのが演算負荷的によろしいのではと思っている。>>はビットシフト。

コメント (6)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

気圧温度計

2017年06月11日 18時36分28秒 | AVR

気圧温度計が動いた。LCDに値を表示させている。

値をそのままではパラパラ値が変動するので、ソフトウェアで16回サンプリングした平均値を表示するようにした。

更新は数秒に一回だが、十分だろう。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

I2C通信

2017年06月11日 17時07分34秒 | AVR

I2Cのデバイスで持っているものは次の通り。現在5Vと3.3Vが混在していてレベルシフタが必要だが・・

・リアルタイムクロック(DS3231)
・気圧計(MPL3115A2)
・液晶
・microSDカードアダプタ(これはSPI通信でI2Cじゃないけど)

温度は気圧計にもRTCにも入っているので、どっちでもいいが、液晶に気圧温度を表示しつつmicroSDにデータを吐き出す、といったデータロガーができそうだ。

microSDって通信途中に電源切れたらファイル壊れるのかな

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

MPL3115A2

2017年06月11日 13時29分52秒 | AVR

随分前に高精度な気圧センサーをもらったので試してみた。

気圧モードと標高モードがあるが、気圧モードにてデータ取得。標高モードのほうが面白かったかもしれないが・・・

上で圧力がジャンプしている箇所があるが、頭上から足元に移動させたがそれを十分に検出できているからすごい。なお上記は128倍サンプリングしたデータを更に10倍平滑している。

ライブラリほかは
https://learn.sparkfun.com/tutorials/mpl3115a2-pressure-sensor-hookup-guide
のものを使いました。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

デジタルサーモスタット

2017年04月16日 14時04分49秒 | AVR

以前、温度調整制御をしようとマイコンでちょっと作ったものがあったが、実は電力が足りなくて加熱が不十分というオチだった。

で、新しく作ろうかと思っていたら、こんなのを見つけた。

アマゾンで、220円。

あれ、マイコンより安くないか?

制御は至ってかんたん。

目標温度、ヒステリシス幅、極性(加熱or冷却)を設定すれば、よい。PIDとかそういう制御ではなく、温度が下がったらオン、温度が上がったらオフというかんたんな制御。

何がすごいって値段だよね。送料いくらだよと思ってしまう。

 

で、もちろん買ってみた。動く。出力を示すLEDが消灯しているとき、8Vくらいの逆バイアスがかかっているので、そこは解消が必要だろう。

マイコンが3.3Vで動いており、電源を5Vにしたらよいが、そうするとリレーが動かない。

リレーを取っ払ってSSRに取り替えれば5Vで動くのでそうしよう。SSRならカチカチ音もしない。ただ、SSRは少々ドロップ電圧が気になるので、放熱には気をつけたいところだ。

 

コメント (1)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

メモ

2017年02月12日 18時02分03秒 | AVR

先日買ったもの

TXCO 12.8MHz 3.3V 精度1.5ppm=月差4秒

消費電流1.5mA 買ったあとに気がついたが、TXCOを搭載したRTCがあった。

http://akizukidenshi.com/catalog/g/gI-09097/ 

http://akizukidenshi.com/catalog/g/gI-05006/ 

 

レーザー(出力200mWとある)

http://item.rakuten.co.jp/amillia-style/laser/

波長635nmとあるが、650nmである。ラインにする箇所を外せばスポットのレーザーとなる。

200mWの出力は本当かわからないが、手元の635nm 5mWレーザーよりかなり明るく、結構な出力なのではないかとおもう。空に向けて照射するとかすかに線が見える。

コメント (2)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

さそり座の火星

2016年05月14日 22時18分29秒 | AVR

昨日さそり座を見上げて、あれ、アンタレスってあんなに明るかったかなと思いながら写真撮影。

で、写真を見たらアンタレスじゃない。調べたら火星だった。

Mが火星

Sは土星

Aがアンタレス

 

随分赤く輝いているからアンタレスかと思ってしまったよ。

コメント (10)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PC修理完了

2016年04月17日 17時48分03秒 | AVR

さて、PCが故障していて約一ヶ月

予想通り電源の故障でしたが、トラップにハマってマザボをずっと疑ってました。

ATX電源はピン間ショートで強制ONにできるのですが、これをやって出力電圧を見ると、どの端子にもしかるべき電圧が出てきていました。なので、電源には問題ないなと思ってヤフオクで使っているマザーボードと同じものが出てくるまで待機。

Intel DG33BUという2007年から発売していたマザボなので、なかなかヤフオクにも出てきませんでした。2週間程待って2500円で 無事落札。

しかし、マザーボードを交換しても動かない。

 

電源か・・・ということで、電源交換して無事に動きましたとさ。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

タイムラプス 日の出から日没まで

2016年01月11日 00時05分13秒 | AVR

2016年1月10日、日の出から日没まで30秒ごとに撮影。解像度高めで再生したほうが綺麗です。

 

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする