قياس الجهد باستخدام الاردوينو

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

 

voltmeter

 

المواد والأدوات

اردوينو

X1 اردوينو اونو

DC-Voltage-Sensor

X1 مستشعر جهد التيار المستمر

LCD

X1 الشاشة الكرستالية

X1لوحة تجارب

arduino-usb-lead-blue

X1 سلك اردوينو

مقاومة متغيرة

1X مقاومة متغيرة

أسلاك توصيل

مجموعة أسلاك توصيل (M/M)

us-sanitizer-without-touch

مجموعة أسلاك توصيل (M/F)

 

توصيل الدائرة

Arduino-Uno- voltage sensor

البرمجة

 

#include "LiquidCrystal.h"

const int voltageSensor = A0;

float vOUT = 0.0;
float vIN = 0.0;
float R1 = 30000.0;
float R2 = 7500.0;
int value = 0;

LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // RS, E, D4, D5, D6, D7

void setup()
{
//Serial.begin(9600);
lcd.begin(16,2);
lcd.print(" Measure > 25V ");
delay(2000);
}

void loop()
{
value = analogRead(voltageSensor);
vOUT = (value * 5.0) / 1024.0;
vIN = vOUT / (R2/(R1+R2));
//Serial.print("Input = ");
//Serial.println(vIN);
lcd.setCursor(0,0);
lcd.print("Input = ");
lcd.setCursor(9,0);
lcd.print(vIN);
delay(500);
}

شرح الكود البرمجي

بالبداية يتطلب استدعاء مكتبة الشاشة الكرستالية

#include "LiquidCrystal.h"

نعرف منفذ لقراءة مستشعر جهد التيار المستمر

const int voltageSensor = A0;

نعرف قيمة ابتدائية للمتغيرات

float vOUT = 0.0;
float vIN = 0.0;

نعرف قيمة المقاومات الموجودة بالحساس

float R1 = 30000.0;
float R2 = 7500.0;
int value = 0;

نعرف منافذ الشاشة الكرستالية

LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // RS, E, D4, D5, D6, D7

في دالة void setup() نكتب أوامر تهيئة الشاشة

void setup()
{

lcd.begin(16,2);
lcd.print(" Measure > 25V ");
delay(2000);
}

في دالة void loop() نأخذ القراءات من المستشعر و نكتب المعادلات لحساب قيمة الجهد
ليتم طباعتها على الشاشة الكرستالية

void loop()
{
value = analogRead(voltageSensor);
vOUT = (value * 5.0) / 1024.0;
vIN = vOUT / (R2/(R1+R2));
//Serial.print("Input = ");
//Serial.println(vIN);
lcd.setCursor(0,0);
lcd.print("Input = ");
lcd.setCursor(9,0);
lcd.print(vIN);
delay(500);
}



لعبة دولار النينجا (Ninja Dollar) باستخدام الاردوينو

مقدمة

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

المواد والأدوات

دولار نينجا

1× اردوينو اونو

ninja-dollar-lcd-game

1× سلك الاردوينو

دولار نينجا

 1× شاشة كرستالية

دولار نينجا

40 رأس دبوس

ninja-dollar-lcd-game

 حزمة أسلاك توصيل (ذكر- ذكر)

دولار نينجا

حزمة أسلاك توصيل (ذكر – أنثى)

دولار النينجا

1× 2C / IIC Serial Interface Module

شفرة مورس

ضغاط تحكم
دولار نينجا

2× مقاومة 1K Ω

اردوينو

1× لوحة تجارب – حجم كبير

دولار نينجا

 مصدر صوت

توصيل الدائرة

لمعرفة المزيد حول الشاشة الكرستالية يمكنك الرجوع للدرس التحكم بالشاشة الكرستالية LCD.

لابد من تلحيم المنافذ مع الشاشة الكرستالية، للمزيد حول اللحام يمكنك الرجوع للدرس تعلم كيفية التلحيم – تلحيم القطع باللوحة الإلكترونية

دولار النينجا

البرمجة

ارفع الكود البرمجي للعبة دولار النينجا على لوحة الاردوينو باستخدام برنامج اردوينو IDE.

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int buttonPin1=1;
const int buttonPin2=6;
const int buzzer=7;
unsigned long pts=0;
//set buttonstates
bool buttonState1=0;
bool buttonState2=0;
//random number for position of obstacles
int randomNums[6];
//random number for number of obstacles
int randomNum=0;
//random number for position of pts
int randomNums1[3];
//random number for number of pts
int randomNum1=0;
//start delay time, which decreases gradually
unsigned int myDelay=500;
//made this boolean to check if button2 is pressed because if it's pressed once in the first for loop i want obstacles not to be written until the end of it
bool temp=0;
//this variable stores the positions of the warrior while he shoots. there can be 16 positions because the warrior has 16 positions.
int tempI[16];
//i use this boolean to check if the point is catched
bool temp1=0;

//use this variable to store the position of the catched point. it must be and array to store the position of all the points in one iteration of the first for loop. if it stored just one position, then the "old" point would come back in the new iteration
int tempI1[3]; 
//use this variable to have a number of shots of the warrior, which is also the length of an array tempI
int button2IsPressed=0;

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin();
  // set buttonpin mode
  pinMode(buttonPin1,INPUT);
  pinMode(buttonPin2,INPUT);
  pinMode(buzzer,OUTPUT);
  lcd.setCursor(4,0);
  lcd.print("THE GAME");
  lcd.setCursor(2,1);
  lcd.print("STARTS IN ");
  lcd.print("5");
  delay(1000);
  lcd.setCursor(12,1);
  lcd.print("4");
  delay(1000);
  lcd.setCursor(12,1);
  lcd.print("3");
  delay(1000);
  lcd.setCursor(12,1);
  lcd.print("2");
  delay(1000);
  lcd.setCursor(12,1);
  lcd.print("1");
  delay(1000);
  lcd.clear();

}

void loop() {
  here:
 

  randomNum=random(5);
  for(int i=0; i<randomNum; ++i){
  randomNums[i]=random(16);}
   randomNum1=random(3);
  for(int i=0; i<randomNum1; ++i){
  randomNums1[i]=random(16);
  }
  //i reset temp variable before every new for loop because the cycle of the moving warrior starts again
  temp=0;
  for(int j=0; j<3; ++j){
  tempI1[j]=0;
  }
  button2IsPressed=0;
//loop that writes dollar(warrior) on the lcd which jumps everytime button is pressed
    for(int i=0; i<16; ++i){
          
          
          //pts must be written here because of the lcd.clear() below (pts wouldn't be written down the whole time otherwise)
          //i must check if pts is greater than 9 or 99 etc to know how many gaps i should  leave for the number. the more points are collected, the smaller delay time is and the faster is dollar
          if(pts>9 && pts<20) 
          {lcd.setCursor(14,0);
           myDelay=400;
          }
          else if(pts>19 && pts<30) {
            lcd.setCursor(14,0);
            myDelay=300;
          }
          else if(pts>29 && pts<50) 
          {
            myDelay=200;
            lcd.setCursor(14,0);
          }
          
          else if(pts>=50){
            pts=0;
            myDelay=500;
            lcd.clear();
            lcd.setCursor(5,0);
            lcd.print("VICTORY");
            tone(buzzer,262);
            delay(200);
            tone(buzzer,330);
            delay(200);
            tone(buzzer,392);
            delay(100);
            tone(buzzer,330);
            delay(100);
            tone(buzzer,392);
            delay(100);
            tone(buzzer,523);
            delay(200);
            noTone(buzzer);
            delay(3000);
            lcd.clear();
            goto here;
            }
          else lcd.setCursor(15,0);
          lcd.print(pts);
            
         buttonState1=digitalRead(buttonPin1);
         buttonState2=digitalRead(buttonPin2);
 //setting obstacles if the warrior didn't shoot or he shot but he also jumped
 if(!temp){
          for(int j=0; j<randomNum; ++j){
          lcd.setCursor(randomNums[j],1);
          lcd.print("#");
       }
 }
 //checking if the warrior  had shot but there were obstacles before him, we want those obstacles to stay 
 else{
  for(int j=0; j<randomNum; ++j){
 //i check only the tempI[0] position because that's the when the warrior shot for the first time and he removed all the remaining obstacles 
    if(tempI[0]>randomNums[j]){
      lcd.setCursor(randomNums[j],1);
      lcd.print("#");
    
      }

      }
  }        
          

//setting pts
if(!temp1){
          for(int j=0; j<randomNum1; ++j){
          lcd.setCursor(randomNums1[j],0);
          
          lcd.print("*");
           
          }
} 
else{
  for(int j=0; j<randomNum1; ++j){
  
   if(randomNums1[j]!=tempI1[j]){
    lcd.setCursor(randomNums1[j],0);
    lcd.print("*");
    }
  }
  }
           
          
        
          //if the button is pressed we set the cursor up (so that our warrior jumps)
          if(buttonState1==HIGH) 
          {lcd.setCursor(i,0);
          tone(buzzer,131);
          delay(200);
          noTone(buzzer);
          }
          else lcd.setCursor(i,1);
          
          lcd.print("$");
         
          //if button2 is pressed our warrior shoots. i had to put this loop here so that warrior shoots from his current spot and then continues to move. that's why delay time is 5 so that this loop finishes as soon as possible
           if (buttonState2==HIGH) 
         {
          tone(buzzer,175);
         delay(100);
         noTone(buzzer);
         
          temp=1;
          //if the button1 is low then we remove all the obstacles. that's why the state if temp variable is changed
          if(buttonState1==LOW) 
          {
            
            tempI[button2IsPressed]=i;
          }
          ++button2IsPressed;
          for(int k=i+1; k<16; ++k){
          //if the buton1 is low then warrior shoots in the second row. otherwise it shoots in the first row
          if(buttonState1==LOW)
          lcd.setCursor(k,1);
          else lcd.setCursor(k,0);
          lcd.print("~");
          delay(5);
          if(buttonState1==LOW)
          lcd.setCursor(k-1,1);
          else lcd.setCursor(k-1,0);
          lcd.print(" ");
          delay(5);
          
     
          }
         }
         
           delay(myDelay);
          lcd.clear();
           //checking if the positions of the pts and the warrior are the same and if the button is pressed because then they collide and we gain 5 extra points
           for(int j=0; j<randomNum1; ++j){
          if(i==randomNums1[j] && buttonState1==HIGH){
           temp1=1;
           tempI1[j]=i;
           pts+=5;
           }
           }
        
             
      
      
          //checking if the positions of the obstacle and the warrior are the same and if the button1 is not pressed, then they collide and it is the end of the game
          for(int j=0; j<randomNum; ++j){
         if(i==randomNums[j] && buttonState1==LOW && temp==0) {
         
         pts=0;
         myDelay=500;
         lcd.clear();
         lcd.setCursor(6,0);
         lcd.print("GAME");
         lcd.setCursor(6,1);
         lcd.print("OVER");
         tone(buzzer,349);
         delay(200);
         tone(buzzer, 277);
         delay(200);
         tone(buzzer,220);
         delay(100);
         tone(buzzer,277);
         delay(100);
         tone(buzzer,220);
         delay(200);
         noTone(buzzer);
         delay(3000);
         lcd.clear();
         //i must skip the for loop because otherwise the game would continue where it ended
          goto here;
        
         }
         //counting number of skipped obstacles and that would be our points
         else if(i==randomNums[j] && buttonState1==HIGH) ++pts;
          }
       
          
         
      }



}

شرح الكود البرمجي

سنقوم في البداية باستدعاء مكتبة (LiquidCrystal_I2C.h) الخاصة بوحدة i2c والتي تحتوي على مجموعة أوامر برمجية نحتاجها في المشروع.

#include <LiquidCrystal_I2C.h>

نعرف عنوان وحدة i2c.

LiquidCrystal_I2C lcd(0x27, 16, 2);

نعرف المتغيرات الخاصة بالأزرار buttonPin1 تم ربطه بالمنفذ 1 و buttonPin2 تم ربطه بالمنفذ 6 ومصدر الصوت buzzer تم ربطه بالمنفذ 7.

const int buttonPin1=1;
const int buttonPin2=6;
const int buzzer=7;

ستكون الحالة الابتدائية لكل الأزارير =0.

bool buttonState1=0;
bool buttonState2=0;

سيتم اختيار أماكن عشوائية لعلامة المربع على الشاشة الكرستالية.

//random number for position of obstacles
int randomNums[6];
//random number for number of obstacles
int randomNum=0;

وأماكن عشوائية لعلامة النجمة على الشاشة الكرستالية.

//random number for position of pts
int randomNums1[3];
//random number for number of pts
int randomNum1=0;

في الدالة ()setup ستستقبل الأزرار المدخلات والشاشة ومصدر الصوت للمخرجات.

ستحتوي الشاشة الابتدائية للعبة دولار نينجا على كلمة THE GAME ثم سيبدأ العدر التنازلي من 5 إلى 1 بعد ذلك ستبدأ اللعبة مباشرة.

void setup() 
{
  // set up the LCD's number of columns and rows:
  lcd.begin();
  // set buttonpin mode
  pinMode(buttonPin1,INPUT);
  pinMode(buttonPin2,INPUT);
  pinMode(buzzer,OUTPUT);
  lcd.setCursor(4,0);
  lcd.print("THE GAME");
  lcd.setCursor(2,1);
  lcd.print("STARTS IN ");
  lcd.print("5");
  delay(1000);
  lcd.setCursor(12,1);
  lcd.print("4");
  delay(1000);
  lcd.setCursor(12,1);
  lcd.print("3");
  delay(1000);
  lcd.setCursor(12,1);
  lcd.print("2");
  delay(1000);
  lcd.setCursor(12,1);
  lcd.print("1");
  delay(1000);
  lcd.clear();

}

في الدالة ()loop ستبدأ النجوم وعلامة المربع بالظهور بأماكن عشوائية متفرقة.

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

إذا لم يستطع الهروب وحدث تلامس بينه وبين علامة المربع ستنتهي اللعبة بخسارة اللاعب دولار وستظهر رسالة The game over.

void loop() 
{
  here:


  randomNum=random(5);
  for(int i=0; i<randomNum; ++i){
  randomNums[i]=random(16);}
   randomNum1=random(3);
  for(int i=0; i<randomNum1; ++i){
  randomNums1[i]=random(16);
  }
  //i reset temp variable before every new for loop because the cycle of the moving warrior starts again
  temp=0;
  for(int j=0; j<3; ++j){
  tempI1[j]=0;
  }
  button2IsPressed=0;
//loop that writes dollar(warrior) on the lcd which jumps everytime button is pressed
    for(int i=0; i<16; ++i){
          
          
          //pts must be written here because of the lcd.clear() below (pts wouldn't be written down the whole time otherwise)
          //i must check if pts is greater than 9 or 99 etc to know how many gaps i should  leave for the number. the more points are collected, the smaller delay time is and the faster is dollar
          if(pts>9 && pts<20) 
          {lcd.setCursor(14,0);
           myDelay=400;
          }
          else if(pts>19 && pts<30) {
            lcd.setCursor(14,0);
            myDelay=300;
          }
          else if(pts>29 && pts<50) 
          {
            myDelay=200;
            lcd.setCursor(14,0);
          }
          
          else if(pts>=50){
            pts=0;
            myDelay=500;
            lcd.clear();
            lcd.setCursor(5,0);
            lcd.print("VICTORY");
            tone(buzzer,262);
            delay(200);
            tone(buzzer,330);
            delay(200);
            tone(buzzer,392);
            delay(100);
            tone(buzzer,330);
            delay(100);
            tone(buzzer,392);
            delay(100);
            tone(buzzer,523);
            delay(200);
            noTone(buzzer);
            delay(3000);
            lcd.clear();
            goto here;
            }
          else lcd.setCursor(15,0);
          lcd.print(pts);
            
         buttonState1=digitalRead(buttonPin1);
         buttonState2=digitalRead(buttonPin2);
 //setting obstacles if the warrior didn't shoot or he shot but he also jumped
 if(!temp){
          for(int j=0; j<randomNum; ++j){
          lcd.setCursor(randomNums[j],1);
          lcd.print("#");
       }
 }
 //checking if the warrior  had shot but there were obstacles before him, we want those obstacles to stay 
 else{
  for(int j=0; j<randomNum; ++j){
 //i check only the tempI[0] position because that's the when the warrior shot for the first time and he removed all the remaining obstacles 
    if(tempI[0]>randomNums[j]){
      lcd.setCursor(randomNums[j],1);
      lcd.print("#");
    
      }

      }
  }        
          

//setting pts
if(!temp1){
          for(int j=0; j<randomNum1; ++j){
          lcd.setCursor(randomNums1[j],0);
          
          lcd.print("*");
           
          }
} 
else{
  for(int j=0; j<randomNum1; ++j){
  
   if(randomNums1[j]!=tempI1[j]){
    lcd.setCursor(randomNums1[j],0);
    lcd.print("*");
    }
  }
  }
           
          
        
          //if the button is pressed we set the cursor up (so that our warrior jumps)
          if(buttonState1==HIGH) 
          {lcd.setCursor(i,0);
          tone(buzzer,131);
          delay(200);
          noTone(buzzer);
          }
          else lcd.setCursor(i,1);
          
          lcd.print("$");
         
          //if button2 is pressed our warrior shoots. i had to put this loop here so that warrior shoots from his current spot and then continues to move. that's why delay time is 5 so that this loop finishes as soon as possible
           if (buttonState2==HIGH) 
         {
          tone(buzzer,175);
         delay(100);
         noTone(buzzer);
         
          temp=1;
          //if the button1 is low then we remove all the obstacles. that's why the state if temp variable is changed
          if(buttonState1==LOW) 
          {
            
            tempI[button2IsPressed]=i;
          }
          ++button2IsPressed;
          for(int k=i+1; k<16; ++k){
          //if the buton1 is low then warrior shoots in the second row. otherwise it shoots in the first row
          if(buttonState1==LOW)
          lcd.setCursor(k,1);
          else lcd.setCursor(k,0);
          lcd.print("~");
          delay(5);
          if(buttonState1==LOW)
          lcd.setCursor(k-1,1);
          else lcd.setCursor(k-1,0);
          lcd.print(" ");
          delay(5);
          
     
          }
         }
         
           delay(myDelay);
          lcd.clear();
           //checking if the positions of the pts and the warrior are the same and if the button is pressed because then they collide and we gain 5 extra points
           for(int j=0; j<randomNum1; ++j){
          if(i==randomNums1[j] && buttonState1==HIGH){
           temp1=1;
           tempI1[j]=i;
           pts+=5;
           }
           }
        
             
      
      
          //checking if the positions of the obstacle and the warrior are the same and if the button1 is not pressed, then they collide and it is the end of the game
          for(int j=0; j<randomNum; ++j){
         if(i==randomNums[j] && buttonState1==LOW && temp==0) {
         
         pts=0;
         myDelay=500;
         lcd.clear();
         lcd.setCursor(6,0);
         lcd.print("GAME");
         lcd.setCursor(6,1);
         lcd.print("OVER");
         tone(buzzer,349);
         delay(200);
         tone(buzzer, 277);
         delay(200);
         tone(buzzer,220);
         delay(100);
         tone(buzzer,277);
         delay(100);
         tone(buzzer,220);
         delay(200);
         noTone(buzzer);
         delay(3000);
         lcd.clear();
         //i must skip the for loop because otherwise the game would continue where it ended
          goto here;
        
         }
         //counting number of skipped obstacles and that would be our points
         else if(i==randomNums[j] && buttonState1==HIGH) ++pts;
          }
       
          
         
      }



}

