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

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

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

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


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Помогите с алгоритмом!


Помогите с алгоритмом!

Сообщений 181 страница 204 из 204

181

Nord написал(а):

на какую резьбу они прикручиваются

* указатель
:: принадлежносты

Читани любую книжку по С  , там всё "вроде" одинаковое и не сильно отличается от баскома, но когда начнутся классы, типы, указатели и векторы... отт тогда мозг начинает "плющить"  Но ниче, их же не зря придумали ещё лет 30 назад?  Если разобраться, конечно классная штуковина, удобная. Но там философия другая, компилятор практически всегда всё "хавает" а вот код может и не работать вовсе...  :stupor:

0

182

Nord написал(а):

даже при использовании Double нет вероятности, цепочка id не превысит 1.7 x 10^308.

Мне кажется, что мы с разных планет...
1 датчик - 8 байт
10 датчиков 80 байт
100 датчиков 800 байт...  1.7 x 10^308 это что-то  :D

Вот смотри, простой тебе пример для подумать. У тебя в системе 20 датчиков. Ты выбираешь рецепт, в котором не нужно 20 а нужно 3. В случае с ардуинщиками они дружно арут на весь форум, шо че такэ - нЭработает. А поменяем рецепт - работает, потому шо там 20 датчиков и они уже предопределены...  А тот ардуинщик их "прикрутил на резьбу" да ещё "накернил" , шоб от вибрации не открутились  :D
Стек id он не догадался придумать для этого, вот и имеем проект, которому нужно 5 датчиков а покупать нужно все 20  :rofl:
Весело, да?

0

183

-NMi- написал(а):

Мне кажется, что мы с разных планет...

Мне порой тоже... ;)

-NMi- написал(а):

1 датчик - 8 байт
10 датчиков 80 байт
100 датчиков 800 байт...  1.7 x 10^308 это что-то

При чем тут 1 или 100 датчиков ?
Разъясняю...
Указанное значение - макс. допустимое для переменной типа Double.
Длина этого типа переменных 8 байт, что, казалось бы подходит для хранения id датчика, но вся закавыка в том, что при записи в переменную цепочки id 28А1СС0ВAA071A5F (от фонаря, не надо в DЕC переводить) может превысить это самое "макс. допустимое".

Так что повторю - я бы для id использовал (и использую сейчас) массивы.
Другой вопрос, как программно формировать имя массива.
К индексу можно обратиться с использованием переменной, а вот с именем - затыка... ;)

Отредактировано Nord (2018-03-01 00:24:53)

0

184

Nord написал(а):

Так что повторю - я бы для id использовал (и использую сейчас) массивы.

Я понимаю... понимаю.
Давай усложним задачку...
Допустим, у тебя ТРИ датчика в системе.
Для рецепта №1 тебе нужен 1 датчик (система сама должна определить какой или через меню выбираешь из распознанных при старте) при разрешении в 9 бит. Остальные игнорируются. По нему будет ШИМ
...
Для рецепта №3 тебе нужно ТРИ датчика, причём первые ДВА в 12 бит а третий в 9 бит точности. И по первому и + по третьему будет ШИМ.

Для варианта №5 вообще будет один абсолютно левый датчик, который при достижении пороговой уставки выключит всё и будет просто пипикать пипикалкой.

Для варианта №9 датчики вааще не нужны.

Как бы ты в такой ситуации "нарисовал" бы код?

0

185

-NMi- написал(а):

Как бы ты в такой ситуации "нарисовал" бы код?

Чтоб не изобретать на ходу, лучше объясню, как я реализую доступ к нужным 1-Wire устройствам в текущем проекте.

В создаваемой системе три линии 1-Wire, на каждой несколько устройств.
Каждое устройство имеет свое четкое расположение на объекте (датчик температуры на улице, датчик температуры в комнате, порт управления DS2408 в другой комнате...), поэтому считывание/управление "где-то там" исключается.

Каждой присвоен (условно) номер от 0 до 2 (по используемым пинам порта МК), например PORТA.0
Для обращения к нужной линии используется переменная num1w.

ID каждого устройства оформлены в виде блока DATA, для каждого устройства своя метка.
id01:                                                  линия 0, устройство 1
DATA &H28, .... строка из 8 байтов id
....
id25:                                                  линия 2, устройство 5
DATA &H28, .... строка из 8 байтов id

Для обращения к нужному устройству используется массив id1w(8).

Чтобы обратиться к нужному устройству, например к устройству 2 в линии 0, загружаем его id из блока DATA:
num1w = 0                                         линия 0
Restore id02                                       устройство 2
For a = 1 To 8
    Read id1w(a)
