赤外線モーションセンサモジュール(HC-SR501)をATtiny85で使う


しばらくブレッドボードで動かしていましたが、特に問題もないので、PCB基盤に組んでみました。
所詮、4ピンのI/Oしか使わないので、ATtiny85を使い、 PCB基盤も30mm*70mmのものを 使いました。

回路図は以下の様になります。
CDSの抵抗は10Kオーム、LEDは3mmのものを使いました。
LEDはセンサーの動作が見えるように付けただけなので、なくてもかまいません。
DC3V〜5Vの入力をUSBの5V出力に変換する変換機はATtiny85のピン#1に直結ですが
間に抵抗を挟んだほうがいいかも知れません。
(その後の実験で10から20オームの抵抗を挟むといいことが分かりました)




使用したスケッチは以下のスケッチです。
CDSからの入力はアナログなので、50回のサンプリングの結果をヒストグラム化し、最も頻繁に出現した値を採用しています。

/*
 * sample program for HC-SR501 PIR MOTION DETECTOR for ATtiny85
 *
 *
 */
#define outPin 1
#define pirPin 2
#define ledPin 3
#define cdsPin A2
#define interval 30

unsigned long time;
unsigned long etime;
int outFlag;

void setup() {
  Serial.begin(9600);
  pinMode(outPin,OUTPUT);
  pinMode(pirPin,INPUT);
  pinMode(ledPin,OUTPUT);
  digitalWrite(pirPin,LOW);
  digitalWrite(outPin,LOW);
  digitalWrite(ledPin,LOW);
  outFlag=0;
}

void loop() {
  int val;
  int A_val;

  val = digitalRead(pirPin); //read state of the PIR
  if (val == LOW) {
    Serial.println("No motion"); //if the value read is low, there was no motion
    digitalWrite(ledPin,LOW);
  } else {
    Serial.println("Motion!"); //if the value read was high, there was motion
    digitalWrite(ledPin,HIGH);
    A_val=MyAnalogRead(cdsPin); 
//read value from CDS
    Serial.print("A_val=");
    Serial.println(A_val);

    if (A_val > 800) {
      time = millis()/1000;
      etime=time+interval; // End Time
      digitalWrite(outPin,HIGH);
      outFlag=1;
    }
  }

  Serial.print("outFlag=");
  Serial.println(outFlag);
  if (outFlag) {
    time = millis()/1000;
    Serial.print(time);
    Serial.print(" ");
    Serial.println(etime);
    if (time > etime) {
      digitalWrite(outPin,LOW);
      outFlag=0;
    }
  }
  delay(1000);
 
}

/*
 * Analog Read with HistGram
 */

#define s_size 50   // アナログデータ格納領域
#define h_size 10   // ヒストグラム格納領域

int MyAnalogRead(int analogPin)
{
  int buf[s_size];
  int hist[h_size];
  int imin=1023;
  int imax=0;
  int A_val;
  int tmp;
  int pos;
  int i;

//Clear Histgram
  for(i=0;i<h_size;i++) hist[i]=0;

//Get Analog Data
  for(i=0;i<s_size;i++) {
    buf[i] = analogRead(analogPin);
    if (buf[i] > imax) imax=buf[i];
    if (buf[i] < imin) imin=buf[i];
//    Serial.print(buf[i]);
//    Serial.print(" ");
  }
//  Serial.print("imin=");
//  Serial.print(imin);
//  Serial.print(" imax=");
//  Serial.println(imax);

//Set Histgram
  for(i=0;i<s_size;i++) {
    tmp=buf[i]-imin;
    if(tmp < h_size) hist[tmp]++;
  }

//Get Max Histgram
  tmp=0;
  for(i=0;i<h_size;i++) {
//    Serial.print(hist[i]);
//    Serial.print(" ");
    if (hist[i] > tmp) {
      tmp=hist[i];
      pos=i;
    }
  }

//  Serial.print(" pos=");
//  Serial.println(pos);
  A_val=imin+pos;
  return A_val;
}

プログラムサイズのことは、何も考えずに作ったのですが、3Kぐらいで収まっています。
ATtiny45でも収まるかもしれません。



モーションセンサーモジュールはHC-SR501とHC-SR505のどちらも使えるように、ヘッダーピンを立てています。







しばらくATtiny85で遊んでみようと思っています。