Кухонный таймер

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Итак, нужен кухонный таймер.

В качестве устройства ввода - неубиваемый телефонный диск, сам аппарат прослужил на кухне более 15 лет и остался полностью работоспособен. В качестве дисплея - четырёхразрядный индикатор, помните первые телефоны с АОН или например, как современные мультиварки с оранжевыми индикаторами. После ввода количества минут таймер отсчитывает их в обратном порядке до нуля. Последние 3 секунды звенит к звонок телефона. При наборе цифры, сдвигает разряд числа вверх и прибавляет набранное. В первых трёх разрядах индикатора - сотни, десятки и единицы минут, потом точка и в четвертом десятки секунд. Для сброса нужно доввести число более 9999, тогда высветится "0" и таймер перейдёт в режим отображения текущего времени. Дополнительно нужен термометр встроенный в ложку и закреплённый вместо трубки на витом проводе. При снятии ложки с рычага индикатор переходит в режим отображения температуры. Доплнительно будет полезен анализатор качества воздуха включающий вытяжку над плитой, а в случае присутствия газа - соответствующий сигнал. 

 

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Собственно схема электрическая принципиальная:

 

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Ниже привожу код:

// Порты ввода-вывода:
//Разряды табло:
int d1 = 12; 
int d2 = 11;
int d3 = 10;
int d4 = 9;
//Вероятно кнопка
// = 8; 
//Сегменты табло через сдвиговый регистр 74HC595:
int latchPin = 7;    //to ST_CP
int clockPin = 6;    //to SH_CP
int dataPin = 5;     //to DS
//Индикация и оповещение:
int buzzer = 4;
int led = 3;
//Пин номеронабирателя:
int in = 2; 
//Термометр
// = 1;
//Часы реального времени:
// = 0;

// Таймер:
long tm; //общий таймер в минутах
long cikl; //цикл таймера
long previousMillis = 0;        // храним время последнего переключения таймера
long interval = 1000;           // интервал таймера (1 секунда)
//int x = 100;
int del = 60; //Частота дисплея

//Номеронабератель:
int needToPrint = 0;
int count;           // Счетчик (для подсчета импульсов)
int lastState = LOW;
int trueState = LOW;
long lastStateChangeTime = 0;
int cleared = 0;
int dialHasFinishedRotatingAfterMs = 100;
int indicatorAfterMs = 1000;
int debounceDelay = 10;

