#1 Re: Програмування Arduino » Arduino vs Servo » Сьогодні 07:55:36

живлення від компа ...5 і 12 в,обіцяли такий самий ...спробую його
Вчора дросельний-сірий запустив ...оцей норм працює,хоча дротів 9 шт.

#2 Re: Програмування Arduino » Arduino vs Servo » Вчора 19:16:02

там енкодер стоїть
може ви і праві ..."Поскользнулся,упал,потерерял сознание,очнулся,ГИПС"
нарахунок конструкції ...це просто нехер робити

#3 Re: Програмування Arduino » Arduino vs Servo » Вчора 15:03:49

ха...неадекватно ,починаю керувати ,добре повертає вліво-вправо...а потім може поїхати казна-куди..ще падло пищить і гріється
в мене підозра ,що його тре калібрувати...

#4 Re: Програмування Arduino » Arduino vs Servo » 2025-08-31 15:58:35

Маю запитання !
Хто мав справу с сервоприводами з літаючих "тварин"
наприклад SERV 01.02-150-15-PWM
Не можу запустити ,веде себе не адекватно
Візуально цілий
Живлення 12В. BLDC-сервопривід с енкодером з PWM

#5 Програмування Arduino » Arduino vs Servo » 2025-08-31 15:41:48

nickjust
відповідей: 10

Вітаю
Знайомий купив сервотестер за 400 грн,взяв спробувати ...не сподобався
Зробив свій ,може кому знадобиться

servotst.jpg




#include <Servo.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// === OLED 128x64 (измени на 32, если у тебя 0.91") ===
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// === Пины ===
const int BUTTON_PIN = A1;     // ADKeyboard
const int POT_PIN = A3;        // Потенциометр
const int SERVO_PIN = 9;

// === Диапазоны ШИМ ===
const int MIN1 = 900,  MAX1 = 2100;  // Режим 1
const int MIN2 = 700,  MAX2 = 2300;  // Режим 2
const int MIN3 = 500,  MAX3 = 2500;  // Режим 3

// === ADC значения ADKey (QYF-995) ===
const int ADC_MODE1  = 786;  // Переключает: MANUAL → AUTO → R-POS
const int ADC_LEFT   = 145;  // Влево
const int ADC_MODE2  = 493;  // Меняет скорость в AUTO
const int ADC_MODE3  = 0;    // Переключает режимы 1→2→3
const int ADC_RIGHT  = 304;  // Вправо
const int ADC_TOLERANCE = 50;

// === Режимы управления ===
enum ControlMode { MANUAL, AUTO, RPOS };
ControlMode controlMode = MANUAL;

// === Переменные ===
Servo myservo;
int mode = 1;                    // 1,2,3 — диапазон
int pos1 = 1500, pos2 = 1500, pos3 = 1500;
int currentMicros = 1500;

// === Авто-режим ===
unsigned long lastAutoMove = 0;
bool autoDirection = true;
int autoStep = 10;

// === Скорость в AUTO ===
int autoSpeedIndex = 1;
int autoSpeeds[3] = {300, 150, 80}; // ms

// === Тихий режим (отключение сервы при покое) ===
unsigned long lastMoveTime = 0;
bool isDetached = false;

// === Для удержания кнопок ===
int lastButton = -1;
unsigned long lastPressTime = 0;
const int DEBOUNCE_DELAY = 200;

// === Прототипы функций ===
int readButton(int adcValue);
void switchMode(int newMode);
int getMin();
int getMax();
void updateDisplay();

void setup() {
  Serial.begin(9600);
  Serial.println("=== Servo Tester: Final Build ===");

  // === OLED ===
  delay(100);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("OLED not found!");
    while (1);
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("Starting...");
  display.display();
  delay(1000);

  switchMode(1);
  currentMicros = 1500;
  myservo.writeMicroseconds(currentMicros);
  lastMoveTime = millis();
  updateDisplay();
}

