منتديات الالكترونيات العصرية  
yoursite.com page title .

استرجاع كلمة المرور طلب كود تفعيل العضوية تفعيل العضوية
العودة   منتديات الالكترونيات العصرية > منتدى الحاكمات الدقيقة Microcontroller > منتدى آردوينو Arduino

  #71  
قديم 02-03-2020, 09:57 PM
الصورة الرمزية F.Abdelaziz
F.Abdelaziz F.Abdelaziz غير متواجد حالياً
استاذ الكترونيان
 
تاريخ التسجيل: May 2009
المشاركات: 2,812
معدل تقييم المستوى: 22
F.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to behold
افتراضي رد: تدريبات ومشاريع الأردوينو Arduino Tutorials an

مثال مع إدخال سلسلة النص من خلال الاتصال التسلسلى :


كود:
/*
 Interactive scrolling led sign for Arduino and MAX7219 8x8 LED Display
 
 This is the code I use to control the MAX7219 8x8 LED modules from my
 Chinese "Geekcreit"-brand Arduino clone.
 
 The first module is connected to the Uno like this:
 
 Module: VCC -> Uno: 5V
 Module: GND -> Uno: GND
 Module: DIN -> Uno: D8
 Module: CS  -> Uno: D9
 Module: CLK -> Uno: D10
 
 Additional modules are connected like this:
 
 Module 2: VCC -> Module 1: VCC
 Module 2: GND -> Module 1: GND
 Module 2: DIN -> Module 1: DIN
 Module 2: CS  -> Module 1: CS
 Module 2: CLK -> Module 1: CLK
 
 See the blog post at https://oneguyoneblog.com/2016/10/20/max7219-arduino-ticker-8x8-led-modules/
 */

#include <MaxMatrix.h>
#include <avr/pgmspace.h>

PROGMEM const unsigned char CH[] = {
  3, 8, B00000000, B00000000, B00000000, B00000000, B00000000, // space
  1, 8, B01011111, B00000000, B00000000, B00000000, B00000000, // !
  3, 8, B00000011, B00000000, B00000011, B00000000, B00000000, // "
  5, 8, B00010100, B00111110, B00010100, B00111110, B00010100, // #
  4, 8, B00100100, B01101010, B00101011, B00010010, B00000000, // $
  5, 8, B01100011, B00010011, B00001000, B01100100, B01100011, // %
  5, 8, B00110110, B01001001, B01010110, B00100000, B01010000, // &
  1, 8, B00000011, B00000000, B00000000, B00000000, B00000000, // '
  3, 8, B00011100, B00100010, B01000001, B00000000, B00000000, // (
  3, 8, B01000001, B00100010, B00011100, B00000000, B00000000, // )
  5, 8, B00101000, B00011000, B00001110, B00011000, B00101000, // *
  5, 8, B00001000, B00001000, B00111110, B00001000, B00001000, // +
  2, 8, B10110000, B01110000, B00000000, B00000000, B00000000, // ,
  4, 8, B00001000, B00001000, B00001000, B00001000, B00000000, // -
  2, 8, B01100000, B01100000, B00000000, B00000000, B00000000, // .
  4, 8, B01100000, B00011000, B00000110, B00000001, B00000000, // /
  4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // 0
  3, 8, B01000010, B01111111, B01000000, B00000000, B00000000, // 1
  4, 8, B01100010, B01010001, B01001001, B01000110, B00000000, // 2
  4, 8, B00100010, B01000001, B01001001, B00110110, B00000000, // 3
  4, 8, B00011000, B00010100, B00010010, B01111111, B00000000, // 4
  4, 8, B00100111, B01000101, B01000101, B00111001, B00000000, // 5
  4, 8, B00111110, B01001001, B01001001, B00110000, B00000000, // 6
  4, 8, B01100001, B00010001, B00001001, B00000111, B00000000, // 7
  4, 8, B00110110, B01001001, B01001001, B00110110, B00000000, // 8
  4, 8, B00000110, B01001001, B01001001, B00111110, B00000000, // 9
  2, 8, B01010000, B00000000, B00000000, B00000000, B00000000, // :
  2, 8, B10000000, B01010000, B00000000, B00000000, B00000000, // ;
  3, 8, B00010000, B00101000, B01000100, B00000000, B00000000, // <
  3, 8, B00010100, B00010100, B00010100, B00000000, B00000000, // =
  3, 8, B01000100, B00101000, B00010000, B00000000, B00000000, // >
  4, 8, B00000010, B01011001, B00001001, B00000110, B00000000, // ?
  5, 8, B00111110, B01001001, B01010101, B01011101, B00001110, // @
  4, 8, B01111110, B00010001, B00010001, B01111110, B00000000, // A
  4, 8, B01111111, B01001001, B01001001, B00110110, B00000000, // B
  4, 8, B00111110, B01000001, B01000001, B00100010, B00000000, // C
  4, 8, B01111111, B01000001, B01000001, B00111110, B00000000, // D
  4, 8, B01111111, B01001001, B01001001, B01000001, B00000000, // E
  4, 8, B01111111, B00001001, B00001001, B00000001, B00000000, // F
  4, 8, B00111110, B01000001, B01001001, B01111010, B00000000, // G
  4, 8, B01111111, B00001000, B00001000, B01111111, B00000000, // H
  3, 8, B01000001, B01111111, B01000001, B00000000, B00000000, // I
  4, 8, B00110000, B01000000, B01000001, B00111111, B00000000, // J
  4, 8, B01111111, B00001000, B00010100, B01100011, B00000000, // K
  4, 8, B01111111, B01000000, B01000000, B01000000, B00000000, // L
  5, 8, B01111111, B00000010, B00001100, B00000010, B01111111, // M
  5, 8, B01111111, B00000100, B00001000, B00010000, B01111111, // N
  4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // O
  4, 8, B01111111, B00001001, B00001001, B00000110, B00000000, // P
  4, 8, B00111110, B01000001, B01000001, B10111110, B00000000, // Q
  4, 8, B01111111, B00001001, B00001001, B01110110, B00000000, // R
  4, 8, B01000110, B01001001, B01001001, B00110010, B00000000, // S
  5, 8, B00000001, B00000001, B01111111, B00000001, B00000001, // T
  4, 8, B00111111, B01000000, B01000000, B00111111, B00000000, // U
  5, 8, B00001111, B00110000, B01000000, B00110000, B00001111, // V
  5, 8, B00111111, B01000000, B00111000, B01000000, B00111111, // W
  5, 8, B01100011, B00010100, B00001000, B00010100, B01100011, // X
  5, 8, B00000111, B00001000, B01110000, B00001000, B00000111, // Y
  4, 8, B01100001, B01010001, B01001001, B01000111, B00000000, // Z
  2, 8, B01111111, B01000001, B00000000, B00000000, B00000000, // [
  4, 8, B00000001, B00000110, B00011000, B01100000, B00000000, // \ backslash
  2, 8, B01000001, B01111111, B00000000, B00000000, B00000000, // ]
  3, 8, B00000010, B00000001, B00000010, B00000000, B00000000, // hat
  4, 8, B01000000, B01000000, B01000000, B01000000, B00000000, // _
  2, 8, B00000001, B00000010, B00000000, B00000000, B00000000, // `
  4, 8, B00100000, B01010100, B01010100, B01111000, B00000000, // a
  4, 8, B01111111, B01000100, B01000100, B00111000, B00000000, // b
  4, 8, B00111000, B01000100, B01000100, B00101000, B00000000, // c
  4, 8, B00111000, B01000100, B01000100, B01111111, B00000000, // d
  4, 8, B00111000, B01010100, B01010100, B00011000, B00000000, // e
  3, 8, B00000100, B01111110, B00000101, B00000000, B00000000, // f
  4, 8, B10011000, B10100100, B10100100, B01111000, B00000000, // g
  4, 8, B01111111, B00000100, B00000100, B01111000, B00000000, // h
  3, 8, B01000100, B01111101, B01000000, B00000000, B00000000, // i
  4, 8, B01000000, B10000000, B10000100, B01111101, B00000000, // j
  4, 8, B01111111, B00010000, B00101000, B01000100, B00000000, // k
  3, 8, B01000001, B01111111, B01000000, B00000000, B00000000, // l
  5, 8, B01111100, B00000100, B01111100, B00000100, B01111000, // m
  4, 8, B01111100, B00000100, B00000100, B01111000, B00000000, // n
  4, 8, B00111000, B01000100, B01000100, B00111000, B00000000, // o
  4, 8, B11111100, B00100100, B00100100, B00011000, B00000000, // p
  4, 8, B00011000, B00100100, B00100100, B11111100, B00000000, // q
  4, 8, B01111100, B00001000, B00000100, B00000100, B00000000, // r
  4, 8, B01001000, B01010100, B01010100, B00100100, B00000000, // s
  3, 8, B00000100, B00111111, B01000100, B00000000, B00000000, // t
  4, 8, B00111100, B01000000, B01000000, B01111100, B00000000, // u
  5, 8, B00011100, B00100000, B01000000, B00100000, B00011100, // v
  5, 8, B00111100, B01000000, B00111100, B01000000, B00111100, // w
  5, 8, B01000100, B00101000, B00010000, B00101000, B01000100, // x
  4, 8, B10011100, B10100000, B10100000, B01111100, B00000000, // y
  3, 8, B01100100, B01010100, B01001100, B00000000, B00000000, // z
  3, 8, B00001000, B00110110, B01000001, B00000000, B00000000, // {
  1, 8, B01111111, B00000000, B00000000, B00000000, B00000000, // |
  3, 8, B01000001, B00110110, B00001000, B00000000, B00000000, // }
  4, 8, B00001000, B00000100, B00001000, B00000100, B00000000, // ~
};

int data = 8;    // DIN pin of MAX7219 displays
int load = 9;    // CS pin of MAX7219 displays
int clock = 10;  // CLK pin of MAX7219 displays
int scrollSpeed = 35; // speed of scrolling text, lower is faster
int maxInUse = 3;  //Number of MAX7219 displays

MaxMatrix m(data, load, clock, maxInUse); // define Library

byte buffer[10];
char inData[64] = "MAX7219 8x8 LED Matrix  "; // The string (max 64 bytes)
char inChar; // Where to store the character read
byte index = 0; // Index into array; where to store the character

void setup(){
  m.init(); // init display
  m.setIntensity(7); // LED light intensity from 0 (dimmest) to 15
  Serial.begin(9600); // init serial connection
}

void loop(){

// Get input from serial connection
  index=0;
  while(Serial.available() > 0) // Don't read unless there is data
  {

    if(index < 63) // One less than the size of the array
    {
      inChar = Serial.read(); // Read a character
      Serial.write(inChar);
      inData[index] = inChar; // Store it
      index++; // Increment where to write next
      inData[index] = '\0'; // Null terminate the string
    }       
  }

  byte c;
  delay(100);
  m.shiftLeft(false, true);
  printStringWithShift(inData, scrollSpeed);  // Send scrolling Text
  clearLCD(maxInUse, scrollSpeed);
}

