Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.



RC5

Сообщений 61 страница 80 из 80

61

Еще прграмка с использованием RC5. Обучение под любые кнопки пульта.
Рассчитана только под пульты RC5-6. Они доступны. Стоят в районе 200р. RTC использую DS3231. От DS1307 давно отказался. Сильно бегают по времени. RC5 используется только для экономии портов(вместо кнопок). КР514ИД1 использую для отладки.  В дальнейшем индикатор будет собран на высоковольтных неоновых, и дешифратор будет стоять К155ИД1. 9 портов для каждого символа это уже много, и все равно ИНки кроме цифр отображать больше ничего не умеют.  Поэтому знак минус выведен на отдельный порт.
Частоту догнал до 16мГц, из-за ненужных морганий сегментов. Думаю при опросе 18в20 с прерываниями накладки происходят. Может чего спецы посоветуют.

Код:
$regfile = "m8adef.dat"                                     ' тип МК
$crystal = 16000000                                         ' выбор кристала для расчета задержек

' Open "comb.0:9600,8,n,1" For Output As #1
'*****************************************[Определение переменных и констант]************************************

Dim I(6) As Word                                            ' четыре разряда
Dim Count As Byte                                           ' счетчик для перебора разрядов
Dim Count_blink As Byte                                     ' счетчик длительности мигания точки
'***********************************************
Dim Sstr As String * 6
Dim Ind_str As String * 1
Dim K As Byte
Dim L As Byte
Dim W As Byte
'=====конфигурация I2C интерфейса scl и sda пины
'===============================================================================
Config Sda = Portc.4                                        ' I2C Data
Config Scl = Portc.5                                        ' I2C Clock
   Config I2cdelay = 1                                      ' Скорость работы шины I2c на программном уровне
   I2cinit
   Waitms 50
'=====заводим константы на биты чтения и записи ds3231
Const Ds3231w = &HD0                                        ' бит записи
Const Ds3231r = &HD1                                        ' бит чтения
'===========переменные для работы датчика температуры DS3231
'===============================================================================
Declare Sub Ds3231
Dim Tds3231_bcd As Integer
Dim Temper_z As Byte At Tds3231_bcd + 1 Overlay             ' целая часть температуры со знаком
Dim Temper_d As Byte At Tds3231_bcd + 0 Overlay             ' дробная часть
Dim Tds3231 As Integer
Dim Tds3231_str As String * 5
'=====переменные для работы с DS3231
'===============================================================================
'=====в десятичном формате
Dim Seco As Byte
Dim Mine As Byte
Dim Hour As Word
Dim Day As Byte
Dim Dat As Byte
Dim Month As Byte
Dim Year As Byte
'=====в двоично-десятичном формате
Dim Seco_bcd As Byte
Dim Mine_bcd As Byte
Dim Hour_bcd As Byte
Dim Day_bcd As Byte
Dim Dat_bcd As Byte
Dim Month_bcd As Byte
Dim Year_bcd As Byte
'=====в текстовом формате
Dim Secostr As String * 2
Dim Minestr As String * 2
Dim Hourstr As String * 2
'=============================================================================
Dim Address As Byte
Dim Command As Byte
Dim Flag As Byte
Dim Flagstr As String * 1
Dim Menu As Bit
Dim Время(6) As Byte
Dim Время_str(6) As String * 2
Dim H As Byte
Dim Hstr As String * 1
'команды хранящиеся в EEPROM
Dim Ee1 As Eram Byte
Dim Ee2 As Eram Byte
Dim Ee3 As Eram Byte
Dim Ee4 As Eram Byte
Dim Ee5 As Eram Byte
Dim Ee6 As Eram Byte
Dim Ee7 As Eram Byte
'команды для сравнения с командами с пульта
'-----------------------------------------------------------------------------
Dim Aa1 As Byte
Dim Aa2 As Byte
Dim Aa3 As Byte
Dim Aa4 As Byte
Dim Aa5 As Byte
Dim Aa6 As Byte
Dim Aa7 As Byte
'Переменные 1 датчика 18В20
'============================================================================================================
Dim Tds1 As Integer                                         'температура получаемая с 1 датчика в 0.1градуса. 10 = 1,0 градус
Dim Tds1_str As String * 4
Dim Err_c1 As Bit                                           'ошибка датчика
'Переменные 2 датчика 18В20
'============================================================================================================
Dim Tds2 As Integer                                         'температура получаемая с 1 датчика в 0.1градуса. 10 = 1,0 градус
Dim Tds2_str As String * 4
Dim Err_c2 As Bit                                           'ошибка датчика
'***********************************************[Инициализация портов]*******************************************
Ddrb = &B00111111                                           ' разряды индикатора (выходы), 2 кнопки (входы)
Portb = &B00111111                                          ' разряды выключены, кнопки к питанию подтянуты
'-------------------------
Ddrd = &B00111111                                           ' сегменты индикатора (выходы)
Portd = &B00000000                                          ' сегменты выключены
'-----------------------------------------------------------------------------
Config Pinc.3 = Input                                       'Кнопка валкодера
Pult Alias Pinc.3
'*********************************************[Инициализация прерываний]*****************************************
Const Ds1820 = 100
Config Timer0 = Timer , Prescale = 256                      ' конфигурируем таймер (~250 Гц)
On Timer0 Refresh                                           ' обзываем прерывание
'-----------------------------------------------------------------------------
Config Rc5 = Pinc.2 , Timer = 1 , Wait = 2000               'конфигурируем ногу для подключения датчика RC5
'-----------------------------------------------------------------------------
Enable Interrupts                                           ' разрешаем все прерывания
Enable Timer0                                               ' и для таймера в частности (индикация)

