메이커 Maker

흡연 감지 카메라 작품 제작 완료 보고서

지구빵집 2022. 1. 18. 09:04
반응형

 

 

흡연 감지 카메라 작품 제작 완료 보고서 

 

흡연 감지 카메라 배경 국민 건강 증진법 9조 4항과 시행규칙에 따르면 공중이 이용하는 시설의 소유자·점유자 또는 관리자는 해당 시설의 전체를 금연구역으로 지정하고 금연구역을 알리는 표지를 설치해야 한다. 여기서 말하는 공중이 이용하는 시설은 국회의 청사, 정부 및 지방단치단체의 청사, 공공기관의 청사, 어린이집, 공연가, 관광 숙박업소, 사회복지시설 등등 지정되어 있다. 또한 국민 건강 증진법 9조 8항과 34조 3항에 따르면 누구든지 지정된 금연구역에서 흡연을 해서는 안되고 금연구역에서 흡연한 자에게는 10만원 이하의 과태료가 부과된다. 하지만 금연구역에서 흡연한 자를 적발하기에는 많은 어려움이 있다.  

 

금연아파트 늘리면 뭐하나···'뻐끔뻐끔' 열받는다. 이미지 http://m.mdilbo.com/detail/c3QycN/659030

 

위의 뉴스와 같이 금연구역을 감시하는 인력과 출동에 많은 노력이 소요된다. 이러한 문제를 해결하기 위해 금연 카메라를 개발하였다.  

 

흡연 감지 카메라 소개

 

금연 카메라는 실내 금연 구역에 설치가 가능하다. 또한 금연 카메라는 기존 담배 냄새 감지기와 다르게 연기를 감지하면 자동으로 사진 촬영 후 경보 알람이 울려 시설의 관리자가 현장을 적발하게끔 도와준다. 대부분 흡연에 적발된 시민들은 일단 큰소리치며 오리발을 내민다. 그러나 금연 카메라를 사용하게 된다면 흡연자가 발뺌하더라도 사진이 촬영되어 확실한 증거가 있으므로 과태료를 부과할 수 있을 것이다. 사진 촬영은 인권침해의 논란이 있겠지만 법률에 따르면 공공의 이익을 위해서 그리고 증거 수집을 위한 사진촬영은 해결된다, 또한 카메라를 설치하는 구역에 사진 촬영의 경고문을 부착한다면 해결이 가능하다.  

 

흡연 감지 카메라

 

흡연 감지 카메라 구성 및 작동방식 

 

아두이노 우노 보드, MQ 센서, 피에조 스피커, 카메라 이외에도 와이파이 모듈, 나노33IOT 등 많은 부품이 사용되었다. 간략하게 구성을 소개하고자 크게 세 개로 나눠서 소개한다. 아두이노 우노보드와 브레드 보드에 카메라를 커넥터 케이블로 연결한다. 마찬가지로 Micro SD카드 모듈에 SD카드를 꽂고 아두이노 우노 보드와 브레드 보드에 커넥터 케이블을 이용해서 연결한다. 와이파이 모듈을 사용하기 위해서 아두이노 우노 보드에 연결해줘야 하는데 와이파이 모듈에 피에조 스피커를 연결하고 커넥터 케이블을 이용해서 우노 보드에 연결한다. 센서는 브레드 보드 두 개와 아두이노 33 IOT를 이용해서 만든다. 센서는 MQ-2, MQ-7, MQ-135 총 세 개를 연결했다. 이 3개의 센서로 연기 및 성분을 감지하여 스피커가 울리고 사진이 찍히도록 설계하였다. 흡연 감지 카메라 작동방식은 다음과 같다.  

흡연 감지 카메라 구성 및 작동방식 

 

흡연 감지 카메라는 담배 연기 및 유해 성분을 감지한다. 이때 사용되는 센서는 MQ-2, MQ-7, MQ-135이며 순서대로 연기 감지, 일산화탄소 감지, 유해가스를 감지한다. 우노 보드를 이용하여 센서의 입력값을 저장하고 값이 제한된 수준을 넘으면 카메라 모듈을 이용하여 사진 촬영 후 피에조 스피커가 경보 알람을 울린다. 사진은 SD카드에 저장되어 관리자가 직접 확인할 수 있다. 앱을 개발하여 사진을 찍고 SD카드에 저장한다. 추가로 SD 카드에 저장하는 것만으로 끝내지 않고 시설 관리자 핸드폰에 사진과 알람을 전송하는 기술을 구현해도 좋다. 

 

