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

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

lazy-fox пишет:

18GT19HT пишет:

но можно же сделать цифровой и замаскировать под ламповый, или УНЧ сделать ламповым, ВЧ части на однокристальном FM приемнике

Это будет зависеть от того смогу ли увеличить ресурс ИН-12Б скажем до 25 лет. Корпус должен соответствовать содержанию. Может в полнакала тлеть пока газоанализатор на нуле, или гасить ночью или днём по будням.

т.к. индикация динамическая то каждая лампа работает 1/4 времени индикации, в остальное время она "не горит"

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

jeka_tm пишет:

уже делают вроде того))

http://radio-hobby.org/modules/newbb/viewtopic.php?topic_id=611&forum=11

комменты улыбнули ;)

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

18GT19HT пишет:

т.к. индикация динамическая то каждая лампа работает 1/4 времени индикации, в остальное время она "не горит"

20 000 часов лучше чем 5 000, но хуже чем искомые 200 000. Хочу внукам завещать.

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

Кстати, видел такой датчик? http://www.chipdip.ru/product/sn18b20/

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

lazy-fox пишет:

18GT19HT пишет:

т.к. индикация динамическая то каждая лампа работает 1/4 времени индикации, в остальное время она "не горит"

20 000 часов лучше чем 5 000, но хуже чем искомые 200 000. Хочу внукам завещать.

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

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

18GT19HT пишет:

Кстати, видел такой датчик? http://www.chipdip.ru/product/sn18b20/

я видел

http://ru.aliexpress.com/item/5pcs-Lot-Waterproof-DS18B20-Digital-Temper...

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

jeka_tm пишет:

18GT19HT пишет:

Кстати, видел такой датчик? http://www.chipdip.ru/product/sn18b20/

я видел

http://ru.aliexpress.com/item/5pcs-Lot-Waterproof-DS18B20-Digital-Temper...

ну типо того... заточи и тыкай в пищу

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

18GT19HT пишет:

ну типо того... заточи и тыкай в пищу

нафига?

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

тамже функция измерения температуры по ТЗ заложена

Kurzenev
Offline
Зарегистрирован: 17.09.2014

А вот я стесняюсь спросить- а что это разработчики на Arduino вдруг взялись использовать газоразрядные индикаторы?

Громоздкая штука, 200В на анод, управлять через 155ИД1, сказать, что очень красиво-ну, сложно.

В чем прелесть-то? Всякие ВЛИ, по-мокму, красивее будут, служат дольше, работать проще, (относительно, -27В тоже где-то надо взять).

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

Kurzenev пишет:

А вот я стесняюсь спросить- В чем прелесть-то? Всякие ВЛИ красивее...

Всякие ВЛИ 18GT19HT уже предлагались.

Они скорее напоминают 1980е, а мне нужно 1880е

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

18GT19HT пишет:

ну типо того... заточи и тыкай в пищу

Думал использовать от мультиметра.

Затачивать не надо, их есть у меня, да и прост как пробка.

Вот только его относительная компенсация весьма спорна.

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

А ты хочешь чтоб выглядело именно как телефон?

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

18GT19HT пишет:

А ты хочешь чтоб выглядело именно как телефон?

да. 

или настенный вариант:

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

Так никто не в курсе как по одному шагу сервой в секунду без delay() двигать? 

У меня 180 шагов(градусов), на которые по секунде я от нуля хочу натянуть серву на пружине, а потом разрядить её в ноль, что бы стукнуть молоточком по колоколу. Секундное тиканье сервой нужно в последнюю минуту таймера. По скольку градусов 180, а в минуте 60 секунд можно организовать принцип "два шага вперёд один назад" за секунду.

#include <Servo.h> // Подключаем библиотеку
Servo motor;  // Создаём инстанцию нашей сервомашинки

//Объявление глобальных переменных

//Сегменты табло через сдвиговый регистр 74HC595:
const int latchPin = 7;  //to ST_CP
const int clockPin = 6;  //to SH_CP
const int dataPin = 5;  //to DS

//Выводы выбора разряда индикатора
const int digit1Pin = 9;  //единицы
const int digit2Pin = 10;  //десятки
const int digit3Pin = 11;  //сотни
const int digit4Pin = 12;  //тысячи

//звуковая индикация
//const int buzzerPin = 3;
int ring = 2;

//номеронабиратель
const int dialPin = 2;

//рычаг
const int switchPin = 8;

//термодатчик
//const int termoPin = ;

//varDisplayRefreshTime - время индикации символа в микросекундах
//чем больше тем ярче, при значительно больших значениях - проявиться мерцание
const unsigned int varDisplayRefreshTime = 5000;

//varDisplayNextTime - расчетное время очередной индикации
unsigned long varDisplayNextTime = 0;

