А у меня другой вопрос возник - в таблице после последнего элемента стоит запятая. Так же не делают… Ардуино ИДЕ «проглатывает»?))
с этим не подскажу, но думаю, если после запятой ничего нет, то она не влияет
Провёл эксперимент у себя.
Сразу скажу: Частота максимальная от ТС - 5500. Проблема ТС не воспроизвелась никак.
Однако!
Есть интересные результаты. И совсем не там, где говорил ТС.
В общем при первоначальном коде увеличивается время первого «длинного» LOW на время того самого «лишнего» импульса (в цифрах: при импульсах порядка 90..91 мкс между 58 импульсами, длинные порядка 270 мкс, а самый длинный - 360 мкс. Длительность определяется по разному немного, потому что дешёвый анализатор). То есть ты был прав. Полагаю, последний код от меня (или тебя) будет вполне работоспособным. Жалко, что ТС нашёл решение для себя и больше не вернётся на форум… ((
Не совсем понимаю почему, видимо следующий элемент в памяти был равен нулю.
а ты пробовал и с "0” и с “1” ? в последней ячейке массива 241 байт (начиная с нуля 240й получается ) . У меня ситуация меняется - либо длинный импульс , либо дополнительный импульс
Я не пробовал, но оно и логично…
тогда странна эта фраза, получается проблема воспроизвелась. и как раз там , где и у ТС.
вот с единицей в памяти в ячейке после массива
а вот с нулем
там же еще два пина 2й и 3й на выход в противофазе работают, если относительно земли мерить, ситуация на этих двух пинах зеркально будет отличаться
Приветствую. В одну ардуино запишу рабочий скетч с поста №16 ( с регулировкой оборотов потенциометром, но без тм 1637), а во вторую скетч с поста №77 ( уже с тм1637). Один потенциометр будет подключен одновременно к двум ардуинкам(вывод А0). Одна генерирует нормальные импульсы, а вторая отображает обороты.
Видимо, у меня такого не воспроизводилось - потому что не было еденицы в памяти мк (далее по массиву).
эмм , а мы тут зря работу над ошибками делали ?
Это вообще «не сильно похоже» будет.
Попробуй лучше скетч из #116
Не «пыли», его же не было и он отвечал на мой вопрос.
Сейчас “неправильных” импульсов нет)
BOOM, MaksVVу вас тут мозговой шторм. Читал ваши посты) Завтра проверю на работе.
Ничего «такого», всего лишь обсуждение.
Не забудь написать результат…
ТС, если еще теперь будут проблемы , с искрообразованием или форсунками, то причина может быть еще, про которую я говорил в # 111
ниже иллюстрация по этому поводу (постарался в масштабе одно под другим расположить , чтобы временная шкала совпадала)
У него работало с изначальной таблицей. Но если с другими блоками пробовать - проблема решается правкой самой таблицы. Кстати, я за таблицу именно (а не вычисление). Это и быстрее и исключает ошибки вычислений (которые бывают иногда).
таблицей, да, удобнее. и можно любую комбинацию задавать формулы шкива
а для удобства можно и вообще так (самому может пригодится, буду искать по этой теме )
#include <TM1637.h>
// Определяем пины для подключения дисплея TM1637
#define CLK 8
#define DIO 9
#define wheel_len 120 // количество зубов сигнала дпкв *2 (потому что зубы+впадины)
#define pt_pin A0
#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] = {
// зуб 1 2 3 4 5 6 7 8 9 10 11 12
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
// зуб 13 14 15 16 17 18 19 20 21 22 23 24
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
// зуб 25 26 27 28 29 30 31 32 33 34 35 36
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
// зуб 37 38 39 40 41 42 43 44 45 46 47 48
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
// зуб 49 50 51 52 53 54 55 56 57 58 59 60
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 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;
}
}
но скетч все равно не универсальный , так как нужно по идее еще и задавать время зуба и время впадины. на многих машинах они не равны и сильно отличаются . Например форд транзит 2012г+
добавил выбор размера по градусам поворота кв зуба и впадины
#define wheel_len 60 // количество зубов сигнала дпкв
#define tooth_len 1 // количество градусов поворота кв зуба
#define hole_len 5 // количество градусов поворота кв впадины
// зуб+впадина = 360/количество зубов (проверяем это) !!! иначе скетч не скомпилируется
#if ((tooth_len+hole_len) != 360/wheel_len)
#error "Ошибка! неправильно задано количество зубов и/или размер зуба и впадины"
#endif
#define pt_pin A0
#define timeout 500
uint32_t RPM = 1000; //rpm
uint32_t pt, mill;
volatile uint8_t index = 0;
// ниже составляем таблицу зубов и впадин как хотим , делаем пропущенные зубья и/или впадины где надо.
const bool Table_CKP[] = {
// зуб 1 2 3 4 5 6 7 8 9 10 11 12
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
// зуб 13 14 15 16 17 18 19 20 21 22 23 24
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
// зуб 25 26 27 28 29 30 31 32 33 34 35 36
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
// зуб 37 38 39 40 41 42 43 44 45 46 47 48
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
// зуб 49 50 51 52 53 54 55 56 57 58 59 60
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0
};
// Check the size here:
static_assert(sizeof(Table_CKP) == wheel_len*2, "Ошибка! неправильно задано количество ячеек зубов и впадин в массиве (таблице)");
void setup() {
DDRD |= (1 << PD2);
DDRD |= (1 << PD3);
PORTD &= ~(1 << PD2);
PORTD &= ~(1 << PD3);
//ниже настраиваем аппаратный таймер ардуино
TCCR1A = 0;
TCCR1B = 8;
TCCR1B |= 1;
OCR1A = 2666666ul/RPM;
TIMSK1 |= (1<<OCIE1A);
// pt = analogRead(pt_pin);
// RPM = map(pt, 0, 1024, 300, 5500);
// Глобально разрешаем прерывания
sei();
}
void loop() {
if (millis() - mill > timeout)
{
mill = millis();
// pt = analogRead(pt_pin);
// RPM = map(pt, 0, 1024, 300, 5500);
OCR1A = 2666666ul/RPM;
}
}
ISR(TIMER1_COMPA_vect) { //сюда заходит раз в 1 градус поворота кв
static bool tooth = 1;
if (Table_CKP[index] == 0) {
PORTD &= ~(1 << PD2);
PORTD |= (1 << PD3);
} else {
PORTD |= (1 << PD2);
PORTD &= ~(1 << PD3);
}
static byte index_gradus = 0 ;
if (++index_gradus >= ((tooth==1) ? tooth_len : hole_len))
{
tooth=!tooth;
index_gradus = 0 ;
if (++index >= wheel_len*2) {index = 0;}
}
}
Вот ТС интригу повесил ))



