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

مقدمة

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

الدرج المضيء

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

الاردوينو يستخدم في حساس الغاز/ الدخان

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

arduino-smoke-gas-sensor

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

 

arduino-stair-lighting

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

arduino-stair-lighting

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

الدرج المضيء

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

 

يمكنك اختيار 11 ثنائي مشع للضوء حسب الألوان التي تريديها وحسب حاجة مشروعك:

 

arduino-stair-lighting

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

arduino-stair-lighting

ثنائي مشع للضوء أبيض (LED)

الدرج المضيء

ثنائي مشع للضوء أزرق (LED)

الدرج المضيءثنائي مشع للضوء أخضر (LED)

الدرج المضيء

11×  مقاومة 220 Ω

حساس الحركة

الدرج المضيء

1× هيكل درج

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

للمزيد حول حساس الحركة يمكنك الرجوع للدرس حساس الحركة (PIR Sensor).

الدرج المضيء

الهيكل

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

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

الدرج المضيء

تم تثبيت الدائرة الكهربائية بشكل محكم خلف القالب الفليني.

الدرج المضيء

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

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

const int led1 = 1;
const int led2 = 2;
const int led3 = 3;
const int led4 = 4;
const int led5 = 5;
const int led6 = 6;
const int led7 = 7;
const int led8 = 8;
const int led9 = 9;
const int led10 = 10;
const int led11 = 11;

int PIRsensor1 = 13;
int PIRsensor2 = 12;


int val1 = 0;
int val2 = 0;



void setup()
{
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
pinMode(led6, OUTPUT);
pinMode(led7, OUTPUT);
pinMode(led8, OUTPUT);
pinMode(led9, OUTPUT);
pinMode(led10, OUTPUT);
pinMode(led11, OUTPUT);

pinMode(PIRsensor1, INPUT);
pinMode(PIRsensor2, INPUT);
}
void loop()
{
val1 = digitalRead(PIRsensor1);
val2 = digitalRead(PIRsensor2);
if (val1 == HIGH)
{
digitalWrite(led1, HIGH); 
delay(500); 
digitalWrite(led2, HIGH);
delay(500);
digitalWrite(led3, HIGH); 
delay(500); 
digitalWrite(led4, HIGH); 
delay(500); 
digitalWrite(led5, HIGH); 
delay(500); 
digitalWrite(led6, HIGH); 
delay(500); 
digitalWrite(led7, HIGH); 
delay(500); 
digitalWrite(led8, HIGH); 
delay(500); 
digitalWrite(led9, HIGH); 
delay(500);
digitalWrite(led10, HIGH);
delay(500); 
digitalWrite(led11, HIGH); 
delay(500);
digitalWrite(led1, LOW);
delay(500);
digitalWrite(led2, LOW);
delay(500);
digitalWrite(led3, LOW);
delay(500);
digitalWrite(led4, LOW);
delay(500);
digitalWrite(led5, LOW);
delay(500);
digitalWrite(led6, LOW);
delay(500);
digitalWrite(led7, LOW); 
delay(500);
digitalWrite(led8, LOW);
delay(500);
digitalWrite(led9, LOW);
delay(500);
digitalWrite(led10, LOW);
delay(500);
digitalWrite(led11, LOW); 
delay(200);
}

if (val2 == HIGH)
{
digitalWrite(led11, HIGH); 
delay(500); 
digitalWrite(led10, HIGH); 
delay(500); 
digitalWrite(led9, HIGH); 
delay(500); 
digitalWrite(led8, HIGH); 
delay(500);
digitalWrite(led7, HIGH); 
delay(500);
digitalWrite(led6, HIGH);
delay(500); 
digitalWrite(led5, HIGH); 
delay(500); 
digitalWrite(led4, HIGH); 
delay(500); 
digitalWrite(led3, HIGH); 
delay(500); 
digitalWrite(led2, HIGH); 
delay(500); 
digitalWrite(led1, HIGH); 
delay(500); 
digitalWrite(led11, LOW);
delay(500); 
digitalWrite(led10, LOW);
delay(500); 
digitalWrite(led9, LOW);
delay(500); 
digitalWrite(led8, LOW); 
delay(500); 
digitalWrite(led7, LOW);
delay(500); 
digitalWrite(led6, LOW);
delay(500); 
digitalWrite(led5, LOW);
delay(500); 
digitalWrite(led4, LOW); 
delay(500); 
digitalWrite(led3, LOW);
delay(500); 
digitalWrite(led2, LOW);
delay(500); 
digitalWrite(led1, LOW);
delay(200);
}
else
{
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
digitalWrite(led5, LOW);
digitalWrite(led6, LOW);
digitalWrite(led7, LOW);
digitalWrite(led8, LOW);
digitalWrite(led9, LOW);
digitalWrite(led10, LOW);
digitalWrite(led11, LOW);
}
}

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

في البداية عرفنا المتغيرات التي سنستخدمها لتخزين قيم الثنائي المشع للضوء.

const int led1 = 1;
const int led2 = 2;
const int led3 = 3;
const int led4 = 4;
const int led5 = 5;
const int led6 = 6;
const int led7 = 7;
const int led8 = 8;
const int led9 = 9;
const int led10 = 10;
const int led11 = 11;

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

int PIRsensor1 = 13;
int PIRsensor2 = 12;

المتغيرين val1 و val2 سيحملون القيمة الابتدائية وهي صفر لحساسي الحركة.

int val1 = 0;
int val2 = 0;

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

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

void setup()
{
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
pinMode(led6, OUTPUT);
pinMode(led7, OUTPUT);
pinMode(led8, OUTPUT);
pinMode(led9, OUTPUT);
pinMode(led10, OUTPUT);
pinMode(led11, OUTPUT);

pinMode(PIRsensor1, INPUT);
pinMode(PIRsensor2, INPUT);
}

في الدالة ()loop ستتم قراءة قيم كلا حساسي الحركة.

إذا كان هناك حركة في الحساس الأول (الدرج أسفل الدرج) ستبدأ الإضاءة بالعمل بشكل متناوب وزمن إيقاف بينهم مدته نصف ثانية,

void loop()
{
val1 = digitalRead(PIRsensor1);
val2 = digitalRead(PIRsensor2);
if (val1 == HIGH)
{
digitalWrite(led1, HIGH); 
delay(500); 
digitalWrite(led2, HIGH);
delay(500);
digitalWrite(led3, HIGH); 
delay(500); 
digitalWrite(led4, HIGH); 
delay(500); 
digitalWrite(led5, HIGH); 
delay(500); 
digitalWrite(led6, HIGH); 
delay(500); 
digitalWrite(led7, HIGH); 
delay(500); 
digitalWrite(led8, HIGH); 
delay(500); 
digitalWrite(led9, HIGH); 
delay(500);
digitalWrite(led10, HIGH);
delay(500); 
digitalWrite(led11, HIGH); 
delay(500);
digitalWrite(led1, LOW);
delay(500);
digitalWrite(led2, LOW);
delay(500);
digitalWrite(led3, LOW);
delay(500);
digitalWrite(led4, LOW);
delay(500);
digitalWrite(led5, LOW);
delay(500);
digitalWrite(led6, LOW);
delay(500);
digitalWrite(led7, LOW); 
delay(500);
digitalWrite(led8, LOW);
delay(500);
digitalWrite(led9, LOW);
delay(500);
digitalWrite(led10, LOW);
delay(500);
digitalWrite(led11, LOW); 
delay(200);
}

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

if (val2 == HIGH)
{
digitalWrite(led11, HIGH); 
delay(500); 
digitalWrite(led10, HIGH); 
delay(500); 
digitalWrite(led9, HIGH); 
delay(500); 
digitalWrite(led8, HIGH); 
delay(500);
digitalWrite(led7, HIGH); 
delay(500);
digitalWrite(led6, HIGH);
delay(500); 
digitalWrite(led5, HIGH); 
delay(500); 
digitalWrite(led4, HIGH); 
delay(500); 
digitalWrite(led3, HIGH); 
delay(500); 
digitalWrite(led2, HIGH); 
delay(500); 
digitalWrite(led1, HIGH); 
delay(500); 
digitalWrite(led11, LOW);
delay(500); 
digitalWrite(led10, LOW);
delay(500); 
digitalWrite(led9, LOW);
delay(500); 
digitalWrite(led8, LOW); 
delay(500); 
digitalWrite(led7, LOW);
delay(500); 
digitalWrite(led6, LOW);
delay(500); 
digitalWrite(led5, LOW);
delay(500); 
digitalWrite(led4, LOW); 
delay(500); 
digitalWrite(led3, LOW);
delay(500); 
digitalWrite(led2, LOW);
delay(500); 
digitalWrite(led1, LOW);
delay(200);
}

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

else
{
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
digitalWrite(led5, LOW);
digitalWrite(led6, LOW);
digitalWrite(led7, LOW);
digitalWrite(led8, LOW);
digitalWrite(led9, LOW);
digitalWrite(led10, LOW);
digitalWrite(led11, LOW);
}

يمكنك اختبار مشروع الدرج المضيء بعد رفع الكود البرمجي.

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




نظام أمان باستخدام الأردوينو ووحدة الاتصال اللاسلكي (SIM800l)

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

SMS و وحدة SIM800l

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

اردوينو

X1 اردوينو 

SIM800l

X1 وحدة SIM800L

PIR SENSOR

X1 حساس الحركة

DC TO DC

X1 منظم جهد (DC TO DC)

Half-size Breadboard

X1 لوحة تجارب 

سلك يو اس بى A-B

X1سلك اردوينو 

اسلاك

 اسلاك توصيل(M/M) 

اسلاك

أسلاك توصيل (M/F)

 


وحدة SIM800L

 SIM800l

وحدة الاتصال اللاسلكي (SIM800L) تساعدك في مراقبة المنزل عن بعد أو تنشيط أي نظام داخل منزلك بمكالمة أو رسائل SMS عبارة عن مودم (GSM) مصغر فيمكن استخدامها لإجراء مهام ارسال أو استقبال الرسائل النصية القصيرة، إجراء مكالمات هاتفية أو استقبالها، الاتصال بالإنترنت من خلال (GPRS) و (TCP / IP)، يمكن استخدامها في عدد كبير من مشاريع إنترنت الأشياء. تحتاج أن تضيف شريحة 2G SIM في منفذ الشريحة لتتمكن من برمجته مع المتحكم حسب متطلبات مشروعك

مؤشر الوميض:

يوجد مؤشر الوميض أعلى الجانب الأيمن على وحدة الاتصال اللاسلكي (SIM800L) يشير إلى حالة شبكتك الخلوية. سيومض بمعدلات مختلفة لإظهار حالة الاتصال بالشبكة:

وميض كل ثانية :الوحدة قيد التشغيل ولكنها لم تتصل بالشبكة الخلوية.

SMS و وحدة SIM800l

وميض كل ثانيتين: تم تنشيط بيانات (GPRS)

SMS و وحدة SIM800l

وميض كل ثلاثة ثواني : اتصلت الوحدة بالشبكة الخلوية ويمكنها إرسال / استقبال الاتصال والرسائل القصيرة

منافذ وحدة الاتصال اللاسلكي (SIM800l)

SIM800l

الجدول التالي يوضح وظائف المنافذ

المنفذ في وحدة (SIM 800L) الوظيفة
NET منفذ للحام الهوائي الحلزوني المزود مع الوحدة .
VCC منفذ الطاقة للوحدة. من 3.4 فولت إلى 4.4 فولت. و 2أمبير عدم تزويد الوحدة بالطاقة بشكل كافي سيتسبب في عدم عملها بشكل صحيح
RST (Reset) RST (إعادة الضبط). سحب الدبوس LOW لمدة 100 مللي ثانية لإجراء إعادة تعيين ثابت.
RxD (Receiver) منفذ للاتصال التسلسلي
TxD (Transmitter) منفذ للاتصال التسلسلي
GND GND
RING دبوس مؤشر. يعطي اشارة HIGH افتراضيًا وسينبض LOW لمدة 120 مللي ثانية عند تلقي مكالمة. يمكن أيضًا تهيئته للنبض عند تلقي رسالة نصية قصيرة.
DTR لإلغاء وتنشيط وضع السكون حسب الاشارة التي يتم ارسالها له. إشارة HIGH تفعيل وضع السكون، وبالتالي تعطيل الاتصال التسلسلي. اشارة LOW تعطيل وضع السكون وتشغيل الوحدة.
MIC± مدخل المايكرفون
SPK± مدخل مكبر الصوت

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

قبل توصيل الدائرة عليك التأكد من أن خرج منظم الجهد (DC TO DC buck converter) يساوي 4.4 قد يتسبب زيادة الجهد إلى تلف وحدة الاتصال اللاسلكي (SIM800l)

SIM800l

البرمجة

برمجة هذا المشروع تحتاج إلى كتابة الشفرة البرمجية بلغة (C++)على بيئة التطوير المتكاملة للأردوينو Arduino IDE)) يمكن التعرف على البرنامج أكثر من خلال الرابط