void loop() {
  int adcValue = analogRead(BUTTON_PIN);
  int button = readButton(adcValue);

  // === Обработка нажатий ===
  if (button != -1 && button != lastButton) {
    lastPressTime = millis();
    lastButton = button;

    // === MODE 3: смена диапазона ===
    if (button == 3) {
      mode = (mode % 3) + 1;
      switchMode(mode);
      updateDisplay();
    }

    // === MODE 2: смена скорости в AUTO ===
    else if (button == 2 && controlMode == AUTO) {
      autoSpeedIndex = (autoSpeedIndex + 1) % 3;
      updateDisplay();
    }

    // === MODE 1: смена режима управления ===
    else if (button == 0) {
      if (controlMode == MANUAL)      controlMode = AUTO;
      else if (controlMode == AUTO)   controlMode = RPOS;
      else if (controlMode == RPOS)   controlMode = MANUAL;
      updateDisplay();
    }
  }

  // === Выход из AUTO или R-POS при LEFT/RIGHT ===
  if (controlMode != MANUAL && (button == 1 || button == 4)) {
    controlMode = MANUAL;
    updateDisplay();
  }

  // === Ручное управление ===
  if (controlMode == MANUAL) {
    if (button == 1 && currentMicros > getMin()) {
      if (millis() - lastPressTime > 100) {
        currentMicros -= (millis() - lastPressTime > 500) ? 20 : 10;
        if (currentMicros < getMin()) currentMicros = getMin();
        attachAndWrite(); // включает серву, если была отключена
        lastMoveTime = millis();
        updateDisplay();
        lastPressTime = millis();
      }
    }
    if (button == 4 && currentMicros < getMax()) {
      if (millis() - lastPressTime > 100) {
        currentMicros += (millis() - lastPressTime > 500) ? 20 : 10;
        if (currentMicros > getMax()) currentMicros = getMax();
        attachAndWrite();
        lastMoveTime = millis();
        updateDisplay();
        lastPressTime = millis();
      }
    }
  }

  // === Авто-режим ===
  if (controlMode == AUTO) {
    if (millis() - lastAutoMove > autoSpeeds[autoSpeedIndex]) {
      lastAutoMove = millis();
      if (autoDirection) {
        currentMicros += autoStep;
        if (currentMicros >= getMax()) {
          currentMicros = getMax();
          autoDirection = false;
        }
      } else {
        currentMicros -= autoStep;
        if (currentMicros <= getMin()) {
          currentMicros = getMin();
          autoDirection = true;
        }
      }
      attachAndWrite();
      lastMoveTime = millis();
      updateDisplay();
    }
  }

  // === Управление от потенциометра ===
  if (controlMode == RPOS) {
    int potValue = analogRead(POT_PIN);
    int target = map(potValue, 0, 1023, getMin(), getMax());
    if (abs(currentMicros - target) > 5) {
      currentMicros += (currentMicros < target) ? 5 : -5;
      attachAndWrite();
      lastMoveTime = millis();
      updateDisplay();
    }
  }

  // === Авто-отключение сервы при покое (тихий режим) ===
  if (!isDetached && millis() - lastMoveTime > 3000) {
    myservo.detach();
    isDetached = true;
  }

  // === Сброс кнопки ===
  if (button == -1 && lastButton != -1) {
    lastButton = -1;
  }

  delay(5);
}

// === Функция: включить серву и отправить сигнал ===
void attachAndWrite() {
  if (isDetached) {
    myservo.attach(SERVO_PIN, getMin(), getMax());
    isDetached = false;
  }
  myservo.writeMicroseconds(currentMicros);
}

// === Определение кнопки ===
int readButton(int adcValue) {
  if (abs(adcValue - ADC_MODE1)  < ADC_TOLERANCE) return 0;
  if (abs(adcValue - ADC_LEFT)   < ADC_TOLERANCE) return 1;
  if (abs(adcValue - ADC_MODE2)  < ADC_TOLERANCE) return 2;
  if (abs(adcValue - ADC_MODE3)  < ADC_TOLERANCE) return 3;
  if (abs(adcValue - ADC_RIGHT)  < ADC_TOLERANCE) return 4;
  return -1;
}