// Put extracted character on Display
void printCharWithShift(char c, int shift_speed){

  if (c < 32) return;
  c -= 32;
  memcpy_P(buffer, CH + 7*c, 7);
  m.writeSprite(maxInUse*8, 0, buffer);
  m.setColumn(maxInUse*8 + buffer[0], 0);

  for (int i=0; i<buffer[0]+1; i++) 
  {
    delay(shift_speed);
    m.shiftLeft(false, false);
  }
}

// Extract characters from Scrolling text
void printStringWithShift(char* s, int shift_speed){

  while (*s != 0){
    printCharWithShift(*s, shift_speed);
    s++;
  }
}

// Add trailing space to clear the display
void clearLCD(int maxInUse, int shift_speed){

  for (int i=0; i<maxInUse*8; i++) 
  {
    m.setColumn((maxInUse*8), 0);
    delay(shift_speed);
    m.shiftLeft(false, false);
  }
}

النتائج :













رد مع اقتباس
  #72  
قديم 02-10-2020, 11:54 AM
الصورة الرمزية F.Abdelaziz
F.Abdelaziz F.Abdelaziz غير متواجد حالياً
استاذ الكترونيان
 
تاريخ التسجيل: May 2009
المشاركات: 2,812
معدل تقييم المستوى: 22
F.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to behold
افتراضي التحكم فى السفن سيجمنت والمشغل max7219 بواسطة الار

التحكم فى السفن سيجمنت والمشغل MAX7219 بواسطة الاردوينو مع المكتبة LedControl :



سوف نستحدم الوحدة (الموديول) المكون من الدائرة المتكاملة MAX7219 مع شاشة عرض سفن سيجمنت مكونة من حتى ثمانى أرقام digits والمبينة أدناه . يمكن توصيل حتى ثمانى وحدات على التتالى cascade .

هناك مكتبة مطلوبة ليتم تضمينها للعمل مع هذه الوحدة وتسمى LedControl ، يتم تحميلها من الرابط أدناه وثبيتها فى بيئة تطوير الاردوينو .
https://github.com/wayoda/LedControl

التوصيل :
المديول به 5 أطراف للتوصيل وهى سهلة التوصيل . يتوفر الموديول مع خيار للتتالي cascading مع المزيد من الموديولات من نوعه ، وبالتالي تشكيل شاشة أكبر. لنفكر فقط في وحدة واحدة للبساطة.
يتم إجراء الاتصالات على النحو التالي :

VCC- 5v of arduino
GND- gnd of arduino
Din- pin 12
CS(Load)-pin 10
Clk-pin 11
Dout is connected to the Din of the next module.




رد مع اقتباس
  #73  
قديم 02-10-2020, 12:15 PM
الصورة الرمزية F.Abdelaziz
F.Abdelaziz F.Abdelaziz غير متواجد حالياً
استاذ الكترونيان
 
تاريخ التسجيل: May 2009
المشاركات: 2,812
معدل تقييم المستوى: 22
F.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to behold
افتراضي رد: تدريبات ومشاريع الأردوينو Arduino Tutorials an

البرمجة :
مثال المكتبة :
البرنامج :



كود:
//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

/* we always wait a bit between updates of the display */
unsigned long delaytime=250;

void setup() {
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);
}


/*
 This method will display the characters for the
 word "Arduino" one after the other on digit 0. 
 */
void writeArduinoOn7Segment() {
  lc.setChar(0,0,'a',false);
  delay(delaytime);

  lc.setRow(0,0,0x05);// r
  delay(delaytime);

  lc.setChar(0,0,'d',false);
  delay(delaytime);

  lc.setRow(0,0,0x1c);//u
  delay(delaytime);

  lc.setRow(0,0,B00010000);//i
  delay(delaytime);

  lc.setRow(0,0,0x15);//n
  delay(delaytime);

  lc.setRow(0,0,0x1D);//o
  delay(delaytime);
  lc.clearDisplay(0);
  delay(delaytime);
} 

/*
  This method will scroll all the hexa-decimal
 numbers and letters on the display. You will need at least
 four 7-Segment digits. otherwise it won't really look that good.
 */
void scrollDigits() {
  for(int i=0;i<13;i++) {
    lc.setDigit(0,3,i,false);
    lc.setDigit(0,2,i+1,false);
    lc.setDigit(0,1,i+2,false);
    lc.setDigit(0,0,i+3,false);
    delay(delaytime);
  }
  lc.clearDisplay(0);
  delay(delaytime);
}

void loop() { 
  writeArduinoOn7Segment();
  scrollDigits();
}


الوصف :

1- فى بداية البرنامج (الاسكيتش) يجب تضمين ملف رأس المكتبة :

كود:
 //We always have to include the library
#include "LedControl.h"

ثم يتم تحديد أطراف الاتصال بين الوحدة والاردوينو ، ومن ثم يتم إنشاء كائن من فئة المكتبة :

كود:
/*
 Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 We have only a single MAX72XX.
 */

LedControl lc=LedControl(12,11,10,1);

الدوال المستخدمة :

الدالة :

كود:
LedControl new_disp = LedControl(dataPin, clkPin,  csPin,  Devices)

• تؤدي هذه الدالة (تسمى دالة المنشىء) إلى إنشاء كائن من فئة LEDControl (اسم الكائن هنا ، new_disp ؛ يمكن استخدام أي اسم صالح آخر ) وهى تتخاطب مع MAX7219 الموجودة على وحدة (موديول) العرض المكون من السفن سيجمنت .
• dataPine هو طرف Arduino الذي يتصل بطرف دخل البيانات DIN بالوحدة (الموديول) . وهو طرف الاردوينو حيث يتم نقل (إزاحة) البيانات للخارج .
• clkPin هو طرف Arduino الذي يتصل بالطرف CLK على الوحدة . وهو طرف الساعة clock .
• csPin هو طرف Arduino المتصل بالطرف CS / Load على الوحدة. هذا الطرف لتحديد (اختيار) الجهاز عندما يتم إرسال البيانات.
• Devices تحدد الحد الأقصى لعدد الأجهزة التي يمكن التحكم فيها. يمكن أن يتراوح ما بين 1 إلى 8. وهو عدد الأجهزة المتصلة في تتالي cascade .
• الجهاز المتصل مباشرةً بالأطراف المحددة يكون له العنوان address 0 . الجهاز الموجود بجواره المتتالي مباشرةً يكون له العنوان 1. الجهاز الثامن (الجهاز الأخير في اتصال التسلسل) يكون له العنوان 7.

الدالة :

كود:
new_disp.shutdown(addr, status)

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

الدالة :

كود:
new_disp.setIntensity(addr, intensity)

• تستخدم هذه الدالة لضبط سطوع الشاشة التي عنوانها addr.
• يمكن أن تتراوح الشدة بين 1 و 15. 1 كحد أدنى و 15 كحد أقصى.

الدالة :

كود:
 new_disp.setDigit(addr, digit, value, dp)

• تستخدم هذه الدالة لعرض رقم number ، المشار إليه بالبارامتر (value) ، على الشاشة بالعنوان addr . يتم عرض الرقم في الموضع (الأحاد units ، العشرات tens ، وما إلى ذلك) المذكورة بواسطة البارامتر digit (يمكن أن تكون من 0 إلى 7) . البارامتر dp يحدد الفاصلة العشرية. إذا كان dp خطأ false ، فستكون النقطة العشرية معطلة.

الدالة :

كود:
new_disp.setChar(addr, digit, value, dp)

• تستخدم هذه الدالة لعرض حرف character ، المشار إليه بالبارامتر (value) على الشاشة بالعنوان addr . يتم عرض الحرف في الموضع (الأحاد units ، العشرات tens ، وما إلى ذلك) المذكورة بواسطة البارامتر digit (يمكن أن تكون من 0 إلى 7). يحدد البارامتر dp الفاصلة العشرية. إذا كان dp خطأ ً false ، فستكون النقطة العشرية معطلة.
• يمكن فقط عرض بعض الحروف .

2- دائما ما ننتظر قليلا ما بين تحديث الشاشة :

كود:
/* we always wait a bit between updates of the display */
unsigned long delaytime=250;

3- نأتى إلى دالة الإعداد setup . فى البداية ، ونظرا لأن MAX72XX يبدأ العمل فى وضع "توفير القدرة" ، فعلينا إيقاظه ، وضبط شدة إضاءة الشاشة ، ومسح الشاشة للتهيئة للعمل :

كود:
 
void setup() {
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);

  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);
}


طباعة الأرقام Printing numbers
الاستخدام الأكثر شيوعًا لشاشات العرض السفن سيجمنت هو إظهار الأرقام numbers . الدالة الأولى التي ننظر إليها setDigit تأخذ وسيط نوع البايت وتطبع الرقم المقابل في العمود المحدد. يعمل نطاق القيم الصالحة من 0..15 . تتم طباعة جميع القيم بين 0..9 كأرقام digits ، ويتم طباعة القيم بين 10..15 كمكافئها السداسي عشر.
سيتم ببساطة تجاهل أي قيمة أخرى ، مما يعني أنه لن تتم طباعة أي شيء. لن يتم إفراغ blanked العمود الموجود على الشاشة ، بل سيحتفظ ببساطة بقيمته الصالحة الأخيرة. يمكن تشغيل الفاصلة العشرية في العمود أو إيقاف تشغيله باستخدام وسيط إضافى .
فيما يلي مثال صغير يطبع قيمة نوع int هى (-999..999) على شاشة مكونة من 4 أرقام digits .


كود:
void printNumber(int v) {
    int ones;
    int tens;
    int hundreds;
    boolean negative;	

    if(v < -999 || v > 999) 
       return;

    if(v<0) {
        negative=true;
        v=v*-1;
    }

    ones=v%10;
    v=v/10;
    tens=v%10;
    v=v/10;
    hundreds=v;
			
    if(negative) {
       //print character '-' in the leftmost column	
       lc.setChar(0,3,'-',false);
    }
    else {
       //print a blank in the sign column
       lc.setChar(0,3,' ',false);
    }
    //Now print the number digit by digit
    lc.setDigit(0,2,(byte)hundreds,false);
    lc.setDigit(0,1,(byte)tens,false);
    lc.setDigit(0,0,(byte)ones,false);
}

فيما يلى النموذج الأولي prototype للدالة :

كود:
/* 
 * Display a (hexadecimal) digit on a 7-Segment Display
 * Params:
 * addr  address of the display
 * digit the position of the digit on the display (0..7)
 * value the value to be displayed. (0x00..0x0F)
 * dp    sets the decimal point.
 */

void setDigit(int addr, int digit, byte value, boolean dp);

يجب أن يكون الوسيط digit فى النطاق 0..7 لأن MAX72XX يمكنه أن يقود ما يصل إلى ثمانية شاشات عرض سفن سيجمنت . الفهرس index يبدأ من 0 كالمعتاد.

طباعة الأحرف Printing characters