void setup()
{
  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(d3, OUTPUT);
  pinMode(d4, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(buzzer,OUTPUT);
  pinMode(led,OUTPUT);
  pinMode(in, INPUT);
  Serial.begin(9600);
  int count = 0;  
  clearLEDs();
}

void loop(){
  // Этот код будет работать постоянно и не должен останавливаться на время между переключениями
  int reading = digitalRead(in);
  if ((millis() - lastStateChangeTime) > dialHasFinishedRotatingAfterMs) {
    // Цифра не набирается, или считывается последний импульс
    if (needToPrint) {
      // Этот код выполняется только когда считался последний имплульс
      // и необходимо вывести итоговую цифру в Serial port, и обнулить счетчик импульсов
      // Используем деление с остатком (%) на 10, т.к. цифра 0 - формируется десятью импульсами
      // 1%10  =  1
      // 2%10  =  2
      // ......
      // 10%10 =  0
      // Делаем расчёт остатка таймера и смещение
      tm = tm * 10 + count;  
      if (tm > 9999) tm = 0;
      // Чистим нумеронабиратель
      needToPrint = 0;
      count = 0;
      cleared = 0;
    }
  }
  if (reading != lastState) {
    lastStateChangeTime = millis();
  }
  if ((millis() - lastStateChangeTime) > debounceDelay) {
    if (reading != trueState) {
      trueState = reading;
      if (trueState == HIGH) {
        // увеличиваем счетчик на 1, если состояние пина HIGH
        count++;
        needToPrint = 1; // необходимо вывести итоговую цифру по окончанию вращения диска номеронабирателя
      }
    }
  }
  lastState = reading;
  //Таймер секундного цикла  
  if (tm > 0) {
    if (cikl == 0) cikl = millis();
    if ((millis() - cikl) > 600) {
      tm = tm - 0,01;
      //Вывод на индикатор
      D1();
      D2();
      D3();
      D4();
      //Serial.println(tm);
      cikl = millis();
    }
  }
}
// Подпрограммы
void D1()
{  
  pickDigit(1);
  pickNumber((tm/100)%10);
  delay(del);
}

void D2()
{
  pickDigit(2);
  pickNumber((tm/10)%10);
  delay(del);
}

void D3()
{
  pickDigit(3);
  pickNumber((tm)%10);
  //dispDec(3);
  delay(del);
}

void D4()
{
  pickDigit(4);
  pickNumber((tm*10)%10);
  delay(del);
}

void pickDigit(int x) 
{
  digitalWrite(d1, HIGH);
  digitalWrite(d2, HIGH);
  digitalWrite(d3, HIGH);
  digitalWrite(d4, HIGH);

  switch(x)
  {
  case 1: 
    digitalWrite(d1, LOW); 
    break;
  case 2: 
    digitalWrite(d2, LOW); 
    break;
  case 3: 
    digitalWrite(d3, LOW); 
    break;
  default: 
    digitalWrite(d4, LOW); 
    break;
  }
}

void pickNumber(int x)
{
  digitalWrite(latchPin, LOW);
  digitalWrite(latchPin, LOW);
  switch(x)
  {
  default: //zero
  shiftOut(dataPin, clockPin, LSBFIRST, 252);   
    break;
  case 1: 
    shiftOut(dataPin, clockPin, LSBFIRST, 96);  
    break;
  case 2: 
    shiftOut(dataPin, clockPin, LSBFIRST, 218);   
    break;
  case 3: 
    shiftOut(dataPin, clockPin, LSBFIRST, 242);   
    break;
  case 4: 
    shiftOut(dataPin, clockPin, LSBFIRST, 102);   
    break;
  case 5: 
    shiftOut(dataPin, clockPin, LSBFIRST, 182);
    break;
  case 6: 
   shiftOut(dataPin, clockPin, LSBFIRST, 190);  
    break;
  case 7: 
     shiftOut(dataPin, clockPin, LSBFIRST, 224);   
    break;
  case 8: 
  shiftOut(dataPin, clockPin, LSBFIRST, 254);   
    break;
  case 9: 
    shiftOut(dataPin, clockPin, LSBFIRST, 246);  
    break;
  }
  digitalWrite(latchPin, HIGH);
}

void dispDec(int x)
{
  digitalWrite(latchPin, LOW);
    digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, 1);  
    digitalWrite(latchPin, HIGH);
}

void clearLEDs()
{
  digitalWrite(latchPin, LOW);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, 0);   
  digitalWrite(latchPin, HIGH);
}

//void ringer()
//{
//  digitalWrite(buzzer,HIGH);//sound
//  delay(100);//delay 1ms
//  digitalWrite(buzzer,LOW);//sound
//  delay(200);//delay 1ms
//}
//void term()
//{
//  //тут получаем температуру
//}
//void lamp()
//{  
//  digitalWrite(led,HIGH);//light up red lamp
//  delay(100);//delay 1000 ms = 1 s
//  digitalWrite(led,LOW);//go out red lamp
//  delay(100);//delay 1000 ms = 1 s
//}
//void buzz()
//{
//  digitalWrite(buzzer,HIGH);//sound
//  delay(5000);//delay 1ms
//  digitalWrite(buzzer,LOW);//sound
//  delay(2000);//delay 1ms
//}






 

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Проблема 1: После вывода в разряд индикатор горит только до вывода в следующий разряд

100       //Вывод на индикатор
101       D1();
102       D2();
103       D3();
104       D4();

Что не так? Как исправить?

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Проблема 2: Таймер никак не хочет считать обратно, и тем более выводить на индикатор десятки секунд

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Araris пишет:

Расчудесный список "хотелок". С воображением и фантазией у автора все прекрасно.

Это лишь основные моменты. Я про корпус ещё не сообщал ;)

Кстати тема задублировалась. Прошу администрацию сообщения перенести сюда, а дубликат http://arduino.ru/forum/proekty/kukhonnyi-taimer-0 удалить.

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Да, чуть совсем не забыл!

Источники:

