Приветствую. На работе осцил.снял сигнал. На большом экране видно как повторяются “неправильные импульсы“: широкий импульс перед пропущенным, потом 58 импульсов пропущенный зуб, снова 58 импульсов и опять широкий импульс перед пропущенным. И дальше так по кругу. Широкий импульс появляется строго через раз. Не спонтанно , не хаотично. Если не получится устранить , то Бог с ним.
Какой именно код загружаешь? Выложи новым сообщением.
А я сейчас анализатором гляну у себя.
#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() {
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;
}
}
У меня с ним нет никаких проблем:
Сейчас попробую “проблемы” в основном цикле устроить и посмотреть.
Вот, устроил огромную задержку в теле цикла, проблем не вижу:
Код:
#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() {
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]);
}
for (uint32_t tt = 0; tt < 200000; tt++) {
asm("nop");
}
}
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;
}
}
Что-то тут “не то”. Да и как-то странно, что именно “через раз”. В коде нет ничего такого, что могло так действовать на выходные данные…
ЗЫ: Купи логический анализатор (типа такого), сильно помогает иногда…
Так и мелькает этот имульс - зараза)) .Да ну его. BOOM, сделаю на двух ардуинках. Ничего страшного.
Логический анализатор приобрету.
Эх, жаль… Загадка так и не будет раскрыта… (((
Еще раз спасибо за мастер класс
По сути все получилось.
Я вот думаю… @Diagnost , а как ты две ардуино то увяжешь?
есть еще такой скетчик, можно выбирать количество зубов, градусы впадин и выступов , количество пропущенных зубов, и частоту грубовато (через терминал). работает на прерываниях , поэтому луп не влияет на выдаваемый сигнал
const uint16_t rpm_D = 1000; // по дефолту 1000 об/мин
const uint16_t tooth_quantity = 60; // выбираем количество зубчиков датчика коленвала
const uint16_t tooth_size = 3; // выбираем длину зуба в градусах
const uint16_t hole_size = 3; // выбираем длину впадины в градусах
// зуб+впадина = 360/количество зубов (проверяем это) !!!
const uint16_t missed_teeth = 2; // выбираем количество пропущенных зубьев
const bool CKPbeginLogic = 0; // логика начала сигнала колена (0 или 1)
#define CKPpin PB0 // пин коленвала (8 пин ардуино) можно менять
void setup() {
Serial.begin(115200);
if ((tooth_size+hole_size)*tooth_quantity!=360) Serial.println("Неправильно выбрано количество и/или размер зубьев!!!");
Serial.print (rpm_D); Serial.println (" rpm");Serial.println();
DDRB|= _BV(CKPpin); // пин дпкв на выход
if (!CKPbeginLogic)PORTB |=_BV(CKPpin); // задаем начальный уровень сигнала дпкв
//ниже настраиваем аппаратный таймер ардуино
TCCR1A = 0;
TCCR1B = 8;
TCCR1B |= 1;
OCR1A = 2666666ul/rpm_D;
TIMSK1 |= (1<<OCIE1A);
}
void loop() // луп в формированиим сигнала дпкв не участвует, здесь только задаются обороты коленвала через терминал
{
if (Serial.available() )
{
byte inbyte = Serial.read();
if (inbyte >='1' && inbyte <='9') // в консоль вводим от 1 до 9, чтоб выбрать обороты(без символов конца строки)
{
uint32_t rpm = (inbyte-'0')*1000;
Serial.print (rpm); Serial.println (" rpm");
OCR1A = 2666666UL/rpm;
}
}
}
ISR (TIMER1_COMPA_vect)// обрабочик таймера, сюда заходит раз в градус поворота коленвала
{
static byte countT = 0; // счетчик градусов зуба/впадины
static byte counttooth = 1; // счетчик зубов
static bool tooth_or_hole = 1; // флаг зуб/впадина
countT++; // прибавляем счетчик градусов зуба/впадины
if ((tooth_or_hole && countT>=tooth_size) || (!tooth_or_hole && countT>=hole_size) ) // если по градусам достигли зуба или впадины
{
tooth_or_hole = !tooth_or_hole; // меняем состояние зуб/впадина
countT = 0; // сбрасываем счетчик градусов зуба/впадины
counttooth++; // увеличиваем номер текущего зуба
if (counttooth>(tooth_quantity*2)) counttooth =1; // сбрасываем увеличение номера зуба в случае достижения максимума
// ниже дергаем ногой (сигнал ДПКВ), если это не пропущенные зубья.
if (missed_teeth == 0 || (tooth_quantity*2 - counttooth) > (missed_teeth*2-1))PORTB ^= _BV(CKPpin);
}
}
на самом деле ваш скетч не совсем 60-2 в классическом понимании. в вашем скетче в сигнале пропущен один выступ и одна впадина.
то есть в месте синхронизации проходят подряд три выступа и три впадины. Для блоков 60-2 такой сигнал может не подойти.
хотя наверное в скетче так сделали, чтобы прямоугольный сигнал с ардуины подсунуть в ЭБУ с индуктивным дпкв, сигнал которого представляет синусоиду. и чтобы пропуск зубьев был похож, так сделали .
проблема есть на твоем скрине , у тебя на моменте где пропуск зуба , впадина длится дольше выступа и, заметь, это как раз через раз происходит.
в коде в массиве, где задается, зуб или впадина (нули и единицы), сделано 240 значений . Это видимо было сделано для полного цикла работы 4 тактного двс, где за два оборота коленвала весь цикл проходит. то есть имеем дпкв 60 импульсов, на каждом импульсе нужна впадина и выступ, то есть 120 значений , а так как оборота 2 за полный цикл, то поэтому массив имеет 240 значений .
но косяк в вашем скетче я нашел. Он возникает в конце массива, поэтому проблема возникает через раз (потому что один пропуск зубьев проходит в центре тела массива и тут косяк не влияет)
проблема тут . вместо
if (index++ >= wheel_len) {
index = 0;}
надо
index++;
if (index >= wheel_len) {index = 0;}
#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() {
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);
}
index++;
if (index >= wheel_len) {
index = 0;
}
}
Есть только одно “НО”…
У меня на логическом анализаторе проблема ТС не воспроизвелась, как бы я не старался (и осциллограмма соответствует первоначальной).
Дублирую скриншоты, если лень листать тему:
- Работа “в штатном режиме”:
- Устроил “проблемы” в основном цикле (
loop()):
Возможно потому, что я тестировал на малых (низких) частотах.
А в этом есть “здравое зерно”…
Сомневаюсь, что именно это вызывает проблему, так как это вызвало бы переключение выходов, а этого не происходит - просто удлиняется импульс (и полагаю, что это происходит у ТС на больших частотах).
Тем не менее, если у ТС есть желание проверить предположение - я только ЗА! Хочется ведь разобраться, а не “п#ськами мериться” )))
Только, наверное, более лаконичная такая запись будет:
#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() {
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;
}
}
Удлинение импульса это уже и есть проблема , ЭБУ это не понравится , и он будет срывать синхронизацию. Отключать форсунки , катушки и тд. Но и дополнительный всплеск перед пропуском зубьев , который у ТС возникает, 90 процентов по этой же причине происходит.
Кстати, а зачем таблица на 240 элементов, если вторые 120 элементов 1 в 1 совпадают с первыми 120ю? Думаю, можно вырезать половину совершенно спокойно.
там в изначальном скетче у ТС был еще один массив на датчик распредвала , а вот он уже должен быть 240 значений , поэтому и дпкв массив такой размер имеет. Так как ТС не нужен сигнал дпрв , у вы его убрали, то да, можно спокойно массив пополам порубить.
раз уж заговорили о лаконичности. видимо надо было твой вариант тогда доработать, так сказать работа над ошибками - сделать префиксную инкрементацию, а не постфиксную
if (++index>= wheel_len) {
index = 0;
}
и как бы проблема уходит. Но я всегда топлю за простую и понятную запись , чтобы потом осциллографы не расчехлять , этот выпендреж иногда ох как дорого выходит.
вот два кода , посмотрите в терминале какой результат - в твоем случае был выход за границы массива
byte index = 0 ;
void setup() {
Serial.begin (115200);
while (1)
{
if (index++>=240){Serial.print(index); break;}
}
}
void loop() {}
и
byte index = 0 ;
void setup() {
Serial.begin (115200);
while (1)
{
if (++index>=240){Serial.print(index); break;}
}
}
void loop() {}
а теперь увеличь в своем скетче с ошибкой массив до 241 значения (при этом размер массива в квадратных скобках пустым оставь), и последнее значение меняй 0 или 1 и увидишь , что в одном случае это удлинение импульса , а в другом - дополнительный неправильный импульс (в зависимости от того какой мусор был в памяти на этом месте) . в твоем слуае при замерах был вариант с удлинением импульса, а у ТС совпало так что дополнительный импульс был