هناك مجموعة محدودة من الأحرف التى يمكن عرضها على شاشة السفن سيجمنت . الاستخدام الشائع سيكون الحرف '-' للقيم السالبة والحروف الستة 'A'..'F' للقيم السداسية.
الدالة setChar(addr,digit,value,dp) - تقبل قيمة value من نوع char للنطاق الكامل لتكويد أسكى ASCII ذات 7 بت. نظرًا لأن الأنماط التي يمكن التعرف عليها محدودة ، أشهر الأحرف المحددة (المعرفة) هي حرف الفراغ <space> . ولكن هناك عدد قليل من الأحرف التي لها معنى على شاشة السفن سيجمنت . فيما يلي مجموعة الأحرف القابلة للطباعة:

• 0 1 2 3 4 5 6 7 8 9
• A a (prints upper case)
• B b (prints lower case)
• C c (prints lower case)
• D d (prints lower case)
• E e (prints upper case)
• F f (prints upper case)
• H h (prints upper case)
• L l (prints upper case)
• P p (prints upper case)
• - (the minus sign)
• ., (lights up the decimal-point)
• _ (the underscore)
• <SPACE> (the blank or space char)

من أجل راحتك ، تم أيضًا إعادة تعريف الأحرف السداسية عشرية بقيم الأحرف 0x00...0x0F . إذا كنت ترغب في مزج الأرقام digits والحروف characters على الشاشة ، يمكنك ببساطة أن تأخذ نفس وسيط البايت التي كنت ستستخدمها للدالة setDigit() وستطبع القيمة السداسية العشرية.

النموذج الأولي للدالة هو نفسه تقريبا لعرض الأرقام digits .

كود:
/* 
 * Display a character on a 7-Segment display.
 * There are only a few characters that make sense here :
 * '0','1','2','3','4','5','6','7','8','9','0',
 * 'A','b','c','d','E','F','H','L','P',
 * '.','-','_',' ' 
 * Params:
 * addr	  address of the display
 * digit  the position of the character on the display (0..7)
 * value  the character to be displayed. 
 * dp     sets the decimal point.
*/

void setChar(int addr, int digit, char value, boolean dp);

يمكن رسم أي حرف آخر باستخدام الدالة setRow() . على سبيل المثال ، إذا كنت تريد عرض شيء يشبه الحرف الصغير 't' :



4- عودة إلى برنامج مثال المكتبة : إنشاء دالة لعرض حروف الكلمة "Arduino" حرف تلو الآخر على خانة الرقم digit 0 من الوحدة :

كود:
/*
 This method will display the characters for the
 word "Arduino" one after the other on digit 0. 
 */
void writeArduinoOn7Segment() {

  lc.setChar(0,0,'a',false);
  delay(delaytime);

  lc.setRow(0,0,0x05);// r
  delay(delaytime);

  lc.setChar(0,0,'d',false);
  delay(delaytime);

  lc.setRow(0,0,0x1c);//u
  delay(delaytime);

  lc.setRow(0,0,B00010000);//i
  delay(delaytime);

  lc.setRow(0,0,0x15);//n
  delay(delaytime);

  lc.setRow(0,0,0x1D);//o
  delay(delaytime);

  lc.clearDisplay(0);
  delay(delaytime);
}

5- إنشاء دالة لتمرير جميع الأعداد السداسية عشر والأحرف على الشاشة ، سوف تحتاج لأربعة أرقام digits على الأقل وإلا لن يكون العرض بالشكل الجيد .


كود:
/*
  This method will scroll all the hexa-decimal
 numbers and letters on the display. You will need at least
 four 7-Segment digits. otherwise it won't really look that good.
 */
void scrollDigits() {
  for(int i=0;i<13;i++) {
    lc.setDigit(0,3,i,false);
    lc.setDigit(0,2,i+1,false);
    lc.setDigit(0,1,i+2,false);
    lc.setDigit(0,0,i+3,false);
    delay(delaytime);
  }

  lc.clearDisplay(0);
  delay(delaytime);
}

6- أخيرا ، فى الدالة loop يتم استدعاء الدالتين للتنفيذ :


كود:
void loop() { 
  writeArduinoOn7Segment();
  scrollDigits();
}

النتائج :







رد مع اقتباس
  #74  
قديم 02-10-2020, 01:05 PM
الصورة الرمزية F.Abdelaziz
F.Abdelaziz F.Abdelaziz غير متواجد حالياً
استاذ الكترونيان
 
تاريخ التسجيل: May 2009
المشاركات: 2,812
معدل تقييم المستوى: 22
F.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to behold
افتراضي رد: تدريبات ومشاريع الأردوينو Arduino Tutorials an

تدريب :

كود:
//We always have to include the library
#include "LedControl.h"

/*
Now we need a LedControl to work with.
***** These pin numbers will probably not work with your hardware *****
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
We have only a single MAX72XX.
*/
LedControl lc=LedControl(12,11,10,1);

/* we always wait a bit between updates of the display */
unsigned long delaytime=500;

void setup() {
/* The MAX72XX is in power-saving mode on startup, we have to do a wakeup call */
lc.shutdown(0,false);

/* Set the brightness to a medium values */
lc.setIntensity(0,8);

/* and clear the display */
lc.clearDisplay(0);
}

void hello(){
lc.setChar(0,0,'H',false);
lc.setChar(0,1,'E',false);
lc.setChar(0,2,'L',false);
lc.setChar(0,3,'L',false);
lc.setChar(0,4,'0',false);
lc.setChar(0,5,'.',false);
lc.setChar(0,6,'.',false);
lc.setChar(0,7,'.',false);
delay(delaytime+1000);

lc.clearDisplay(0);
delay(delaytime);

lc.setDigit(0,0,1,false);
delay(delaytime);
lc.setDigit(0,1,2,false);
delay(delaytime);
lc.setDigit(0,2,3,false);
delay(delaytime);
lc.setDigit(0,3,4,false);
delay(delaytime);
lc.setDigit(0,4,5,false);
delay(delaytime);
lc.setDigit(0,5,6,false);
delay(delaytime);
lc.setDigit(0,6,7,false);
delay(delaytime);
lc.setDigit(0,7,8,false);
delay(1500);

lc.clearDisplay(0);
delay(delaytime);
}

void loop() {
hello();
}

النتائج :



رد مع اقتباس
  #75  
قديم 02-10-2020, 01:16 PM
الصورة الرمزية F.Abdelaziz
F.Abdelaziz F.Abdelaziz غير متواجد حالياً
استاذ الكترونيان
 
تاريخ التسجيل: May 2009
المشاركات: 2,812
معدل تقييم المستوى: 22
F.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to behold
افتراضي رد: تدريبات ومشاريع الأردوينو Arduino Tutorials an

تدريب : قراءة مدخل تناظرى والعرض على السفن سيجمنت والمشغل MAX7219 :

كود:
 #include "LedControl.h"

LedControl lc=LedControl(12,11,10,1);

void setup() {
       Serial.begin(9600);
     lc.shutdown(0,false);
     lc.setIntensity(0,8);
     lc.clearDisplay(0);
}

void loop() { 

int adc = analogRead(A0);

  lc.setDigit(0,0,adc/1000,false);//thousands : 1023/1000 = 1 
  lc.setDigit(0,1,(adc/100)%10,false);// hundreds : (1023/100) %10 = (10)%10 = 0 
  lc.setDigit(0,2,(adc/10)%10,false);// tens : (1023/10) %10 = (102) %10 = 2 
  lc.setDigit(0,3,adc%10,false);// ones : 1023%10 = 3 

Serial.println(adc);
  delay(100);
  
}

النتيجة :




تعديل البرنامج لقياس درجة الحرارة باستخدام الحساس LM35 :

كود:
#include "LedControl.h"

LedControl lc=LedControl(12,11,10,1);

void setup() {
       Serial.begin(9600);
     lc.shutdown(0,false);
     lc.setIntensity(0,8);
     lc.clearDisplay(0);
}

void loop() { 

int adc = analogRead(A0);
adc = adc* 0.489; // transfer factor 

  lc.setDigit(0,0,adc/100,false);//digit 0  , hundred , 150/100 = 1
  lc.setDigit(0,1,(adc/10)%10,false);// digit 1 , ten , 150 /10 =15 %10 =5
  lc.setDigit(0,2, adc%10,false);// digit 2 , one ,  150 %10 =0
  //lc.setDigit(0,3,adc%10,false);// digit 3
lc.setRow(0,3,0x4E);//Addr 0 , Position 3 ,Value “C”
Serial.println(adc);
  delay(100);
  
}


النتيجة :




تعديل البرنامج بحيث لا تظهر الأصفار على الشمال :

كود:
#include "LedControl.h"

LedControl lc=LedControl(12,11,10,1);

void setup() {
       Serial.begin(9600);
     lc.shutdown(0,false);
     lc.setIntensity(0,8);
     lc.clearDisplay(0);
}

void loop() { 

int adc = analogRead(A0);//Reading 
int temp = adc* 0.489; // Change reading to temperature (0-150 degrees)  

int hundred = temp /100;// digit 0
int ten = (temp /10)%10;// digit 1
int one = temp %10;// digit 2

if(temp <100) 
lc.setChar(0,0,' ',false); // Print space char in digit 0
else 
lc.setDigit(0,0, hundred,false);//Print hundred digit 

if(temp <10)
lc.setChar(0,1,' ',false); // Print space char in digit 1
else 
lc.setDigit(0,1, ten,false);//Print ten digit

 lc.setDigit(0,2, one,false);// digit 2 , Print one digit 
 
lc.setRow(0,3,0x4E);// digit 3 , Addr 0 , Position 3 ,Value “C” , print ‘C’

Serial.println(temp);
  delay(100);
  
}

النتيجة :





رد مع اقتباس
  #76  
قديم 02-13-2020, 08:25 PM
الصورة الرمزية F.Abdelaziz
F.Abdelaziz F.Abdelaziz غير متواجد حالياً
استاذ الكترونيان
 
تاريخ التسجيل: May 2009
المشاركات: 2,812
معدل تقييم المستوى: 22
F.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to behold
افتراضي ساعة Clock باستخدام الاردوينو وشاشة مكونة من أربعة

ساعة Clock باستخدام الاردوينو وشاشة مكونة من أربعة وحدات سفن سيجمنت بنظام الانتخاب Multiplexing وساعة التوقيت الحقيقى DS3231

يدور هذا التدريب حول إنشاء ساعة رقمية عن طريق "انتخاب" multiplexing ما بين أربعة وحدات سقن سيجمنت باستخدام Arduino UNO وعرض الوقت بتنسيق
HH: MM .

الدائرة الكهربية :



البرمجة :