1. Дисковый номеронабератель http://diy-blog.net/podklyuchenie-diskovogo-nomeronabiratelya-k-arduino/

2. Сдвиговый регистр http://arduino.ru/Tutorial/registr_74HC595

3. Индикатор http://www.rubachek.com/node/130

Были несомненно другие, но сейчас уже не вспомню.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

мельком глянул

1. если хватает выводов зачем сдвиговый регистр? он время тратит. зачем огород городить, или не знаете куда применить сдвиговый регистр?

2. считывать номеронабиратель лучше по прерываниям

3. что за странный набор резисторов для номеронабирателя. насколько помню там просто механика. должно и внутренних подтягивающих хватить. ну может максимум мелкий кондер параллельно подцепить от дребезга

4. если сделаете как предлагал выше код достаточно сильно уменьшится

5. есть ли смысл собирать свое если готовый кажется рублей 50 стоит? но если все же хочется свое почему бы и нет. хотя выбор устройства ввода странный, но это ваше дело

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Jeka_tm >>

1. Выводов кастрофически не хватает. Экономия в пять выводов одной микросхемой в ущерб скорости оправдано.

2. Пример в студию

3. Нужно сделать один уровень во время импульса набора, и другой уровень в момент размыкания. В оригинале было 440 Ом и 10 кОм

4. См пп2

5. Если винтажный и функциональный прибор по ТЗ найдется готовый - готов приобрести.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

1. если выводов не хватает прицепите втрой сдвиговый регистр. еще 4 вывода освободится

сдвиговый регистры в принципе лучше заменить на MAX7219. и проще и выводы экономит, и процессор почти не тратит если не постоянно отправлять цифры на индикатор, а только при изменении

2. а смысл? железка собрана?

3. 0 и 5В плохие уровни?

4. см п.2

5. не такой врядли есть, лучше конечно если хочется собрать свой

 

lazy-fox
Offline
Зарегистрирован: 22.08.2014
jeka_tm пишет:

2. считывать номеронабиратель лучше по прерываниям

4. если сделаете как предлагал выше код достаточно сильно уменьшится

 
Забудем пока про таймер. Напишите код как ардуине считать по прерываниям набор номера.

Что такое прерывания я знаю. Не знаю как реализовать физически и программно на ардуино. Научите.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

неа. люди совсем обнаглели. ни спасибо ни пожалуйста. сами делайте, идею я подал

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Да просто идей про прерывания на ардуино слышал уже море, а как спросишь пример на Uno + кнопка - сразу в кусты все разбегаются! Идея по прерываниям работать - согласен неплохая. Но реализована она только внутри. Пользователю ее не дают юзать. 

По этому лучшее что пока нашел - millis(). Эта функция возвращает кол-во милисикунд с момента запуска. Можно в общем цикле сравнивать ее со своим же значением (минус продолжительность цикла) в момент прошлого действия: 

062   if ((millis() - lastStateChangeTime) > dialHasFinishedRotatingAfterMs) {
         ...
     }
jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да ладно))

http://arduino.ru/Reference/AttachInterrupt

пользуйся

vdk
Offline
Зарегистрирован: 14.04.2013

А поискать пример вааще никак?

Вот, например, что первым находится

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Вот это уже по делу! А то все слова, слова...

Сама идея использования прерываний для ввода - хороша. Но в моем случае функция millis() все равно останется, по крайней мере для вывода на индикатор. Как выяснилось индикатор светит только в один регистр одновременно (или во все но одинаковое значение). А светить мне нужно периодически (динамически). 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

MAX7219

vdk
Offline
Зарегистрирован: 14.04.2013

lazy-fox пишет:

 А светить мне нужно периодически (динамически). 

И как этакое сделать - это мы должны думать, да?

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Повторно изучил даташит и примеры по MAX7219. Остались вопросы. 

На сколько я понимаю предлагаемый драйвер семирегистровый. У меня четыре регистра. Есть такой?

Внутри представляет собой тот же сдвиговый регистр, но управляется по модной шине SPI.  Полагал что эта шина нужна для взаимодействия между устройствами.