أولا: عليك تحميل مكتبة (SoftwareSerial)

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

#include <SoftwareSerial.h>
SoftwareSerial mySerial(3, 2);
int p=7;
void setup()
{ 
pinMode(p, INPUT);
mySerial.begin(9600);
delay(1000);
}
void loop()
{int buttonState = digitalRead(7);
if (buttonState == HIGH) {
delay(1000);
mySerial.println("AT");
delay(500);
mySerial.println("AT+CMGF=1");
delay(500);
mySerial.println("AT+CMGS=\"+966XXXXXXXX\"\r");
delay(500);
mySerial.print("Warning! Motion detected!");
delay(500);
mySerial.write(26);}}

شرح الشفرة البرمجية (Code)

استدعاء مكتبة (SoftwareSerial)

 #include <SoftwareSerial.h>

تعريف منافذ الأردوينو التي تم توصيلها مع منافذ الارسال والاستقبال للاتصال التسلسلي (TX-RX) في وحدة الاتصال اللاسلكي (SIM800l) حيث تم توصيل المنفذ الرقمي 3 مع منفذ الاستقبال (RX) والمنفذ الرقمي 2 مع منفذ الارسال(TX)

 SoftwareSerial mySerial(3, 2);

تعريف منافذ الأردوينو الذي تم توصيل منفذ الخرج (Out) في حساس الحركة وهو المنفذ رقم 7

int p=7;

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

كذلك نقوم بتهيئة الاتصال التسلسلي

 
void setup()
{ 
pinMode(p, INPUT);
mySerial.begin(9600);
delay(1000);
}

في دالة void loop () سنعرف متغير يخزن داخله حالة حساس الحركة التي ستم قرأتها من المنفذ رقم 7
ثم نكتب الجملة الشرطية التي تجعل البرنامج ينتظر لمدة ثانية إذا كانت توجد حركة

 void loop()
{int buttonState = digitalRead(7);
if (buttonState == HIGH) {
delay(1000);

تحدد بروتوكولات ارتباط الاتصال في بداية الاتصال

mySerial.println("AT");
delay(500);

التشغيل على وضع نص SMS

mySerial.println("AT+CMGF=1");
delay(500);

تحديد الرقم الذي سيتم ارسال الرساله له

 
mySerial.println("AT+CMGS=\"+9665XXXXXX\"\r");
delay(500);

نص الرسالة الذي سيتم ارسالها في حال وجود حركة

 
mySerial.print("Warning! Motion detected!");
delay(500);
mySerial.write(26);}}

 




اصنع إضاءة للقراءة بدرجات سطوع مختلفة

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

desk-lamp

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

اردوينو

x1اردوينو

حساس اللمس إضاءة تتحكم بسطوعها

x1حساس اللمس

ليدات 10 ملم

x4  LED

مقاومة 220

x1 مقاومة 220 أوم

أسلاك توصيل

مجموعة أسلاك توصيل (ذكر / أنثى)

اسلاك إضاءة تتحكم بسطوعها

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

سلك اردوينو

X1 سلك أردوينو 

لوحة تجارب

X1 لوحة التجارب

خيوط طباعة

خيوط طباعة 

اكليريك

أكليريك 3*50*30

آلة تفريز

ألة تفريز

hf-spindle-500/

HF Spindle 500W

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

قم بتوصيل القطع الالكترونية (حساس اللمس و الليدات )مع الاردوينو كما هو موضح

إضاءة تتحكم بسطوعها


البرمجة

ارفع الكود البرمجي الذي يساعدك في صنع إضاءة تتحكم بسطوعها

#define touch 4
int p=0;
void setup() 
{
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(9, OUTPUT);
}
void loop()
{
int Value = digitalRead(touch);

if (Value == HIGH)

{
p++;
delay(200);
} 
if(p==1){
analogWrite(3,255);
analogWrite(5,255);
analogWrite(6,255);
analogWrite(9,255);
if(p==2){
analogWrite(3,100);
analogWrite(5,100);
analogWrite(6,100);
analogWrite(9,100);
}
if(p==3){
analogWrite(3,0);
analogWrite(5,0);
analogWrite(6,0);
analogWrite(9,0);}
p=0;
}
}

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

نعرف حساس اللمس باسم (touch )الموصل مع المنفذ الرقمي 4

#define touch 4

نعرف متغير بقيمة ابتدائية =0 يمثل عدد المرات التي يتم النقر على الحساس فيها

 
int p=0;

في دالة (void setup) نعرف المنافذ الرقمية المتصلة مع الليدات (3و5و6و9) على أنها مخارج

 
void setup() 
{
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(9, OUTPUT);
}

في دالة (void loop) بدأ بتعريف متغير ()و الذي يمثل قراءة المنفذ رقم 4

void loop()
{
int Value = digitalRead(touch);

جملة شرطية في كل مرة يتم النقر على الحساس تزداد قيمة p بواحد يعني يحسب نقرة واحدة

 
if (Value == HIGH)

{
p++;
delay(200);
}

استخدمنا منافذ تعديل عرض النبضة الرقمية (PWM) للحصول على نتائج تناظرية ستتحكم في سطوع الإضاءة. تكون النتيجة كما لو كانت الإشارة عبارة عن جهد ثابت بين 0 و5 فولت يتحكم في سطوع الليدات، نمثل ذلك بالقيم من 0 – 255
النقرة الأولى تشغل الليدات على أعلى سطوع (255)

 
if(p==1){
analogWrite(3,255);
analogWrite(5,255);
analogWrite(6,255);
analogWrite(9,255);}

النقرة الثانية يقل السطوع

 
if(p==2){
analogWrite(3,100);
analogWrite(5,100);
analogWrite(6,100);
analogWrite(9,100);
}

النقرة الثالثة يتم ايقاف تشغيل الليدات

 
if(p==3){
analogWrite(3,0);
analogWrite(5,0);
analogWrite(6,0);
analogWrite(9,0);

و نعيد قيمة المتغير p إلى 0

 
p=0;
}
}

الهيكل

اعتمدنا في تصميم الهيكل على جزئين الأول تم طباعته بطابعة ثلاثية الأبعاد و هو الجزء الخاص بتثبيت الليدات عليه و الجزء الثاني بآلة التفريز و الذي يتكون من ذراع و غطاء الأردوينو  يمكن تحميل ملفات الهيكل من خلال الرابط 

إضاءة تتحكم بسطوعها

إضاءة تتحكم بسطوعها




اصنع آلة حاسبة بنفسك باستخدام الاردوينو ولوحة المفاتيح

مقدمة

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

arduino-calculatorv

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

آلة حاسبة

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

آلة حاسبة

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

آلة حاسبة

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

 

آلة حاسبة

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

تحديد مستوى الماء

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

arduino-calculator

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

arduino-calculator

1× لوحة مفاتيح

شفرة

1× 40 رأس دبوس

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

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

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

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

آلة حاسبة

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

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


#include <LiquidCrystal.h> 
#include <Keypad.h> 

const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns

// Define the Keymap
char keys[ROWS][COLS] = {

  {'1','2','3','A'},

  {'4','5','6','B'},

  {'1','2','3','C'},

  {'*','0','#','D'}

};

byte rowPins[ROWS] = { 0, 1, 2, 3 };// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte colPins[COLS] = { 4, 5, 6, 7 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.

Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); //  Create the Keypad

const int rs = 8, en = 9, d4 = 10, d5 = 11, d6 = 12, d7 = 13; //Pins to which LCD is connected
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

 long Num1,Num2,Number;
 char key,action;
 boolean result = false;
 
