Практична робота №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);//показуємо введений пароль

}

}

}

}