بعد اكتمال عملية الرفع يمكنك بدء جو المتعة والتحدي مع دولار النينجا.

اختبر صحة خطواتك.

 لا تنسَ فصل مصدر الطاقة بعد الانتهاء من استخدام النظام.

 




تنصيب برنامج Arduino IDE على الراسبيري باي

مقدمة

في هذا الدرس ستتعلم كيفية تنصيب برنامج اردوينو IDE على الراسبيري باي  من خلاله يمكنك برمجة لوحة الاردوينو.

برمجة الاردوينو

المواد والأدوات

برمجة الاردوينو

 1× راسبيري باي

برمجة الاردوينو

 1× سلك (HDMI)

برمجة الاردوينو

1× سلك ايثرنت

برمجة الاردوينو

1× محول تيار (5V-2A)

برمجة الاردوينو

 1× كرت ذاكرة

program-your-arduino-from-your-raspberry-pi

 1× ثنائي مشع للضوء

program-your-arduino-from-your-raspberry-pi

 1× اردوينو اونو

program-your-arduino-from-your-raspberry-pi

1× سلك اردوينو

توصيل القطع

1- الراسبيري باي

وصّل سلك الاردوينو في منفذ USB للراسبيري باي كما في الشكل.
برمج لوحة الاردوينو

2- الاردوينو

برمج لوحة الاردوينو

تهيئة الراسبيري باي

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

وبعد تثبيت النظام، يمكنك تهيئة النظام من خلال الرجوع  للدرس الثاني تهيئة نظام التشغيل

افتح الشاشة السوداء LXterminal للبدء باستخدام الراسبيري باي.

قارئ النصوص

للبدء، قم بإستخدام الـ Termial لتحديث الراسبيري باي إلى أحدث إصدار.

sudo apt-get update
sudo apt-get upgrade

ثم أعد تشغيل الراسبيري باي.

reboot

سنبدأ بتنصيب برنامج اردوينو IDE.

افتح المتصفح.

اكتب بخانة البحث Arduino IDE وادخل على الموقع الرسمي.

برمج لوحة الاردوينو

حمّل النسخة Linux ARM 32 Bits.

اضغط على Just download ستبدأ عملية التنصيب مباشرة.

برمج لوحة الاردوينو

بعد اكتمال عملية التنصيب سنبدأ باستخراج الملف المضغوط.

انقر على أيقونة الراسبيان في أعلى يسار الصفحة من القائمة اخر Accessories ثم اختر Archiver.program-your-arduino-from-your-raspberry-pi

انقر على Archive ثم Open اختر الملف المضغوط الذي قمت بتنصيبه arduino-1.8.19-linuxarm.tar.xy.

انتظر حتى تتوقف الدائرة الحمراء الموجودة أسفل يمين الصفحة عن الوميض ويصبح لونها أخضر.
program-your-arduino-from-your-raspberry-pi

انقر على Action ثم Extract واختر الملف الذي قمت بفك الضغط عنه وانقر على Extract انتظر حتى تتوقف الدائرة الحمراء عن الوميض وتصبح خضراء.

program-your-arduino-from-your-raspberry-pi

افتح Terminal واكتب الأوامر التالية:

cd Downloads 
ls 
cd arduino-1.8.9
sudo ./install.sh

اذهب إل علامة الراسبيان أعلى يسار الشاشة من القائمة اختر Programming ستلاحظ وجود Arduino IDE انقر عليه سيبدأ بالعمل مباشرة.program-your-arduino-from-your-raspberry-pi

حدد منفذ الاردوينو اونو.

برمجة الاردوينو


برمجة الاردوينو

ارفع الكود البرمجي التالي للوحة الاردوينو.

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);//turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);//turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

اختبر خطواتك.

 لا تنسَ فصل مصدر الطاقة بعد الانتهاء من استخدام النظام.




التحكم بالشاشة الكرستالية باستخدام الاردوينو ووحدة البلوتوث

مقدمة

وسائل التحكم عن بُعد هي أجهزة إلكترونية يكون التحكم فيها يدويًا للتحكم في جهاز آخر، وذلك عبر إشارات مثل الأشعة تحت الحمراء أو إشارات الراديو اللاسلكية أو البلوتوث، في هذا الدرس سنتعلم كيفية التحكم بالشاشة الكرستالية عن بعد باستخدام الاردوينو ووحدة البلوتوث.

arduino-bluetooth-remote-lcd-display

المواد والأدوات

التحكم بالشاشة الكرستالية

1× اردوينو اونو

التحكم بالشاشة الكرستالية

1× سلك الاردوينو

التحكم بالشاشة الكرستالية

 1× شاشة كرستالية

التحكم بالشاشة الكرستالية

 حزمة أسلاك توصيل (ذكر- ذكر)

arduino-bluetooth-remote-lcd-display

حزمة أسلاك توصيل (ذكر – أنثى)

arduino-bluetooth-remote-lcd-display

1× 2C / IIC Serial Interface Module

arduino-bluetooth-remote-lcd-display

1× لوحة تجارب حجم صغير

دولار نينجا

40 رأس دبوس

arduino-bluetooth-remote-lcd-display

1× هاتف بنظام اندرويد

توصيل الدائرة

لمعرفة المزيد حول الشاشة الكرستالية يمكنك الرجوع للدرس التحكم بالشاشة الكرستالية LCD.

للمزيد حول وحدة البلوتوث يمكنك الرجوع للدرس التالي نظام التحكم في الإضاءة عبر البلوتوث.arduino-bluetooth-remote-lcd-display

البرمجة

قبل رفع الكود البرمجي للوحة الاردوينو افصل السلكان Tx و Rx وبعد رفع الكود أعد الأسلاك كما كانت.

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
String inData;
void setup() 
{
Serial.begin(9600);
lcd.begin();
lcd.clear();
}

void loop()
{
int i=0;
char commandbuffer[150];
if(Serial.available()){
delay(3000);
while( Serial.available() && i< 150) {
commandbuffer[i++] = Serial.read();
}
commandbuffer[i++]='\0';
}
if(i>0)
Serial.println((char*)commandbuffer);
lcd.print((char*)commandbuffer);
delay(4000);
lcd.clear();
}

شرح الكود البرمجي

سنقوم في البداية باستدعاء مكتبة (LiquidCrystal_I2C.h) الخاصة بوحدة i2c والتي تحتوي على مجموعة أوامر برمجية نحتاجها في المشروع.

ثم نضيفها للاردوينو IDE.

بتتبع المسار التالي:

Sketch > Include libraries > Add ZIP library 

ونضيف المجلد الذي قمنا بتحميله.

#include <LiquidCrystal_I2C.h>

نعرف عنوان وحدة i2c.

LiquidCrystal_I2C lcd(0x27, 16, 2);

في المتغير inData سيتم تخزين البيانات المقروءة من كلمات وجمل .

String inData;

في الدالة ()setup سيتم تهيئة الشاشة الكرستالية استعدادًا لطباعة الجمل والكلمات عليها.

void setup() 
{
Serial.begin(9600);
lcd.begin();
lcd.clear();
}

في الدالة ()loop سيتم قراءة البيانات من وحدة البلوتوث وسيتم طباعتها على الشاشة الكرستالية.

void loop()
{
int i=0;
char commandbuffer[150];
if(Serial.available()){
delay(3000);
while( Serial.available() && i< 150) {
commandbuffer[i++] = Serial.read();
}
commandbuffer[i++]='\0';
}
if(i>0)
Serial.println((char*)commandbuffer);
lcd.print((char*)commandbuffer);
delay(4000);
lcd.clear();
}

برنامج BlueTerm

حمّل برنامج BlueTerm المجاني على جهازك المحمول من متجر GooglePlay.

بعد التحميل افتح التطبيق ستكون الواجهة بهذا الشكل.

arduino-bluetooth-remote-lcd-display

انقر الزر اليمين من الهاتف المحمول ستظهر هذه الخيارات اختر Connect device.

arduino-bluetooth-remote-lcd-display

اختر نوع وحدة البلوتوث المستخدمة في هذا الدرس استخدمنا HC-06.التحكم بالشاشة الكرستالية

بعد اكتمال عملية الربط يمكن الآن التحكم بالشاشة الكرستالية عن طريق الاردوينو ووحدة البلوتوث.

اختبر صحة خطواتك.

 لا تنسَ فصل مصدر الطاقة بعد الانتهاء من استخدام النظام.




اصنع منبه رسائل البريد الإلكتروني باستخدام الاردوينو

مقدمة

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

منبه رسائل البريد الإلكتروني

المواد والأدوات

arduino-unread-gmail-email-notifier

1× اردوينو اونو

منبه رسائل البريد الإلكتروني

1× سلك الاردوينو

 

منبه رسائل البريد الإلكتروني

حزمة أسلاك توصيل (ذكر – أنثى)

arduino-unread-gmail-email-notifier

 1× ثنائي مشع للضوء أحمر (LED)

منبه رسائل البريد الإلكتروني

 شاشة كرستالية

منبه رسائل البريد الإلكتروني

I2C / IIC Serial Interface Module

شفرة

1× 40 رأس دبوس

توصيل الدائرة

للمزيد حول الشاشة الكرستالية يمكنك الرجوع للدرس التحكم بالشاشة الكرستالية LCD.

وصَل دائرة منبه رسائل البريد الإلكتروني كما في الشكل: 
 منبه رسائل البريد الإلكتروني

تفعيل IMAP

 افتح المتصفح الخاص بك وسجّل دخول على حسابك في Gmail.

أعلى يمين الصفحة انقر على العلامة الظاهرة بالصورة.

The Settings gear in Gmail

اختر See all settings.

The "See All Settings" button in Gmail

اختر أيقونة Forwarding and POP/IMAP.

Gmail settings with the Forwarding and POP/IMAP tab highlighted

في قسم IMAP access, اختر Enable IMAP.

وفي قسم POP download اختر Enable POP for all email.

The Enable IMAP option

احفظ التغييرات الجديدة.

كود اردوينو IDE

ارفع الكود البرمجي التالي على لوحة الاردوينو باستخدام برنامج اردوينو IDE.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);

int val = 0; 
byte led = 13;

void setup(){
Serial.begin(9600); 
pinMode(led, OUTPUT); 
lcd.begin(); 
lcd.backlight(); 
}

void loop()
{
if(Serial.available()) 
if (val = Serial.read() - '0')
{
lcd.setCursor(1, 0); 
lcd.print("You've messages"); 
digitalWrite(led, val);
}
else
{
lcd.setCursor(1, 0); 
lcd.print("No new messages"); 
digitalWrite(led, val);
}
}

شرح الكود البرمجي

في البداية سنقوم بكتابة المكتبات الضرورية في مشروع صناعة منبه رسائل البريد الإلكتروني مثل <Wire.h> و <LiquidCrystal_I2C.h>.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

في هذه الأسطر سيتم تهيئة المتغير val الذي سيحمل معلومات عن رسائل البريد الإلكتروني والمتغير led تم ربطه مع لوحة الاردوينو بالمنفذ 13.

int val = 0; 
byte led = 13;

في الدالة ()setup سيتم تهيئة الشاشة الكرستالية والثنائي المشع للضوء.

void setup()
{
Serial.begin(9600); 
pinMode(led, OUTPUT); 
lcd.begin(); 
lcd.backlight(); 
}

في الدالة ()loop سيتم تحديث البريد الإلكتروني بشكل مستمر للبحث عن رسائل جديدة.

إذا كان هناك رسائل جديدة سيعمل الثنائي المشع للضوء وسينطبع على الشاشة رسالة You’ve messages.

وإذا لم يكن هناك رسائل سينطفئ الثنائي المشع للضوء وسنطبع على الشاشة No new messages.

void loop()
{
if(Serial.available()) 
if (val = Serial.read() - '0')
{
lcd.setCursor(1, 0); 
lcd.print("You've messages"); 
digitalWrite(led, val);
}
else
{
lcd.setCursor(1, 0); 
lcd.print("No new messages"); 
digitalWrite(led, val);
}
}

 كود البايثون

في البداية عليك تنصب برنامج Python 2.7 يمكنك الرجوع للدرس التالي لمعرفة كيفية تنصيبه تنصيب Python 2.7.

انقر بالسهم اليمين على Command Prompt واختر من القائمة Run as administrator.

arduino-unread-gmail-email-notifier

ادخل على مسار برنامج البايثون.

(هذا السطر قابل للتغيير بناء على موقع برنامج البايثون في جهازك)

cd C:\python27

حدّث Pip من خلال كتابة الأمر التالي.

pip install --upgrade pip

حمّل مكتبة pyserial.

pip install pyserial

افتح برنامج IDLE (Python) من قائمة File اختر New File التالي.

منبه رسائل البريد الإلكتروني

اكتب الكود البرمجي لكن عليك قراءة شرح الكود البرمجي قبل رفعه للوحة الاردوينو.

import imaplib, serial #import modules

ser = serial.Serial('COM3', 9600) #create serial object, enter in the proper port 
obj = imaplib.IMAP4_SSL('imap.gmail.com') #create imap object, set to gmail
obj.login('Your Email', 'Password') #enter in gmail credentials

#runs continuously 
while 1: 
obj.select() #refresh 
val = len(obj.search(None, 'UnSeen')[1][0].split()) #generate a value of 1 or 0
#print "The val is: %s\n" % val #print value to monitor
ser.write(str(val)) #write value to serial port

شرح الكود البرمجي

في البداية سيتم استدعاء المكتبات الضرورية مثل imaplib و serial.

import imaplib, serial #import modules

عليك تحرير هذا السطر وكتابة المنفذ المستخدم هنا تم استعمال المنفذ COM3.

ser = serial.Serial('COM3', 9600) #create serial object, enter in the proper port 

ادخل البريد الإلكتروني الخاص بك هنا Your Email  وكلمة السر هنا Password.

obj.login('Your Email', 'Password') #enter in gmail credentials

هنا سيتم قراءة حالة البريد الإلكتروني بشكل مستمر في حال وصول رسالة جديدة سيعمل منبه رسائل البريد الإلكتروني مباشرة.

while 1: 
obj.select() #refresh 
val = len(obj.search(None, 'UnSeen')[1][0].split()) #generate a value of 1 or 0
#print "The val is: %s\n" % val #print value to monitor
ser.write(str(val)) #write value to serial port

 ارفع الكود البرمجي على لوحة الاردوينو من قائمة Run انقر على Run module.

