ダストセンサー」タグアーカイブ

ZH02を触ってみた

先日入手したWinsenのダストセンサーZH06を触ってみた。先日ZPH02というのを触ったけどそれより少し良い奴。ZPHはDuty比しか返してくれないので換算が面倒だけどこっちはI2Cでug/m3で返してくれる。ただしPWMは二つの値を順次返してくれるようでマイコンなしで扱うのは大変そう。

コネクタはオスオスのがついてきた。メスのコネクターはなかったので半分に切ってピンヘッダーに半田した。

UART接続

環境

  • ArduinoNano互換機
  • Arduino IDE1.8.13(Windows10)
  • ブレッドボードとジャンパーケーブル少々

配線

NanoとPCはUSB接続

ZH06Nano
#1 VDD5V
#2 GNDGND
#3 Reserved未接続
#4 RXD Serial receive pinD3(スケッチで指定)
#5 TXD Serial send pinD2(スケッチで指定)
#6 Reserved未接続
#7 Reserved未接続
#8 PWM output未接続

ソース

#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);

#define LED_PIN 13

#define BUFFER_SIZE 31
#define START_BIT 0x42

unsigned char inBuffer[BUFFER_SIZE];


void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  mySerial.setTimeout(1500);
}

void loop() {
  bool readFlg = false;
  int bufIndx = 0;

  if(mySerial.find(START_BIT)){
    mySerial.readBytes(inBuffer,BUFFER_SIZE);
  }

  if (checkSum()) {
    writeData();
  }
  delay(100);
}

bool checkSum() {
  int dataSum = 0;
  for ( int i = 0; i < (BUFFER_SIZE-2) ; i++) {
    dataSum += inBuffer[i];
  }
  dataSum += START_BIT;
  
  Serial.print("calc=");
  Serial.print(dataSum, HEX);
  Serial.print(" checksum=");
  Serial.print( (inBuffer[29] << 8) + inBuffer[30], HEX);
  Serial.print(" ");

  bool isGoodChecksum = (dataSum == ((inBuffer[29] << 8) + inBuffer[30]));

  
  if(!isGoodChecksum){
    Serial.println("チェックサムエラー");
  }
  return isGoodChecksum;
}

void writeData() {
  for ( int i = 0; i < BUFFER_SIZE; i++ ) {
    Serial.print(inBuffer[i], HEX);
    Serial.print(",");
  }
  Serial.print("[pm1.0 ");
  Serial.print((inBuffer[9] << 8) + inBuffer[10]);
  Serial.print("]");
  Serial.print("[pm2.5 ");
  Serial.print((inBuffer[11] << 8) + inBuffer[12]);
  Serial.print("]");
  Serial.print("[pm10 ");
  Serial.print((inBuffer[13] << 8) + inBuffer[14]);
  Serial.print("]");
  Serial.println("");
}

問い合わせモードにするコマンドもあるけど試していない。データシートのリンクないけどこれで動いた

ZPH02を触ってみた

先日入手したWinsenのダストセンサーZPH02を触ってみた。検索でv1.2のデータシートがかかったけど公式からデータシートにリンクが張られているV1.0のほうだった。(公式の写真だとピンヘッダーが1*4だけど1*5のが届いたので微妙に違うものかも)なお、ピンヘッダーについてはデータシートにアサイン等記載なかった。少なくともコネクタと並び順は違う。

コネクタ(EH2.54-5P terminal socket)に関してはケーブルが付属していなかった。とりあえずジャンパーのメスと同じサイズなのでそれで引きさした。

出力は粒子数直接ではなくて粒子数に応じて出力LowのDuty比がかわる。データシート参照。

UART接続

環境

  • ArduinoNano互換機
  • Arduino IDE1.8.13(Windows10)
  • ブレッドボードとジャンパーケーブル少々

配線

NanoとPCはUSB接続

PHZ02Nano
#1 Control pinGND
#2 Output OUT2/RXD未接続
#3 Power positive (VCC)5V
#4 Output OUT1/TXDD2(スケッチで指定)
#5 GNDGND