// === Переключение режима ===
void switchMode(int newMode) {
  if (mode == 1) pos1 = currentMicros;
  if (mode == 2) pos2 = currentMicros;
  if (mode == 3) pos3 = currentMicros;
  mode = newMode;
  if (mode == 1) {
    myservo.attach(SERVO_PIN, MIN1, MAX1);
    currentMicros = pos1;
  } else if (mode == 2) {
    myservo.attach(SERVO_PIN, MIN2, MAX2);
    currentMicros = pos2;
  } else if (mode == 3) {
    myservo.attach(SERVO_PIN, MIN3, MAX3);
    currentMicros = pos3;
  }
  myservo.writeMicroseconds(currentMicros);
  lastMoveTime = millis();
  isDetached = false;
}

// === Мин/макс текущего режима ===
int getMin() { return (mode == 1) ? MIN1 : (mode == 2) ? MIN2 : MIN3; }
int getMax() { return (mode == 1) ? MAX1 : (mode == 2) ? MAX2 : MAX3; }

// === Обновление дисплея ===
void updateDisplay() {
  display.clearDisplay();

  display.setCursor(0, 0);
  display.print("Control:");
  if (controlMode == MANUAL) display.println("MANUAL");
  else if (controlMode == AUTO) display.println("AUTO");
  else if (controlMode == RPOS) display.println("R-POS ");

  display.setCursor(0, 12);
  display.print("Range:");
  display.print(getMin());
  display.print("-");
  display.print(getMax());

  display.setCursor(0, 24);
  display.print("Position:");
  display.print(currentMicros);

  if (controlMode == AUTO) {
    display.setCursor(0, 36);
    display.print("Spd:");
    if (autoSpeedIndex == 0) display.println("Slow");
    else if (autoSpeedIndex == 1) display.println("Medium");
    else display.println("Fast");
  } else {
    display.setCursor(0, 36);
    display.println("Speed:---");
  }

  // Прогресс-бар
  int bar = map(currentMicros, getMin(), getMax(), 0, 126);
  display.drawRect(1, 54, 126, 6, SSD1306_WHITE);
  display.fillRect(2, 55, bar, 4, SSD1306_WHITE);

  display.display();
}

Інструкція з використання тестера сервоприводу

Цей пристрій призначений для тестування сервоприводів з можливістю зміни діапазону керування, режимів роботи та візуальним відображенням на дисплеї OLED.

Підключення:

Підключіть сервопривід до піну PWM (сигнальний дріт — жовтий/білий).
Підключіть живлення:Бажано використовувати окреме джерело 5–12 В для сервоприводу.
Загальна "земля" (GND) повинна бути спільною з Arduino.
         
     


Керування кнопками ADKeyboard

Кнопка MODE 1:
   
Перемикає режим керування:
MANUAL-AUTO-R-POSITION

Кнопка MODE 3:
Перемикає діапазон ШІМ:
900–2100 us
700–2300
500–2500

Кнопка MODE 2:
   
У режимі AUTO: змінює швидкість руху:
повільно > середньо > швидко

Кнопка LEFT у режимі MANUAL: переміщує сервопривід вліво
Кнопка RIGHT у режимі MANUAL: переміщує сервопривід вправо

Режими керування
1. MANUAL (ручний режим)

Керування кнопками LEFT і RIGHT.
При короткому натисканні — малий крок (10 мкс).
При довгому утриманні — плавне прискорення (до 20 мкс за крок).
Вихід з режимів AUTO або R-POSITION — натисніть LEFT або RIGHT.
     

2. AUTO (автоматичний режим)

Сервопривід автоматично рухається від мінімального до максимального положення і назад.
Швидкість змінюється кнопкою MODE 2.
Вихід: натисніть LEFT або RIGHT.
     

3. R-POS (керування від потенціометра)

Оберіть потенціометр на A3, щоб керувати положенням сервоприводу.
Вихід: натисніть LEFT або RIGHT.
     


Інформація на OLED-дисплеї

На дисплеї відображається:

