Следующая стадия энкодер!
Попробуй еще вот этот код. Если я правильно библиотеку на ТМ нашел, то этот код при FREQ меньше 1000 будет показывать ’ 900’ вместо ‘0900’ как у тебя первоначально сделано.
#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 1000
uint32_t tick_delay, mill;
uint32_t FREQ = 900; //rpm
uint16_t pt;
uint8_t digits[] = {0, 0, 0, 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,
};
// Функция "печати" FREQ на TM1637...
void print_freq(void) {
tm1637.point(false);
(digits[0] = (FREQ / 1000)) ? tm1637.display(0, digits[0]) : tm1637.display(0, 0x7F); // тысячи (десятки км/ч)
digits[1] = (FREQ / 100) % 10; // сотни (единицы км/ч)
tm1637.point(false);
tm1637.display(1, digits[1]);
digits[2] = (FREQ / 10) % 10; // десятки (десятые км/ч)
tm1637.point(false); // Включаем точку для разделения целой и дробной части
tm1637.display(2, digits[2]);
digits[3] = FREQ % 10; // единицы (сотые км/ч)
tm1637.point(false);
tm1637.display(3, digits[3]);
}
void setup() {
pinMode(out1_pin, OUTPUT);
pinMode(out2_pin, OUTPUT);
// Инициализируем дисплей
tm1637.init();
tm1637.set(6); // Устанавливаем яркость дисплея (0-7)
pt = analogRead(pt_pin);
FREQ = map(pt, 0, 1024, 300, 5500);
tick_delay = ((120000000UL / FREQ) / wheel_len);
print_freq();
mill = millis();
}
void loop() {
for (uint8_t i = 0; i < wheel_len; i++) {
digitalWrite(out1_pin, Table1[i]);
digitalWrite(out2_pin, !Table1[i]);
delayMicroseconds(tick_delay);
}
if (millis() - mill > timeout) {
mill = millis();
pt = analogRead(pt_pin);
FREQ = map(pt, 0, 1024, 300, 5500);
tick_delay = ((120000000UL / FREQ) / wheel_len);
// Отображаем скорость на дисплее
print_freq();
}
}
Спать уже хочу, но вроде бы ошибок быть не должно (но это не точно
)
Автомобильные блоки не запускаются. Не могут “ переварить “ этот сигнал с ардуино. В осциллограмме переодически проскакивает больше двух пропущенных зубов. BOOM, в любом случае для меня это прорыв) Задействую две ардуинки. Одна с сигналом дпкв с поста №16, а другая с тм1637 будет отображать обороты. Еще раз спасибо. Тему можно закрывать.
А ну-ка вот этот еще код опробуй (попробуем всё-таки в одну ардуину “уложиться”
) :
#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 байт.
Он же с фильтрацией нуля в первом знакоместе TM1637 (работает ли - не знаю, от тебя ответа не было):
#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)) ? tm1637.display(0, digits[0]) : tm1637.display(0, 0x7F); // тысячи (десятки км/ч)
digits[1] = (FREQ / 100) % 10; // сотни (единицы км/ч)
digits[2] = (FREQ / 10) % 10; // десятки (десятые км/ч)
digits[3] = FREQ % 10; // единицы (сотые км/ч)
// Отображаем скорость на дисплее
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. Завтра проверю на блоках.
Второй при меньше 1000 в первом знакоместе что отображает?
Осциллограф не подключал. А индикатор так же показывает от 300 до 5500 об.
Так же?
По идеи первый должен показывать ‘0300’, а второй ‘ 300’ (то есть вообще ничего на первом знакоместе не зажигать)…
сейчас еще раз посмотрю.
Ааааа, я кое-что забыл. Сейчас исправлю.
Исправил #45, попробуй его сейчас.
Ноль пропал)![]()
Отлично. Тогда завтра жду информацию по совместимости с оборудованием ))
Хотел спросить. Немного не по теме. Ардуино нано не прошиваются у меня их 5-ть и не один не хочет. Скачал новую программу, установил драйвера под CH341. Пробовал и через OldBootloader. Не прошиваются и все.
Смотри маркировку CH340, если затёрта - это китайская подделка на китайский CH340 ![]()
Купи программатор USBasp и прошивай им (через разъём ISP).
Написано CH340G.
Лучше отдельную тему создать по этим ардуино. Чтобы эту «не засирать»…)
Пятница, и надеюсь на обратную связь. В унынии пить пиво или с радости напицца )))