الأحد، 6 سبتمبر 2020

نظام تنبيه لأمن الباب بالاردوينو

 في هذه المقالة ، سوف نتعلم كيفية إنشاء نظام تنبيه نصي SMS باستخدام وحدة Arduino و SIM800L.

المكونات الإلكترونية المستخدمة في هذا المشروع

PCBWay Custom PCB

اسلاك التوصيل

10kمقاومة  

Reed Switch Sensor 

Arduino UNO

في عدة أماكن ، هناك حاجة لأنظمة الأمان لحماية الغرف. لهذا ، نحتاج إلى تركيب معدات تحمي المكان ، وعلى سبيل المثال ، إصدار تنبيه لإخطار أن شخصًا ما قد دخل إلى الغرفة.

تتمثل إحدى طرق حل هذه المشكلة في استخدام Arduino مع مستشعر تبديل القصب. أي عندما يفتح شخص ما الباب ، يتلقى الشخص تنبيهًا عبر الرسائل القصيرة على هاتفه الخلوي.

سيتم إرسال هذه الرسالة من خلال وحدة SIM800L GSM. يتم عرض الدائرة في الشكل 1.

circuit_sim800l_arduino.png

الآن ، ستتعلم كيفية إنشاء المشروع خطوة بخطوة.

المشروع خطوة بخطوة

أولاً ، سنشرح كيف يعمل المشروع. تحتاج إلى تثبيت مستشعر تبديل الريشة ومغناطيس في بابك. وبعد ذلك ، ستقوم بتوصيل المستشعر بنظام Arduino الخاص بك.

عند فتح الباب ، يتحرك المغناطيس بعيدًا عن مستشعر مفتاح القصب وسيفتح. بهذه الطريقة ، سيكتشف النظام أن الباب قد تم فتحه وسيقوم بإرسال رسالة نصية قصيرة عبر SIM800L للمستخدم.

يتم عرض الدائرة في اللوح أدناه.

detected-opened-door.jpg


الكود المصدري للمشروع

أدناه ، يمكنك رؤية الكود المصدري لهذا المشروع. فيما بعد ، سنقدم خطوة بخطوة لهذا الرمز.

#include <SoftwareSerial.h>
SoftwareSerial chip(10, 11);

String SeuNumero = "+xxxxxxxxxxxxx";

#define sensor 12

bool ValorAtual = 0, ValorAnterior = 0;

void setup()
{
  Serial.begin(9600);
  Serial.println("Inicializando Sistema...");
  delay(5000);
  chip.begin(9600);
  delay(1000);

  pinMode(sensor, INPUT); //Configura o Pino do Sensor como Entrada
}

void loop()
{
  //Le o valor do pino do sensor
  ValorAtual = digitalRead(sensor);

  if(ValorAtual == 1 && ValorAnterior == 0)
  {
      ClosedDoor();
      ValorAnterior == 1;
  }

  if(ValorAtual == 1 && ValorAnterior == 0)
  {
      OpenedDoor();
      ValorAnterior == 0;
  }

}

void OpenedDoor() //Funcao para enviar mensagem de alerta Umidade Baixa
{
  chip.println("AT+CMGF=1");
  delay(1000);
  chip.println("AT+CMGS=\"" + SeuNumero + "\"\r");
  delay(1000);
  String SMS = "Opened Door!";
  chip.println(SMS);
  delay(100);
  chip.println((char)26);
  delay(1000);
}

void ClosedDoor()//Funcao para enviar mensagem de alerta Umidade Normal
{
  chip.println("AT+CMGF=1");
  delay(1000);
  chip.println("AT+CMGS=\"" + SeuNumero + "\"\r");
  delay(1000);
  String SMS = "Closed Door!";
  chip.println(SMS);
  delay(100);
  chip.println((char)26);
  delay(1000);
}
    

السبت، 29 أغسطس 2020

كيفية بناء ساعة ناطق من اردوينو باستخدام RTC وتحويل النص إلى كلام

 تعلم كيفية إنشاء ساعة قائمة على Arduino باستخدام RTC IC الذي يعبر عن الوقت والتاريخ عند الطلب!