void setup() {
  lcd.begin(16, 2); //We are using a 16*2 LCD display
  lcd.print("DIY Calculator"); //Display a intro message


   delay(2000); //Wait for display to show info
    lcd.clear(); //Then clean it
}

void loop() {
  
key = kpd.getKey(); //storing pressed key value in a char

if (key!=NO_KEY)
DetectButtons();

if (result==true)
CalculateResult();

DisplayResult();   
}

void DetectButtons()
{ 
     lcd.clear(); //Then clean it
    if (key=='*') //If cancel Button is pressed
    {Serial.println ("Button Cancel"); Number=Num1=Num2=0; result=false;}
    
     if (key == '1') //If Button 1 is pressed
    {Serial.println ("Button 1"); 
    if (Number==0)
    Number=1;
    else
    Number = (Number*10) + 1; //Pressed twice
    }
    
     if (key == '4') //If Button 4 is pressed
    {Serial.println ("Button 4"); 
    if (Number==0)
    Number=4;
    else
    Number = (Number*10) + 4; //Pressed twice
    }
    
     if (key == '7') //If Button 7 is pressed
    {Serial.println ("Button 7");
    if (Number==0)
    Number=7;
    else
    Number = (Number*10) + 7; //Pressed twice
    } 
  

    if (key == '0')
    {Serial.println ("Button 0"); //Button 0 is Pressed
    if (Number==0)
    Number=0;
    else
    Number = (Number*10) + 0; //Pressed twice
    }
    
     if (key == '2') //Button 2 is Pressed
    {Serial.println ("Button 2"); 
     if (Number==0)
    Number=2;
    else
    Number = (Number*10) + 2; //Pressed twice
    }
    
     if (key == '5')
    {Serial.println ("Button 5"); 
     if (Number==0)
    Number=5;
    else
    Number = (Number*10) + 5; //Pressed twice
    }
    
     if (key == '8')
    {Serial.println ("Button 8"); 
     if (Number==0)
    Number=8;
    else
    Number = (Number*10) + 8; //Pressed twice
    }   
  

    if (key == '#')
    {Serial.println ("Button Equal"); 
    Num2=Number;
    result = true;
    }
    
     if (key == '3')
    {Serial.println ("Button 3"); 
     if (Number==0)
    Number=3;
    else
    Number = (Number*10) + 3; //Pressed twice
    }
    
     if (key == '6')
    {Serial.println ("Button 6"); 
    if (Number==0)
    Number=6;
    else
    Number = (Number*10) + 6; //Pressed twice
    }
    
     if (key == '9')
    {Serial.println ("Button 9");
    if (Number==0)
    Number=9;
    else
    Number = (Number*10) + 9; //Pressed twice
    }  

      if (key == 'A' || key == 'B' || key == 'C' || key == 'D') //Detecting Buttons on Column 4
  {
    Num1 = Number;    
    Number =0;
    if (key == 'A')
    {Serial.println ("Addition"); action = '+';}
     if (key == 'B')
    {Serial.println ("Subtraction"); action = '-'; }
     if (key == 'C')
    {Serial.println ("Multiplication"); action = '*';}
     if (key == 'D')
    {Serial.println ("Devesion"); action = '/';}  

    delay(100);
  }
  
}

void CalculateResult()
{
  if (action=='+')
    Number = Num1+Num2;

  if (action=='-')
    Number = Num1-Num2;

  if (action=='*')
    Number = Num1*Num2;

  if (action=='/')
    Number = Num1/Num2; 
}

void DisplayResult()
{
  lcd.setCursor(0, 0);   // set the cursor to column 0, line 1
  lcd.print(Num1); lcd.print(action); lcd.print(Num2); 
  
  if (result==true)
  {lcd.print(" ="); lcd.print(Number);} //Display the result
  
  lcd.setCursor(0, 1);   // set the cursor to column 0, line 1
  lcd.print(Number); //Display the result
}

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

هنا استدعينا المكتبات التي سنحتاجها مثل مكتبة الشاشة الكرستالية <LiquidCrystal.h> ومكتبة لوحة المفاتيح <Keypad.h>.

نستطيع تحميل مكتبة الشاشة الكرستالية بتتبع المسار التالي:

Sketch > Include libraries > Manage libraries

ثم نكتب بخانة البحث Liquid crystal by Arduino

ثم نضغط على Install.

ثم نحمل مكتبة Keypad.

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

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

Sketch > Include libraries > Add ZIP library 

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

#include <LiquidCrystal.h> 
#include <Keypad.h>

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

const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns

هنا يتم تعريف أزرار لوحة المفاتيح وهم 16 مفتاح منوعة ما بين أرقام ورموز وحروف.

// Define the Keymap
char keys[ROWS][COLS] = {

  {'1','2','3','A'},

  {'4','5','6','B'},

  {'1','2','3','C'},

  {'*','0','#','D'}

};

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

byte rowPins[ROWS] = { 0, 1, 2, 3 };// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte colPins[COLS] = { 4, 5, 6, 7 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.

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

const int rs = 8, en = 9, d4 = 10, d5 = 11, d6 = 12, d7 = 13; //Pins to which LCD is connected
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

في دالة ()setup يتم طباعة جملة ابتدائية DIY Calculator صنع آلة الحاسبة بنفسك.

بعد ذلك سيتم مسح الشاشة ()lcd.clear استعدادًا لطباعة الحسابات الرياضية.

void setup() {
  lcd.begin(16, 2); //We are using a 16*2 LCD display
  lcd.print("DIY Calculator"); //Display a intro message

   delay(2000); //Wait for display to show info
    lcd.clear(); //Then clean it
}

في الدالة ()loop يتم قراءة المدخلات للوحة المفاتيح وسيتم استدعاء الدالة ()CalculateResult لحساب العملية الرياضية.

وبعد ذلك سيتم طباعة النتيجة على الشاشة من خلال الدالة ()DisplayResult.

void loop() {
  
key = kpd.getKey(); //storing pressed key value in a char

if (key!=NO_KEY)
DetectButtons();

if (result==true)
CalculateResult();

DisplayResult();   
}

في الدالة ()DetectButtons سيتم إدخال الرقم الذي تم إدخاله من قبل المستخدم وسينطبع الرقم على الشاشة بعد ذلك عليه اختيار نوع العملية الحسابية من الرموز الموجودة على يمين لوحة التحكم.

حرف A= جمع.

حرف B= طرح.

حرف C= ضرب.

حرف D= قسمة.

ثم يقوم المستخدم بإدخال رقم آخر بعد العملية الحسابية استعدادًا لتنفيذ لعملية الرياضية.

بعد إدخال نوع العملية الحسابية انقر على الرمز # يتم تنفيذها .

إذا أردت حذف العملية السابقة يمكنك النقر على زر النجمة *.

void DetectButtons()
{ 
     lcd.clear(); //Then clean it
    if (key=='*') //If cancel Button is pressed
    {Serial.println ("Button Cancel"); Number=Num1=Num2=0; result=false;}
    
     if (key == '1') //If Button 1 is pressed
    {Serial.println ("Button 1"); 
    if (Number==0)
    Number=1;
    else
    Number = (Number*10) + 1; //Pressed twice
    }
    
     if (key == '4') //If Button 4 is pressed
    {Serial.println ("Button 4"); 
    if (Number==0)
    Number=4;
    else
    Number = (Number*10) + 4; //Pressed twice
    }
    
     if (key == '7') //If Button 7 is pressed
    {Serial.println ("Button 7");
    if (Number==0)
    Number=7;
    else
    Number = (Number*10) + 7; //Pressed twice
    } 
  

    if (key == '0')
    {Serial.println ("Button 0"); //Button 0 is Pressed
    if (Number==0)
    Number=0;
    else
    Number = (Number*10) + 0; //Pressed twice
    }
    
     if (key == '2') //Button 2 is Pressed
    {Serial.println ("Button 2"); 
     if (Number==0)
    Number=2;
    else
    Number = (Number*10) + 2; //Pressed twice
    }
    
     if (key == '5')
    {Serial.println ("Button 5"); 
     if (Number==0)
    Number=5;
    else
    Number = (Number*10) + 5; //Pressed twice
    }
    
     if (key == '8')
    {Serial.println ("Button 8"); 
     if (Number==0)
    Number=8;
    else
    Number = (Number*10) + 8; //Pressed twice
    }   
  

    if (key == '#')
    {Serial.println ("Button Equal"); 
    Num2=Number;
    result = true;
    }
    
     if (key == '3')
    {Serial.println ("Button 3"); 
     if (Number==0)
    Number=3;
    else
    Number = (Number*10) + 3; //Pressed twice
    }
    
     if (key == '6')
    {Serial.println ("Button 6"); 
    if (Number==0)
    Number=6;
    else
    Number = (Number*10) + 6; //Pressed twice
    }
    
     if (key == '9')
    {Serial.println ("Button 9");
    if (Number==0)
    Number=9;
    else
    Number = (Number*10) + 9; //Pressed twice
    }  

      if (key == 'A' || key == 'B' || key == 'C' || key == 'D') //Detecting Buttons on Column 4
  {
    Num1 = Number;    
    Number =0;
    if (key == 'A')
    {Serial.println ("Addition"); action = '+';}
     if (key == 'B')
    {Serial.println ("Subtraction"); action = '-'; }
     if (key == 'C')
    {Serial.println ("Multiplication"); action = '*';}
     if (key == 'D')
    {Serial.println ("Devesion"); action = '/';}  

    delay(100);
  }
  
}

في دالة ()CalculateResult سيتم تنفيذ العملية الرياضية المدخلة من قبل المستخدم.

void CalculateResult()
{
  if (action=='+')
    Number = Num1+Num2;

  if (action=='-')
    Number = Num1-Num2;

  if (action=='*')
    Number = Num1*Num2;

  if (action=='/')
    Number = Num1/Num2; 
}

في الدالة ()DisplayResult سيتم عرض الأرقام المدخلة والعمية الحسابية والنتيجة.

void DisplayResult()
{
  lcd.setCursor(0, 0);   // set the cursor to column 0, line 1
  lcd.print(Num1); lcd.print(action); lcd.print(Num2); 
  
  if (result==true)
  {lcd.print(" ="); lcd.print(Number);} //Display the result
  
  lcd.setCursor(0, 1);   // set the cursor to column 0, line 1
  lcd.print(Number); //Display the result
}

تأكد بأن آلة الحاسبة تعمل بالشكل الصحيح.

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




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