nano 33 iot wifi 프로그래밍 

 

#include <SPI.h>
#include <WiFiNINA.h>

#include "arduino_secrets.h" 
char ssid[] = "0o0";      
char pass[] = "12345670";    
int keyIndex = 0;           

int status = WL_IDLE_STATUS;

WiFiClient client;

// server address:
char server[] = "192.168.99.194";
//IPAddress server(64,131,82,241);

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  pinMode(A0,INPUT);
  
  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  // you're connected now, so print out the status:
  printWifiStatus();
}

void loop() {
  int smoke = digitalRead(A0);
  int smoke2 = digitalRead(A1);
  int smoke3 = digitalRead(A2);

  int sum = smoke + smoke2 + smoke3;

  if(sum < 3){
    if(client.connect(server,80)){
      client.write("Modul-1",7);
    }
     client.stop();
  }


 
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

 

uno wifi rev 2 wifi 프로그래밍 코드

 

#include <SPI.h>
#include <WiFiNINA.h>
#include <SoftwareSerial.h> 

SoftwareSerial BTSerial(3,4);

#include "arduino_secrets.h" 

char ssid[] = "0o0";        
char pass[] = "12345670";    
int keyIndex = 8;                
boolean alreadyConnected = true;

int status = WL_IDLE_STATUS;

WiFiServer server(80);

void setup() {
  pinMode(2,OUTPUT);
  Serial.begin(9600);
  BTSerial.begin(9600);

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    while (true);
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
 //   Serial.print("Attempting to connect to SSID: ");
 //   Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  server.begin();
  
  // you're connected now, so print out the status:
//  printWifiStatus();
}


void loop() {
  // listen for incoming clients
  WiFiClient client = server.available();

  if (client) {
      digitalWrite(2,HIGH); delay(300); digitalWrite(2,LOW):
      char thisChar = client.read();
      BTSerial.write('1');

    }
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

 

uno 카메라 및 SD card 리더기 프로그래밍 

 

#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h> 
#include "memorysaver.h"
//This demo can only work on OV2640_MINI_2MP and  OV5642_MINI_5MP and OV5642_MINI_5MP_BIT_ROTATION_FIXED platform.
#if !(defined (OV5640_MINI_5MP_PLUS)||defined (OV5642_MINI_5MP_PLUS))
#error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file
#endif

#define SD_CS 9

// Set pin 4,5,6,7 as the slave select for SPI:
const int CS1 = 7;

bool CAM1_EXIST = false; 

SoftwareSerial BTSerial(4,3);

#if defined (OV2640_MINI_2MP)
ArduCAM myCAM1(OV2640, CS1);

#elif defined (OV3640_MINI_3MP)
ArduCAM myCAM1(OV3640, CS1);

#else
ArduCAM myCAM1(OV5642, CS1);

#endif

void setup() {
  // put your setup code here, to run once:
  uint8_t vid, pid;
  uint8_t temp;
  Wire.begin(); 
 Serial.begin(9600);
 BTSerial.begin(9600);
// set the CS output:
pinMode(CS1, OUTPUT);
digitalWrite(CS1, HIGH);

pinMode(SD_CS, OUTPUT);
// initialize SPI:
SPI.begin(); 
//Reset the CPLD
myCAM1.write_reg(0x07, 0x80);
delay(100);
myCAM1.write_reg(0x07, 0x00);
delay(100);  
  //Check if the 4 ArduCAM Mini 2MP Cameras' SPI bus is OK
  while(1){
  myCAM1.write_reg(ARDUCHIP_TEST1, 0x55);
  temp = myCAM1.read_reg(ARDUCHIP_TEST1);
  if(temp != 0x55)
  {
    Serial.println(F("SPI1 interface Error!"));
  }else{
      CAM1_EXIST = true;
      Serial.println(F("SPI1 interface OK."));
    }
 
    if(!(CAM1_EXIST)){
    delay(1000);continue;
    }else
    break;
  }
  //Initialize SD Card
  while(!SD.begin(SD_CS)){
    Serial.println(F("SD Card Error"));delay(1000);
  }
  Serial.println(F("SD Card detected."));
    
  #if defined (OV2640_MINI_2MP)
  while(1){
      //Check if the camera module type is OV2640
     myCAM1.wrSensorReg8_8(0xff, 0x01);
     myCAM1.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
     myCAM1.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
     if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))){
      Serial.println(F("Can't find OV2640 module!"));
      delay(1000);continue;
      }else{
         Serial.println(F("OV2640 detected."));break;
        }
    } 