Например, если у меня будет центральный таймер в коридоре с выходом в интернет, и я захочу с него обмениваться информацией с периферийными таймерами - кухонным (сварились ли пельмени), комнатным(будильник прикроватный с монитором сна), и балконным(телескоп следящий за положением тел в альфа-центавре), а так же таймерами робота-пылесоса и робота-пивовара, - тогда да без SPI не обойтись, а тут?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

еще раз изучите, почитайте статьи а то глупость написали

а прочитайте еще то что я написал когда предлагал 7219 первый раз

не обязательно по хардварному spi если так пугает

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Путём нехитрых преобразований, благодаря PSD часть кода, отвечающего за индикацию была доработана:

//Сегменты табло через сдвиговый регистр 74HC595:
int latchPin = 7;    //to ST_CP
int clockPin = 6;    //to SH_CP
int dataPin = 5;     //to DS
//Переменные необходимые для индикации
int tm = 0;
int DisplayDigital = 0;   //значение индикатора
byte DisplaySymbol[12]={252, 96, 218, 242, 102, 182, 190, 224, 254, 246, 0};   //массив знакосинтезирующий - заполнить соттветствующим образом
unsigned int DisplayTime = 5000;   //время индикации символа в микросекундах (чем больше тем ярче, при значительно больших значениях - мерцание)
byte DysplayLastPosition = 0;   //последний отображаемый разряд
unsigned long DisplayLastTime = 0;   //последнее время индикации

void setup(){
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(d3, OUTPUT);
  pinMode(d4, OUTPUT);   
  digitalWrite(d1, HIGH);
  digitalWrite(d2, HIGH);
  digitalWrite(d3, HIGH);
  digitalWrite(d4, HIGH);
}

void loop(){
  
  tm = millis() / 100;
  //вызов функции индикации. необходимо разумно включить вызов функции из  разных частей программы
  Display(tm);
}

void Display(int DisplayVal){
  if (micros() >= DisplayLastTime + DisplayTime || micros() <  
    DisplayLastTime)
  {
    DisplayLastTime = micros();
    DysplayLastPosition = DysplayLastPosition + 1;
    if (DysplayLastPosition > 4)
    {
      DysplayLastPosition = 1;
    }
    digitalWrite(latchPin, LOW);
    switch (DysplayLastPosition){
    case 1:
      DisplayDigital = DisplayVal/100%10;
      digitalWrite(d4, HIGH);
      if (DisplayVal>99) shiftOut(dataPin, clockPin, LSBFIRST, DisplaySymbol[DisplayDigital]);
      else shiftOut(dataPin, clockPin, LSBFIRST, DisplaySymbol[11]);
      digitalWrite(latchPin, HIGH);
      digitalWrite(d1, LOW);
      break;
    case 2:
      DisplayDigital = DisplayVal/10%10;
      digitalWrite(d1, HIGH);
      if (DisplayVal>9) shiftOut(dataPin, clockPin, LSBFIRST, DisplaySymbol[DisplayDigital]);
      else shiftOut(dataPin, clockPin, LSBFIRST, DisplaySymbol[11]);
      digitalWrite(latchPin, HIGH);
      digitalWrite(d2, LOW);
      break;
    case 3:
      DisplayDigital = DisplayVal%10;
      digitalWrite(d2, HIGH);
      //shiftOut(dataPin, clockPin, LSBFIRST, 1); //это точка. хорошо бы тут ей моргать, но видимо придётся сделать ещё один массив для третьего разряда с точкой
      if (DisplayVal>0,9) shiftOut(dataPin, clockPin, LSBFIRST, DisplaySymbol[DisplayDigital]);
      else shiftOut(dataPin, clockPin, LSBFIRST, DisplaySymbol[11]);
      digitalWrite(latchPin, HIGH);
      digitalWrite(d3, LOW);
      break;
    case 4:
      DisplayDigital = DisplayVal*10%10;
      digitalWrite(d3, HIGH);
      if (DisplayVal>0,01) shiftOut(dataPin, clockPin, LSBFIRST, DisplaySymbol[DisplayDigital]);
      else shiftOut(dataPin, clockPin, LSBFIRST, DisplaySymbol[11]);
      digitalWrite(latchPin, HIGH);
      digitalWrite(d4, LOW);
      break;
    }
  }
}