Ctrl: поточний режим керування (MANUAL, AUTO, R-POSITION)
Range: діапазон ШІМ (наприклад, 900-2100)
Position: поточне положення сервоприводу в мікросекундах (мкс)
Speed: швидкість у режимі AUTO (Slow, Medium, Fast)
Прогрес-бар: візуальне відображення положення сервоприводу
     


Тихий режим (автоматичне відключення):

Якщо сервопривід не рухається 3 секунди, він автоматично відключається (detach),
щоб не гудів.При наступному керуванні він автоматично підключається назад.
     


Поради та зауваження:

Якщо сервопривід гудить у спокої — це нормально для дешевих моделей (SG90, MG996R).
Він намагається утримати положення.Для стабільної роботи використовуйте окреме джерело
живлення.

#6 Re: Програмування Arduino » Лічильник оборотів на моторчику від CD » 2025-08-26 18:01:49

Беремо оптопару з опто мишки
Принцип роботи: Кулко з прорізами обертається між ІЧ-випромінювачем та приймачем оптопари.
При кожному проходженні прорізу сигнал на піні змінюється (LOW - HIGH).
Вважаємо кількість імпульсів.
За замовчуванням: 1 імпульс = 1 проріз. Але нам потрібно: 1 оборот = N прорізів > калібрування.

Встанови через Arduino IDE > Скетч > Підключити бібліотеку > Керувати бібліотеками:
TM1637Display (автор: avishorp)
   
Як калібрувати:
Запусти пристрій. Повертай колесо рівно один оборот. Натисніть кнопку "Калібрування" - екран покаже "CAL". Зроби один повний оборот. Знову натисніть "Калібрування" - пристрій запам'ятає кількість імпульсів за оборот.

Або два датчики Холла, зсунуті по колу на 1/4 кроку між магнітами → вийде квадратурний сигнал.
Варіанти:
    Один магніт + два датчики - зміщені на 45-90 ° механічно

schet_20250826-1838.jpg


#include <TM1637Display.h>

// Пины
#define CLK 2
#define DIO 3
#define PIN_A 4
#define PIN_B 5
#define BTN_RESET 6
#define BTN_CAL 7

// TM1637 дисплей
TM1637Display display(CLK, DIO);

// Переменные
volatile long pulseCount = 0;        // счётчик импульсов
long revolutions = 0;                // количество оборотов
int pulsesPerRevolution = 24;        // калибровочное значение (по умолчанию 24 прорези на оборот)
bool calibrating = false;            // режим калибровки
unsigned long lastTime = 0;

// Предварительное объявление
void updateDisplay();
void ICACHE_RAM_ATTR onPulse();

void setup() {
  pinMode(PIN_A, INPUT_PULLUP);
  pinMode(PIN_B, INPUT_PULLUP);
  pinMode(BTN_RESET, INPUT_PULLUP);
  pinMode(BTN_CAL, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(PIN_A), onPulse, CHANGE);
  attachInterrupt(digitalPinToInterrupt(PIN_B), onPulse, CHANGE);

  display.setBrightness(0x0f); // максимальная яркость

  Serial.begin(9600);
}

void loop() {
  static unsigned long lastDebounce = 0;
  int readingReset = digitalRead(BTN_RESET);
  int readingCal = digitalRead(BTN_CAL);

  // Кнопка сброса
  if (readingReset == LOW && millis() - lastDebounce > 200) {
    pulseCount = 0;
    revolutions = 0;
    updateDisplay();
    lastDebounce = millis();
  }

  // Кнопка калибровки
  if (readingCal == LOW && millis() - lastDebounce > 200) {
    calibrating = !calibrating;
    if (calibrating) {
      // Выводим "CAL" на дисплей
      uint8_t data[] = {0b00111001, 0b00001110, 0b00111001, 0b00111001}; // "CAL"
      display.setSegments(data);
    } else {
      // Выход из калибровки — считаем, что 1 оборот = текущее значение |pulseCount|
      if (abs(pulseCount) > 0) {
        pulsesPerRevolution = abs(pulseCount);
      }
      pulseCount = 0;
      revolutions = 0;
    }
    delay(300); // антидребезг
    lastDebounce = millis();
  }

  // Обновляем обороты раз в 100 мс
  if (millis() - lastTime > 100) {
    if (!calibrating) {
      revolutions = pulseCount / pulsesPerRevolution;
    }
    updateDisplay();
    lastTime = millis();
  }
}