//varDysplayPosition - отображаемый разряд
byte varDysplayPosition = 0;

//varMode - режим работы
//0 - температура
//1 - N/U
//2 - таймер
//3 - часы
//4 - N/U
byte varMode = 3;

//varModeOld - предыдущий режим работы
byte varModeOld = 3;

//varSetMode - ожидание установки таймера
byte varSetMode = 0;

//Десятки секунд
unsigned long varTenSec;

//последнее состояние десятков секунд
byte varTenSecLast;

//минута
byte varMinuteCounter = 0;

//arrDysplaySymbols[11] - массив знакосинтезирующий
const byte arrDysplaySymbols[11] = 
  {
  252,
  96,
  218,
  242,
  102,
  182,
  190,
  224,
  254,
  246,
  0
  };

//arrCounter[5] - массив показаний для различных режимов работы
long arrCounter[5];

//vardialPinState - состояние на входе dialPin
byte vardialPinState = 1;

//vardialPinLastState - последнее состояние на входе dialPin
byte vardialPinLastState = 1;

//vardialReadyDigitNext - готовность к вводу следующего разряда
byte vardialReadyDigitNext = 0;

//vardialPinPulseLock - имульс зафиксирован
byte vardialPinPulseLock = 0;

//vardialCount - текущее количество циклов опроса dialPin
word vardialCount = 0;

//vardialCountMin - минимальное количество циклов для защиты от дребезга контактов
const word vardialCountMin = 3;

//vardialCountDigitNext - минимальное количество циклов для перехода к следующему разряду
const word vardialCountDigitNext = 100;

//vardialCountEndOfSet - минимальное количество циклов для завершения ввода
const word vardialCountEndOfSet = 15000;


//vardialChangeTime
long vardialChangeTime = 0;



void setup()
{
//конфигурирование портов ввода/вывода
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(digit1Pin, OUTPUT);
  pinMode(digit2Pin, OUTPUT);
  pinMode(digit3Pin, OUTPUT);
  pinMode(digit4Pin, OUTPUT);

  //pinMode(buzzerPin, OUTPUT);
  motor.attach(3); // Подключаем серву на 3 пин
  pinMode(dialPin, INPUT_PULLUP);
  pinMode(switchPin, INPUT_PULLUP);

//формирование на выводах начальных состояний
  digitalWrite(digit1Pin, HIGH);
  digitalWrite(digit2Pin, HIGH);
  digitalWrite(digit3Pin, HIGH);
  digitalWrite(digit4Pin, HIGH);

  Serial.begin(9600);  //отладка
//установка часов
  do
  {
    Display();
    dial(3);
    if (arrCounter[3] == 0) varSetMode = 1;
  } while (varSetMode == 1);
}

void loop()
{
  varTenSec = millis()/10000;
  varTenSec = varTenSec%10;
  Display();
  Clock();
  thermo();
  Display();
  dial(2);

//checkDialer();  //отладка
//out2con();  //отладка
}



//dial(*) - подпрограмма номеронабирателя
//* - режим работы для которого осуществляется ввод
void dial(byte varModeDial)
{
  vardialPinState = digitalRead(dialPin);
  if (vardialPinState != vardialPinLastState)
  {
    vardialChangeTime = millis();
  }
  if (vardialPinState == 1)
  {// вход врежим установки и подсчет импульсов
    if (varSetMode == 0)
    {// вход врежим установки
      varSetMode = 1;
      varMode = varModeDial;
      vardialCount = 0;
      arrCounter[varModeDial] = 0;
    }
    else
    {// подсчет импульсов
      if ((millis() - vardialChangeTime) > vardialCountMin && vardialPinPulseLock == 0)
      {
        if (vardialReadyDigitNext == 0 && varModeDial == 3)
        {
          arrCounter[varModeDial] *= 10;
        }
        arrCounter[varModeDial] ++;
        word varCounterDigitZero = arrCounter[varModeDial]%10;

        if (varCounterDigitZero == 0)
        {
          arrCounter[varModeDial] = arrCounter[varModeDial] - 10;
        }
        vardialPinPulseLock = 1;
        vardialReadyDigitNext = 1;
      }
    }
  }
  else
  {
    if (varSetMode == 0)
    {
      return;
    }
    else
    {// паузы и выход из режима установки
      if ((millis() - vardialChangeTime) > vardialCountMin)
      {
        vardialPinPulseLock = 0;
      }
      if ((millis() - vardialChangeTime) > vardialCountEndOfSet)
      {// выход из режима установки
        varSetMode = 0;
      }
      else if ((millis() - vardialChangeTime) > vardialCountDigitNext && vardialReadyDigitNext == 1)
      {// паузы
        if (varModeDial == 2)
        {
          arrCounter[varModeDial] *= 10;
        }
        //выполнить усечение arrCounter[varModeDial] до трех разрядов
        arrCounter[varModeDial] = arrCounter[varModeDial]%10000;
        vardialReadyDigitNext = 0;
      }
    }
  }
  vardialPinLastState = vardialPinState;
}