في هذا الدرس سنتعلم كيف نبرمج الاردوينو وقارئ (RFID) لصنع عربة تسوق ذكية واضافة شريحة (RFID) إلى المنتجات. و يمكن معرفة سعر المنتج مباشرة بتمريره على القارئ بالعربة، وحساب فاتورة المشتريات، وعرض البيانات على الشاشة الكريستالية (LCD) ، كما يمكن حذف المنتج بالضغط على ضغاط التحكم و تمرير المنتج على قارئ (RFID)

RFID عربة

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

اردوينو

X1اردوينو 

قارئ rfid

X 1قارئ (RFID)

LCD

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

رأس دبوس

X1 40 رأس دبوس

Full-size

X1 لوحة تجارب

سلك اردوينو

X1 سلك أردوينو

مصدر صوت

X1 مصدر صوت 

مفتاح

X1 ضغاط تحكم

arduino-smoke-gas-sensor

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

Jumper Wires Male/Male

أسلاك توصيل (ذكر/ ذكر)

مقاومة 220

X1 مقاومة 220 أوم

مقاومة

X1 مقاومة 10 كيلو اوم 

 

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

RFID-CART

تم توصيل القارئ بالأردوينو كما يلي :

قارئ RFID الأردوينو
SDA منفذ 10
SCK منفذ 13
MOSI منفذ 11
MISO منفذ 12
IRQ لا يتم توصيله
GND GND
 RST منفذ 9
 3.3v 3.3v (لاتقم بتوصيله إلى 5v)

البرمجة

أولا : قراءة البيانات من RFID tag :

قبل كتابة التعليمات البرمجية ، تحتاج إلى تحميل المكتبة الازمة لقارئ RFID من هنـا.

 وإضافة المكتبة إلى المكتبات الموجودة ببرنامج الاردوينو.  يمكن الاطلاع على طريقة تنزيل المكتبات من خلال الرابط

بعد أن تم توصيل الدائرة، انتقل إلى (File) >(Examples)>(MFRC522) >(DumpInfo)وارفع ملف البرمجة على الاردوينو

ثم قم بفتح الشاشة التسلسلية، يجب أن تظهر النافذة كالتالي :

security-access-using-rfid-reader

عند تمرير بطاقة (RFID) ستظهر كافة بيانات البطاقة على نافذة شاشة الاتصال التسلسلي

security-access-using-rfid-reader

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

ثانيًا : الكود البرمجي

#include <LiquidCrystal.h>
#include <SPI.h> 
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
String coffee = "25 13 68 33";
String tea = "4F 44 4D 29";
String water = "ED 82 B2 73";
int count = 0;
int p1=0,p2=0,p3=0; 
double total = 0;
int count_prod = 0;
void setup()