Declare Sub Look_timer()
'********************************************[Присвоение уникальных имен]****************************************
Dig1 Alias Portb.0 : Dig2 Alias Portb.1 : Dig3 Alias Portb.2 : Dig4 Alias Portb.3 : Dig5 Alias Portb.4 : Dig6 Alias Portb.5 : Dot Alias Portd.0
A Alias Portd.1 : B Alias Portd.2 : C Alias Portd.3 : D Alias Portd.4 : E Alias Portd.5
'*********************************************[Начало основной программы]****************************************
'-----------------------------------------------------------------------------
'вытаскиваем значения команд из энергонезависимой памяти и присваиваем рабочим переменным
'-----------------------------------------------------------------------------
Aa1 = Ee1
Aa2 = Ee2
Aa3 = Ee3
Aa4 = Ee4
Aa5 = Ee5
Aa6 = Ee6
Aa7 = Ee7

L = 1 : K = 0 : Menu = 0
'******************************************************************************************
Do

 Getrc5(address , Command)                                  'принимаем адресс и команду с пульта
  If Address = 0 Then                                       'работаем с любым пультом
      Command = Command And &B01111111

    If Flag = 0 Then
        Select Case Command
         Waitms 300
           Case Aa1 : Toggle Menu                           'Входим в меню установки
           Case Aa2 : Incr H                                'Выбираем, что будем утанавливать
           Case Aa3 : Decr H                                '
           Case Aa4 : Incr Время(h)                         'Увеличиваем значение Год, Месяц, и тд
           Case Aa5 : Decr Время(h)                         '
           Case Aa6 : K = 1                                 'Запись в
           Case Aa7 : Incr L                                'Переключение индикации время, термометры
          End Select
    End If

    If Flag <> 0 Then                                       '
        Select Case Flag                                    'в зависимости от номера флага запишем команду в свою ячейку памяти
           Case 1 : Ee1 = Command                           'записываем номер команды в EEPROM
           Case 2 : Ee2 = Command
           Case 3 : Ee3 = Command
           Case 4 : Ee4 = Command
           Case 5 : Ee5 = Command
           Case 6 : Ee6 = Command
           Case 7 : Ee7 = Command
        End Select
        Flag = 0                                            'сбрасываем флаг записи

        Aa1 = Ee1                                           'вытаскиваем все из энергонезависимой памяти
        Aa2 = Ee2
        Aa3 = Ee3
        Aa4 = Ee4
        Aa5 = Ee5
        Aa6 = Ee6
        Aa7 = Ee7
    End If
    Waitms 10
  End If

 If Pult = 0 Then                                           'Кнопка флага для записи команд с пульта
   Waitms 100                                               'избавляемся от дребезга кнопки
  Incr Flag
   If Flag > 7 Then Flag = 0                                'если нажали кнопку 8 раз
 End If
 If L > 4 Then L = 1
'******************************************************************************************                                                               ' основной цикл
If Menu = 0 Then Gosub Ds3231

 Gosub Temper
 Gosub Ind                                                  ' обновление значения времени на индикаторе
' Waitms 500
 Loop
'***********************************[Процедуры обработки подпрограмм и прерываний]*******************************
Refresh:                                                    ' прерывание таймера Т0 (переполнение каждые ~4 мс)
 Set Dig1 : Set Dig2 : Set Dig3 : Set Dig4 : Set Dig5 : Set Dig6 : Reset Dot       ' гасим индикатор

 Incr Count : If Count > 6 Then Count = 1                   ' выбираем какой разряд сейчас включать
 Incr Count_blink : If Count_blink > 250 Then Count_blink = 1       ' длительность мигания точки

    Ind_str = Mid(sstr , Count , 1)
  Select Case Ind_str
    Case "0" : D = 0 : C = 0 : B = 0 : A = 0                '&b0000
    Case "1" : D = 0 : C = 0 : B = 0 : A = 1                '&b0001
    Case "2" : D = 0 : C = 0 : B = 1 : A = 0                '&b0010
    Case "3" : D = 0 : C = 0 : B = 1 : A = 1                '&b0011
    Case "4" : D = 0 : C = 1 : B = 0 : A = 0                '&b0100
    Case "5" : D = 0 : C = 1 : B = 0 : A = 1                '&b0101
    Case "6" : D = 0 : C = 1 : B = 1 : A = 0                '&b0110
    Case "7" : D = 0 : C = 1 : B = 1 : A = 1                '&b0111
    Case "8" : D = 1 : C = 0 : B = 0 : A = 0                '&b1000
    Case "9" : D = 1 : C = 0 : B = 0 : A = 1                '&b1001
    Case " " : D = 1 : C = 1 : B = 1 : A = 1                '&b1111 гасит
  End Select

 If W = 1 And Count_blink < 125 Then                        ' включаем точку в нужном разряде
   If Count = 2 Or Count = 4 Then Set Dot
 End If

 If W = 0 And Count = 3 Then Set Dot                        'Точка при отображении температуры без мигания

  Select Case Count                                         ' и включаем соответствующий разряд индикатора
    Case 1 : Reset Dig1
    Case 2 : Reset Dig2
    Case 3 : Reset Dig3
    Case 4 : Reset Dig4
    Case 5 : Reset Dig5
    Case 6 : Reset Dig6
  End Select

 Return
'----------------------------------------------------------------------------------------------------------------

