// библиотеки для работы с LCD дисплеем по I2C #include #include // инициализация дисплея. // 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; } }