{pinMode(14, OUTPUT);
lcd.begin(16,2);
pinMode(8, INPUT);
Serial.begin(9600); // Initiate a serial communication
SPI.begin(); // Initiate SPI bus
mfrc522.PCD_Init(); // Initiate MFRC522
lcd.setCursor(0, 0);
lcd.print(" SHOPPING CART");
delay (2000);
lcd.setCursor(0, 1);
delay (2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" WELCOME TO ");
lcd.setCursor(0, 1); 
lcd.print(" OUR STORE");


}
void loop() 
{
if ( ! mfrc522.PICC_IsNewCardPresent()) 
{
return;
}

if ( ! mfrc522.PICC_ReadCardSerial()) 
{
return;
}
lcd.clear();
String content= "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++) 
{
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
content.toUpperCase();
int a=digitalRead(8);
//FIREST PRODUCT 
if (content.substring(1) == coffee && (a == 0)) 
{lcd.setCursor(0, 0);
lcd.println("Coffee15.00 SR");
tone(14,350);
delay(5);
noTone(14);
total = total + 15.00;
p1++;
lcd.setCursor(0, 1);
lcd.print("Total=");
lcd.print(total);
count_prod++;
delay (3000);
}

else if (content.substring(1) == coffee && (a == 1)) 
{
if(p1>0)
{lcd.clear();
lcd.setCursor(0, 0);
lcd.print("coffee Removed!!! ");
tone(14,350);
delay(5);
noTone(14);
total = total - 15.00;
p1--;
lcd.setCursor(0, 1);
lcd.println("Total=");
lcd.print(total);
delay (3000);
} 
else
{lcd.clear();
lcd.print("Not in cart!!! ");}}

//FIREST PRODUCT 
if (content.substring(1) == tea && (a == 0)) 
{lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tea 8 SR");
tone(14,350);

delay(5);
noTone(14);
total = total + 8.00;
p2++;
lcd.setCursor(0, 1);
lcd.print("Total=");
lcd.print(total);
count_prod++;
delay (3000);
}

else if (content.substring(1) == tea && (a == 1)) 
{if(p2>0)
{lcd.clear(); 
lcd.print("Tea Removed!!!");
tone(14,350); 
delay(5);
noTone(14);
total = total - 8.00;
p2--;
lcd.setCursor(0, 1);
lcd.println("Total=");
lcd.print(total);
delay (3000);
} 
else
{lcd.clear();
lcd.print("Not in cart!!!");
delay (3000);
}}
if (content.substring(1) == water && (a == 0)) 
{lcd.clear();
lcd.setCursor(0, 0);
lcd.print("water 2.00 SA ");
tone(14,350); 
delay(5);
noTone(14);
total = total + 2.00;
p3++;
lcd.setCursor(0, 1);
lcd.print("Total=");
lcd.print(total);
count_prod++;
delay (3000);
}

else if (content.substring(1) == water && (a == 1)) 
{
if(p3>0)
{lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Water Removed!!! ");
tone(14,350);
delay(5);
noTone(14);
total = total - 2.00;
p3--;
lcd.setCursor(0, 1);
lcd.print("Total=");
lcd.print(total);
delay (3000);
} 
else
{lcd.print("Not in cart!!! ");
delay (3000);
}}
}

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

في الأسطر التالية يتم استدعاء المكتبات التالية (LiquidCrystal-SPI-MFRC522) والتي تحتوي على أوامر برمجية مهمة لتشغيل المشروع

#include <LiquidCrystal.h>
#include <SPI.h> 
#include <MFRC522.h>

نعرف المنافذ المتصلة مع القارئ

#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.

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

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

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

 
String coffee = "25 13 68 33";
String tea = "4F 44 4D 29";
String water = "ED 82 B2 73";

نعرف متغير (count) يشر إلى عدد المنتجات التي تم شراؤها و المتغيرات (p1-p2-p3) تشير للمنتج الأول و الثاني و الثالث

 
int count = 0;
int p1=0,p2=0,p3=0; 
double total = 0;
int count_prod = 0;

في دالة (void setup)نعرف منفذ مصدر الصوت و نقوم بتهئية الشاشة ،وقارئ FRID

void setup()

{pinMode(14, OUTPUT);
lcd.begin(16,2);
pinMode(8, INPUT);
Serial.begin(9600); // Initiate a serial communication
SPI.begin(); // Initiate SPI bus
mfrc522.PCD_Init(); // Initiate MFRC522

نطبع على الشاشة عبارات ترحيبية تظهر عند بدء التشغيل فقط

lcd.setCursor(0, 0);
lcd.print(" SHOPPING CART");
delay (2000);
lcd.setCursor(0, 1);
delay (2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" WELCOME TO ");
lcd.setCursor(0, 1); 
lcd.print(" OUR STORE");

}

عند دالة (void loop) نجعل البرنامج جاهز لقراءة البطاقات

 
void loop() 
{
if ( ! mfrc522.PICC_IsNewCardPresent()) 
{
return;
}

if ( ! mfrc522.PICC_ReadCardSerial()) 
{
return;
}
lcd.clear();
String content= "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++) 
{
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
content.toUpperCase();

 

نعرف متغير خاص بالمفتاح الذي سيتم ضغطه عند حذف المنتجات فقط

int a=digitalRead(8);

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

if (content.substring(1) == coffee && (a == 0))
{lcd.setCursor(0, 0);
lcd.println("Coffee15.00 SR");
tone(14,350);
delay(5);
noTone(14);
total = total + 15.00;
p1++;
lcd.setCursor(0, 1);
lcd.print("Total=");
lcd.print(total);
count_prod++;
delay (3000);
}

عند قراءة الرمز الخاص ببطاقة القهوة مع الضغط على المفتاح يتم حذف القهوة و عرضها على الشاشة

else if (content.substring(1) == coffee && (a == 1))
{
if(p1>0)
{lcd.clear();
lcd.setCursor(0, 0);
lcd.print("coffee Removed!!! ");
tone(14,350);
delay(5);
noTone(14);
total = total - 15.00;
p1--;
lcd.setCursor(0, 1);
lcd.println("Total=");
lcd.print(total);
delay (3000);
}

 

اذا لم تكن القهوة موجودة تظهر رسالة على الشاشة أنها غير موجودة

 

else
{lcd.clear();
lcd.print("Not in cart!!! ");}}

اضافة وحذف المنتج الثاني

if (content.substring(1) == tea && (a == 0))
{lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tea 8 SR");
tone(14,350);
delay(5);
noTone(14);
total = total + 8.00;
p2++;
lcd.setCursor(0, 1);
lcd.print("Total=");
lcd.print(total);
count_prod++;
delay (3000);
}

else if (content.substring(1) == tea && (a == 1))
{if(p2>0)
{lcd.clear();
lcd.print("Tea Removed!!!");
tone(14,350);
delay(5);
noTone(14);
total = total - 8.00;
p2--;
lcd.setCursor(0, 1);
lcd.println("Total=");
lcd.print(total);
delay (3000);
}
else
{lcd.clear();
lcd.print("Not in cart!!!");
delay (3000);
}}

اضافة وحذف المنتج الثالث

if (content.substring(1) == water && (a == 0))
{lcd.clear();
lcd.setCursor(0, 0);
lcd.print("water 2.00 SA ");
tone(14,350);
delay(5);
tone(14,350);
total = total + 2.00;
p3++;
lcd.setCursor(0, 1);
lcd.print("Total=");
lcd.print(total);
count_prod++;
delay (3000);
}

else if (content.substring(1) == water && (a == 1))
{
if(p3>0)
{lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Water Removed!!! ");
tone(14,350);
delay(5);
noTone(14,350);
total = total - 2.00;
p3--;
lcd.setCursor(0, 1);
lcd.print("Total=");
lcd.print(total);
delay (3000);
}
else
{lcd.print("Not in cart!!! ");
delay (3000);
}}
}

 




اعرض صورك على الشاشة (OLED) باستخدام الاردوينو

مقدمة

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

displaying-your-own-photo-on-oled

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

 

شاشة (OLED)

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

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

displaying-your-own-photo-on-oled

تحويل الصورة إلى كود بنظام (HEX)

في البداية عليك تحويل الصورة لكود(HEX).

نظام (HEX) أو نظام العد الستة عشري سمي بذلك لأنه يحتوي على 16 (ستة عشر) رمزًا لتمثيله (كتابته)، وهم بالترتيب من الرمز الأصغر (0 – صفر) إلى الرمز الأكبر (F).

انقر على الرابط التالي: تحويل الصور إلى كود بنظام (HEX).

1- اختر الصورة  المناسبة لك.

عرض الصور على الشاشة

2. عيّن الإعدادات التالية: لابد أن يكون مقاس الصورة 128*64 حتى يتلائم مع حجم الشاشة (OLED).

يمكنك اختيار لون الخلفية المناسب لك أبيض أو أسود أو شفاف.

درجة السطوع: 184 أو حسب الدرجة المناسبة للصورة.

Scaling تتلائم مع حجم الشاشة لتملأها.

Center نختار Horizontally أي أفقيًا.

عرض الصور على الشاشة

3. Code output format اختر Arduino code.

ثم انقر على Generate code حتى يتم إنشاء الكود.

displaying-your-own-photo-on-oled

انسخ الكود البرمجي الذي داخل دالة const unsigned char epd_bitmap_Transparant_Background_Geeks__new_ [] PROGMEM = {
ستحتاج إليه في قسم الكود البرمجي.

displaying-your-own-photo-on-oled

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

حمّل مكتبة <Adafruit_SSD1306.h> و <Adafruit_GFX.h>.

قبل رفع كود عرض الصور على الشاشة (OLED) إلى لوحة الاردوينو هناك أمور مهمة عليك تحريرها بعد قراءة شرح الكود البرمجي.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define OLED_RESET 4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define LOGO_HEIGHT   64
#define LOGO_WIDTH    128

//image bitmap data 
const unsigned char logo_bmp [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xff, 0x00, 0x03, 0xf8, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xc7, 0x00, 0x03, 0x8c, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x83, 0x00, 0x03, 0x04, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x03, 0x00, 0x03, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x9f, 0x00, 0x03, 0xe4, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xff, 0x00, 0x03, 0xfc, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xff, 0x00, 0x03, 0xf8, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x0f, 0xff, 0x02, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x03, 0xf8, 0x06, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x78, 0x38, 0x0f, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x40, 0x18, 0x60, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x40, 0x18, 0x41, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0xe1, 0x0f, 0xc3, 0xf8, 0x43, 0x87, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0xc0, 0x18, 0x07, 0x81, 0x3f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x81, 0x00, 0x40, 0x18, 0x0f, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x40, 0x18, 0x07, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x81, 0x0f, 0xc3, 0xf8, 0x03, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0xe1, 0x0f, 0xc3, 0x38, 0x41, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x40, 0x08, 0x60, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x52, 0x08, 0xe0, 0x40, 0x3f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0xe2, 0x7e, 0x27, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc3, 0xe4, 0xc0, 0x67, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x44, 0x80, 0x4f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x48, 0x49, 0x94, 0xcf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x92, 0x49, 0x0c, 0x9f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x86, 0x99, 0x38, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfd, 0xac, 0x90, 0x86, 0x80, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xf9, 0x2c, 0x0d, 0xfc, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x63, 0xff, 0xf9, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
};

void setup() {
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  testdrawbitmap();    // Draw the required image 
}

void loop() {
}

void testdrawbitmap(void) {
  display.clearDisplay();

  display.drawBitmap(
    (display.width()  - LOGO_WIDTH ) / 2,
    (display.height() - LOGO_HEIGHT) / 2,
    logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
  display.display();
  delay(1000);
}

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

في هذه الأسطر يتم استدعاء المكتبات التالية: <Wire.h> و <Adafruit_GFX.h> و <Adafruit_SSD1306.h>.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

هنا حجم الشاشة والصورة المستخدمة 128*64.

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

هنا نكتب بروتوكول إعادة الضبط.

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

الصق كود (HEX) الخاص بالصورة التي قمت باختيارها هنا استخدمنا شعار وادي العباقرة.

static const uint8_t PROGMEM image_data_20190410_114707[] = {
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x07, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x0f, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xff, 0x00, 0x03, 0xf8, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xc7, 0x00, 0x03, 0x8c, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x83, 0x00, 0x03, 0x04, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x03, 0x00, 0x03, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x9f, 0x00, 0x03, 0xe4, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xff, 0x00, 0x03, 0xfc, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xff, 0x00, 0x03, 0xf8, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x0f, 0xff, 0x02, 0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x03, 0xf8, 0x06, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x78, 0x38, 0x0f, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x40, 0x18, 0x60, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x40, 0x18, 0x41, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0xe1, 0x0f, 0xc3, 0xf8, 0x43, 0x87, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0xc0, 0x18, 0x07, 0x81, 0x3f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x81, 0x00, 0x40, 0x18, 0x0f, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x40, 0x18, 0x07, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x81, 0x0f, 0xc3, 0xf8, 0x03, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0xe1, 0x0f, 0xc3, 0x38, 0x41, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x40, 0x08, 0x60, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x52, 0x08, 0xe0, 0x40, 0x3f, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0xe2, 0x7e, 0x27, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc3, 0xe4, 0xc0, 0x67, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcc, 0x44, 0x80, 0x4f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x48, 0x49, 0x94, 0xcf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x92, 0x49, 0x0c, 0x9f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x86, 0x99, 0x38, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfd, 0xac, 0x90, 0x86, 0x80, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xf9, 0x2c, 0x0d, 0xfc, 0x1f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x63, 0xff, 0xf9, 0x3f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
};

في دالة ()void setup نهيئ شاشة العرض (OLED) ثم نمسح الشاشة استعدادًا لعرض الصور والرسومات عليها تأكد من كتابة عنوان I2c لشاشة العرض.

void setup() {
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  testdrawbitmap();    // Draw the required image 
}

 دالة void loop() بدون أوامر برمجية حيث سينفذ الكود أمر التشغيل في void setup().

void loop() { }

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

تأكد بأن النظام يعمل بالشكل الصحيح.

لا تنسَ فصل وحدة الطاقة بعد الانتهاء من استخدام نظام عرض الصور على الشاشة (OLED).




تحديد مستوى الماء باستخدام الاردوينو

مقدمة

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

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

تحديد مستوى الماء

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

تحديد مستوى الماء

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

arduino-smoke-gas-sensor

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

arduino-water-level-sensor

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

تحديد مستوى الماء

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

تحديد مستوى الماء

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

تحديد مستوى الماء

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

تحديد مستوى الماء

حساس مستوى الماء

شفرة

1× 40 رأس دبوس

حساس مستوى الماء

يحتوي حساس مستوى الماء على سلسلة من عشرة خطوط نحاسية مكشوفة، خمسة منها خطوط كهربائية وخمس خطوط استشعارية.

هذه الخطوط متشابكة بحيث يكون هناك خط إحساس واحد بين كل خطين للطاقة.

عادةً ما تكون هذه الخطوط غير متصلة ولكن يتم تغطيتها بالماء عند غمرها فيه.

نظام لقياس مستوى الماء

له 3 مداخل موضحة في الشكل التالي:

تحديد مستوى الماء

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

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

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

نظام لقياس مستوى الماء

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

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

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int resval = 0; // holds the value
int respin = A5; // sensor pin used

void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("WATER LEVEL: ");
}
void loop() {
// set the cursor to column 0, line 1
lcd.setCursor(0, 1);

resval = analogRead(respin); //Read data from analog pin and store it to resval variable

if (resval<=20)
{
lcd.println("Empty ");
}
else if (resval>20 && resval<=350)
{
lcd.println("Low ");
}
else if (resval>350 && resval<=400)
{ lcd.println("Medium ");
}
else if (resval>400){
lcd.println("High ");
}
delay(1000);
}

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

هذا السطر يستدعي مكتبة الشاشة الكرستالية.

نستطيع تحميلها بتتبع المسار التالي:

Sketch > Include libraries > Manage libraries

ثم نكتب بخانة البحث Liquid crystal by Arduino

ثم نضغط على Install.

#include <LiquidCrystal.h>

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

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

عرفنا المتغير resval عند قيمة ابتدائية تساوي صفر وعرفنا المتغير respin يمثل قيمة قراءة المدخل التناظري A5.

int resval = 0; // holds the value
int respin = A5; // sensor pin used

في دالة ()setup، التي ستبدأ عند بدء التشغيل، تتم تهيئة الشاشة وتشغيل الإضاءة الخلفية وطباعة النص “WATER LEVEL: “.

void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("WATER LEVEL: ");
}

في الدالة ()loop، سيتم حساب كمية الماء المحيطة بحساس مستوى الماء.

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

إذا كانت بين 20 و350 سينطبع على الشاشة مستوى الماء منخفض.

إذا كانت أكبر من 350 وأقل من 400 سينطبع على الشاشة مستوى الماء متوسط.

إذا كانت أكبر من 400 سينطبع على الشاشة مستوى الماء مرتفع.

void loop() {
// set the cursor to column 0, line 1
lcd.setCursor(0, 1);

resval = analogRead(respin); //Read data from analog pin and store it to resval variable

if (resval<=20)
{
lcd.println("Empty ");
}
else if (resval>20 && resval<=350)
{
lcd.println("Low ");
}
else if (resval>350 && resval<=400)
{ lcd.println("Medium ");
}
else if (resval>400){
lcd.println("High ");
}
delay(1000);
}

يمكنك اختبار نظام تحديد مستوى الماء.

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




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

مقدمة

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

منقلة رقمية

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

arduino-digital-protractor-mpu6050

اردوينو اونو

منقلة رقمية

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

منقلة رقمية

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

arduino-digital-protractor-mpu6050

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

منقلة رقمية

حساس الحركة والتسارع في ثلاث اتجاهات

arduino-smoke-gas-sensor

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

الشاشة تستخدم في مع الاردوينو وحساس الغاز/ الدخان

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

arduino-smoke-gas-sensor

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

منقلة رقمية

محرك سيرفو

شفرة

1× 40 رأس دبوس

حساس الحركة والتسارع في ثلاث اتجاهات

حساس التسارع والحركة مصمم لقياس أبسط وأدق التغيرات في معدل الحركة في ثلاث اتجاهات.

منقلة رقمية

يستخدم حساس التسارع والحركة في مجالات كثيرة، أبسط مثال هو شاشة هاتفك المحمول عند إمالة الهاتف يتغير اتجاه الشاشة إما بشكل عرضي أو بشكل طولي.

arduino-digital-protractor-mpu6050

يحتوي الحساس على 8 مداخل وهي موضحة بالشكل التالي:

منقلة رقمية

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

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

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

منقلة رقمية

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

#include <Servo.h>                 //Include Servo Motor library for using Servo 
#include <LiquidCrystal.h>         //Include LCD library for using LCD 
#include <Wire.h>                  //Include WIre library for using I2C 
LiquidCrystal lcd(2,3,4,5,6,7);   //Define LCD display pins RS,E,D4,D5,D6,D7
const int MPU_addr=0x68;         //I2C MPU6050 Address
Servo myservo;                  //myservo object for class servo 
int16_t axis_X,axis_Y,axis_Z;    
int minVal=265;
int maxVal=402; double x;
double y; double z; int pos = 0;   void setup() {   Wire.begin();                        //Begins I2C communication
  Wire.beginTransmission(MPU_addr);    //Begins Transmission with MPU6050
  Wire.write(0x6B);                    //Puts MPU6050 in Sleep Mode   Wire.write(0);                       //Puts MPU6050 in power mode    Wire.endTransmission(true);          //Ends Trasmission myservo.attach(9);               //Servo PWM pin as 9 in UNO
  lcd.begin(16,2);                 //Sets LCD in 16X2 Mode
} void loop() {   Wire.beginTransmission(MPU_addr); //Begins I2C transmission    Wire.write(0x3B);                 //Start with register 0x3B (ACCEL_XOUT_H)         Wire.endTransmission(false);   Wire.requestFrom(MPU_addr,14,true); //Request 14 Registers from MPU6050   axis_X=Wire.read()<<8|Wire.read(); //Obtain 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    axis_Y=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_YOUT_H) & 0x3C (ACCEL_YOUT_L)
  axis_Z=Wire.read()<<8|Wire.read(); //0x3B (ACCEL_ZOUT_H) & 0x3C (ACCEL_ZOUT_L)
    int xAng = map(axis_X,minVal,maxVal,-90,90); 
    int yAng = map(axis_Y,minVal,maxVal,-90,90);
    int zAng = map(axis_Z,minVal,maxVal,-90,90);
   x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);     //Formula to calculate x values in degree
     int pos = map(x,0,180,0,180); // As X value is from 0 to 360 deg      myservo.write(pos);           // Write angle obtained 0 to 180 to servo
     lcd.setCursor(0,0);
     lcd.print("Angle");      lcd.setCursor(0,1);      lcd.print(x);                
     delay(500);
     lcd.clear();
}

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

هنا نستدعي مكتبة الشاشة الكرستالية ومكتبة Wire.h التي تحتوى على الدوال اللازمة للتواصل بين الاردوينو وحساس التسارع ومكتبة محرك السيرفو.

نستطيع تحميل مكتبة الشاشة الكرستالية بتتبع المسار التالي:

Sketch > Include libraries > Manage libraries

ثم نكتب بخانة البحث Liquid crystal by Arduino

ثم نضغط على Install.

#include <Servo.h>              
#include <LiquidCrystal.h>
#include <Wire.h>       

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

LiquidCrystal lcd(2,3,4,5,6,7);  

بعد ذلك يتم تحديد بروتوكول الاتصال التسلسلي l2c الخاص بحساس التسارع.

const int MPU_addr=0x68;   

هذا السطر يعرف myservo الخاص بمحرك السيرفو ثم يتم تعريف القيم الخاصة بحساس التسارع على ثلاثة محاور x و y و z.

Servo myservo;                
int16_t axis_X,axis_Y,axis_Z;   

يتم تحدد أقصى قيمة وأقل قيمة يقرأها الحساس بين (265-402) لقياس الزوايا من 0 إلى 360.

int minVal=265;
int maxVal=402;

في دالة ()void يبدأ الاتصال التسلسلي والنقل بين حساس التسارع والعنوان 0x68.

  Wire.begin();            
  Wire.beginTransmission(MPU_addr);  

في هذا السطر يدخل حساس التسارع في وضع السكون بعد توصيله مع العنوان 0x6B, يستأنف العمل بعد ادخال القيمة صفر.

Wire.write(0x6B);                   
Wire.write(0);     

بعد تفعيل حساس التسارع انهِ النقل.

Wire.endTransmission(true);      

محرك السيرفو تم ربطه مسبقًا مع المدخل الرقمي 9 على لوحة الاردوينو.

  myservo.attach(9);  

في دالة ()loop يستأنف الاتصال من جديد.

 Wire.beginTransmission(MPU_addr);

ويبدأ مع المسجل 0x3B (ACCEL_XOUT_H)

Wire.write(0x3B);        

يستأنف الاتصال من جديد لكن بإضافة False لكن الاتصال هنا مفعل.

Wire.endTransmission(false);

هذا السطر يطلب بيانات حساس التسارع (x و y و z) من المسجل 14.

Wire.requestFrom(MPU_addr,14,true);

بعد أخذ البيانات المسجلة لكلًا من (x و y و z) يتم تخزينها في axis_X,axis_Y,axis_Z.

 axis_X=Wire.read()<<8|Wire.read();
  axis_Y=Wire.read()<<8|Wire.read();
  axis_Z=Wire.read()<<8|Wire.read();

اجعل القيم لكل الثلاث محاور (x و y و z) بين (265-402) يتم تمثيلها كـ90 و -90

 int xAng = map(axis_X,minVal,maxVal,-90,90);
    int yAng = map(axis_Y,minVal,maxVal,-90,90);
    int zAng = map(axis_Z,minVal,maxVal,-90,90);

هنا قيمة x لحساب الزاوية من 0 – 360 نقوم بتحويل فقط قيمة x لأن دوران محرك السيرفو يعتمد عليها.

x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);    