#1をGNDにするか未接続かでPHZ02の出力がUARTになるかPWMになるかが切り替えられる。GNDだとUARTモードになる。UARTだと#4がTXになるのでそれをNanoのRXを割り当てたGPIOで受け取る。もともとのハードウェアなRX端子はPCとのやりとりで使いたいのでSoftwareSerialにて割り当てた。

ソース

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);

#define LED_PIN 13

#define BUFFER_SIZE 9
unsigned char inBuffer[BUFFER_SIZE];


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

void loop() {
  bool readFlg = false;
  int bufIndx = 0;
  
  while (mySerial.available() > 0) {
    unsigned char readValue =  mySerial.read();
    if (bufIndx > BUFFER_SIZE) {
      continue;
    }
    inBuffer[bufIndx] = readValue;
    bufIndx++;

    readFlg = true;
  }

  delay(10); // 少し待ってあげないと配列がちゃんと読み込めない

  if (readFlg && checkSum()) {
    writeData();
  }
  delay(100);
}

bool checkSum() {
  unsigned char tempq = 0;
  for ( int i = 1; i < 8 ; i++) {
    tempq += inBuffer[i];
  }
  tempq = (~tempq) + 1;
  
  if(!(tempq == inBuffer[8] )){
    Serial.println("チェックサムエラー");
  }
  return (tempq == inBuffer[8] );
}

void writeData() {
  for ( int i = 0; i < BUFFER_SIZE; i++ ) {
    Serial.print(inBuffer[i], HEX);
    Serial.print(",");
  }
  Serial.print("[");
  Serial.print(inBuffer[3]);
  Serial.print(".");
  Serial.print(inBuffer[4]);
  Serial.print("]");

  Serial.println("");
}


ZPH02の通信速度(Baud Rate)は9600なのでソフトシリアルで指定。コンストラクタでD2を指定。

コメント入れてあるdelay(10)がないと配列ちゃんと読み込めなかった。

チェックサムは~7バイト。スタートバイトはいらない。

