#1 2024-04-27 09:05:34

chipaka
Учасник
Зареєстрований: 2024-04-27
Повідомлень: 2

Шкала, що заливається

Доброго часу.
Народ допоможіть початківцу. Є такий скетч. Ніяк не можу повернути шкалу, що заливається. заливання починається зверху. Як зробити знизу.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>
#define SENSOR A0
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SH1106 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

void setup() {
  display.begin(SH1106_SWITCHCAPVCC);
  display.display();
  delay(1000);
  display.clearDisplay();
  display.setRotation(0);
  }
 
void loop() {
   
  display.clearDisplay();
  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(WHITE); // Draw white text
  display.setCursor(0, 3);     // Start at top-left corner 
   
  display.drawRect(100, 0, 18, 64, 1); // рисуем прямоугольник 1

  int raw = analogRead(SENSOR);

  static int avgVadc = 0;
  avgVadc = (avgVadc * 3 + raw)/4;
  avgVadc = constrain(avgVadc, 0, 500);
  int FuelLevel = map(avgVadc, 0, 500, 0, 300);
  display.setCursor(20, 10);
  display.setTextSize(3);
  display.println(FuelLevel);
  int FuelLeve2 = map(avgVadc, 0, 500, 0, 64);
  display.fillRect (100, 0, 18, FuelLeve2, 1);
   
  display.display();
  delay(100);
}

Остання редакція chipaka (2024-04-27 09:06:51)

Неактивний

#2 2024-04-27 21:04:09

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 205

Re: Шкала, що заливається

Спробуйте

display.fillRect (100, 64-FuelLeve2, 18, FuelLeve2, 1);

Але у вашому коді є інші проблеми. Сама рамка при висоті 64 вже займає 2 пікселі, тому для шкали залишається 62 пікселя. А в Adafruit GFX є проблема з граничними значеннями: fillRect() малює прямокутник висотою в 1 піксель (лінію), навіть якщо висота дорівнює 0. Тобто для 0 і 1 зображення буде однаковим.

Для точнішого відображення FuelLeve2 потрібно мапити на діапазон [0..62] і не викликати fillRect() при значенні 0:

int FuelLeve2 = map(avgVadc, 0, 500, 0, 62);
if (FuelLeve2) {
  display.fillRect (100, 63-FuelLeve2, 18, FuelLeve2, 1);
}

Це якщо avgVadc приймає значення від 0 до 500 включно, і вас задовільняє округлення до найменшого цілого, що виконує map(). Якщо ж хочете відображати ненульовий рівень при невеликих значеннях avgVadc, або повний рівень при значеннях, трохи менших від 500, тоді потрібно змінити формулу для мапінгу.

Доречі, не обовʼязково малювати поверх вертикальних ліній рамки, має бути достатньо

display.fillRect (101, 63-FuelLeve2, 16, FuelLeve2, 1);

Остання редакція dimich (2024-04-27 21:16:37)

Неактивний

#3 2024-04-27 21:20:17

chipaka
Учасник
Зареєстрований: 2024-04-27
Повідомлень: 2

Re: Шкала, що заливається

Дякую

Неактивний

#4 2024-04-27 22:00:12

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 205

Re: Шкала, що заливається

Для округлення до найближчого цілого можна так:

long map_round(long x, long in_max, long out_max)
{
  return (x * out_max + in_max / 2) / in_max;
}
...
int FuelLeve2 = map_round(avgVadc, 500, 62);
...

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму