نمایشگر سون سگمنت 4رقمی، حالت توسعه یافته نمایشگر سون سگمنت 1رقمی است که در مقاله قبل مورد بحث و بررسی قرار گرفت. درست مثل نمایشگر 1رقمی، 7عدد LED روی نمایشگر 4رقمی وجود دارد که با نامهای a،b،…g و P یا DP مشخص شدهاند. نمای پایههای ورودی و خروجی نمایشگر سون سگمنت 4رقمی در شکل 1 نشان داده شده و شمارهی رقمها از سمت چپ به ترتیب 3،2،1 و 4 است یک سون سگمنت 4 رقمی دارای یک کاتد مشترک است و نمایش یک رقم هنگامیکه پایه در وضعیت LOW است، معادل اتصال پایه مشترک به زمین در یک سون سگمنت 1 رقمی است.
سون سگمنت 4رقمی به عنوان تایمر
کد زیر اطلاعات استفاده از یک نمایشگر سون سگمنت 4رقمی را به عنوان تایمر بر حسب ثانیه ارائه میدهد. برای برنامهنویسی دو تابع مورد استفاده قرار میگیرند؛ یکی تابع ()digit که رقم مناسب را روشن میکند و دیگری تابع ()number که عدد ثانیه را به واحدهای دهتایی، صدتایی و هزارتایی تقسیم میکند. تأخیر ms5 بین نمایش اعداد مختلف از چشمک زدن جلوگیری میکند، ولی با افزایش تأخیر به ms250، الگوی نشان دادن اعداد توسط نمایشگر را به یک رقم در هر بار تغییر میدهد. در شکل2 سیمی که به رنگ زرد است، به منظور درک بهتر مدار با اتصالات معرفی شده در جدول 1 رسم شده است.
همچنین کد زیر طریقهی کنترل نمایشگر سون سگمنت چهار رقمی را نیز نشان میدهد. استفاده از شیفت رجیسترها، دستورهای تکراری برای تعیین حالت LED و دستورهای ()digitalwrite را که در همین مقاله مورد بحث قرار میگیرد برای هر رقم، کاهش میدهد.
جدول 1- طریقه اتصال پایههای نمایشگر سون سگمنت 4رقمی برای کار به عنوان تایمر
شماره پایه نمایشگر
|
متصل میشود به
|
و به
|
---|---|---|
1
|
مقاومت 220Ω
|
پایه 6 آردوینو
|
2
|
مقاومت 220Ω
|
پایه 5 آردوینو
|
3
|
|
|
4
|
مقاومت 220Ω
|
پایه 4 آردوینو
|
5
|
مقاومت 220Ω
|
پایه 8 آردوینو
|
6
|
پایه 13 آردوینو
|
|
7
|
مقاومت 220Ω
|
پایه 3 آردوینو
|
8
|
پایه 12 آردوینو
|
|
9
|
پایه 11 آردوینو
|
|
10
|
مقاومت 220Ω
|
پایه 7 آردوینو
|
11
|
مقاومت 220Ω
|
پایه 2 آردوینو
|
12
|
پایه 10 آردوینو
|
|
کد به کار گیری نمایشگر سون سگمنت 4رقمی به عنوان تایمر
int pins[] = {2,3,4,5,6,7,8}; // LED pins
int digits[] = {10,11,12,13}; // digit control pins
int zero[] = {1,1,1,1,1,1,0}; // LED states for zero
int one[] = {0,1,1,0,0,0,0}; // LED states for one
int two[] = {1,1,0,1,1,0,1};
int three[] = {1,1,1,1,0,0,1};
int four[] = {0,1,1,0,0,1,1};
int five[] = {1,0,1,1,0,1,1};
int six[] = {1,0,1,1,1,1,1};
int seven[] = {1,1,1,0,0,0,0};
int eight[] = {1,1,1,1,1,1,1};
int nine[] = {1,1,1,1,0,1,1};
int time, n;
int del = 5; // time delay (ms)
void setup()
{
// define pins and digits as output
for (int i = 0; i<7; i++) pinMode (pins[i], OUTPUT);
for (int i = 0; i<4; i++) pinMode (digits[i], OUTPUT);
}
void loop()
{
time = millis()/1000; // time is number of seconds
digit(0); // digit D1 for thousands
number(time/1000); // number to be displayed
delay(del);
digit(1); // digit D2 for hundreds
number((time%1000)/100); // modulus(time, 1000)/100
delay(del);
digit(2); // digit D3 for tens
number((time%100)/10); // modulus(time, 100)/10
delay(del);
digit(3); // digit D4 for units
number(time%10); // modulus(time, 10)
delay(del);
}
void digit(int d)
// function to set digit states
{
// turn all digits off
for (int i = 0; i<4; i++) digitalWrite(digits[i], 1);
digitalWrite(digits[d], 0); // digit pin state is LOW, display is on
}
void number(int n)
// function to display numbers
{
if
(n==0) for (int i = 0; i<7; i++)
digitalWrite(pins[i], zero[i]);
else if (n==1) for (int i = 0; i<7; i++)
digitalWrite(pins[i], one[i]);
else if (n==2) for (int i = 0; i<7; i++)
digitalWrite(pins[i], two[i]);
else if (n==3) for (int i = 0; i<7; i++)
digitalWrite(pins[i], three[i]);
else if (n==4) for (int i = 0; i<7; i++)
digitalWrite(pins[i], four[i]);
else if (n==5) for (int i = 0; i<7; i++)
digitalWrite(pins[i], five[i]);
else if (n==6) for (int i = 0; i<7; i++)
digitalWrite(pins[i], six[i]);
else if (n==7) for (int i = 0; i<7; i++)
digitalWrite(pins[i], seven[i]);
else if (n==8) for (int i = 0; i<7; i++)
digitalWrite(pins[i], eight[i]);
else if (n==9) for (int i = 0; i<7; i++)
digitalWrite(pins[i], nine[i]);
}
توابع () digit و () number که در کد بالا بعد از void استفاده شدهاند، توابعی هستند که مقداری به عنوان خروجی به برنامه اصلی برنمیگردانند. اگر تابعی عددی صحیح یا حقیقی y را به برنامه اصلی برگرداند، آنگاه باید به جای void به ترتیب بعد از int یا float استفاده شود و دستور return y نیز باید در تابع قرار بگیرد. اگر ورودی یک تابع یک رشته، عدد صحیح یا عدد حقیقی باشد آنگاه دستور باید شامل اسم متغیر به همراه نوع آن باشد، مانند void digit(int d). برای مثال در کد زیر، تابع double را نشان میدهد که عدد صحیح x را میگیرد و عدد حقیقی y را برمیگرداند.
تابعی برای گرفتن داده از نوع عدد صحیح و برگرداندن از نوع اعشاری (float)
Float double(int x)
{
float y = 2.0*x;
return y;
}
تابع ()number در اولین لیست کد ارائه شده، از خارج قسمت تقسیم زمان بر 10، 100 یا 1000 استفاده میکند و modulus (x,y) باقیماندهی تقسیم عدد صحیح x بر عدد صحیح y میباشد. برای مثال اگر زمان 1234 باشد، از آنجایی که مقسومعلیه از حسابان اعداد صحیح استفاده میکند، تعداد دهها modulus(1234, 100)=34 وسپس با تقسیم بر 10 عدد 3 را نتیجه میدهد.
ترکیب دستورات if else معمولا برای چندین تست متقابلا منحصربهفرد، اثربخشتر از سری دستورات ()if است، چرا که تستها به جای اجرای ترتیبی میتوانند به صورت همزمان اجرا شوند. یک جایگزین دستورات if else، دستورات switch case هستند. دستور switch متغیر تست را با متغیرهای درون دستور case مقایسه میکند و با توجه به نتیجهی مقایسه، کد متناظر اجرا میشود. استفاده از دستورات switch case زمانی میتواند به فهم کد کمک کند که چندین دستور درون یک case قرار داشته باشد؛ در غیر این صورت استفاده از دستورات if else کفایت میکند. توجه داشته باشید که هر دستور case باید با یک دستور break خاتمه یابد. معادل دستورات if else ، با دستورات جایگزین switch case در کد زیر ارائه شده است :
switch(n)
{
case 0:
for (int i = 0; i<7; i++) digitalWrite(pins[i], zero[i]);
break;
case 1:
for (int i = 0; i<7; i++) digitalWrite(pins[i], one[i]);
break;
case 3:
for (int i = 0; i<7; i++) digitalWrite(pins[i], three[i]);
break;
}
وقتی یکی از دو شرط موجود برای محقق شدن دستوری خاص لازم باشند، آنگاه یک دستور ()if کافی است، مانند if(x>7) y = y+1؛ اما اگر هر دو شرط لازم باشند، هر دو جفت دستور زیر نتیجهای یکسان میدهند، ولی کد سمت چپ بهینهتر است.
if(x>7) y = y+1;
if(x<=7) y = y-1;
if(x>7) y = y+1;
else y = y-1;
برخلاف دستور ()if که یک بار عمل میکند، دستور ()while تا وقتی شرط متناظر با آن ارضا شود، مدام outcome را تکرار میکند؛ بنابراین while(condition) outcome یک حلقه است. به عنوان مثال دستور if(1==1) Serial.printIn(“test”) عبارت”test” را یک بار روی مانیتور نمایش میدهد، اما دستور while(1 == 1) Serial.println(“test”) مدام عبارت “test” را روی مانیتور نمایش میدهد. دستور if(condition) break برای خارج شدن از یک حلقهی ()while استفاده میشود.
یک شیفت رجیستر
یک شیفت رجیستر میتواند حالتهای LED را درون نمایشگر سون سگمنت بارگذاری کند، که این کار باعث میشود سیمهای متصل به برد آردوینو از هشت به سه عدد کاهش یابد (شکل 3 را ببینید)، درست مانند نمایشگر سون سگمنت یک رقمی .طریقه استفاده از اتصالات شیفت رجیستر و نمایشگر سون سگمنت 4رقمی به ترتیب در جداول 2 و 3 داده شدهاند.
جدول 2- اتصالات شیفت رجیستر 74HC595
جدول 3- اتصالات نمایشگر سون سگمنت 4رقمی و سنسور دما
یک سنسور دمای LM35DZ میتواند با نمایشگر زمان مورد استفاده قرار گیرد (شکل3 را ببینید). برنامه قادر است مرتبا دمای محیط و زمانی که از اجرای کد میگذرد را روی نمایشگر نشان دهد. نقطه اعشاری برای دما در تابع digit توسط اضافه کردن مقدار 128 به عددی که باید نمایش داده شود، لحاظ شده است. برای مثال نمایش باینری عدد دو با و بدون نقطهی اعشاری به ترتیب به صورت B11011011 و B01011011 نمایش داده میشود که معادل دسیمال آنها 219 و 91 میباشند. در شکل3 سیم قهوهای شیفت رجیستر را به نمایشگر سون سگمنت 4رقمی به منظور نمایش نقطهی اعشاری متصل میکند.
کد نمایش زمان و دما روی سون سگمنت 4 رقمی در آردوینو
pinMode (dataPin, OUTPUT); // define shift register DATA pin as output
pinMode (latchPin, OUTPUT); // define shift register LATCH pin as output
pinMode (clockPin, OUTPUT); // define shift register CLOCK pin as output
for (int i = 0; i<4; i++) pinMode (digits[i], OUTPUT);
analogReference (INTERNAL); // set ADC voltage to 1.1V rather than 5V
}
void loop()
{
start = millis(); // milliseconds elapsed
while (millis()-startduration && millis()-start<2*duration)
{
digit(1, (temp%1000)/100, 0); // digit D2 for tens
digit(2, (temp%100)/10, 1); // digit D3 for units 1 for DP
digit(3, temp%10, 0); // digit D4 for decimal places
}
}
void digit(int d, int n, int DP)
{
// turn all digits off, digit states are HIGH
for (int i = 0; i<4; i++) digitalWrite(digits[i], 1);
digitalWrite(latchPin, LOW); // add 128 for decimal point
shiftOut(dataPin, clockPin, MSBFIRST, numbers[n]+DP*128);
digitalWrite(latchPin, HIGH); // change display pattern
digitalWrite(digits[d], 0); // turn digit on, digit state LOW
delay(del); // delay del (ms)
}
ترتیب دستورها در تابع ()digit به منظور حصول اطمینان از عدم نمایش سایه از اعداد قبلی بر روی نمایشگر الزامی است. تمام رقمهای نمایشگر قبل از اینکه الگوی جدید بارگذاری شود، خاموش میشوند. اگر رقمی از ارقام سون سگمنت قبل از بارگذاری الگوی عددی جدید روشن باشد، آنگاه برای بازهی زمانی کوچکی عدد قدیمی بر روی نمایشگر نمایش داده خواهد شد، که این امر موجب ایجاد سایهای از اعداد قبلی بر روی نمایشگر میشود.
دو شیفت رجیستر
با اتصال دو شیفت رجیستر به یکدیگر، یکی سگمنتهای LED و دیگری رقمها را کنترل میکند. برای نمایش یک عدد بر روی نمایشگر سون سگمنت 4رقمی، اطلاعاتی که برای روشن شدن ارقام نمایشگر لازم است و الگوی عدد به صورت بیت به بیت در رجیستر حافظهی اولین شیفت رجیستر بارگذاری میشوند. اطلاعاتی که بیت به بیت بارگذاری میشود، بیش از هشت بیت را شامل میشود، بنابراین بیتهای اضافه به شیفت رجیستر دوم منتقل میشوند. شکلهای4 و 5 بارگذاری بیت به بیت اطلاعات عدد پنج را با نمایش B00010110 و الگوی B01101101 برای نمایش بر روی سومین رقم نشان میدهند.
در شکل6 رقمهای نمایشگر سون سگمنت 4رقمی به پایههای QB، QC، QD و QE دومین شیفت رجیستر متصل شدهاند و هنگامیکه پایه شیفت رجیستر LOW شود، LEDهای رقم متناظر روشن میشوند. نمایش باینری اطلاعاتی که باعث روشن شدن سومین رقم نمایشگر میشود B00010110 میباشد؛ حال آنکه باید سومین رقم متصل به پایه QD، LOW و رقمهای 2،1 و 4 که به ترتیب به QB، QC و QE متصلاند، HIGH باشند. نمایش دسیمال دادههایی که رقمهای D1، D2، D3 و D4 را روشن میکنند به ترتیب عبارتاند از: 28 (یا B11100)، 26 (یا B11010)، 22 (یا B10110) و 14 (یا B01110). توجه داشته باشید که در شکل 6 شیفت رجیستر دوم به صورت وارونه رسم شده تا شماتیک قابل فهمتر باشد، بر این اساس انتهای قطعهی 74HC595 که محل پایههای 1 و 16 یا QB و VCC است، در سمت راست قرار میگیرد.
چون دو شیفت رجیستر به صورت متوالی به یکدیگر متصل شدهاند، تنها 3 اتصال به برد آردوینو احتیاج است، حال آنکه در حالتی که هیچ شیفت رجیستری استفاده نشود، 12 اتصال لازم است. پایه خروجی سریال اولین شیفت رجیستر QH’ باید به پایهی ورودی سریال دومین شیفت رجیستر SER متصل شود. پایههای کلاک رجیستر حافظه SRCLK و پایههای کلاک شیفت رجیستر RCLK از هر دو شیفت رجیستر به یکدگیر متصل میشوند. توجه کنید که شکل 6 تمهیدات نشان دادن نقطهی اعشاری را شامل نمیشود. تغییرات لازم الاجرا در اتصالات شیفت رجیستر 74HC595 زمانی که شیفت رجیستر دومی در کار باشد در جدول4 آورده شده است.
جدول 4- تغییر در اتصالات اولین شیفت رجیستر با اتصال شیفت رجیستر دوم
74HC595 (1) و 74HC595 (2) به ترتیب معرف اولین و دومین شیفت رجیستر هستند. واضح است که شیفت رجیستر دوم فقط به نمایشگر سون سگمنت 4رقمی و شیفت رجیستر اول متصل میشود ولی به آردوینو به استثنای پایههای 5V و GND متصل نمیشود (جدول 5 را ببینید).
جدول 5- اتصالات شیفت رجیستر دوم
دستور int digits[] = {10,11,12,13} در لیست کد چهارم با دستور int digits[] = {28,26,22,14} جایگزین شده است که اعداد داخل کروشه نمایش دسیمال بیتهای لازم برای روشن کردن رقمهای D1، D2، D3 و D4 هستند. با پاک کردن دستوراتی که برای روشن و خاموش کردن رقمهای نمایشگر وجود دارند، تابع () digit جای خود را به دستور جدید ()shiftOut (به صورت پررنگ) برای شیفت رجیستر دوم داده است:
2 دیدگاه در “راه اندازی سون سگمنت 4 رقمی با آردوینو”
سلام ، سون سگمنتی که شما راه اندازی کردید کاتد مشترکه یا آند مشترک؟
ممنون میشم راهنمایی کنید
سلام و احترام، همانطور که در ابتدای مقاله ذکر شده؛ کاتد مشترک است.