سلام دوستان
من تازه کا کردن با آردوینو رو شروع کردم . سوالی که دارم اینه که چطور باید interrupt ایجاد کنم . اگه منبع آموزش فارسی دارید ممنون میشم معرفی کنید
سلام دوستان
من تازه کا کردن با آردوینو رو شروع کردم . سوالی که دارم اینه که چطور باید interrupt ایجاد کنم . اگه منبع آموزش فارسی دارید ممنون میشم معرفی کنید
لطفا بیشتر توضیح بدید چه نوع وقفه میخواید ایجاد کنید؟ مثلا میخواید در صورت تغییر وضعیت پایه اینتراپت خارجی وقفه اتفاق بیوفته و به روتین وقفه برید؟!
بله . ممنون میشم راهنمایی کنید
برای این کار شما باید در حلقه setup اول تنظیمات وقفه رو توسط تابع زیر انجام دهید:
attachInterrupt(interrupt, ISR, mode)
یا
attachInterrupt(pin, ISR, mode)
در توابع بالا بجای ISR اسم تابعی رو مینویسید که موقع اتفاق افتادن وقفه خارجی باید فراخوانی و اجرا بشه، قسمت mode هم برای مشخص کردن نوع وقفه خارجی هست یعنی اینکه مثلا با لبه بالاروند باشه یا لبه پایین رونده یا تغییر وضعیت پایه و قفه و ...، پین یا interrupt هم شماره اینتراپت مورد نظرتون رو مینویسید مثلا وقفه خارجی 0، اینکه در هر برد کدام پایه مربوط به کدام وقفه هست رو میتونید از لینکی که بعد میدم نگاه کنید. بعد از نوشتن این تابع در بخش setup برنامه هر وقت وقفه رخ بده برنامه اون تابع که نامش رو در قسمت ISR نوشتید رو اجرا میکنه و بعد از تمام شدنش به برنامه باز میگرده. سعی کنید تابع ISR کوتاه و مختصر باشه که سریع اجرا بشه چرا که هنگام اتفاق افتادن یک وقفه با توجه به ساختار میکروهای AVR و نوع اولویت دهی که در آردوینو انجام شده به وقفه های دیگه رسیدگی نمیشه و همچنین بعضی از توابع مثل تاخیر میلی ثانیه یا دستورات میلی در تابع وقفه کار نمیکنند.
برای اطلاعات بشتر و دیدن نمونه کد به لینک زیر مراجعه کنید:
Arduino - AttachInterrupt
ممنون از اطلاعاتتون
دوستان من از یه تابع وقفه استفاده کردم و می خواهم هر بار که وقفه اجرا میشه مثلا بعد 1 ثانیه اطلاعات تغییر یافته در وقفه رو در مثلا سریال مانیتور نشان بده منتها این دقیقا به تعداد 25 بار کار می کنه و تغییرات آن متغیر رو 25 بار در سریال مانیتور نشون می ده ولی بعد دیگه متوقف میشه و دیگه چیزی نشون نمیده به نظرتان ایراد کار کجاست؟ کسی می تونه کمک کنه
کد اولیه ای که تابع اینتراتپ وقفه در آن استفاده شده است به شرح زیر است که برای شمارش دور و فرکانس استفاده میشه :
// read RPM
int half_revolutions = 0;
int rpm = 0;
unsigned long lastmillis = 0;
void setup(){
Serial.begin(9600);
attachInterrupt(0, rpm_fan, FALLING);
}
void loop(){
if (millis() - lastmillis == 1000){ //Uptade every one second, this will be equal to reading frecuency (Hz).
// detachInterrupt(0);//Disable interrupt when calculating
rpm = half_revolutions * 60; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use half_revolutions * 30.
Serial.print("RPM =\t"); //print the word "RPM" and tab.
Serial.print(rpm); // print the rpm value.
Serial.print("\t Hz=\t"); //print the word "Hz".
Serial.println(half_revolutions); //print revolutions per second or Hz. And print new line or enter.
half_revolutions = 0; // Restart the RPM counter
lastmillis = millis(); // Uptade lasmillis
attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
}
}
// this code will be executed every time the interrupt 0 (pin2) gets low.
void rpm_fan(){
half_revolutions++;
}
حالا اگر من به همین کد کارت حافظه هم اضافه کنم که در زیر آوردم برای ذخیره داده ها دیگه فقط 25 تا داده را در سریال مانیتور نشان میده در حالی که در کد اولی این مشکل ایجاد نمیشه. ایرادش چیه ؟
// read RPM
#include <SPI.h>
#include <SD.h>
// for Due/Mega/Leonardo use the hardware SPI pins (which are different)
#define _sclk 13
#define _miso 12
#define _mosi 11
const int chipSelect = 4; //number of pin cs of sd-card
// read RPM
int half_revolutions = 0;
int rpm = 0;
unsigned long lastmillis = 0;
void setup(){
Serial.begin(9600);
attachInterrupt(0, rpm_fan, FALLING);
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;}
Serial.println("card initialized.");
SD.remove("datalog.txt");
File dataFile = SD.open("datalog.txt", FILE_WRITE);
dataFile.print("بسمه تعالی ");dataFile.print("\n");
dataFile.print("RPM \tFrequence\n");
dataFile.print("-------\t\t--------------\n");
dataFile.close();
}
void loop(){
if (millis() - lastmillis == 1000){ //Uptade every one second, this will be equal to reading frecuency (Hz).
detachInterrupt(0);//Disable interrupt when calculating
rpm = half_revolutions * 60; // Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use half_revolutions * 30.
Serial.print("RPM =\t"); //print the word "RPM" and tab.
Serial.print(rpm); // print the rpm value.
Serial.print("\t Hz=\t"); //print the word "Hz".
Serial.println(half_revolutions); //print revolutions per second or Hz. And print new line or enter.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if (dataFile) { // if the file is available, write to it:
dataFile.print(rpm);dataFile.print("\t");dataFile. print(half_revolutions);
dataFile.print("\n");
dataFile.close();
}
else { // if the file isn't open, pop up an error:
Serial.println("error opening datalog.txt");
}
half_revolutions = 0; // Restart the RPM counter
lastmillis = millis(); // Uptade lasmillis
attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
}
}
// this code will be executed every time the interrupt 0 (pin2) gets low.
void rpm_fan(){
half_revolutions++;
}
اگه هم بخواهم از وقفه استفاده نکنم به امید اینکه مشکل حل بشه باز همون آش و همون کاسه شد ضمن اینکه دورهای بالاتر از 1 دور رو نمی تونه بگیره