Ind:
  If Menu = 0 Then                                          'Если нужно только подвести
   Время(1) = Year
   Время(2) = Month
   Время(3) = Dat
   Время(4) = Day
   Время(5) = Hour
   Время(6) = Mine
  End If
   Tds1_str = Mid(tds1_str , 2 , 3)
   Tds2_str = Mid(tds2_str , 2 , 3)

  If H = 1 And Menu = 1 Then Year = Время(1)                'Установка переменных для аписи RTC
  If H = 2 And Menu = 1 Then Month = Время(2)
  If H = 3 And Menu = 1 Then Dat = Время(3)
  If H = 4 And Menu = 1 Then Day = Время(4)
  If H = 5 And Menu = 1 Then Hour = Время(5)
  If H = 6 And Menu = 1 Then Mine = Время(6)
  If H > 6 And Menu = 1 Then H = 6
  If H < 1 And Menu = 1 Then H = 1
  Hstr = Str(h)
  Время_str(h) = Str(время(h))
  Время_str(h) = Format(время_str(h) , "00")
  Flagstr = Str(flag)

      If K = 1 And Menu = 1 Then                            'Запись RTC
         Seco = 0
         Seco = Makedec(seco)
         Gosub Setup_rtc
         K = 0
      End If

  If Flag = 0 And Menu = 0 And L = 1 Then                   'Выводим на индикатор часы минуты секунды
   Sstr = Hourstr + Minestr + Secostr
   W = 1
  End If

  If Flag = 0 And Menu = 0 And L = 2 Then                   'Уличный 18в20
   Sstr = " " + Tds1_str + "  "
   W = 0
  End If

  If Flag = 0 And Menu = 0 And L = 3 Then                   'Комнатный 18в20
   Sstr = " " + Tds2_str + "  "
   W = 0
  End If

  If Flag = 0 And Menu = 0 And L = 4 Then                   'Температура DS3231(тоже комнатная. Но в корпусе все греется)
   Sstr = " " + Tds3231_str + "  "
   W = 0
  End If

  If Flag <> 0 Then
   Sstr = Flagstr + "     "
   W = 2
  End If

  If Menu = 1 Then
   Sstr = " " + Hstr + " " + Время_str(h) + " "             'Индикация в менюхе
   W = 2
  End If

  If Left(tds1_str , 1) = "-" Then                          'Отдельный порт при отрицательной температуре
     E = 1
   Else
     E = 0
  End If

Return
'*****************************************************[Прочее]***************************************************
'Обработка датчика температуры DS18B20
'====================================================================================================
Temper:
   Gosub Look_timer
   1wreset Pinc , 0
   Gosub Look_timer
   If Err = 1 Then
         Err_c1 = 1                                         'ставим флаг ошибки датчика
         Tds1 = 32767                                       'если при опросе небыло ответа ставим флаг ошибки
      Else
         Err_c1 = 0
         1wwrite &HCC , 1 , Pinc , 0                        'пропуск ROM(для всех)
         1wwrite &H44 , 2 , Pinc , 0                        'конвертировать температуру(для всех)
   End If

'     Waitms 94

   If Err_c1 = 0 Then
      Gosub Look_timer                                      'если небыло ошибки при начале конвертирования
      1wreset Pinc , 0
      Gosub Look_timer
      If Err = 1 Then
            Tds1 = 32767                                    'если при опросе небыло ответа ставим флаг ошибки
          Else                                              'иначе, если ошибки не было, продолжаем опрос датчика
            1wwrite &HCC , 1 , Pinc , 0
            1wwrite &HBE , 1 , Pinc , 0
            Tds1 = 1wread(2 , Pinc , 0)
            Tds1 = Tds1 * 10
            Tds1 = Tds1 \ 16
      End If
       Tds1_str = Str(tds1)
       Tds1_str = Format(tds1_str , "+000")
      Else
       Tds1 = 32767
       Tds1_str = " 000"
   End If
'===================================================================
   Gosub Look_timer
   1wreset Pinc , 1
   Gosub Look_timer
   If Err = 1 Then
         Err_c2 = 1                                         'ставим флаг ошибки датчика
         Tds2 = 32767                                       'если при опросе небыло ответа ставим флаг ошибки
      Else
         Err_c2 = 0
         1wwrite &HCC , 1 , Pinc , 1                        'пропуск ROM(для всех)
         1wwrite &H44 , 2 , Pinc , 1                        'конвертировать температуру(для всех)
   End If

'      Waitms 94                                           'время преобразования для 9 битного разрешения

   If Err_c2 = 0 Then
      Gosub Look_timer                                      'если небыло ошибки при начале конвертирования
      1wreset Pinc , 1
      Gosub Look_timer
      If Err = 1 Then
            Tds2 = 32767                                    'если при опросе небыло ответа ставим флаг ошибки
          Else                                              'иначе, если ошибки не было, продолжаем опрос датчика
            1wwrite &HCC , 1 , Pinc , 1
            1wwrite &HBE , 1 , Pinc , 1
            Tds2 = 1wread(2 , Pinc , 1)
            Tds2 = Tds2 * 10
            Tds2 = Tds2 \ 16
      End If
       Tds2_str = Str(tds2)
       Tds2_str = Format(tds2_str , "+000")
      Else
       Tds2 = 32767
       Tds2_str = " 000"
   End If

Return
'=====опрос микросхемы DS3231
'===============================================================================
Ds3231:

   I2cstart
   I2cwbyte Ds3231w
   I2cwbyte &H00                                            'стартовый адрес
   I2cstart
   I2cwbyte Ds3231r
'=====прием и запись данных
   I2crbyte Seco_bcd , Ack
   I2crbyte Mine_bcd , Ack
   I2crbyte Hour_bcd , Ack
   I2crbyte Day_bcd , Ack
   I2crbyte Dat_bcd , Ack
   I2crbyte Month_bcd , Ack
   I2crbyte Year_bcd , Nack
   I2cstop

   I2cstart                                                 ' даем режим готовности часам
   I2cwbyte Ds3231w                                         ' адрес микросхемы
   I2cwbyte &H11                                            ' адрес откуда начинаем читать данные
   I2cstart                                                 ' даем сигнал старт на прочтение данных
   I2cwbyte Ds3231r                                         ' даем понять что готовы принимать данные
   I2crbyte Temper_z , Ack                                  ' целая часть температуры со знаком
   I2crbyte Temper_d , Nack                                 ' дробная часть
   I2cstop                                                  ' закончили
   Gosub Convert