//thermo() - подпрограмма измерения температуры
void thermo()
{
  if (varSetMode == 1)
  {
    return;
  }
//контроль снятия с рычага
  if (digitalRead(switchPin) == LOW)
  {
    if (varMode != 0)
    {
      varModeOld = varMode;
      varMode = 0;
    }
//подпрограммы измерения температуры
  }
  else
  {
    if (varMode == 0)
    {
      varMode = varModeOld;
    }
  }
}



//Clock() - подпрограмма часов
void Clock()
{
  if (varTenSecLast != varTenSec)
  {
    varTenSecLast = varTenSec;
    varMinuteCounter ++;
    if (varMinuteCounter == 6)
    {
      varMinuteCounter = 0;
      arrCounter[3] ++;
      if (arrCounter[3]/10%10 == 6)
      {
        arrCounter[3] += 40;
      }
      if (arrCounter[3] >= 2400)
      {
        arrCounter[3] = 0;
      }
    }
    if (arrCounter[2] != 0)
    {
      if (varSetMode == 0)
      {
        Timer();
      }
    }
    else
    {
      if (varMode == 2)
      {
        varMode = 3;
      }
    }
  }
}


//Timer() - подпрограмма таймера
void Timer()
{
  arrCounter[2] --;
  if (arrCounter[2]%10 >= 6)
  {
    arrCounter[2] = arrCounter[2] - 4;
  }
  if (arrCounter[2] < 60) 
  {
    if (ring < 176) 
    {
      ring = ring + 2; //ставим на 2 градуса больше
      Serial.println (ring);
      motor.write(ring); 
    }
    if (ring < 180) 
    {
      ring = ring - 1; //ставим на 1 градус меньше
      Serial.println (ring);
      motor.write(ring); 
    }
  }
  if (arrCounter[2] == 1) //тут звеним в звнок
  {
    Serial.println (0);
    motor.write(0);
  }
  if (arrCounter[2] == 0) //выключаем
  {
//    varMode = 3;
    Serial.println (1);
    motor.write(1);
    //  motor.write(0); //серва гудит в нулевом положении
  }
}


//beepOn() - подпрограмма звуковой индикации
//void beepOn()
//{
//  analogWrite(buzzerPin, 127);
//}
//beepOff() - подпрограмма звуковой индикации
//void beepOff()
//{
//  analogWrite(buzzerPin, 0);
//}



//Display() - подпрограмма индикации
void Display()
{
  int digitPinOff;
  int digitPinOn;
  int DisplayDigital;
//  if (varDisplayNextTime <= micros() && varDisplayNextTime > micros() - varDisplayRefreshTime)
  if (varDisplayNextTime <= micros())
  {
    varDisplayNextTime += varDisplayRefreshTime;
    varDysplayPosition = varDysplayPosition + 1;
    if (varDysplayPosition > 4)
    {
      varDysplayPosition = 1;
    }
    switch (varDysplayPosition)
    {
      case 1:
        DisplayDigital = arrCounter[varMode]%10;
        DisplayDigital = arrDysplaySymbols[DisplayDigital];
        digitPinOff = digit4Pin;
        digitPinOn = digit1Pin;
      break;
      case 2:
        if (arrCounter[varMode] > 9 || varMode == 3)
        {
          DisplayDigital = arrCounter[varMode]/10%10;
          DisplayDigital = arrDysplaySymbols[DisplayDigital];
        }
        else
        {
          DisplayDigital = arrDysplaySymbols[11];
        }
        digitPinOff = digit1Pin;
        digitPinOn = digit2Pin;
      break;
      case 3:
        if (arrCounter[varMode] > 99 || varMode == 3)
        {
          DisplayDigital = arrCounter[varMode]/100%10;
          DisplayDigital = arrDysplaySymbols[DisplayDigital];
        }
        else
        {
          DisplayDigital = arrDysplaySymbols[11];
        }
        digitPinOff = digit2Pin;
        digitPinOn = digit3Pin;
      break;
      case 4:
        if (arrCounter[varMode] > 999)
        {
          DisplayDigital = arrCounter[varMode]/1000%10;
          DisplayDigital = arrDysplaySymbols[DisplayDigital];
        }
        else
        {
          DisplayDigital = arrDysplaySymbols[11];
        }
        digitPinOff = digit3Pin;
        digitPinOn = digit4Pin;
      break;
    }
    if (varMode == varDysplayPosition)
    {
      unsigned long varPointBlinkTime = millis()/500;
      varPointBlinkTime = varPointBlinkTime%10;
      varPointBlinkTime = varPointBlinkTime & B00000001;
      if (varPointBlinkTime == 1 || varSetMode == 1)
      {
        DisplayDigital = DisplayDigital ^ B00000001;
      }
    }
    digitalWrite(digitPinOff, HIGH);
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, DisplayDigital);
    digitalWrite(latchPin, HIGH);
    digitalWrite(digitPinOn, LOW);
  }
}



