Практична
робота №5
Тема:
Використання модулів переривання, оптопари
В
даній практичній роботі розглянемо підключення оптопари
та визначимо кількість проходів за допомогою Arduino. На приклад ми маємо
транспортер по якому проходять штучні вироби, і нам потрібно порахувати скільки
виробів прошло по транспортеру.
Необхідне
обладнання:
· Arduino;
· 2 кнопки;
· Два резистори номіналом 10кОм;
· 7
сегментний 4 розрядний індикатор на драйвері TM1637;
· Модуль
фоторезистора;
· Лазерний
модуль Ky-008 650nm.
Датчик
проходів являє собою пристрій складається з двох частин - приймача і джерела
випромінювання. Рахунок і запис даних здійснюється за допомогою arduino nano. Як приймач
використовується модуль фоторезистора, виконаний на
основі мікросхеми LM393. Дані будуть передаватися по аналоговому виходу модуля.
Фоторезистор повинен знаходиться в спеціальному
затемненому корпусі, щоб виключити можливість спрацьовування лічильника від
сторонніх джерел світла. Джерело випромінювання являє собою найпростіший
лазерний діод. У цьому пристрої був використаний лазер від простої лазерної
указки. Наявність лазера дає перевагу в відстані і стабільності в порівнянні з
інфрачервоними світлодіодами. Так же в цьому пристрої є 7 - сегментний 4 -
розрядний індикатор під управлінням драйвера TM1637. Для здійснення скидання
використовуються 2 кнопки без фіксації. Скидання відбувається тільки після
введення пароля. В процесі розробки буде задіяна незалежна пам'ять
мікроконтролера для того, щоб дані не губилися при випадковому або навмисному
відключенні живлення.
Кнопка
скидання і введення пароля підключені через 10 кОм резистор. Arduino, модуль фоторезистора і
індикатор живляться від 5 вольтової лінії, можна
використовувати вивід + 5v від arduino. Сам arduino може живитися від зовнішнього джерела живлення
(7-12 вольт) використовуючи пін Vin,
по usb або пін + 5v.
Принцип
роботи програми простий. Лазер постійно світить на фоторезистор.
Програма кожного разу отримує значення з фоторезистора
0-1023. Під час випромінювання лазера показання з фоторезистора
не перевищує 50, коли якийсь об'єкт перекриває промінь лазера то його показання
перевищує порогове значення в 50. Коли значення перевищить поріг в 50 програма
почекає 500 мс (достатня для того, щоб виріб пройшов) потім знову опитує датчик
і якщо значення знову менше 50 означає що виріб пройшов інакше буде чекати поки
виріб не пройде якщо раптом він встав на місці. Затиснувши кнопку протягом 3-х секунд
що почати скидання програма перейде в режим скидання пароля, на індикаторі буде
відображатися введення з кнопки цифрове
значення (повторне натискання збільшує значення коду на +1). Без особливих
зусиль можна ввести 2-х значний пароль скидання. У програмі використовується
незалежна пам'ять eeprom в яку записується значення
лічильника. Перед початком роботи програма звертається до пам'яті витягує і
виводить на дисплей, який був збережений значення лічильника (найбільше). Щоб
збільшити ресурс даного пристрою обмежену в циклах запису пам'ять
використовуємо з максимальною ефективністю. Для цього кожне наступне значення,
отримане з лічильника записується в наступні комірки пам'яті, тобто
використовуються всі осередки пам'яті по порядку. При скиданні очищається
значення лічильника не тільки в оперативній пам'яті але і в eeprom.
Код:
#include <TM1637.h> //Підключаємо бібліотеку для
роботи індикатора
#include <EEPROM.h> //підключаємо
бібліотеку для роботи з енергонезалежною пам’яттю
#define CLK 5
#define DIO 4
TM1637 disp(CLK,DIO);//установлюємо виходи CLK,DIO для цифрового індикатора
int
a_pin_1=A7; //аналоговий вхід с фоторезистора
int
d_pin_1=2; //цифровий вхід кнопки 1
int
d_pin_2=3; //цифровий вхід кнопки 2
int res=0; //змінна значення фоторезистора
0-1023
int goods; // змінна лічильник виробів
int reset=0;// змінна значення кнопки 1 (кнопка скидання)
int pass_reset=0; // змінна значення кнопки 2 (ввід паролю скидання)
int pass=0; //змінна значення введеного паролю
bool g; //змінна
перемикач роботи (підрахунок або скидання)
byte hi; //змінна для записування значень по бітам
byte low;
int maxi=0; // максимальне значення біту в EEPROM
int address=0; //адреса в пам’яті EEPROM
void setup()
{
disp.set(5);
disp.init(D4056A);
pinMode(d_pin_1,INPUT);
pinMode(d_pin_2,INPUT);
for (int addr=0; addr<EEPROM.length(); addr=addr+2)//шукаємо
останній запис в EEPROM, саме велике
значення
{
hi = EEPROM.read(addr);//беремо по дві
комірки пам’яті і збираємо число
low = EEPROM.read(addr+1);
int val = word(hi,
low);
if (val>maxi)//змінна maxi отримає значення
останнього запису.
{
maxi=val;
}
}
goods=maxi;
disp.display(goods); //виводимо на індикатор останнє значення
}
void loop()
{
if(goods<10000)//підрахунок буде вестися до 9999
{
//перевіряємо чине
натиснута кнопка скидання 1
reset=digitalRead(d_pin_1);
if(reset==1)//если да то
{
g=true;//переключаємося
в режим скидання, підрахунок закінчено, отримаємо значення паролю скидання
if(pass==7)//по замовчуванню пароль 7, якщо пароль правильний, то
{
g=false; //переключаємо
в режим підрахунку
goods=0;//очищаємо
лічильник
pass=0;//очищаємо
пароль
for (int i = 0 ; i < EEPROM.length()
; i++) {
EEPROM.write(i,
0);//обнуляємо пам’ять EEPROM
}
disp.display(goods);
}
else //якщо пароль
не правильний
{
if(pass>0)
{
g=false; // переключаємо
в режим підрахунку
disp.display(goods);// продовжуємо підрахунок і виводимо на дисплей останнє
число
pass=0;//обнуляємо пароль
}
}
}
//режим підрахунку
if(g==false)
{
res=analogRead(a_pin_1);//отримаємо значення з фоторезистора
if(res>50)//промінь лазера перекритий
{
delay(500);//чекаємо
500 млс
res=analogRead(a_pin_1);//знову отримаємо значення з фоторезистора
if(res<50)//промінь лазеру знову світить, означає що
пройшов виріб
{
goods+=1;//додаємо
значення
disp.display(goods);//виводимо значення на індикатор
pass=0;
hi = highByte(goods);
low = lowByte(goods);
EEPROM.write(address, hi);
EEPROM.write((address+1),
low);//розбиваємо число по байтам і записуємо в
пам’ять
address = address + 2;//заміна адреси комірки
if (address == EEPROM.length())
{
address = 0;// обнулення адреси комірок
}
}
}
}
//ввід паролю з
кнопки 2
if(g==true)//режим вводу паролю
{
pass_reset=digitalRead(d_pin_2);// отримаємо цифрове значення с кнопки
2
if(pass_reset==1)// кнопка скидання паролю натиснута
{
delay(200);//середня
швидкість натискання кнопки людиною
pass+=1;
disp.display(pass);//показуємо введений пароль
}
}
}
}