Return

'=====Преобразование и форматирование переменных времени и даты
'===============================================================================
Convert:
'=====преобразование в десятичную систему
   Seco = Makedec(seco_bcd)
   Mine = Makedec(mine_bcd)
   Hour = Makedec(hour_bcd)
   Day = Makedec(day_bcd)
   Dat = Makedec(dat_bcd)
   Month = Makedec(month_bcd)
   Year = Makedec(year_bcd)

   If Temper_z < 128 Then
         Select Case Temper_d
            Case 0 : Temper_d = 0                           '0000_0000
            Case 64 : Temper_d = 2                          '0100_0000
            Case 128 : Temper_d = 5                         '1000_0000
            Case 192 : Temper_d = 7                         '1100_0000
         End Select
         Tds3231 = Temper_z * 10
         Tds3231 = Tds3231 + Temper_d
      Else
         Temper_z = Not Temper_z
         Temper_d = Not Temper_d
         Select Case Temper_d
            Case 0 : Temper_d = 0                           '1111_1111
            Case 63 : Temper_d = 2                          '0011_1111
            Case 127 : Temper_d = 5                         '0111_1111
            Case 191 : Temper_d = 7                         '1011_1111
         End Select
         Tds3231 = Temper_z * 10
         Tds3231 = Tds3231 + Temper_d
         Tds3231 = Tds3231 * -1
   End If
'=====форматирование
   Secostr = Str(seco)
   Secostr = Format(secostr , "00")
   Minestr = Str(mine)
   Minestr = Format(minestr , "00")
   Hourstr = Str(hour)
   Hourstr = Format(hourstr , "00")
   Tds3231_str = Str(tds3231)
   Tds3231_str = Format(tds3231_str , "000")
   Return
'===============================================================================
Look_timer:
    Do
      nop
    Loop Until Tcnt0 < Ds1820
 Return
'=====отправление данных в часы
'===============================================================================
Setup_rtc:
   Sstr = "000000"

   Seco_bcd = Makebcd(seco)
   I2cstart
   I2cwbyte Ds3231w
   I2cwbyte 0
   I2cwbyte Seco_bcd
   I2cstop

   Mine_bcd = Makebcd(mine)
   I2cstart
   I2cwbyte Ds3231w
   I2cwbyte 1
   I2cwbyte Mine_bcd
   I2cstop

   Hour_bcd = Makebcd(hour)
   I2cstart
   I2cwbyte Ds3231w
   I2cwbyte 2
   I2cwbyte Hour_bcd
   I2cstop

   Day_bcd = Makebcd(day)
   I2cstart
   I2cwbyte Ds3231w
   I2cwbyte 3
   I2cwbyte Day_bcd
   I2cstop

   Dat_bcd = Makebcd(dat)
   I2cstart
   I2cwbyte Ds3231w
   I2cwbyte 4
   I2cwbyte Dat_bcd
   I2cstop

   Month_bcd = Makebcd(month)
   I2cstart
   I2cwbyte Ds3231w
   I2cwbyte 5
   I2cwbyte Month_bcd
   I2cstop

   Year_bcd = Makebcd(year)
   I2cstart
   I2cwbyte Ds3231w
   I2cwbyte 6
   I2cwbyte Year_bcd
   I2cstop

   Wait 1

Return

0

62

rom-i написал(а):

Думаю при опросе 18в20 с прерываниями накладки происходят.

Библиотека для аппартаного модуля 1Wire на основе USART

0

63

Пётр
Не по понятиям ответ. Чисто для рейтинга.
Та библиотека, задержку больше делает.

0

64

Гавно с задершкой 750. Фуфел это.

0

65

В этой пруге, реально датчики отвечают.

0

66

Вопрос задан про динамику.
Эта библиотека для 18в20 наилучшая. Под Баском.

0

67

rom-i написал(а):

Гавно с задершкой 750. Фуфел это.

Даташит на DS18B20 читали? При 12-ти битном преобразовании нужно не меньше 750 миллисекунд на измерение температуры.

rom-i написал(а):

Вопрос задан про динамику.

В 61 сообщении вообще нет ни единого вопроса, а только рассуждения.

0

68

Дорогой Пётр, и все участники форума. Знак вопроса не поставил потому, что вопросов очень много. Программированием занимаюсь всего года два, электроникой около 40 лет. После небольших обсуждений можно задать конкретные.
От куда берется эта моргуха сегментами?
Как это может пролезть черезь дешифратор? Здесь вообще не понятно. На макетке собирать задуманную конструкцию не сильно приятно. Нужно на разряды вешать высоковольтные ключи. Это два транзистора, два сопрота. Шесть разрядов. Точки можно оставить пока светюнами. У ИНок выводы гибкие. Если делать бородой с учетом высокого напряжения 200В, поверьте решение глупое. Готовую конструкцию без отработанной пруги, работать на помойку. Тем более, что собирать это все будет мой напарник. По его решению переход на индикацию температуры будет по хлопку(то емть аккустический датчик). Возвращаться к часам по таймеру. Всякие поочередные индикации просто раздражают. Когда ночью в дреме хочешь узнать время, а там температура. Которая тебе нах не нужна в данный момент. По ней на работу точно не поднимешся.
Про библиотеку 18в20. Именно про задежку.
Собирал термометр с двумя датчиками(только для экперимента). Брал библиотеку с задержкой 750мс. Для одного оставлена как есть, для другого задежку закомментировал. Разницы нет. Оба датчика отвечали без сбоев. Показания температуры адекватны. При -28 в морозилке, +30 на уличе. Мой друг программист из Полтавы тож делает задержку. Но по его переводу даташита получилось 94мс. У мну получается она вообще не нужна. Датчик делает ее сам. Зачем ее вводить дополнительно?

