Рисование гистограммы на жидкокристаллическом дисплее

Я делаю свои первые шаги на Arduino и пытаюсь выполнить упражнение, в котором мне нужно нарисовать графическую полосу на жидкокристаллическом дисплее 16x2, которая показывает значения, считываемые из вектора из 16 целочисленных элементов, усиленных значением, считываемым с потенциометра (подключенного к аналоговому выводу A0) во время выполнения. График должен меняться в режиме реального времени, когда я перемещаю курсор потенциометра влево или вправо.

У меня есть следующая структура кода:

void loop() {

// Считайте 16 векторных элементов и затем сопоставляйте их с высотой экрана ...

// Выведите их значения, умноженные на значение, считанное с потенциометра, на последовательный монитор ...

// Нарисуйте полосу для каждого из векторных элементов (в итоге у вас будет 16 полос)...

// Если график достиг края экрана, больше не усиливайте его. Если она достигла дна, сделайте то же самое

//Подожди немного. Начните рисовать все с нуля.

До сих пор у меня есть вот что:

#include<LiquidCrystal.h>

// Создать жидкокристаллический объект и соединить управляющие провода

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int vector[16] = {3, 7, 10, 15, 28, 12, 43, 1, 6, 19, 29, 23, 54, 76, 57, 66};

int value=0;

void setup(){
  Serial.begin(9600);
  
  // количество столбцов и строк жидкокристаллического дисплея
  
  lcd.begin(16, 2);
}

void loop(){
  
  value = analogRead(A0);

  for(int i=0; i<16; i++){
    int vector2[i] = map(vector[i], 0, 1024, 0, 20);
    Serial.println(vector2[i]*value);
  }
}

Однако до сих пор я получаю следующую ошибку:

 In function 'void loop()':
28:25: error: array must be initialized with a brace-enclosed initializer
 exit status 1

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

#include<LiquidCrystal.h>

// Создайте жидкокристаллический объект и соедините управляющие провода

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte bar[] ={B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111};

void setup(){
  Serial.begin(9600);
  
  // Укажите количество столбцов и строк жидкокристаллического дисплея
  
  lcd.begin(16, 2);
  lcd.createChar(0, bar);
}

void loop(){
lcd.setCursor(0,0);
cd.write(byte(0));
  
}

Но даже это будет печатать только столбец в первой строке и столбце, а не в обеих строках и первом столбце ЖК-дисплея.

Может ли кто-то помочь мне с ошибкой, которая у меня уже есть, и дать мне некоторое представление о том, как сделать последние 3 шага структуры кода?

, 👍1

Обсуждение

просмотрите, как работать с массивами ... https://www.arduino.cc/reference/en/language/variables/data-types/array/, @jsotola

ваш код повторно печатается в местоположение 0,0 ... я не вижу, что в этом непонятного, @jsotola

Вы используете массив vector2[] внутри loop (), который имеет неопределенный размер, потому что вы не правильно его объявили. Ошибка достаточно описательна и также выделит строку, где была обнаружена ошибка., @StarCat

Хорошо получил часть vector2 уже! Спасибо, @João Sacramento

Как вы надеетесь нарисовать 16 - элементную гистограмму в текстовом ЖК-дисплее? Самое близкое, что вы можете получить,-это использовать пользовательские символы, чтобы иметь частичные блоки для вертикального графика., @Majenko

@Majenko это было то, о чем я думал, но не могу придумать, как поместить символ столбца в обе строки или как нарисовать его в зависимости от значения потенциометра value2*, @João Sacramento


1 ответ


1

Во - первых, вам нужно будет определить некоторые пользовательские символы. Есть примеры того, как это сделать. Вам нужны символы, которые постепенно заполняются снизу доверху, например:

▁ ▂ ▃ ▄ ▅ ▆ ▇ █

Теперь у вас есть 8 строк на символ и две строки символов, что дает вам возможный диапазон рисования от 0 до 16. Поэтому вам нужно сопоставить свой максимальный диапазон с этим диапазоном 0-16.

Наконец, вы хотите создать функцию для рисования одной полосы. Для этого потребуется два параметра - положение стержня (x) и высота стержня (y). Немного математики позже, и вы сможете решить, что печатать верхними и нижними символами.

  • Если значение равно = 0:
    • И верх, и низ-это пробелы
  • Если значение равно:
    • Нижний символ-это символ с тем же количеством строк, что и значение
    • Верхний символ пуст.
  • Если значение > 8:
    • Нижний символ-это тот, у которого заполнены все 8 строк
    • Верхний символ - это символ со значением-8 заполненных строк.

Таким образом, вы можете получить что - то вроде (примечание-непроверено):

const uint8_t bars[8][8] = {
    { 0, 0, 0, 0, 0, 0, 0, 0xff },
    { 0, 0, 0, 0, 0, 0, 0xff, 0xff },
    { 0, 0, 0, 0, 0, 0xff, 0xff, 0xff },
    { 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff },
    { 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff },
    { 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
    { 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
};

void setup() {
    // другие вещи, такие как настройка ЖК-дисплея...

    for (uint8_t i = 0; i < 8; i++) {
        lcd.createChar(i, bars[i]);
    }
}

void drawBar(uint8_t x, uint8_t y) {
    char top, bot;

    if (y == 0) { // Оба пробела
        top = ' ';
        bot = ' ';
    } else if (y <= 8) { // Bottom has bar graph, top is empty
        top = ' ';
        bot = val - 1; // Символы начинаются с 0, поэтому 1-8 равно 0-7
    } else if (y <= 16) { // Bottom is full, top has bar graph
        top = (y - 9); //  Символы начинаются с 0, поэтому 9-16-это 0-7
        bot = 7;
    } else { // Переполнение - как верхнее, так и нижнее заполнение
        top = 7;
        bot = 7;
    }

    lcd.setCursor(x, 0);
    lcd.write(top);
    lcd.setCursor(x, 1);
    lcd.write(bot);
}

void loop() {
    // ваши вещи здесь
}

Затем, чтобы нарисовать полосу, вы просто вызываете drawBar 16 раз:

for (uint8_t i = 0; i < 16; i++) {
    uint8_t y = <your calculation on vector2[i] here>
    drawBar(i, y);
}

Если вы все сделали правильно, вы должны в конечном итоге получить что-то вроде:

▁█ ▄ ▆█▇   ▃ ▃▇
██▃█▇███▅▆▇█▆██▃
,