Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Вопросы по С/С++ (СИ)

Чт фев 08, 2024 21:08:31

как - это Вы уже написали. Где - в каждом случае switch.

Код:
case 0:
   PORTD = (unsigned char)(~(SEGMENTE[display % 1000/100])); // Выводим первый разряд
   if (display < 10) { // или 100, 1000...
     PORTD |= 0x80; //и добавляем десятичную точку если число меньше 10
   }
   break;


только вот с display % 1000/100 разберитесь, это выглядит странно. И не факт, что оптимизатор не упростит операции с равным приоритетом до display % 10

посмотрите на div_t и div()

Re: Вопросы по С/С++ (СИ)

Пт фев 09, 2024 10:38:39

нужно поставить после второго сегмента, когда будет более 9,99 , то есть 10,1

Я дал не полную информацию, в коде фиксированная точка и для 4-х разрядного все как бы нормально (switch из четырех case ну и 9,99 сменяется на 10,01), а на 3-х разрядным (switch из трех case) после 9,99 сменяется например на 0, 01 то есть теряется десятичный знак.
в каждом случае switch

до 10- показания 999 без точки и сменяется на 001 (то же без точки), если более 10 вольт. Может нужен float для переменной? volatile unsigned int display = 0;
Спойлерswitch(seg_counter)
{
case 0:
PORTD = (unsigned char)(~(SEGMENTE[display % 1000/100]));
if (display < 10) {
PORTD |= 0x80;
}
break;
case 1:
PORTD = (unsigned char)(~(SEGMENTE[display % 100/10]));
if (display < 10) {
PORTD |= 0x80;
}
break;
case 2:
PORTD = (unsigned char)(~(SEGMENTE[display % 10]));
if (display < 10) {
PORTD |= 0x80;
}
break;
}
if (seg_counter++ > 2) seg_counter = 0;
}

Re: Вопросы по С/С++ (СИ)

Пт фев 09, 2024 12:15:46

Вы просто вставили мой пример во все случаи, не изменив? Забавно. А мне казалось, совершенно понятно, что он делает, и что более доступно быть не может...
Простой вопрос: если display = 9, в каких разрядах условие if (display < 10) не выполнится?
lord99 писал(а):Может нужен float для переменной?
Может быть. А может, double. Вы же программу пишите, Вам виднее, что у Вас там хранится и с какой точностью и какими ресурсами готовы пожертвовать... Но я бы в данном случае не тип переменной выбирал, а книжку по программированию.

Re: Вопросы по С/С++ (СИ)

Сб фев 10, 2024 20:00:26

Был очень занят, с ответом задержался.
Вы же программу пишите, Вам виднее,

Исходник не мой, я только начинаю учиться.
вопрос: если display = 9, в каких разрядах условие if (display < 10) не выполнится?
Если display=9, то условие выполнится во всех разрядах (см. скрин)
СпойлерИзображение Изображение Изображение

Переключение диапазона с 9,99v на 10,1v точкой я сделал так
Спойлерswitch(seg_counter)
{
case 0:
PORTD = ~((SEGMENTE[display % 1000/100])); // Выводим первый разряд и добавляем десятичную точку
// PORTD = (unsigned char)(~(SEGMENTE[display % 1000/100])); //
if (display < 999) //
{
PORTD &= ~ 0x80; //
}
break;
case 1:
PORTD = ~(SEGMENTE[display % 100/10]); // Выводим второй разряд и переключаем десятичную точку на 2-й разряд
//PORTD = (unsigned char)(~(SEGMENTE[display % 100/10]));
if (display > 999)
{
PORTD &= ~ 0x80; //
}
break;
case 2:
// PORTD = (unsigned char)(~(SEGMENTE[display %10]));
PORTD = ~(SEGMENTE[display % 10]); // Выводим третий разряд
break;
}
if (seg_counter++ > 2) seg_counter = 0;
}

Точка разряда переключается, но показания не верные, при реальных U=10,23v на индикаторе 01,8v Если бы был сдвиг в право, получили бы 10,18v то есть 10,2v для 3-х разрядов (если проверять на индикаторе 4 разрядном).
СпойлерИзображение Изображение
В протеусе все видно.
Вложения
proteus.rar
(34.11 KiB) Скачиваний: 7

Re: Вопросы по С/С++ (СИ)

Сб фев 10, 2024 21:24:16