يمكنك اختبار منبه رسائل البريد الإلكتروني بعد رفع الكود البرمجي.

 لا تنسَ فصل مصدر الطاقة بعد الانتهاء من استخدام النظام.




التحكم بالحاسوب باستخدام الاردوينو والهاتف الذكي

مقدمة

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

المواد والأدوات

smartphone-controlled-mouse

1× اردوينو اونو

smartphone-controlled-mouse

1× سلك الاردوينو

التحكم بالحاسوب عن بعد

موديول بلوتوث من النوع HC-06

التحكم بالحاسوب

حزمة أسلاك توصيل (ذكر – أنثى)

التحكم بالحاسوب

1× هاتف بنظام اندرويد

توصيل الدائرة

للمزيد حول وحدة البلوتوث يمكنك الرجوع للدرس التالي نظام التحكم في الإضاءة عبر البلوتوث.

التحكم بالحاسوب

كود اردوينو IDE

قبل رفع الكود البرمجي للوحة الاردوينو عد للدائرة الكهربائية وافصل السلكين المربوطين بالمنافذ A4 و A5.

بعد ذلك ارفع الكود البرمجي للوحة الاردوينو وبعد اكتمال عملية الرفع أعد الأسلاك كما كانت.

int datareceived[5] {0,0,0,0};          // To store byte from phone
int in_byte = 0;
int array_index = 0;
int l_prev=0,r_prev=0; // previous status of mouse left and right click 
void setup() {
Serial.begin (9600); // starts the serial monitor
}
 int height=0,width=0;
void loop() {
  int clicks=0;
  int sensitivity=20;       // you can adjust the sensitivity
  int xpos=0,ypos=0;
if (Serial.available() > 0) {  //recieve byte from phone
  in_byte= Serial.read(); //store in byte into a variable
  if (in_byte == (255)) { // if the variable is 0 stet the array inxed to 0.
    array_index = 0;
  }
  datareceived[array_index] = in_byte;  //store number into array
  array_index = array_index +1;
  
if(datareceived[1]>=110)
xpos=map(datareceived[1],110,172,0,sensitivity);       // When moved right
if(datareceived[1]<=70)
xpos=map(datareceived[1],60,1,0,-sensitivity);        // When moved left
if(datareceived[2]>=110)
ypos=map(datareceived[2],110,255,0,sensitivity);     // When moved down
if(datareceived[2]<=60)
ypos=map(datareceived[2],70,1,0,-sensitivity);       // When moved up


if(datareceived[3]==1 && l_prev==0)      // TO recognise a single button press
  clicks=1;
else if(datareceived[3]==2 && r_prev==0)
clicks=2;
else if(datareceived[3]==3 || datareceived[3]==4)
clicks=datareceived[3];  //  scroll

l_prev=datareceived[3];
r_prev=datareceived[3];

if(xpos!=0 or ypos!=0 or clicks!=0)       // when either of the joystick is moved or the button is pressed or scrolled
{
height=height+ypos;
width=width+xpos;
if(height>=799)
height=799;
if(height<=0)
height=0;
if(width>=1279)
width=1279;
if(width<=0)
width=0;
Serial.print(width);
Serial.print(":");
Serial.print(height);
Serial.print(":");
Serial.println(clicks);
clicks=0;
}
}
}

شرح الكود البرمجي

في المصفوفة datareceived ستخزن البيانات التي ستتم قراءتها من الهاتف الذكي وستكون قيمتها الابتدائية=0.

int datareceived[5] {0,0,0,0};          // To store byte from phone

في المتغيرين l_prev و r_prev=0 سيتم تخزين القيم الابتدائية لحالة الحركة ليمين ويسار الحاسوب =0.

int l_prev=0,r_prev=0; // previous status of mouse left and right click 

في دالة ()void loop:

المتغير sensitivity=20 يمثل حساسية الحركة والانتقال من مكان لآخر يمكنك تغيير القيمة.

 متغير xpos يشير إلى موقع السهم على محور x في شاشة الكمبيوتر وقيمته الابتدائية = 0.

متغير ypos يشير إلى موقع السهم على محور y في شاشة الكمبيوتر وقيمته الابتدائية = 0.

 int sensitivity=20;       // you can adjust the sensitivity
 int xpos=0,ypos=0;

في المصفوفة datareceived سيتم تخزين القيم المقروءة من الهاتف الذكي وتحديثها بشكل مستمر.

  datareceived[array_index] = in_byte;  //store number into array

بعد قراءة البيانات من الهاتف الذكي سيتم تحديد وجهة الحركة للسهم.

إذا كانت القيم المقروءة >=110 ستكون حركة السهم لليمين.

إذا كانت القيم المقروءة <=70 ستكون حركة السهم لليسار.

إذا كانت القيم المقروءة >=110 ستكون حركة السهم للأسفل. 

إذا كانت القيم المقروءة <=60 ستكون حركة السهم للأعلى.

if(datareceived[1]>=110)
xpos=map(datareceived[1],110,172,0,sensitivity);       // When moved right
if(datareceived[1]<=70)
xpos=map(datareceived[1],60,1,0,-sensitivity);        // When moved left
if(datareceived[2]>=110)
ypos=map(datareceived[2],110,255,0,sensitivity);     // When moved down
if(datareceived[2]<=60)
ypos=map(datareceived[2],70,1,0,-sensitivity);       // When moved up

هنا سيتم تحديد النقر هل هو لزر اليسار أو لزر اليمين.

if(datareceived[3]==1 && l_prev==0)      // TO recognise a single button press
  clicks=1;
else if(datareceived[3]==2 && r_prev==0)
clicks=2;
else if(datareceived[3]==3 || datareceived[3]==4)

هنا سيتم تحديد مكان الانتقال إما لأعلى أو أسفل الصفحة.

clicks=datareceived[3];  //  scroll

برنامج MIT App Inventor

حمّل تصميم واجهة المستخدم والكود البرمجي من هنا.

من المتصفح افتح موقع MIT App Inventor.

أنشئ حساب على الموقع ثم انقر علي Create Apps.

التحكم بالحاسوب عن بعد

من قائمة Project اختر Import projects (.aia) from my computer ثم انقر على الملف الذي حملته مسبقًا ويحتوي على واجهة المستخدم والكود البرمجي.

التحكم بالحاسوب عن بعد

من قائمة Connect اختر Al companion

التحكم بالحاسوب عن بعد

سيظهر كود ورمز مكون من 6 حروف.

حمّل تطبيق MIT App Inventor على جهازك الذكي.

يمكنك ادخال الرمز في المستطيل أو النقر على scan QR code ومسح الكود السابق.

ثم انقر على connect with code.
التحكم بالحاسوب عن بعد

ستظهر هذه الواجهة انقر على Bluetooth Connect.smartphone-controlled-mouse

اختر نوع وحدة البلوتوث من القائمة النوع المستخدم في هذا الدرس HC-06.التحكم بالحاسوب عن بعد

ستظهر كلمة Connected في حال اكتمال عملية الاتصال.

شرح لطريقة استعمال الواجهة.

التحكم بالحاسوب عن بعد

كود البايثون

في البداية عليك تنصب برنامج Python 3 يمكنك الرجوع للدرس التالي لمعرفة كيفية تنصيبه تنصيب Python 3.

انقر بالسهم اليمين على Command Prompt واختر من القائمة Run as administrator.

التحكم بالحاسوب عن بعد

ادخل على مسار برنامج البايثون.

(هذا السطر قابل للتغيير بناء على موقع برنامج البايثون في جهازك)

cd C:\Program Files (x86)\Python39-32

حدّث Pip من خلال كتابة الأمر التالي.

python -m pip install --upgrade pip

حمّل مكتبة فأرة الحاسوب.

python –m pip install mouse

حمّل مكتبة pyserial.

python -m pip install pyserial

افتح برنامج IDLE (Python 3.9 32-bit) من قائمة File اختر New File التالي.

smartphone-controlled-mouse

الصق الكود البرمجي وارفعه للوحة الاردوينو من قائمة Run انقر على Run module.

import mouse, sys
import time 
import serial

mouse.FAILSAFE=False
ArduinoSerial=serial.Serial('com3',9600)  #Specify the correct COM port
time.sleep(1)                             #delay of 1 second

while 1:
   data=str(ArduinoSerial.readline().decode('ascii'))
   (x,y,z)=data.split(":")  # read the x and y axis data
   (x,y)=(int(x),int(y))   # convert to int
   mouse.move(x,y)         # move the cursor to desired coordinates
   if '1' in z:                       
      mouse.click(button="left")     #clicks mouse button
   elif '2' in z:
      mouse.click(button="right")
   elif '3' in z:
      mouse.wheel(delta=-1)       # Scroll down
   elif '4' in z:
      mouse.wheel(delta=1)       # Scroll up
  

شرح الكود البرمجي

افتح صفحة جديدة في IDLE Python وقم باستدعاء المكتبات المطلوبة mouse, sys serial python و time.

import mouse, sys
import time 
import serial

حدد المنفذ COM المستخدم في الاتصال مع الاردوينو، لديك وقم بتعديل الأمر في السطر التالي حسب رقم المنفذ.

(يمكنك تعيينه عن طريق برنامج اردوينو IDE من قائمة Port).

ArduinoSerial=serial.Serial('com3',9600)  #Specify the correct COM port

هنا تتم قراءة القيم من المنافذ التناظرية A0 و A1 وسيتم تحريك السهم في أماكن مختلفة على الشاشة بناء على هذه القيم.

while 1:
   data=str(ArduinoSerial.readline().decode('ascii'))
   (x,y,z)=data.split(":")  # read the x and y axis data
   (x,y)=(int(x),int(y))   # convert to int
   mouse.move(x,y)         # move the cursor to desired coordinates

بناء على القراءات سيتم تحديد حركة السهم إما للأعلى أو للأسفل أو لليمين أو لليسار.

   if '1' in z:                       
      mouse.click(button="left")     #clicks mouse button
   elif '2' in z:
      mouse.click(button="right")
   elif '3' in z:
      mouse.wheel(delta=-1)       # Scroll down
   elif '4' in z:
      mouse.wheel(delta=1)       # Scroll up

يمكنك التحكم بالحاسوب عن بعد باستخدام الاردوينو وهاتفك الذكي بعد رفع الكود البرمجي.

اختبر صحة خطواتك.

 لا تنسَ فصل مصدر الطاقة بعد الانتهاء من استخدام النظام.




لعبة X/O باستخدام الاردوينو والشاشة الكرستالية

مقدمة

تستخدم الشاشة في تطبيقات مختلفة في حياتنا اليومية لعرض البيانات والاحصائيات وعرض الصور والفيديوهات المصورة، ستتعلم في هذا الدرس كيف تبرمج لعبة X/O باستخدام الاردوينو والشاشة الكرستالية مقاس 2.8 انش.

لعبة X/O

المواد والأدوات

arduino-game-x-o-on-the-tft-display

1× اردوينو اونو

arduino-game-x-o-on-the-tft-display

1× سلك الاردوينو

لعبة X/O

شاشة كرستالية “2.8

توصيل الدائرة

قم بتثبيت الشاشة الكرستالية كما هو ظاهر بالصور عليك الانتباه للمنافذ يجب توصيلها في مكانها  الصحيح على لوحة الاردوينو.لعبة X/O

لعبة X/O

الكود البرمجي

قبل رفع الكود البرمجي للوحة الاردوينو عليك تحميل المكتبات الضرورية للمشروع.

من خلال الرابط التالي:

أولا مكتبة Touchscreen 

ثانيا مكتبة Elegoo_GFX

ثالثا مكتبة Elegoo_TFTLCD

#include <TouchScreen.h>
#include <Elegoo_GFX.h>
#include <Elegoo_TFTLCD.h>
#include <avr/pgmspace.h>

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4


#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

#define YP A2
#define XM A3
#define YM 8
#define XP 9

TouchScreen ts = TouchScreen(XP, YP, XM, YM, 400);
Elegoo_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

const unsigned char x_bitmap[]PROGMEM={
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x3,0xff,0xff,0xc0,0x1,0xff,0xff,0xe0,0x0,
0x1,0xff,0xff,0xe0,0x1,0xff,0xff,0xc0,0x0,
0x1,0xff,0xff,0xf0,0x3,0xff,0xff,0xc0,0x0,
0x0,0xff,0xff,0xf0,0x7,0xff,0xff,0x80,0x0,
0x0,0xff,0xff,0xf8,0x7,0xff,0xff,0x80,0x0,
0x0,0x7f,0xff,0xf8,0xf,0xff,0xff,0x0,0x0,
0x0,0x3f,0xff,0xfc,0xf,0xff,0xfe,0x0,0x0,
0x0,0x3f,0xff,0xfe,0x1f,0xff,0xfe,0x0,0x0,
0x0,0x1f,0xff,0xfe,0x1f,0xff,0xfc,0x0,0x0,
0x0,0x1f,0xff,0xff,0x3f,0xff,0xfc,0x0,0x0,
0x0,0xf,0xff,0xff,0x7f,0xff,0xf8,0x0,0x0,
0x0,0xf,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,
0x0,0x7,0xff,0xff,0xff,0xff,0xf0,0x0,0x0,
0x0,0x3,0xff,0xff,0xff,0xff,0xe0,0x0,0x0,
0x0,0x3,0xff,0xff,0xff,0xff,0xe0,0x0,0x0,
0x0,0x1,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,
0x0,0x1,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,
0x0,0x0,0xff,0xff,0xff,0xff,0x80,0x0,0x0,
0x0,0x0,0xff,0xff,0xff,0xff,0x80,0x0,0x0,
0x0,0x0,0x7f,0xff,0xff,0xff,0x0,0x0,0x0,
0x0,0x0,0x3f,0xff,0xff,0xfe,0x0,0x0,0x0,
0x0,0x0,0x3f,0xff,0xff,0xfe,0x0,0x0,0x0,
0x0,0x0,0x1f,0xff,0xff,0xfc,0x0,0x0,0x0,
0x0,0x0,0x1f,0xff,0xff,0xfc,0x0,0x0,0x0,
0x0,0x0,0x1f,0xff,0xff,0xfc,0x0,0x0,0x0,
0x0,0x0,0x3f,0xff,0xff,0xfe,0x0,0x0,0x0,
0x0,0x0,0x3f,0xff,0xff,0xfe,0x0,0x0,0x0,
0x0,0x0,0x7f,0xff,0xff,0xff,0x0,0x0,0x0,
0x0,0x0,0xff,0xff,0xff,0xff,0x80,0x0,0x0,
0x0,0x0,0xff,0xff,0xff,0xff,0x80,0x0,0x0,
0x0,0x1,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,
0x0,0x1,0xff,0xff,0xff,0xff,0xc0,0x0,0x0,
0x0,0x3,0xff,0xff,0xff,0xff,0xe0,0x0,0x0,
0x0,0x3,0xff,0xff,0xff,0xff,0xe0,0x0,0x0,
0x0,0x7,0xff,0xff,0xff,0xff,0xf0,0x0,0x0,
0x0,0xf,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,
0x0,0xf,0xff,0xff,0xff,0xff,0xf8,0x0,0x0,
0x0,0x1f,0xff,0xff,0x7f,0xff,0xfc,0x0,0x0,
0x0,0x1f,0xff,0xfe,0x3f,0xff,0xfc,0x0,0x0,
0x0,0x3f,0xff,0xfc,0x3f,0xff,0xfe,0x0,0x0,
0x0,0x3f,0xff,0xfc,0x1f,0xff,0xfe,0x0,0x0,
0x0,0x7f,0xff,0xf8,0x1f,0xff,0xff,0x0,0x0,
0x0,0xff,0xff,0xf8,0xf,0xff,0xff,0x80,0x0,
0x0,0xff,0xff,0xf0,0x7,0xff,0xff,0x80,0x0,
0x1,0xff,0xff,0xe0,0x7,0xff,0xff,0xc0,0x0,
0x1,0xff,0xff,0xe0,0x3,0xff,0xff,0xc0,0x0,
0x3,0xff,0xff,0xc0,0x3,0xff,0xff,0xe0,0x0,
0x3,0xff,0xff,0xc0,0x1,0xff,0xff,0xe0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0
};
//x = 0 :blue
//x = 1 :red
int x = 0;
int rturn = 0;


int a;
int ab;
int b;
int bb;
int c;
int cb;
int d;
int db;
int e;
int eb;
int f;
int fb;
int g;
int gb;
int h;
int hb;
int i;
int ib;

void setup() {
tft.reset();
tft.begin(0x9341);
tft.fillScreen(BLACK);
tft.setRotation(1);
Serial.begin(9600);
tft.setCursor(60, 110);
tft.setTextColor(RED);
tft.setTextSize(3);
tft.println("X-O Game");
delay(2000);
tft.setCursor(5, 178);
tft.setTextColor(GREEN);
tft.setTextSize(1);
tft.println("In this game, there are two players : Player O");
tft.setCursor(5, 187);
tft.println("and Player X. Each turn, they can put pads on a");
tft.setCursor(5, 196);
tft.println("grid. You win once three of your pads are aligned.");

delay(1000);
tft.fillScreen(BLACK);
tft.drawLine(113, 10, 113, 230, WHITE);
tft.drawLine(208, 10, 208, 230, WHITE);
tft.drawLine(30, 80, 290, 80, WHITE);
tft.drawLine(30, 160, 290, 160, WHITE);
pinMode(13, OUTPUT);
}