قيمة الزاوية x التي بين 0 -360 يتم تحويلها لـ0-180.

 int pos = map(x,0,180,0,180);

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

 myservo.write(pos);         
lcd.setCursor(0,0);
lcd.print("Angle");
lcd.setCursor(0,1);
lcd.print(x);               
delay(500);
lcd.clear();

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

زاوية تقريبًا 50.منقلة رقمية

زاوية تقريبًا 3.

منقلة رقمية

 




نقل البيانات بين 2 أردوينو باستخدام الليزر

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

البيانات أردوينو باستخدام الليزر

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

اردوينو

X 2 اردوينو أونو 

سلك اردوينو

X 1 سلك أردوينو

محول طاقة

X 1 محول طاقة

لوحة تجارب

X 1 لوحة تجارب

شاشة lcd

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

X1رأس دبوس 

مقاومة 220

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

 

مرسل ليزر

X 1 مرسل ليزر 

مستقبل ليزر

X 1 مستقبل ليزر

أسلاك توصيل

أسلاك توصيل (أنثى/ذكر)

أسلاك توصيل

أسلاك توصيل (ذكر/ذكر)

 

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

دائرة المستقبل :

دائرة مستقبل البيانات

دائرة المرسل:

دائرة مرسل البيانات أردوينو باستخدام الليزر

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

البيانات أردوينو باستخدام الليزر

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

الكود البرمجي للمرسل يتم رفعه على الأردوينو الذي سيرسل البيانات

int ledPin = 13;

void setup() {                
  pinMode(ledPin, OUTPUT);     
  Serial.begin(9600);
}

void loop() {
  
  byte input;
    while (Serial.available() > 0) {
    input = Serial.read();
    
    digitalWrite(ledPin, HIGH);   
    delay(10);
    digitalWrite(ledPin, LOW);


    for (int i = 0; i < 8; i++) {
      digitalWrite(ledPin, (input & (1 << i)) >> i);
      delay(100);
    }
    digitalWrite(ledPin, LOW);
    
    delay(10);
  } 
}

الكود البرمجي للمستقبل يتم رفعه على الأردوينو الذي يستقبل بيانات

 
#define NUM_SAMPLES 10
int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor
double average;
#include <LiquidCrystal.h>   //Load Liquid Crystal Library
LiquidCrystal lcd(12, 11, 5, 6, 7, 8);

void setup() {
  lcd.begin(16,2);
  Serial.begin(9600);
  sensorValue = analogRead(sensorPin);
  average = sensorValue;
}

void loop() {
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  boolean high = false;
  high = isSignalHigh(average, sensorValue);
  if (high) {    
    byte incoming = 0;
    delay(10);
    for (int i = 0; i < 8; i++) {
    incoming |= ( isSignalHigh(average, analogRead(sensorPin)) << i);
    delay(100);
    }
    lcd.print((char)incoming); //Print measured distance
    Serial.print((char)incoming);
  }
    average = approxRollingAverage(average, sensorValue);   
}

double approxRollingAverage(double avg, double new_sample) {

  avg -= avg / NUM_SAMPLES;
  avg += new_sample / NUM_SAMPLES;

  return avg;
   
}

boolean isSignalHigh(double average, double sample) {
  if (sample - average > 10)
    return true;
  return false; 
    
}

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

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

نعرف المنفذ الذي سيتم توصيله مع مرسل أشعة الليرز به باسم (ledpin) الذي تم توصيله مع منفذ رقم 13

int ledPin = 13;

نعين المنفذ (ledpin) كمخرجات
و نفعل الاتصال التسلسلي

void setup() { 
// initialize the digital pin as an output.
pinMode(ledPin, OUTPUT); 
Serial.begin(9600);
}

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

