#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <WiFi.h>
#include <WebServer.h>
#include <DHT.h>
#include <DHT_U.h>
// تعاریف سختافزاری و وایفای
#define SDA_PIN 21
#define SCL_PIN 22
#define TRIG_PIN 25
#define ECHO_PIN 26
#define BUTTON_PIN 14
#define DHT_PIN 13 // پینی که DHT22 را به آن وصل میکنید (مثلاً GPIO 13)
#define DHT_TYPE DHT22 // نوع سنسور
#define LDR_PIN 34 // GPIO34 فقط ورودی آنالوگ
#define PIR_PIN 32 // پین PIR
bool pirState = false; // وضعیت حرکت
#define MQ2_PIN 35 // GPIO آنالوگ برای MQ-2
int mq2Value = 0; // مقدار خوانده شده از سنسور
unsigned long mq2LastReadTime = 0;
const unsigned long mq2ReadInterval = 2000; // هر 2 ثانیه
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
// تنظیمات OLED (128x64)
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_I2C_ADDRESS 0x3C
#define PIR_FRAME_DELAY 42
#define PIR_FRAME_WIDTH 64
#define PIR_FRAME_HEIGHT 64
#define PIR_FRAME_COUNT (sizeof(pirFrames) / sizeof(pirFrames[0]))
const byte PROGMEM pirFrames[][512] ={
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,224,0,0,0,0,0,0,127,248,0,0,0,0,0,0,248,60,0,0,0,0,0,1,224,28,0,0,0,0,0,7,128,14,0,0,0,0,0,15,0,15,0,0,0,0,0,30,0,15,0,0,0,0,0,56,0,31,128,0,0,0,0,112,112,29,192,0,0,0,0,224,240,25,224,0,0,0,0,225,240,24,252,0,0,0,0,199,240,60,127,128,0,0,1,199,96,60,31,192,0,0,1,206,96,62,1,224,0,0,3,142,224,119,128,224,0,0,3,140,224,115,240,224,0,0,7,28,192,113,255,224,0,0,7,24,192,96,63,224,0,0,6,57,192,224,3,128,0,0,7,49,192,224,0,0,0,0,7,241,192,224,0,0,0,0,3,225,192,112,0,0,0,0,0,129,192,120,0,0,0,0,0,3,224,56,0,0,0,0,0,3,248,28,0,0,0,0,0,3,188,14,0,0,0,0,0,3,30,15,0,0,0,0,0,3,15,7,0,0,0,0,0,7,15,131,128,0,0,0,0,7,31,195,128,0,0,0,0,14,29,225,128,0,0,0,0,30,28,225,128,0,0,0,0,28,24,97,192,0,0,0,0,56,56,97,192,0,0,0,0,112,112,112,192,0,0,0,0,240,240,112,192,0,0,0,0,224,224,48,224,0,0,0,1,193,192,48,224,0,0,0,3,131,128,56,96,0,0,0,3,135,0,56,96,0,0,0,3,135,0,24,96,0,0,0,3,142,0,28,224,0,0,0,1,252,0,15,224,0,0,0,0,248,0,15,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,31,240,0,0,0,0,0,0,127,248,0,0,0,0,0,0,248,60,0,0,0,0,0,1,224,28,0,0,0,0,0,7,128,14,0,0,0,0,0,15,0,15,0,0,0,0,0,30,0,15,0,0,0,0,0,60,0,31,128,0,0,0,0,112,112,29,192,0,0,0,0,112,240,25,192,0,0,0,0,225,240,24,248,0,0,0,0,227,240,56,127,0,0,0,0,199,96,60,31,192,0,0,1,198,96,62,3,192,0,0,1,206,224,127,0,224,0,0,3,142,224,119,240,224,0,0,3,156,192,115,255,224,0,0,3,28,192,96,127,192,0,0,7,25,192,224,7,128,0,0,7,57,192,224,0,0,0,0,7,241,192,224,0,0,0,0,3,241,192,112,0,0,0,0,0,193,224,120,0,0,0,0,0,3,240,56,0,0,0,0,0,3,248,28,0,0,0,0,0,3,188,14,0,0,0,0,0,3,30,14,0,0,0,0,0,3,15,7,0,0,0,0,0,3,15,131,0,0,0,0,0,7,15,195,128,0,0,0,0,15,29,195,128,0,0,0,0,14,28,225,128,0,0,0,0,28,24,225,192,0,0,0,0,56,56,97,192,0,0,0,0,120,120,112,192,0,0,0,0,112,112,112,192,0,0,0,0,224,224,112,224,0,0,0,1,193,192,48,224,0,0,0,1,131,192,56,96,0,0,0,3,135,128,56,96,0,0,0,3,135,0,24,96,0,0,0,1,206,0,28,224,0,0,0,1,252,0,15,224,0,0,0,0,248,0,15,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,31,240,0,0,0,0,0,0,127,248,0,0,0,0,0,0,240,28,0,0,0,0,0,1,224,28,0,0,0,0,0,3,192,14,0,0,0,0,0,15,0,14,0,0,0,0,0,30,0,15,0,0,0,0,0,60,16,31,0,0,0,0,0,56,120,31,128,0,0,0,0,112,240,25,192,0,0,0,0,113,240,25,224,0,0,0,0,99,240,56,252,0,0,0,0,227,224,60,127,0,0,0,0,231,224,60,15,128,0,0,0,199,224,126,3,192,0,0,1,206,224,119,193,192,0,0,1,206,192,119,249,192,0,0,3,141,192,97,255,128,0,0,3,157,192,224,63,128,0,0,3,157,192,224,4,0,0,0,3,249,192,224,0,0,0,0,1,249,192,112,0,0,0,0,1,241,224,112,0,0,0,0,0,1,240,56,0,0,0,0,0,3,248,28,0,0,0,0,0,3,184,28,0,0,0,0,0,3,156,14,0,0,0,0,0,3,142,7,0,0,0,0,0,3,143,7,0,0,0,0,0,3,15,131,0,0,0,0,0,7,15,195,128,0,0,0,0,14,29,195,128,0,0,0,0,30,28,225,128,0,0,0,0,60,28,225,192,0,0,0,0,56,56,97,192,0,0,0,0,112,112,112,192,0,0,0,0,224,224,112,224,0,0,0,1,193,224,48,224,0,0,0,1,195,192,56,96,0,0,0,1,131,128,56,96,0,0,0,1,199,0,24,96,0,0,0,1,254,0,28,224,0,0,0,0,252,0,15,224,0,0,0,0,56,0,15,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,192,0,0,0,0,0,0,63,240,0,0,0,0,0,0,127,248,0,0,0,0,0,0,240,28,0,0,0,0,0,1,224,28,0,0,0,0,0,3,192,14,0,0,0,0,0,7,128,14,0,0,0,0,0,14,0,15,0,0,0,0,0,28,48,31,0,0,0,0,0,56,120,31,128,0,0,0,0,56,240,27,128,0,0,0,0,49,240,57,192,0,0,0,0,113,240,57,240,0,0,0,0,115,224,56,252,0,0,0,0,115,224,60,63,0,0,0,0,99,224,124,15,0,0,0,0,231,224,127,3,128,0,0,0,231,192,127,195,128,0,0,0,199,192,103,255,0,0,0,1,199,192,224,255,0,0,0,1,207,192,224,30,0,0,0,1,223,192,224,0,0,0,0,0,253,192,112,0,0,0,0,0,249,224,112,0,0,0,0,0,1,224,56,0,0,0,0,0,1,240,56,0,0,0,0,0,1,184,28,0,0,0,0,0,1,156,28,0,0,0,0,0,1,158,14,0,0,0,0,0,3,142,6,0,0,0,0,0,3,143,7,0,0,0,0,0,3,143,135,0,0,0,0,0,7,15,131,128,0,0,0,0,14,13,195,128,0,0,0,0,28,28,193,128,0,0,0,0,56,60,225,192,0,0,0,0,112,56,225,192,0,0,0,0,240,112,112,224,0,0,0,0,224,224,112,224,0,0,0,0,193,192,56,96,0,0,0,0,195,128,56,96,0,0,0,0,231,0,24,96,0,0,0,0,255,0,31,224,0,0,0,0,126,0,15,192,0,0,0,0,0,0,7,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,7,3,0,0,0,0,0,0,3,223,0,0,0,0,0,0,3,254,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,192,0,0,0,0,0,0,63,240,0,0,0,0,0,0,127,248,0,0,0,0,0,0,240,28,0,0,0,0,0,1,224,12,0,0,0,0,0,3,192,14,0,0,0,0,0,7,128,14,0,0,0,0,0,15,0,30,0,0,0,0,0,30,24,31,0,0,0,0,0,28,56,31,0,0,0,0,0,24,112,31,0,0,0,0,0,56,240,59,128,0,0,0,0,57,224,59,192,0,0,0,0,57,224,57,240,0,0,0,0,49,224,56,252,0,0,0,0,51,224,120,62,0,0,0,0,115,224,124,14,0,0,0,0,115,192,127,6,0,0,0,0,115,192,111,206,0,0,0,0,103,192,227,254,0,0,0,0,103,192,224,124,0,0,0,0,231,192,224,0,0,0,0,0,127,192,112,0,0,0,0,0,127,224,112,0,0,0,0,0,57,224,48,0,0,0,0,0,1,240,56,0,0,0,0,0,1,248,24,0,0,0,0,0,1,248,28,0,0,0,0,0,1,220,12,0,0,0,0,0,1,206,14,0,0,0,0,0,1,206,14,0,0,0,0,0,3,143,7,0,0,0,0,0,7,143,135,0,0,0,0,0,15,15,131,128,0,0,0,0,30,15,195,128,0,0,0,0,60,29,193,192,0,0,0,0,120,56,225,192,0,0,0,0,112,112,224,224,0,0,0,0,224,240,112,224,0,0,0,0,225,224,56,96,0,0,0,0,227,192,56,96,0,0,0,0,127,128,28,96,0,0,0,0,127,0,31,224,0,0,0,0,30,0,15,192,0,0,0,0,0,0,7,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,112,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,7,3,0,0,0,0,0,0,3,255,0,0,0,0,0,0,3,254,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,224,0,0,0,0,0,0,63,240,0,0,0,0,0,0,127,248,0,0,0,0,0,0,240,28,0,0,0,0,0,1,224,12,0,0,0,0,0,1,192,12,0,0,0,0,0,3,128,12,0,0,0,0,0,7,8,28,0,0,0,0,0,15,24,30,0,0,0,0,0,14,56,30,0,0,0,0,0,28,112,30,0,0,0,0,0,28,240,62,0,0,0,0,0,28,224,63,128,0,0,0,0,24,224,51,192,0,0,0,0,25,224,49,224,0,0,0,0,25,224,112,240,0,0,0,0,57,224,124,48,0,0,0,0,57,192,127,48,0,0,0,0,57,192,111,240,0,0,0,0,57,192,227,240,0,0,0,0,57,192,224,224,0,0,0,0,59,192,224,0,0,0,0,0,63,192,96,0,0,0,0,0,31,224,112,0,0,0,0,0,1,224,112,0,0,0,0,0,1,240,48,0,0,0,0,0,1,240,56,0,0,0,0,0,0,248,56,0,0,0,0,0,0,220,24,0,0,0,0,0,0,220,28,0,0,0,0,0,1,206,28,0,0,0,0,0,7,206,12,0,0,0,0,0,15,15,14,0,0,0,0,0,30,15,14,0,0,0,0,0,60,31,135,0,0,0,0,0,120,63,135,0,0,0,0,0,224,121,195,0,0,0,0,0,225,225,195,128,0,0,0,0,227,192,195,128,0,0,0,0,127,128,225,128,0,0,0,0,127,0,97,128,0,0,0,0,28,0,97,128,0,0,0,0,0,0,127,128,0,0,0,0,0,0,63,0,0,0,0,0,0,0,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,128,0,0,0,0,0,7,7,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,224,0,0,0,0,0,0,63,248,0,0,0,0,0,0,127,248,0,0,0,0,0,0,240,28,0,0,0,0,0,0,224,12,0,0,0,0,0,1,192,12,0,0,0,0,0,3,192,12,0,0,0,0,0,3,140,28,0,0,0,0,0,7,28,28,0,0,0,0,0,14,56,28,0,0,0,0,0,14,56,28,0,0,0,0,0,12,112,60,0,0,0,0,0,12,240,62,0,0,0,0,0,12,224,63,0,0,0,0,0,12,224,55,128,0,0,0,0,12,224,115,128,0,0,0,0,12,224,121,128,0,0,0,0,12,224,125,128,0,0,0,0,28,224,255,128,0,0,0,0,12,224,239,128,0,0,0,0,28,192,224,0,0,0,0,0,15,192,224,0,0,0,0,0,15,192,224,0,0,0,0,0,7,224,96,0,0,0,0,0,0,224,112,0,0,0,0,0,0,240,112,0,0,0,0,0,0,240,112,0,0,0,0,0,0,248,48,0,0,0,0,0,0,248,48,0,0,0,0,0,1,248,56,0,0,0,0,0,7,220,56,0,0,0,0,0,15,140,24,0,0,0,0,0,62,14,24,0,0,0,0,0,124,14,28,0,0,0,0,0,112,62,28,0,0,0,0,0,224,255,12,0,0,0,0,0,225,231,14,0,0,0,0,0,255,195,14,0,0,0,0,0,127,3,134,0,0,0,0,0,62,3,134,0,0,0,0,0,0,1,134,0,0,0,0,0,0,1,206,0,0,0,0,0,0,1,254,0,0,0,0,0,0,0,252,0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,0,0,0,0,3,254,0,0,0,0,0,0,3,143,0,0,0,0,0,0,7,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,128,0,0,0,0,0,7,7,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,224,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,56,0,0,0,0,0,0,112,28,0,0,0,0,0,0,224,12,0,0,0,0,0,1,192,12,0,0,0,0,0,1,192,12,0,0,0,0,0,3,140,28,0,0,0,0,0,3,156,28,0,0,0,0,0,7,28,24,0,0,0,0,0,6,56,24,0,0,0,0,0,14,112,56,0,0,0,0,0,14,112,56,0,0,0,0,0,6,112,56,0,0,0,0,0,6,112,60,0,0,0,0,0,6,112,124,0,0,0,0,0,6,112,124,0,0,0,0,0,6,112,124,0,0,0,0,0,6,112,252,0,0,0,0,0,6,112,248,0,0,0,0,0,7,112,224,0,0,0,0,0,7,240,224,0,0,0,0,0,3,224,224,0,0,0,0,0,1,224,224,0,0,0,0,0,0,224,96,0,0,0,0,0,0,224,96,0,0,0,0,0,0,112,96,0,0,0,0,0,0,112,96,0,0,0,0,0,0,240,112,0,0,0,0,0,7,248,112,0,0,0,0,0,31,248,112,0,0,0,0,0,126,28,112,0,0,0,0,0,120,28,48,0,0,0,0,0,224,60,48,0,0,0,0,0,224,252,56,0,0,0,0,0,227,252,56,0,0,0,0,0,127,206,56,0,0,0,0,0,63,14,24,0,0,0,0,0,24,14,24,0,0,0,0,0,0,6,28,0,0,0,0,0,0,7,28,0,0,0,0,0,0,7,24,0,0,0,0,0,0,7,248,0,0,0,0,0,0,3,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,143,0,0,0,0,0,0,7,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,224,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,60,0,0,0,0,0,0,112,28,0,0,0,0,0,0,224,12,0,0,0,0,0,0,224,12,0,0,0,0,0,1,192,12,0,0,0,0,0,1,206,28,0,0,0,0,0,3,142,28,0,0,0,0,0,3,156,24,0,0,0,0,0,7,24,24,0,0,0,0,0,7,56,56,0,0,0,0,0,7,48,56,0,0,0,0,0,7,48,48,0,0,0,0,0,7,56,112,0,0,0,0,0,3,56,112,0,0,0,0,0,3,56,112,0,0,0,0,0,3,56,96,0,0,0,0,0,3,152,224,0,0,0,0,0,3,152,224,0,0,0,0,0,3,184,224,0,0,0,0,0,1,248,224,0,0,0,0,0,1,240,224,0,0,0,0,0,0,192,224,0,0,0,0,0,0,224,224,0,0,0,0,0,0,224,224,0,0,0,0,0,0,96,224,0,0,0,0,0,0,112,224,0,0,0,0,0,7,240,224,0,0,0,0,0,63,240,224,0,0,0,0,0,126,48,224,0,0,0,0,0,240,56,224,0,0,0,0,0,192,56,96,0,0,0,0,0,192,248,96,0,0,0,0,0,231,248,96,0,0,0,0,0,127,248,96,0,0,0,0,0,126,24,96,0,0,0,0,0,0,24,96,0,0,0,0,0,0,24,112,0,0,0,0,0,0,24,112,0,0,0,0,0,0,28,112,0,0,0,0,0,0,28,224,0,0,0,0,0,0,31,224,0,0,0,0,0,0,7,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,7,3,0,0,0,0,0,0,7,223,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,224,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,56,0,0,0,0,0,0,112,28,0,0,0,0,0,0,224,12,0,0,0,0,0,0,224,12,0,0,0,0,0,0,192,12,0,0,0,0,0,1,198,28,0,0,0,0,0,1,206,28,0,0,0,0,0,1,140,24,0,0,0,0,0,3,156,24,0,0,0,0,0,3,156,56,0,0,0,0,0,3,24,56,0,0,0,0,0,3,152,48,0,0,0,0,0,3,156,48,0,0,0,0,0,3,156,112,0,0,0,0,0,1,156,112,0,0,0,0,0,1,204,96,0,0,0,0,0,1,206,224,0,0,0,0,0,1,206,224,0,0,0,0,0,1,238,224,0,0,0,0,0,1,252,192,0,0,0,0,0,1,252,192,0,0,0,0,0,1,240,192,0,0,0,0,0,0,192,192,0,0,0,0,0,0,224,192,0,0,0,0,0,0,224,192,0,0,0,0,0,0,224,192,0,0,0,0,0,0,224,192,0,0,0,0,0,3,224,192,0,0,0,0,0,7,225,192,0,0,0,0,0,15,113,192,0,0,0,0,0,28,113,192,0,0,0,0,0,24,113,192,0,0,0,0,0,28,241,192,0,0,0,0,0,31,241,192,0,0,0,0,0,15,241,192,0,0,0,0,0,0,113,192,0,0,0,0,0,0,113,192,0,0,0,0,0,0,113,192,0,0,0,0,0,0,113,192,0,0,0,0,0,0,113,192,0,0,0,0,0,0,63,128,0,0,0,0,0,0,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,224,0,0,0,0,0,0,63,248,0,0,0,0,0,0,63,248,0,0,0,0,0,0,112,28,0,0,0,0,0,0,96,12,0,0,0,0,0,0,224,12,0,0,0,0,0,0,224,12,0,0,0,0,0,0,198,28,0,0,0,0,0,1,198,28,0,0,0,0,0,1,206,28,0,0,0,0,0,1,206,24,0,0,0,0,0,1,204,56,0,0,0,0,0,3,156,56,0,0,0,0,0,3,156,48,0,0,0,0,0,1,206,48,0,0,0,0,0,1,206,112,0,0,0,0,0,1,198,112,0,0,0,0,0,0,231,96,0,0,0,0,0,1,231,224,0,0,0,0,0,1,227,224,0,0,0,0,0,1,243,224,0,0,0,0,0,1,255,192,0,0,0,0,0,1,255,192,0,0,0,0,0,1,220,192,0,0,0,0,0,1,193,192,0,0,0,0,0,1,193,192,0,0,0,0,0,0,193,192,0,0,0,0,0,0,193,192,0,0,0,0,0,0,193,128,0,0,0,0,0,0,193,128,0,0,0,0,0,0,225,128,0,0,0,0,0,1,227,128,0,0,0,0,0,3,227,128,0,0,0,0,0,3,227,128,0,0,0,0,0,3,195,128,0,0,0,0,0,3,195,128,0,0,0,0,0,1,195,128,0,0,0,0,0,1,195,128,0,0,0,0,0,0,195,128,0,0,0,0,0,0,195,0,0,0,0,0,0,0,195,0,0,0,0,0,0,0,199,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,126,0,0,0,0,0,0,0,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,143,0,0,0,0,0,0,7,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,224,0,0,0,0,0,0,63,240,0,0,0,0,0,0,63,248,0,0,0,0,0,0,112,28,0,0,0,0,0,0,96,12,0,0,0,0,0,0,96,12,0,0,0,0,0,0,224,12,0,0,0,0,0,0,231,28,0,0,0,0,0,1,231,28,0,0,0,0,0,1,198,28,0,0,0,0,0,1,198,24,0,0,0,0,0,3,206,56,0,0,0,0,0,3,206,56,0,0,0,0,0,3,206,48,0,0,0,0,0,3,199,48,0,0,0,0,0,3,231,112,0,0,0,0,0,3,227,240,0,0,0,0,0,3,243,224,0,0,0,0,0,1,241,224,0,0,0,0,0,1,241,224,0,0,0,0,0,1,249,224,0,0,0,0,0,1,223,192,0,0,0,0,0,1,223,192,0,0,0,0,0,1,207,192,0,0,0,0,0,1,193,192,0,0,0,0,0,1,193,128,0,0,0,0,0,1,195,192,0,0,0,0,0,1,195,192,0,0,0,0,0,1,195,192,0,0,0,0,0,1,195,224,0,0,0,0,0,1,195,224,0,0,0,0,0,1,135,224,0,0,0,0,0,1,135,192,0,0,0,0,0,1,135,128,0,0,0,0,0,1,135,0,0,0,0,0,0,3,135,0,0,0,0,0,0,3,134,0,0,0,0,0,0,3,134,0,0,0,0,0,0,3,142,0,0,0,0,0,0,3,142,0,0,0,0,0,0,3,142,0,0,0,0,0,0,3,142,0,0,0,0,0,0,3,252,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,0,0,0,0,3,254,0,0,0,0,0,0,3,255,0,0,0,0,0,0,7,7,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,128,0,0,0,0,0,7,7,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,192,0,0,0,0,0,0,63,240,0,0,0,0,0,0,63,248,0,0,0,0,0,0,112,28,0,0,0,0,0,0,112,12,0,0,0,0,0,0,96,12,0,0,0,0,0,0,224,12,0,0,0,0,0,3,227,28,0,0,0,0,0,7,227,28,0,0,0,0,0,7,231,28,0,0,0,0,0,7,231,24,0,0,0,0,0,6,231,56,0,0,0,0,0,6,199,56,0,0,0,0,0,14,199,56,0,0,0,0,0,14,199,48,0,0,0,0,0,12,227,240,0,0,0,0,0,12,241,240,0,0,0,0,0,15,241,224,0,0,0,0,0,7,248,224,0,0,0,0,0,1,220,96,0,0,0,0,0,1,220,112,0,0,0,0,0,1,206,240,0,0,0,0,0,1,207,224,0,0,0,0,0,1,135,192,0,0,0,0,0,1,129,192,0,0,0,0,0,1,131,192,0,0,0,0,0,1,131,224,0,0,0,0,0,3,131,96,0,0,0,0,0,3,135,112,0,0,0,0,0,3,135,48,0,0,0,0,0,3,14,48,0,0,0,0,0,3,14,112,0,0,0,0,0,3,14,112,0,0,0,0,0,7,14,224,0,0,0,0,0,7,12,224,0,0,0,0,0,7,13,192,0,0,0,0,0,7,29,192,0,0,0,0,0,6,31,128,0,0,0,0,0,6,31,0,0,0,0,0,0,14,24,0,0,0,0,0,0,14,24,0,0,0,0,0,0,14,56,0,0,0,0,0,0,7,248,0,0,0,0,0,0,7,240,0,0,0,0,0,0,3,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,112,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,128,0,0,0,0,0,7,7,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,192,0,0,0,0,0,0,31,240,0,0,0,0,0,0,63,248,0,0,0,0,0,0,112,28,0,0,0,0,0,0,112,28,0,0,0,0,0,1,224,12,0,0,0,0,0,3,224,12,0,0,0,0,0,7,227,12,0,0,0,0,0,15,99,28,0,0,0,0,0,14,99,28,0,0,0,0,0,12,227,24,0,0,0,0,0,28,227,56,0,0,0,0,0,28,231,56,0,0,0,0,0,24,231,184,0,0,0,0,0,57,227,240,0,0,0,0,0,57,241,240,0,0,0,0,0,57,248,240,0,0,0,0,0,63,248,112,0,0,0,0,0,31,220,56,0,0,0,0,0,15,206,56,0,0,0,0,0,1,199,56,0,0,0,0,0,1,195,248,0,0,0,0,0,1,195,240,0,0,0,0,0,1,129,224,0,0,0,0,0,1,129,224,0,0,0,0,0,1,131,224,0,0,0,0,0,1,131,240,0,0,0,0,0,3,131,112,0,0,0,0,0,3,135,56,0,0,0,0,0,3,135,24,0,0,0,0,0,3,135,24,0,0,0,0,0,3,15,56,0,0,0,0,0,7,15,56,0,0,0,0,0,7,15,56,0,0,0,0,0,7,31,56,0,0,0,0,0,6,31,56,0,0,0,0,0,14,31,48,0,0,0,0,0,14,63,112,0,0,0,0,0,12,63,240,0,0,0,0,0,28,51,224,0,0,0,0,0,28,113,192,0,0,0,0,0,28,112,0,0,0,0,0,0,31,224,0,0,0,0,0,0,15,224,0,0,0,0,0,0,7,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,112,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,7,3,0,0,0,0,0,0,3,255,0,0,0,0,0,0,3,254,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,31,240,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,28,0,0,0,0,0,0,240,28,0,0,0,0,0,3,224,12,0,0,0,0,0,7,224,12,0,0,0,0,0,15,99,12,0,0,0,0,0,28,99,28,0,0,0,0,0,28,99,28,0,0,0,0,0,24,227,24,0,0,0,0,0,56,227,24,0,0,0,0,0,57,227,184,0,0,0,0,0,49,227,184,0,0,0,0,0,113,241,240,0,0,0,0,0,115,240,240,0,0,0,0,0,99,248,120,0,0,0,0,0,127,222,60,0,0,0,0,0,63,207,28,0,0,0,0,0,29,199,142,0,0,0,0,0,1,195,206,0,0,0,0,0,1,193,252,0,0,0,0,0,1,193,248,0,0,0,0,0,1,129,240,0,0,0,0,0,1,129,224,0,0,0,0,0,1,131,240,0,0,0,0,0,1,131,184,0,0,0,0,0,3,131,56,0,0,0,0,0,3,135,28,0,0,0,0,0,3,135,12,0,0,0,0,0,3,135,140,0,0,0,0,0,3,15,140,0,0,0,0,0,7,15,140,0,0,0,0,0,7,15,142,0,0,0,0,0,14,29,142,0,0,0,0,0,14,25,142,0,0,0,0,0,28,57,142,0,0,0,0,0,28,57,206,0,0,0,0,0,24,113,206,0,0,0,0,0,56,113,254,0,0,0,0,0,48,224,252,0,0,0,0,0,48,224,120,0,0,0,0,0,57,192,0,0,0,0,0,0,31,128,0,0,0,0,0,0,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,31,240,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,60,0,0,0,0,0,1,240,28,0,0,0,0,0,3,224,12,0,0,0,0,0,15,224,12,0,0,0,0,0,31,115,12,0,0,0,0,0,28,115,156,0,0,0,0,0,24,115,156,0,0,0,0,0,56,243,152,0,0,0,0,0,57,243,152,0,0,0,0,0,113,243,184,0,0,0,0,0,113,241,248,0,0,0,0,0,115,240,240,0,0,0,0,0,99,248,120,0,0,0,0,0,227,252,60,0,0,0,0,0,127,222,30,0,0,0,0,0,127,207,135,0,0,0,0,0,61,195,199,0,0,0,0,0,1,193,231,0,0,0,0,0,1,192,254,0,0,0,0,0,1,193,254,0,0,0,0,0,1,129,240,0,0,0,0,0,1,129,240,0,0,0,0,0,1,131,184,0,0,0,0,0,1,131,188,0,0,0,0,0,3,131,28,0,0,0,0,0,3,135,14,0,0,0,0,0,3,135,14,0,0,0,0,0,3,135,134,0,0,0,0,0,3,143,134,0,0,0,0,0,7,15,135,0,0,0,0,0,7,13,199,0,0,0,0,0,14,29,195,0,0,0,0,0,28,56,195,0,0,0,0,0,28,56,195,128,0,0,0,0,56,112,227,128,0,0,0,0,120,112,227,128,0,0,0,0,112,224,99,128,0,0,0,0,96,192,119,128,0,0,0,0,97,192,127,0,0,0,0,0,115,128,30,0,0,0,0,0,127,128,0,0,0,0,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,224,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,60,0,0,0,0,0,0,240,28,0,0,0,0,0,3,224,12,0,0,0,0,0,7,224,12,0,0,0,0,0,15,115,12,0,0,0,0,0,30,115,156,0,0,0,0,0,28,115,156,0,0,0,0,0,24,243,152,0,0,0,0,0,56,243,152,0,0,0,0,0,49,241,184,0,0,0,0,0,113,241,248,0,0,0,0,0,115,240,240,0,0,0,0,0,99,248,124,0,0,0,0,0,227,252,30,0,0,0,0,0,127,223,15,0,0,0,0,0,127,199,135,0,0,0,0,0,61,195,227,128,0,0,0,0,1,192,247,0,0,0,0,0,1,192,255,0,0,0,0,0,1,193,254,0,0,0,0,0,1,129,240,0,0,0,0,0,1,129,240,0,0,0,0,0,1,131,184,0,0,0,0,0,1,131,156,0,0,0,0,0,3,131,14,0,0,0,0,0,3,135,14,0,0,0,0,0,3,135,134,0,0,0,0,0,3,135,135,0,0,0,0,0,3,143,135,0,0,0,0,0,7,15,195,0,0,0,0,0,15,13,195,128,0,0,0,0,14,28,195,128,0,0,0,0,28,28,225,128,0,0,0,0,60,56,225,192,0,0,0,0,56,112,97,192,0,0,0,0,112,112,113,192,0,0,0,0,240,224,112,192,0,0,0,0,225,192,49,192,0,0,0,0,225,192,63,192,0,0,0,0,227,128,31,128,0,0,0,0,127,0,14,0,0,0,0,0,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,143,0,0,0,0,0,0,7,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,31,240,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,60,0,0,0,0,0,0,240,28,0,0,0,0,0,1,224,12,0,0,0,0,0,3,224,12,0,0,0,0,0,7,243,12,0,0,0,0,0,15,115,156,0,0,0,0,0,14,115,156,0,0,0,0,0,28,115,152,0,0,0,0,0,28,115,152,0,0,0,0,0,56,243,184,0,0,0,0,0,113,241,248,0,0,0,0,0,113,240,240,0,0,0,0,0,99,248,120,0,0,0,0,0,231,252,60,0,0,0,0,0,127,223,14,0,0,0,0,0,127,199,134,0,0,0,0,0,29,195,199,0,0,0,0,0,1,193,230,0,0,0,0,0,1,192,254,0,0,0,0,0,1,192,252,0,0,0,0,0,1,129,240,0,0,0,0,0,1,129,240,0,0,0,0,0,1,129,184,0,0,0,0,0,1,131,188,0,0,0,0,0,1,131,156,0,0,0,0,0,1,131,14,0,0,0,0,0,3,135,14,0,0,0,0,0,3,135,134,0,0,0,0,0,3,135,135,0,0,0,0,0,7,15,135,0,0,0,0,0,7,15,195,0,0,0,0,0,14,29,195,128,0,0,0,0,28,28,195,128,0,0,0,0,60,56,225,128,0,0,0,0,56,112,225,192,0,0,0,0,112,112,97,192,0,0,0,0,112,224,113,192,0,0,0,0,225,192,113,192,0,0,0,0,227,192,63,128,0,0,0,0,119,128,63,128,0,0,0,0,127,0,14,0,0,0,0,0,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,31,240,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,28,0,0,0,0,0,0,112,28,0,0,0,0,0,0,96,12,0,0,0,0,0,0,96,12,0,0,0,0,0,0,99,12,0,0,0,0,0,0,99,28,0,0,0,0,0,0,227,28,0,0,0,0,0,1,227,24,0,0,0,0,0,1,243,184,0,0,0,0,0,3,243,184,0,0,0,0,0,3,241,248,0,0,0,0,0,7,240,240,0,0,0,0,0,7,248,112,0,0,0,0,0,14,252,56,0,0,0,0,0,14,206,28,0,0,0,0,0,7,199,28,0,0,0,0,0,7,195,156,0,0,0,0,0,3,193,252,0,0,0,0,0,1,192,248,0,0,0,0,0,1,192,240,0,0,0,0,0,1,193,224,0,0,0,0,0,1,193,240,0,0,0,0,0,1,129,248,0,0,0,0,0,1,131,184,0,0,0,0,0,1,131,156,0,0,0,0,0,1,131,156,0,0,0,0,0,1,131,12,0,0,0,0,0,1,135,14,0,0,0,0,0,3,135,14,0,0,0,0,0,7,135,134,0,0,0,0,0,7,15,135,0,0,0,0,0,14,31,135,0,0,0,0,0,28,29,195,0,0,0,0,0,28,57,195,128,0,0,0,0,56,112,195,128,0,0,0,0,112,240,225,128,0,0,0,0,112,224,225,128,0,0,0,0,113,192,97,128,0,0,0,0,123,128,127,128,0,0,0,0,63,128,63,0,0,0,0,0,31,0,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,192,0,0,0,0,0,0,31,240,0,0,0,0,0,0,63,248,0,0,0,0,0,0,112,28,0,0,0,0,0,0,112,12,0,0,0,0,0,0,96,12,0,0,0,0,0,0,96,12,0,0,0,0,0,0,99,12,0,0,0,0,0,0,99,28,0,0,0,0,0,0,99,28,0,0,0,0,0,0,99,24,0,0,0,0,0,0,99,56,0,0,0,0,0,0,227,184,0,0,0,0,0,0,99,248,0,0,0,0,0,0,241,240,0,0,0,0,0,0,248,240,0,0,0,0,0,0,252,112,0,0,0,0,0,0,220,112,0,0,0,0,0,1,206,48,0,0,0,0,0,1,199,48,0,0,0,0,0,1,199,240,0,0,0,0,0,1,195,224,0,0,0,0,0,1,193,224,0,0,0,0,0,1,193,224,0,0,0,0,0,1,193,224,0,0,0,0,0,1,193,240,0,0,0,0,0,1,193,240,0,0,0,0,0,1,193,184,0,0,0,0,0,1,195,152,0,0,0,0,0,1,195,156,0,0,0,0,0,1,195,156,0,0,0,0,0,3,195,140,0,0,0,0,0,3,135,14,0,0,0,0,0,7,15,14,0,0,0,0,0,14,15,6,0,0,0,0,0,28,31,135,0,0,0,0,0,60,57,135,0,0,0,0,0,56,113,195,0,0,0,0,0,48,241,195,128,0,0,0,0,49,224,195,128,0,0,0,0,63,192,227,128,0,0,0,0,31,128,227,128,0,0,0,0,15,0,127,0,0,0,0,0,0,0,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,112,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,7,3,0,0,0,0,0,0,3,255,0,0,0,0,0,0,3,254,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,224,0,0,0,0,0,0,63,240,0,0,0,0,0,0,63,248,0,0,0,0,0,0,112,28,0,0,0,0,0,0,96,12,0,0,0,0,0,0,96,12,0,0,0,0,0,0,96,12,0,0,0,0,0,0,227,28,0,0,0,0,0,0,231,28,0,0,0,0,0,0,231,28,0,0,0,0,0,0,231,24,0,0,0,0,0,0,198,56,0,0,0,0,0,0,199,56,0,0,0,0,0,0,231,56,0,0,0,0,0,0,227,176,0,0,0,0,0,0,241,240,0,0,0,0,0,0,241,240,0,0,0,0,0,0,248,240,0,0,0,0,0,1,216,224,0,0,0,0,0,1,220,224,0,0,0,0,0,1,207,224,0,0,0,0,0,1,207,224,0,0,0,0,0,1,195,224,0,0,0,0,0,1,192,224,0,0,0,0,0,1,192,224,0,0,0,0,0,1,193,224,0,0,0,0,0,0,193,240,0,0,0,0,0,0,193,240,0,0,0,0,0,0,193,248,0,0,0,0,0,0,225,248,0,0,0,0,0,1,225,152,0,0,0,0,0,1,195,156,0,0,0,0,0,3,135,156,0,0,0,0,0,7,15,12,0,0,0,0,0,14,15,14,0,0,0,0,0,28,31,14,0,0,0,0,0,56,59,6,0,0,0,0,0,56,115,135,0,0,0,0,0,56,227,135,0,0,0,0,0,31,193,131,0,0,0,0,0,15,129,195,0,0,0,0,0,7,0,199,0,0,0,0,0,0,0,255,0,0,0,0,0,0,0,126,0,0,0,0,0,0,0,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,128,0,0,0,0,0,7,7,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,224,0,0,0,0,0,0,63,248,0,0,0,0,0,0,63,248,0,0,0,0,0,0,112,28,0,0,0,0,0,0,96,12,0,0,0,0,0,0,224,12,0,0,0,0,0,0,226,12,0,0,0,0,0,0,231,28,0,0,0,0,0,0,199,28,0,0,0,0,0,1,198,28,0,0,0,0,0,1,206,28,0,0,0,0,0,1,206,60,0,0,0,0,0,1,142,60,0,0,0,0,0,1,206,60,0,0,0,0,0,0,199,60,0,0,0,0,0,0,231,124,0,0,0,0,0,0,227,124,0,0,0,0,0,0,227,236,0,0,0,0,0,1,243,236,0,0,0,0,0,1,243,236,0,0,0,0,0,1,255,236,0,0,0,0,0,1,255,252,0,0,0,0,0,1,206,252,0,0,0,0,0,1,192,224,0,0,0,0,0,0,192,224,0,0,0,0,0,0,192,224,0,0,0,0,0,0,224,224,0,0,0,0,0,0,224,224,0,0,0,0,0,0,96,224,0,0,0,0,0,0,112,240,0,0,0,0,0,0,112,240,0,0,0,0,0,0,225,240,0,0,0,0,0,0,227,240,0,0,0,0,0,1,195,176,0,0,0,0,0,1,135,48,0,0,0,0,0,3,142,56,0,0,0,0,0,7,14,56,0,0,0,0,0,7,30,56,0,0,0,0,0,7,62,24,0,0,0,0,0,7,254,24,0,0,0,0,0,3,246,24,0,0,0,0,0,1,199,56,0,0,0,0,0,0,3,248,0,0,0,0,0,0,3,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,143,0,0,0,0,0,0,7,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,224,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,60,0,0,0,0,0,0,112,28,0,0,0,0,0,0,96,12,0,0,0,0,0,0,224,12,0,0,0,0,0,0,226,12,0,0,0,0,0,1,199,28,0,0,0,0,0,1,198,30,0,0,0,0,0,1,142,30,0,0,0,0,0,3,142,30,0,0,0,0,0,3,156,62,0,0,0,0,0,3,156,62,0,0,0,0,0,3,140,62,0,0,0,0,0,1,140,54,0,0,0,0,0,1,142,118,0,0,0,0,0,1,206,119,0,0,0,0,0,1,198,115,0,0,0,0,0,1,198,251,0,0,0,0,0,1,199,251,0,0,0,0,0,1,254,255,0,0,0,0,0,1,254,255,0,0,0,0,0,1,252,224,0,0,0,0,0,0,192,224,0,0,0,0,0,0,224,224,0,0,0,0,0,0,224,96,0,0,0,0,0,0,240,96,0,0,0,0,0,0,112,96,0,0,0,0,0,0,120,112,0,0,0,0,0,0,120,112,0,0,0,0,0,0,56,112,0,0,0,0,0,0,56,224,0,0,0,0,0,0,56,224,0,0,0,0,0,0,113,192,0,0,0,0,0,0,113,192,0,0,0,0,0,0,115,192,0,0,0,0,0,0,227,192,0,0,0,0,0,0,227,192,0,0,0,0,0,0,199,192,0,0,0,0,0,0,254,192,0,0,0,0,0,0,254,192,0,0,0,0,0,0,61,192,0,0,0,0,0,0,31,192,0,0,0,0,0,0,15,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,7,3,0,0,0,0,0,0,3,223,0,0,0,0,0,0,3,254,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,224,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,60,0,0,0,0,0,0,112,28,0,0,0,0,0,0,224,12,0,0,0,0,0,0,224,12,0,0,0,0,0,1,192,12,0,0,0,0,0,1,198,30,0,0,0,0,0,3,142,30,0,0,0,0,0,3,142,30,0,0,0,0,0,7,28,30,0,0,0,0,0,7,28,62,0,0,0,0,0,7,56,63,0,0,0,0,0,7,24,55,0,0,0,0,0,7,24,119,0,0,0,0,0,7,24,115,128,0,0,0,0,3,28,121,192,0,0,0,0,3,28,124,192,0,0,0,0,3,28,254,192,0,0,0,0,3,156,239,192,0,0,0,0,3,156,231,192,0,0,0,0,1,252,225,128,0,0,0,0,1,248,96,0,0,0,0,0,0,192,96,0,0,0,0,0,0,224,112,0,0,0,0,0,0,240,112,0,0,0,0,0,0,240,48,0,0,0,0,0,0,248,48,0,0,0,0,0,0,252,56,0,0,0,0,0,0,124,56,0,0,0,0,0,0,110,56,0,0,0,0,0,0,108,48,0,0,0,0,0,0,108,112,0,0,0,0,0,0,252,112,0,0,0,0,0,0,252,112,0,0,0,0,0,0,252,96,0,0,0,0,0,0,220,224,0,0,0,0,0,0,216,224,0,0,0,0,0,0,216,192,0,0,0,0,0,0,220,192,0,0,0,0,0,0,223,192,0,0,0,0,0,0,255,128,0,0,0,0,0,0,254,0,0,0,0,0,0,0,124,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,7,3,0,0,0,0,0,0,3,223,0,0,0,0,0,0,3,254,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,224,0,0,0,0,0,0,63,248,0,0,0,0,0,0,120,60,0,0,0,0,0,0,112,28,0,0,0,0,0,0,224,12,0,0,0,0,0,1,192,12,0,0,0,0,0,1,192,14,0,0,0,0,0,3,140,30,0,0,0,0,0,7,14,30,0,0,0,0,0,7,28,31,0,0,0,0,0,14,56,31,0,0,0,0,0,14,120,63,0,0,0,0,0,14,112,59,0,0,0,0,0,14,112,59,192,0,0,0,0,14,112,57,224,0,0,0,0,14,112,120,240,0,0,0,0,12,112,124,120,0,0,0,0,12,112,126,56,0,0,0,0,12,96,239,184,0,0,0,0,12,96,227,248,0,0,0,0,14,224,224,240,0,0,0,0,7,224,224,0,0,0,0,0,7,192,96,0,0,0,0,0,1,224,112,0,0,0,0,0,1,224,48,0,0,0,0,0,1,240,56,0,0,0,0,0,0,248,56,0,0,0,0,0,0,252,24,0,0,0,0,0,0,222,28,0,0,0,0,0,0,206,28,0,0,0,0,0,0,199,28,0,0,0,0,0,0,199,28,0,0,0,0,0,1,199,28,0,0,0,0,0,1,199,28,0,0,0,0,0,3,143,24,0,0,0,0,0,3,143,24,0,0,0,0,0,3,15,24,0,0,0,0,0,7,31,24,0,0,0,0,0,7,31,56,0,0,0,0,0,6,31,56,0,0,0,0,0,6,63,248,0,0,0,0,0,7,123,240,0,0,0,0,0,7,241,224,0,0,0,0,0,3,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,143,0,0,0,0,0,0,7,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,0,0,0,0,0,0,7,143,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,224,0,0,0,0,0,0,63,240,0,0,0,0,0,0,127,248,0,0,0,0,0,0,240,28,0,0,0,0,0,1,224,12,0,0,0,0,0,1,192,14,0,0,0,0,0,3,128,14,0,0,0,0,0,7,8,30,0,0,0,0,0,15,28,31,0,0,0,0,0,14,56,31,0,0,0,0,0,28,120,27,0,0,0,0,0,24,240,59,128,0,0,0,0,24,224,59,192,0,0,0,0,56,224,57,240,0,0,0,0,57,224,56,124,0,0,0,0,57,224,120,30,0,0,0,0,57,224,124,14,0,0,0,0,49,192,127,134,0,0,0,0,49,192,111,238,0,0,0,0,115,192,227,254,0,0,0,0,59,192,224,124,0,0,0,0,63,192,224,0,0,0,0,0,31,192,112,0,0,0,0,0,1,224,112,0,0,0,0,0,1,224,56,0,0,0,0,0,1,240,56,0,0,0,0,0,1,248,28,0,0,0,0,0,1,156,28,0,0,0,0,0,1,142,14,0,0,0,0,0,1,143,14,0,0,0,0,0,1,143,142,0,0,0,0,0,3,143,142,0,0,0,0,0,3,143,134,0,0,0,0,0,7,15,134,0,0,0,0,0,7,29,134,0,0,0,0,0,14,25,134,0,0,0,0,0,14,57,134,0,0,0,0,0,28,57,198,0,0,0,0,0,28,113,198,0,0,0,0,0,56,113,198,0,0,0,0,0,56,225,198,0,0,0,0,0,56,224,254,0,0,0,0,0,31,192,252,0,0,0,0,0,15,128,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,6,3,128,0,0,0,0,0,7,7,0,0,0,0,0,0,3,254,0,0,0,0,0,0,1,252,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,192,0,0,0,0,0,0,63,240,0,0,0,0,0,0,127,248,0,0,0,0,0,0,240,28,0,0,0,0,0,1,224,12,0,0,0,0,0,3,192,14,0,0,0,0,0,7,128,14,0,0,0,0,0,15,0,15,0,0,0,0,0,30,24,31,0,0,0,0,0,60,56,31,128,0,0,0,0,56,240,27,128,0,0,0,0,49,240,57,192,0,0,0,0,113,240,57,248,0,0,0,0,115,224,56,126,0,0,0,0,99,224,60,31,0,0,0,0,227,224,126,7,128,0,0,0,231,224,127,3,128,0,0,0,199,192,103,227,128,0,0,1,199,192,99,255,128,0,0,1,207,192,224,127,0,0,0,1,207,192,224,6,0,0,0,0,253,192,224,0,0,0,0,0,249,192,112,0,0,0,0,0,1,224,120,0,0,0,0,0,1,240,56,0,0,0,0,0,1,248,28,0,0,0,0,0,3,188,28,0,0,0,0,0,3,158,14,0,0,0,0,0,3,143,15,0,0,0,0,0,3,143,135,0,0,0,0,0,3,143,199,0,0,0,0,0,7,13,195,0,0,0,0,0,7,29,195,0,0,0,0,0,14,28,195,0,0,0,0,0,28,56,195,128,0,0,0,0,28,56,227,128,0,0,0,0,56,112,227,128,0,0,0,0,112,96,227,128,0,0,0,0,112,224,97,128,0,0,0,0,225,192,97,128,0,0,0,0,225,192,97,128,0,0,0,0,227,128,115,128,0,0,0,0,127,0,63,128,0,0,0,0,127,0,63,0,0,0,0,0,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,252,0,0,0,0,0,0,3,254,0,0,0,0,0,0,7,7,0,0,0,0,0,0,6,3,0,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,14,3,128,0,0,0,0,0,7,3,0,0,0,0,0,0,3,223,0,0,0,0,0,0,3,254,0,0,0,0,0,0,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,0,0,63,240,0,0,0,0,0,0,127,248,0,0,0,0,0,0,240,28,0,0,0,0,0,1,224,28,0,0,0,0,0,7,192,14,0,0,0,0,0,15,0,15,0,0,0,0,0,30,0,15,0,0,0,0,0,60,16,31,128,0,0,0,0,120,112,31,128,0,0,0,0,112,240,25,192,0,0,0,0,97,240,24,240,0,0,0,0,227,240,56,254,0,0,0,0,199,96,60,63,128,0,0,1,199,224,62,7,192,0,0,1,206,224,127,0,192,0,0,1,142,224,119,224,192,0,0,3,140,192,115,255,192,0,0,3,157,192,96,127,192,0,0,3,29,192,224,15,128,0,0,3,57,192,224,0,0,0,0,3,241,192,224,0,0,0,0,3,241,192,112,0,0,0,0,0,129,224,120,0,0,0,0,0,3,240,56,0,0,0,0,0,3,248,28,0,0,0,0,0,3,188,14,0,0,0,0,0,3,158,14,0,0,0,0,0,3,15,7,0,0,0,0,0,3,15,131,0,0,0,0,0,7,31,195,128,0,0,0,0,7,29,227,128,0,0,0,0,14,28,225,128,0,0,0,0,28,24,225,128,0,0,0,0,56,56,97,192,0,0,0,0,56,112,97,192,0,0,0,0,112,112,113,192,0,0,0,0,224,224,112,192,0,0,0,1,225,192,112,192,0,0,0,1,195,192,48,224,0,0,0,1,131,128,56,224,0,0,0,1,135,0,56,224,0,0,0,1,206,0,61,224,0,0,0,0,254,0,31,192,0,0,0,0,124,0,15,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
WebServer server(80);
// ساخت آبجکتهای سختافزاری
RTC_DS3231 rtc;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
DHT dht(DHT_PIN, DHT_TYPE);
// --- DHT variables ---
unsigned long dhtLastReadTime = 0;
const unsigned long dhtReadInterval = 2000; // هر 2 ثانیه
float lastHumidity = 0.0;
float lastTemperature = 0.0;
// --- LDR variables ---
int ldrValue = 0;
unsigned long ldrLastReadTime = 0;
const unsigned long ldrReadInterval = 1000; // هر ۱ ثانیه
// ----------------------------------------------------------------------
// --- متغیرهای وضعیت و تعاریف سراسری ---
// ----------------------------------------------------------------------
bool childWasSleeping = false;
long lastDistance = 0;
unsigned long heartDelayStart = 0;
bool heartDelayActive = false;
bool heartAnimationRunning = false;
uint8_t heartFrame = 0;
const uint8_t heartFrames = 8;
// وضعیت قرصها
enum PillState { WAIT_PILL1, PILL1_TAKEN, PILL2_READY, PILL2_TAKEN };
PillState pillState = WAIT_PILL1;
// حالت سیستم
enum SystemState {
WAIT_ULTRASONIC,
HAND_ANIMATION,
HEART_ANIMATION,
SHOW_TIME_PILLS
};
SystemState systemState = WAIT_ULTRASONIC;
// --- Hand Washing Animation (بدون تغییر) ---
uint8_t currentStep = 0;
uint16_t frameInStep = 0;
const uint8_t TOTAL_STEPS = 7;
const uint8_t framesPerStep[7] = {8, 8, 8, 67, 8, 8, 8};
void displayPrepare() {
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
}
// --- توابع Hand Drawing و Animation (بدون تغییر) ---
void drawHand(uint8_t x, uint8_t y, bool left) {
display.fillRoundRect(x + (left ? 0 : 6), y + 8, 12, 16, 2, SSD1306_WHITE);
display.fillRoundRect(x + (left ? 2 : 8), y + 2, 2, 8, 1, SSD1306_WHITE);
display.fillRoundRect(x + (left ? 5 : 11), y, 2, 10, 1, SSD1306_WHITE);
display.fillRoundRect(x + (left ? 8 : 14), y + 1, 2, 9, 1, SSD1306_WHITE);
display.fillRoundRect(x + (left ? 11 : 17), y + 3, 2, 7, 1, SSD1306_WHITE);
display.fillRoundRect(x + (left ? -2 : 4), y + 12, 4, 8, 1, SSD1306_WHITE);
}
void drawWater(uint8_t frame) {
for (int i = 0; i < 4; i++) {
uint8_t x = 58 + i - 2;
uint8_t y = 22 + i * 4 + (frame % 3);
display.drawPixel(x, y, SSD1306_WHITE);
}
}
void drawBubbles(uint8_t frame) {
for (int i = 0; i < 3; i++) {
uint8_t x = 45 + i * 15;
uint8_t y = 35 + (frame + i) % 4;
display.drawCircle(x, y, 2, SSD1306_WHITE);
}
}
// --- Steps ---
void step1_water(uint8_t frame){
display.setTextSize(1);
display.setCursor(25, 5);
display.print("Turn on water");
display.fillRect(50, 15, 20, 4, SSD1306_WHITE); // faucet top
display.fillRect(58, 19, 4, 6, SSD1306_WHITE); // faucet body
if(frame > 3) drawWater(frame);
uint8_t offset = frame < 6 ? frame : 6;
drawHand(35 + (6 - offset), 40, true);
drawHand(60 - (6 - offset), 40, false);
}
void step2_wet(uint8_t frame){
display.setTextSize(1);
display.setCursor(30, 5);
display.print("Wet hands");
display.fillRect(50, 15, 20, 4, SSD1306_WHITE);
display.fillRect(58, 19, 4, 6, SSD1306_WHITE);
drawWater(frame);
drawHand(41, 40, true);
drawHand(54, 40, false);
}
void step3_soap(uint8_t frame){
display.setTextSize(1);
display.setCursor(30, 5);
display.print("Apply soap");
display.fillRoundRect(15, 20, 8, 12, 2, SSD1306_WHITE); // Soap dispenser body
display.fillRoundRect(17, 17, 4, 4, 1, SSD1306_WHITE); // Dispenser pump
if(frame % 8 < 4) display.drawCircle(19, 32 + (frame % 4), 1, SSD1306_WHITE); // Soap drop
drawHand(50, 40, true);
drawHand(63, 40, false);
if(frame > 4) display.drawCircle(55, 45, 1, SSD1306_WHITE); // Soap on hand
}
void step4_scrub(uint8_t frame){
display.setTextSize(1);
display.setCursor(25, 5);
display.print("Scrub 20 sec");
uint8_t motion = (frame % 4 < 2) ? 1 : 0;
drawHand(45 + motion, 40 - motion, true);
drawHand(58 - motion, 40 + motion, false);
drawBubbles(frame);
display.setTextSize(2);
display.setCursor(85, 25);
display.print("20");
display.setTextSize(1);
display.drawRect(88, 38, 30, 8, SSD1306_WHITE);
long progress = map(frame, 0, framesPerStep[3] - 1, 0, 28);
display.fillRect(89, 39, progress, 6, SSD1306_WHITE);
}
void step5_rinse(uint8_t frame){
display.setTextSize(1);
display.setCursor(35, 5);
display.print("Rinse");
display.fillRect(50, 15, 20, 4, SSD1306_WHITE);
display.fillRect(58, 19, 4, 6, SSD1306_WHITE);
drawWater(frame);
drawHand(41, 40, true);
drawHand(54, 40, false);
if(frame < 6) drawBubbles(frame);
}
void step6_dry(uint8_t frame){
display.setTextSize(1);
display.setCursor(25, 5);
display.print("Dry with towel");
display.drawRect(20, 25, 20, 12, SSD1306_WHITE);
uint8_t bounce = (frame % 4 < 2) ? 1 : 0;
drawHand(50, 35 + bounce, true);
drawHand(63, 35 + bounce, false);
if(frame % 6 < 3) display.fillRect(45, 40, 20, 8, SSD1306_WHITE);
}
void step7_done(uint8_t frame){
display.setTextSize(1);
display.setCursor(25, 5);
display.print("Hands clean!");
drawHand(45, 20, true);
drawHand(58, 20, false);
if(frame % 8 < 4){
display.drawPixel(40, 30, SSD1306_WHITE);
display.drawPixel(70, 32, SSD1306_WHITE);
display.drawPixel(55, 28, SSD1306_WHITE);
}
display.setCursor(35, 55);
display.print("Well done!");
}
void drawAnimation(){
switch(currentStep){
case 0: step1_water(frameInStep); break;
case 1: step2_wet(frameInStep); break;
case 2: step3_soap(frameInStep); break;
case 3: step4_scrub(frameInStep); break;
case 4: step5_rinse(frameInStep); break;
case 5: step6_dry(frameInStep); break;
case 6: step7_done(frameInStep); break;
}
}
// --- Time and Pills Display ---
void drawTimeAndPills(){
// 1. Time
DateTime now = rtc.now();
char buf[20];
sprintf(buf, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
display.setTextSize(2);
display.setCursor(0, 0);
display.print(buf);
// 2. Pill Status
display.setTextSize(1);
display.setCursor(0, 20);
switch(pillState){
case WAIT_PILL1: display.print("Take Pill 1"); break;
case PILL1_TAKEN: display.print("Pill 1 Taken"); break;
case PILL2_READY: display.print("Take Pill 2"); break;
case PILL2_TAKEN: display.print("All Done"); break;
}
display.setCursor(0, 40);
display.print("Monitor Active");
}
// --- Ultrasonic, Heart Animation (بدون تغییر) ---
long readUltrasonic() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
long distance = duration * 0.034 / 2;
return distance;
}
void drawHeart(int x, int y, uint8_t size) {
int r = size * 2;
display.fillCircle(x - r/2, y - r/2, r/2, SSD1306_WHITE);
display.fillCircle(x + r/2, y - r/2, r/2, SSD1306_WHITE);
display.fillTriangle(
x - r, y - r/4,
x + r, y - r/4,
x, y + r,
SSD1306_WHITE);
}
void drawHeartAnimation() {
display.setTextSize(1);
display.setCursor(25, 5);
display.print("Heart Pill");
uint8_t scale = 2 + (heartFrame % heartFrames);
drawHeart(64, 32, scale);
heartFrame++;
if(heartFrame >= heartFrames * 2) {
heartFrame = 0;
pillState = PILL2_READY;
heartAnimationRunning = false;
systemState = SHOW_TIME_PILLS;
}
}
// --- Web Server Handlers (بروزرسانی شده برای نمایش DHT) ---
void handleRoot() {
// --- وضعیت MQ-2 / هشدار ترک مکان ---
String mq2_status = "";
if (mq2Value > 1000) { // Threshold = 1000
mq2_status = "⚠️ Gas High! Leave the area!";
} else {
mq2_status = ""; // هیچ هشداری
}
// --- وضعیت فاصله ---
String distance_status;
String status_color;
String status_emoji;
if (lastDistance <= 50) {
distance_status = "Khab-e Amigh (Deep Sleep)";
status_color = "#2ecc71"; // سبز
status_emoji = "😴";
} else if (lastDistance >= 150) {
distance_status = "Bidari/Khoruj (Waking/Out of Range)";
status_color = "#e74c3c"; // قرمز
status_emoji = "🚨";
} else {
distance_status = "Dar hale Paiesh (Monitoring Safe Zone)";
status_color = "#f1c40f"; // زرد
status_emoji = "👀";
}
// --- وضعیت نور و هشدار ویتامین D ---
String light_status;
String vitaminD_warning = "";
if (ldrValue < 1000) {
light_status = "Dark 🌙";
vitaminD_warning = "⚠️ Low sunlight! Consider Vitamin D ☀️";
} else if (ldrValue < 2500) {
light_status = "Normal ☁️";
vitaminD_warning = "";
} else {
light_status = "Bright ☀️";
vitaminD_warning = "";
}
// --- وضعیت PIR / حرکت ---
String pir_status;
if (pirState) {
pir_status = "کودک به زمین فوتبال آمد و باید در ابتدا آب بنوشد 💧";
} else {
pir_status = ""; // اگر حرکتی نیست چیزی نمایش نده
}
// --- ساخت HTML ---
String html = R"=====(
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ESP32 Child Monitor</title>
<style>
body { font-family: 'Tahoma', sans-serif; text-align: center; background-color: #f4f7f6; color: #333; padding: 10px; }
.container { max-width: 450px; margin: 20px auto; background: #ffffff; padding: 25px; border-radius: 12px; box-shadow: 0 6px 12px rgba(0,0,0,0.15); }
h2 { color: #2c3e50; border-bottom: 2px solid #ecf0f1; padding-bottom: 10px; }
.data-card { margin-top: 20px; padding: 15px; border-radius: 8px; font-weight: bold; transition: all 0.3s ease; font-size: 1.1em; }
.alert-card { margin-top: 20px; padding: 15px; border-radius: 8px; font-weight: bold; background-color: #e74c3c; color: white; font-size: 1.1em; }
.main-value { font-size: 2.5em; color: #3498db; margin: 10px 0; font-weight: 700; }
.ip-info { font-size: 0.8em; color: #7f8c8d; margin-top: 15px; }
.rtl-text { direction: rtl; }
.dht-row { display: flex; justify-content: space-around; margin-top: 20px; padding: 10px 0; border-top: 1px solid #ecf0f1; }
.dht-item { flex: 1; padding: 10px; border-right: 1px solid #ecf0f1; }
.dht-item:last-child { border-right: none; }
.dht-label { font-size: 0.9em; color: #7f8c8d; }
.dht-value { font-size: 1.5em; color: #2980b9; font-weight: bold; margin-top: 5px; }
</style>
<meta http-equiv="refresh" content="5">
</head>
<body>
<div class="container">
<h2 class="rtl-text">Child Monitoring System (ESP32) 👋</h2>
<!-- هشدار PIR / حرکت در بالای صفحه -->
<div class="alert-card">%PIR%</div>
<!-- هشدار MQ-2 / ترک مکان -->
<div class="alert-card">%MQ2_STATUS%</div>
<h3 class="rtl-text">Detected Distance (Sleep)</h3>
<div class="main-value">%DISTANCE% cm</div>
<div class="data-card" style="background-color: %STATUS_COLOR%; color: white;">
%STATUS_EMOJI% <span class="rtl-text">%DISTANCE_STATUS%</span> %STATUS_EMOJI%
</div>
<h3 class="rtl-text" style="margin-top: 30px;">Environmental Conditions (DHT22, LDR & Gas)</h3>
<div class="dht-row">
<div class="dht-item">
<div class="dht-label rtl-text">Temperature</div>
<div class="dht-value">%TEMP% °C</div>
</div>
<div class="dht-item">
<div class="dht-label rtl-text">Humidity</div>
<div class="dht-value">%HUMIDITY% %%</div>
</div>
<div class="dht-item">
<div class="dht-label rtl-text">Light</div>
<div class="dht-value">%LIGHT%</div>
</div>
<div class="dht-item">
<div class="dht-label rtl-text">Gas (MQ-2)</div>
<div class="dht-value">%MQ2%</div>
</div>
</div>
<div class="data-card" style="background-color:#f39c12; color:white; margin-top:10px;">
%VITAMIN_D%
</div>
<p class="rtl-text" style="margin-top: 30px;">
<b>Pill Status:</b> %PILL_STATE%
</p>
<hr>
<p class="ip-info">
<b>IP Address:</b> %IP% |
<b>Server Time:</b> %TIME%
</p>
</div>
</body>
</html>
)=====";
// --- جایگزینی مقادیر ---
DateTime now = rtc.now();
char time_buf[20];
sprintf(time_buf, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
String pill_status_text;
switch(pillState){
case WAIT_PILL1: pill_status_text = "Ready for Pill 1"; break;
case PILL1_TAKEN: pill_status_text = "Pill 1 Taken - Wait for Pill 2"; break;
case PILL2_READY: pill_status_text = "Ready for Pill 2"; break;
case PILL2_TAKEN: pill_status_text = "Finished (All pills taken)"; break;
}
html.replace("%IP%", WiFi.localIP().toString());
html.replace("%DISTANCE%", String(lastDistance));
html.replace("%DISTANCE_STATUS%", distance_status);
html.replace("%STATUS_COLOR%", status_color);
html.replace("%STATUS_EMOJI%", status_emoji);
html.replace("%TIME%", time_buf);
html.replace("%PILL_STATE%", pill_status_text);
html.replace("%TEMP%", String(lastTemperature, 1));
html.replace("%HUMIDITY%", String(lastHumidity, 1));
html.replace("%LIGHT%", light_status);
html.replace("%VITAMIN_D%", vitaminD_warning);
html.replace("%PIR%", pir_status);
// ✅ جایگزینی MQ-2
html.replace("%MQ2%", String(mq2Value));
html.replace("%MQ2_STATUS%", mq2_status);
// --- ارسال صفحه ---
server.send(200, "text/html", html);
}
// --- Setup ---
void setup(){
Serial.begin(115200);
// پینهای سنسور و دکمه
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(PIR_PIN, INPUT);
// [جدید] مقداردهی اولیه DHT
dht.begin();
// I2C
Wire.begin(SDA_PIN, SCL_PIN);
// OLED Initialization
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_I2C_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
while (true);
}
//... (نمایش اولیه)
// RTC Initialization
if (!rtc.begin()){
Serial.println("Couldn't find RTC");
while(true);
}
// ---------- WiFi ----------
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
//... (فرآیند اتصال WiFi)
int wifi_retries = 0;
while (WiFi.status() != WL_CONNECTED && wifi_retries < 20) {
delay(500);
Serial.print(".");
wifi_retries++;
}
Serial.println();
if (WiFi.status() == WL_CONNECTED) {
Serial.println("WiFi Connected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// نمایش روی OLED
display.clearDisplay();
display.setCursor(0, 20);
display.print("WiFi Connected!");
display.setCursor(0, 35);
display.print(WiFi.localIP().toString().c_str());
display.display();
} else {
Serial.println("WiFi Failed to Connect!");
display.clearDisplay();
display.setCursor(0, 20);
display.print("WiFi Failed!");
display.display();
}
server.on("/", handleRoot);
server.begin();
}
// --- Main Loop (بروزرسانی شده) ---
void loop() {
displayPrepare();
server.handleClient();
// --- Read DHT22 ---
if (millis() - dhtLastReadTime >= dhtReadInterval) {
float h = dht.readHumidity();
float t = dht.readTemperature(); // Celsius
if (!isnan(h) && !isnan(t)) {
lastHumidity = h;
lastTemperature = t;
Serial.print("Humidity: ");
Serial.print(lastHumidity);
Serial.print(" %\t Temperature: ");
Serial.print(lastTemperature);
Serial.println(" *C");
}
dhtLastReadTime = millis();
}
// --- Read LDR ---
if (millis() - ldrLastReadTime >= ldrReadInterval) {
ldrValue = analogRead(LDR_PIN);
ldrLastReadTime = millis();
Serial.print("LDR: ");
Serial.println(ldrValue);
}
// --- Read MQ-2 ---
if (millis() - mq2LastReadTime >= mq2ReadInterval) {
mq2Value = analogRead(MQ2_PIN);
Serial.print("MQ2 Value: ");
Serial.println(mq2Value);
mq2LastReadTime = millis();
}
pirState = digitalRead(PIR_PIN); // HIGH وقتی حرکت شناسایی شد
// اگر PIR تحریک شد، انیمیشن PIR را اجرا کن
if (pirState == HIGH) {
for (int i = 0; i < PIR_FRAME_COUNT; i++) {
display.clearDisplay();
// مرکز کردن انیمیشن
int x = (SCREEN_WIDTH - PIR_FRAME_WIDTH) / 2;
int y = (SCREEN_HEIGHT - PIR_FRAME_HEIGHT) / 2;
display.drawBitmap(x, y, pirFrames[i], PIR_FRAME_WIDTH, PIR_FRAME_HEIGHT, SSD1306_WHITE);
display.display();
delay(PIR_FRAME_DELAY);
}
}
switch (systemState) {
case WAIT_ULTRASONIC: {
long distance = readUltrasonic();
lastDistance = distance;
display.setCursor(0, 10);
display.print("Monitoring sleep...");
char buf[40];
sprintf(buf, "Dist: %ld cm", distance);
display.setCursor(0, 25);
display.print(buf);
display.setCursor(0, 40);
display.print("System Active");
if (distance <= 50) {
childWasSleeping = true;
display.setCursor(0, 55);
display.print("Sleeping detected");
}
if (childWasSleeping && distance >= 150) {
systemState = HAND_ANIMATION;
currentStep = 0;
frameInStep = 0;
childWasSleeping = false;
}
break;
}
case HAND_ANIMATION:
drawAnimation();
frameInStep++;
if (frameInStep >= framesPerStep[currentStep]) {
frameInStep = 0;
currentStep++;
if (currentStep >= TOTAL_STEPS) {
systemState = SHOW_TIME_PILLS;
}
}
break;
case HEART_ANIMATION:
if (heartAnimationRunning) {
drawHeartAnimation();
}
else if (heartDelayActive) {
if (millis() - heartDelayStart >= 5000) {
heartAnimationRunning = true;
heartDelayActive = false;
heartFrame = 0;
} else {
display.setCursor(20, 30);
display.print("Wait 5 seconds...");
}
}
break;
case SHOW_TIME_PILLS:
drawTimeAndPills();
break;
}
display.display();
// --- مدیریت دکمه (بدون تغییر) ---
if (digitalRead(BUTTON_PIN) == LOW) {
delay(50);
while (digitalRead(BUTTON_PIN) == LOW);
if (pillState == WAIT_PILL1) {
pillState = PILL1_TAKEN;
heartDelayActive = true;
heartDelayStart = millis();
systemState = HEART_ANIMATION;
}
else if (pillState == PILL1_TAKEN && heartAnimationRunning) {
heartAnimationRunning = false;
pillState = PILL2_READY;
systemState = SHOW_TIME_PILLS;
}
else if (pillState == PILL2_READY) {
pillState = PILL2_TAKEN;
}
}
delay(150);
}