Next a

После этого можно обращаться к конкретному устройству, например:
1WWRITE &H55
For a = 1 To 8
    1WWRITE id1w(a) , PORTA , num1w
Next a
...
Дальше делаем, что требуется...

Разместить id в теле программы решил только потому, что так захотелось изначально... ;)
Для внесения изменений в адресах и количества/типов устройств, МК все равно надо переть к программатору:
- если просто заменить датчик, то переписать id в DATA.
- если меняется количество или типы устройств, то программа всяко будет корректироваться.

А в таком раскладе без разницы, в каком углу памяти МК буду храниться id... ;)

Подход, возможно, неидеален, но мне понятен и не вызывает блужданий по программе. ;)
Неидеальность - повторение указанных выше 4-5 строчек при каждой смене обращений к устройствам...
Если бы была возможность сформировать имя метки для Restore в виде переменной, то можно было бы их вынести в подпрограмму. С командой &H55 так и сделано.

Отредактировано Nord (2018-03-01 04:38:01)

0

186

-NMi- написал(а):

нужен 1 датчик (система сама должна определить какой или через меню выбираешь из распознанных при старте)

Вот если решить, как сформировать имя метки для Restore в виде переменной, то этот вопрос не вызывал бы сомнений... ;)

0

187

Nord написал(а):

Для обращения к нужному устройству используется массив id1w(8).

Чтобы обратиться к нужному устройству, например к устройству 2 в линии 0, загружаем его id из блока DATA:


Вот, вот она, идея моя, но не совсем так реализована.
Почему бы не просто посчитать указатель и не копировать из массива в массив?
***
Ну три 1w шины это кАнэчно изврат, можешь объяснить, почему три а не одна?

0

188

-NMi- написал(а):

Почему бы не просто посчитать указатель и не копировать из массива в массив?

Можно сразу объявить нужное количество массивов в EEPROM, закатать туда ID и вытягивать нужный.
Тогда возникает вопрос опять же с идентификацией этих массивов...
Текстовую часть имени массива программно не изменить... Те же грабли, что и с именами меток...
Поэтому пошел этим путем.

-NMi- написал(а):

Ну три 1w шины это кАнэчно изврат, можешь объяснить, почему три а не одна?

Топология прокладки - "звезда".
В принципе, они все равно сходятся в одном месте, можно и в одну объединить.

Разделил для удобства "навигации", каждая ветка - свой набор объектов.
Программно это ненапряжно... ;)

0

189

попозже... дисплеи приехали, всю голову сломал, не работают или зависають...чо за  :mad:

0

190

Где можно посмотреть как практически записать в память 24c16 переменную integer ?

0

191

olegkaras написал(а):

Где можно посмотреть как практически записать в память 24c16 переменную integer ?


Здесь

0

192

sasha_1973 написал(а):

Здесь

Это только у меня не получается перейти по ссылке ?

Отредактировано olegkaras (2018-03-04 10:46:53)

0

193

olegkaras написал(а):

Это только у меня не получается перейти по ссылке ?


Смотря какой форум.

_http://bascomavr.ru/viewtopic.php?id=1131

_http://bascomavr.3bb.ru/viewtopic.php?id=1131

Отредактировано sasha_1973 (2018-03-04 10:49:54)

0

194

Как в BASCOM правильно записать
Х=Х>>8 ,
X=(X<<8)  |  B   ?

0

195

Никак. Это С конструкция сдвига 8 восемь раз влево (старший бит) и OR с переменной В.
Если только разбивать на несколько операций. Сдвиг, ИЛИ , затем в общую переменную.

0

196

-NMi- написал(а):

Никак. Это С конструкция сдвига 8 восемь раз влево (старший бит) и OR с переменной В.
Если только разбивать на несколько операций. Сдвиг, ИЛИ , затем в общую переменную.

А практически можете показать как разбить ?

0

197

Сдвиг вправо и влево похоже для очистки младших 8 бит. Можно написать так.

Код:
Shift Х, Right, 8
Shift Х, Left, 8
Х=Х Or B

+1

198

Clr X
x=xor B
тоже самое.

+1

199

Как правильно записать условие. Скажем
Текущее время = 23:00
Через 1:10 нужно включить нагрузку
То есть в 00:10.
Проблема в том что условие должно выполнятся даже если прибор включили тогда когда текущее время уже больше заданного.

Отредактировано olegkaras (2018-03-11 21:55:44)

0

200

olegkaras написал(а):

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


Или резервное питание МК, или использовать EEPROM, бортовую или внешнюю, решать Вам.

0

201