void loop() {

byte input;

// Read character from serial
while (Serial.available() > 0) {
input = Serial.read();

 نعطي أوامر بتشغيل الليزرلارسال البيانات من أردوينو باستخدام الليزر

digitalWrite(ledPin, HIGH); 
delay(10);
digitalWrite(ledPin, LOW);

نحدد تشغيل الليد بناء على معادلة بين متغير I له قيم بين 0 و 8 و المدخلات من شاشة الاتصال التسلسلي

for (int i = 0; i < 8; i++) {
digitalWrite(ledPin, (input & (1 << i)) >> i);
delay(100);
}
digitalWrite(ledPin, LOW);

delay(10);
} 
}

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

نعرف منفذ مستقبل الليزر و منافذ شاشة الLCD

#define NUM_SAMPLES 10
int sensorPin = A0; 
int sensorValue = 0; 
double average;
#include <LiquidCrystal.h> //Load Liquid Crystal Library
LiquidCrystal lcd(12, 11, 5, 6, 7, 8);

نحدد العدد الأقصى لخانات السطر الواحد وعدد السطور الأقصى التي تسمح بها الشاشة .
و نحدد متغير باسم sensorValue للقيم التي يتم قراءتها من الحساس

void setup() {
lcd.begin(16,2);
Serial.begin(9600);
sensorValue = analogRead(sensorPin);
average = sensorValue;
}

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

void loop() {

sensorValue = analogRead(sensorPin);
boolean high = false;
high = isSignalHigh(average, sensorValue);
if (high) { 
byte incoming = 0;
delay(10);
for (int i = 0; i < 8; i++) {
incoming |= ( isSignalHigh(average, analogRead(sensorPin)) << i);
delay(100);
}
lcd.print((char)incoming); //Print measured distance
Serial.print((char)incoming);
}
average = approxRollingAverage(average, sensorValue); 
}

double approxRollingAverage(double avg, double new_sample) {

avg -= avg / NUM_SAMPLES;
avg += new_sample / NUM_SAMPLES;

return avg;

}

boolean isSignalHigh(double average, double sample) {
if (sample - average > 10)
return true;
return false; 

}



تمثيل المسافة باستخدام الاردوينو وواجهة المستخدم الرسومية

مقدمة

تستخدم واجهة المستخدم الرسومية (GUI) في مجالات كثيرة منها الطب لتمثيل تخطيط قلب المريض أو في الرياضيات لتمثيل الإحصائياتت والبيانات وغيرها من المجالات في هذا الدرس ستتعلم كيفية تمثيل المسافة باستخدام الاردوينو وواجهة المستخدم الرسومية.

تمثيل المسافة

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

تمثيل المسافة

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

تمثيل المسافة

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

arduino-python-gui-representing-distance

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

arduino-python-gui-representing-distance

حساس المسافة (HC-SR04)

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

للمزيد حول حساس الموجات فوق الصوتية يمكنك الرجوع للدرس التالي حساب المسافة بإستخدام حساس الموجات فوق صوتية

arduino-python-gui-representing-distance

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

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

ارفع الكود التالي إلى لوحة الاردوينو عن طريق (Arduino DE) وافتح شاشة الاتصال التسلسلي.

#define Trigger 2
#define Echo 3
int timetaken, dist;
int sendv;

void setup() {
 Serial.begin (9600);
  pinMode(Trigger, OUTPUT);
  pinMode(Echo, INPUT);
}
void loop() {
  timetaken=dist=0; //initialize the variable to zero before calculation

 //request the US to send a wave
  digitalWrite(Trigger, HIGH);
  digitalWrite(Trigger, LOW);

  timetaken = pulseIn(Echo, HIGH); //calculate the time taken for the wave to return
  dist = (timetaken/2) / 2.91; //formulae to calculate the distance using time taken
  if (dist <= 200 && dist > 0)//send the value to python only if it ranhes from 0-20 cm
  sendv = dist;

 Serial.println(sendv);
 delay(200);

}

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

هذه الأسطر توضح منافذ الاردوينو التي ستستخدمها لربط منافذ حساس الموجات فوق الصوتية Trigger مع المنفذ الرقمي 2 و Echo مع المنفذ الرقمي 3.

#define Trigger 2
#define Echo 3

هنا عرّفنا المتغير timetaken ويقوم بحساب الوقت اللازم لرجوع الموجه لحساس الموجات فوق البنفسجية والمتغير dist يقوم بحساب المسافة وآخر متغير هو sendv يقوم بإرسال القيمة للبايثون.

int timetaken, dist;
int sendv;

في الدالة ()setup ستتم قراءة البيانات بواسطة حساس الموجات فوق الصوتية منفذ Trigger للمدخلات ومنفذ Echo للمخرجات وستنطبع القراءة على شاشة الاتصال التسلسلي.

void setup() 
{
 Serial.begin (9600);
  pinMode(Trigger, OUTPUT);
  pinMode(Echo, INPUT);
}

في الدالة ()loop ستكون القيمة الافتراضية صفر لمتغير المسافة ومتغير الوقت اللازم. (ما لم يقوم المستخدم بتنفيذ إجراء على حساس الموجات فوق الصوتية)

void loop() {
  timetaken=dist=0; //initialize the variable to zero before calculation

بعد ذلك سيتم تحديث البيانات المقروءة من حساس الموجات فوق الصوتية عن طريق المتغير Trigger.

digitalWrite(Trigger, HIGH);
  digitalWrite(Trigger, LOW);

المتغير timetaken سيقوم بحساب الوقت اللازم لرجوع الموجه المأخوذة من الحساس عن طريق المتغير Echo.

timetaken = pulseIn(Echo, HIGH); //calculate the time taken for the wave to return

المتغير dist سيقوم بتحديث المسافة المقروءة من حساس الموجات فوق الصوتية بالاعتماد على متغير timetaken.

  dist = (timetaken/2) / 2.91; //formulae to calculate the distance using time taken

إذا كانت المسافة المقروءة أصغر من أو تساوي 200 وأكبر من 0 سيتم إرسال القيمة للبايثون. (أي بين 0-20 سم)

  if (dist <= 200 && dist > 0)//send the value to python only if it ranhes from 0-20 cm

أخيرًا ستتم طباعة المسافة على شاشة الاتصال التسلسلي.

 Serial.println(sendv);

تنصيب (python) و (Vpython)

1- تنصيب (Python IDLE)

في البداية عليك تنصيب برنامج البايثون بنسخته القديمة عليك تحميل الإصدار القديم؛ لأن برنامج  Vpython لا يدعم الإصدارات الجديدة من البايثون.

 انقر على الرابط التالي Python 2.7.0 وثبت البرنامج على جهاز الحاسوب.

حمّل نسخة 32 بت دائمًا مهما كان نظام التشغيل.

arduino-python-gui-representing-distance

افتح ملف exe الذي تم تنزيله واتبع التعليمات لا تقم بتغيير المسار الذي يتم فيه تثبيت Python.

سيكون المسار C:\Python27 بشكل افتراضي اتركه كما هو عليه.

arduino-python-gui-representing-distance

2- ضبط إعدادات لوحة الأوامر

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

علينا اضافة مترجم اوامر البايثون إلى امتدادات الأوامر – PATH environment variable.
عليك الذهاب للوحة التحكم بويندوز واتباع المسار التالي:
Control Panel\System and Security\System
اختر من القائمة Advanced system setting:

arduino-python-gui-representing-distance

انقر على Environment variable:

arduino-python-gui-representing-distance

انقر على Path من قائمة System Variables.

arduino-python-gui-representing-distance

انقر على New وأضف المسار التالي (أو المسار الذي قمت بتحميل البرنامج عليه):

C:\Python27

تمثيل المسافة

بعد اتمامك للخطوات سيكتمل تنصيب البرنامج، يمكنك التحقق من وجوده وذلك بالبحث عنه مع قائمة البرامج Python IDLE.

3- تنصيب (Pyserial)

بعد ذلك علينا تنصيب Pyserial بنسخته القديمة انقر على الرابط التالي وحمله على حاسوبك Pyserial 2.7

تمثيل المسافة

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

اختر المسار الذي قمت بتحميل برنامج البايثون عليه بعد ذلك اضغط على next.

تمثيل المسافة

4- تنصيب (Vpython)

بعد ذلك حمّل VPython إصدار 32 بت بنفس مسار برنامج البايثون.

arduino-python-gui-representing-distance

تأكد من تحميل الحزمة الكاملة Full installation.

تمثيل المسافة

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

افتح VIDLE for VPython.

اتبع المسار التالي حتى تتمكن من اختبار صحة تحميلك للبرنامج:

File ->Open ->Bounce

ثم

Run -> Run Module

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

تمثيل المسافة

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

افتح برنامج VIDLE for VPython والصق الكود البرمجي التالي وارفعه على لوحة الاردوينو عن طريق النقر على:

Run -> Run Module

from visual import *
import serial #Serial imported for Serial communication
import time #Required to use delay functions

ArduinoSerial = serial.Serial('com18',9600) #Create Serial port object called arduinoSerialData
time.sleep(2) #wait for 2 secounds for the communication to get established

obj = box(pos=(-5,0,0), size=(0.1,4,4), color=color.white)
wallL = box(pos=(-1,0,0), size=(0.2,12,12), color=color.cyan)
text(text='US sensor', axis=(0,1,0) , pos=(-2,-6,0), depth=-0.3, color=color.cyan)
t = 0
while 1:
rate(100)
t = int (ArduinoSerial.readline()) #read the serial data and print it as line
t= t* 0.05
obj.pos.x = t
print(t)

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

افتح صفحة جديدة في VIDLE for VPython وقم باستدعاء المكتبات المطلوبة visual تساعدك في انشاء نماذج ثلاثية الأبعاد, serial python لقرءة القيم من لوحة الاردوينو عن طريق المنفذ التسلسلي و time تساعدك في استخدام دوال معينة مثل delay.

from visual import *
import serial #Serial imported for Serial communication
import time #Required to use delay functions

حدد المنفذ COM المستخدم في الاتصال مع الاردوينو.
(هذا سطر قابل للتغيير بناء على نوع المنفذ الذي ستستخدمه في المشروع يمكنك تعيينه عن طريق برنامج اردوينو IDE من قائمة Port).

ArduinoSerial = serial.Serial('com18',9600) #Create Serial port object called arduinoSerialData

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

obj = box(pos=(-5,0,0), size=(0.1,4,4), color=color.white)
wallL = box(pos=(-1,0,0), size=(0.2,12,12), color=color.cyan)
text(text='US sensor', axis=(0,1,0) , pos=(-2,-6,0), depth=-0.3, color=color.cyan)
t = 0
while 1:
rate(100)
t = int (ArduinoSerial.readline()) #read the serial data and print it as line
t= t* 0.05
obj.pos.x = t
print(t)

بعد رفع الكود البرمجي سيظهر تمثيل المسافة على شكل مستطيل ثلاثي الأبعاد سماوي ثابت ومستطيل ثلاثي الأبعاد متحرك رمادي.

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

arduino-python-gui-representing-distance




اصنع سلة ذكية متعددة الأغراض باستخدام الاردوينو

مقدمة

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

سلة ذكية

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

arduino-smart-basket

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

سلة ذكية

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

arduino-smart-basket

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

سلة ذكية

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

arduino-smoke-gas-sensor

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

سلة ذكية

حساس المسافة (HC-SR04)

سلة ذكية

2× محرك سيرفو (TowerPro SG90 micro servo)

arduino-smart-basket

1× شريط لاصق ذو وجهين

سلة ذكية

1× قالب كرتوني أو فليني لإعداد هيكل السلة

(اختياري)

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

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

وللمزيد حول حساس الموجات الفوق صوتية يمكنك الرجوع للدرس التالي حساس الموجات فوق الصوتية.

arduino-smart-basket

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

بعد ذلك ثبت الدائرة على هيكل السلة باستخدام اللاصق ذو وجهين.

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

عليك تنصيب مكتبة <NewPing.h> من الرابط التالي مكتبة NewPing.

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

#include <Wire.h>
#include <NewPing.h>
#include <Servo.h>

Servo myservo1;
Servo myservo2;

#define TRIGGER_PIN_1 7
#define ECHO_PIN_1 6
#define MAX_DISTANCE 400

NewPing sonar1(TRIGGER_PIN_1,ECHO_PIN_1,MAX_DISTANCE);

float distance1;
float duration1;

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
myservo1.attach(11); // Servo pin
myservo2.attach(10); // Servo pin
}
void loop() {
// put your main code here, to run repeatedly:
duration1=sonar1.ping();
distance1=(duration1 / 2)*0.0343; Serial.println(distance1);
if(distance1 < 35){ // set the minimum distance here
myservo1.write(10);
myservo2.write(100);
delay(600);}
else{ myservo1.write(100); myservo2.write(10); } }

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