سيتم شرح كيفية أخذ الوقت (بالساعة hour والدقيقة minute) من وحدة ساعة الوقت الحقيقى RTC بتنسيق 24 ساعة 24hr ، ثم يتم تحويله إلى التنسيق المناسب لعرضه في شاشة العرض السفن سيجمنت المكونة من 4 أرقام .
لربط الموديول DS3231 RTC مع Arduino UNO ، يتم استخدام ناقل I2C من Arduino UNO. يتم تضمين مكتبة تسمى <DS3231.h> في البرنامج للوصول إلى دوال الإعداد setting وقراءة الوقت والتاريخ وبيانات درجة الحرارة وما إلى ذلك. قم بتنزيل المكتبة وتثبيتها فى بيئة تطوير الاردوينو . نظرًا لأن وحدة RTC تستخدم واجهة I2C ، يتم استخدام المكتبة <wire.h> أيضًا في البرنامج.
يتم أخذ الساعة hour والدقيقة minute أولاً من RTC ويتم دمجهما معًا مثل 0930 (09:30 pm) ومن ثم يتم فصل الأرقام بشكل فردى مثل الآلاف thousands والمئات hundreds والعشرات tens والآحاد units ، والأرقام الفردية يتم تحويلها إلى تنسيق ثنائي مثل الصفر 0 يحول إلى 63 (0111111) . يتم إرسال هذا الكود الثنائي إلى سجل الإزاحة ومن ثم من سجل الإزاحة إلى السفن سيجمنت من نوع الكاثود المشترك ، ليتم عرض الرقم 0 على شاشة السفن سيجمنت . وبهذه الطريقة ، يتم انتخاب multiplexed الأرقام الأربعة ويتم عرض الساعة والدقيقة.


خطوات البرنامج :
1- في البداية ، يتم تضمين المكتبات الضرورية مثل مكتبة DS3231 والمكتبة Wire (مكتبة I2C).

كود:
 #include <Wire.h>   
#include<DS3231.h>

2- يتم تعريف أطراف التحكم فى السفن سيجمنت . ستلعب عناصر التحكم هذه دورًا مهمًا في انتخاب multiplexing الشاشة.

كود:
#define latchPin 5                      
#define clockPin 6
#define dataPin 4

3- يتم الإعلان عن المتغيرات لتخزين النتيجة المحولة أو الأولية raw المأخوذة من RTC.


كود:
 int h;               //Variable declared for hour
int m;              //Variable declared for minute
int thousands;    
int hundreds;
int tens;
int unit;
bool h24;
bool PM;

4- يتم الإعلان عن كائن الفئة DS3231 مثل RTC لتبسيط الاستخدام في الأسطر .

كود:
DS3231 RTC;

5- فى الدالة setup ، نظرا لأنه يتم ربط وحدة RTC مع الاردوينو باستخدام الاتصال I2C. لذلك ، تستخدم الدالة wire.begin() لبدء الاتصال I2C في العنوان الافتراضي للوحدة RTC حيث لا توجد وحدات I2C أخرى.

كود:
 Wire.begin();

6- كما يتم تعريف وضع الطرف ، ما إذا كان سيتصرق كدخل أم كخرج .

كود:
  pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,OUTPUT);
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);


7- تعمل الدالة loop بشكل لا نهائي وتأخذ الوقت بالساعة والدقيقة من الوحدة RTC DS3231 . يشير البارامتر ‘h24’ إلى تنسيق المتغير فى شكل 24hr .

كود:
كود:
int h= RTC.getHour(h24, PM); 
int m = RTC.getMinute();

8- بعد ذلك يتم الجمع بين الساعة hour والدقيقة minute كعدد واحد (مثال إذا كانت الساعة 10 والدقيقة 60 عندئذ يكون العدد 10*100=1000+60 =1060 ).

كود:
int number = h*100+m;

9- يتم الحصول على الأرقام الفردية من العدد (على سبيل المثال ، العدد 1060- الواحد 1 هو الآلاف thousands ، و الصفر 0 هو المئات hundreds ، والواحد التالى 1 هو العشرات tens والصفر الذى يليه 0 هو الآحاد unit ، آخر رقم). لفصل الأرقام ، يتم استخدام معامل باقى القسمة % . على سبيل المثال ، في 1060 للحصول على 1 عندئذ 1060/1000=1.06%10=1. ومن ثم يتم تخزين الأرقام المنفصلة في متغيرات منفصلة.

كود:
   int thousands = number/1000%10;
    int hundreds = number/100%10; 
    int tens = number/10%10;       
    int unit = number%10;

10- بعد ذلك يتم استخدام عبارة switch case لكل رقم فردي لتحويلها إلى التنسيق المناسب (تنسيق ثنائي) وإرسالها عبر مسجل الإزاحة لعرضها على السفن سيجمنت . على سبيل المثال (بالنسبة للرقم واحد “1” يتم تغييره إلى 06 (0000 0110)) . بحيث يتم إرساله عبر الإزاحة ، ويتم عرض الرقم واحد “1” على السفن سيجمنت (الصفر 0 يعنى LOW ، والواحد 1 يعنى HIGH).

كود:
 switch (t)
{
  case 0:
  unit = 63;
  break;
  case 1:
  unit = 06;
  break;
  case 2:
  unit =91;
  break;
  case 3:
  unit=79;
  break;
  case 4:
  unit=102;
  break;
  case 5:
  unit = 109;
  break;
  case 6:
  unit =125;
  case 7:
  unit = 07;
  break;
  case 8:
  unit = 127;
  break;
  case 9:
  unit =103;
  break; 
  }

11- بعد ذلك ، يتم إرسال الرقم الفردي بالتنسيق الثنائي عبر الدالة "shiftout" مع MSB أولاً ويكون الطرف المشترك للرقم digit الخاص به منخفضا LOW (كاثود مشترك) ويكون طرف latch مرتفعا HIGH .

كود:
digitalWrite(9, LOW);//digit thousands on , common cathode

digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST,thousands); 
digitalWrite(latchPin, HIGH); 

delay(5);

digitalWrite(9, HIGH); //   digit thousands off


البرنامج :

كود:
//Four-Digit 7 Segments Multiplexing using Arduino: Display time in HH:MM
#include <Wire.h>    //Library for SPI communication
#include <DS3231.h>   //Library for RTC module
 
#define latchPin 5                       
#define clockPin 6
#define dataPin 4

DS3231 RTC;         //Declare object RTC for class DS3231

int h;              //Variable declared for hour
int m;              //Variable declared for minute
int thousands;     
int hundreds;
int tens;
int unit;
bool h24;
bool PM;

void setup () 
{
    Wire.begin();
    
    pinMode(9,OUTPUT);
    pinMode(10,OUTPUT);
    pinMode(11,OUTPUT);
    pinMode(12,OUTPUT);

    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);
    }
 
void loop () 
{
    int h= RTC.getHour(h24, PM);  //To get the Hour
    int m = RTC.getMinute();      //TO get the minute

    int number = h*100+m;         //Converts hour and minute in 4-digit
    int thousands = number/1000%10; //Getting thousands digit from the 4 digit
    int hundreds = number/100%10;  //Getting hundreds digit from 4 digit
    int tens = number/10%10;        //Getting tens digit from 4-digit
    int unit = number%10;           //Getting last digit from 4-digit
    int t= unit;
    int u= tens;
    int v= hundreds;
    int w= thousands;

//Converting the individual digits into corresponding number for passing it through the shift register so LEDs are turned ON or OFF in seven segment
switch (t)
{
  case 0:
  unit = 63;//common cathod
  break;
  case 1:
  unit = 06;
  break;
  case 2:
  unit =91;
  break;
  case 3:
  unit=79;
  break;
  case 4:
  unit=102;
  break;
  case 5:
  unit = 109;
  break;
  case 6:
  unit =125;
  case 7:
  unit = 07;
  break;
  case 8:
  unit = 127;
  break;
  case 9:
  unit =103;
  break;  
  }
switch (u)
{
  case 0:
  tens = 63;
  break;
  case 1:
  tens = 06;
  break;
  case 2:
  tens =91;
  break;
  case 3:
  tens=79;
  break;
  case 4:
  tens=102;
  break;
  case 5:
  tens= 109;
  break;
  case 6:
  tens =125;
  case 7:
  tens = 07;
  break;
  case 8:
  tens = 127;
  break;
  case 9:
  tens =103;
  break;  
  }
 
  switch (v)
  {
  case 0:
  hundreds = 63;
  break;
  case 1:
  hundreds = 06;
  break;
  case 2:
  hundreds =91;
  break;
  case 3:
  hundreds=79;
  break;
  case 4:
  hundreds=102;
  break;
  case 5:
  hundreds = 109;
  break;
  case 6:
  hundreds =125;
  case 7:
  hundreds = 07;
  break;
  case 8:
  hundreds = 127;
  break;
  case 9:
  hundreds =103;
  break;  
  }
  
  switch (w)
  {
  case 0:
  thousands = 63;
  break;
  case 1:
  thousands = 06;
  break;
  case 2:
  thousands =91;
  break;
  case 3:
  thousands=79;
  break;
  case 4:
  thousands=102;
  break;
  case 5:
  thousands = 109;
  break;
  case 6:
  thousands =125;
  case 7:
  thousands = 07;
  break;
  case 8:
  thousands= 127;
  break;
  case 9:
  thousands =103;
  break;  
  }

    digitalWrite(9, LOW);// Turinig on thousands digit

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST,thousands);  // The thousand digit is sent
    digitalWrite(latchPin, HIGH);  // Set latch pin HIGH to store the inputs 

   delay(5);                      // delay for multiplexing 
   digitalWrite(9, HIGH);         // Turinig off thousands digit

    digitalWrite(10, LOW);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST,hundreds );    // The hundered digit is sent
    digitalWrite(latchPin, HIGH);

   
    delay(5);
   digitalWrite(10, HIGH);                              
  
    digitalWrite(11, LOW);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST,tens);   // The tens digit is sent
    digitalWrite(latchPin, HIGH);

   
    delay(5);
    digitalWrite(11, HIGH);
    
    digitalWrite(12, LOW);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST,unit);   // The last digit is sent
    digitalWrite(latchPin, HIGH);

    delay(5);
    digitalWrite(12, HIGH);
    
}





رد مع اقتباس
  #77  
قديم 02-18-2020, 02:10 PM
الصورة الرمزية F.Abdelaziz
F.Abdelaziz F.Abdelaziz غير متواجد حالياً
استاذ الكترونيان
 
تاريخ التسجيل: May 2009
المشاركات: 2,812
معدل تقييم المستوى: 22
F.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to behold
افتراضي قياس الرطوبة Humidity ودرجة الحرارة Temperature

قياس الرطوبة Humidity ودرجة الحرارة Temperature باستخدام الاردوينو Arduinoوالحساس DHT11

الرطوبة ودرجة الحرارة هى بارامترات شائعة لقياس الظروف البيئية. في هذا المشروع القائم على Arduino ، سنقوم بقياس درجة الحرارة والرطوبة المحيطة وعرضها على شاشة LCD مقاس 16 × 2. يتم استخدام مستشعر درجة الحرارة والرطوبة الشائع DHT11 مع Arduino uno لتطوير مقياس حرارة thermometer مئوى Celsius ومقياس رطوبة كنسبة مئوية .
يتكون هذا المشروع من ثلاثة أقسام – القسم الأول يستشعر الرطوبة ودرجة الحرارة باستخدام حساس الرطوبة ودرجة الحرارة DHT11. القسم الثاني يقرأ خرج وحدة الحساس DHT ويستخرج قيم درجة الحرارة والرطوبة إلى رقم مناسب من حيث النسبة المئوية والدرجة المئوية. والجزء الثالث من النظام يعرض الرطوبة ودرجة الحرارة على شاشة LCD .