#elif defined (OV3640_MINI_3MP)
  while(1){
      //Check if the camera module type is OV2640
     myCAM1.rdSensorReg8_8(OV3640_CHIPID_HIGH, &vid);
     myCAM1.rdSensorReg8_8(OV3640_CHIPID_LOW, &pid);
     if ((vid != 0x36 ) && ( pid != 0x4C)){
      Serial.println(F("Can't find OV3640 module!"));
      delay(1000);continue;
      }else{
         Serial.println(F("OV3640 detected."));break;
        }
    } 
  #else
  while(1){
   //Check if the camera module type is OV5642
    myCAM1.wrSensorReg16_8(0xff, 0x01);
    myCAM1.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
    myCAM1.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
     if((vid != 0x56) || (pid != 0x42)){
       Serial.println(F("Can't find OV5642 module!"));
       delay(1000);continue;
      }else{
        Serial.println(F("OV5642 detected."));break;
     }   
  }
   #endif
    myCAM1.set_format(JPEG);
    myCAM1.InitCAM();
  #if defined (OV2640_MINI_2MP)
    myCAM1.OV2640_set_JPEG_size(OV2640_640x480);
  #elif defined (OV3640_MINI_3MP)
    myCAM1.OV3640_set_JPEG_size(OV3640_640x480);
  #else
    myCAM1.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);   //VSYNC is active HIGH
    myCAM1.OV5642_set_JPEG_size(OV5642_320x240);
 #endif
  delay(1000);
  myCAM1.clear_fifo_flag();
}


void loop() {
 if(BTSerial.available())
  {
    char Data = BTSerial.read();
 


  Serial.println(Data);
  if(Data == '1' ){
  if(CAM1_EXIST)
    myCAMSaveToSDFile(myCAM1);
    delay(5000);
    }
  }
}


void myCAMSaveToSDFile(ArduCAM myCAM){
  char str[8];
  byte buf[256];
  static int i = 0;
  static int k = 0;
  uint8_t temp = 0,temp_last=0;
  uint32_t length = 0;
  bool is_header = false;
  File outFile;
  //Flush the FIFO
  myCAM.flush_fifo();
  //Clear the capture done flag
  myCAM.clear_fifo_flag();
  //Start capture
  myCAM.start_capture();
  Serial.println("start Capture");
 while(!myCAM.get_bit(ARDUCHIP_TRIG , CAP_DONE_MASK));
 Serial.println(F("Capture Done."));  
 length = myCAM.read_fifo_length();
 Serial.print(F("The fifo length is :"));
 Serial.println(length, DEC);
  if (length >= MAX_FIFO_SIZE) //384K
  {
    Serial.println(F("Over size."));
    return ;
  }
    if (length == 0 ) //0 kb
  {
    Serial.println(F("Size is 0."));
    return ;
  }
 //Construct a file name
 k = k + 1;
 itoa(k, str, 10);
 strcat(str, ".jpg");
 //Open the new file
 outFile = SD.open(str, O_WRITE | O_CREAT | O_TRUNC);
 if(!outFile){
  Serial.println(F("File open faild"));
  return;
 }
myCAM.CS_LOW();
 myCAM.set_fifo_burst();
while ( length-- )
  {
    temp_last = temp;
    temp =  SPI.transfer(0x00);
    //Read JPEG data from FIFO
    if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
    {
        buf[i++] = temp;  //save the last  0XD9     
       //Write the remain bytes in the buffer
        myCAM.CS_HIGH();
        outFile.write(buf, i);    
      //Close the file
        outFile.close();
        Serial.println(F("Image save OK."));
        is_header = false;
        i = 0;
    }  
    if (is_header == true)
    { 
       //Write image data to buffer if not full
        if (i < 256)
        buf[i++] = temp;
        else
        {
          //Write 256 bytes image data to file
          myCAM.CS_HIGH();
          outFile.write(buf, 256);
          i = 0;
          buf[i++] = temp;
          myCAM.CS_LOW();
          myCAM.set_fifo_burst();
        }        
    }
    else if ((temp == 0xD8) & (temp_last == 0xFF))
    {
      is_header = true;
      buf[i++] = temp_last;
      buf[i++] = temp;   
    } 
  } 
}

 

참고자료

카메라 사진 촬영을 위한 법률, 흡연 단속 실태 

 

흡연 감지 카메라

 

 

 

반응형