В этой статье я покажу, как можно с помощью обычного светодиода и фоторезистора сделать тахометр – измеритель скорости вращения моторчика. И чтобы было интересней, полученные данные будут выведены на LCD дисплей, у меня как раз завалялся модуль HD44780, он умеет выводить данные в две строки по 16 столбцов.
Как работает фоторезистор
Фоторезистор – это полупроводник, который меняет свое сопротивление в зависимости от количества света, который на него попадает. Чем больше света, тем ниже сопротивление. Эта способность нам поможет в реализации тахометра. Будем светить с помощью светодиода на фоторезистор с небольшого расстояния — 1,5-2 сантиметра. И с помощью ардуино будем мониторить какое напряжение проходит через фоторезистор, если напряжение будет падать, значит что-то загораживает свет. Если на вал мотора одеть лопасть, и заставить крутиться между светодиодом и фоторезистором, то можно узнать, как часто лопасть загораживает свет. А дальше дело техники – сделать пару десятков замеров, посчитать среднее арифметическое, для более точного замера и перевести эти данные в количество оборотов в минуту.
При первом испытании, получилось, что мотор, на котором я тестировал, вращается со скоростью почти 12 тысяч оборотов в минуту. В голову сразу пришла мысль, что где-то ошибка в расчетах или arduino не корректно обрабатывает данные с фоторезистора. Пришлось замедлить мотор с помощью потенциометра, и данные тоже стали замедляться. Обороты упали до двух, а потом и до одной тысячи в минуту. Все работало и высчитывалось корректно. Но при максимальном повышении оборотов, получались все те же 12 тыс. Пришлось поискать даташит на моторчик и оказалось, что его нормальная скорость вращения – это 11,5 -12,5 тыс оборотов. То есть все работает корректно. Ни когда бы не подумал, что такой маленький моторчик может вращаться с такой скоростью.
Ниже две фотографии, на одной изображено, как расположены светодиод и фоторезистор, а на второй уже к ним добавился мотор, скорость вращения которого, будет измеряться.
Вывод данных на LCD дисплей HD44780 с помощью arduino
Для работы с дисплеем HD44780 очень удобно использовать модуль I2C интерфейса. Бывают модули и LCD дисплеи продаются по отдельности, но зачастую и сразу в комплекте, спаянные. Я рекомендую, использовать уже собранные вместе, поскольку если подключать без I2C то придется подключать дисплей с помощью 16 проводов, когда через I2C их количество снижется до 4, два из которых это питание. А два других провода подключаются к пинам ардуино A4 и A5.
Чтобы управление выводом данных на дисплей, было более удобным и комфортным можно воспользоваться библиотекой LiquidCrystal_I2C.
Ниже приведена схема подключение дисплея, а также светодиода с фоторезистором к arduino.
Что использовалось в проекте:
- Arduino (я использовал arduino uno, но можно любую другую). Покупал тут: arduino uno
- 1 резисторов сопротивлением 300 Ом. Покупал тут:набор резисторов 700 шт. От 10 Ом до 1 МОм
- 1 резисторов сопротивлением 10 кОм. Покупал тут:набор резисторов 700 шт. От 10 Ом до 1 МОм
- 1 светодиод. Покупал тут: 100 светодиодов, 10 разных цветов
- LCD дисплей Hd44780 с модулем I2C. Покупал тут: LCD дисплей Hd44780 с модулем I2C
- Фоторезистор. Покупал тут: Фоторезисторы, 20 шт
Скетч тахометра на arduino
Ниже приведен скетч с подробными комментариями, а также его можно скачать себе на компьютер: скачать.
// библиотеки для работы с LCD дисплеем по I2C #include <Wire.h> #include <LiquidCrystal_I2C.h> // инициализация дисплея. // GND - земля // VVC - 5+ вольт // SDA - пин A4 // SCL - пин A5 // 16 столбцов и 2 строки LiquidCrystal_I2C lcd(0x27,16,2); const int pinPhoto = A0; // порт для считывания данных с фоторизистора int light = 0; // переменная для хранения данных с фоторизистора int numTurn = 0; // номер итерации проверки оборотов int valArray[100]; // массив для хранения данных с фоторезистора, нужные для начальной настройки int maxLight = 1024; // порог, при котором будем считать, что светодиод закрыт int sum = -1; // сумма количеств оборотов int count_zamer = 20; // количество итераций, после которых будет высчитано среднее значение скорости unsigned long lastMillis = 0; // переменная для хранения времени предыдущего перекрытия светодиода bool work = true; // флаг, который поднимается после открытия светодиода void setup() { Serial.begin(9600); pinMode( pinPhoto, INPUT ); // ждем пока светодиод прогреется delay(1000); // каждые 10 милисек считаем значение с фоторезистора, 100 раз for(int i = 0; i< 100; i++){ valArray[i] = analogRead( pinPhoto ); delay(10); } // выбераем минимальное значение с фоторезистора for(int i = 0; i< 100; i++){ if(maxLight > valArray[i]) maxLight = valArray[i]; } // немного снизим порог maxLight -= 10; Serial.println( maxLight ); delay(500); Serial.println( "START!" ); lastMillis = millis(); // запускаем дисплей lcd.init(); // включаем подсветку lcd.backlight(); // стираем все лишнее lcd.clear(); // выводим текст lcd.setCursor(0, 0); lcd.print("S"); lcd.setCursor(1, 0); lcd.print("T"); lcd.setCursor(2, 0); lcd.print("A"); lcd.setCursor(3, 0); lcd.print("R"); lcd.setCursor(4, 0); lcd.print("T"); lcd.setCursor(5, 0); lcd.print("!"); } void loop() { // считаем показания с фоторезистора light = analogRead( pinPhoto ); // если значение ниже порога, значит светодиод загорожен if(light < maxLight && work){ // опускаем флаг, чтобы не считать, пока светодиод перекрыт work = false; // если первая итерация, то не считаем ее, чтобы начать отсчет времени if(sum == -1){ // записываем время старта lastMillis = millis(); sum = 0; }else{ unsigned long currentMillis = millis(); // записываем в sum количество миллисекунд между оборотами sum += (currentMillis - lastMillis); numTurn++; // считаем 20 раз, для большей точности if(numTurn == count_zamer){ float sredSpeed = 0; numTurn = 0; // берем среднее и высчитываем количество оборотов для минуты sredSpeed = 60000 / ((float)sum / (float)count_zamer); // оборотов в минуту Serial.print("speed: "); Serial.println(sredSpeed); sum = -1; // вывод данных на LCD дисплей lcd.clear(); lcd.setCursor(0, 0); lcd.print("S"); lcd.setCursor(1, 0); lcd.print("P"); lcd.setCursor(2, 0); lcd.print("E"); lcd.setCursor(3, 0); lcd.print("E"); lcd.setCursor(4, 0); lcd.print("D"); lcd.setCursor(5, 0); lcd.print(":"); // преобразовываем числовое значение в строку // и по одному символу выводим не дисплей char string_turn[] = ""; sprintf(string_turn,"%d", (int)sredSpeed); char *current = string_turn; int count_numbers = 0; while ( *current != '\0' ) { lcd.setCursor(6+count_numbers, 0); lcd.print(*current); count_numbers++; current++; } lcd.setCursor(count_numbers+7, 0); lcd.print("r"); lcd.setCursor(count_numbers+8, 0); lcd.print("/"); lcd.setCursor(count_numbers+9, 0); lcd.print("m"); lcd.setCursor(count_numbers+10, 0); lcd.print("i"); lcd.setCursor(count_numbers+11, 0); lcd.print("n"); } lastMillis = currentMillis; } } // если светодиод не загорожен if(light >= maxLight){ work = true; } }
Послесловие
Работающее устройства можете посмотреть на видео, там я сделал несколько замеров.
Нет схемы с номиналами деталей.