0

69

rom-i написал(а):

От куда берется эта моргуха сегментами?

Как она выглядит? Видео можете записать?

rom-i написал(а):

Датчик делает ее сам. Зачем ее вводить дополнительно?

Датчик производит измерение, на что требуется не меньше 750 мс. Если прочитать раньше, получим результат предыдущего измерения температуры, а не текущего. То есть раньше чем через 750 мс читать смысла нет.

0

70

rom-i
Где-то на форуме говорили, что DS18B20 вообще лучше читать 1 раз в 10 секунд.
Так как при частом к нему обращении (1 раз в секунду) возникает  эффект само_разогрева.
В результате DS18B20 начинает врать на 1-1,5 градуса.

+1

71

Тоже вранье. Читал на форумах про это. Но в реале не наблюдал. Даже DHT22 банил по четыре раза в секунду в связке с 18в20. За неделю с ними ничего не случилось. Но люди говорят нельзя так.
Почему?
Не знаю как вложить папку. В пруге четыре подпрограммы. Логер для неотапливоема помещения. Погреб, или подвал на даче. Два 18в20. Пишет лог на 24с32 которая в модуле DS3231. Здесь опрос раз в 5 минут. Но для экспериментов вырубал сон МК, и опрос шел примерно четыре раза за секунду. Ни одного сбоя.

Код:
$regfile = "m8def.dat"
$crystal = 1000000
$baud = 9600
$hwstack = 40
$swstack = 128
$framesize = 32
Dim Ver_log As String * 20
Ver_log = "TL_3_6M"
Print Ver_log

   Ddrb = &B_1111_1111 : Portb = &B_0000_0000
   Ddrd = &B_1111_0011 : Portd = &B_0001_1100
' 
'===================================================================
  Config Adc = Single , Prescaler = Auto , Reference = Internal
'=====  
'===============================================================================
  Config Timer2 = Timer , Async = On , Prescale = 1024      ' 2   

  On Timer2 __timer2 Nosave              '      TIMER2
  Dim  As Byte
  Dim _ As Byte : _ = 45      '  * 8 ( )
      = _                              '45*8=6  (      )

'---------------       ------------------
Assr.3 = 1 : Waitms 100                                     '  - AS2     
'      AS2 (3)   ASSR (ASSR.3),    
' "Powersave" -   .    TIMER2
Mcucr = &B10110000                                          '  POWERSAWE

'===== 
'===============================================================================
Config Int0 = Falling
On Int0 __int_0
Dim _ As Bit : _ = 0

Config Int1 = Falling
On Int1 __int_1
Dim _1 As Bit : _1 = 0

Set Portd.2
'=====  
'===============================================================================
Config Portc.3 = Output
Mypover Alias Portc.3
'=====  SIM800L
'===============================================================================
Config Portd.4 = Output
Powersim Alias Portd.4
'===========    DS18B20
'===============================================================================
Dim Tds1 As Integer                                         '   1   0.1. 10 = 1,0 
Dim Tds2 As Integer                                         '   2   0.1. 10 = 1,0 
Dim Err_c0 As Byte                                          ' 
Dim Err_c1 As Byte                                          ' 

'===== I2C  scl  sda 
'===============================================================================
Config Sda = Portc.4                                        ' I2C Data
Config Scl = Portc.5                                        ' I2C Clock
   Config I2cdelay = 1                                      '    I2c   
   I2cinit
   Waitms 50

'=====       ds1307
Const Ds1307w = &HD0                                        '  
Const Ds1307r = &HD1                                        '  

'==================================================================
Const Phonenumber = "+7911xxxxxxx"                          '     
Dim Otvet As String * 200                                   ',    
Dim Flag As Bit : Flag = 0                                  '   
Dim L As Word
Dim L_str As String * 5

'=====    DS1307
'===============================================================================
'=====  
Dim Seco As Byte
Dim Mine As Byte
Dim Hour As Byte
Dim Hour_8 As Bit                                           '   8
Dim Day As Byte
Dim Dat As Byte
Dim Month As Byte
Dim Year As Byte
'===== - 
Dim Seco_bcd As Byte
Dim Mine_bcd As Byte
Dim Hour_bcd As Byte
Dim Day_bcd As Byte
Dim Dat_bcd As Byte
Dim Month_bcd As Byte
Dim Year_bcd As Byte
'=====  
Dim Secostr As String * 2
Dim Minestr As String * 2
Dim Hourstr As String * 2
Dim Daystr As String * 2
Dim Datstr As String * 2
Dim Monthstr As String * 2
Dim Yearstr As String * 4

'=====   EEPROM
Dim Chip_sel As Byte                                        ' 
Dim Chip_sel_r1 As Byte                                     '    
Chip_sel = &B10100000
Dim Adr_l As Byte                                           '   
Dim Adr_h As Byte                                           '   
Dim Adr_h_r As Byte                                         '   
Dim Adr_l_r As Byte                                         '   

'=====          
Dim Adr_h_eeprom As Eram Byte                               '    
Dim Adr_l_eeprom As Eram Byte                               '    
   Adr_h = Adr_h_eeprom                                     '   
   If Adr_h = 255 Then                                      '    (    )
      Adr_h = 0                                             '  
      Adr_h_eeprom = Adr_h                                  '    eeprom
   End If
   Adr_l = Adr_l_eeprom                                     '  
   If Adr_l = 255 Then
      Adr_l = 0
      Adr_l_eeprom = Adr_l                                  '    eeprom
   End If