هذه الأسطر توضح المكتبات المستخدمة مكتبة <Wire.h> للتواصل بين الاردوينو وحساس الموجات فوق الصوتية ومكتبة <Servo.h> الخاصة بمحرك السيرفو وأخيرًا مكتبة <NewPing.h> الخاصة بحساس الموجات فوق الصوتية.

#include <Wire.h>
#include <NewPing.h>
#include <Servo.h>

هنا يتم تعريف المغيرات الخاصة بكلا محركي السيرفو الأول myservo1 والسيرفو الثاني myservo2.

Servo myservo1;
Servo myservo2;

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

منفذ TRIGGER مع المنفذ الرقمي 7.

ECHO مع المنفذ الرقمي 6.

#define TRIGGER_PIN_1 7
#define ECHO_PIN_1 6

المتغير MAX_DISTANCE يحمل أقصى مسافة سيكتشفها حساس المسافة (يمكنك تحرير المسافة على النحو الذي تريده).

#define MAX_DISTANCE 400

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

NewPing sonar1(TRIGGER_PIN_1,ECHO_PIN_1,MAX_DISTANCE);

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

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
myservo1.attach(11); // Servo pin
myservo2.attach(10); // Servo pin
}

في الدالة ()loop يتم قراءة المسافة بيننا وبين حساس الموجات فوق الصوتية إذا كانت أقل من 35 سيعمل كلا محركي السيرفو وتنفتح السلة الذكية وتنغلق من تلقاء نفسها بدون لمسها.

void loop() {
// put your main code here, to run repeatedly:
duration1=sonar1.ping();
distance1=(duration1 / 2)*0.0343;
Serial.println(distance1);
if(distance1 < 35){ // set the minimum distance here
myservo1.write(10);
myservo2.write(100);
delay(600);}
else{
myservo1.write(100);
myservo2.write(10);
}
}

 




اصنع فأرة الحاسوب بنفسك باستخدام الاردوينو وعصا التحكم

مقدمة

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

arduino-joystick-controlled-mouse

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

فأرة الحاسوب

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

فأرة الحاسوب

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

فأرة الحاسوب

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

فأرة الحاسوب

1×  عصا التحكم

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

للمزيد حول عصا التحكم يمكنك الرجوع للدرس التالي استخدام عصا التحكم joystick مع الاردوينو

فأرة الحاسوب

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

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

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

arduino-joystick-controlled-mouse

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

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

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

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

python -m pip install --upgrade pip

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

python –m pip install mouse

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

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

ارفع الكود التالي إلى لوحة الاردوينو عن طريق (IDE) وافتح شاشة الاتصال التسلسلي.

void setup()
{
Serial.begin(9600);
pinMode(9,INPUT); // SW pin
digitalWrite(9,HIGH);
}
int prev_state=0; // previous state of switch
void loop() {
int z=0,xpos=0,ypos=0;
int x=analogRead(A0);
int y=analogRead(A1);
int sensitivity=10; // you can adjust the sensitivity based on your comfort
if(x>=550) // when moved up
xpos=map(x,550,1023,0,sensitivity);
if(x<=450) // when moved down
xpos=map(x,450,0,0,-sensitivity);
if(y>=550) // when moved right
ypos=map(y,550,1023,0,sensitivity);
if(y<=450) // when moved left
ypos=map(y,450,0,0,-sensitivity);
int curr_state=digitalRead(9);
if(curr_state==1 && prev_state==0) // when SW is pressed
z=1;
else
z=0;
if(xpos!=0 or ypos!=0 or z==1) // prints only when the joystick is moved
{
Serial.print(xpos); // print the data and separating by ":"
Serial.print(":");
Serial.print(ypos);
Serial.print(":");
Serial.println(z);
}
prev_state=curr_state; delay(10); // for normal operation
}

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

في الدالة ()setup تتم قراءة المدخلات من عصا التحكم عن طريق المنفذ الرقمي 9 ثم تتم طباعتها على شاشة الاتصال التسلسلي.

void setup()
{
Serial.begin(9600);
pinMode(9,INPUT); // SW pin
digitalWrite(9,HIGH);
}

في دالة ()void loop يتم تعريف المتغيرات x, y و z.

تكون قيمة المحور z تساوي صفر.

وقيمة المحور x تتم قراءتها من المنفذ التناظري A0.

وقيمة المحور z تتم قراءتها من المنفذ التناظري A1.

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

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

المتغير sensitivity=10 يمثل حساسية فأرة الحاسوب يمكنك تغيير القيمة.

void loop() {
int z=0,xpos=0,ypos=0;
int x=analogRead(A0);
int y=analogRead(A1);
int sensitivity=10; // you can adjust the sensitivity based on your comfort

تمثل قراءة المدخل التناظري  X حركة الفارة على المحور x الحركة بشكل عامودي، إذا كانت قيمة المدخل x أكبر من 550 نقوم بتعيين نطاق قيم المدخل x من 0 إلى 1024 إلى نطاق من 0 إلى القيمة الموجبة ل sensitivity التي تم تحديدها.

وإذا كانت قيمة المدخل x أقل أو تساوي 450 نقوم بتعيين نطاق قيم المدخل x من 0 إلى 1024 إلى نطاق من 0 إلى القيمة السالبة ل sensitivity التي تم تحديدها.

if(x>=550) // when moved up
xpos=map(x,550,1023,0,sensitivity);
if(x<=450) // when moved down
xpos=map(x,450,0,0,-sensitivity);

تمثل قراءة المدخل التناظري y حركة الفارة على المحور y الحركة بشكل أفقي، إذا كانت قيمة المدخل y أكبر من 550 نقوم بتعيين نطاق قيم المدخل y من 0 إلى 1024 إلى نطاق من 0 إلى القيمة الموجبة ل sensitivity التي تم تحديدها.

وإذا كانت قيمة المدخل y أقل أو تساوي 450 نقوم بتعيين نطاق قيم المدخل y من 0 إلى 1024 إلى نطاق من 0 إلى القيمة السالبة ل sensitivity التي تم تحديدها.

if(y>=550) // when moved right
ypos=map(y,550,1023,0,sensitivity);
if(y<=450) // when moved left
ypos=map(y,450,0,0,-sensitivity);

متغير curr_state يمثل قراءة قيمة المدخلات الرقمية من المنفذ رقم 9 إذا كان الزر مضغوط فالقيمة الراجعة 1.

وإذا لم يتم الضغط عليه تكون القيمة صفر أي بحالة سكون.

int curr_state=digitalRead(9);
if(curr_state==1 && prev_state==0) // when SW is pressed
z=1;
else
z=0;

ستتم طباعة القيم على الشاشة الاتصال التسلسلي إذا كان هناك أي تغيّر في قراءات قيم عصا التحكم.

إذا لم يتم تحريك عصا التحكم فلن يتم طباعة أي قيم.

if(xpos!=0 or ypos!=0 or z==1) // prints only when the joystick is moved
{
Serial.print(xpos); // print the data and separating by ":"
Serial.print(":");
Serial.print(ypos);
Serial.print(":");
Serial.println(z);
}

الكود البرمجي (بايثون)

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

التحكم بالحاسوب بحركات اليد

ارفع الكود البرمجي للوحة الاردوينو من قائمة 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'))   #read the data
   (x,y,z)=data.split(":")           # assigns to x,y and z
   (X,Y)=mouse.get_position()        #read the cursor's current position
   (x,y)=(int(x),int(y))                           #convert to int
   mouse.move(X+x,Y-y)           #move cursor to desired position
   if '1' in z:                        # read the Status of SW
      mouse.click(button="left")    # clicks left button

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

افتح صفحة جديدة في 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'))   #read the data
   (x,y,z)=data.split(":")           # assigns to x,y and z
   (X,Y)=mouse.get_position()        #read the cursor's current position
   (x,y)=(int(x),int(y))                           #convert to int
mouse.move(X+x,Y-y)           #move cursor to desired position

هنا تتم قراءة القيم من المنفذ الرقمي 9 إذا كان الزر مضغوط ستكون القيمة الراجعة 1.

 if '1' in z:                        # read the Status of SW
      mouse.click(button="left")    # clicks left button