في هذا البرنامج التعليمي ، سننشئ ساعة تعتمد على Arduino في الوقت الفعلي والتي ستتحدث عن الوقت والتاريخ عند الضغط على الزر. تكمن الفكرة في إنشاء طريقة لبيانات المستشعر من Arduino ليتم التحدث بها عبر الهاتف الذكي ، وأنا أستخدم وحدة RTC كمثال. يمكن أن يكون برنامجًا تعليميًا رائعًا للتصميم حول تطبيقات IoT وأجهزة الاستشعار للمكفوفين حيث يمكن مراقبة البيانات عبر الصوت.

باستخدام RTC IC

سنقوم بنشر IC على مدار الساعة في الوقت الحقيقي (RTC) بدلاً من استخدام IC المؤقت 555 العادي. يقوم RTC بتتبع الوقت حتى بدون طاقة. يحتوي على دائرة مدمجة لاستشعار الطاقة والتي تتعقب حالات انقطاع التيار وتتحول تلقائيًا إلى مصدر الطاقة الاحتياطية.

في حالة Arduino ، تتم إعادة ضبط الساعة الداخلية عند إعادة تشغيلها أو فصلها. يفقد مسار الوقت ويعيد ضبط الساعة إلى الصفر ويبدأ العد من الصفر عند التشغيل. لذلك ، من أجل مزامنة ساعة Arduino الداخلية مع الساعة الحقيقية حتى في حالة عدم وجود طاقة ، نستخدم RTC.

سنقوم بواجهة Arduino و RTC لإرسال البيانات إلى هاتف ذكي باستخدام وحدة Bluetooth التي تسمح بنطق البيانات عبر تطبيق تحويل النص إلى كلام.


الأجهزة المطلوبة

اردوينو UNO

وحدة DS1307 RTC

اللوح

توصيل الأسلاك

مزود الطاقة

اضغط الزر

وحدة بلوتوث HC-05

البرامج المطلوبة

اردوينو IDE

تطبيق تحويل النص إلى كلام اردوينو بلوتوث

الوحدة النمطية DS-1307 RTC

DS1307 عبارة عن ساعة في الوقت الحقيقي (RTC) بها ثمانية دبابيس وتستخدم واجهة I2C. إنها ساعة منخفضة الطاقة مع 56 بايت من البطارية الاحتياطية SRAM. توفر الساعة بيانات مؤهلة للثواني والدقائق والساعات واليوم والشهر والسنة. يتم تعديل تاريخ انتهاء كل شهر تلقائيًا ، بما في ذلك الأشهر التي تقل عن 31 يومًا.

Speaking_Clock_RW_MP_image8.jpg


الربط بين RTC و Arduino

RTClib هي مكتبة خفيفة الوزن تستخدم لتحديد تاريخ ووقت Arduino ويمكن تنزيلها من هنـــــــــــــــــا 

يتتبع RTC IC الوقت الحقيقي الحالي الذي يمكن استخدامه لبرمجة الإجراءات في وقت معين. يستخدم المذبذب البلوري في معظم الدوائر المتكاملة RTC بتردد 32.768 كيلوهرتز (نفس التردد المستخدم في ساعات الكوارتز والساعات). هذا التردد يساوي 2 ^ 15 دورة في الثانية.

وحدة بلوتوث HC-05

وحدة Bluetooth HC-05 هي مكون سهل الاستخدام يستخدم بروتوكول المنفذ التسلسلي (SSP). إنه مصمم لإنشاء اتصالات تسلسلية لاسلكية شفافة.

Speaking_Clock_RW_MP_image7.png

هذه الوحدة هي Bluetooth V2 + EDR (معدل بيانات محسّن) ، ولها تعديل 3 ميغابت في الثانية إلى جانب جهاز إرسال واستقبال لاسلكي 2.4 جيجا هرتز ونطاق أساسي. يستخدم جهاز Bluetooth ذو رقاقة أحادية خارجية من bluecore يعتمد على تقنية CMOS ويستخدم ميزة قفز التردد التكيفي (AFH). حجمها صغير مثل 12.7 مم × 27 مم.


