изменение направления гистограммы в C

Я хочу запрограммировать собственную версию вариометра для представления подъема и понижения в метрах в секунду. Значения отображаются на экране ЖК-модуля. Значения подъема и снижения уменьшаются с помощью потенциометра, который я могу вращать, чтобы изменять значения во время работы программы. Отображаемые значения набора высоты находятся в диапазоне от climb: 0 m/s до climb: 300 m/s, а значения снижения — в диапазоне от sink: 0 m/s до sink: -300 m/s. Этот бит в порядке.

Теперь я хочу отобразить их в виде гистограммы с нулевой точкой в ​​центре. По мере увеличения climb до 300 блоки справа от нулевой точки заполняются соответственно слева направо. Когда значение sink уменьшается до -300, я хочу, чтобы блоки слева от нулевой точки заполнялись соответственно справа налево, по существу изменяя направление правой стороны.

   climb = (DELVAL*600ul + 1023/2)/1023;               
   sink =  (DELVAL*600ul + 1023/2)/1023;

   climb2 = ((DELVAL-511.5)*600ul + 1023/2)/1023;                        
   sink2 =  ((DELVAL+511.5)*600ul + 1023/2)/1023;

   if (DELVAL > 511.5)
   {
        sprintf(buf, "Climb: +%d  m/s ", climb-300);                
        lcd_putxy(2,0,buf);
        for (delay = 0; delay < 50000; delay++);                   
   }
   if (DELVAL < 511.5)
   {
        sprintf(buf, "Sink: -%d   m/s ", ~sink+300);                
        lcd_putxy(2,0,buf);
        for (delay = 0; delay < 50000; delay++);
   }
   character1 = climb2 / 35;
   character2 = sink2 / 35;

      lcd_move(1,10);                                  

   for (i = 0; i < character1; i++)                            
   {

      lcd_putchar(0xD0);                                      
   }
      lcd_putstr("  ");                                      

  for (delay = 0; delay < 50000; delay++);            

  lcd_move(1,2);                                      

  for (i = 0; i < character2; i++)                     
  {    
       lcd_putchar(0xD0);         
  } 
   for (delay = 0; delay < 50000; delay++);

DELVAL — это данные, считанные с потенциометра. Я могу заставить работать правую часть гистограммы, но не могу заставить работать левую часть. Может ли кто-нибудь сообщить мне о каких-либо проблемах с моим кодом и объяснить, как лучше всего заставить работать левую сторону.

Часть, которая не работает в моем коде, — это цикл for, содержащий character2.


person user_1    schedule 15.12.2016    source источник
comment
Вам нужно добавить несколько примеров желаемого результата. Например, в состоянии покоя (нулевой подъем/снижение) вам может понадобиться ░░░░█░░░░; при максимальном наборе высоты ░░░░█████ и при максимальном снижении █████░░░░. Или что-то подобное. Вы можете скопировать и вставить Unicode блочный элемент или рисование прямоугольников символов со страниц Википедии. В StackOverflow также есть справка по редактированию уценки.   -  person Nominal Animal    schedule 15.12.2016
comment
Какой ЖК-контроллер вы используете?   -  person Uint32    schedule 15.12.2016
comment
@NominalAnimal, как у вас есть, именно так, как я этого хочу. Единственная разница в том, что средняя нулевая точка занимает более крупный блочный символ. У меня работает правая сторона, но как только она входит в левую сторону sink, ЖК-дисплей отображает блоки по всему экрану.   -  person user_1    schedule 16.12.2016


Ответы (1)


Вы не описали, что не работает. Но я предполагаю, что левая сторона рисуется слева направо, а не справа налево, как вы предполагали. Где вы намеревались изменить направление левой стороны?

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

int left_bar_length = character2;
int max_bar_length = 300 / 35;
int left_scale_edge = 2;
int scale_center = left_scale_edge + max_bar_length;

// Move cursor to left end of left bar.
lcd_move(1, scale_center - left_bar_length);                                      

// Draw the left bar.
for (i = 0; i < left_bar_length; i++)                     
{    
     lcd_putchar(0xD0);         
} 
person kkrambo    schedule 15.12.2016
comment
Извините, гистограмма слева начинается с середины, а блоки заполняются слева по мере уменьшения DELVAL. @ккрамбо - person user_1; 15.12.2016
comment
Я отредактировал вопрос, чтобы показать раздел, который не работает @kkrambo - person user_1; 15.12.2016
comment
@user_1 Ваш цикл с character2 не работает, потому что он всегда начинает рисовать с (1, 2). Вы не сделали ничего, чтобы изменить направление. Ваш цикл character2 рисует слева направо, как и ваш цикл character1. Исправление, которое я представил здесь, по-прежнему технически рисует слева направо, но оно не всегда начинается с (1, 2). Вместо этого он начинается с (1, scale_center - left_bar_length). Это создаст иллюзию рисования справа налево, потому что правый край левой полосы всегда будет выровнен с центром шкалы. - person kkrambo; 15.12.2016
comment
@user_1 Является ли значение character2 отрицательным? (Я не могу сказать, чего вы ожидаете от своего кода.) Мой код ожидает, что left_bar_length будет положительным, поэтому, возможно, установите для него абсолютное значение character2. - person kkrambo; 15.12.2016
comment
нет, значение character2 должно быть положительным. Это просто значение понижения, которое я отображаю как отрицательное, чтобы создать эффект уменьшения высоты. @ккрамбо - person user_1; 16.12.2016
comment
@user_1 Если character2 вычисляется до правильного значения (что-то между 0 и 8), то я думаю, что мое исправление должно сработать. Но если character2 вычисляется неправильно, значит, что-то не так с вашей математикой. Почему вы добавляете 511,5 к DELVAL при вычислении sink2? Это действительно работает так, как вы ожидаете? Вы прошли свой код в отладчике? - person kkrambo; 16.12.2016
comment
Я еще не прошел код в отладчике. Оглядываться на это сейчас и выполнять некоторые расчеты вручную DELVAL + 511.5 неправильно. Вместо этого я провел некоторые расчеты вручную с DELVAL - 511.5, и sink2 после полного масштабирования до character2 равно от -8 (минимальное значение DELVAL) до 0 (максимальное значение DELVAL (511,5)). Поэтому, когда он входит в мой цикл for, он уже ниже 0, поэтому цикл for выполняется неправильно. Так что, возможно, решение состоит в том, чтобы инвертировать sink2, затем уменьшить его до character2 и следовать вашему предложению оттуда. Будет ли это правильно? @ккрамбо - person user_1; 16.12.2016
comment
Следуя предложению, я имею в виду замену character2 на left_bar_length. - person user_1; 16.12.2016
comment
@ user_1 Да, я полагаю, это заставит вас работать достаточно хорошо. Но почему вы инвертируете целочисленное значение с помощью оператора ~? Я не верю, что это правильный способ использования этого оператора, и я думаю, что это может привести к неточностям. Вы должны использовать метод абсолютного значения, abs(), или просто инвертировать значение с помощью -. - person kkrambo; 16.12.2016