1 2 3 4 5 6 7 8 9 10 10/10 10,00оценок: 5

Разработка системы умного дома (АРДУИНО)+ПК нужны советы

Тема в разделе "Умный дом", создана пользователем Wagin, 17.12.18.

  1. Andy-B
    Регистрация:
    09.03.20
    Сообщения:
    18
    Благодарности:
    0

    Andy-B

    Участник

    Andy-B

    Участник

    Регистрация:
    09.03.20
    Сообщения:
    18
    Благодарности:
    0
    Вернемся к нашим "баранам"
    Из чего следует, что у Netbykи каждые 49 дней переполняется счетчик миллисекунд и циклы виснут, а у тебя есть некая проверка на переполнение, как лекарство от этого.
    Только у ламеров "раз в 49 дней переполняется счетчик миллисекунд и циклы виснут" и только ламеры делают проверку на переполнение счетчиков миллисекунд. Всему виной непонимание целочисленной арифметики. Для абдуринщиков это норма. Не стану тебя просить показать код и так всё понятно.
     
  2. Netbyka
    Регистрация:
    30.07.15
    Сообщения:
    3.888
    Благодарности:
    2.325

    Netbyka

    Живу здесь

    Netbyka

    Живу здесь

    Регистрация:
    30.07.15
    Сообщения:
    3.888
    Благодарности:
    2.325
    Дочитай чуть дальше, дядя, прежде чем понты колотить, знаток куев :)]
     
  3. Andy-B
    Регистрация:
    09.03.20
    Сообщения:
    18
    Благодарности:
    0

    Andy-B

    Участник

    Andy-B

    Участник

    Регистрация:
    09.03.20
    Сообщения:
    18
    Благодарности:
    0
    Прочитал всё. Расскажи ка мне, Netbyka, про переполнение счетчика миллисекунд, сдается мне ты не вкуриваешь суть происходящего, раз несешь этот бред в массы. А стало быть имеешь все основания гордо нести звание - ламер.
     
  4. Netbyka
    Регистрация:
    30.07.15
    Сообщения:
    3.888
    Благодарности:
    2.325

    Netbyka

    Живу здесь

    Netbyka

    Живу здесь

    Регистрация:
    30.07.15
    Сообщения:
    3.888
    Благодарности:
    2.325
    Рассказываю, специально для знатока целочисленной арифметики:
    - есть функция, возвращающая 32-битное unsigned long, которое соответствует количеству миллисекунд с момента запуска девайса.
    - есть стандартный подход "из примеров" к коду, который в общем-то работает как должен, первое время:
    Код:
    if(millis() > (timer + 10000)){
      timer = millis();
      do_something();
    }
    - но когда с момента старта девайса проходит 2^32 миллисекунд - FFFFFFFF превращается в 00000000, а вот такой вот пример кода превращается в тыкву, потому что, скажем, 1000, 2000, 3000, 1231344 millis() - все это будет меньше чем (4294962296 + 10000), где 4294962296 - предыдущее состояние timer.

    Знаток целочисленной арифметики, вероятно, знает как это победить - но вот компилятор, похоже, не очень, и он честно пытается сравнить 1231344 с (4294962296 + 10000).
    По крайней мере конкретно компилятор для Ардуины.

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

    Но читать буквы знаток целочисленной арифметики не умеет, видимо...
     
  5. Arcnet
    Регистрация:
    24.12.09
    Сообщения:
    3.328
    Благодарности:
    3.658

    Arcnet

    Живу здесь

    Arcnet

    Живу здесь

    Регистрация:
    24.12.09
    Сообщения:
    3.328
    Благодарности:
    3.658
    Адрес:
    Пермь
    Наверное, имеется в виду, что если ваш код переписать примерно так:
    Код:
    if((millis()-timer) > 10000){
      timer = millis();
      do_something();
    }
    
    То переполнение не страшно. Такая вот unsigned арифметика.

    P. S. Если по простому, то когда в результате вычитания unsigned чисел получаем отрицательное число, то к нему добавляется максимальное (для этого типа) число и опять получаем unsigned.
    1. Например, для беззнакового восьмибитного числа: 5 -10 = - 5
    2. Так как результат отрицательный, то добавляем 255: -5 + 255 = 250
    3. Получаем в результате: 5-10=250

    Получается, что для состояний (восьмибитного) счетчика от 10 до 5 проходит 250 "тиков".
    Что правильно. И не важно, что счетчик в процессе счета переполнился. Результат всё равно правильный. Главное, чтобы он переполнился не более одного раза. :)

    P. P. S. @Andy-B, можно было бы и повежливее объяснить такой нюанс! :no:
     
    Последнее редактирование: 14.01.23
  6. Netbyka
    Регистрация:
    30.07.15
    Сообщения:
    3.888
    Благодарности:
    2.325

    Netbyka

    Живу здесь

    Netbyka

    Живу здесь

    Регистрация:
    30.07.15
    Сообщения:
    3.888
    Благодарности:
    2.325
    Это не мой код :)]
    В принципе решений есть несколько, оодно из них, например - приводить (timer + XXX) к unsigned long в явном виде и сравнивать, другое - добавлять к timer ХХХ сразу после millis(), но надо учитывать что в этих случаях при переходе timer + ХХХ через 0 функция будет выполняться сразу, т. к. millis() "до 0" заведомо больше
    В общем есть нюансы.
     
  7. AVG111
    Регистрация:
    25.09.18
    Сообщения:
    2.772
    Благодарности:
    1.266

    AVG111

    Живу здесь

    AVG111

    Живу здесь

    Регистрация:
    25.09.18
    Сообщения:
    2.772
    Благодарности:
    1.266
    Адрес:
    Москва
    ESP 8266:
    uint8_t n=5,m=10, f;

    void setup() {
    Serial. begin (115200);
    Serial. setTimeout (5);
    delay (1000);
    f=n-m;
    Serial. print("f="); Serial. println (f);
    if (n-m>1) Serial. println("n-m>1"); else Serial. println("n-m<=1");
    }
    void loop() {}

    Результат:
    22:31:30.512 -> f=251
    22:31:30.512 -> n-m<=1

    Преобразование типов самая опасная штука. Код на Ардуино, с использованием конструкциЙ (float) на ESP не работает. Приходится по строчкам делить. При переносе на другие платформы создает кучу проблем.
    5 в 2сс 101, 10 в 2сс 1010. 5-10=5+(-10). В 2 сс получаем (код дополнительный) 101 - 1010= 101 + 11110110=11110111 (251 в 10 сс.).
    А вот в операторе if происходит преобразование типов.
    Так, что не все так просто, как в справочниках.
     
  8. Arcnet
    Регистрация:
    24.12.09
    Сообщения:
    3.328
    Благодарности:
    3.658

    Arcnet

    Живу здесь

    Arcnet

    Живу здесь

    Регистрация:
    24.12.09
    Сообщения:
    3.328
    Благодарности:
    3.658
    Адрес:
    Пермь
    Понятно, что в жизни всё не просто.
    Я только пытался понять, о чём "товарищ" пытался сказать. (Кроме того, что он Д'Артаньян, а остальные "Ардуинщики")
    Может быть, и не угадал...
     
  9. Arcnet
    Регистрация:
    24.12.09
    Сообщения:
    3.328
    Благодарности:
    3.658

    Arcnet

    Живу здесь

    Arcnet

    Живу здесь

    Регистрация:
    24.12.09
    Сообщения:
    3.328
    Благодарности:
    3.658
    Адрес:
    Пермь
    Мне всё таки кажется в подобных случаях правильнее отработать в рамках "unsigned" арифметики.
    То есть, через дельту состояний счетчика. Разумеется, тщательно отслеживая преобразования типов.

    P. S. Кстати, в сообщении выше я ошибся.
    В восьмибитной арифметике надо считать по модулю 256. То есть, прибавлять к отрицательным разностям не 255, а 256. :|:
     
  10. Arcnet
    Регистрация:
    24.12.09
    Сообщения:
    3.328
    Благодарности:
    3.658

    Arcnet

    Живу здесь

    Arcnet

    Живу здесь

    Регистрация:
    24.12.09
    Сообщения:
    3.328
    Благодарности:
    3.658
    Адрес:
    Пермь
    С учетом неявного преобразования типов в операторе if
    Как то так должно работать.
    И переполнения не должны влиять.
    Код:
    unsigned long time, timer;
    time = millis()-timer;
    if(time > 10000){
      timer = millis();
      do_something();
    }
    
     
  11. AVG111
    Регистрация:
    25.09.18
    Сообщения:
    2.772
    Благодарности:
    1.266

    AVG111

    Живу здесь

    AVG111

    Живу здесь

    Регистрация:
    25.09.18
    Сообщения:
    2.772
    Благодарности:
    1.266
    Адрес:
    Москва
    Вот в операторе if и преобразовывалось все в другой тип. Но не факт, что на Ардуино будет также.
    Я стараюсь обходить такие вещи. Даже выражения a && b | c, записываю (a && b) | c). Где то уже один раз с этим попал.
    Поэтому переполнение millis() определяю по тому, что текущее значение меньше предыдущего. Так как то надежнее, везде работать будет.
     
  12. Arcnet
    Регистрация:
    24.12.09
    Сообщения:
    3.328
    Благодарности:
    3.658

    Arcnet

    Живу здесь

    Arcnet

    Живу здесь

    Регистрация:
    24.12.09
    Сообщения:
    3.328
    Благодарности:
    3.658
    Адрес:
    Пермь
    Будет, будет! :)
    Поэтому сначала вычисляем явно unsigned разницу, а потом уже её проверяем в if.
    Там уже любые преобразования типов будут не важны. Дельта счетчика уже вычислена.
    Главное, чтобы тип переменных совпадал с типом millis() - unsigned long.

    IMHO, так должно работать везде. Во всяком случае, я сейчас не вижу причин для другого поведения.
     
  13. Andy-B
    Регистрация:
    09.03.20
    Сообщения:
    18
    Благодарности:
    0

    Andy-B

    Участник

    Andy-B

    Участник

    Регистрация:
    09.03.20
    Сообщения:
    18
    Благодарности:
    0
    Я как бы три раза намекал на непонимание "товарищами" целочисленной арифметики. Но "товарищи" не только арифметики не понимают, но и намеков.
    У горе-программеров я вижу несколько проблем:
    -пытаются прибавлять к счетчику;
    -используют знаковую арифметику;
    -боятся вычитать из меньшего большее.
    Если делать беззнаковое вычитание, тогда никакое переполнение на результат не влияет и никакие костыли с проверками переполнения не нужны.
     
  14. Педро
    Регистрация:
    30.01.22
    Сообщения:
    308
    Благодарности:
    129

    Педро

    Живу здесь

    Педро

    Живу здесь

    Регистрация:
    30.01.22
    Сообщения:
    308
    Благодарности:
    129
    Ох и ах...отобрали ардуинку от детей и изгаляются кто как может...
    Берите выше и к вам потянутся люди.
    А детское отдайте детям.
     
  15. Andy-B
    Регистрация:
    09.03.20
    Сообщения:
    18
    Благодарности:
    0

    Andy-B

    Участник

    Andy-B

    Участник

    Регистрация:
    09.03.20
    Сообщения:
    18
    Благодарности:
    0
    К сожалению некоторые так и остаются детьми не взирая на возраст. Однажды поморгав светодиодом считают что видели всё. Им и в голову не приходит провести хоть какой-то сравнительный анализ: среды разработки, программных/аппаратных/технических решений. Куда ткнут пальцем, то и применяют. Замуровывают километры витой пары в стены. На кой х@р нужен CAN в выключателе? А ведь чел найдет массу обоснований его применения: надежность, скорость, обнаружение коллизий. Выключатель генерит 20-30 бит информации в сутки. Какой CAN?
    Или комп на винде в автоматизации дома, решение из разряда "я умею прогать под винду"...
    Или WiFi в каждой дырке... ППЦ.
    Чел так и не понял смысл:
    И ведь он абсолютно уверен, что ардуино это надежное универсальное техническое решение, его говнокод не ниже SDK и API, а стандарты языка программирования это для лохов, главное уметь моргать светодиодом.
    Доводы типа "6 лет работает" умиляют. А послезавтра накроется медным тазом его контроллер, встанет всё, пока он будет в темноте искать ему замену.
    Не может быть в автоматизации дома таких решений: "все яйца в одну корзину", "баня, через дорогу раздевалка".
    Можно и дальше метать бисер, но что это изменит... Ардуино во веки веков. Аминь.