'===============================================================================
'    
Dim I As Byte                                               '  -
Dim W(16) As Byte
Dim Month_last As Byte At W + 0 Overlay
Dim Dat_last As Byte At W + 1 Overlay                       '        
Dim T1max As Integer At W + 2 Overlay                       '    
Dim T1min As Integer At W + 4 Overlay                       '    
Dim T1aver As Integer At W + 6 Overlay                      '     
Dim T2max As Integer At W + 8 Overlay                       '       
Dim T2min As Integer At W + 10 Overlay                      '       

T1min = 1500                                                '     ,   
T1max = -1500                                               '     ,   
T2min = 1500                                                '     ,     
T2max = -1500                                               '     ,     
Declare Sub Write24lc32                                     '   24L32

'=====    
'===============================================================================
Dim R(16) As Byte
Dim T1max_r As Integer At R + 2 Overlay                     '    
Dim T1min_r As Integer At R + 4 Overlay                     '    
Dim T1aver_r As Integer At R + 6 Overlay                    '     
Dim T2max_r As Integer At R + 8 Overlay                     '       
Dim T2min_r As Integer At R + 10 Overlay                    '       
Declare Sub Read24lc32                                      '   24L32

'=====     
Dim T1sum As Long                                           '        -2147483648  +2147483647
Dim T1aver_long As Long                                     '  
Dim Nt1 As Long                                             '     -2147483648  +2147483647
Dim T2sum As Long                                           '        -2147483648  +2147483647
Dim T2aver_long As Long                                     '  
Dim Nt2 As Long                                             '     -2147483648  +2147483647

Dim Seco_last As Byte                                       '     
Dim Mine_last As Byte
Dim Hour_last As Byte                                       '     
Dim Year_last As Byte

'       
Declare Sub Timesf
   Dim Mine_f As Byte
   Dim Mine_fstr As String * 2
   Dim Times As String * 5
   Dim Hourdes_rf As Byte

'=====    
Dim Minedes As Byte
Dim Hourdes As Byte
Declare Sub Hourvdes

'=====     
Dim Month_rstr As String * 2
Dim Dat_rstr As String * 2

Dim T1max_rstr As String * 5                                '  1
   Dim Ht1max_rstr As String * 5
Dim T1min_rstr As String * 5
   Dim Ht1min_rstr As String * 5
Dim T1aver_rstr As String * 5

Dim T2max_rstr As String * 5                                '  2
   Dim Ht2max_rstr As String * 5
Dim T2min_rstr As String * 5
   Dim Ht2min_rstr As String * 5
Dim T2aver_rstr As String * 5
'=====    
Dim T1max_str As String * 5                                 '  1
   Dim Ht1max_str As String * 5
Dim T1min_str As String * 5
   Dim Ht1min_str As String * 5
Dim T1aver_str As String * 5

Dim T2max_str As String * 5                                 '  2
   Dim Ht2max_str As String * 5
Dim T2min_str As String * 5
   Dim Ht2min_str As String * 5
Dim T2aver_str As String * 5

'===============================================================================
Dim T1log As Integer                                        '  1        
Dim T2log As Integer                                        '  2    
Dim T1log_str As String * 6
Dim T2log_str As String * 6
'===============================================================================
   Mypover = 0
   Gosub Ds1307                                             '         
   Mypover = 1

Enable Int0
Enable Int1
Enable Timer2
Enable Interrupts

Gosub Awake

'*******************************************************************************
  _:
'===============================================================================
      If  = 0 Then
         Gosub Awake
          = _
      End If

      If _ = 1 Then
         Ucsrb.txen = 1
         Gosub Printvar
         Gosub Send_csv
         _ = 0
      End If

      If _1 = 1 Then
         Ucsrb.txen = 1
         Gosub Reset_all
         Gosub Send_csv
         _1 = 0
      End If



      Gosub _
 Goto _
End

'===============================================================================
'    TIMER2,   8 
'===============================================================================
  __timer2:
'-------------------------------------------------------------------------------
    !Push R16                                               '  ,     
    !In R16 , Sreg
    !Push R16

    !lds R16 , {}
    !cpi R16 , 0
    !breq __timer2

    !dec R16
    !sts {} , R16

   __timer2:
    !Pop R16
    !Out Sreg , R16
    !Pop R16

    !reti
'-------------------------------------------------------------------------------
  Return
'===============================================================================
'----------------------------------------
__int_0:
   _ = 1
    = 0
Return
'----------------------------------------
'----------------------------------------
__int_1:
   _1 = 1
    = 0
Return
'----------------------------------------

'===============================================================================
  _:
'-------------------------------------------------------------------------------
    Adcsra.aden = 0                                         ' ,   
    Ucsrb.rxen = 0                                          '  USART
    Ucsrb.txen = 0                                          '  USART

    Ddrb = &B_1111_1111 : Portb = &B_0000_0000
    Ddrc = &B_1111_1111 : Portc = &B_0000_1000
    Ddrd = &B_1111_0011 : Portd = &B_0001_1100

    Mcucr = &B_0011_0000                                    ' PowerSave  Atmega8A
    Mcucr.se = 1

'    Mcucr.sm0 = 1
'    Mcucr.sm1 = 1
'    Mcucr.sm2 = 0                                           '   
    sleep
'    Powersave
'    Ucsrb.rxen = 1                                          '  USART
'    Ucsrb.txen = 1                      '  USART
'    Adcsra.aden = 1                                         ' 
'-------------------------------------------------------------------------------
  Return
'===============================================================================

'*******************************************************************************
$include "ds1307.bas"
$include "2x18b20.bas"
$include "24lc32.bas"
'*******************************************************************************