Остались открытыми вопросы мерцания точкой раз в секунду (фактически при перерисовке индикатора), а так же вывод в четвертый разряд дробной части числа - десятки секунд.

18GT19HT
Offline
Зарегистрирован: 23.08.2014

А что касается резисторов и подключения номеранабирателя используй встроенные подтягивающие резисторы. Описание: http://arduino.cc/en/Tutorial/InputPullupSerial

 

"Десятки секунд"





unsigned long timeTSec;

void setup()
{
  Serial.begin(9600);
}

void loop(){
//десятки секунд
  timeTSec = micros()/10000000;
  timeTSec = timeTSec%10;
  Serial.println(timeTSec);
}

 

18GT19HT
Offline
Зарегистрирован: 23.08.2014

Мигание точкой



//объявление переменных
unsigned long PointBlinkTime = 0;
byte PointBlinkLastTime = 0;


//встроить в case3
  PointBlinkTime = micros()/500000;
  PointBlinkTime = PointBlinkTime%10;
  PointBlinkTime = PointBlinkTime & B00000001;
  if (PointBlinkTime = PointBlinkLastTime)
  {
    PointBlinkLastTime = PointBlinkTime;
  //"перебрасывает" выводящий точку пин - изменить в соответствии со схемой
    DisplaySymbol[DisplayDigital] = DisplaySymbol[DisplayDigital] ^ B10000000;
  }

 

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Про подтягивающие сопротивления - здорово. Попробую использовать.

Что касается проекта в целом вижу основную проблему в единицах и приведении типов.
Мы вводим целые значения с номеронабирателя. Добавляем тоже только целые.
Таймер должен отнимать целые единицы секунд или 1,6 минуты (что бы мерцать точкой), а это уже float.
Выводим на индикацию по разрядам раздельно так же целыми, но прорисовываем весь индикатор.

Напрашивается вывод перевести всё во float, но тогда не катит %

18GT19HT
Offline
Зарегистрирован: 23.08.2014

Не нужен тебе float! int должно хватать за глаза. Точка у тебя логическая\виртуальная, а не математическая.

lazy-fox
Offline
Зарегистрирован: 22.08.2014

18GT19HT пишет:

Не нужен тебе float! int должно хватать за глаза. Точка у тебя логическая\виртуальная, а не математическая.

Тогда нужно обращаться к разрядам индикатора как к символьным полям. Сейчас я 123.5 минуты вывожу, а когда таймер до нуля досчитает выведу текущее время 14.32

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

может проще нормально писать? 5 часов 3 минуты

18GT19HT
Offline
Зарегистрирован: 23.08.2014

lazy-fox пишет:

18GT19HT пишет:

Не нужен тебе float! int должно хватать за глаза. Точка у тебя логическая\виртуальная, а не математическая.

Тогда нужно обращаться к разрядам индикатора как к символьным полям. Сейчас я 123.5 минуты вывожу, а когда таймер до нуля досчитает выведу текущее время 14.32

В основном цикле (loop) необходимо закодировать таймер, а прога индикации сама разобьет на разряды и отрисует.

18GT19HT
Offline
Зарегистрирован: 23.08.2014

Попробуй еще раз описать алгоритм работы устройства, хотя бы человеческим языком, так что бы получилась связанная картина конечных состояний с определением всех возможных комбинаций режимов и пределами вводимых/выводимых значений - потом останеться просто описать это программе.

lazy-fox
Offline
Зарегистрирован: 22.08.2014

18GT19HT пишет:

Попробуй еще раз описать алгоритм работы устройства, хотя бы человеческим языком, так что бы получилась связанная картина конечных состояний с определением всех возможных комбинаций режимов и пределами вводимых/выводимых значений - потом останеться просто описать это программе.

Пробую. Есть несколько (пять) режимов работы устройства:

1. Таймер в минутах (999.5 - _ _0.0) шаг 0.1 мин, точка в третьем разряде.
Во время ввода номера значение таймера округляется нвиз до целого, увеличивается на порядок и прибавляется введённая цифра. Вводится только целое число.

2. Время, отображается когда таймер равен нулю (_0.00 - 23.59) шаг 1 мин и точка во втором разряде

3. Градусник, когда поднят рычаг  (_ _ _0. - 9999.) , в градусах цельсия.