//отладка
void checkDialer()
{
  if (digitalRead(dialPin) == LOW)
  {
    arrCounter[1] ++;
    arrCounter[4] = 0;
  }
  else
  {
    arrCounter[1] = 0;
    arrCounter[4] ++;
  }
  Serial.print (arrCounter[1]);
  Serial.print ("\t");
  Serial.println (arrCounter[4]);
}



//отладка
void out2con()
{
  Serial.print ("Mode=");
  Serial.print (varMode);
  Serial.print ("\tt=");
  Serial.print (arrCounter[0]);
  Serial.print ("\tTimer=");
  Serial.print (arrCounter[2]);
  Serial.print ("\tClock=");
  Serial.print (arrCounter[3]);
  Serial.print ("\tSetMode=");
  Serial.print (varSetMode);
  Serial.print ("\tdialCount=");
  Serial.print (vardialCount);
  Serial.print ("\tdialPinLS=");
  Serial.print (vardialPinLastState);
  Serial.print ("\tdialPinS=");
  Serial.print (vardialPinState);
  Serial.print ("\t");
  Serial.println ();
}

 

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

А зачем так долго и вдумчиво взводить пружину? - там же есть "засечьки" (if (arrCounter[2] == ...) за десять секунд взводишь пружину сформировав на ШИМ выходе нужные импульсы, а при "0" сбрасываешь пружину

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

lazy-fox пишет:
...

Вспомнилась армейская Р-150 с этими индикаторами новенькая пахнущая еще свежим текстолитом, когда я на боевом дежурстве был.

Ну и дрянь эти иникаторы. Рядок длинный был в первый месяц новенькие сгорело 3 штуки. Я сразу отказался от этой дряни, потому как старушка Р-154 не забрали еще.

Глупость. Дрянь. Мальчик выкининь каку.

Портянки толком не высушишь. Хлеб оставшийся после обеда на боевом дежурстве в сухари не высушишь. Принимала она не скажу что лучше Р-154-ой или Р-250-ой. Выполеннена была в виде неподьемного шкафа от пола на высоту 2 метра. Если вдруг передислоцироваться надо будет переде стингером под ней тебя и похоронят. Там где в выборе частоты каждая цифра важна, меня задолбала срывать пломбу и перетыкивать эти лампы чтобы правильно выствалять. А за сутки дежурства частоту могли 4 раза поменять.

Со всей ответсвенностью заявляю Авно. Проверено на войне.

 

 

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

art100 пишет:

Ну и дрянь эти иникаторы. Со всей ответсвенностью заявляю Авно. Проверено на войне.

Для армии в СССР много чего ненужного делали. Одна Дуга к примеру чего стоит.

А индикаторы такие применялись в счетных машинах того же времени, что и Р-ка.

Вполне сносно работали. Причём я видел их же позднее сильно б/у, и могу сказать что проблемы возникали в частичном прогаре разрядов и знаков которые светят чаще. Были даже какие то методики восстановления разрядом существенно большего наприяжения. Но Вы правы, что их применение практичность прибора снизит.

Я думаю попробовать их имитировать. Взять к примеру не красный индикатор, а желтый и добавить подходящий светофильтр. А яркостью я упралять уже научился. Может получиться почти тлеющий теплый свет. Ну разве что без гламурного голубого фона в стеклянной лампе.

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

Визуальная индикация оказалась сложной, но решаемой задачей. Чего не скажешь о звуковом оповещении.

На первый взгляд все просто - два колокола, молоток на эл.магнитном приводе от порта ардуины.

Вариантов было рассмотрено много и на серве, и соленоид, и штатный телефонный (звенит громче и приятней):

По сему вопрос к уважаемому сообществу: как объяснить ардуине что на 3 цифровом выходе нужно при до достижении таймером указанного значения произвести серию импульсов напряжением 12 вольт. Планирую питать схему 12 вольтовым напряжением. Соответственно заменив плату ArduinoUno на контроллер с требуемой обвязкой (сдвиговик, крен, и тп) можно будет электрически что то добавить для усиления импульсов звонка.

//Timer() - подпрограмма таймера
void Timer()
{
  arrCounter[2] --;
  if (arrCounter[2]%10 >= 6) 
  {
    //Таймер считает десятками секунд
    arrCounter[2] = arrCounter[2] - 4;
  }
  if (arrCounter[2] =< 1) 
  {
    //тут звеним в звнок
  }
}