Awake:
   Ddrc = &B_1100_1000 : Portc = &B_0000_0000
   Waitms 100
   Gosub Ds1307
   Gosub 4ds18b20

   '=====  
   T1log = Tds1
   T1log_str = Str(t1log)
   T1log_str = Format(t1log_str , "+0.0")

   '=====  
   T2log = Tds2
   T2log_str = Str(t2log)
   T2log_str = Format(t2log_str , "+0.0")

   If T1log <> 32767 Then                                   '      - 
      Gosub Extremum_t1                                     ' / 
      Gosub Average_t1                                      ' 
   End If

   If T2log <> 32767 Then                                   '      - 
      Gosub Extremum_t2
   End If
   Gosub Eeprom
   Mypover = 1
Return

'=====     
Extremum_t1:
   If T1log > T1max Then
      T1max = T1log
      Call Hourvdes
      W(13) = Hourdes

      Hourdes_rf = W(13)
      Gosub Timesf
      Ht1max_str = Times

      T1max_str = Str(t1max)
      T1max_str = Format(t1max_str , "+0.0")
   End If

   If T1log < T1min Then
      T1min = T1log
      Call Hourvdes
      W(14) = Hourdes                                       '    

      Hourdes_rf = W(14)
      Gosub Timesf
      Ht1min_str = Times

      T1min_str = Str(t1min)
      T1min_str = Format(t1min_str , "+0.0")
   End If
Return

'=====      
Extremum_t2:
   If T2log > T2max Then
      T2max = T2log
      Call Hourvdes
      W(15) = Hourdes

      Hourdes_rf = W(15)
      Gosub Timesf
      Ht2max_str = Times

      T2max_str = Str(t2max)
      T2max_str = Format(t2max_str , "+0.0")
   End If

   If T2log < T2min Then
      T2min = T2log
      Call Hourvdes
      W(16) = Hourdes

      Hourdes_rf = W(16)
      Gosub Timesf
      Ht2min_str = Times

      T2min_str = Str(t2min)
      T2min_str = Format(t2min_str , "+0.0")
   End If
Return

'=====  
Average_t1:
   Incr Nt1                                                 '   
   T1sum = T1sum + T1log                                    '  
   T1aver_long = T1sum / Nt1                                ' 
   T1aver = T1aver_long                                     '  Intrger
   T1aver_str = Str(t1aver)
   T1aver_str = Format(t1aver_str , "+0.0")
Return

'     
'===============================================================================
Eeprom:
   If Hour_last > Hour Then Flag = 0                        '        
   If Hour => 21 And Flag = 0 Then                          '   8    

'   If Mine_last > Mine Then Flag = 0    '        
'   If Mine > 30 And Flag = 0 Then       '   30    

'   If Seco_last > Seco Then Flag = 0
'   If Seco => 0 And Flag = 0 Then

   Ucsrb.txen = 1                                           '  USART
   Adcsra.aden = 1                                          ' 
   Start Adc
  '=======  SIM800L===============================================
    Powersim = 0
    Wait 2
    L = Getadc(2)                                           '       
'    L = L - 1
    L_str = Str(l)
    L_str = Format(l_str , "0.00")
    Wait 8
    Print "AT"
    Waitms 250
    Print "AT"
    Waitms 250
    Print "AT+CMGF=1"
    Waitms 250
    Otvet = "SIM800L " + Datstr + "/" + Monthstr + "/20" + Yearstr + " " + Hourstr + ":" + Minestr + ":" + Secostr + Chr(10) + "T1log= " + T1log_str + "'C " + "T2log= " + T2log_str + "'C" + Chr(10) + "T1max= " + T1max_str + "'C " + Ht1max_str + Chr(10) + "T1min= " + T1min_str + "'C " + Ht1min_str + Chr(10) + "T2max= " + T2max_str + "'C " + Ht2max_str + Chr(10) + "T2min= " + T2min_str + "'C " + Ht2min_str + Chr(10) + "Batarea " + L_str + " V"
    '========= 
    Print "AT+CMGS=" ; Chr(34) ; Phonenumber ; Chr(34)
    Waitms 200
    Print Otvet ; Chr(26)
    Print Chr(26);
    Waitms 200
    Print Chr(13)
    Wait 15
    Powersim = 1
   '=====  
      Gosub Write24lc32
      Adr_l = Adr_l + 16
      If Adr_l = 0 Then Adr_h = Adr_h + 1
      If Adr_h = 15 Then Adr_h = 0
   '=====     ,       
      T1min = 1500
      T1max = -1500
      T2min = 1500
      T2max = -1500

      Nt1 = 0
      T1sum = 0
      T1aver = 0

      Adr_l_eeprom = Adr_l                                  '=====       
      Adr_h_eeprom = Adr_h
      Waitms 5
      Flag = 1
   End If
Return

'   CSV 
'===============================================================================
Send_csv:
   Mypover = 0
   Print "Data;T1max;TimeT1max;T1min;TimeT1min;AverT1;T2max;TimeT2max;T2min;TimeT2min"
   Adr_h_r = 0
   Adr_l_r = 0
   Do
      Gosub Read24lc32
      If R(1) = 255 Then
         Print "%"
         Return
      End If

      Print Dat_rstr ; "/" ; Month_rstr ; "/20" ; Yearstr ; ";" ; T1max_rstr ; ";" ; Ht1max_rstr ; ";" ; T1min_rstr ; ";" ; Ht1min_rstr ; ";" ; T1aver_rstr ; ";" ; T2max_rstr ; ";" ; Ht2max_rstr ; ";" ; T2min_rstr ; ";" ; Ht2min_rstr

      Adr_l_r = Adr_l_r + 16
      If Adr_l_r = 0 Then Adr_h_r = Adr_h_r + 1
   Loop Until Adr_h_r = 16
   Mypover = 1
Return