يعتمد عمل هذا المشروع على الاتصال التسلسلى لسلك مفرد . فى البداية يرسل الاردوينو إشارة بدء إلى الوحدة DHT ثم يعطي DHT إشارة استجابة تحتوي على بيانات درجة الحرارة والرطوبة. يقوم الاردوينو بالتجميع والاستخراج في شكل جزأين ، الأول هو الرطوبة والثاني هو درجة الحرارة ومن ثم إرسالها إلى شاشة LCD 16X2 .
في هذا المشروع ، استخدمنا وحدة module استشعار تسمى DHT11. تتميز هذه الوحدة بتركيبة للرطوبة والحرارة مع خرج إشارة رقمية معايرة ، يعني أن وحدة الاستشعار DHT11 هي وحدة مشتركة لاستشعار الرطوبة ودرجة الحرارة والتي تعطي إشارة خرج رقمية معايرة. المستشعر DHT11 يعطينا قيمة دقيقة للغاية للرطوبة ودرجة الحرارة ويضمن موثوقية عالية والاستقرار على المدى الطويل. يحتوي هذا المستشعر على مكون لقياس الرطوبة من نوع المقاومة ومكون لقياس درجة الحرارة من النوع NTC مع متحكم 8 بت مدمج له استجابة سريعة وفعال من حيث التكلفة ومتوفر في حزمة بأربعة أطراف فى صف واحد .



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




شيء مهم هو التأكد من قيمة مقاومة السحب لأعلى لأننا إذا وضعنا مستشعر DHT على مسافة أقل من 20 متر ، فمن المستحسن أن تكون قيمة مقاومة السحب لأعلى هى 5k . إذا وضع DHT على مسافة أطول من 20 متر عندئذ استخدم القيمة المناسبة لمقاومة السحب لأعلى .

الدائرة الكهربية :




يتم استخدام شاشة LCD لعرض درجة الحرارة والرطوبة والتي ترتبط مباشرة مع اردوينو في وضع 4 بت. يتم توصيل أطراف الشاشة المسماة RS, EN, D4, D5, D6 , D7 لأطراف الاردوينو الرقمية رقم 2, 3, 4, 5, 6 , 7 . ويتم توصيل وحدة الاستشعار DHT11 بالطرف الرقمي 12 من الاردوينو ومع مقاومة السحب لأعلى 5k .

وصف البرمجة :

1- في البرمجة ، سوف نستخدم مكتبات مسبقة الصنع للمستشعر DHT11 ووحدة العرض LCD.

كود:
 #include<dht.h>      // Including library for dht
#include<LiquidCrystal.h>

2- ثم نقوم بتعريف أطراف الشاشة LCD وتعريف طرف المستشعر DHT ، وإنشاء كائن من الفئة dht ، وإعلان حرف درجة الحرارة :

كود:
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
#define dht_dpin 12 
dht DHT;
byte degree[8] = 
              {
                0b00011,
                0b00011,
                0b00000,
                0b00000,
                0b00000,
                0b00000,
                0b00000,
                0b00000
              };

3- ويتم تهيئة كل الأشياء فى دالة الإعداد setup .

كود:
 void setup()
{
 lcd.begin(16, 2);
 lcd.createChar(1, degree);
 lcd.clear();
 lcd.print("   Humidity   ");
 lcd.setCursor(0,1);
 lcd.print("  Measurement ");
 delay(2000);
 lcd.clear();
}

4- بعد ذلك في الدالة loop وباستخدام الدالة dht ، يقرأ المستشعر DHT بالدالة DHT.read11، ثم باستخدام بعض دوال dht (DHT.humidity , DHT.temperature ) ، نستخلص الرطوبة ودرجة الحرارة ونعرضها على شاشة LCD.

كود:
 void loop()
{
  DHT.read11(dht_dpin);

  lcd.setCursor(0,0);
  lcd.print("Humidity: ");
  lcd.print((int)DHT.humidity);   // printing Humidity on LCD
  lcd.print("%");

  lcd.setCursor(0,1);
  lcd.print("Temperature:");
  lcd.print((int)DHT.temperature);   // Printing temperature on LCD
  lcd.write(1); // lcd.print((char)223);
  lcd.print("C");
  delay(500);
}



البرنامج :

كود:
#include<dht.h>      // Including library for dht
#include<LiquidCrystal.h>

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
#define dht_dpin 12 
dht DHT;
byte degree[8] = 
              {
                0b00011,
                0b00011,
                0b00000,
                0b00000,
                0b00000,
                0b00000,
                0b00000,
                0b00000
              };

void setup()
{
 lcd.begin(16, 2);
 lcd.createChar(1, degree);
 lcd.clear();
 lcd.print("   Humidity   ");
 lcd.setCursor(0,1);
 lcd.print("  Measurement ");
 delay(2000);
 lcd.clear();
}

void loop()
{
  DHT.read11(dht_dpin);
  lcd.setCursor(0,0);
  lcd.print("Humidity: ");
  lcd.print((int)DHT.humidity);   // printing Humidity on LCD , DHT.humidity returns humidity in percent
  lcd.print(" %");
  lcd.setCursor(0,1);
  lcd.print("Temperature:");
  lcd.print((int)DHT.temperature); // Printing temperature on LCD,DHT.temperature returns the temperature in Celsius
  lcd.write(1);
  lcd.print("C");
  delay(500);
}



مثال مع العرض على المنفذ التسلسلى :



كود:
 
#include "dht.h"
#define dht_dpin 12 // sensor Pin
 
dht DHT;
 
void setup(){
 
  Serial.begin(9600);
  delay(500);//Delay to let system boot
  Serial.println("DHT11 Humidity & temperature Sensor\n\n");
  delay(1000);//Wait before accessing Sensor
 
}//end "setup()"
 
void loop(){
  //Start of Program 
 
    DHT.read11(dht_dpin);
    
    Serial.print("Current humidity = ");
    Serial.print(DHT.humidity); //  DHT.humidity returns humidity in percent
    Serial.print("%  ");
    Serial.print("temperature = ");
    Serial.print(DHT.temperature); // DHT.temperature returns the temperature in Celsius
    Serial.println("C  ");
    
    delay(5000);//Wait 5 seconds before accessing sensor again.
 
  //Fastest should be once every two seconds.
 
}// end loop()
رد مع اقتباس
  #78  
قديم 02-22-2020, 08:40 PM
الصورة الرمزية F.Abdelaziz
F.Abdelaziz F.Abdelaziz غير متواجد حالياً
استاذ الكترونيان
 
تاريخ التسجيل: May 2009
المشاركات: 2,812
معدل تقييم المستوى: 22
F.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to behold
افتراضي رد: تدريبات ومشاريع الأردوينو Arduino Tutorials an

مقاطعات الاردوينو Arduino Interrupts

مفهوم المقاطعة :
إعتبر سيارة سريعة الحركة ، إذا صدمت سيارة أخرى فجأة في الاتجاه المعاكس ، فإن أول شيء يحدث هو أن مستشعر التسارع accelerometer الموجود في السيارة يستشعر حدوث عدم تسارع de-acceleration (تباطؤ) مفاجئ ويؤدي إلى مقاطعة خارجية للميكروكونترولر (المتحكم الدقيق) الموجود في السيارة ، ثم ينتج المتحكم إشارة كهربائية لنشر الأكياس الهوائية على الفور. يقوم المتحكم الموجود في السيارة بمراقبة العديد من الأشياء في وقت واحد مثل استشعار سرعة السيارة ، والتحقق من أجهزة الاستشعار الأخرى ، والتحكم في درجة حرارة مكيف الهواء وما إلى ذلك. فما الذي يجعل الفتح المفاجىء لكيس الهواء في ثوانٍ؟ يتم استخدام إشارة المقاطعة Interrupt هنا والتي لها الأولوية القصوى للجميع.
مثال بسيط آخر على المقاطات Interrupts هو الهواتف المحمولة التي تعمل باللمس والتي لها الأولوية القصوى للإحساس باللمس "Touch". لدى كل جهاز إلكتروني تقريبًا نوع من المقاطعات لإيقاف (مقاطعة) العملية المعتادة والقيام ببعض الأشياء ذات الأولوية العليا عند حدث معين. يتم استئناف العملية العادية بعد قضاء المقاطعة.
من الناحية الفنية ، تعد المقاطعات Interrupts آلية يمكن بواسطتها تعليق (إيقاف) الإدخال / الإخراج أو التعليمة من التنفيذ العادي للمعالج والحصول على خدماته كما لوأن لها أولوية مرتفعة . على سبيل المثال ، يمكن مقاطعة المعالج الذي يقوم بتنفيذ عادي من قبل بعض أجهزة الاستشعار لتنفيذ عملية معينة موجودة في ISR (روتين خدمة المقاطعة). بعد تنفيذ المعالج ISR يمكن مرة أخرى استئناف التنفيذ العادي.

أنواع المقاطعات :
هناك نوعان من المقاطعات:
مقاطعة الأجهزة (الهاردوير) Hardware Interrupt : يحدث ذلك عندما يحدث حدث خارجي مثل تغيير حالة طرف المقاطعة الخارجي حالته من LOW إلى HIGH أو LIGH إلى LOW .
مقاطعة البرمجيات Software Interrupt : يحدث وفقا للتعليمات من البرمجيات . على سبيل المثال مقاطعات المؤقت Timer هي مقاطعة برمجية .

المقاطعات في الاردوينو :
الآن سوف نرى كيفية استخدام المقاطعات في لوحة الاردوينو ، والتى لها نوعان من المقاطعات:
• مقاطعة خارجية External Interrupt .
• مقاطعة تغيير الطرف Pin Change Interrupt.

المقاطعة الخارجية External Interrupt :
يتم تفسير هذه المقاطعة بواسطة الأجهزة hardware وتكون سريعة جداً. يمكن تعيين هذه المقاطعات ليتم تشغيلها في حالة حدوث مستويات "صاعدة " RISING أو "هابطة " FALLING أو الحالة LOW.
فى الاردوينو أونو UNO والنانو NANO تخصص الأطراف الرقمية 2 و 3 للمقاطعة الخارجية .

مقاطعات تغيير الطرف Pin Change Interrupts :
يمكن أن يكون للاردوينو أطراف مقاطعة أكثر تمكن enabled باستخدام المقاطعات Pin Change . في لوحات الاردوينو القائمة على المتحكمات ATmega168 / 328 ، يمكن استخدام أي الأطراف أو جميع أطراف الإشارة العشرين كأطراف مقاطعة. يمكن أيضًا تشغيلها باستخدام الحواف الصاعدة RISING أو الهابطة FALLING .

استخدام المقاطعات الخارجية في الاردوينو :
من أجل استخدام المقاطعات في الاردوينو ، يجب فهم المفاهيم التالية.