// Обработка изменения сигнала на A или B
void ICACHE_RAM_ATTR onPulse() {
  static uint8_t lastState = 0;
  uint8_t state = (digitalRead(PIN_A) << 1) | digitalRead(PIN_B);

  if (state != lastState) {
    // Квадратурный декодер
    switch (lastState) {
      case 0b00:
        if (state == 0b01) pulseCount--;
        else if (state == 0b10) pulseCount++;
        break;
      case 0b01:
        if (state == 0b11) pulseCount--;
        else if (state == 0b00) pulseCount++;
        break;
      case 0b11:
        if (state == 0b10) pulseCount--;
        else if (state == 0b01) pulseCount++;
        break;
      case 0b10:
        if (state == 0b00) pulseCount--;
        else if (state == 0b11) pulseCount++;
        break;
    }
    lastState = state;
  }
}

// Обновление дисплея
void updateDisplay() {
  if (calibrating) return;

  // Показываем обороты (с учётом знака)
  char str[5];
  sprintf(str, "%4ld", revolutions);
  display.showNumberDec(revolutions, false, 4, 0);
}

#7 Re: Програмування Arduino » Arduino vs LCD Trium Mars трабл » 2025-08-18 10:32:45

2dimich  якщо можете накидайте мені скетч ..для роботи тріума з бібліотекою PCD8544 та PCF8812  ...не виходить ...нема зображення

#8 Re: Програмування Arduino » Arduino vs LCD Nokia 8310 » 2025-08-16 11:21:52

в групах та на олх продають ломані телефони ...деякі просто як лом ....приносили мені по 5 грн вбиті ...купляєшь кота у мішку ііііі тестуєшь...якщо у вашому місці проживання є майстерня ....у них цього "гуталина просто завались"


P.S.  вчора принесли утопленіка motorolla C115 // за так віддали

#10 Re: Програмування Arduino » Arduino vs LCD Nokia 8310 » 2025-08-15 15:01:50

купив за 10 грн...паяти ,просто кайф , з моим то зором
для показометра ...вистачає

Зара у коробці біля 100 диспів для ізврату :-)
Та і мозок троха занятий ....

#11 Програмування Arduino » Arduino vs LCD Nokia 8310 » 2025-08-15 10:52:42

nickjust
відповідей: 5

Доброго усім дня
Може комусь стане на нагоді
Підключення дисплею від Nokia8310 (6510) до Arduino
та бібліотека https://dropmefiles.com.ua/ua/UyVL

nokia_6510_8310.jpg

#12 Re: Програмування Arduino » Arduino vs LCD Trium Mars трабл » 2025-08-15 10:44:07

Дисплей на Trium Mars монохромний 96x65 pix Буфер 102x72 pix
Контролер LPH7690
Такий стоїть на NOKIA 6210
На форумах пишуть,що подібний до PCD8544 та PCF8812 - але не зміг адаптувати
На Рахунок дзеркалення- я мав на увазі , що дисплей на телефоні шлейфом униз,
Відображаю графіку та текст  шлейфом наверх ...побороти не зміг


Якщо маєте нормальні фонти для монохромних диспів з кирилицею ,прошу поділитися

#13 Re: Програмування Arduino » Arduino vs LCD Trium Mars трабл » 2025-08-14 18:07:56

Що не до вподоби
-кирилиця не працює
-текст виводить де попало
-пробував більший шрифт ..не працює
-дзеркалить по Y

Казали що норм працює з PCF8812 (PCD8544) - не получилось





#include <Arduino.h>
#include <SPI.h>

// init disp
#define USE_HARDWARE_SPI 0
#define LCD_CONTRAST     0x15
#define LCD_CS           8
#define LCD_DC          10
#define LCD_RST          9
#define SOFT_SCK        13
#define SOFT_MOSI       11
#define SPI_DELAY        5

