Форум ModelldepO  

Вернуться   Форум ModelldepO > Моделизм > Электрика и DCC > Arduino
 
 
Опции темы Опции просмотра
Старый 12.09.2016, 12:19   #1
BNSF9399
Местный
 
Аватар для BNSF9399
 
Регистрация: 06.03.2014
Адрес: Москва
Сообщений: 1,741
Сказал(а) 'не согласен(а)'!: 5
Сказали 'не согласен'! 9 раз(а) в 7 сообщениях
Сказал(а) спасибо: 553
Поблагодарили 2,794 раз(а) в 755 сообщениях
Все 'Спасибо' этого пользователя. :
0 за это сообщение
0 Всего
Репутация: репутация неоспорима (2791)
По умолчанию масштабное измерение скорости V2.0

Чтобы не "мусорить" в чужой теме...
Давно блуждали мысли, "поковырять" arduino, но так как реального применения не находилось, то так на уровне мыслей все и оставалось.
И тут наткнулся на тему xu56857 масштабное измерение скорости
Первоначально планировалось только доработать авторский код с целью добавления возможности выбора масштаба и единиц измерения, но выслушав советы BR95009 и Qvan22, основательно "перелопатил" исходный скетч.
В чем отличие от авторского - как таковые убраны задержки обработки кода, т.е. программа работает постоянно, все задержки реализованы при помощи флагов.
Все пины и константы вынесены в переменные, что позволяет подключать датчики и кнопки к любому выходу с минимальными правками кода.
Добавлен выбор масштаба (HO, TT, N). При необходимости можно добавить любой масштаб
Добавлен выбор единиц измерения (км/ч, MPH). При необходимости можно добавить любые единицы (дюймы в сек, миллиметры в сек... Все, что душе угодно).
Для сохранения выбранных настроек используется энергонезависимая память контроллера (EEPROM), что позволяет при повторном включении вернутся к последним выбранным единицам измерения и масштабу
Добавлена анимация во время измерения. Вместо надписей GO LEFT/GO RIGHT - реализована бегущая строка из символов > и < движущихся в соответствующем направлении


Пока все реализовано на макетке на UNO, жду нужные компоненты от наших китайских товарищей и буду реализовывать в "железе".
Схема
Нажмите на изображение для увеличения
Название: speedo.jpg
Просмотров: 463
Размер:	87.7 Кб
ID:	130518
скетч
Arduino код:
#include <LiquidCrystal.h> // Добавляем библиотеку LCD 
#include <EEPROM.h> // Добавляем библиотеку работы с энергонезависимой памятью 
// Добавляем библиотеку антидребезга кнопок 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * 
  Main code by Thomas O Fredericks (tof@t-o-f.info) 
  Previous contributions by Eric Lowry, Jim Schimpf and Tom Harkaway 
  [url]https://github.com/thomasfredericks/Bounce2/archive/master.zip[/url] 
  * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 
#include <Bounce2.h> 

// переменные, которые можно менять
float S 70//дистанция (расстояние между датчиками) в миллиметрах
int resultDelay 3000// время показа результата измерений в миллисекундах
int animationDelay 50// время задержки анимации в миллисекундах
unsigned long timeoutDelay 60000// время ожидания срабатывания второго датчика в миллисекундах

// флаги
unsigned long flagLeft 0// время срабатывания левого датчика
unsigned long flagRight 0// время срабатывания правого датчика
unsigned long flagShow 0//время окончания отображения результатов
unsigned long flagAnimation 0//время отображения следующего символа при анимации

// переменные для расчетов
unsigned long timeStart;//время срабатывания первого датчика
unsigned long timeStop;//время срабатывания второго датчика
long T//интервал в милисекундах
float V//скорость в м/с
float sV//масштабная скорость
int selcted_scale EEPROM.read(0); // ключ массива выбранного масштаба
int selcted_unit EEPROM.read(1); // ключ массива выбранных единиц измерения

// массивы, которые можно дополнять или изменять
const String scale[][2] = {{" HO""87"}, {" TT""120"}, {"  N""160"}}; // массив масштабов (отображение на экране, множитель)
const String units[][2] = {{"KPH""3.6"}, {"MPH""2.23694"}}; // массив единиц измерения (отображение на экране, коэффициент перевода из метров в секунду)

LiquidCrystal lcd(765432); // (RS, E, DB4, DB5, DB6, DB7) инициализируем дисплей
int ir_left 8// вход лекого датчика
int ir_right 9// вход правого датчика
int scalePin 10// вход кноки выбора масштаба
int unitsPin 11// вход кнопки выбора единиц измерения скорости

Bounce scaleBouncer Bounce(); // объект-обработчик антидребезга кнопки выбра масштаба
Bounce unitsBouncer Bounce(); // объект-обработчик антидребезга кнопки выбора единиц измерения

// переменные для анимации
int r;
char c;

void setup() {
  
lcd.begin(162);
  
pinMode(ir_leftINPUT);
  
pinMode(ir_rightINPUT);
  
pinMode(scalePinINPUT);
  
pinMode(unitsPinINPUT);
  
// параметры обработчика антидребезга
  
scaleBouncer.attach(scalePin);
  
scaleBouncer.interval(5);
  
unitsBouncer.attach(unitsPin);
  
unitsBouncer.interval(5);
}