'===== EEPROM     
'===============================================================================
Reset_all:
Mypover = 0
   Print Ver_log
   Print "Erase EEPROM"
   Adr_h = 0
   Adr_l = 0
   Do
      I = 1
      I2cstart                                              '   i2c 
      I2cwbyte Chip_sel                                     '  &B10100000-&B10101110
      I2cwbyte Adr_h                                        '  0-15
      I2cwbyte Adr_l                                        '  0-255
      Do
        I2cwbyte &HFF
        Incr I
      Loop Until I = 17
      I2cstop                                               '  i2c
      Waitms 10

      Adr_l = Adr_l + 16
      If Adr_l = 0 Then Adr_h = Adr_h + 1
   Loop Until Adr_h = 16
   '=====  
   Adr_h = 0
   Adr_l = 0
   Adr_l_eeprom = Adr_l
   Adr_h_eeprom = Adr_h
   Print "Erase EEPROM - OK!"
   Mypover = 0
Return

Printvar:
   Print " "
   Print Ver_log
   Print Datstr ; "/" ; Monthstr ; "/" ; "20" ; Yearstr ; "     " ; Hourstr ; ":" ; Minestr ; ":" ; Secostr
   Print "T1log=" ; T1log_str ; " T1Max=" ; T1max_str ; " T1Min=" ; T1min_str ; "   T2log=" ; T2log_str ; " T2max=" ; T2max_str ; " T2min=" ; T2min_str
   Print " "
Return


Sub Hourvdes                                                '        
      Hourdes = Hour * 10
      Minedes = Mine / 6
      Hourdes = Hourdes + Minedes
End Sub

'=====      00:00
'====================================================================

Sub Timesf
                                                            '21 B
   Times = Str(hourdes_rf)                                  '21 S
   Times = Format(times , "000")                            '021 S

   Mine_fstr = Right(times , 1)                             '1 S
   Mine_f = Val(mine_fstr)                                  '1 B
   Mine_f = Mine_f * 6                                      '6 B
   Mine_fstr = Str(mine_f)                                  '6 S
   Mine_fstr = Format(mine_fstr , "00")                     '06 S***

   Times = Left(times , 2)                                  '02 S
   Times = Times + ":"                                      '02: S
   Times = Times + Mine_fstr                                '02:06 S
End Sub

0

72

Вранье или нет, но опрашивать климатические датчики в бытовых условиях чаще, чем раз в 5 сек - просто трата ресурсов МК.
Да и 5 сек - очень даже слишком часто, можно смело увеличить период опроса в 10 раз.

0

73

rom-i написал(а):

Тоже вранье. Читал на форумах про это. Но в реале не наблюдал.

Я наблюдал как при частом опросе датчики увеличивали показания температуры на 1 и больше градусов, т. е. при включении устройства допустим было 24 градуса, а через 10 секунд работы датчики начали сообщать о 25 градусах хотя реально температура не изменилась.

0

74

На границе так, и должно быть. В библиотеке используемой мною температура с десятыми. Если на грани 24.9, и 25.0 так оно, и будет. Это ни о чем не говорит.

Отредактировано rom-i (2018-09-30 17:23:54)

0

75

Неужели вы думаете что я не смотрел на десятые доли градусов? Написал же что при саморазогреве, температура увеличивается больше чем на градус. Это если датчик в воздухе. При хорошем контакте с жидкостью или чем-то другим с хорошей теплопроводностью, саморазогрев не так явно проявляется и его можно не заметить.

0

76

Не поленюсь. Есть у мну два логера кинутых. Люди попросили, и отказались. Один будет писать каждые 5 минут, второй опрос будет вести со скоростью отработки программы. Примерно 3 раза в секунду. Лог будет писаться на 24с32. Это уже делал. Может не обратил внимания.
Хотя но. Работоспособность проверял в морозилке холодильника "Атлант". Управление собрано производителями на Меге8. Выставлено -28. Проверял сколько аакум от сотика протянет при такой температуре. Черезь неделю выковырил ледышку, отаял. Подключил снять лог из памяти черезь USART. Максимально 28.0 , минимально 27,0. Гистерезис 1 градус вместо заявленных 0.5. Поэтому поводу сильно не осерчал, но присутствие обмана есть. Работает отлично(холодильник). Не придавал значения о частом опросе датчиков. Их два.

Отредактировано rom-i (2018-09-30 17:57:07)

0

77

Датчик внутри ледышки будет показывать что угодно, только не правду...
Лед - прекрасный термобарьер, не зря его используют в морозильных камерах. Исходящий от него холод - вторичное явление.
Однажды проводили эксперимент с использованием нескольких термодатчиков, установленных в одном месте, но в разных условиях.
Так вот тот, который был в замершей воде, показывал одну и ту же температуру, тогда как соседние "гуляли" с разбросом до 15°...

0

78

У меня в комнате рядом висит 18б20 и спиртовой градусник...
Я все не мог понять, почему температурЫ не совпадают?
Пока не прочитал на форуме о само_разогреве.
Перевел 18б20 в режим чтения 1 раз в 10 секунд.
Теперь более-менее.
На сколько я могу доверять своему зрению - спирт и цифра на одном уровне.

0

79

Эксперименты одно, а в работаюших моих конструкциях тоже опрос идет не чаще раз в две секунды. В данном случае думаю сделать раз минуту. Это не термостат. В таком случае почаще нужно. Раз в минуту думаю моргухи вообще не будут заметны. На 16мГц их уже нет.

0

80

rom-i написал(а):

Эксперименты одно, а в работаюших моих конструкциях...

Чем отличается работа датчика при эксперименте от работы в конечной конструкции ? ;)
Указанный эксперимент ставился с другой целью, никак не для проверки работоспособности датчиков.

0