// ===== font 5x8: 5 col + 3 space)
// Формат: { col0, col1, col2, col3, col4, 0x00, 0x00, 0x00 }
const uint8_t fontData[][8] = {
  // A (0)
  {0x7E, 0x11, 0x11, 0x11, 0x7E, 0x00, 0x00, 0x00},
  // B (1)
  {0x7F, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, 0x00},
  // C (2)
  {0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x00, 0x00},
  // D (3)
  {0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x00, 0x00},
  // E (4)
  {0x7F, 0x49, 0x49, 0x49, 0x41, 0x00, 0x00, 0x00},
  // F (5)
  {0x7F, 0x09, 0x09, 0x09, 0x01, 0x00, 0x00, 0x00},
  // G (6)
  {0x3E, 0x41, 0x49, 0x49, 0x7A, 0x00, 0x00, 0x00},
  // H (7)
  {0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00, 0x00, 0x00},
  // I (8)
  {0x00, 0x41, 0x7F, 0x41, 0x00, 0x00, 0x00, 0x00},
  // J (9)
  {0x20, 0x40, 0x41, 0x7F, 0x01, 0x00, 0x00, 0x00},
  // K (10)
  {0x7F, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00},
  // L (11)
  {0x7F, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00},
  // M (12)
  {0x7F, 0x02, 0x0C, 0x02, 0x7F, 0x00, 0x00, 0x00},
  // N (13)
  {0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00, 0x00, 0x00},
  // O (14)
  {0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x00, 0x00},
  // P (15)
  {0x7F, 0x09, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00},
  // Q (16)
  {0x3E, 0x41, 0x45, 0x43, 0x3E, 0x00, 0x00, 0x00},
  // R (17)
  {0x7F, 0x09, 0x19, 0x29, 0x46, 0x00, 0x00, 0x00},  
  // S (18)
  {0x46, 0x49, 0x49, 0x49, 0x32, 0x00, 0x00, 0x00},
  // T (19)
  {0x01, 0x01, 0x7F, 0x01, 0x01, 0x00, 0x00, 0x00},
  // U (20)
  {0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00, 0x00, 0x00},
  // V (21)
  {0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00, 0x00, 0x00},
  // W (22)
  {0x3F, 0x40, 0x3C, 0x40, 0x3F, 0x00, 0x00, 0x00},
  // X (23)
  {0x41, 0x22, 0x1C, 0x22, 0x41, 0x00, 0x00, 0x00},
  // Y (24)
  {0x07, 0x08, 0x70, 0x08, 0x07, 0x00, 0x00, 0x00},
  // Z (25)
  {0x41, 0x61, 0x51, 0x49, 0x47, 0x00, 0x00, 0x00},

  // num 0-9 (26..35)
  {0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00, 0x00, 0x00}, // 0
  {0x00, 0x42, 0x7F, 0x40, 0x00, 0x00, 0x00, 0x00}, // 1
  {0x61, 0x49, 0x49, 0x49, 0x3F, 0x00, 0x00, 0x00}, // 2
  {0x46, 0x49, 0x49, 0x49, 0x3E, 0x00, 0x00, 0x00}, // 3
  {0x38, 0x14, 0x14, 0x14, 0x7F, 0x00, 0x00, 0x00}, // 4
  {0x4F, 0x49, 0x49, 0x49, 0x31, 0x00, 0x00, 0x00}, // 5
  {0x3E, 0x49, 0x49, 0x49, 0x3A, 0x00, 0x00, 0x00}, // 6
  {0x01, 0x01, 0x71, 0x0D, 0x03, 0x00, 0x00, 0x00}, // 7
  {0x36, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, 0x00}, // 8
  {0x26, 0x49, 0x49, 0x49, 0x3E, 0x00, 0x00, 0x00}  // 9
};

// char ASCII
const uint8_t* getChar(char c) {
  if (c >= 'A' && c <= 'Z') return fontData[c - 'A'];
  if (c >= '0' && c <= '9') return fontData[c - '0' + 26];
  return nullptr;
}

