الأهداف

في النشاط التالي سوف نصنع عدّاد من 0 إلى 9.

ما يلزمنا

  • لوحة أردوينو
  • لوحة تجارب
  • 08 مقاومات 220 Ω (أحمر، أحمر، أحمر)
  • عارض ذو سبع مقاطع
  • أسلاك توصيل.

الصورة التالية تُظهر كيفية ربط العرض.

seven-segments-arduino

 

sevenseg

 

الجدول التالي يبّين المقاطع الواجب إضاءتها لإظهار الرقم المناسب من 0 إلى 9

segmenttable

إفتح واجهة التطوير و حرر نص البرنامج التالي:

//                         DP,g,f,e,d,c,b,a
const int segmentPins[8] = {2,3,4,5,6,7,8,9};
int speed = 1000;
void setup() {               
  for (int i=0; i <8; i++ ) {
  pinMode(segmentPins[i], OUTPUT);  
    }
}

void loop() {
 // 0
 digitalWrite(segmentPins[0], 1);
 digitalWrite(segmentPins[1], 1);
 digitalWrite(segmentPins[2], 1);
 digitalWrite(segmentPins[3], 1);
 digitalWrite(segmentPins[4], 1);
 digitalWrite(segmentPins[5], 1);
 digitalWrite(segmentPins[6], 0);
 delay(speed);
 // 1
 digitalWrite(segmentPins[0], 0);
 digitalWrite(segmentPins[1], 1);
 digitalWrite(segmentPins[2], 1);
 digitalWrite(segmentPins[3], 0);
 digitalWrite(segmentPins[4], 0);
 digitalWrite(segmentPins[5], 0);
 digitalWrite(segmentPins[6], 0);
 delay(speed);
  // 2
 digitalWrite(segmentPins[0], 1);
 digitalWrite(segmentPins[1], 1);
 digitalWrite(segmentPins[2], 0);
 digitalWrite(segmentPins[3], 1);
 digitalWrite(segmentPins[4], 1);
 digitalWrite(segmentPins[5], 0);
 digitalWrite(segmentPins[6], 1);
 delay(speed);
 // 3
 digitalWrite(segmentPins[0], 1);
 digitalWrite(segmentPins[1], 1);
 digitalWrite(segmentPins[2], 1);
 digitalWrite(segmentPins[3], 1);
 digitalWrite(segmentPins[4], 0);
 digitalWrite(segmentPins[5], 0);
 digitalWrite(segmentPins[6], 1);
 delay(speed);
 // 4
 digitalWrite(segmentPins[0], 0);
 digitalWrite(segmentPins[1], 1);
 digitalWrite(segmentPins[2], 1);
 digitalWrite(segmentPins[3], 0);
 digitalWrite(segmentPins[4], 0);
 digitalWrite(segmentPins[5], 1);
 digitalWrite(segmentPins[6], 1);
 delay(speed);
  // 5
 digitalWrite(segmentPins[0], 1);
 digitalWrite(segmentPins[1], 0);
 digitalWrite(segmentPins[2], 1);
 digitalWrite(segmentPins[3], 1);
 digitalWrite(segmentPins[4], 0);
 digitalWrite(segmentPins[5], 1);
 digitalWrite(segmentPins[6], 1);
 delay(speed);
  // 6
 digitalWrite(segmentPins[0], 1);
 digitalWrite(segmentPins[1], 0);
 digitalWrite(segmentPins[2], 1);
 digitalWrite(segmentPins[3], 1);
 digitalWrite(segmentPins[4], 1);
 digitalWrite(segmentPins[5], 1);
 digitalWrite(segmentPins[6], 1);
 delay(speed);
  // 7
 digitalWrite(segmentPins[0], 1);
 digitalWrite(segmentPins[1], 1);
 digitalWrite(segmentPins[2], 1);
 digitalWrite(segmentPins[3], 0);
 digitalWrite(segmentPins[4], 0);
 digitalWrite(segmentPins[5], 0);
 digitalWrite(segmentPins[6], 0);
 delay(speed);
 // 8
 digitalWrite(segmentPins[0], 1);
 digitalWrite(segmentPins[1], 1);
 digitalWrite(segmentPins[2], 1);
 digitalWrite(segmentPins[3], 1);
 digitalWrite(segmentPins[4], 1);
 digitalWrite(segmentPins[5], 1);
 digitalWrite(segmentPins[6], 1);
 delay(speed);
  // 9
 digitalWrite(segmentPins[0], 1);
 digitalWrite(segmentPins[1], 1);
 digitalWrite(segmentPins[2], 1);
 digitalWrite(segmentPins[3], 0);
 digitalWrite(segmentPins[4], 0);
 digitalWrite(segmentPins[5], 1);
 digitalWrite(segmentPins[6], 1);
 delay(speed);
 
}

قم بفحص نص البرنامج ثم إرفعه إلى اللوحة.

لقد أنجزت عداد من 0 إلى 9. بدأنا في البرنامج بتحديد المنافذ الرقمية (PIN2 – PIN9) كمخارج و قمنا بوصلها عبر مقاومات تحديد التيار بالمقاطع: a,b,c,d,e,f,g (لم نوصل مقطع نقطة الفاصلة لعدم الحاجة إليها هنا).