lord99 писал(а):Если display=9, то условие выполнится во всех разрядах (см. скрин)
Вот именно. Вам же это не нужно?
Давайте поэтапно.
Необходимо определить, как будет отображаться число.
Есть несколько вариантов, опишу три (но их больше):
1. Точка всегда фиксированная, стоит в каком-то из разрядов. Например, есть три разряда (максимальное число 999), допустим, во втором всегда стоит точка. Тогда максимальное число - 99.9, и тут делать ничего не надо, просто добавляем во втором разряде свечение точки. Именно подобный способ использовался в примере, который взят за основу.
2. Точка не фиксирована, но после неё фиксированное число знаков. То есть, можно отобразить числа 1.0, 99.2, но нельзя 1.02 и т. д. Если оговорить, что число выравнивается вправо, то это станет вариант 1.
3. Точка не фиксирована, но после неё отображается столько знаков, сколько влезет. Чем это отличается от второго варианта? Тем, что число 9.489 во втором варианте отобразится как 9.4 или 9.5 в зависимости от выбранного варианта округления, а в третьем - как 9.48, если мы добавим 1, то 10.4, если добавим ещё 100, то 110. Если нули не отображать и выравнивание вправо, то у чисел 9.0000 и 110.489 точка стоит в одном и том же разряде, так как они отобразятся как 9. и 100.

Как должно отображаться число у Вас?

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 02:43:30

Добавлю проблему.
Плавающая точка на дисплее должна иметь гистерезис, то есть переключаться вверх и вниз с разными порогами. Иначе считать показания на границе переключений будет невозможно. Дисплей будет постоянно прыгать между двумя точками.

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 11:39:04

Как должно отображаться число у Вас?

с 1 вариантом (базовый вариант, от этого я хочу уйти) ставим точку где хотим и пользуемся не зависимо от количества разрядов. Недостаток в трех разрядном предел измерения до 9,99вольт и - измерение с точностью 0,01вольт, или измерение до 99,9вольт с точностью 0,1вольт (во всем диапазоне). В 4-х разрядном индикаторе предел и точность - измерение до 99,99вольт с точностью 0,01вольт.
Давайте поэтапно. Есть несколько вариантов
Я может не правильно себе представляю, что значит точка не фиксирована. Чтобы использовать индикатор с меньшим размером (берем 3разряда) и измеряем до 10 вольт будет с точностью 0,01вольт. После 9,99вольт пусть точка сместится в право на 1 разряд, как я и сделал с помощью оператора switch. Вариант 2 или 3 не могу выбрать, потому, что так глубоко не изучал это и не хватает знаний. Думаю что мне больше подходит Вариант 3, вот как в китайском вольтамперметре измерение напряжений до 9,99вольт и переключение точки после этого на 10,0вольт.
Вложения
main.c
Чтоб было яснее, вот что есть на данный момент.
(3.61 KiB) Скачиваний: 10

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 13:07:58

Я посмотрел исходный код, и возникла пара замечаний:
1). Это не связано напрямую с отображением на дисплее, но всё же: среднее арифметическое значение АЦП это не очень правильно. Например, измеряем 250 раз (именно столько в коде) напряжение 4 В. 240 раз выдало 4, а 10 раз было по каким-то причинам 0. Нам очевидно, что 0 - неверные значения, и их надо игнорировать. Но в итоге программа выдаст 3.84. Устраивает такая погрешность?
2). В коде обработки данных АЦП есть такой комментарий:
/* Вычисляем среднее значение АЦП, вольты переводим в милливольты умножением на 100,а не на 1000.
Из-за расположения точки в индикаторе. */
Это означает, что автор кода что-то такое напридумывал, что не оглядываясь на это, нельзя что-либо менять в дисплейной части. Особенно расположение точки :)

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 18:02:27

пара замечаний:
1).Например, измеряем 250 раз (именно столько в коде) напряжение 4 В. 240 раз выдало 4, а 10 раз было по каким-то причинам 0. Нам очевидно, что 0 - неверные значения, и их надо игнорировать. Но в итоге программа выдаст 3.84. Устраивает такая погрешность?
Да, действительно это много, получается 4%. Стесняюсь спросить, каким образом было сделано измерение? вы изменили настройки T2, или используете стороннее приложение, чтоб так на лету задавать количество измерений? Поведайте первокласнику в изучении, я то же так хочу.
2).В комментариях к оригиналу проекта был вопрос почему на 100, а не на 1000, я просто этот комментарий вставил в этот исходник и переписал код под CV.
среднее арифметическое значение АЦП это не очень правильно.
Это "первая проба пера", как нужно? -другая формула? Не много баловался с arduino ide, в одном из скетч как зарядка для акк, делалось 2 измерения, одно 1ms
Спойлер// Измерение UAK, длительность 1мс
float readU0() {
long U1 = 0; //Напряжение на АКБ
float result = 0.0;
float V1 = 0.0;
float K0 = 0.0030324; // pro mini (12.69) UAK 9,01,24
delayMicroseconds(100);
for (int j = 1; j <= 8; j++)
{
U1 += analogRead(A0);
}
V1 = U1 * K0;
result = V1;
return result;
}