// out xy
void drawText(uint8_t x, uint8_t y, const char* text) {
  setPosition(x, y);
  while (*text) {
    char c = *text;
    if (c >= 'a' && c <= 'z') c -= 32; // char high
    const uint8_t* chr = getChar(c);
    if (chr) {
      for (int i = 0; i < 8; i++) {
        sendData(chr[i]);
      }
    }
    text++;
  }
}

// central char
void drawCentered(const char* text) {
  int len = strlen(text);
  int totalWidth = len * 5; // 5 px w/o space
  int x = (84 - totalWidth) / 2;
  drawText(x, 2, text);
}

// ===== SPI and base func =====
void spiInit() {
  #if USE_HARDWARE_SPI
    SPI.begin();
    SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  #else
    pinMode(SOFT_SCK, OUTPUT);
    pinMode(SOFT_MOSI, OUTPUT);
  #endif
  pinMode(LCD_CS, OUTPUT);
  pinMode(LCD_DC, OUTPUT);
  pinMode(LCD_RST, OUTPUT);
  digitalWrite(LCD_CS, HIGH);
}

void spiTransfer(uint8_t data) {
  #if USE_HARDWARE_SPI
    SPI.transfer(data);
  #else
    for (uint8_t i = 0; i < 8; i++) {
      digitalWrite(SOFT_MOSI, (data & 0x80) ? HIGH : LOW);
      digitalWrite(SOFT_SCK, HIGH);
      delayMicroseconds(SPI_DELAY);
      digitalWrite(SOFT_SCK, LOW);
      delayMicroseconds(SPI_DELAY);
      data <<= 1;
    }
  #endif
}

void sendCommand(uint8_t cmd) {
  digitalWrite(LCD_DC, LOW);
  digitalWrite(LCD_CS, LOW);
  spiTransfer(cmd);
  digitalWrite(LCD_CS, HIGH);
}

void sendData(uint8_t data) {
  digitalWrite(LCD_DC, HIGH);
  digitalWrite(LCD_CS, LOW);
  spiTransfer(data);
  digitalWrite(LCD_CS, HIGH);
}

void setPosition(uint8_t x, uint8_t y) {
  sendCommand(0x40 | y);
  sendCommand(0x80 | x);
}

void initDisplay() {
  digitalWrite(LCD_RST, LOW);
  delay(50);
  digitalWrite(LCD_RST, HIGH);
  delay(150);
  sendCommand(0x21); // on extend cmd
  sendCommand(0xCF); // U stand
  sendCommand(0x04); // Tc compens
  sendCommand(LCD_CONTRAST); // contrast
  sendCommand(0x20); // return base cmd
  sendCommand(0x0C); // on disp w/o cursor
  sendCommand(0x1B); // activate
  delay(10);
}

void fillScreen(uint8_t pattern) {
  for (uint8_t y = 0; y < 9; y++) {
    setPosition(0, y);
    for (uint8_t x = 0; x < 96; x++) {
      sendData(pattern);
    }
  }
}

// ===== main prog =====
void setup() {
  Serial.begin(9600);
  spiInit();
  initDisplay();

  // clear disp
  fillScreen(0x00);

  // output "VITAM" on central
  drawCentered("VITAM");
  delay(5000);
  fillScreen(0x00);
  drawText(0, 0, "HELLO");     // down left position
  drawText(10,20, "1234567890");      // num
  drawCentered("TEST");        // central
  

}

void loop() {
  // xz
  delay(1000);
}

#14 Re: Програмування Arduino » Arduino vs LCD Trium Mars трабл » 2025-08-14 11:53:28

де можна скачати толкову халявну прогу для роботи з с-массивами ,пробував на пітоні ...працює але криво

#15 Re: Програмування Arduino » Arduino vs LCD Trium Mars трабл » 2025-08-13 16:54:47

ch341a ще гірший , а можна на RP2040 Bridge зробити...щляхів уеб...сь  багато smile
зараз не можу зробити нормальний вивід тексту на Trium Mars та Siemens LPH9135 (графіку виводить чотко)

#16 Re: Програмування Arduino » Arduino vs LCD Trium Mars трабл » 2025-08-13 16:26:48