روتين خدمة المقاطعة Interrupt Service Routine (ISR) :
روتين خدمة المقاطعة ISR أو معالج المقاطعة Interrupt handler هو حدث يحتوي على مجموعة صغيرة من التعليمات . عند حدوث مقاطعة خارجية ، يقوم المعالج أولاً بتنفيذ هذه التعليمات البرمجية الموجودة في ISR ويعود مرة أخرى إلى الحالة التي ترك فيها التنفيذ العادي.

بناء جملة ISR فى الاردوينو كما يلى :

كود:
 attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

الوسيط الأول :

كود:
digitalPinToInterrupt(pin)

في الاردوينو أونو Uno ، ونانو NANO الأطراف المستخدمة للمقاطعة هي 2,3 وفى الميجا mega هى 2,3,18,19,20,21 . يتم تحديد طرف الدخل المستخدم للمقاطعة الخارجية هنا.

الوسيط الثانى :
ISR: هي دالة تستدعى عند إجراء مقاطعة خارجية.

الوسيط الثالث :
Mode : نوع الانتقال إلى التشغيل trigger ، على سبيل المثال falling ، rising ، إلخ.
• RISING : لتشغيل مقاطعة عندما ينتقل طرف من LOW إلى HIGH.
• FALLING : لتشغيل مقاطعة عندما ينتقل طرف من HIGH إلى LOW .
• CHANGE : لتشغيل المقاطعة عندما ينتقل طرف من LOW إلى HIGH أو من HIGH إلى LOW (أي عندما تتغير حالة الطرف ).

بعض الشروط أثناء استخدام المقاطعة :
• روتين خدمة مقاطعة المقاطعة (ISR) يجب أن يكون أقصر ما يمكن.
• الدالة Delay () لا تعمل داخل ISR ويجب تجنبها.

في هذا التدريب الخاص بمقاطعة الاردوينو ، يتم زيادة عدد number من 0 (العمل العادى) ويتم استخدام زري ضغط لتشغيل مقاطعة ، كل واحد متصل بطرف D2 & D3. يتم استخدام ليد LED لبيان المقاطعة. في حالة الضغط على زر الضغط الأول ، يتم تشغيل الليد ON ويظهر العرض interrupt2 ويختفى ، وعندما يتم الضغط على زر الضغط الثانى ، يتم إيقاف تشغيل الليد OFF ويظهر العرض interrupt1 ويختفى .

الدائرة الكهربية :



يتم توصيل اثنين من أزرار الضغط للاردوينو أونو في الأطراف D2 و D3. يتم استخدامها لعمل مقاطعتين خارجيتين ، أحدهما لتشغيل ليد LED والآخر لإيقاف تشغيل الليد LED. كل زر ضغط لديه مقاومة سحب لأسفل بقيمة 10k متصلة بالأرضى. لذلك عند الضغط على زر الضغط ، يكون المنطق HIGH (1) وعندما لا يتم الضغط عليه يكون المنطق LOW (0) . مقاومة السحب لأسفل إلزامية ، وإلا ستكون هناك قيم عائمة عند طرفى الدخل D2 & D3.
كما يتم استخدام ليد LED لبيان أن المقاطعة قد تم تشغيلها أو الضغط على زر.

برمجة مقاطعة الاردوينو :
في هذا التدريب ، يتم زيادة عدد من 0 والذي يتم عرضه بشكل مستمر على شاشة LCD (16x2) المتصلة مع الاردوينو أونو ، كلما تم الضغط على الزر الأيمن (طرف المقاطعة D3) ، يتم تشغيل الليد LED ويظهر العرض Interrupt2 ، وعند الضغط على الزر الأيسر (طرف المقاطعة D2) يتم إيقاف تشغيل الليد LED ويظهر العرض Interrupt1.

البرنامج :


كود:
//Interrupts using Arduino
//Circuit Digest
#include<LiquidCrystal.h>                        // Including lcd display library
LiquidCrystal lcd (7,8,9,10,11,12);              // Define LCD display pins RS,E,D4,D5,D6,D7
volatile int output = LOW;                      
int i = 0;   
void setup()                                                      
{
  lcd.begin(16,2);                              //  setting LCD as 16x2 type
  lcd.setCursor(0,0);
  lcd.print("CIRCUIT DIGEST");                                    
  lcd.setCursor(0,1);
  lcd.print("ArduinoInterrupt");
  delay(3000);                                                     
  lcd.clear();                                                    
  pinMode(13,OUTPUT);                                           
                                   
  attachInterrupt(digitalPinToInterrupt(2),buttonPressed1,RISING);  //  function for creating external interrupts at pin2 on Rising (LOW to HIGH)
  attachInterrupt(digitalPinToInterrupt(3),buttonPressed2,RISING);  //  function for creating external interrupts at pin3 on Rising (LOW to HIGH)   
  
}
void loop()                                                      
{  
   lcd.clear();                                                   
   lcd.print("COUNTER:");                                           
   lcd.print(i);                                                  
   ++i;                                                            
   delay(1000);   
   digitalWrite(13,output);     //Turns LED ON or OFF depending upon output value
}
void buttonPressed1()           //ISR function excutes when push button at pinD2 is pressed
{                    
   output = LOW;                //Change Output value to LOW                                
   lcd.setCursor(0,1);                                          
   lcd.print("Interrupt 1");
}
void buttonPressed2()           //ISR function excutes when push button at pinD3 is pressed                             
{                    
   output = HIGH;               //Change Output value to HIGH                                    
   lcd.setCursor(0,1);                                          
   lcd.print("Interrupt2");
}


الوصف :

1- فى البداية ً يتم تضمين ملف الرأس لشاشة LCD ومن ثم يتم تعريف أطراف LCD المستخدمة في الاتصال مع الاردوينو .أيضا يتم إعلان المتغيرات . لاحظ إلان المتغير output المستخدم بروتين خدمة المقاطعة باعتباره volatile .

كود:
#include<LiquidCrystal.h>                        
LiquidCrystal lcd (7,8,9,10,11,12); // Define LCD display pins RS, E, D4, D5, D6, D7

volatile int output = LOW;                      
int i = 0;

2- داخل الدالة setup ، يتم عرض بعد الرسائل الافتتاحية على شاشة LCD .

كود:
 void setup()                                                      
{
  lcd.begin(16,2);                              //  setting LCD as 16x2 type

  lcd.setCursor(0,0);
  lcd.print("CIRCUIT DIGEST");
                                    
  lcd.setCursor(0,1);
  lcd.print("ArduinoInterrupt");

  delay(3000);
                                                     
  lcd.clear(); 
                                                   
  pinMode(13,OUTPUT);                                           
                                   
  attachInterrupt(digitalPinToInterrupt(2),buttonPressed1,RISING);  //  function for creating external interrupts at pin2 on Rising (LOW to HIGH)
  attachInterrupt(digitalPinToInterrupt(3),buttonPressed2,RISING);  //  function for creating external interrupts at pin3 on Rising (LOW to HIGH)   
  
}

3- ثم في نفس الدالة setup يجب تحديد أطراف الدخل والخرج . يتم توصيل الطرف D13 بأنود الليد LED ، لذلك يجب تعريف هذا الطرف على أنه خرج .

كود:
pinMode(13,OUTPUT);

4- الآن الجزء الرئيسي المهم في البرمجة هو الدالة attachInterrupt() ، ويتم تضمينها أيضا داخل الدالة setup .

كود:
attachInterrupt(digitalPinToInterrupt(2),buttonPressed1,RISING);  //  function for creating external interrupts at pin2 on Rising (LOW to HIGH)
  attachInterrupt(digitalPinToInterrupt(3),buttonPressed2,RISING);  //  function for creating external interrupts at pin3 on Rising (LOW to HIGH)

هنا ، يتم تحديد أن الطرف 2 هو للمقاطعة الخارجية ، ويتم استدعاء الدالة buttonPressed1 عندما يكون هناك RISING (LOW to HIGH) عند D2. والطرف 3 هو أيضًا للمقاطعة الخارجية ويتم استدعاء الدالة buttonPressed2 عندما يكون هناك RISING على الطرف D3.

5- داخل الدالة loop ، يتم زيادة العدد (i) من الصفر وطباعته على شاشة LCD(16x2) .

كود:
void loop()                                                      
{  
   lcd.clear();                                                   
   lcd.print("COUNTER:");                                           
   lcd.print(i);                                                  
   ++i;                                                            
   delay(1000);   
   digitalWrite(13,output);     //Turns LED ON or OFF depending upon output value
}

في نفس الدالة loop ، يتم استخدام الدالة digitalWrite على الطرف D13 حيث يتم توصيل أنود الليد LED. اعتمادًا على قيمة المتغير output، سيتم تشغيل الليد LED أو إيقاف تشغيله .

كود:
 digitalWrite(13,output);     //Turns LED ON or OFF depending upon output value

6- الجزء الأكثر أهمية هو إنشاء دالة معالج المقاطعة وفقًا للاسم المستخدم في الدالة attachInterrupt.
نظرا لأنه تم استخدام أطراف المقاطعة 2 و 3 لذلك مطلوب اثنين ISR كما يلى :

كود:
void buttonPressed1()           //ISR function excutes when push button at pinD2 is pressed
{                    
   output = LOW;                //Change Output value to LOW                                
   lcd.setCursor(0,1);                                          
   lcd.print("Interrupt 1");
}

يتم تنفيذ هذه الدالة عند الضغط على زر الضغط على الطرف D2 (RISING EDGE) . تعمل هذه الدالة على تغيير حالة الخرج إلى LOW مما يؤدي إلى إيقاف تشغيل الليد LED وطباعة “interrupt1” على شاشة LCD.


كود:
void buttonPressed2()           //ISR function executes when push button at pinD3 is pressed                             
{                    
   output = HIGH;               //Change Output value to HIGH                                    
   lcd.setCursor(0,1);                                          
   lcd.print("Interrupt2");
}

يتم تنفيذ هذه الدالة عند الضغط على زر الضغط على الطرف D3. تعمل هذه الدالة على تغيير حالة output إلى HIGH مما يؤدي إلى تشغيل الليد LED وطباعة “interrupt2” على شاشة LCD.
رد مع اقتباس
  #79  
قديم 02-23-2020, 10:15 PM
الصورة الرمزية F.Abdelaziz
F.Abdelaziz F.Abdelaziz غير متواجد حالياً
استاذ الكترونيان
 
تاريخ التسجيل: May 2009
المشاركات: 2,812
معدل تقييم المستوى: 22
F.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to behold
افتراضي الاردوينو والمهام المتعددة Multitasking وكيفية است

الاردوينو والمهام المتعددة Multitasking وكيفية استخدام الدالة millis()