ربط HC-05 مع Arduino باستخدام SerialSoftware.h

تم تطوير مكتبة SoftwareSerial لتمكين الاتصال التسلسلي على المسامير (الرقمية الأخرى) في Arduino باستخدام البرنامج لإعادة إنتاج وظائف المنفذ التسلسلي ، ومن هنا جاء اسمه "SoftwareSerial". من الممكن أيضًا أن يكون لديك أكثر من منفذ تسلسلي للبرنامج بسرعات تصل إلى 115200 بت في الثانية.

إعداد تطبيق Arduino Bluetooth لتحويل النص إلى كلام

يتلقى تطبيق الهاتف الذكي هذا رسائل نصية عبر البلوتوث من جهاز Bluetooth مقترن ، أي لوحة Arduino مع وحدة HC-05. ثم يقوم بتحويل النص المستلم إلى كلام.

Speaking_Clock_RW_MP_image10.png


Speaking_Clock_RW_MP_image4.png

تكوين زر الضغط

يتم توصيل زر الضغط عبر المقاوم 10 كيلو أوم ، المعروف باسم المقاوم المنسدل ، من الأرض إلى دبوس التبديل المتصل بـ Arduino. يقوم بتوصيل الدبوس بالأرض عندما يكون المفتاح مفتوحًا ، لذلك يقرأ LOW عندما لا يكون هناك جهد قادم من خلال المفتاح.


عند الضغط على الزر الانضغاطي ، يتم ضبط حالة الزر على HIGH ويتم تكوين إشارة الصوت عبر Bluetooth. بمجرد تحرير الزر ، تنتقل حالة الزر إلى LOW وتنقطع الدائرة.

فيما يلي مخطط الدائرة الذي يوضح وضع الزر الانضغاطي والمقاوم 10 كيلو أوم.

تكوين زر الضغط

يتم توصيل الزر الانضغاطي عبر المقاوم 10 كيلو أوم ، والمعروف باسم المقاوم المنسدل ، من الأرض إلى دبوس التبديل المتصل بـ Arduino. يقوم بتوصيل الدبوس بالأرض عندما يكون المفتاح مفتوحًا ، لذلك يقرأ LOW عندما لا يكون هناك جهد قادم من خلال المفتاح.

عند الغط على الزر الانضغاطي ، يتم ضبط حالة الزر على HIGH ويتم تكوين إشارة الصوت عبر Bluetooth. بمجرد تحرير الزر ، تنتقل حالة الزر إلى LOW وتنقطع الدائرة.

فيما يلي مخطط الدائرة الذي يوضح وضع الزر الانضغاطي والمقاوم 10 كيلو أوم.

Speaking_Clock_RW_MP_image1.png

تجميع الأجهزة

دعنا نربط المكونات الفردية والوحدات الموضحة أعلاه بـ Arduino UNO كما هو موضح في المخطط   التالي.

Speaking_Clock_RW_MP_image9.jpg


Speaking_Clock_RW_MP_image5.jpg


واجهة تحويل النص إلى كلام من Arduino Bluetooth

قم بتحميل كود Arduino من أسفل هذه المقالة. بمجرد التحميل ، افتح إعداد Bluetooth بهاتفك وابحث عن أجهزة Bluetooth. في قائمة أجهزة Bluetooth المتاحة ، قم بإقران هاتفك باسم الجهاز HC-05 باستخدام رمز المرور 1234 أو 0000. ثم افتح تطبيق تحويل النص إلى كلام Arduino Bluetooth. ستظهر لك قائمة الأجهزة المقترنة. حدد HC-05 كما هو موضح في الصور أدناه.

إذا ضغطت على زر الضغط ، فسيتحدث التطبيق ويعرض الوقت والتاريخ الحاليين. يمكن أيضًا التحكم في درجة الصوت والسرعة داخل التطبيق.

Speaking_Clock_RW_MP_image6.png


Speaking_Clock_RW_MP_image11.png


كود المشروع الكامل


#include <Wire.h>
#include <SoftwareSerial.h>
#include "RTClib.h"