const int segmentPins[8] = {2,3,4,5,6,7,8,9};

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

الصفوف

هي عبارة عن تتابع عناصر من نفس النوع مرقمة بالتتابع 0، 1، 2، 3،… هذه الأرقام تسمى بالفهرس أو المؤشر و التي تحدد مكان العنصر في الصف.

إذا كان إسم الصف هو segmentPins فإن هو العنصر الأول (لاحظ أن الترقيم يبدأ من الصفر) و هو العنصر الثاني و هكذا. و عامة فإن العنصرi هو الموجود في المكان رقم i-1 .

segmentPins[0]

segmentPins[1]

تعريف الصف

int myInts[6];

int myPins[] = {2,3,8,4,6};

int mySensValue[6] = {2, 4, -8, 3, 2, 5};

char message[6] = "hello";

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

نعود إلى مشروعنا، تعريف الصف

const int segmentPins[8] = {2,3,4,5,6,7,8,9};

سُبق بالتعليمة const والتي تعني أن عناصر الصف ثابتة و لا يمكن تغييرها أثناء البرنامج.

إذن يحتوي الصف على 8 عناصر تمثل المنافذ الواجب وصلها بالمقاطع (المقاطع السبع زائد نقطة الفاصلة).

كتبنا حلقة لإعداد المنافذ كمخارج.

seg

و أخيرا كما في الجدول السابق نبدأ في إظهار الأرقام من 0 إلى 9 كما في المثال التالي.

//  0
digitalWrite(segmentPins[0], 1);
digitalWrite(segmentPins[1], 1);
digitalWrite(segmentPins[2], 1);
digitalWrite(segmentPins[3], 1);
digitalWrite(segmentPins[4], 1);
digitalWrite(segmentPins[5], 1);
digitalWrite(segmentPins[6], 0);
delay(speed);

تعمل التعليمة على تحديد سرعة العداد. قم بتغيير قيم المتغير speed و لاحظ أثر ذلك على سرعة العد.

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

const byte numeral[10] = {
//abcdefg /dp
	B11111100, // 0
	B01100000, // 1
	B11011010, // 2
	B11110010, // 3
	B01100110, // 4
	B10110110, // 5
	B00111110, // 6
	B11100000, // 7
	B11111110, // 8
	B11100110, // 9
};

// dp,g,f,e,d,c,b,a
const int segmentPins[8] = {9,8,7,6,5,4,3,2};

void setup()
{
	for(int i=0; i < 8; i++){
		pinMode(segmentPins[i], OUTPUT); 
	}
}

void loop()
{
	for(int i=0; i <= 9; i++){
		showDigit(i);
		delay(1000);
	}
}

void showDigit( int number)
{
	boolean isBitSet;
	for(int segment = 1; segment < 8; segment++){
		isBitSet = bitRead(numeral[number], segment);
		digitalWrite( segmentPins[segment], isBitSet);
	}
}

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

الصف و هو من النوع byte أي 8 بت. كل بت فيه يحمل حالة مقطع لكل عنصر من العشر عناصر(الممثلة للأرقام من 0 إلى 9): «0» مقطع منطفئ، «1» تمثل مقطع مضيئ.

const byte numeral[10]

إذن هذا الصف يحمل هيئة الأرقام التي نريد إظهارها. لاحظ أن الأعداد بصيغة البت تسبق بحرف B من كلمة Binary أي نظام ثنائي.

الدوال

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

يمكن للدوال أن تُزود بمعاملات توضع بين قوسين بعد إسم الدالة.

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

تحتوي لغة أردوينو على العديد من الدوال المعرفة مسبقا والتي إستعملنا البعض منها مثل: loop(), setup() و هي دوال لا تُعيد قيم. كما يحتوي على أخرى مثل sqrt(), sin(), cos()  و التي تُرجع قيم إذ تقوم بحساب تجب الزاوية، جب الزاوية و الجذر التربيعي على التوالي. مثلا .

a=sqrt(9);

في مشروعنا أنشأنا الدالة showDigit( int number) التي تقوم بإظهار الرقم (number) و بدورها تستعين بدالة أردوينو bitRead() والتي تُرجع لنا حالة البت في الصف numeral[] 

الصورة التالية  تشرح عمل البرنامج بإسهاب.

chap

bitRead()

تقرأ قيمة بت واحد لعدد في موضع محدد.

النص

bitRead(x,n)

x : العدد المحدد

n : موضع البت المراد قراءة قيمته.

الإرجاع

قيمة البت 0 أو 1.

 

مثال

bitRead(B11111110,0)  →  0

bitRead(B00000010,3)  →  1

 

ما تعلمناه

  • كيفية ربط العارض ذو القطع السبع.
  • التعليمة const
  • الصفوف.
  • إستعمال الدوال.
  • الدالة ()bitRead .

تمارين

  1. أعد كتابة البرنامج السابق كي يقوم بالعد في النظام الست عشري الذي يتكون من 16 رقم كما في الصورة التالية.
  2. أضف زر للتركيب السابق و أكتب برنامج يبدأ بالعد عند الضغط على الزر.
  3. أضف زر للتركيب السابق و أكتب برنامج يبدأ بالرقم 0 و يزيد واحد كلما ضغطت على الزر.

disp_all