4. Газоанализатор при изменении уровня загрязнения воздуха (0.000 - 9.999), регулирует обороты вытяжки.

5. Процент природного газа в воздухе, пока не снять/повесить рычаг (.0000 - .9999), инициирует звуковую сигнализацию.

Точка всегда мигает раз в секунду.

P.S.: Планировал начать с главного и последовательно наращивая функционал получить вышеназванное.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Это не алгоритм, это хотелки.

18GT19HT
Offline
Зарегистрирован: 23.08.2014

Для начала и это что-то.

Переход между режимами таймер время: нет таймера - значит время

Переход от режимов время/таймер к измерению температуры и обратно: по событию рычага

А как осуществляется переход к режимам газ и из каких режимов - я запутался

lazy-fox
Offline
Зарегистрирован: 22.08.2014

18GT19HT пишет:

Для начала и это что-то.

Переход между режимами таймер время: нет таймера - значит время

Переход от режимов время/таймер к измерению температуры и обратно: по событию рычага

А как осуществляется переход к режимам газ и из каких режимов - я запутался

Нет таймера-значит время

рычаг - это кнопка в восьмой строке кода. Если нажата режим "время/таймер", если отпущена "термометр".

газ меряется периодически (раз в минуту) в фоновом режиме и в случае утечки газа - гудит, в случае низкого качества воздуха - увеличивает обороты вытяжки. Вероятно это два разных датчика. Они выводятся на индикатор при наступлении заданных пороговых значений на несколько секунд в любом режиме

Предполагал, что в основном цикле будет такой алгоритм: ММ-получаем время, СС-проверяем таймер (если есть отнимаем единицу), СС-проверяем рычаг (если снят меряем температуру), ММ-меряем воздух, ММ-меряем газ, СС-выводим на индикатор, СС-звеним (если таймер 0>3), СС-гудим (если газ>предел утечки),  ПП-набираем номер

ММ - событие раз в минуту, СС - раз в секунду, по прерыванию

lazy-fox
Offline
Зарегистрирован: 22.08.2014

К вопросу о звуковом оповещении. Начнем с простого пьезоэлемента. Если я его применю, то при наличии предельной концентрации газа в воздухе в пьезоэлементе произойдет разряд и я рискую услышать несколько более громкий щелчек с кухни?

18GT19HT
Offline
Зарегистрирован: 23.08.2014

lazy-fox пишет:

К вопросу о звуковом оповещении. Начнем с простого пьезоэлемента. Если я его применю, то при наличии предельной концентрации газа в воздухе в пьезоэлементе произойдет разряд и я рискую услышать несколько более громкий щелчек с кухни?

В пьезоизлучателе, а равно как и магнитодинамической системе той или иной конструкции, открытый разряд, так сказать, не предусмотрен конструкцией

lazy-fox
Offline
Зарегистрирован: 22.08.2014
int in = 0;    // Номер прерывания, которое будет вызыватся. Не номер контакта! Контакт которому соответствует прерывание - 2
void setup() 
{
attachInterrupt(in,nabor,RISING); // Параметры прерывания
int nm;
int tm;
}

// Функция которая будет выполнятся при наборе номера
void nabor() 
{
nm = ... //код номеронабирателя
}

void loop() 
{
if nm >0{
tm = tm*10+nm;
}
}

Пока предварительно осваиваю номеронабиратель по прерываниям...

18GT19HT
Offline
Зарегистрирован: 23.08.2014

А напиши как у тебя соединены сегменты (не разряды) индикатора с регистром - необходимо для правильного кодирования знакосинтезирующего массива.

A, B, C, D, E, F, G, DP

Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7

lazy-fox
Offline
Зарегистрирован: 22.08.2014

18GT19HT пишет:

А напиши как у тебя соединены сегменты (не разряды) индикатора с регистром - необходимо для правильного кодирования знакосинтезирующего массива.

A, B, C, D, E, F, G, DP

Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7

Все верно. Если я правильно понимаю, нужно подтвердить это:

В изначальной схеме, после визуальной трассировки проводников были исправлены некоторые неточности.

На всякий случай - соответствия сегментов

art100
Offline
Зарегистрирован: 09.03.2014