void loop()
{
returning:

if(rturn==1){
tft.fillScreen(BLACK);
tft.drawLine(113, 10, 113, 230, WHITE);
tft.drawLine(208, 10, 208, 230, WHITE);
tft.drawLine(30, 80, 290, 80, WHITE);
tft.drawLine(30, 160, 290, 160, WHITE);
rturn = 0;
x = 0;
a = 0;
ab = 0;
b = 0;
bb = 0;
c = 0;
cb = 0;
d = 0;
db = 0;
e = 0;
eb = 0;
f = 0;
fb = 0;
g = 0;
gb = 0;
h = 0;
hb = 0;
i = 0;
ib = 0;
}
digitalWrite(13, HIGH);
TSPoint p = ts.getPoint();
digitalWrite(13, LOW);
if (p.z > ts.pressureThreshhold) {
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);

if(p.y < 380){
if(p.x < 400){
if(x==0){
tft.fillCircle(70, 45, 25, YELLOW);
x=x+1;
a = 1;
delay(10);
}
else if(x==1){
drawX(35, 10);
x=x-1;
ab = 1;
delay(10);
}
}
else if(p.x < 650 && p.x > 400){
if(x==0){
tft.fillCircle(160, 45, 25, YELLOW);
x=x+1;
b = 1;
delay(10);
}
else if(x==1){
drawX(130, 10);
x=x-1;
bb = 1;
delay(10);
}}
else if(p.x > 650){
if(x==0){
tft.fillCircle(250, 45, 25, YELLOW);
x=x+1;
c = 1;
delay(10);
}
else if(x==1){
drawX(220, 10);
x=x-1;
cb = 1;
delay(10);
}
}
}
else if(p.y > 380 && p.y < 650){
if(p.x < 400){
if(x==0){
tft.fillCircle(70, 120, 25, YELLOW);
x=x+1;
d = 1;
delay(10);
}
else if(x==1){
drawX(35, 90);
x=x-1;
db = 1;
delay(10);
}
}
else if(p.x < 650 && p.x > 400){
if(x==0){
tft.fillCircle(160, 120, 25, YELLOW);
x=x+1;
e = 1;
delay(10);
}
else if(x==1){
drawX(130, 90);
x=x-1;
eb = 1;
delay(10);
}
}
else if(p.x > 650){
if(x==0){
tft.fillCircle(250, 120, 25, YELLOW);
x=x+1;
f = 1;
delay(10);
}
else if(x==1){
drawX(220, 90);
x=x-1;
fb = 1;
delay(10);
}
}
}
else if(p.y > 650){
if(p.x < 400){
if(x==0){
tft.fillCircle(70, 195, 25, YELLOW);
x=x+1;
g = 1;
delay(10);
}
else if(x==1){
drawX(35, 160);
x=x-1;
gb = 1;
delay(10);
}
}else if(p.x < 650 && p.x > 400){
if(x==0){
tft.fillCircle(160, 195, 25, YELLOW);
x=x+1;
h = 1;
delay(10);
}
else if(x==1){
drawX(130, 160);
x=x-1;
hb = 1;
delay(10);
}
}
else if(p.x > 650){
if(x==0){
tft.fillCircle(250, 195, 25,YELLOW );
x=x+1;
i = 1;
delay(10);
}
else if(x==1){
drawX(220, 160);
x=x-1;
ib = 1;
delay(10);
}
}
}
delay(500);
if(a==1 && b==1 && c==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(d==1 && e==1 && f==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(g==1 && h==1 && i==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}if(a==1 && d==1 && g==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(b==1 && e==1 && h==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(c==1 && f==1 && i==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}if(c==1 && e==1 && g==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(a==1 && e==1 && i==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}if(ab==1 && bb==1 && cb==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(db==1 && eb==1 && fb==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(gb==1 && hb==1 && ib==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(ab==1 && db==1 && gb==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(bb==1 && eb==1 && hb==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(cb==1 && fb==1 && ib==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(cb==1 && eb==1 && gb==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(ab==1 && eb==1 && ib==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(a||ab==1){
if(b||bb==1){
if(c||cb==1){
if(d||db==1){
if(e||eb==1){
if(f||fb==1){
if(g||gb==1){
if(h||hb==1){
if(i||ib==1){
tft.fillScreen(BLACK);
tft.setCursor(65, 100);
tft.setTextColor(GREEN);
tft.setTextSize(3);
tft.println("No winner.");
delay(2000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
}
}
}
}
}
}
}
}
}
}
void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color)
{
int16_t i, j, byteWidth = (w + 7) / 8;
uint8_t byte;
for(j=0; j<h; j++) {
for(i=0; i<w; i++) {
if(i & 7) byte <<= 1;
else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8);
if(byte & 0x80) tft.drawPixel(x+i, y+j, color);
}
}
}
void drawX(int x, int y)
{drawBitmap(x,y,x_bitmap,65,65,RED);
}

يتم تنزيل المكتبات من خلال شريط القوائم في برنامج arduino IDE

لعبة X/O

أو من خلال فك الضغط عن ملفات المكتبات و نقلها إلى الملف التالي الموجود بجهازك  C:\Program Files (x86)\Arduino

شرح الكود البرمجي

 

هذه الأسطر توضح المكتبات المستخدمة في المشروع والتي تخص مكتبة الشاشة الكرستالية والرسومات المطبوعة عليها.

#include <TouchScreen.h>
#include <Elegoo_GFX.h>
#include <Elegoo_TFTLCD.h>
#include <avr/pgmspace.h>

هنا يتم تعريف المدخلات التناظرية في لوحة الاردوينو والمستخدمة في الشاشة الكرستالية.

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4

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

#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

في الدالة ()setup يتم تهيئة الشاشة لطباعة النصوص والرموز المستخدمة في لعبة X/O وأيضًا توضيح الألوان المستخدمة لطباعة النصوص والرموز يمكنك تحرير الألوان حسب ما تراه جيد ومناسب لك.

في البداية سينطبع على الشاشة X-O Game ثم بعد ذلك ستبدأ اللعبة.

void setup() {
  
tft.reset();
tft.begin(0x9341);
tft.fillScreen(BLACK);
tft.setRotation(1);

Serial.begin(9600);

tft.setCursor(60, 110);
tft.setTextColor(RED);
tft.setTextSize(3);
tft.println("X-O Game");
delay(2000);


tft.setCursor(5, 178);
tft.setTextColor(GREEN);
tft.setTextSize(1);
tft.println("In this game, there are two players : Player BLUE");
tft.setCursor(5, 187);
tft.println("and Player RED. Each turn, they can put pads on a");
tft.setCursor(5, 196);
tft.println("grid. You win once three of your pads are aligned.");

delay(9000);


tft.fillScreen(BLACK);

tft.drawLine(113, 10, 113, 230, WHITE);
tft.drawLine(208, 10, 208, 230, WHITE);

tft.drawLine(30, 80, 290, 80, WHITE);
tft.drawLine(30, 160, 290, 160, WHITE);

  pinMode(13, OUTPUT);

}

في الدالة ()loop سيتم عرض الشاشة الخاصة باللعبة بالألوان والرموز التي تم تحديدها في الكود البرمجي.

سيتم استخدام الدائرة الصفراء لتمثيل O وسيتم استخدام حرف X الأزرق لتمثيل X.

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

سيتم عرض النتيجة مباشرة بعد اكتمال كل التسع رموز أو في حالة فوز أحد الأطراف قبل اكتمال التسع رموز سيتم إيقاف اللعبة وإعلان الفائز.


#define WHITE   0xFFFF
void loop() 
{

returning:
if(rturn==1){
tft.fillScreen(BLACK);
tft.drawLine(113, 10, 113, 230, WHITE);
tft.drawLine(208, 10, 208, 230, WHITE);\tft.drawLine(30, 80, 290, 80, WHITE);
tft.drawLine(30, 160, 290, 160, WHITE);
rturn = 0;
x = 0;

a = 0;
ab = 0;
b = 0;
bb = 0;
c = 0;
cb = 0;
d = 0;
db = 0;
e = 0;
eb = 0;
f = 0;
fb = 0;
g = 0;
gb = 0;
h = 0;
hb = 0;
i = 0; 
ib = 0;
}


digitalWrite(13, HIGH);
TSPoint p = ts.getPoint();
digitalWrite(13, LOW);

if (p.z > ts.pressureThreshhold) {

pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);

if(p.y < 380){

if(p.x < 400){
if(x==0){
tft.fillCircle(70, 45, 25, YELLOW);
x=x+1;
a = 1;
delay(10);
}
else if(x==1){
drawX(35, 10);
x=x-1;
ab = 1;
delay(10);
}
}

else if(p.x < 650 && p.x > 400){
if(x==0){
tft.fillCircle(160, 45, 25, YELLOW);
x=x+1;
b = 1;
delay(10);
}
else if(x==1){
drawX(130, 10);
x=x-1;
bb = 1;
delay(10);
}

}

else if(p.x > 650){
if(x==0){
tft.fillCircle(250, 45, 25, YELLOW);
x=x+1;
c = 1;
delay(10);
}
else if(x==1){
drawX(220, 10);
x=x-1;
cb = 1;
delay(10);
}

}
}



else if(p.y > 380 && p.y < 650){

if(p.x < 400){ 
if(x==0){
tft.fillCircle(70, 120, 25, YELLOW);
x=x+1;
d = 1;
delay(10);
}
else if(x==1){
drawX(35, 90);
x=x-1;
db = 1;
delay(10);
}

}
else if(p.x < 650 && p.x > 400){
if(x==0){
tft.fillCircle(160, 120, 25, YELLOW);
x=x+1;
e = 1;
delay(10);
}
else if(x==1){
drawX(130, 90);
x=x-1;
eb = 1;
delay(10);
}

}
else if(p.x > 650){
if(x==0){
tft.fillCircle(250, 120, 25, YELLOW);
x=x+1;
f = 1;
delay(10);
}
else if(x==1){
drawX(220, 90);
x=x-1;
fb = 1;
delay(10);
}

}

}
else if(p.y > 650){
if(p.x < 400){ 
if(x==0){
tft.fillCircle(70, 195, 25, YELLOW);
x=x+1;
g = 1;
delay(10);
}
else if(x==1){
drawX(35, 160);
x=x-1;
gb = 1;
delay(10);
}

}
else if(p.x < 650 && p.x > 400){
if(x==0){
tft.fillCircle(160, 195, 25, YELLOW);
x=x+1;
h = 1;
delay(10);
}
else if(x==1){
drawX(130, 160);
x=x-1;
hb = 1;
delay(10);
}

}
else if(p.x > 650){
if(x==0){
tft.fillCircle(250, 195, 25,YELLOW );
x=x+1;
i = 1;
delay(10);
}
else if(x==1){
drawX(220, 160);
x=x-1;
ib = 1;
delay(10);
}

}

}
delay(500);
if(a==1 && b==1 && c==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
} 
if(d==1 && e==1 && f==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
} 
if(g==1 && h==1 && i==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(a==1 && d==1 && g==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
} 
if(b==1 && e==1 && h==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
} 
if(c==1 && f==1 && i==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(c==1 && e==1 && g==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(a==1 && e==1 && i==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(GREEN);
tft.setTextSize(2);
tft.println("Player O Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(ab==1 && bb==1 && cb==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(db==1 && eb==1 && fb==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(gb==1 && hb==1 && ib==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(ab==1 && db==1 && gb==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(bb==1 && eb==1 && hb==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(cb==1 && fb==1 && ib==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(cb==1 && eb==1 && gb==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(ab==1 && eb==1 && ib==1){
tft.fillScreen(BLACK);
tft.setCursor(80, 110);
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.println("Victory !");
tft.setCursor(72, 140);
tft.setTextColor(RED);
tft.setTextSize(2);
tft.println("Player X Win !");
delay(3000);
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
if(a||ab==1){
if(b||bb==1){
if(c||cb==1){
if(d||db==1){
if(e||eb==1){
if(f||fb==1){
if(g||gb==1){
if(h||hb==1){
if(i||ib==1){
tft.fillScreen(BLACK); 
tft.setCursor(65, 100);
tft.setTextColor(GREEN);
tft.setTextSize(3);
tft.println("No winner."); 
delay(2000); 
tft.fillScreen(BLACK);
tft.setCursor(20, 110);
tft.setTextColor(CYAN);
tft.setTextSize(2);
tft.println("Ready for another game ?");
delay(2000);
tft.setCursor(100, 140);
tft.setTextColor(MAGENTA);
tft.setTextSize(2);
tft.println("Loading");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading.");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading..");
delay(800);
tft.setCursor(100, 140);
tft.println("Loading...");
delay(800);
rturn = 1;
goto returning;
}
}
}
}
}
} 
}
}
}

}
}
void drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color)
{
int16_t i, j, byteWidth = (w + 7) / 8;
uint8_t byte;
for(j=0; j<h; j++) {
for(i=0; i<w; i++) {
if(i & 7) byte <<= 1;
else byte = pgm_read_byte(bitmap + j * byteWidth + i / 8);
if(byte & 0x80) tft.drawPixel(x+i, y+j, color);
}
}
}

void drawX(int x, int y)
{

drawBitmap(x,y,x_bitmap,65,65,RED);
}

يمكنك رفع الكود البرمجي على لوحة الاردوينو باستخدام برنامج اردوينو IDE.

اختبر لعبة X/O.

لا تنسَ فصل مصدر الطاقة بعد الانتهاء من استخدام اللعبة.




حساب سرعة دراجة هوائية باستخدام اردوينو

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

speed-meter-bike/

المواد و الأدوات

في هذا الدرس تحتاج إلى الأدوات التالية

اردوينو اونو 1X
I2C / IIC Serial Interface Module 1X
سلك اردوينو 1X
شاشة كرستالية 1X
لوحة تجارب 1X
مستشعر مفتاح الاتصال المغناطيسي 1X
مقاومة 10 كيلو أوم 1X
ضغاط التحكم  1X
مجموعة أسلاك توصيل 1X

 

 

توصيل الدائرة

توصيل الدائرة

الكود البرمجي

//librarys
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); 
//definition of variables
long previous, triptime, time, impulses;
float speedometer, dist, aspeed;
int screen=1;
//If you have other circuit of wheel you need change it
float radius=2;
void setup() {
lcd.init(); // initialize the lcd 
// Print a message to the LCD.
lcd.setCursor(1,0);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
lcd.print("Bike speedometer");
delay(1000);
lcd.setCursor(5, 1);
lcd.print("V 1.0");
delay(4000);
lcd.clear();
delay(500);
lcd.setCursor(0, 0);
lcd.print("Dist:");
}
void loop() {
int aa=analogRead (A0);
Serial.println (aa); 
//if wheel turns
if(analogRead(A0)>=300){
//number of turns++
impulses++;
//count turn time
time=(millis()-previous);
//count speed
speedometer=(3600000 / time) * radius/ 1000;
speedometer=(circuit / time)*3600.0;
previous=millis();
delay(100);
}
Lcd();
}
void Lcd(){
//when button is clicked
if(digitalRead (A1)==1){
lcd.clear();
screen++;
if(screen==3){
screen=1;
}
}
if(screen==1){
//displays speed
lcd.setCursor(0, 1);
lcd.print("Speed:");
lcd.setCursor(7, 1);
lcd.print(speedometer);
lcd.print("km/h");
}
if(screen== 2){
//diplays trip time
triptime=millis()/60000;
lcd.setCursor(0, 1);
lcd.print("Time:");
lcd.setCursor(7, 1);
lcd.print(triptime);
}
lcd.setCursor(0, 0);
lcd.print("Dist:");
//calculation of the distance
dist=impulses*radius/1000.00;
//dislays distance
lcd.setCursor(6,0);
lcd.print(dist);
lcd.print("km");
}

شرح الكود البرمجي 

سنقوم في البداية باستدعاء مكتبة (LiquidCrystal_I2C) الخاصة بوحدة i2c و التي تحتوي على مجموعة أوامر برمجية نحتاجها في المشروع

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

نعرف عنوان وحدة i2c

LiquidCrystal_I2C lcd(0x27,20,4); 
//definition of variables

نعرف المتغيرات التالية و هي (previous, triptime, time, impulses, speedometer, dist, aspeed)

long previous, triptime, time, impulses;
float speedometer, dist, aspeed;

تعريف متغير (screen) و الذي يشير إلى طباعة البيانات و ستتم طباعتها على 3 شاشات شاشة تحتوي على المسافة والسرعة و شاشة تعرض المسافة و متوسط السرعة وشاشة للوقت و المسافة

int screen=1;

تحديد نصف القطر للعجلة

float radius=2.0;

تهيئة الشاشة والمنافذ

void setup() {
itialize the lcd 
lcd.init();
// Print a message to the LCD.

lcd.backlight();
lcd.setCursor(1,0);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
lcd.print("Bike speedometer ");
delay(1000);}

في دالة void loop يتم حساب سرعة دراجة هوائية حسب الوقت المعادلة بالدالة

void loop() {
int aa=analogRead (A0);
//if wheel turns
if(analogRead(A0)>=300){
//number of turns++
impulses++;
//count turn time
time=(millis()-previous);
//count speed
speedometer=(radius/ time)*3600.0;
previous=millis();
delay(100);
}

تحديد البيانات في كل شاشة و سيتم عرض 3 شاشات شاشة تظهر السرعة و شاشة تظهر متوسط السرعة وشاشة تظهر وقت الرحلة بالدقائق

Lcd();
}
void Lcd(){
//when button is clicked
if(digitalRead (A1)==1){
lcd.clear();
screen++;
if(screen==3){
screen=1;
}
}

if(screen==1){
//displays speed
lcd.setCursor(0, 1);
lcd.print("Speed:");
lcd.setCursor(7, 1);
lcd.print(speedometer);
lcd.print("km/h");
}

if(screen== 2){
//diplays trip time
triptime=millis()/60000;

lcd.setCursor(0, 1);
lcd.print("Time:");
lcd.setCursor(7, 1);
lcd.print(triptime);


}

عرض المسافة

lcd.setCursor(0, 0); 
lcd.print("Dist:"); //calculation of the distance 
dist=impulses*circuit/1000.00; //dislays distance 
lcd.setCursor(6,0);
 lcd.print(dist); 
lcd.print("km"); }

قم بتثبيت المستشعر بحيث يكون في جزء ثابت يقابل العجلة، وعلى العجلة يتم تثبيت المغناطيس في كل مرة تتحرك العجلة و يصبح المغناطيس في مقابل الحساس سيتم حساب نبضة،

 تحتاج إلى توفير صندوق باستخدام طابعة ثلاثية الأبعاد أو قاطع الليزر لحفظ كافة القطع بشكل ثابت أثناء الرحلة

 

 




الحصالة الذكية باستخدام الاردوينو ومستشعر تجنب الحواجز

مقدمة

في هذا الدرس ستتعلم كيف تصنع حصالة ذكية تقوم بحساب العملات المعدنية باستخدام الاردوينو ومستشعر تجنب الحواجز بالأشعة تحت الحمراء.coin-sorting-counting-machine-arduino

المواد والأدوات

الحصالة الذكية

اردوينو اونو

الحصالة الذكية

مستشعر تجنب الحواجز بالأشعة تحت الحمراء

arduino-usb-lead-blue

x1 سلك الاردوينو

حصالة ذكية

شاشة كرستالية (LCD 2×16)

حصالة ذكية

1× لوحة تجارب – حجم كبير

حصالة ذكية

 1× مقاومة متغيرة

اسلاك توصيل

 حزمة أسلاك توصيل (ذكر- أنثى)

الحصالة الذكية

 حزمة أسلاك توصيل (ذكر- ذكر)

شفرة

1× 40 رأس دبوس

الحصالة الذكية

1× هيكل الحصالة

توصيل الدائرة

للمزيد حول مستشعر تجنب الحواجز بالأشعة تحت الحمراء يمكنك الرجوع للدرس إضاءة ذكية باستخدام مستشعر تجنب الحواجز بالأشعة تحت الحمراء.

وللمزيد حول الشاشة الكرستالية يمكنك الرجوع للدرس التحكم بالشاشة الكرستالية LCD.

coin-sorting-counting-machine-arduino

هيكل الحصالة الذكية

في هذا الدرس تم استخدام قالب كرتوني لمحاكاة الحصالة الذكية.

coin-sorting-counting-machine-arduino

الحصالة الذكية

يمكنك اختيار شكل الهيكل المناسب لك سواء قالب فيليني أو كرتوني أو نموذج بالطابعة ثلاثية الأبعاد أو نموذج خشبي بجهاز الليزر.

بعد ذلك ثبت الدائرة الكهربائية على الهيكل.الحصالة الذكية

الحصالة الذكية

الكود البرمجي

ارفع كود الحصالة الذكية على لوحة الاردوينو باستخدام برنامج اردوينو (IDE).

#include "EEPROMex.h"
#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const float coinA = A0; 
const int coinB = A1;
const int coinC = A2;

float irA=0;
int irB,irC = 0;
float cntA=0;
float cntB,cntC,cnttotal = 0;

void setup() 
{
Serial.begin(9600); 
pinMode(coinA ,INPUT);
pinMode(coinB ,INPUT);
pinMode(coinC,INPUT);

lcd.begin(16, 2);
lcd.write(EEPROM.read(5));
}

void loop() 
{
irA =digitalRead(coinA); 
irB =digitalRead(coinB); 
irC=digitalRead(coinC); 

if(irA ==LOW){cntA+=0.50; delay(600);}
if(irB ==LOW){cntB+=1; delay(600);}
if(irC ==LOW){cntC+=2; delay(600);}
cnttotal =cntA+cntB+cntC;

EEPROM.write(5,cnttotal);
Serial.println(EEPROM.read(5));
lcd.setCursor(0,0);
lcd.print("Total :");
lcd.setCursor(0,1);
lcd.print(cnttotal);
}

شرح الكود البرمجي

هذه الأسطر تستدعي المكتبات الضرورية للدرس مثل مكتبة الشاشة الكرستالية <LiquidCrystal.h> و مكتبة “EEPROMex.h” التي تستخدم لكتابة وقراءة الأرقام.

يمكنك تحميل المكتبات من هنا.

يتم تنزيل المكتبات من خلال شريط القوائم في برنامج arduino IDE.

لعبة X/O

أو من خلال فك الضغط عن ملفات المكتبات ونقلها إلى الملف التالي الموجود بجهازك  C:\Program Files (x86)\Arduino

#include "EEPROMex.h"
#include <LiquidCrystal.h>

بعد ذلك تم انشاء المتغيرات اللازمة مثل المتغيرات الخاصة بالشاشة الكرستالية.

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

في هذه الأسطر تم تعريف المتغيرات التي سيتم استخدامها لتخزين القيم المقروءة من مستشعر تجنب الحواجز.

المتغير coinA من النوع float يستخدم لتخزين القيم المقروءة من المنفذ A0.

المتغير coinB من النوع int يستخدم لتخزين القيم المقروءة من المنفذ A1.

المتغير coinC من النوع int يستخدم لتخزين القيم المقروءة من المنفذ A2.

const float coinA = A0; 
const int coinB = A1;
const int coinC = A2;

سيتم تعيين القيم الابتدائية لكل مستشعرات تجنب الحواجز = 0.

وسيتم تعيين القيمة الابتدائية للمجموع الكلي لكل مستشعرات تجنب الحواجز = 0.

float irA=0;
int irB,irC = 0;
float cntA=0;
float cntB,cntC,cnttotal = 0;

في الدالة ()setup يتم تهيئة الشاشة الكرستالية وجعل المتغير coinA و coinB و coinC كمدخلات لقراءة القيم من المستشعرات.

void setup() 
{
Serial.begin(9600); 
pinMode(coinA ,INPUT);
pinMode(coinB ,INPUT);
pinMode(coinC,INPUT);

lcd.begin(16, 2);
lcd.write(EEPROM.read(5));
}

في الدالة ()loop يتم تخزين القيم المقروءة من المستشعرات الثلاث.

المدخل coinA قيمته تخزن في المتغير irA.

المدخل coinB قيمته تخزن في المتغير irB.

المدخل coinC قيمته تخزن في المتغير irC.

void loop() 
{
irA =digitalRead(coinA); 
irB =digitalRead(coinB); 
irC =digitalRead(coinC);

هنا سيتم حساب العملات في كل مستشعر.

وبعد ذلك يتم جمع القيم من كل المستشعرات وتخزينها في cnttotal.

if(irA ==LOW){cntA+=0.50; delay(600);}
if(irB ==LOW){cntB+=1; delay(600);}
if(irC ==LOW){cntC+=2; delay(600);}
cnttotal =cntA+cntB+cntC;

سيتم طباعة Total متبوعة بالمجموع الكلي للعملات المعدنية.

EEPROM.write(5,cnttotal);
Serial.println(EEPROM.read(5));
lcd.setCursor(0,0);
lcd.print("Total :");
lcd.setCursor(0,1);
lcd.print(cnttotal);
}

يمكنك اختبار الحصالة الذكية بعد رفع الكود البرمجي.

 لا تنسَ فصل مصدر الطاقة بعد الانتهاء من استخدام النظام.




مقياس تدفق الماء و التحكم بالكمية باستخدام الاردوينو

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

تدفق الماء


المواد و الأدوات*

اردوينو

X1 أردوينو أونو 

مرحل

X1 مرحل 

سلك الاردوينو

X1 سلك الأردوينو 

مفتاح

X8 ضغاط التحكم 

لوحة تجارب

X2 لوحة تجارب 

حساس التدفق

X1 حساس التدفق 

مقاومة

X8 مقاومة 10 كيلو أوم

مقاومة 220

1X مقاومة 220 أوم

مقاومة متغيرة

X1 مقاومة متغيرة 

صمام ملف

X1 ملف صمام 

وصلة  تيار ثابت

X1 وصلة تيار ثابت 

محول طاقة

X1 مصدر طاقة 24 فولت

توصيل الدائرة

توصيل الدائرة

 

حساس التدفق

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

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

مستشعر التدفق

ويحتوي المستشعر على 3 أسلاك باللون الأحمر والأصفر والأسود. يستخدم السلك الأحمر للجهد الذي يتراوح من 5 فولت إلى 18 فولت والسلك الأسود متصل بـ GND. يستخدم السلك الأصفر للإخراج (نبضات)، والتي يمكن قراءتها بواسطة المتحكم ، كذلك يظهر على المستشعر سهم يشير إلى مسار الماء

مستشعر التدفق

فكرة المشروع

النظام في هذا المشروع يتكون من 8 مفاتيح تحكم و شاشة عرض كرستالية، بالإضافة لحساس التدفق، الذي يتم من خلاله قياس كمية الماء، وكذلك يوجد صمام الملف الذي يسمح بمرور الماء إلى الحساس، و يتم غلق الصمام عند وصول الماء للمستوى المطلوب. وظائف المفاتيح بالنظام كالتالي :

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

ثانيًا: مفتاح تحديد الوحدة يمكن قياس الكمية بوحدة مليلتر أو لتر، إذا كان في حالة 0يعني أنه على وحدة مليلتر. وحالة 1 يعني لتر

ثالثا: متاح إعادة ضبط الكمية المعينة إلى 0، حيث تُظهر الشاشة SP   والتي تعني الكمية التي يعمل النظام للوصول لها والتي تم تحديدها من قبل المستخدم.

رابعًا: زر إعادة ضبط عداد الكمية المعبئة إلى 0، لبدء تعبئة جديدة، حيث تظهر الشاشة CNT والتي تشير لكمية الماء التي تم تعبئتها

خامسًا: مفاتيح تعين كمية الماء، وهي أربع مفاتيح +1,+10,+100,+1000.

 

تحديد عدد نبضات لتر واحد من الماء

 مواصفات المنتج أن 450 نبضة للتر واحد من الماء لكن للوصول لقراءة دقيقة سنقوم بعملية الوزن ،عن طريق أخذ قراءة عدد النبضات عند تمرير لتر واحد من الماء

الكود البرمجي 

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13); //Pines arduino to lcd

//-------Pins-----//
int Relay = 1; //Solenoid valve open/close
int start_stop = 2; //Start/Stop button
const int sensor_pulse = 16; //Sensor pulse
int rst_cnt = 3; // Reset counter button
//---------Storage debounce function-----//
boolean currentstart_stop = LOW; 
boolean laststart_stop =LOW; 
boolean lastsensor_pulse = LOW;
boolean currentsensor_pulse = LOW;
boolean lastrst_cnt = LOW;
boolean currentrst_cnt = LOW;
boolean RelayState = LOW; 

int counter = 0;

void setup() {
pinMode(Relay, OUTPUT);
lcd.begin(16, 2);
lcd.setCursor(5, 0);
lcd.print("COUNTER");
lcd.setCursor(0, 1);
lcd.print("PULSES");

}
//----Debouncing function----//
boolean debounce(boolean last, int pin)
{
boolean current = digitalRead(pin);
if (last != current)
{
delay(5);
current = digitalRead(pin);
}
return current;
}

void loop() { 
currentstart_stop = debounce(laststart_stop, start_stop); //Debounce for Start/Stop Button
currentsensor_pulse = debounce(lastsensor_pulse, sensor_pulse); //Debounce for Sensor pulse Button
currentrst_cnt = debounce(lastrst_cnt, rst_cnt); //Debounce for reset counter Button

//-----Start/Stop toggle function----//
if (currentstart_stop == HIGH && laststart_stop == LOW){

if (RelayState == HIGH){ //Toggle the state of the Relay
digitalWrite(Relay, LOW);
RelayState = LOW;


} 
else{
digitalWrite(Relay, HIGH);
RelayState = HIGH;
}
}

laststart_stop = currentstart_stop;

if (lastsensor_pulse== LOW && currentsensor_pulse == HIGH){
counter=counter+ 1;
}
lastsensor_pulse = currentsensor_pulse;

lcd.setCursor(7, 1);
lcd.print(counter);

if(RelayState == LOW){ //Reset counter while sistem is not running
if (currentrst_cnt == HIGH && lastrst_cnt == LOW){//Reset Counter
lcd.setCursor(6, 1); // Clear CNT area
lcd.print(" ");
counter= 0; 

}
lastrst_cnt = currentrst_cnt; 
}

}// end void loop

شرح الكود البرمجي 

استدعاء مكتبة الشاشة الكرستالية، و تعريف المنافذ للشاشة

 #include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13); //Pines arduino to lcd

تعريف منافذ الحساس تم توصيله مع منفذ A2= 16، و تسمية المتغير sensor_pulse، كذلك تعريف منفذ مفتاح التحكم بتشغيل النظام و هو المنفذ رقم 3 و منفذ مفتاح التحكم بتصفير العداد و هو المنفذ رقم 2

//-------Pins-----//
int Relay = 17; //Solenoid valve open/close
int start_stop = 2; //Start/Stop button
const int sensor_pulse = 16; //Sensor pulse
int rst_cnt = 3; // Reset counter button

تعين الحالة الابتدائية للمتغرات

boolean currentstart_stop = LOW; 
boolean laststart_stop =LOW; 
boolean lastsensor_pulse = LOW;
boolean currentsensor_pulse = LOW;
boolean lastrst_cnt = LOW;
boolean currentrst_cnt = LOW;
boolean RelayState = LOW; 

int counter = 0;

في دالة void setup نقوم بتهيئة الشاشة وتعريف منافذ الادخال و الاخراج

void setup() {
pinMode(Relay, OUTPUT);
lcd.begin(16, 2);
lcd.setCursor(5, 0);
lcd.print("COUNTER");
lcd.setCursor(0, 1);
lcd.print("PULSES");

}
//----Debouncing function----//
boolean debounce(boolean last, int pin)
{
boolean current = digitalRead(pin);
if (last != current)
{
delay(5);
current = digitalRead(pin);
}
return current;
}

في دالة void loop يتم حساب عدد النبضات و عرضها على الشاشة الكرستالية

void loop() { 
currentstart_stop = debounce(laststart_stop, start_stop); //Debounce for Start/Stop Button
currentsensor_pulse = debounce(lastsensor_pulse, sensor_pulse); //Debounce for Sensor pulse Button
currentrst_cnt = debounce(lastrst_cnt, rst_cnt); //Debounce for reset counter Button

//-----Start/Stop toggle function----//
if (currentstart_stop == HIGH && laststart_stop == LOW){

if (RelayState == HIGH){ //Toggle the state of the Relay
digitalWrite(Relay, LOW);
RelayState = LOW;


} 
else{
digitalWrite(Relay, HIGH);
RelayState = HIGH;
}
}

laststart_stop = currentstart_stop;
if (lastsensor_pulse== LOW && currentsensor_pulse == HIGH){
counter=counter+ 1;
}
lastsensor_pulse = currentsensor_pulse;
lcd.setCursor(7, 1);
lcd.print(counter);
if(RelayState == LOW){ //Reset counter while sistem is not running
if (currentrst_cnt == HIGH && lastrst_cnt == LOW){//Reset Counter
lcd.setCursor(6, 1); // Clear CNT area
lcd.print(" ");
counter= 0; 
}
lastrst_cnt = currentrst_cnt; 
}
}// end void loop

قم بحفض القيمة لكل لتر من الماء ليتم تعديلها في الشفرة البرمجية للمشروع

الكود البرمجي

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13); //Pines arduino to lcd

//-------Pins-----//
int Relay = 17; //Solenoid valve open/close
int start_stop = 2; //Start/Stop button
int rst_sp = 3; // Reset Set Point Button
int rst_cnt = 4; // Reset counter button
int unit = 5; // Change Unit Button
const int sensor_pulse =16; // Sensor Pulse In
//----Analog as Input-----//
int add_one =6; // +1 Button
int add_ten = 7; // +10 Button
int add_cien = 14; // +100 Button
int add_mil = 15; // +1000 Buton

//-----Variables for debouncing-----//
boolean currentstart_stop = LOW; 
boolean laststart_stop =LOW; 
boolean lastsensor_pulse = LOW;
boolean currentsensor_pulse = LOW;
boolean lastunit = LOW;
boolean currentunit = LOW;
boolean lastrst_sp = LOW;
boolean currentrst_sp = LOW;
boolean lastrst_cnt = LOW;
boolean currentrst_cnt = LOW;
boolean lastadd_one = LOW;
boolean currentadd_one = LOW;
boolean lastadd_ten = LOW;
boolean currentadd_ten = LOW;
boolean lastadd_cien = LOW;
boolean currentadd_cien = LOW;
boolean lastadd_mil = LOW;
boolean currentadd_mil = LOW;

//-----Storage state for toggle function---//
boolean unitState = LOW; //storage for the current state of the unit
boolean RelayState = LOW; //storage for the current state of the Relay (off/on)

//-------You have to put your pulses x liters here-----//
float cal_1=2.5; //Calibrate ml x pulse (cal_1 = 1000/400)
int cal_2= 400; //Calibrate pulses x liters
//-----------------------------------------------------//

float counter_1 = 0.0; 
int counter_2= 0; 
int TotalCount_1= 0;
int TotalCount_2= 0;
int set_point_1= 0; 
int set_point_2= 0;

void setup(){
lcd.begin(16, 2);
pinMode(Relay, OUTPUT); 
pinMode(add_one, INPUT); 
pinMode(add_ten, INPUT); 
pinMode(add_cien, INPUT); 
pinMode(add_mil, INPUT);

lcd.setCursor(0,0); //Show "SP" on the LCD
lcd.print("SP"); 
lcd.setCursor(0,1); //Show "CNT" on the LCD
lcd.print("CNT"); 

}
//----Debouncing function for all buttons----//
boolean debounce(boolean last, int pin)
{
boolean current = digitalRead(pin);
if (last != current)
{
delay(5);
current = digitalRead(pin);
}
return current;
}

void loop(){
//-----Debounce Buttons-----//
currentstart_stop = debounce(laststart_stop, start_stop); //Debounce for Start/Stop Button
currentsensor_pulse = debounce(lastsensor_pulse, sensor_pulse); //Debounce for Sensor
currentunit = debounce(lastunit, unit); //Debounce for unit Button
currentrst_sp = debounce(lastrst_sp, rst_sp); //Debounce for reset set point Button
currentrst_cnt = debounce(lastrst_cnt, rst_cnt); //Debounce for reset counter Button
currentadd_one = debounce(lastadd_one, add_one); //Debounce for +1 Button
currentadd_ten = debounce(lastadd_ten, add_ten); //Debounce for +10 Button
currentadd_cien = debounce(lastadd_cien, add_cien); //Debounce for +100 Button
currentadd_mil = debounce(lastadd_mil, add_mil); //Debounce for +1000 Button


//-----Start/Stop toggle function----//
if (currentstart_stop == HIGH && laststart_stop == LOW){

if (RelayState == HIGH){ //Toggle the state of the Relay
digitalWrite(Relay, LOW);
RelayState = LOW;
} 
else{
digitalWrite(Relay, HIGH);
RelayState = HIGH;
}
}

laststart_stop = currentstart_stop;

//-------Unit toggle function----//
if(RelayState == LOW){ //You only can change unit while system is not running! 

//------ Lt/ml unit toggle function----//
if (currentunit == HIGH && lastunit == LOW){
lcd.setCursor(4, 1); //Clear lcd(CNT area) between unit change,keeping last count
lcd.print(" ");
lcd.setCursor(3,0); //Clear lcd (SP area) between unit change, keeping last SP
lcd.print(" ");

if (unitState == HIGH){ //Toggle the state of the unit (L/ml)
digitalWrite(unit, LOW);
unitState = LOW;
}
else{
digitalWrite(unit, HIGH);
unitState = HIGH; 
}
}
lastunit = currentunit;
}
//------Print unit state-----//
if(unitState==HIGH){ //Unit state HIGH = L 
lcd.setCursor(14,0);
lcd.print("Lt");
lcd.setCursor(14, 1);
lcd.print("Lt");

}
else { //Unit state LOW = ml
lcd.setCursor(14,0);
lcd.print("Ml");
lcd.setCursor(14,1);
lcd.print("Ml");
}//End Print unit state

//--------------------------// 
//------------Ml Counter-----//
//---------------------------//
if(unitState==LOW){ // LOW= Ml state

//-----------------------//
//-----Settings----------//
//----------------------//

if(RelayState == LOW){ // You only can change settings while system is not running!

//-----Adders Buttons (set point_1)---//

if (currentadd_ten == HIGH && lastadd_ten == LOW){ // Add +10
set_point_1 = set_point_1 +10;
}
lastadd_ten = currentadd_ten;

if (currentadd_cien == HIGH && lastadd_cien == LOW){ // Add +100
set_point_1 = set_point_1 +100;
}
lastadd_cien = currentadd_cien;

if (currentadd_mil == HIGH && lastadd_mil == LOW){ // Add +1000
set_point_1 = set_point_1 +1000;
}
lastadd_mil = currentadd_mil; 

//-------Reset Buttons----//
if (currentrst_sp == HIGH && lastrst_sp == LOW){ //Reset Set Point
lcd.setCursor(3, 0); // Clear SP area
lcd.print(" ");
set_point_1 = 0;
}
lastrst_sp = currentrst_sp;
if (currentrst_cnt == HIGH && lastrst_cnt == LOW){//Reset Counter
lcd.setCursor(4, 1); // Clear CNT area
lcd.print(" ");
counter_1= 0; 
TotalCount_1= 0;
}
lastrst_cnt = currentrst_cnt;
}//-----End Settings-----//

//----Start Counter------//
if(RelayState == HIGH){ // Only counts while relay is HIGH
if (lastsensor_pulse== LOW && currentsensor_pulse == HIGH){
counter_1 = counter_1 + cal_1;
}
}
lastsensor_pulse = currentsensor_pulse;

//-------Counter function-----//
if(counter_1 >= 10){
TotalCount_1 = TotalCount_1 + 10;
counter_1=0; //Counter reset
}

lcd.setCursor(3, 0); //Show set point
lcd.print(set_point_1);
lcd.setCursor(4, 1); // Show counter
lcd.print(TotalCount_1);

//--Stop Counter.You can´t start if set point is lower or equal to counter--//
if(RelayState==HIGH){
if(set_point_1 <= TotalCount_1){ 
RelayState = LOW;
digitalWrite(Relay, LOW);
//***********************************************Autoreset
lcd.setCursor(4, 1); // Clear CNT area
lcd.print(" ");
counter_1= 0; 
TotalCount_1= 0; 
}
}
}//End unit state LOW (ml)

//--------------------------// 
//------------Lt Counter-----//
//---------------------------//

if(unitState== HIGH){ //HIGH = Lt state

//-----------------------//
//-----Settings----------//
//----------------------//

if(RelayState == LOW){ // You only can change settings while system is not running!

//-----Adders Buttons (set point_2)---//
if (currentadd_one == HIGH && lastadd_one == LOW){ // Add +1 
set_point_2 = set_point_2 +1;
}
lastadd_one = currentadd_one;

if (currentadd_ten == HIGH && lastadd_ten == LOW){ // Add +10
set_point_2 = set_point_2 +10;
}
lastadd_ten = currentadd_ten;

if (currentadd_cien == HIGH && lastadd_cien == LOW){ // Add +100
set_point_2 = set_point_2 +100;
}
lastadd_cien = currentadd_cien;

if (currentadd_mil == HIGH && lastadd_mil == LOW){ // Add +1000
set_point_2 = set_point_2 +1000;
}
lastadd_mil = currentadd_mil; 

//-------Reset Buttons----//
if (currentrst_sp == HIGH && lastrst_sp == LOW){ //Reset Set Point
lcd.setCursor(3, 0); // Clear SP area
lcd.print(" ");
set_point_2 = 0;
}
lastrst_sp = currentrst_sp;
if (currentrst_cnt == HIGH && lastrst_cnt == LOW){//Reset Counter
lcd.setCursor(4, 1); // Clear CNT area
lcd.print(" ");
counter_2= 0; 
TotalCount_2= 0;
}
lastrst_cnt = currentrst_cnt;
}//-----End Settings-----//

//----Start Counter------//
if(RelayState == HIGH){ // Only counts while relay is HIGH
if (lastsensor_pulse== LOW && currentsensor_pulse == HIGH){
counter_2 = counter_2 + 1;
}
}
lastsensor_pulse = currentsensor_pulse;

//-------Counter function-----//
if(counter_2 == cal_2){
TotalCount_2 = TotalCount_2 + 1;
counter_2 = 0; //Counter reset
}

lcd.setCursor(3, 0); //Show set point
lcd.print(set_point_2);
lcd.setCursor(4, 1); // Show counter
lcd.print(TotalCount_2);

//--Stop Counter.You can´t start if set point is lower or equal to counter--//
if(RelayState==HIGH){
if(set_point_2 <= TotalCount_2){
RelayState = LOW;
digitalWrite(Relay, LOW);
//*****************************Autoreset
lcd.setCursor(4, 1); // Clear CNT area
lcd.print(" ");
counter_2= 0; 
TotalCount_2= 0; 
} 
}


}//End unit state HIGH (L)




}//End Void Loop

شرح الكود البرمجي

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

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13); //Pines arduino to lcd

تعريف منافذ مفاتيح النظام

//-------Pins-----//
int Relay = 17; //Solenoid valve open/close
int start_stop = 2; //Start/Stop button
int rst_sp = 3; // Reset Set Point Button
int rst_cnt = 4; // Reset counter button
int unit = 5; // Change Unit Button
const int sensor_pulse =16; // Sensor Pulse In
//----Analog as Input-----//
int add_one =6; // +1 Button
int add_ten = 7; // +10 Button
int add_cien = 14; // +100 Button
int add_mil = 15; // +1000 Buton

تعريف متغيرات

//-----Variables for debouncing-----//
boolean currentstart_stop = LOW; 
boolean laststart_stop =LOW; 
boolean lastsensor_pulse = LOW;
boolean currentsensor_pulse = LOW;
boolean lastunit = LOW;
boolean currentunit = LOW;
boolean lastrst_sp = LOW;
boolean currentrst_sp = LOW;
boolean lastrst_cnt = LOW;
boolean currentrst_cnt = LOW;
boolean lastadd_one = LOW;
boolean currentadd_one = LOW;
boolean lastadd_ten = LOW;
boolean currentadd_ten = LOW;
boolean lastadd_cien = LOW;
boolean currentadd_cien = LOW;
boolean lastadd_mil = LOW;
boolean currentadd_mil = LOW;

//-----Storage state for toggle function---//
boolean unitState = LOW; //storage for the current state of the unit
boolean RelayState = LOW; //storage for the current state of the Relay (off/on)

هنا يتم تعديل الأمر البرمجي بناء على عدد النبضات التي وجدتها في كود الموازنة، حيث تقوم بقسمة عدد النبضات على 1000 لتعين متغير cal_1 و متغسر cal_2 يساوي عدد النبضات

//-------You have to put your pulses x liters here-----//
float cal_1=2.5; //Calibrate ml x pulse (cal_1 = 1000/400)
int cal_2= 400; //Calibrate pulses x liters
//-----------------------------------------------------//

float counter_1 = 0.0;
int counter_2= 0;
int TotalCount_1= 0;
int TotalCount_2= 0;
int set_point_1= 0;
int set_point_2= 0;

في دالة void setup يتم تهيئة الشاشة

void setup(){
lcd.begin(16, 2);
pinMode(Relay, OUTPUT);
pinMode(add_one, INPUT);
pinMode(add_ten, INPUT);
pinMode(add_cien, INPUT);
pinMode(add_mil, INPUT);

lcd.setCursor(0,0); //Show "SP" on the LCD
lcd.print("SP");
lcd.setCursor(0,1); //Show "CNT" on the LCD
lcd.print("CNT");

}
//----Debouncing function for all buttons----//
boolean debounce(boolean last, int pin)
{
boolean current = digitalRead(pin);
if (last != current)
{
delay(5);
current = digitalRead(pin);
}
return current;
}


دالة الvoid loop لبدء النظام

 

void loop(){
//-----Debounce Buttons-----//
currentstart_stop = debounce(laststart_stop, start_stop); //Debounce for Start/Stop Button
currentsensor_pulse = debounce(lastsensor_pulse, sensor_pulse); //Debounce for Sensor
currentunit = debounce(lastunit, unit); //Debounce for unit Button
currentrst_sp = debounce(lastrst_sp, rst_sp); //Debounce for reset set point Button
currentrst_cnt = debounce(lastrst_cnt, rst_cnt); //Debounce for reset counter Button
currentadd_one = debounce(lastadd_one, add_one); //Debounce for +1 Button
currentadd_ten = debounce(lastadd_ten, add_ten); //Debounce for +10 Button
currentadd_cien = debounce(lastadd_cien, add_cien); //Debounce for +100 Button
currentadd_mil = debounce(lastadd_mil, add_mil); //Debounce for +1000 Button

//-----Start/Stop toggle function----//
if (currentstart_stop == HIGH && laststart_stop == LOW){

if (RelayState == HIGH){ //Toggle the state of the Relay
digitalWrite(Relay, LOW);
RelayState = LOW;
}
else{
digitalWrite(Relay, HIGH);
RelayState = HIGH;
}
}

laststart_stop = currentstart_stop;

//-------Unit toggle function----//
if(RelayState == LOW){ //You only can change unit while system is not running!

//------ Lt/ml unit toggle function----//
if (currentunit == HIGH && lastunit == LOW){
lcd.setCursor(4, 1); //Clear lcd(CNT area) between unit change,keeping last count
lcd.print(" ");
lcd.setCursor(3,0); //Clear lcd (SP area) between unit change, keeping last SP
lcd.print(" ");

if (unitState == HIGH){ //Toggle the state of the unit (L/ml)
digitalWrite(unit, LOW);
unitState = LOW;
}
else{
digitalWrite(unit, HIGH);
unitState = HIGH;
}
}
lastunit = currentunit;
}

الشرط التالي لتغير الوحدة

//------Print unit state-----//
if(unitState==HIGH){ //Unit state HIGH = L
lcd.setCursor(14,0);
lcd.print("Lt");
lcd.setCursor(14, 1);
lcd.print("Lt");

}
else { //Unit state LOW = ml
lcd.setCursor(14,0);
lcd.print("Ml");
lcd.setCursor(14,1);
lcd.print("Ml");
}//End Print unit state

//--------------------------//
//------------Ml Counter-----//
//---------------------------//
if(unitState==LOW){ // LOW= Ml state

//-----------------------//
//-----Settings----------//
//----------------------//

يمكن تغير الإعدادات اذا كان النظام لايعمل

if(RelayState == LOW){ // You only can change settings while system is not running!

//-----Adders Buttons (set point_1)---//

if (currentadd_ten == HIGH && lastadd_ten == LOW){ // Add +10
set_point_1 = set_point_1 +10;
}
lastadd_ten = currentadd_ten;

if (currentadd_cien == HIGH && lastadd_cien == LOW){ // Add +100
set_point_1 = set_point_1 +100;
}
lastadd_cien = currentadd_cien;

if (currentadd_mil == HIGH && lastadd_mil == LOW){ // Add +1000
set_point_1 = set_point_1 +1000;
}
lastadd_mil = currentadd_mil;

الشرط التالي لتحديد عمل مفتاح اعادة الضبط

//-------Reset Buttons----//
if (currentrst_sp == HIGH && lastrst_sp == LOW){ //Reset Set Point
lcd.setCursor(3, 0); // Clear SP area
lcd.print(" ");
set_point_1 = 0;
}
lastrst_sp = currentrst_sp;
if (currentrst_cnt == HIGH && lastrst_cnt == LOW){//Reset Counter
lcd.setCursor(4, 1); // Clear CNT area
lcd.print(" ");
counter_1= 0;
TotalCount_1= 0;
}
lastrst_cnt = currentrst_cnt;
}//-----End Settings-----//

//----Start Counter------//
if(RelayState == HIGH){ // Only counts while relay is HIGH
if (lastsensor_pulse== LOW && currentsensor_pulse == HIGH){
counter_1 = counter_1 + cal_1;
}
}
lastsensor_pulse = currentsensor_pulse;

دالة العداد

//-------Counter function-----//
if(counter_1 >= 10){
TotalCount_1 = TotalCount_1 + 10;
counter_1=0; //Counter reset
}

lcd.setCursor(3, 0); //Show set point
lcd.print(set_point_1);
lcd.setCursor(4, 1); // Show counter
lcd.print(TotalCount_1);

//--Stop Counter.You can´t start if set point is lower or equal to counter--//
if(RelayState==HIGH){
if(set_point_1 <= TotalCount_1){
RelayState = LOW;
digitalWrite(Relay, LOW);
//***********************************************Autoreset
lcd.setCursor(4, 1); // Clear CNT area
lcd.print(" ");
counter_1= 0;
TotalCount_1= 0;
}
}
}//End unit state LOW (ml)

//--------------------------//
//------------Lt Counter-----//
//---------------------------//

if(unitState== HIGH){ //HIGH = Lt state

//-----------------------//
//-----Settings----------//
//----------------------//

if(RelayState == LOW){ // You only can change settings while system is not running!

//-----Adders Buttons (set point_2)---//
if (currentadd_one == HIGH && lastadd_one == LOW){ // Add +1
set_point_2 = set_point_2 +1;
}
lastadd_one = currentadd_one;

if (currentadd_ten == HIGH && lastadd_ten == LOW){ // Add +10
set_point_2 = set_point_2 +10;
}
lastadd_ten = currentadd_ten;

if (currentadd_cien == HIGH && lastadd_cien == LOW){ // Add +100
set_point_2 = set_point_2 +100;
}
lastadd_cien = currentadd_cien;

if (currentadd_mil == HIGH && lastadd_mil == LOW){ // Add +1000
set_point_2 = set_point_2 +1000;
}
lastadd_mil = currentadd_mil;

//-------Reset Buttons----//
if (currentrst_sp == HIGH && lastrst_sp == LOW){ //Reset Set Point
lcd.setCursor(3, 0); // Clear SP area
lcd.print(" ");
set_point_2 = 0;
}
lastrst_sp = currentrst_sp;
if (currentrst_cnt == HIGH && lastrst_cnt == LOW){//Reset Counter
lcd.setCursor(4, 1); // Clear CNT area
lcd.print(" ");
counter_2= 0;
TotalCount_2= 0;
}
lastrst_cnt = currentrst_cnt;
}//-----End Settings-----//

//----Start Counter------//
if(RelayState == HIGH){ // Only counts while relay is HIGH
if (lastsensor_pulse== LOW && currentsensor_pulse == HIGH){
counter_2 = counter_2 + 1;
}
}
lastsensor_pulse = currentsensor_pulse;

//-------Counter function-----//
if(counter_2 == cal_2){
TotalCount_2 = TotalCount_2 + 1;
counter_2 = 0; //Counter reset
}

lcd.setCursor(3, 0); //Show set point
lcd.print(set_point_2);
lcd.setCursor(4, 1); // Show counter
lcd.print(TotalCount_2);

//--Stop Counter.You can´t start if set point is lower or equal to counter--//
if(RelayState==HIGH){
if(set_point_2 <= TotalCount_2){
RelayState = LOW;
digitalWrite(Relay, LOW);
//*****************************Autoreset
lcd.setCursor(4, 1); // Clear CNT area
lcd.print(" ");
counter_2= 0;
TotalCount_2= 0;
}
}

}//End unit state HIGH (L)




}//End Void Loop



عرض أوقات الصلاة على الشاشة باستخدام الاردوينو

مقدمة

في هذا الدرس ستتعلم كيف تعرض أوقات الصلاة على شاشة Oled باستخدام الاردوينو.arduino-smart-prayer-times-display

المواد والأدوات

أوقات الصلاة

1× اردوينو اونو

أوقات الصلاة

1× سلك الاردوينو

أوقات الصلاة

 حزمة أسلاك توصيل (ذكر- ذكر)

arduino-smart-prayer-times-display

1× وحدة الوقت الحقيقي (RTC)

arduino-smart-prayer-times-display

1× شاشة (OLED)


arduino-smart-prayer-times-display

لوحة تجارب حجم وسط

توصيل الدائرة

للمزيد حول الشاشة (OLED) يمكنك الرجوع للدرس  شاشة عرض (OLED) Display.

وللمزيد حول وحدة الوقت الحقيقي يمكنك الرجوع للدرس استخدام DS3231 RTC Module مع الاردوينو.arduino-smart-prayer-times-display

الكود البرمجي

بالبداية عليك تحميل المكتبات التالية.

 Streaming.h  و “mainroutines.h” و <U8g2lib.h>

اقرأ شرح الكود البرمجي قبل رفع الكود البرمجي إلى لوحة الاردوينو.

#include <Wire.h>
#include <RTClib.h>
#include <Streaming.h>
#include <SoftwareSerial.h>
#include <U8g2lib.h>
#include "mainroutines.h"

const unsigned int text1_y0=30, text2_y0=60, text2_x1=0, text2_x2=58;
char text1[8], text2[6], todaydate[9];
int displaypage=0;
const uint8_t BTTX = 3;
const uint8_t BTRX = 2;
int quartsec, OldDay, OldMinute, OldSecond, dayMinutes, NextSalat;
int i;
DateTime now;
char time[9];

U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA); 
SoftwareSerial BTSerial(BTRX, BTTX);

struct FLAGS {
unsigned Recalcule : 1;
unsigned CheckTime : 1;
unsigned seconde : 1;
unsigned SeqAthan : 1;
unsigned Toggles : 1;
unsigned demiseconde: 1;
unsigned heures : 1;
unsigned displayPageTog : 1;
};
struct FLAGS Flags;

void setup()
{
Serial.begin(115200);
BTSerial.begin(9600);
BTSerial.listen();
u8g2.begin();
u8g2.setFont(u8g2_font_logisoso24_tr);
u8g2.setFontMode(0);


u8g2.firstPage();
do {
u8g2.drawUTF8(0,text1_y0,"SalatTime");
u8g2.drawUTF8(0,text2_y0,"L. Baghli");
} 
while ( u8g2.nextPage() );

Wire.begin();
rtc.begin();
if (! rtc.isrunning()) {
Serial.println(F("RTC NOT running!"));
rtc.adjust(DateTime(2021,8, 24, 16,8, 0));
}

Serial.flush();
STinit();
Flags.Recalcule=1;
Flags.heures=0;
Flags.CheckTime=0;
Flags.displayPageTog=0;
cli();
TCCR1A = 0;
TCCR1B = (0<<WGM13) | (1<<WGM12) | 4;
OCR1A = 15625;
TIMSK1 = 1<<OCIE1A;
TIFR1 = 0;
TCNT1 = 0;
sei();
}
void CheckTime()
{
now = rtc.now();
Flags.Toggles = !Flags.Toggles;
if (OldSecond != now.second()) {
if (++displaypage>5) displaypage=0;
OldSecond = now.second();
Serial << now.day() << F("/")<< now.month() << F("/")<<now.year()
<< F(" ")<< now.hour() << F(":")<<now.minute() << F(":")<<now.second() << endl;
}
if (OldDay != now.day()) Flags.Recalcule = 1;
if ((OldMinute != now.minute()) && (Flags.Recalcule == 0))
{
if ((SalatT.m[NextSalat]==now.minute()) && (SalatT.h[NextSalat]==now.hour()))
{// Athan
Flags.SeqAthan = 1;
}
else Flags.SeqAthan = 0;
OldMinute = now.minute();
dayMinutes = now.hour()*60+now.minute();
for (i=4; i>=0; i--)
if (SalatT.h[i]*60 + SalatT.m[i] >= dayMinutes)
{
NextSalat = i;
Serial << F("SalatT.m[")<< i <<F("] =") << SalatT.m[i] << endl;
}
}
}
void MaJRTC(int * dt)
{
if ((dt[0]<1) || (dt[0]>31)) return;
if ((dt[1]<1) || (dt[1]>12)) return;
if ((dt[2]<2000) || (dt[2]>2099)) return;
if ((dt[3]<0) || (dt[3]>23)) return;
if ((dt[4]<0) || (dt[4]>59)) return;
if ((dt[5]<0) || (dt[5]>59)) return;
rtc.adjust(DateTime(dt[2], dt[1], dt[0], dt[3], dt[4], dt[5]));
}
ISR(TIMER1_COMPA_vect) {
if (Flags.SeqAthan)
{
Flags.Toggles = !Flags.Toggles;
}
if (++quartsec == 4) quartsec = 0;
Flags.CheckTime = 1; // check time chaque 1/4 seconde
Flags.displayPageTog = 1; // page affichée chaque 1/4 seconde
if (quartsec == 0) {
Flags.seconde = 1;
}
}
void DisplayPages()
{
switch(displaypage)
{
case 0: sprintf( text1, "Fajr");
sprintf( text2, "%02hhu:%02hhu", SalatT.h[0],SalatT.m[0] );
break;
case 1: sprintf( text1, "Duhr");
sprintf( text2, "%02hhu:%02hhu", SalatT.h[1],SalatT.m[1] );
break;
case 2: sprintf( text1, "Asr");
sprintf( text2, "%02hhu:%02hhu", SalatT.h[2],SalatT.m[2] );
break;
case 3: sprintf( text1, "Mgrb");
sprintf( text2, "%02hhu:%02hhu", SalatT.h[3],SalatT.m[3] );
break;
case 4: sprintf( text1, "Isha");
sprintf( text2, "%02hhu:%02hhu", SalatT.h[4],SalatT.m[4] );
break;
for (int i=0; i<8; i++) text1[i] = todaydate[i];
sprintf( text2, "");
break;
}
sprintf( time, "%02hhu:%02hhu:%02hhu", now.hour(), now.minute(), now.second() );
u8g2.firstPage();
do {
u8g2.drawUTF8(0,text1_y0,time);
u8g2.drawUTF8(text2_x1,text2_y0, text1);
u8g2.drawUTF8(text2_x2,text2_y0, text2);
} while ( u8g2.nextPage() );
}
void loop()
{
if (Flags.CheckTime) {
CheckTime();
Flags.CheckTime = 0;
}
if (Flags.Recalcule) {
ComputeSalatTime();
OldDay = now.day();
sprintf( todaydate, "%02hhu/%02hhu/%02hhu", now.day(),now.month(),now.year()%100 );
todaydate[8]=0;
OldMinute = 61;
OldSecond = 61;
Flags.Recalcule = 0;
}
if (Flags.displayPageTog) {
DisplayPages();
Flags.displayPageTog = 0;
}
}

شرح الكود البرمجي

هنا تم استدعاء المكتبات التي سنستخدمها لعرض أوقات الصلاة على الشاشة.

#include <Wire.h>
#include <RTClib.h>
#include <Streaming.h>
#include <SoftwareSerial.h>
#include <U8g2lib.h>
#include "mainroutines.h"

هنا يتم تعريف المتغيرات التي سنستخدمها لتخزين النص الذي سينطبع على الشاشة.

char text1[8], text2[6], todaydate[9];

ربط المنافذ في الشاشة OLED بحيث يكون المنفذ SCL مع المنفذ SCL الموجود في وحدة الوقت والمنفذ SDA مع المنفذ SDA في وحدة الوقت.

U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA);

يتم تقسيم الجهد 5V BTTX يحمل القيمة 3 و BTRX يحمل القيمة 2.

const uint8_t BTTX = 3;
const uint8_t BTRX = 2;

في الدالة ()setup يتم تهيئة الشاشة استعدادًا لطباعة الوقت وحساب أوقات الصلاة.

void setup()
{
Serial.begin(115200);
BTSerial.begin(9600);
BTSerial.listen();
u8g2.begin();
u8g2.setFont(u8g2_font_logisoso24_tr);
u8g2.setFontMode(0);
u8g2.firstPage();
do {
u8g2.drawUTF8(0,text1_y0,"SalatTime");
u8g2.drawUTF8(0,text2_y0,"L. Baghli");
} 
while ( u8g2.nextPage() );
Wire.begin();
rtc.begin();
if (! rtc.isrunning()) {
Serial.println(F("RTC NOT running!"));
rtc.adjust(DateTime(2021,8, 24, 16,8, 0));
}

 هذا السطر لابد من تعديله حسب التاريخ والوقت الحالي لديك و كتابة الوقت بالثواني و الدقائق و الساعة ، و التاريخ اليوم و الشهر والسنة

rtc.adjust(DateTime(2021,8, 24, 16,8, 0));  

هنا يتم تهيئة المتغيرات التي تستخدم لحساب أوقات الصلاة.

STinit();
Flags.Recalcule=1;
Flags.heures=0;
Flags.CheckTime=0;
Flags.displayPageTog=0;

في الدالة ()CheckTime يتم حساب الوقت وطباعته على الشاشة كل ثانية.

void CheckTime()
{
now = rtc.now();
Flags.Toggles = !Flags.Toggles;
if (OldSecond != now.second()) {
if (++displaypage>5) displaypage=0;
OldSecond = now.second();
Serial << now.day() << F("/")<< now.month() << F("/")<<now.year()
<< F(" ")<< now.hour() << F(":")<<now.minute() << F(":")<<now.second() << endl;
}
if (OldDay != now.day()) Flags.Recalcule = 1;
if ((OldMinute != now.minute()) && (Flags.Recalcule == 0))
{
if ((SalatT.m[NextSalat]==now.minute()) && (SalatT.h[NextSalat]==now.hour()))
{
Flags.SeqAthan = 1;
}
else Flags.SeqAthan = 0;
OldMinute = now.minute();
dayMinutes = now.hour()*60+now.minute();
for (i=4; i>=0; i--)
if (SalatT.h[i]*60 + SalatT.m[i] >= dayMinutes)
{
NextSalat = i;
Serial << F("SalatT.m[")<< i <<F("] =") << SalatT.m[i] << endl;
}
}
}

هنا يتم برمجة وحدة الوقت بحيث الساعات باليوم تكون 24 والدقائق 60 دقيقة للساعة و60 ثانية بالدقيقة.

void MaJRTC(int * dt)
{
if ((dt[0]<1) || (dt[0]>31)) return;
if ((dt[1]<1) || (dt[1]>12)) return;
if ((dt[2]<2000) || (dt[2]>2099)) return;
if ((dt[3]<0) || (dt[3]>23)) return;
if ((dt[4]<0) || (dt[4]>59)) return;
if ((dt[5]<0) || (dt[5]>59)) return;
rtc.adjust(DateTime(dt[2], dt[1], dt[0], dt[3], dt[4], dt[5]));
}
ISR(TIMER1_COMPA_vect) 
{
if (Flags.SeqAthan)
{
Flags.Toggles = !Flags.Toggles;
}
if (++quartsec == 4) quartsec = 0;
Flags.CheckTime = 1; 
Flags.displayPageTog = 1; 
if (quartsec == 0) {
Flags.seconde = 1;
}
}

هنا سيتم برمجة الشاشة لتحتوي على ست شاشات مختلفة في المحتوى.

الأولى: عرض موعد صلاة الفجر.

الثانية: عرض موعد صلاة الظهر.

الثالثة: عرض موعد صلاة العصر.

الرابعة: عرض صلاة المغرب.

الخامسة: عرض صلاة العشاء.

السادسة: عرض تاريخ اليوم.

void DisplayPages()
{
switch(displaypage)
{
case 0: sprintf( text1, "Fajr");
sprintf( text2, "%02hhu:%02hhu", SalatT.h[0],SalatT.m[0] );
break;
case 1: sprintf( text1, "Duhr");
sprintf( text2, "%02hhu:%02hhu", SalatT.h[1],SalatT.m[1] );
break;
case 2: sprintf( text1, "Asr");
sprintf( text2, "%02hhu:%02hhu", SalatT.h[2],SalatT.m[2] );
break;
case 3: sprintf( text1, "Mgrb");
sprintf( text2, "%02hhu:%02hhu", SalatT.h[3],SalatT.m[3] );
break;
case 4: sprintf( text1, "Isha");
sprintf( text2, "%02hhu:%02hhu", SalatT.h[4],SalatT.m[4] );
break;
for (int i=0; i<8; i++) text1[i] = todaydate[i];
sprintf( text2, "");
break;
}
sprintf( time, "%02hhu:%02hhu:%02hhu", now.hour(), now.minute(), now.second() );
u8g2.firstPage();
do {
u8g2.drawUTF8(0,text1_y0,time);
u8g2.drawUTF8(text2_x1,text2_y0, text1);
u8g2.drawUTF8(text2_x2,text2_y0, text2);
} while ( u8g2.nextPage() );
}

في الدالة ()loop سيتم تحديث الوقت وموعد الصلاة والتاريخ بشكل مستمر.

void loop()
{
if (Flags.CheckTime) {
CheckTime();
Flags.CheckTime = 0;
}
if (Flags.Recalcule) {
ComputeSalatTime();
OldDay = now.day();
sprintf( todaydate, "%02hhu/%02hhu/%02hhu", now.day(),now.month(),now.year()%100 );
todaydate[8]=0;
OldMinute = 61;
OldSecond = 61;
Flags.Recalcule = 0;
}
if (Flags.displayPageTog) {
DisplayPages();
Flags.displayPageTog = 0;
}
}

حمّل الملفات التالية التي تحتوي على الدوال المهمة؛ لحساب أوقات الصلاة بناء على موقعك الجغرافي.

mainroutines.cpp

و

mainroutines.h

انقر على Add File أضف الملفات اللذان قمت بتحميلهما.arduino-smart-prayer-times-displayبعد إضافتهما يمكنك التعديل عليهما اذهب إلى الملف mainroutines.cpp.

حرر الأسطر التالية لكي تناسب منطقة السكن لديك.

ادخل على هذا الرابط وضع منطقة السكن لديك (استخدم نسخة Expert).

عدّل []CountryName و []TownName و TimeZoneTown و Convention  و DST بناء على البيانات التي عرضها.

استخدم هذا الرابط لعرض خريطة منطقة السكن لديك.

انسخ وعدل قيم latitude و longitude الموجودة في الكود البرمجي.

في هذا الدرس استخدمنا البيانات الخاصة بمدينة الرياض.

/** change your town */
	const char CountryName[] PROGMEM =  "Arabie Saoudite";
	const char TownName[] PROGMEM = ""Ar Riyad";
	const double latitude = 24.6498255*deg2rd;
	const double longitude = 46.7687988*deg2rd;
	const int TimeZoneTown = 3;
	const int Convention =  5;
	const int DST = 0;

بعد تعديل الكود البرمجي يمكنك رفع الكود إلى لوحة الاردوينو.

يمكنك اختبار صحة خطواتك.

 لا تنسَ فصل مصدر الطاقة بعد الانتهاء من استخدام النظام.




لعبة الرماية باستخدام الاردوينو

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

لعبة الرماية باستحدام الاردوينو

 

المواد والأدوات

اردوينو

X1 اردوينو

Full-size-breadboard-830-2-640x480

X1 لوحة تجارب 

شاشة عرض 7 مقاطع - 4أرقام

X1 سبعة مقاطع 4-أرقام

أسلاك توصيل

مجموعة أسلاك توصيل(M/M)

10 ohm resistors

X4 مقاومة 10 كيلو أوم 

مفتاح

X1 ضغاط التحكم 

لعبة الرماية باستحدام الاردوينو

X1 سلك أردوينو

زنبرك

X10 زنبرك

وحدة سبع مقاطع – أربع ارقام

تستخدم وحدات العرض في كثير من المشاريع التي تتطلب عرض معلومات رقمية مثل درجة الحرارة، والوقت. يوجد شاشات عرض مكونة من 7 وحدات لتشكل رقم واحد تحتوي على 10 دبابيس، 7 منها للقطاعات، وواحد للنقطة، و2 دبابيس لمصدر الطاقة إما GND أو VCC حسب نوع الشاشة – قطب موجب مشترك Common Anode أو قطب سالب مشترك Common Cathode-
من ناحية أخرى، لا تحتوي الشاشة المكونة من 4 أرقام على 40 دبوس، بل تحتوي على 12 دبوس فقط: 7 للمقاطع وواحد للنقطة ودبابيس اختيار مكونة من 4 أرقام تحدد الرقم الذي سيكون نشطًا لعرض الحرف الذي أرسله Arduino على دبابيس قطعة 7 + 1.
يتم ترتيب المقاطع السبعة بطريقتين: إما أن يتم تجميع كل قطب سالب في دبوس واحد (GND)، وهذا النوع يسمى سالب مشترك Common Cathode، أو يتم تجميع كل قطب موجب في دبوس واحد (Vcc)، وهذا النوع يسمى قطب موجب مشترك Common Anode. وبالمثل، فإن الأجزاء المكونة من 7 أرقام والمكونة من 4 أرقام هي إما قطب موجب مشترك Common Anode أو قطب سالب مشترك Common Cathode، وبالتالي توجد أربعة دبابيس مشتركة للأرقام الأربعة.

لعبة الرماية باستحدام الاردوينو

لعبة الرماية باستحدام الاردوينو

توصيل الدائرة

 

لعبة الرماية باستحدام الاردوينو

نهاية أطراف الأسلاك يتم توصيلها مع الحلقات في الهيكل بحيث تكون أصغر حلقة موصله مع A 0  والتي تليها مع A1  والأخيرة مع A2

الهيكل

فكرة المشروع وضع ثلاث حلقات مكونه من مادة موصلة على قاعدة، كل حلقة متصلة مع خط الطاقة 5 فولت بالاردوينو، تنفصل عنها 3 حلقات باستخدام الزنبرك موصلة مع منافذ الأردوينو

  إذا استطاع اللاعب إصابة الهدف تتلامس الحلقات ويتم حساب النقاط ومن ثم عرضها على شاشة السبع وحدات أربع أرقام

في هذا الشكل يظهر توزيع الزنبركات والحلقات المتصلة على القاعدة الأساسية

لعبة الرماية باستحدام الاردوينو

اذا كنت تمتلك طابعة ثلاثية الأبعاد قم بطباعة أداة القوس و السهم التي ستستخدمها لتصويب الأهداف من خلال الرابط

 

الكود البرمجي

#define aPin 2 
#define bPin 1 
#define cPin 4 
#define dPin 5 
#define ePin 6 
#define fPin 7 
#define gPin 8 

#define c1Pin 9 // Common pin for digit 1
#define c2Pin 10 // Common pin for digit 2
#define c3Pin 11 // Common pin for digit 3
#define c4Pin 12 // Common pin for digit 4

#define c1 A0
#define c2 A1
#define c3 A2
#define bt_reset A3
long Counter=0;
int flag1=0, flag2=0, flag3=0, timer=0;
int Common = 0; //<Common=1; for Common anode> <Common=0; for Common cathode>
int On, Off, Off_C; 
int DTime = 4; // Display timer

void setup(){ // put your setup code here, to run once

pinMode(c1, INPUT);
pinMode(c2, INPUT);
pinMode(c3, INPUT);
pinMode(bt_reset, INPUT);

pinMode(aPin, OUTPUT);
pinMode(bPin, OUTPUT);
pinMode(cPin, OUTPUT);
pinMode(dPin, OUTPUT);
pinMode(ePin, OUTPUT); 
pinMode(fPin, OUTPUT);
pinMode(gPin, OUTPUT);
pinMode(c1Pin, OUTPUT);
pinMode(c2Pin, OUTPUT);
pinMode(c3Pin, OUTPUT);
pinMode(c4Pin, OUTPUT);


if(Common==1){On=0, Off=1, Off_C=0;} //for Common anode
else{On=1, Off=0, Off_C=1;} //for Common cathode

// Indicate that system is ready
for (int i = 9; i >=0; i--) {
showNumber(i);
digitalWrite(c1Pin, Common);
digitalWrite(c2Pin, Common);
digitalWrite(c3Pin, Common);
digitalWrite(c4Pin, Common);
delay(1000); 
} 
}

void loop(){

if(digitalRead (c1) == 1){
if(flag1==0){ flag1=1;
Counter = Counter+30;
if(Counter>9999){Counter=0;} 
}}
else{flag1=0;}

if(digitalRead (c2) == 1){ 
if(flag2==0){ flag2=1;
Counter = Counter+20;
if(Counter<0){Counter=9999;} 
} 
}else{flag2=0;}
if(digitalRead (c3) == 1){ 
if(flag2==0){ flag2=1;
Counter = Counter+10;
if(Counter<0){Counter=9999;} 
} 
}else{flag3=0;}

if(digitalRead (bt_reset) == 1){ 
Counter=0;
if(timer<200){timer=timer+1;}
if(timer==200){

} 
}else{timer=0;}


showNumber((Counter/1000)%10);
digitalWrite(c1Pin, Common);
delay(DTime);
digitalWrite(c1Pin, Off_C);

showNumber((Counter/100)%10);
digitalWrite(c2Pin, Common);
delay(DTime);
digitalWrite(c2Pin, Off_C);

showNumber((Counter/10)%10);
digitalWrite(c3Pin, Common);
delay(DTime);
digitalWrite(c3Pin, Off_C);

showNumber(Counter%10);
digitalWrite(c4Pin, Common);
delay(DTime);
digitalWrite(c4Pin, Off_C);

}


void showNumber(int x){

switch(x){
case 1: one(); break;
case 2: two(); break;
case 3: three(); break;
case 4: four(); break;
case 5: five(); break;
case 6: six(); break;
case 7: seven(); break;
case 8: eight(); break;
case 9: nine(); break;
default: zero(); break;
}
}

void one(){
digitalWrite( aPin, Off); // 
digitalWrite( bPin, On); // |
digitalWrite( cPin, On); // |
digitalWrite( dPin, Off); // |
digitalWrite( ePin, Off); // |
digitalWrite( fPin, Off);
digitalWrite( gPin, Off);
}

void two(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // | 
digitalWrite( cPin, Off); // ____|
digitalWrite( dPin, On); // | 
digitalWrite( ePin, On); // |____
digitalWrite( fPin, Off);
digitalWrite( gPin, On);
}

void three(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // |
digitalWrite( cPin, On); // ____|
digitalWrite( dPin, On); // |
digitalWrite( ePin, Off); // ____|
digitalWrite( fPin, Off); 
digitalWrite( gPin, On);
}

void four(){
digitalWrite( aPin, Off); // 
digitalWrite( bPin, On); // | |
digitalWrite( cPin, On); // |____|
digitalWrite( dPin, Off); // |
digitalWrite( ePin, Off); // |
digitalWrite( fPin, On);
digitalWrite( gPin, On);
}

void five(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, Off); // |
digitalWrite( cPin, On); // |____
digitalWrite( dPin, On); // |
digitalWrite( ePin, Off); // ____|
digitalWrite( fPin, On); 
digitalWrite( gPin, On);
}

void six(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, Off); // |
digitalWrite( cPin, On); // |____
digitalWrite( dPin, On); // | |
digitalWrite( ePin, On); // |____|
digitalWrite( fPin, On);
digitalWrite( gPin, On);
}

void seven(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // |
digitalWrite( cPin, On); // |
digitalWrite( dPin, Off); // |
digitalWrite( ePin, Off); // |
digitalWrite( fPin, Off);
digitalWrite( gPin, Off);
}

void eight(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // | |
digitalWrite( cPin, On); // |____|
digitalWrite( dPin, On); // | |
digitalWrite( ePin, On); // |____|
digitalWrite( fPin, On); 
digitalWrite( gPin, On); 
}

void nine(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // | |
digitalWrite( cPin, On); // |____|
digitalWrite( dPin, On); // |
digitalWrite( ePin, Off); // ____|
digitalWrite( fPin, On); 
digitalWrite( gPin, On);
}

void zero(){ 
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // | |
digitalWrite( cPin, On); // | |
digitalWrite( dPin, On); // | |
digitalWrite( ePin, On); // |____|
digitalWrite( fPin, On); 
digitalWrite( gPin, Off); 
}

 شرح الكود البرمجي

نعرف منافذ شاشة السبع مقاطع اربع أرقام

#define aPin 2
#define bPin 1
#define cPin 4
#define dPin 5
#define ePin 6
#define fPin 7
#define gPin 8
#define c1Pin 9 // Common pin for digit 1
#define c2Pin 10 // Common pin for digit 2
#define c3Pin 11 // Common pin for digit 3
#define c4Pin 12 // Common pin for digit 4

نعرف الخطوط الثلاثة الخاسة بحلقات هدف الرماية

#define c1 A0
#define c2 A1
#define c3 A2

نعرف زر تصفير حساب النقط

#define bt_reset A3

نعرف متغير لحساب النقاط باسم counter

long Counter=0;

نعرف متغير باسم common نعطيه قيمة 1 اذا كان شاشة السبع مقاطع اربع أرقاب ذات قطب موجب مشترك و 0 اذا كانت ذات قطب سابي مشترك

int flag1=0, flag2=0, flag3=0, timer=0;
int Common = 0; //<Common=1; for Common anode> <Common=0; for Common cathode>
int On, Off, Off_C;
int DTime = 4; // Display timer

في دالة void setup نعرف منافذ الدخل والخرج

void setup(){ // put your setup code here, to run once

pinMode(c1, INPUT);
pinMode(c2, INPUT);
pinMode(c3, INPUT);
pinMode(bt_reset, INPUT);

pinMode(aPin, OUTPUT);
pinMode(bPin, OUTPUT);
pinMode(cPin, OUTPUT);
pinMode(dPin, OUTPUT);
pinMode(ePin, OUTPUT);
pinMode(fPin, OUTPUT);
pinMode(gPin, OUTPUT);
pinMode(c1Pin, OUTPUT);
pinMode(c2Pin, OUTPUT);
pinMode(c3Pin, OUTPUT);
pinMode(c4Pin, OUTPUT);


if(Common==1){On=0, Off=1, Off_C=0;} //for Common anode
else{On=1, Off=0, Off_C=1;} //for Common cathode

في بداية تشغيل البرنامج و للتأكد من أن جميع وحدات شاشة العرض في جميع الأرقام تعمل بشكل صحيح يتم اظهار عد تنازلي على الشاشة من 9 الى 0 على كل رقم

for (int i = 9; i >=0; i--) {
showNumber(i);
digitalWrite(c1Pin, Common);
digitalWrite(c2Pin, Common);
digitalWrite(c3Pin, Common);
digitalWrite(c4Pin, Common);
delay(1000);
}
}

في بداية دالة voide loop نحدد الشرط اذا قرأ الأردوينو المنفذ الخاص بالدائرة الداخلية على أنه 1 يتم اضافة قيمة 30 نقطة لمتغير النقاط counter

void loop(){

if(digitalRead (c1) == 1){
if(flag1==0){ flag1=1;
Counter = Counter+30;
if(Counter>9999){Counter=0;}
}}
else{flag1=0;}

اذا قرأ الأردوينو اشارة 1 من المنفذ A1 سيتم اضافة 20 نقطة

if(digitalRead (c2) == 1){
if(flag2==0){ flag2=1;
Counter = Counter+20;
if(Counter<0){Counter=9999;}
}

اذا قرأ الأردوينو اشارة 1 من المنفذ A2 سيتم اضافة 10 نقطة

}else{flag2=0;}
if(digitalRead (c3) == 1){
if(flag2==0){ flag2=1;
Counter = Counter+10;
if(Counter<0){Counter=9999;}
}
}else{flag3=0;}

اذا قرأ الأردوينو اشارة 1 من المنفذ A3 تصفير عداد النقاط أي عند الضغط على ضغاط التحكم

if(digitalRead (bt_reset) == 1){
Counter=0;
if(timer<200){timer=timer+1;}
if(timer==200){

}
}else{timer=0;}

الدوال التالية لتعريف الأرقام من 0- 9


void one(){
digitalWrite( aPin, Off); //
digitalWrite( bPin, On); // |
digitalWrite( cPin, On); // |
digitalWrite( dPin, Off); // |
digitalWrite( ePin, Off); // |
digitalWrite( fPin, Off);
digitalWrite( gPin, Off);
}

void two(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // |
digitalWrite( cPin, Off); // ____|
digitalWrite( dPin, On); // |
digitalWrite( ePin, On); // |____
digitalWrite( fPin, Off);
digitalWrite( gPin, On);
}

void three(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // |
digitalWrite( cPin, On); // ____|
digitalWrite( dPin, On); // |
digitalWrite( ePin, Off); // ____|
digitalWrite( fPin, Off);
digitalWrite( gPin, On);
}

void four(){
digitalWrite( aPin, Off); //
digitalWrite( bPin, On); // | |
digitalWrite( cPin, On); // |____|
digitalWrite( dPin, Off); // |
digitalWrite( ePin, Off); // |
digitalWrite( fPin, On);
digitalWrite( gPin, On);
}

void five(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, Off); // |
digitalWrite( cPin, On); // |____
digitalWrite( dPin, On); // |
digitalWrite( ePin, Off); // ____|
digitalWrite( fPin, On);
digitalWrite( gPin, On);
}

void six(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, Off); // |
digitalWrite( cPin, On); // |____
digitalWrite( dPin, On); // | |
digitalWrite( ePin, On); // |____|
digitalWrite( fPin, On);
digitalWrite( gPin, On);
}

void seven(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // |
digitalWrite( cPin, On); // |
digitalWrite( dPin, Off); // |
digitalWrite( ePin, Off); // |
digitalWrite( fPin, Off);
digitalWrite( gPin, Off);
}

void eight(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // | |
digitalWrite( cPin, On); // |____|
digitalWrite( dPin, On); // | |
digitalWrite( ePin, On); // |____|
digitalWrite( fPin, On);
digitalWrite( gPin, On);
}

void nine(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // | |
digitalWrite( cPin, On); // |____|
digitalWrite( dPin, On); // |
digitalWrite( ePin, Off); // ____|
digitalWrite( fPin, On);
digitalWrite( gPin, On);
}

void zero(){
digitalWrite( aPin, On); // ____
digitalWrite( bPin, On); // | |
digitalWrite( cPin, On); // | |
digitalWrite( dPin, On); // | |
digitalWrite( ePin, On); // |____|
digitalWrite( fPin, On);
digitalWrite( gPin, Off);
}