//bluetooth variable
SoftwareSerial BT(10,11);

RTC_DS1307 rtc;

//pushbutton declaration
int buttonPin = 7;
int buttonState = 0;
boolean on=false;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char monthsOfTheYear[13][12] = {"m","January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
void setup () 
{
 while (!Serial); // for Leonardo/Micro/Zero
 Serial.begin(9600);
 Wire.begin();
 rtc.begin();
 BT.begin(9600);
 if (! rtc.begin()) 
 {
   Serial.println("Couldn't find RTC");
   while (1);
 }
 if (! rtc.isrunning()) 
 {
   Serial.println("RTC is NOT running!");
 }
// This line sets the RTC with an explicit date & time, for example to set
// rtc.adjust(DateTime(2020, 1, 21, 19, 47, 36));
 pinMode(buttonPin, INPUT);

 //testing serial monitor
 Serial.print("Date: ");
 Serial.print(__DATE__);
 Serial.print('\n');
 Serial.print("Time: ");
 Serial.print(__TIME__);

}
void loop () {

  buttonState = digitalRead(buttonPin);
  DateTime now = rtc.now();
  if(buttonState == HIGH)
  {
    //Serial.print('test');
      on=true;
      if(on == true)
      {
         digitalWrite(buttonPin, HIGH);
         delay(4000);
         BT.println("Today is");
         delay(3000);
         BT.println(monthsOfTheYear[now.month()]);
         delay(1000);
         BT.println(now.day());
         delay(1000);
         BT.println(now.year());
         delay(3000);
         BT.println("Time in 24 hour clock is");
         delay(3000);
         BT.println(now.hour());
         delay(1000);
         BT.println("hours");
         delay(3000);
         BT.println(now.minute());
         delay(1000);
         BT.println("minutes");
         delay(3000);
         BT.println(now.second());
         delay(1000);
         BT.println("seconds");
        
      }
  }
  else if (buttonState == LOW)
  {
    digitalWrite(buttonPin, LOW);
  }
delay(800);

الجمعة، 3 يوليو 2020

اردوينو للعد التنازلي قابل للتعديل


Adjustable Countdown Timer


الأشياء المستخدمة في هذا المشروع

4-digit 7-segment display
بوش بتن- مفتاح الضغط
صافرة كهربائية - بزر

من المحتمل أن يكون مؤقت العد التنازلي هو المشروع الأكثر طبيعية للعرض المكون من 4 أرقام المكون من 7 أرقام. أثناء استكشاف ما هو متاح عبر الإنترنت ، عثرت على العديد من المشاريع ، ولكن لم أجد المشروع الذي كان يدور في خلدي ، وهو مؤقت العد التنازلي القابل للتعديل المستقل الذي يمكنك ضبطه بسهولة باستخدام الأزرار (وليس عن طريق تحميل رمز معدل). لذلك قررت أن أصنع واحدة.


قضيت بعض الوقت في كتابة رمز يجعل من السهل استخدام وتعديل المؤقت ، بحيث يمكن استخدامه عمليًا.

يمكن أيضًا استخدام الرمز المتضمن في مشاريع أخرى مع عرض مكون من 4 أرقام مكون من 7 أجزاء. على وجه الخصوص ، لديه الوظيفة التي تعرض رقم معين (0-9999) لفاصل زمني معين. ربما تكون هذه الوظيفة موجودة في بعض المكتبات ، لكن البحث السريع لم يكشف عنها. نظرًا لأن برمجة هذا العرض صعبة بعض الشيء (حيث يمكنك إظهار رقم واحد فقط في كل مرة) ، فإن هذه الوظيفة مفيدة حقًا.

التعريفات


كود الترميز
#include <math.h>

int digit_pin[] = {6, 9, 10, 11}; // PWM Display digit pins from left to right

int speakerPin = 15;

#define DIGIT_ON  LOW
#define DIGIT_OFF  HIGH

int segA = 2; 
int segB = 3; 
int segC = 4; 
int segD = 5; 
int segE = A0; //pin 6 is used bij display 1 for its pwm function
int segF = 7; 
int segG = 8; 
//int segPD = ; 


int button1=13;
int button2=12;
int button3=16;
int button4=17;

int countdown_time = 60;

struct struct_digits {
    int digit[4];
  };


void setup() {                
  pinMode(segA, OUTPUT);
  pinMode(segB, OUTPUT);
  pinMode(segC, OUTPUT);
  pinMode(segD, OUTPUT);
  pinMode(segE, OUTPUT);
  pinMode(segF, OUTPUT);
  pinMode(segG, OUTPUT);

  for (int i=0; i<4; i++) {
    pinMode(digit_pin[i], OUTPUT);
  }

  pinMode(speakerPin, OUTPUT);

  pinMode(button1,INPUT_PULLUP);
  pinMode(button2,INPUT_PULLUP);
  pinMode(button3,INPUT_PULLUP);
  pinMode(button4,INPUT_PULLUP);
}


void playTone(int tone, int duration) {
  for (long k = 0; k < duration * 1000L; k += tone * 2) {  
    digitalWrite(speakerPin, HIGH);
    delayMicroseconds(tone);
    digitalWrite(speakerPin, LOW);
    delayMicroseconds(tone);
  }
}


void lightNumber(int numberToDisplay) {

#define SEGMENT_ON  HIGH
#define SEGMENT_OFF LOW

  switch (numberToDisplay){

  case 0:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 1:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 2:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 3:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 4:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 5:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 6:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 7:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 8:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 9:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 10:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;  
  }
 
}



void SwitchDigit(int digit) {
  for (int i=0; i<4; i++) {
    if (i == digit) {
      digitalWrite(digit_pin[i], DIGIT_ON);
    } else {
      digitalWrite(digit_pin[i], DIGIT_OFF);
    }
  }
}


struct struct_digits IntToDigits(int n){
  struct struct_digits dig;
  int zeros=0;
  int d;
  for (int i=0; i<4; i++) {
    d=n/pow(10,3-i);
    zeros += d;
    n = n - d*pow(10,3-i);
    if (zeros!=0 || i==3) {
      dig.digit[i]=d;
    } else {
      dig.digit[i]=10;
    }
  }
  return dig;
}

void PrintNumber(int n, int time) {
  struct struct_digits dig;

  dig = IntToDigits(n);
  
  for (int i=0; i<= time/20; i++) {
    if (digitalRead(button2)==LOW) {
      return;
    }
    for (int j=0; j<4; j++) {
      SwitchDigit(j);
      lightNumber(dig.digit[j]);
      delay(5);
    }
  }
}


bool Countdown(int n, int del){
  for (int q=n; q>0; q--){
    PrintNumber(q,del);
    if (digitalRead(button2)==LOW) {
      return false;
    }
  }
  PrintNumber(0,0);
  playTone(1519,1000);
  return true;
}



void reset() {
  int m, zeros, d, pressed3 = 0, pressed4 = 0;
  m=countdown_time;
  struct struct_digits dig;

  dig = IntToDigits(countdown_time);
  
  while (digitalRead(button1)==HIGH) {
    for (int j=0; j<4; j++) {
      SwitchDigit(j);
      lightNumber(dig.digit[j]);
      delay(5);
    }
    if (digitalRead(button3)==LOW) { 
      if (pressed3 == 0 || pressed3 > 30) {
        if (countdown_time > 0) {
          countdown_time -= 1 ;
        }
        dig = IntToDigits(countdown_time);
      } 
      pressed3 += 1;
    }
    else if (digitalRead(button4)==LOW) { 
      if (pressed4 == 0 || pressed4 > 30) {
        if (countdown_time <9999) {
          countdown_time += 1 ;
        }
        dig = IntToDigits(countdown_time);
      } 
      pressed4 += 1;
    }
    if (digitalRead(button3)==HIGH) {
      pressed3=0;
    }
    if (digitalRead(button4)==HIGH) {
      pressed4=0;
    }
  }
}

void loop(){
  reset();
  while (!Countdown(countdown_time,962)) {
    reset();
  }
  while (digitalRead(button2)==1){};
}