for ( int i = 1; i < 8 ; i++) {

なにか、チェックサムがおかしな値しか返らなくなって再起動しなくてはいけない事象があった。(まだ詳しく見られていない。)

精度はパルス幅0.1%までの模様。値は結構上下するみたいなのでそのまま使うと上下に振れすぎて読みにくいかも。

スタートビットちゃんとみてデータ取得していない拾っていない途中まで読み込んでいるのは次回捨てている。

PWM接続

環境

  • ArduinoNano互換機(電源用)
  • Arduino IDE1.8.13(Windows10)
  • ブレッドボードとジャンパーケーブル少々

配線

PHZ02Nano
#1 Control pin未接続
#2 Output OUT2/RXDPWM出力(計測用にオシロの+に)
#3 Power positive (VCC)5V
#4 Output OUT1/TXD未接続
#5 GNDGND(計測用にオシロの-に)

#1をGNDにするか未接続かでPHZ02の出力がUARTになるかPWMになるかが切り替えられる。未接続だとPWMモードになる。

出力

1秒サイクルでLow(0V)の割合が濃度。

ダストセンサー2種類届いた

とPM1.0/ PM10/ PM2.5ダストセンサー ZH06とPM2.5ダストセンサーZPH02が届いた。AliのWinsen公式で買って13日。

ZH06はケーブルついていた。ZPH02は付属ケーブル無し。

使い方はこれから調べる

ZH06

データシートはこちら

出力はPWMとUART。コネクタは1.25t-8a、入手しにくいから公式で一緒に売ってくれないかな。データシートのFig9あたりに置き方書いてあるけど通気口ふさいだらよくないし置く確度とかも意識しろと。この間かったDSM501Aにも書いてあったけど通気関係は結構シビアっぽい。

湿度は80%まで。ちょいちょい引っかかりそうね。

想定寿命は10000時間以上。連続稼働だと1年ちょいなので短めは短めね。モジュール本体はケーブル接続なので交換部品だけ買えるようにしておけばよいか。 そして油/煙のある環境はあかんと。

数値の計算式”Please refer the document of ZH06 I-IV Series Communication Protocol.”とか書いているけど、そのドキュメントどこにあるんだ?どりあえず旧バージョンのデータシートにそれっぽいのがのっているのできっとこれでよいだろう。あとでサポートにきかなくては。あいかわらずWinsenのドキュメント類はうち並みの整備状況っぽい。

ZPH02

データシートはこちら(V1.0で公式の製品情報からリンクがある物)こちら(V1.2でGoogle検索で出ててきたもの)が見つかった届いたものは、UARTのレスポンスbyte[6]が1でbyte[7]が0なのでどちらのデータシートとも微妙に違う。サポートに確認しようと思ったけど、ドキュメント大体なのでbyte[7]が0というのが現在の動作なのだろう。(売るならちゃんと聞く) 公式からリンクが張られている方だった。よくみたらVOCセンサーがない場合はbyte6が0x00と補足に書いてあった。

PIN5をグランドにするかどうかでPWMモードかUARTモードかを切り替えるとのこと。

UARTは5Vで1秒ごとの受信のみ。

コネクター以外にピンヘッダー付きそうな端子があるけどデータシートに記載なし。同じものが引き出されていそうなきはするけど、少なくとも並び順はコネクターと違う。後で調べる。

使い方

こちら

PM2.5ダストセンサーDSM501Aが届いた

Aliで買ったダストセンサー(ほこりセンサー)が届いた。(こちら

発注から到着は11日。最後ヤマトさんが持ってきた。(購入時800円中500円送料)

商品のページだと可変抵抗器2こついているけど届いたのは一つしかない。公式にはもうデータシートなさそう。ネットに残っているデータシート見ると触るなと書いてあるし基盤の形も色々なのでフェイク品ではなく色々バージョンがあると信じて触ってみよう。

端子は銀色を左上において左から

#1Control Vout 1 control
#2Vout 2Vout 2 output
#3Vcc Positive power supply(5V)
#4Vout 1 Vout 1 output
#5GND Ground

附属品のコネクターケーブルの色はVCCとかと関係ない。

粒子の数が283mlあたりという微妙な単位で出てくるけど1立方フィートの1/1000ぽい。

リンクのドキュメントには置き方書いていない。ただ、ヒーターで上昇気流を発生させているから云々と書いてあってどこか他のサイトに縦置きして出入口をふさぐなというようなことが書いてあった。

レンズは汚れたら綿棒で拭けと。

配線等はこちらほぼそのまま参考に数値はとれた。あっているのか?

// DSM501A Pin3 → Arduino 5V
// DSM501A Pin5 → Arduino GND
// PM1.0以上を計測したい場合:DSM501A Pin2 → Arduino D8
// PM2.5以上を計測したい場合:DSM501A Pin4 → Arduino D8
// Wind Abaft Co., Ltd.

#include<string.h>
byte buff[2];
int pin = 8;//DSM501A input D8
unsigned long duration;
unsigned long starttime;
unsigned long endtime;
unsigned long sampletime_ms = 30000; // データシートの計測方法が30秒のため
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;
 
int i=0;
void setup()
{
  Serial.begin(9600);
  pinMode(8,INPUT);
  starttime = millis(); 
  Serial.println("Start");
}
void loop()
{
  duration = pulseIn(pin, LOW);
  lowpulseoccupancy += duration;
  endtime = millis();
  if ((endtime-starttime) > sampletime_ms)
  {
    ratio = (lowpulseoccupancy-endtime+starttime + sampletime_ms)/(sampletime_ms*10.0);  // Integer percentage 0=>100
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // データシートのグラフ参照
    Serial.print("lowパルス幅(30秒間):");
    Serial.print(lowpulseoccupancy);
    Serial.print("    Lowパルス幅の占有率[%]:");
    Serial.print(ratio);
    Serial.print("    DSM501A計測粒子数[pcs/283ml]:");
    Serial.println(concentration);
    Serial.print("    DSM501A計測粒子数[pcs/ml]:");// ここだけ追加
    Serial.println(concentration/283);
    lowpulseoccupancy = 0;
    starttime = millis();
  } 
}