приїде модуль , напишу ...самому цікаво...диспів дох...а, оледи 1306 жаба дусить купляти

#17 Re: Програмування Arduino » Arduino vs LCD Trium Mars трабл » 2025-08-12 18:18:12

вибачте ...помилився...в залізі все гуд   ініціалізацію написав ,з шрифтами махаюсь

нарахунок тестів LCD , замовив FT232H High-Speed USB Multifunction Module - JTAG UART FIFO SPI I2C Interface.Буду на Phyton тестувати  ...так простіще буде...

#18 Програмування Arduino » Arduino vs LCD Trium Mars трабл » 2025-08-11 21:23:45

nickjust
відповідей: 42

Доброго вечора
підключив дисп SPI LCD TRIUM MARS (схема в аттаче)
до Ардуїно
SCK на D13
SDA на D11
RES на D9
DC На D10
VCC - 3.3 вольта
GND до GND

Резистивні поділювачи стоять
Пробував таке

Протокол PCD8544 та PCF8812

    lcd_send(0x40 | y, LCD_CMD);
    lcd_send(0x80 | x, LCD_CMD);

        (D/c=0) 27 (11011)

Не відображає ніц
Прошу допомоги


triumfix.jpg

#19 Re: Програмування Arduino » SPI TFT GMT130 v1.0 240x240 ST7789 трабл » 2025-08-08 08:30:59

2jokeer

Це я кому написав??
Резистивні поділювачи стоять - на Ардуїно 5в на диспе 3.14в


ДЯКУЮ jokeer
tft.init(240, 240, SPI_MODE3);
Допомогло!


Вшистко гра!
Треба читати /issues/

#20 Програмування Arduino » SPI TFT GMT130 v1.0 240x240 ST7789 трабл » 2025-08-07 22:32:50

nickjust
відповідей: 6

підключив дисп SPI TFT GMT130 v1.0 240x240 ST7789
до Ардуїно
SCK на D13
SDA на D11
RES на D9
DC На D10
BLK - 3.3 вольта
VCC - 3.3 вольта
GND до GND

Резистивні поділювачи стоять - на Ардуїно 5в на диспе 3.14в

#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <SPI.h>


#define TFT_CS   -1      // Chip Select не викор.
#define TFT_DC   10      // Data/Command → D10
#define TFT_RST  9       // Reset → D9


Adafruit_ST7789 tft(TFT_CS, TFT_DC, TFT_RST);

void setup() {

  tft.init(240, 240);
  tft.setRotation(1);
  tft.fillScreen(ST77XX_BLACK);
  tft.fillRect(0,   0,  80,  80,  ST77XX_RED);
  tft.fillRect(80,  0,  80,  80,  ST77XX_GREEN);
  tft.fillRect(160, 0,  80,  80,  ST77XX_BLUE);
  tft.fillRect(0,   80,  80,  80,  ST77XX_CYAN);
  tft.fillRect(80,  80,  80,  80,  ST77XX_MAGENTA);
  tft.fillRect(160, 80,  80,  80,  ST77XX_YELLOW);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(2);
  tft.setCursor(40, 180);
  tft.println("ST7789 WORKS! :)");
}

void loop() {
  // end
}

Компіляція -Завантаження (Arduino nano) - підсвітка ...і ніц на дисплеї немає
Adafruit-ST7735-Library-master і Adafruit_GFX_Library-1.11.11 стоять

Прошу допомоги

#21 Проекти » IR декодер на ATtiny85 додати Ком-порт » 2024-06-13 09:48:02

nickjust
відповідей: 0

Привіт всім.
Спаяв універсальний IR декодер на ATtiny85
Відкомпілював через Ардуїно, прошив за допомогою USBASP і спаяв на макетці
все працює, але мені потрібно щоб і в компорт виводило значення 4 байти, перших два це адреса, наступні 2 команда

типу
00BFA659
00BF1F45

Хто може виправити програму?
Схему без виведення на кому порт узяв тут Technoblogy - IR Remote Control
http://www.technoblogy.com/show?24A9


Домалював ком порт
https://dropmefiles.com.ua/ua/G6KCaS24W

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