قاد تعدد المهام أجهزة الكمبيوتر إلى ثورة حيث يمكن تشغيل برنامج واحد أو أكثر في وقت واحد مما يزيد من الكفاءة والمرونة والقدرة على التكيف والإنتاجية. في الأنظمة المضمّنة embedded ، يمكن لميكروكنترولر أيضًا التعامل مع تعدد المهام وتنفيذ مهمتين أو أكثر في وقت واحد دون إيقاف التعليمات الحالية.
في هذا التدريب سوف نتعلم كيف يؤدي Arduino تعدد المهام. بشكل عام ، يتم استخدام الدالة delay() في Arduino للقيام بمهمة دورية مثل وميض ليد LED Blinking ولكن هذه الدالة توقف البرنامج لبعض الوقت المحدد ولا تسمح بإجراء عمليات أخرى. لذلك يوضح هذا التدريب كيف يمكننا تجنب استخدام الدالة delay() واستبدالها بالدالة millis() لأداء أكثر من مهمة في وقت واحد وجعل Arduino متحكم متعدد المهام. قبل الخوض في التفاصيل ، لنبدأ بتفهم تعدد المهام.

ماهو "تعدد المهام" Multitasking ؟
تعدد المهام يعني ببساطة تنفيذ أكثر من مهمة أو برنامج في وقت واحد في نفس الوقت. تقريبا جميع أنظمة التشغيل لها ميزة تعدد المهام. يُعرف هذا النوع من أنظمة التشغيل باسم MOS (نظام التشغيل متعدد المهام). يمكن أن يكون MOS نظام تشغيل الكمبيوتر المحمول أو المكتبي . مثال جيد على تعدد المهام في أجهزة الكمبيوتر هو عندما يقوم المستخدمون بتشغيل تطبيق البريد الإلكتروني ، ومتصفح الإنترنت ، ومشغل الوسائط ، والألعاب ، في نفس الوقت وإذا كان المستخدمون لا يرغبون في استخدام التطبيق يتم تشغيله في الخلفية إذا لم يتم إغلاقه. يستخدم المستخدم النهائي كل هذه التطبيقات في نفس الوقت لكن نظام التشغيل يأخذ هذا المفهوم بشكل مختلفًا بعض الشيء. دعونا نناقش كيف يدير نظام التشغيل تعدد المهام.



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


لماذا يجب تجنب استخدام الدالة delay()
إذا تم النظر في الوثائق المرجعية للاردوينو ، نجد أن هناك نوعان من دوال التأخير ، الأول هو delay() والثاني هو delayMicroseconds() . كلتا الدالتان متطابقتان من حيث توليد التأخير. الفرق الوحيد هو أنه في الدالة delay() ، يكون الوسيط الذي يتم تمريره عدد صحيح بالمللي ثانية أي إذا كتبنا delay(1000) سيكون التأخير هو 1000 مللي ثانية أي ثانية واحدة. بالمثل ، في الدالة delayMicroseconds() ، يكون الوسيط الذى يتم تمريره بالميكروثانية أي إذا كتبنا delayMicroseconds(1000) ، فسيكون التأخير 1000 ميكروثانية أي 1 مللي ثانية.
هنا تأتي النقطة ، كلتا الدالتين توقفان مؤقتًا البرنامج لمقدار الوقت المنقضي في دالة التأخير. لذلك إذا كنا نعطي تأخيرًا لمدة ثانية واحدة ، فلن يتمكن المعالج من الانتقال إلى التعليمات التالية حتى تمر ثانية واحدة. وبالمثل ، إذا كان التأخير 10 ثوانٍ ، فسيتوقف البرنامج لمدة 10 ثوانٍ ولن يسمح للمعالج بالانتقال إلى التعليمات التالية حتى تمر 10 ثوانٍ. هذا يعوق أداء المتحكم من حيث السرعة وتنفيذ التعليمات.
أفضل مثال لتوضيح عيب دالة التأخير هو استخدام عدد 2 زر ضاغط . لنفرض أننا نريد تبديل toggle اثنين من الليدات باستخدام زرى الضغط . لذلك إذا تم الضغط على أحد زرى الضغط ، فيجب أن يضيء الليد المقابل لمدة ثانيتين ، وبالمثل إذا تم الضغط على الزر الثاني ، فيجب أن يتوهج الليد المقابل لمدة 4 ثوانٍ. ولكن عندما نستخدم delay ، إذا ضغط المستخدم على الزر الأول ، فسيتوقف البرنامج لمدة ثانيتين وإذا ضغط المستخدم على الزر الثاني قبل تأخير لمدة ثانيتين ، فلن يقبل المتحكم الإدخال حيث أن البرنامج في مرحلة التوقف halt . تشير الوثائق الرسمية لاردوينو بوضوح إلى ذلك في وصف دالة التأخير . يمكنك المراجعة والتحقق من ذلك ليكون أكثر وضوحًا.

لماذا استخدام الدالة millis() ؟
للتغلب على المشكلة الناتجة عن التأخير ، يجب على المبرمج استخدام الدالة millis() والتي هي سهلة الاستخدام بمجرد أن تصبح معتادا عليها ، وسوف تستخدم أداء وحدة المعالجة المركزية بنسبة 100 ٪ دون توليد أي تأخير في تنفيذ التعليمات. الدالة millis() هي دالة تقوم فقط بإرجاع مقدار المللي ثانية التي انقضت منذ بدأت لوحة Arduino في تشغيل البرنامج الحالي دون تجميد البرنامج. سيتم تجاوز overflow هذا الرقم الزمني (أي العودة إلى الصفر) ، بعد حوالي 50 يومًا.
تماما مثل ما أن الاردوينو لها الدالة delayMicroseconds() ، فإن لديه النسخة micro من الدالة millis() وهى micros() . الفرق بين micros و millis هو أنه سيتم تجاوز micros() بعد حوالي 70 دقيقة ، مقارنة مع millis() وهو 50 يومًا. بناءً على التطبيق ، يمكنك استخدام millis() أو micros() .

إستخدام millis() بدلا من delay() :
لاستخدام millis() للتوقيت والتأخير ، تحتاج إلى تسجيل وتخزين الوقت الذي حدث فيه الإجراء لبدء الوقت ثم التحقق على فترات زمنية ما إذا كان الوقت المحدد قد انقضى. هكذا كما ذكر ، يتم تخزين الوقت الحالي في متغير.

كود:
unsigned long currentMillis = millis();

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

كود:
unsigned long previousMillis;
unsigned long period = 1000;

لفهم ذلك ، دعنا نأخذ مثالاً على وميض ليد LED بسيط. ستخبرنا period = 1000 بأن الليد LED سوف يومض لمدة ثانية واحدة أو 1000 مللي ثانية.




كود:
const int ledPin =  4; // the LED pin number connected
int ledState = LOW;             // used to set the LED state
unsigned long previousMillis = 0;  //will store last time LED was blinked
const long period = 1000;         // period at which to blink in ms

void setup() {
  pinMode(ledPin, OUTPUT); // set ledpin as output
}

void loop() {
 unsigned long currentMillis = millis(); // store the current time
  if (currentMillis - previousMillis >= period) { // check if 1000ms passed
   previousMillis = currentMillis;   // save the last time you blinked the LED
   if (ledState == LOW) { // if the LED is off turn it on and vice-versa
     ledState = HIGH;
   } else {
ledState = LOW;
}
   digitalWrite(ledPin, ledState);//set LED with ledState to blink again
 }
}


هنا العبارة <if (currentMillis - previousMillis >= period)> تتحقق من ما إذا مر 1000ms . إذا مر 1000ms ، عندئذ يومض الليد ومرة أخرى يأتى إلى نفس الحالة ، ويستمر ذلك . هذا كل شيء ، لقد تعلمنا استخدام millis بدلاً من delay . هذه الطريقة لن توقف البرنامج لفترة زمنية محددة.
المقاطعات Interrupts في الاردوينو تعمل كما هو الحال في الميكروكنترولر الأخرى. تحتوي لوحة Arduino UNO على طرفين منفصلين لتوصيل المقاطعات هى الطرف 2 والطرف 3 . راجع المقاطعة فى الاردوينو.
سنقوم هنا بعرض المهام المتعددة للاردوينو من خلال التعامل مع مهمتين في نفس الوقت. ستشمل المهام وميض اثنين من الليدات في تأخير زمني مختلف جنبا إلى جنب مع زر ضغط الذي سيتم استخدامه للتحكم على حالة ON / OFF لليد . لذلك سيتم تنفيذ ثلاث مهام في وقت واحد.

الدائرة الكهربية :



برمجة الاردوينو أونو للمهام المتعددة Programming Arduino UNO for Multitasking
تتطلب برمجة الاردوينو أونو للمهام المتعددة فقط المنطق وراء كيفية عمل millis() الموضح أعلاه. يوصى بممارسة وميض ليد باستخدام millis() مرارًا وتكرارًا لجعل المنطق واضحًا ولتجعل نفسك مرتاحًا مع millis() قبل البدء في برمجة الاردوينو أونو للقيام بمهام متعددة. في هذا التدريب ، يتم استخدام المقاطعة أيضًا مع millis() في وقت واحد من أجل تعدد المهام. الزر سيكون مقاطعة. لذلك كلما تم توليد مقاطعة ، مثل الضغط على زر ، سوف يتحول الليد وضع التشغيل on أو إيقاف التشغيل off .
1- فى بداية البرنامج :
• يتم إعلان أرقام الأطراف حيث يتم توصيل الليدات والزر الضاغط .

كود:
int led1 =  6;
int led2 =  7;
int toggleLed = 5;
int pushButton = 2;

• بعد ذلك نعلن عن متغيرًات لتخزين حالة الليدات للاستخدام المستقبلي.

كود:
int ledState1 = LOW;
int ledState2 = LOW;

• تمامًا كما هو موضح أعلاه في مثال الوميض ، يتم إعلان المتغيرات period و previousmillisللمقارنة وتوليد التأخير لليدات . يومض الليد الأول بعد كل ثانية ويومض الليد الثانى بعد كل 200 مللي ثانية.

كود:
unsigned long previousMillis1 = 0; 
const long period1 = 1000;

unsigned long previousMillis2 = 0;
const long period2 = 200;

• كما يتم استخدام دالة millis لتوليد تأخير منع تأثير الارتداد debounce لتجنب الضغطات المتعددة لزر الضغط.

كود:
int debouncePeriod = 20;  
int debounceMillis = 0;
• ويتم استخدام ثلاثة متغيرات لتخزين حالة زر الضغط كمقاطعة ، وليد التبديل toggle LED وحالة زر الضغط.

كود:
 bool buttonPushed = false;
int ledChange = LOW;  
int lastState = HIGH;

2- فى الدالة setup :
• يتم تحديد (تعريف) عمل الطرف الذي سيعمل كدخل أو كخرج .

كود:
pinMode(led1, OUTPUT);             
pinMode(led2, OUTPUT);
pinMode(toggleLed, OUTPUT);
pinMode(pushButton, INPUT);

• كما يتم تحديد (تعريف) طرف المقاطعة عن طريق ربط attaching المقاطعة مع تعريف ISR ووضع Mode المقاطعة. لاحظ أنه يوصى باستخدام digitalPinToInterrupt(pin_number) عند إعلان الدالة attachInterrupt() لترجمة الرقم الرقمي الفعلي إلى رقم المقاطعة المحدد.

كود:
attachInterrupt(digitalPinToInterrupt(pushButton), pushButton_ISR, CHANGE);

3- تتم كتابة روتين خدمة المقاطعة وسيؤدي فقط إلى تغيير العلم buttonPushed. لاحظ أن روتين خدمة المقاطعة يجب أن يكون قصيرا قدر الإمكان.

كود:
void pushButton_ISR()
{
  buttonPushed = true; 
}

4- تبدأ الدالة loop بتخزين قيمة millis في المتغير CurrentMillis والذي سيخزن قيمة الوقت المنقضي في كل مرة تتكرر فيها الحلقة.

كود:
unsigned long currentMillis = millis();

يوجد ثلاث مهام متعددة ، وميض ليد عند كل ثانية ، ووميض ليد ثانى كل 200 مللي ثانية ، وإذا تم الضغط على زر الضغط ، يتم تبديل تشغيل/إيقاف ON / OFF ليد ثالث . لذلك سوف نكتب ثلاثة أجزاء للقيام بهذه المهمة.
• المهمة الأولى هى تبديل حالة LED بعد كل ثانية واحدة من خلال مقارنة millis المنقضي.

كود:
if (currentMillis - previousMillis1 >= period1) { 
    previousMillis1 = currentMillis;  
    if (ledState1 == LOW) { 
      ledState1 = HIGH;
    } else {
      ledState1 = LOW;
    }
    digitalWrite(led1, ledState1);   
  }

• المهمة الثانية ، وبشكل مشابه ، يتم تبديل ليد بعد كل 200 مللي ثانية من خلال مقارنة millis المنقضي.

كود:
if (currentMillis - previousMillis2 >= period2) {
    previousMillis2 = currentMillis;  
    if (ledState2 == LOW) {
      ledState2 = HIGH;
    } else {
      ledState2 = LOW;
    }
    digitalWrite(led2, ledState2);
  }

• المهمة الثالثة ، أخيرًا ، يتم مراقبة العلم buttonPushed وبعد إنشاء تأخير إلغاء الارتداد 20 مللي ثانية ، فقط يتم تبديل حالة الليد LED التي تتوافق مع زر الضغط المرفق كمقاطعة.

كود:
  if (buttonPushed = true)    // check if ISR is called
  {
    if ((currentMillis - debounceMillis) > debouncePeriod && buttonPushed)  // generate 20ms debounce delay to avoid multiple presses
    {
      debounceMillis = currentMillis;      // save the last debounce delay time
      if (digitalRead(pushButton) == LOW && lastState == HIGH)     // change the led after push button is pressed
      {
        ledChange = ! ledChange;
        digitalWrite(toggleLed, ledChange);   
        lastState = LOW;
      }
      else if (digitalRead(pushButton) == HIGH && lastState == LOW)    
      {
        lastState = HIGH;
      }
     buttonPushed = false;
    }
  }

البرنامج :

كود:
/* Arduino Multitasking
    Author : CircuitDigest (circuitdigest.com)
*/
int led1 =  6;      // led1 connected at pin 6
int led2 =  7;       // led2 connected at pin 7
int toggleLed = 5;    // push button controlled led connected at pin 5
int pushButton = 2;    // push button connected at pin 2 which is also interrupt pin
int ledState1 = LOW;  // to determine the states of led1 and led2
int ledState2 = LOW;
unsigned long previousMillis1 = 0;  //store last time LED1 was blinked
const long period1 = 1000;         // period at which led1 blinks in ms
unsigned long previousMillis2 = 0;  //store last time LED2 was blinked
const long period2 = 200;             // period at which led1 blinks in ms
int debouncePeriod = 20;            // debounce delay of 20ms
int debounceMillis = 0;            // similar to previousMillis
bool buttonPushed = false;     // interrupt routine button status 
int ledChange = LOW;      // to track the led status last 
int lastState = HIGH;    // to track last button state

void setup() {
  pinMode(led1, OUTPUT);               // define pins as input or output
  pinMode(led2, OUTPUT);
  pinMode(toggleLed, OUTPUT);
  pinMode(pushButton, INPUT);
  attachInterrupt(digitalPinToInterrupt(pushButton), pushButton_ISR, CHANGE);  // use interrupt pin2 
}

void pushButton_ISR()
{
  buttonPushed = true;   // ISR should be as short as possible
}

void loop() {
  unsigned long currentMillis = millis(); // store the current time

  if (currentMillis - previousMillis1 >= period1) {    // check if 1000ms passed
    previousMillis1 = currentMillis;   // save the last time you blinked the LED
    if (ledState1 == LOW) {  // if the LED is off turn it on and vice-versa
      ledState1 = HIGH;   //change led state for next iteration
    } else {
      ledState1 = LOW;
    }
    digitalWrite(led1, ledState1);    //set LED with ledState to blink again
  }

  if (currentMillis - previousMillis2 >= period2) { // check if 1000ms passed
    previousMillis2 = currentMillis;   // save the last time you blinked the LED
    if (ledState2 == LOW) { // if the LED is off turn it on and vice-versa
      ledState2 = HIGH;
    } else {
      ledState2 = LOW;
    }
    digitalWrite(led2, ledState2);//set LED with ledState to blink again
  }

  if (buttonPushed = true)    // check if ISR is called
  {
    if ((currentMillis - debounceMillis) > debouncePeriod && buttonPushed)  // generate 20ms debounce delay to avoid multiple presses
    {
      debounceMillis = currentMillis;      // save the last debounce delay time
      if (digitalRead(pushButton) == LOW && lastState == HIGH)     // change the led after push button is pressed
      {
        ledChange = ! ledChange;
        digitalWrite(toggleLed, ledChange);    
        lastState = LOW;
      }
      else if (digitalRead(pushButton) == HIGH && lastState == LOW)     
      {
        lastState = HIGH;
      }
      buttonPushed = false;
    }
  }
}
رد مع اقتباس
  #80  
قديم 03-03-2020, 08:42 PM
الصورة الرمزية F.Abdelaziz
F.Abdelaziz F.Abdelaziz غير متواجد حالياً
استاذ الكترونيان
 
تاريخ التسجيل: May 2009
المشاركات: 2,812
معدل تقييم المستوى: 22
F.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to beholdF.Abdelaziz is a splendid one to behold
افتراضي قفل رقمي مشفر بكلمة مرور باستخدام Arduino,Keypad,E

قفل رقمي مشفر بكلمة مرور باستخدام Arduino,Keypad,EEPROM,LCD :

الدائرة الكهربية :



البرنامج :

كود:
#include <Keypad.h>
#include<LiquidCrystal.h>
#include<EEPROM.h>

LiquidCrystal lcd(A0,A1,A2,A3,A4,A5);//RS,E,D4,D5,D6,D7

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char hexaKeys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {2,3,4,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6,7,8,9};   //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);


char password[4];// Input password
char pass[4],pass1[4];
char customKey=0;

int i=0;// password  characters counter
int led=12;//Green LED connected to pin 12
int buzzer = 10;//Buzzer connected to pin 10 
int relay = 11; //relay connected to pin 11

void setup()
{
  lcd.begin(16,2);

  pinMode(relay, OUTPUT);//Relay output
  pinMode(led, OUTPUT);
  pinMode(buzzer, OUTPUT);

  
  lcd.print(" Electronic ");
  lcd.setCursor(0,1);
  lcd.print(" Keypad Lock ");
  delay(2000);
  lcd.clear();

  lcd.print("Enter Ur Passkey:");
  lcd.setCursor(0,1);

//This part must remove after first run 
  for(int j=0;j<4;j++)
    EEPROM.write(j, j+49); //49 = character ‘1’
  for(int j=0;j<4;j++)
    pass[j]=EEPROM.read(j);
}

void loop()
{
  digitalWrite(relay, HIGH);//Key locked

  customKey = customKeypad.getKey();

  if(customKey=='#')
    change();

  if (customKey)
  {
    password[i++]=customKey;// Input password
    lcd.print(customKey);
    beep();
  }

  if(i==4)//No. of input characters
  {
    delay(200);

    for(int j=0;j<4;j++)
      pass[j]=EEPROM.read(j);//Saved password
   
 if(!(strncmp(password, pass,4)))// compare password with pass only the first four characters. returns 0, if both are equal
    { //if match
      digitalWrite(led, HIGH);//Open indication
      beep();
      lcd.clear();

      lcd.print("Passkey Accepted");
      digitalWrite(relay, LOW);//Relay off , lock open
      delay(2000);

      lcd.setCursor(0,1);
      lcd.print("#.Change Passkey");
      delay(2000);
      lcd.clear();

      lcd.print("Enter Passkey:");
      lcd.setCursor(0,1);
      i=0;
      digitalWrite(led, LOW);
    }

    else // if not match
    {
      digitalWrite(relay, HIGH);
      digitalWrite(buzzer, HIGH);
      lcd.clear();
      lcd.print("Access Denied...");
      lcd.setCursor(0,1);
      lcd.print("#.Change Passkey");
      delay(2000);
      lcd.clear();
      lcd.print("Enter Passkey:");
      lcd.setCursor(0,1);
      i=0;
      digitalWrite(buzzer, LOW);
    }//end of if…else
  }//end of if(i==4)
}// end of loop


void change()
{
  int j=0;
  lcd.clear();
  lcd.print("UR Current Passk");
  lcd.setCursor(0,1);

  while(j<4)
  {
    char key=customKeypad.getKey();

    if(key)
    {
      pass1[j++]=key;
      lcd.print(key);
      beep();
    }//end if

    key=0;
  }//end while

  delay(500);

  if((strncmp(pass1, pass, 4)))
  {
    lcd.clear();
    lcd.print("Wrong Passkey...");
    lcd.setCursor(0,1);
    lcd.print("Better Luck Again");
    delay(1000);
  }

  else
  {
    j=0;
    lcd.clear();
    lcd.print("Enter New Passk:");
    lcd.setCursor(0,1);

    while(j<4)
    {
      char key=customKeypad.getKey();

      if(key)
      {
        pass[j]=key;
        lcd.print(key);
        EEPROM.write(j,key);
        j++;
        beep();
      }//end if

    }//end while

    lcd.print(" Done......");
    delay(1000);
  }//end else

  lcd.clear();
  lcd.print("Enter Ur Passk:");
  lcd.setCursor(0,1);

  customKey=0;

} // end of void change

void beep()
{
  digitalWrite(buzzer, HIGH);
  delay(20);
  digitalWrite(buzzer, LOW);
}

رد مع اقتباس
إضافة رد

مواقع النشر (المفضلة)

أدوات الموضوع
انواع عرض الموضوع

تعليمات المشاركة
لا تستطيع إضافة مواضيع جديدة
لا تستطيع الرد على المواضيع
لا تستطيع إرفاق ملفات
لا تستطيع تعديل مشاركاتك

BB code is متاحة
كود [IMG] متاحة
كود HTML معطلة



الساعة الآن 02:23 PM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
الحقوق محفوظة لمنتديات الاليكترونيات العصرية

Security team

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77