// расчет скорости
void calculateSpeed(int selcted_unitint selcted_scale){
  
= (timeStop timeStart);
  
T;
  
sV units[selcted_unit][1].toFloat() * scale[selcted_scale][1].toInt();
  
char buffer[12];
  
String tmpStr dtostrf(sV121buffer);
  
lcd.setCursor(00);
  
lcd.print(tmpStr);
  
flagShow millis() + resultDelay;
  
timeStart 0;
  
timeStop 0;
}

//рисуем бегущую строку
void animation() {
  
lcd.setCursor(r0);
  
lcd.print(c);
  if(
flagRight 0) {
    
r++;
    if(
11){
      
1;
      if(
== '>') {
        
' ';
      }
      else {
        
'>';
      }
    }
  }
  else if(
flagLeft 0) {
    
r--;
    if(
1){
      
11;
      if(
== '<') {
        
' ';
      }
      else {
        
'<';
      }
    }
  }
  
flagAnimation millis() + animationDelay;
}

void loop() {
  if(
selcted_scale sizeof(scale)/sizeof(scale[0])-1) {
    
// если считанное значение больше, чем количество элементов в массиве масштабов - обнуляем значение
    
selcted_scale 0;
    
EEPROM.write(00);
  }
  if(
selcted_unit sizeof(units)/sizeof(units[0])-1) {
    
// если считанное значение больше, чем количество элементов в массиве единиц измерения скоростей - обнуляем значение
    
selcted_unit 0;
    
EEPROM.write(10);
  }
  
// если флаг отображения результатов меньше текущего времени выполняем код, в противном случае продолжаем отображать результаты измерений
  
if(flagShow millis()) {
    
flagShow 0;
    
// если сработал один датчик, но за время timeoutDelay не сработал второй - выводим TIME OUT
    
if(timeStart && timeStart timeoutDelay millis()) {
      
lcd.clear();
      
lcd.setCursor(00);
      
lcd.print("    TIME OUT    ");
      
flagShow millis() + resultDelay;
      
timeStart 0;
      
timeStop 0;
      
flagLeft 0;
      
flagRight 0;
      
flagAnimation 0;
    }
    
// если одновременно сработали оба датчика, но не выставлены флаги начала измерения - выводим ошибку
    
else if(digitalRead(ir_right) == LOW && digitalRead(ir_left) == LOW && flagLeft == && flagRight == 0) {
      
lcd.clear();
      
lcd.setCursor(00);
      
lcd.print("     ERROR      ");
      
flagShow millis() + 1000;
    }
    
// если нет сигнала от обоих датчиков и не выставлены флаги обоих датчиков - система готова к измерениям
    
else if(digitalRead(ir_right) == HIGH && digitalRead(ir_left) == HIGH && flagLeft == && flagRight == 0) {
      
// если была нажата кнопка масштаба
      
if(scaleBouncer.update()){
        if(
scaleBouncer.read() == HIGH) {
          
selcted_scale++;
          if(
selcted_scale sizeof(scale)/sizeof(scale[0])-1){
            
selcted_scale 0;
          }
        }
       }
      
// если была нажата кнопка единиц измерения
      
if (unitsBouncer.update()){
        if(
unitsBouncer.read() == HIGH) {
          
selcted_unit++;
          if(
selcted_unit sizeof(units)/sizeof(units[0])-1){
            
selcted_unit 0;
          }
        }
      }
      
lcd.setCursor(130);
      
lcd.print(units[selcted_unit][0]);
      
lcd.setCursor(131);
      
lcd.print(scale[selcted_scale][0]);
      
lcd.setCursor(10);
      
lcd.print("READY      ");
    }
    
// если измерения не началось и сработал один из датчиков при этом нет флага второго датчика - начинаем замер
    
else if(timeStart == && ((digitalRead(ir_right) == LOW && flagLeft == 0) || (digitalRead(ir_left) == LOW && flagRight == 0))) {
      
timeStart millis();
      if(
digitalRead(ir_right) == LOW){
        
flagRight millis();
        
'>';
        
1;
      }
      else {
        
flagLeft millis();
        
'<';
        
11;
      }
      
lcd.setCursor(10);
      
lcd.print("           ");
      
animation();
    }
    
// если сработал один из датчиков и выставлен флаг второго - заканчиваем измерения и производим расчет скорости
    
else if((digitalRead(ir_right) == LOW && flagLeft 0) || (digitalRead(ir_left) == LOW && flagRight 0)) {
      
timeStop millis();
      
flagLeft 0;
      
flagRight 0;
      
flagAnimation 0;
      
EEPROM.update(0selcted_scale);
      
EEPROM.update(1selcted_unit);
      
calculateSpeed(selcted_unitselcted_scale);
    }
    
// если настало время рисовать новый символ при анимации
    
else if(flagAnimation millis()){
      
animation();
    }
  }


Последний раз редактировалось BNSF9399; 14.09.2016 в 02:12.
BNSF9399 вне форума  
Вверх
3 пользователя(ей) сказали cпасибо:
 


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
масштабное измерение скорости xu56857 Arduino 37 29.12.2017 21:43
Тепловоз ТЭП80 - наш рекордсмен скорости (271км/ч) Coyote ЖД техника 1 30.01.2016 00:04
Влияние скорости на свет Murat Электрика и DCC 2 22.08.2010 18:09
Как добиться снижения скорости лока? Sandro общий 20 22.07.2009 21:39
Регулирование скорости локомотива на аналоге qwer04061995 Электрика и DCC 11 17.09.2008 09:25


Текущее время: 01:51. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc. Перевод: zCarot
Copyright © ModelldepO.ru 2006 -