人の接近を検知しメロディを鳴らす
SP&PIRリーフに搭載された近距離検出用途の赤外線センサIC(AKM AK9754AE)を使って、人が近づいたらメロディが鳴るシステムを作りましょう。

使用するリーフ
Section titled “使用するリーフ”以下のリーフを使用します
| Type | Name | Q’ty |
|---|---|---|
| AZ62 | Connector Cover | 1 |
| AI02 | SP&PIR | 1 |
| AZ01 | USB | 1 |
| AP01 | AVR MCU | 1 |
| AV01 | CR2032 | 1 |
| CR2032 coin cell battery | 1 | |
| M2*15mm screw | 2 |
リーフの組み立て
Section titled “リーフの組み立て”下図のようにリーフを組み立てましょう。

ソースコード
Section titled “ソースコード”Arduino IDEで下記のプログラムを書きましょう。
//=====================================================================// Leafony Platform sample sketch// Platform : PIR&SP// Processor : ATmega328P (3.3V /8MHz)// Application : PIR with SP Beep//// Leaf configuration// (1) AI02 SP&PIR// (2) AP01 AVR MCU// (3) AZ01 USB//// (c) 2021 LEAFONY SYSTEMS Co., Ltd// Released under the MIT license// https://opensource.org/licenses/MIT//// Rev.00 2021/04/01 First release//=====================================================================//=====================================================================// difinition//=====================================================================#include <stdio.h>#include <Arduino.h>#include <Wire.h>#include "pitches.h"
#define I2C_PIR_ADDR 0x65#define I2C_SEND_BUF_LENGTH 10unsigned char i2c_sendBuf[I2C_SEND_BUF_LENGTH];
#define I2C_RECEIVE_BUF_LENGTH 10unsigned char i2c_receiveBuf[I2C_RECEIVE_BUF_LENGTH];unsigned char i2c_receiveLenght;
//------------------------------// buzzer output = 5pin//------------------------------#define BUZZER_OUT 5
byte readReg;double irData;double tempData;char buf[120];
volatile int state = 0;
//=====================================================================// setup//=====================================================================void setup() { //pinMode(2, INPUT); attachInterrupt(0,catchHuman , FALLING ); //人接近検知割り込み
Wire.begin(); Serial.begin( 115200 ); delay(100);
//人感センサ設定 i2c_write_byte(I2C_PIR_ADDR, 0x20, 0xFF); //CNTL1 Resrt i2c_write_byte(I2C_PIR_ADDR, 0x2A, 0xF2); //CNTL11 人感アルゴリズム有効/割り込み出力有効 i2c_write_byte(I2C_PIR_ADDR, 0x25, 0x0F); //CNTL6 センサゲイン205%(最大) i2c_write_byte(I2C_PIR_ADDR, 0x2B, 0xFF); //CNTL12 Mode=1 start Meas(連続測定モード) delay(1000);}//=====================================================================// Main loop//=====================================================================void loop() { clearI2CReadbuf(); i2c_read(I2C_PIR_ADDR, 0x04, 6, i2c_receiveBuf); sprintf(buf, "REG = %02X , %02X , %02X , %02X , %02X , %02X", i2c_receiveBuf[0], i2c_receiveBuf[1], i2c_receiveBuf[2], i2c_receiveBuf[3], i2c_receiveBuf[4], i2c_receiveBuf[5]); Serial.println(buf); sprintf(buf, "Human detection = %d", (i2c_receiveBuf[0] & 0x10) >> 4 ); Serial.println(buf);
//IRセンサ測定データ irData = clacIR(); Serial.print("IR = "); Serial.print(irData,2); Serial.println(" pA");
//センサ温度 tempData = clacTemp(); Serial.print("TSENS = "); Serial.print(tempData,2); Serial.println(" deg"); Serial.println("==================================="); if (state == 1){ //------------------------------ // notes in the melody: //------------------------------ int melody[] = { NOTE_C5, NOTE_C5, NOTE_G5, NOTE_G5, NOTE_A5, NOTE_A5, NOTE_G5, NOTE_F5, NOTE_F5, NOTE_E5, NOTE_E5,NOTE_D5,NOTE_D5,NOTE_C5 };
//------------------------------ // note durations: 4 = quarter note, 8 = eighth note, etc.: //------------------------------ int noteDurations[] = { 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 2 }; //---------------------------------------- // iterate over the notes of the melody: //---------------------------------------- for (int thisNote = 0; thisNote < 14; thisNote++) { //---------------------------------------- // to calculate the note duration, take one second // divided by the note type. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. //---------------------------------------- int noteDuration = 1000 / noteDurations[thisNote]; tone(BUZZER_OUT, melody[thisNote], noteDuration);
//---------------------------------------- // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: //---------------------------------------- float pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes);
//----------------------- // stop the tone playing: //----------------------- noTone(BUZZER_OUT); } state = 0; } delay(1000);}
//=====================================================================void catchHuman(){ state = 1; Serial.println("!! Interrupt !!"); //人の接近を検知}
//=====================================================================double clacTemp(){ double ret; unsigned short val = (unsigned short)((i2c_receiveBuf[4] << 8) | i2c_receiveBuf[3]); if ( (val & 0x8000) == 0x8000) { val = ~val + 1; ret = (double)((val) * 0.0019837 ) * -1; } else { ret = (double)val * 0.0019837; } return ret + 25;}
//=====================================================================double clacIR(){ double ret; unsigned short val = (unsigned short)((i2c_receiveBuf[2] << 8) | i2c_receiveBuf[1]); if ( (val & 0x8000) == 0x8000) { val = ~val + 1; ret = (double)(val * 0.4578 ) * -1; } else { ret = (double)(val * 0.4578 ); } return ret;}/*********************************************** I2C スレーブデバイスに1バイト書き込む**********************************************/void i2c_write_byte(int device_address, int reg_address, int write_data){ Wire.beginTransmission(device_address); Wire.write(reg_address); Wire.write(write_data); Wire.endTransmission();}/*********************************************** I2C スレーブデバイスから1バイト読み込む**********************************************/unsigned char i2c_read_byte(int device_address, int reg_address){
int read_data = 0;
Wire.beginTransmission(device_address); Wire.write(reg_address); Wire.endTransmission(false);
Wire.requestFrom(device_address, 1); read_data = Wire.read();
return read_data;}/*********************************************** I2C スレーブデバイスに複数バイト書き込む**********************************************/void i2c_write(int device_address, int reg_address, int lengrh, unsigned char* write_byte){
Wire.beginTransmission(device_address); Wire.write(reg_address); for (int i = 0; i < lengrh; i++){ Wire.write(write_byte[i]); } Wire.endTransmission();}/*********************************************** I2C スレーブデバイスから複数バイト読み込む**********************************************/void i2c_read(int device_address, int reg_address, int lengrh, unsigned char* read_byte){
Wire.beginTransmission(device_address); Wire.write(reg_address); Wire.endTransmission(false);
Wire.requestFrom(device_address, lengrh); for (int i = 0; i < lengrh; i++){ read_byte[i] = Wire.read(); }}/*********************************************** I2C 受信バッファクリア**********************************************/void clearI2CReadbuf(){ memcpy(i2c_receiveBuf, 0x00, I2C_RECEIVE_BUF_LENGTH);}人が近づくとメロディが鳴ります。