Эмуляция сигнала ДПКВ 60-2

А ну-ка вот этот еще код опробуй (попробуем всё-таки в одну ардуину “уложиться” :smiley: ) :

#include <TM1637.h>
// Определяем пины для подключения дисплея TM1637
#define CLK         8
#define DIO         9

#define wheel_len   240
#define pt_pin      A0
#define out1_pin    2
#define out2_pin    3
#define timeout     500

uint32_t tick_delay, FREQ = 5500;        //rpm
uint32_t pt, mill;
volatile uint8_t index = 0;

// Создаем объект дисплея TM1637
TM1637 tm1637(CLK, DIO);

const char Table1[wheel_len] = {
  0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
  0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
  0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
};

void setup() {
  
  cli(); // Запрещаем прерывания

  DDRD |= (1 << PD2);
  DDRD |= (1 << PD3);

  PORTD &= ~(1 << PD2);
  PORTD &= ~(1 << PD3);

  // Настройка режима CTC Timer1
  TCCR1A &= ~((1 << WGM10) | (1 << WGM11));
  TCCR1B &= ~((1 << WGM13));
  TCCR1B |= (1 << WGM12);

  // Настройка предделителя на 8 Timer1
  TCCR1B |= (1 << CS11);
  TCCR1B &= ~((1 << CS12) | (1 << CS10));

  // Разрешаем прерывание по совпадению с OCR1A
  TIMSK1 |= (1 << OCIE1A);

  pt = analogRead(pt_pin);

  FREQ = map(pt, 0, 1024, 300, 5500);

  // Устанавливаем значение для сравнения
  tick_delay = ((120000000UL / FREQ) / wheel_len) * 2;
  OCR1A = tick_delay;

  // Глобально разрешаем прерывания
  sei();
}



void loop() {

  if (millis() - mill > timeout) {

    mill = millis();
    pt = analogRead(pt_pin);

    FREQ = map(pt, 0, 1024, 300, 5500);

    tick_delay = ((120000000UL / FREQ) / wheel_len) * 2;
    OCR1A = tick_delay;

    // Разбиваем на отдельные цифры
    int8_t digits[] = {0, 0, 0, 0};
    digits[0] = FREQ / 1000;        // тысячи (десятки км/ч)
    digits[1] = (FREQ / 100) % 10;  // сотни (единицы км/ч)
    digits[2] = (FREQ / 10) % 10;   // десятки (десятые км/ч)
    digits[3] = FREQ % 10;          // единицы (сотые км/ч)

    // Отображаем скорость на дисплее
    tm1637.point(false);
    tm1637.display(0, digits[0]);
    tm1637.point(false);
    tm1637.display(1, digits[1]);
    tm1637.point(false);  // Включаем точку для разделения целой и дробной части
    tm1637.display(2, digits[2]);
    tm1637.point(false);
    tm1637.display(3, digits[3]);
  }
}

ISR(TIMER1_COMPA_vect) {

  if (Table1[index] == 0) {
    PORTD &= ~(1 << PD2);
    PORTD |= (1 << PD3);
  } else {
    PORTD |= (1 << PD2);
    PORTD &= ~(1 << PD3);
  }

  if (index++ >= wheel_len) {
    index = 0;
  }
}

Должен работать “как слива в ж…” (ну ты понял).
Генерацию я у себя проверил - идет. ТМ1637 у меня нет.
Но, конечно же, нужно с оборудованием проверить.
Работает по другому принципу - на прерывании Timer1 (16 бит). А значит генерации импульсов ничто из главного цикла (loop()) помешать не может )))

Мои данные компиляции (у меня Arduino Nano v2 на Atmega168):

Скетч использует 2450 байт (17%) памяти устройства. Всего доступно 14336 байт.
Глобальные переменные используют 370 байт (36%) динамической памяти, оставляя 654 байт для локальных переменных. Максимум: 1024 байт.