lazy-fox пишет:
...сегменты...разряды...индикатора...регистром...
врукопашную

Светодиоды большие это важная часть?

Может ну их к лешему.

Пошли ты лесом этих советчиков раз готового кода с регистром сдвиговым не дают.

Я диплом на 5 написал в свое время с регистром сдвиговым и больше по мне не барское это дело счетами ковыряться паяльником разводить если готовое заводское можно купить и код простой как грабли.

А может есть простой LCD1602 с контроллером запоминающим за 4$

http://ru.aliexpress.com/item/Free-Shipping-High-Quality-5V-Screen-White-Character-Blue-Backlight-LCD-Module-1602-for-Arduino/1772760469.html

////art100 to write 20140827 Дисковый Номеро Набираетель попользуем
#include <LiquidCrystal.h>
//pins---------------------------------
#define NN       2 // номеро набиратель
#define BUTTON1  3 // клавиша трубки
LiquidCrystal lcd(4,5,6,7,8,9);//LiquidCrystal lcd(8,9,10,11,12,13);//uno
/* 16x2 LCD  compatible with the  Hitachi HD44780 driver
1 +5v
2 pin1-20k-pin3
3 gnd
4 RS    - 4
5 gnd
6 E     - 5
11 LCD D4 pin to digital pin 6
12 LCD D5 pin to digital pin 7
13 LCD D6 pin to digital pin 8
14 LCD D7 pin to digital pin 9
15 Anod  +5V nc
16 Katod gnd nc
 */
#define SPRK1   10 // ШИМ
#define RELE1   11 // ШИМ
#define LED13   13 // контролька
.....
//------------------------------------------------
void setup(){
  pinMode(LED13,OUTPUT);digitalWrite(LED13,HIGH);//контролька
  lcd.begin(16, 2);// set up the LCD's number of columns and rows: 
  lcd.clear();
  Serial.begin(9600);
  pinMode(NN,      INPUT_PULLUP);
  pinMode(BUTTON1, INPUT_PULLUP);
  pinMode(SPRK1,OUTPUT); // ШИМ
  pinMode(RELE1,OUTPUT); digitalWrite(RELE1,LOW);// ШИМ
  lcd.setCursor(0,0);lcd.print("art100 Power var");
}
//=================================================
void loop(){

  // NN--знакомый код да?---------------------------------------------------------------------------
  int reading = digitalRead(NN);
  if ((millis() - lastStateChangeTime) > dialHasFinishedRotatingAfterMs) {
    // Цифра не набирается, или считывается последний импульс
    ...
      // 2%10  =  2
      // ......
      // 10%10 =  0
    number=count%10;
    PowerTmp=number;
    ...
  }
  lastState = reading;
  // NN-----------------------------------------------------------------------------

  //PWM- ну тут ты своего понавстявляй что у тебя там две цифры сравнения час мин часвременная минвременная затем рубим--
  if(PowerTmp==1){ digitalWrite(RELE1,HIGH); lcd.setCursor(0,1); lcd.print(" 220v = "); lcd.setCursor(8,1); lcd.print(number); lcd.print("   ON "); }//
...
  if(PowerTmp==0){ digitalWrite(RELE1, LOW); lcd.setCursor(0,1); lcd.print(" 220v = "); lcd.setCursor(8,1); lcd.print(number); lcd.print("  OFF "); }//
//  if(digitalRead(BUTTON1)==LOW){ digitalWrite(RELE1,LOW); }//
  //-
//  }
  //PWM-----------------------------------------------------------------------------

}
// че тут кода то писать то мне 5 часов хватило

 

lazy-fox
Offline
Зарегистрирован: 22.08.2014

QC1602A v2.0 мне замечательно знаком и в наличии имеется. Кириллицы в нем нет. По-этому нормально писать он всё равно не сможет

jeka_tm пишет:
может проще нормально писать? 5 часов 3 минуты

Тем более он может быть удобен для работы с прибором в непосредственной близости, я бы сказал "на расстоянии вытянутой руки", ибо дальше разглядеть показания вряд ли будет возможно. В моём случае таймер будет закреплён на стене, над плитой, под вытяжкой. Это место замечательно просматривается с любой точки кухни. Расчётное расстояние непринуждённого  обзора от 0.3 до 3.5 метров.