другое 100ms
Спойлер// Измерение UAK 128, длительность 100мс
float readU016() {
long U1 = 0; //Напряжение на АКБ
float result = 0.0;
float V1 = 0.0;
float K1=0.00018951;//это Pro mini (12.73>>12.69) UK
delay(86);
for (int j = 1; j <= 128; j++)
{
U1 += analogRead(A0);
}
V1 = U1 * K1;
result = V1;
return result;
}

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

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 18:09:16

lord99 писал(а): каким образом было сделано измерение?
никаким, я просто предположил подобную ситуацию, для наглядности, что даже при 250 выборках небольшое количество ложных данных сильно влияет на среднее арифметическое.
lord99 писал(а):как нужно? -другая формула?
ну, хотя бы так: http://we.easyelectronics.ru/Theory/che ... filtr.html в комментариях там есть отсылки к более серьёзной литературе.

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 18:36:22

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

Это касается не только точки. При (относительно) частом обновлении показания дисплея могут раздражать. Хотя, некоторым даже нравятся подобные "переливы".)

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 19:58:08

При (относительно) частом обновлении показания дисплея могут раздражать.
Ваша правда, вот если говорить за этот проект, то в протеусе "бегает" последний разряд (к примеру 4,21v-4,23v) и на реальном железе так будет? А другой подход в проекте с дисплеем на Lcd, показания как вкопанные стоят. С не фиксированной точкой вопрос остался.
я просто предположил подобную ситуацию, для наглядности, что даже при 250 выборках небольшое количество ложных данных сильно влияет на среднее арифметическое.
Мне попадалось сообщение, человек в протеусе видел и считал эти выборки, правой кн.контекстное меню по мк/ConfigureDiagnostics/ADC modules/debug/ok но я не разобрался в цифрах результатов.
Вложения
test.rar
proteus
(28.64 KiB) Скачиваний: 9
test.hex
ВОЛЬТМЕТР с LCD 1602
(11.96 KiB) Скачиваний: 7

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 20:35:07

только вот с display % 1000/100 разберитесь, это выглядит странно. И не факт, что оптимизатор не упростит операции с равным приоритетом до display % 10
Что именно "странно"? Обычное выражение. Пусть и не самое оптимальное. Выделение значения 2-й цифры display.
И с чего оптимизатор должен делать такую дичь??? "%1000/100" не эквивалентно "/10". И адекватный оптимизатор не станет такого делать.

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 21:22:25

Если требуется определённый порядок выполнения операций с равным приоритетом, то используют скобки. Знаете такие символы ()? Дичь - это писать без них. А оптимизатор легко упростит, если захочет, потому что ему абсолютно похер, что это программист решил какую-то цифру в числе выделить. Только не до %10, это уже я ошибся, а до %100000 (или сколько там нулей получается...)
Это я ещё не говорю о том, что если спросить про приоритеты, то что про них расскажут начинающие...

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 22:00:50

Приоритет должен быть один: писать так, чтобы понял даже дебил. Поэтому скобок жалеть не стоит

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 22:05:29

Если требуется определённый порядок выполнения операций с равным приоритетом, то используют скобки. Знаете такие символы ()? Дичь - это писать без них. А оптимизатор легко упростит, если захочет, потому что ему абсолютно похер, что это программист решил какую-то цифру в числе выделить.
Опять бред несёте... Вам бы учебник по си почитать что-ли? Который сами же рекомендовали выше. 8)
Язык си чётко регламентирует как приоритеты операций, так и направление их выполнения на разных уровнях приоритета.
В выражении display % 1000 /100 все операции имеют одинаковый приоритет и направление выполнения - слева направо. И никаких оптимизаций вменяемый оптимизатор здесь не сделает.

А скобки где ни попадя, городят только неумехи, не сумевшие прочитать и усвоить порядок приоритета и направление операций.

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 22:07:22

Сочувствую.

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 22:07:48

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

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 22:12:33

я бы тебе мог кучу примеров привести, где ты задолбаешься вспоминать приоритеты, но ты же поступишь нечестно, полезешь в гугл смотреть, поэтому, оставайся в своём заблуждении, "пишущий для себя".

Re: Вопросы по С/С++ (СИ)

Вс фев 11, 2024 22:19:35

я бы тебе мог кучу примеров привести, где ты задолбаешься вспоминать приоритеты, но ты же поступишь нечестно, полезешь в гугл смотреть, поэтому, оставайся в своём заблуждении, "пишущий для себя".
Я могу согласиться, что иногда скобки (даже если они реально не нужны) полезно поставить если выражение очень сложное, громоздкое и визуально трудно воспринимается. Но лепить их в простейшем выражении из всего двух элементарных операций... - это, имхо, верх маразма. :dont_know:
Ответить