Где то на этом форуме видел что можно адрес память 24с сдвигать по кругу при каждой записи для увеличения срока службы памяти , как это практически сделать ?

0

202

olegkaras написал(а):

Где то на этом форуме видел что можно адрес память 24с сдвигать по кругу при каждой записи для увеличения срока службы памяти , как это практически сделать ?

Логика примерно такая:
...
При работе (записи):
Incr <адрес>
...
Где-то в программе:
If <адрес> = &HFFFF Then <адрес> = &H0000

Практическая реализация зависит от даташита.

Отредактировано Nord (2018-04-25 18:28:54)

0

203

sasha_1973 написал(а):

.....использовать EEPROM, бортовую или внешнюю, решать Вам.

Использовать EEPROM не вариант для долговечного устройства, а вот многие модули (Arduino) часов уже имеют I2C память на плате.

olegkaras написал(а):

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

Недавно понадобилось подобное, написал подпрограмму, которая даёт ответ в минутах, то-есть берёт текущее время и нужное время, а после возвращает разницу в минутах, то-есть получаю время от точки записи до реального времени в минутах:
Расчёт времени по времени

Это сыроватый код, но у меня работает:

В массив Vrin(6) запихиваете дату в формате:
'1-сек
'2-мин
'3-час
'4-день
'5-месяц
'6-год
Вызываете подпрограмму Timeload, та вызывает стандартную библиотеку часов и использует переменные:
'Seco
'Mine
'Hour
'Dat
'Month
'Year
ответ в минутах получаете в переменной типа Dword - Vrout

Код:
'========================================== Переменные рассчёта времени
Dim Vrin(6) As Byte                                         'Запомненное время
Dim Vrout As Dword                                          'Выход в минутах
Dim Vrtm3 As Dword                                          'Временная переменная Dword для рассчёта
Dim Vrtm1 As Byte                                           'Временная переменная Byte для рассчёта


...
...
...
...

'================== рассчёт времени
Timeload:




'Массив Vrin(6)
'1-секунды
'2-минуты
'3-часы
'4-день
'5-месяц
'6-год
'Переменные с часов реального времени:
'Seco
'Mine
'Hour
'Dat
'Month
'Year




Gosub Clock:
Vrtm3 = 0
If Month <> Vrin(5) Then
   Select Case Vrin(5)
     Case 1:
     Vrtm3 = 44640
     Case 2:
        Vrtm1 = Year Mod 4
        If Vrtm1 = 0 Then
           Vrtm3 = 41760
           Else
           Vrtm3 = 40320
        End If
     Case 3:
     Vrtm3 = 44640
     Case 4:
     Vrtm3 = 43200
     Case 5:
     Vrtm3 = 44640
     Case 6:
     Vrtm3 = 43200
     Case 7:
     Vrtm3 = 44640
     Case 8:
     Vrtm3 = 43200
     Case 9:
     Vrtm3 = 44640
     Case 10:
     Vrtm3 = 44640
     Case 11:
     Vrtm3 = 43200
     Case 12:
     Vrtm3 = 44640
   End Select
End If
Vrout = Vrtm3
      If Dat => Vrin(4) Then                                'Высчитываем если другой день и при этом равен месяц и год
                Vrtm3 = Dat - Vrin(4)
                Vrtm3 = Vrtm3 * 1440
                Vrout = Vrout + Vrtm3
                Else
                Vrtm3 = Vrin(4) - Dat
                Vrtm3 = Vrtm3 * 1440
                Vrout = Vrout - Vrtm3
      End If

      If Hour => Vrin(3) Then                               'если час больше и год,месяц,день равен
            Vrtm3 = Hour - Vrin(3)
            Vrtm3 = Vrtm3 * 60
            Vrout = Vrout + Vrtm3
            Else
               Vrtm3 = Vrin(3) - Hour
               Vrtm3 = Vrtm3 * 60
               Vrout = Vrout - Vrtm3
      End If

      If Mine => Vrin(2) Then                               'Если минуты больше и секунды тоже, то высчитываем ответ
         Vrtm3 = Mine - Vrin(2)
         Vrout = Vrout + Vrtm3
          Else                                              'вычитаем минуты если они меньше чем дано - нужно для перехода из часа в час
              Vrtm3 = Vrin(2) - Mine
              Vrout = Vrout - Vrtm3
      End If

       If Seco < Vrin(1) And Vrout > 0 Then Vrout = Vrout - 1
Return

*Есть ограничение, но учтены переходы дня и месяца и даже года.

0

204

Ev3658 написал(а):

даёт ответ в минутах, то-есть берёт текущее время и нужное время, а после возвращает разницу в минутах

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

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Помогите с алгоритмом!