Прошу помощи с функцией
- Войдите на сайт для отправки комментариев
Сб, 24/04/2021 - 01:08
Добрый вечер! Пишу свой первый скетч (если не считать ну совсем простых) в ардуино, и в т.ч.на языке Си.
До этого имел дело лишь с PIC и ассемблером , тоже на простейшем любительском уровне.
В общем ,почти всё работает , но споткнулся на ровном месте - не правильно выводятся значения на индикатор ниже -6.5 и выше 6.5. Причём проверяю калькулятором - всё вроде правильно...
Мог бы переписать всё
[code] void schet(){ // на входе имеем high_byte и low_byte данные температуры с датчика. // биты 7,6,5,4,3 байта high_byte - знаковые. a[0]-a[2]-разряды числа, a[3]- знак // для вывода на 7-сегм.индикатор unsigned int chislo = 0; chislo = (high_byte << 8) | low_byte; // сшиваем байты if(high_byte & 0b00001000){ // если число отрицательное chislo = ( ~chislo) + 1; // переводим в беззнаковое a[3] = 10; // и выодим "-" на индикаторе } else { a[3] = 11; } // иначе гасим знак "-" // получаем unsigned int chislo с макс. значением 2047 (т.е. без старших 5ти разрядов) // что при разрешении 0.0625 даёт макс. значение темп-ры 127 // chislo = 0x0191; // =========== (!) 25.1C прописываем постоянное значение для проверки(!) == // ============================ выводится не верно =============================================== unsigned long chislo_h = chislo * 625;// получаем десятичное значение без дроби //с макс.знач. 1 279 375 if(chislo_h > 999000){ a[0] = 10; // сигнал ошибки " - - - -" a[1] = 10; a[2] = 10; a[3] = 10; return; // устанавливаем границу измерения 99.9С } unsigned long dd = (unsigned long) chislo_h % 100000; // остаток от деления a[1] = (byte)(dd / 10000);// значение для среднего разряда unsigned int cc = (unsigned int) dd % 10000; //остаток a[2] = (byte)(cc / 1000) ;// значение для младшего разряда unsigned int vv = (unsigned int) cc % 1000; // остаток if((vv / 100)>= 5){ // округление сотых a[2] = a[2] + 1; } // a[0] = 2; // ======================================= // a[1] = 5; // a[2] = 1; // ============== только для проверки(!) == // ======= 25.1 выводятся верно ! =========== } //-------------------- [/code]
по другому, в сети есть примеры, но интересно понять где ошибка.
Прошу помощи
P.S.Если что Arduino nano, моделирую в Proteus. Самой платы пока нет.
какой тип имеет переменная chislo
думаю что строка 5 и 24 выполняются не так, как задумано
какой тип имеет переменная chislo
unsigned int
думаю что строка 5 и 24 выполняются не так, как задумано
В строке 5 вроде просто объявляю...
P.S.
В 24 пока не пойму что не так
думаю что строка 5 и 24 выполняются не так, как задумано
В строке 5 вроде просто объявляю...
строка 9 как подписана - компилятор может не вполне адекватно такое выполнять...
какой тип имеет переменная chislo
unsigned int
ну вот все и понятно
Правая часть выражения строки 24 считается в типе uint16
максимальное значение uin16 - 65535, если не забыл
Вот отсюда ваш предел в 6.5 градусов и вылазит
Перепишите строку 24 вот так:
строка 9 как подписана - компилятор может не вполне адекватно такое выполнять...
Подскажите пожалуйста как надо
какой тип имеет переменная chislo
unsigned int
ну вот все и понятно
Правая часть выражения строки 24 считается в типе uint16
максимальное значение uin16 - 65535, если не забыл
Вот отсюда ваш предел в 6.5 градусов и вылазит
Перепишите строку 24 вот так:
Спасибо, понял ошибку!
строка 9 как подписана - компилятор может не вполне адекватно такое выполнять...
Подскажите пожалуйста как надо
не вполне уверен, но 2 раза делать число без знаковым - бог его знает, компиляторы они бывают вешаются, просто проверить пошагово выводом в монитор.
ну и с 24уже написали, еще попробуйте тупо подвинуть значения на 4 бита (уберите лишние) и выведите результат.
Ещё раз спасибо! Проверил заработало.
Но , почему-то теперь десятые вне значений -6.5 и 6.5 врут на 5ть единиц!?
Ещё раз спасибо! Проверил заработало.
Но , почему-то теперь десятые вне значений -6.5 и 6.5 врут на 5ть единиц!?
строки 24, 35 и 38 числа огромные, попробуйте уменьшить сперва исходное число, а потом выделяйте разряды числа.
просто проверить пошагово выводом в монитор.
ну и с 24уже написали, еще попробуйте тупо подвинуть значения на 4 бита (уберите лишние) и выведите результат.
Вывести в монитор без платы не знаю как.
И не совсем понял какие 4-ре бита лишние
Вывести в монитор без платы не знаю как.
И не совсем понял какие 4-ре бита лишние
строка 7 выведите число и посмотрите (в бинарном виде), думаю 4 бита будут лишние их можно удалить.
попробуйте уменьшить сперва исходное число, а потом выделяйте разряды числа.
Так специально увеличил, т.к если уменьшаю - получается потеря или надо float
Т.е. не знаю как уменьшить без потерь
строка 7 выведите число и посмотрите (в бинарном виде), думаю 4 бита будут лишние их можно удалить.
В unsigned int chislo после 9й строки 5ть старших бит равны 0. Как их удалить не знаю
Так специально увеличил, т.к если уменьшаю - получается потеря или надо float
Т.е. не знаю как уменьшить без потерь
ну какие потери, если у вас каждая десятая градуса - это 1000? Очевидно, что результат, как минимум, в тысячу раз завышен.
В строке 24 можете умножить 0.625 - число будет в 1000 раз меньше и точность не пострадает
В строке 24 можете умножить 0.625 - число будет в 1000 раз меньше и точность не пострадает
А тип на float не изменится?
А тип на float не изменится?
и да и нет.
Тип результата все равно определяется тем, какая переменная стоит слева от знака равенства. У вас там целое
Книжки читайте, а то так и будете каждую строчку спрашивать
В строке 24 можете умножить 0.625 - число будет в 1000 раз меньше и точность не пострадает
А тип на float не изменится?
пробуйте так:
посмотрите что получится вместо строки 24 (свою переменную подставьте )
del
А тип на float не изменится?
и да и нет.
Тип результата все равно определяется тем, какая переменная стоит слева от знака равенства. У вас там целое
Книжки читайте, а то так и будете каждую строчку спрашивать
Да спрашиваю потому что как раз в посте №8 имел значение тип справа от знака.
И книжки конечно же буду читать
Приношу извинения , при копировании кода потерялась одна строка, сразу не заметил
пробую ещё раз(№34)
Да спрашиваю потому что как раз в посте №8 имел значение тип справа от знака.
Имеют значения типы с обоих сторон. Различайте тип выражения и тип результата. В коде в начальном сообщении в строке 24
тип выражения - uint16, а тип результата uint32.
А вот тут
тип выражения - float, а результата - как в прошлом случае
Вычисление в правой части происходит в типе выражения. Поэтому в вашей строчке, когда в результате умножения получалось больше 65К - число обрезалось. Когда правая часть вычислена - только после этого происходит преобразование типа выражения к типу переменной, что стоит в левой части. В этот момент число уже было обрезано и преобразование его в лонг уже не могло исправить ошибку
В строке 24 можете умножить 0.625 - число будет в 1000 раз меньше и точность не пострадает
А тип на float не изменится?
пробуйте так:
посмотрите что получится вместо строки 24 (свою переменную подставьте )
Сделал, есно уменьшив соответственно делители.
Теперь выводится точно до 9.9 , а дальше пропадает разряд.)))
P.S.
Похоже так просто числа не обманешь. Возможно нужен другой подход
Да спрашиваю потому что как раз в посте №8 имел значение тип справа от знака.
Имеют значения типы с обоих сторон. Различайте тип выражения и тип результата. В коде в начальном сообщении в строке 24
тип выражения - uint16, а тип результата uint32.
А вот тут
тип выражения - float, а результата - как в прошлом случае
Вычисление в правой части происходит в типе выражения. Поэтому в вашей строчке, когда в результате умножения получалось больше 65К - число обрезалось. Когда правая часть вычислена - только после этого происходит преобразование типа выражения к типу переменной, что стоит в левой части. В этот момент число уже было обрезано и преобразование его в лонг уже не могло исправить ошибку
Спасибо за науку!
Благодаря науке здесь полученной , внёс кое-какие изменения в код и стало гораздо лучше.
Теперь данные отображаются правильно во всём диапазоне температур, но всё же изредка десятые "плавают".
Сложность ещё в том, что значения датчика в Proteus тоже нельзя считать однозначными. Я проверял ещё ранее поступающие данные осциллографом, и значения тоже не всегда были 100% .
Но по битам всё норм, так как есть проверка crc-8. Дело в преобразовании в десятичное значение.
Ещё раз спасибо помогавшим.
расскажи мне, нахрена тебе десятые доли температуры? Ты различаешь 15 градусов и 15.2? Или, если на улице -34.5°С, то шапку надевать надо, а если -34°С, то не надо?
расскажи мне, нахрена тебе десятые доли температуры? Ты различаешь 15 градусов и 15.2? Или, если на улице -34.5°С, то шапку надевать надо, а если -34°С, то не надо?
и чо?
расскажи мне, нахрена тебе десятые доли температуры? Ты различаешь 15 градусов и 15.2? Или, если на улице -34.5°С, то шапку надевать надо, а если -34°С, то не надо?
И что означает эта пила?
Вряд ли температура может изменяться практически по синусоиде с периодом около 7 минут. Следовательно, на графике мы наблюдаем не столько саму температуру, сколько ошибки по ее измерению.
Вот для того, чтобы наблюдать температуру, а не ошибки, и принято ограничивать количество выводимых значащих цифр.
расскажи мне, нахрена тебе десятые доли температуры? Ты различаешь 15 градусов и 15.2? Или, если на улице -34.5°С, то шапку надевать надо, а если -34°С, то не надо?
Просто хочу разобраться. Было-бы более высокое разрешение у датчика, пробовал бы сделать и с большим)))
А на практике десятые бывают даже очень нужны, когда надо отслеживать тенденцию, так сказать...
расскажи мне, нахрена тебе десятые доли температуры? Ты различаешь 15 градусов и 15.2? Или, если на улице -34.5°С, то шапку надевать надо, а если -34°С, то не надо?
+100500!
Я вроде показывал тебе, как у меня сделано. Народ доволен - меньше мелких элементов - лучше всё видно
расскажи мне, нахрена тебе десятые доли температуры? Ты различаешь 15 градусов и 15.2? Или, если на улице -34.5°С, то шапку надевать надо, а если -34°С, то не надо?
И что означает эта пила?
Вряд ли температура может изменяться практически по синусоиде с периодом около 7 минут. Следовательно, на графике мы наблюдаем не столько саму температуру, сколько ошибки по ее измерению.
Вот для того, чтобы наблюдать температуру, а не ошибки, и принято ограничивать количество выводимых значащих цифр.
на графике мы наблюдаем работу кондиционера в конкретной точке серверной стойки, измеряется тремя датчиками, ошибок в измерении нет )))
"Все не так , ребята..." )))
Погонял прогу, протестировал, однако недоволен результатом.
Иногда значения совпадают с датчиком, иногда отличаются на 0.1С - не страшно...
Но иногда (редко но бывает) разница 0.4С(!) Это беспредел по моему. Где-то именно я накосячил.
Например: На индикаторе датчика Proteus 19.2
в память ардуины записывается число 0х0134 что в десятичном значении = 308.
Дальше по тексту скетча 308х625=192500. Следовательно должно быть на выходе 19.2С (Округление отключил пока)
Где косяк???
Получается жадный платит дважды. Экономить место в памяти не всегда возможно.
Всё заработало, когда все числа сделал unsigned long
пост 35 , строки 15, 17,20 - зачем!!!!! это вообще непонятно на кой оно вам
уберите лишнее в строке 5 и преобразуйте результат в другой тип и не нужен будет лонг. Вам уже несколько человек на это указывали, а вы эти тысячи так и таскаете.
а потом избавляетесь по необходимости.
Вы сделали выводы, но как-то странно, они конечно правильные но не рациональные во всех смыслах
пост 35 , строки 15, 17,20 - зачем!!!!! это вообще непонятно на кой оно вам
уберите лишнее в строке 5 и преобразуйте результат в другой тип и не нужен будет лонг. Вам уже несколько человек на это указывали, а вы эти тысячи так и таскаете.
а потом избавляетесь по необходимости.
Вы сделали выводы, но как-то странно, они конечно правильные но не рациональные во всех смыслах
Не понимаю, как без строк 15,17,20 ?
И что лишнее в строке 5? Ведь если уменьшим , то получим десятичную дробь, которая потом пропадёт...
Или совсем не просекаю?
Или совсем не просекаю?
попробую еще раз: у вас есть 4рех разрядное число (макс 5 + знак). (5) Если выше 100С измерять
знак кидаем в отдельную переменную - это сделано.
теперь есть число у которого 4 (5) разрядов, мы знаем 100% что 2 разряда десятые и сотые.
Вариант: зачем таскать дроби когда можно сотые превратить в единицы, но при этом помнить куда нарисовать запятую.
строки 15, 17 и 20 можно сократить на 1000 - вот зачем вы эту тысячу каждый раз таскаете?
И что лишнее в строке 5?
в строке 5 (вернее после строки 4) не хватает действия, которое избавит от деления в строке 20 и сократит вычисления для других разрядов.
даччик какой?
даччик какой?
ds18b20
даччик какой?
человек изобретает велосипед, пытаясь понять как он работает - пока получается плохо, но кататься уже можно :))))))))))
Или совсем не просекаю?
попробую еще раз: у вас есть 4рех разрядное число (макс 5 + знак). (5) Если выше 100С измерять
знак кидаем в отдельную переменную - это сделано.
теперь есть число у которого 4 (5) разрядов, мы знаем 100% что 2 разряда десятые и сотые.
Вариант: зачем таскать дроби когда можно сотые превратить в единицы, но при этом помнить куда нарисовать запятую.
строки 15, 17 и 20 можно сократить на 1000 - вот зачем вы эту тысячу каждый раз таскаете?
По моему то, о чём Вы говорите и есть в посте №26 стр 15.16.
А вывод и так не подразумевает запятой... или нет?
даччик какой?
человек изобретает велосипед, пытаясь понять как он работает - пока получается плохо, но кататься уже можно :))))))))))
Вы ещё всю программу не видели, там всё так )))
строки 15, 17 и 20 можно сократить на 1000 - вот зачем вы эту тысячу каждый раз таскаете?
По моему то, о чём Вы говорите и есть в посте №26 стр 15.16.
А вывод и так не подразумевает запятой... или нет?
вы зачем каждый раз (3 раза) выполняете операцию деления (/ 1000ul) в типе unsigned long??? вам с таким расточительством нужен проц с >GHz тактированием нужен....
ЗЫ вот знаете почему современные телефоны "вешаются" от простых приложений имея 8 ядер на борту? Да потому что недоучки совсем забивают на оптимизацию кода. Зачем вы выполняете операции с размером 4 байта на которые 2 байта жалко?
Гриш, да бессмысленно все. Почти 50 сообщений - а ТС по собственному выражению - "совсем не просекает".
Предлагаю сделать перерыв, пусть подумает сам, сказано уже достаточно
вы зачем каждый раз (3 раза) выполняете операцию деления (/ 1000ul) в типе unsigned long??? вам с таким расточительством нужен проц с >GHz тактированием нужен....
ЗЫ вот знаете почему современные телефоны "вешаются" от простых приложений имея 8 ядер на борту? Да потому что недоучки совсем забивают на оптимизацию кода. Зачем вы выполняете операции с размером 4 байта на которые 2 байта жалко?
Операцию деления в типе unsigned long выполняю потому, что в другом типе теряю дробную часть.
Которая само-собой появляется при уменьшении числа.
100% есть другое решение, пока не нашёл , но буду искать)))
Рад, для начала, и так что работает.))
Операцию деления в типе unsigned long выполняю потому, что в другом типе теряю дробную часть.
ну ведь бред же, Димыч. неужели не понимаешь? Дробную часть ты теряешь в любом случае - что лонг делить, что инт, да хоть байт. Проблема то совсем не в этом.
ну ведь бред же, Димыч. неужели не понимаешь? Дробную часть ты теряешь в любом случае - что лонг делить, что инт, да хоть байт. Проблема то совсем не в этом.
Да , но делил по другому - терял гораздо больше. А так - в принципе ничего не теряю. Сотые не вывожу только из-за индикатора, нет разряда, да и не нужен, достаточно округлить.
Именно задумка и есть - ничего(или почти ничего) не терять.
P.S. А сделать упрощённую версию ничего не стоит.
А сделать упрощённую версию ничего не стоит.
только за 50 сообщений так и не осилил...