art100
Offline
Зарегистрирован: 09.03.2014

lazy-fox пишет:

QC1602A v2.0 мне замечательно знаком и в наличии имеется. Кириллицы в нем нет. По-этому нормально писать он всё равно не сможет

jeka_tm пишет:
может проще нормально писать? 5 часов 3 минуты

Тем более он может быть удобен для работы с прибором в непосредственной близости, я бы сказал "на расстоянии вытянутой руки", ибо дальше разглядеть показания вряд ли будет возможно. В моём случае таймер будет закреплён на стене, над плитой, под вытяжкой. Это место замечательно просматривается с любой точки кухни. Расчётное расстояние непринуждённого  обзора от 0.3 до 3.5 метров.

А что у нас с русскими? Я вообще не в теме про русские. Я как-то станки делаю и тут всегда латиница. Какой-то русский индиктор с контроллером специальным надо пкупать? CCылочку? Я свой индикатор и телефон практически из мусорки достал. Индикатору наверно вообще лет 15. Телефону 54 года.

 

18GT19HT
Offline
Зарегистрирован: 23.08.2014

art100 пишет:

Пошли ты лесом этих советчиков раз готового кода с регистром сдвиговым не дают.

Наполовину сделанную работу не показывают...

В очередной раз переписал программу индикации - теперь с мерцанием точки. Покажу после кодирования часов и таймера.

art100
Offline
Зарегистрирован: 09.03.2014

чтоб кода дурного не писать видно как девять ножек протянул?

всегото надо в нижнюю строчка пошла нижняя строчка

lcd.setCursor(0,1); lcd.print(" 220v = "); lcd.setCursor(8,1); lcd.print(number); lcd.print("   ON ");

Вот кода для сдвигового регистра и 4 семисегментников дадут пусть зубоскалят.

Там еще таймера расписавать больше дня.

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

art100 ты че там бухой чтоли? бред уже начинаешь писать. читай хоть внимательнее

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Я процитировал предложение "нормальной" индикации jeka_tm "5 часов 3 минуты".  Слова "часов" и "минут" написаны по русски. Так не получится на 1602А, да и не видно будет символы высотой 4 мм с расстояния в 3.5 метра. Существуют индикаторы с русскими таблицами символов. Скажу больше, можно символы генерить и выводить побитно. Я забил написав 12 русских букв (столько нужно было для проекта).

//Буква Ю
byte U[SYMBOL_HEIGHT] =
{
  B10010,
  B10101,
  B10101,
  B11101,
  B11101,
  B10101,
  B10101,
  B10010,
};

В Вашем случае, конечно, использование именно такого индикатора оправдано.

art100
Offline
Зарегистрирован: 09.03.2014

jeka_tm пишет:

art100 ты че там бухой чтоли? бред уже начинаешь писать. читай хоть внимательнее

а в чем вопрос? ТС неделю индикатор завести не может Ну ладно попробую это все переичать. Хороводы вокруг регистра водите.

 

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да не так дословно. напишу точнее вместо 125.5 писать 05:03

lazy-fox
Offline
Зарегистрирован: 22.08.2014

Да, по ходу art100 сам телефон дзержинского от сети 220 вольт запитал, вот его и не отпускает.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да при чем тут индикатор. он у меня просил код для прерываний для номеросчитывателя. не включай барана, пишу это уже не первый раз

art100
Offline
Зарегистрирован: 09.03.2014

Не столько бУкАв я осилить не смог.

Мне завести телефон-arduino-LCD-PWM хватило вместе со слесарской работой 1-ого дня.

Я не могу постичь чего вы тут обсуждаете.

Перепись железа отсутсвует

Схема железа отсутствует.

Какая-то бадяга про код.

Код работы с НомероНабирателем 100% рабочий.

Я пас. Пойду рюмашку наливочки пока жена не видит опрокину.

Извыняй Жека если чо не так. Ногами не бейте.

 

 

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да ладно проехали

код рабочий только если только он работает, так как прерываний не требуется

но когда индикатор через сдвиговый регистр подключен, динамическая индикация, соответственно постоянное ногодрыганье, и тут можно пропустить импульс с номеронабирателя, поэтому и писал что лучше через прерывания