Требуется помощь в написании кода

Думаю что вынужден буду отказаться от столь щедрого предложения.

Код не намного сложнее чем мигания светодиодами, не считаю что он стоит этих денег.
Полистаю талмуды и справлюсь сам.

Указатель давления топлива в рампе смог сделать, а с этим справлюсь подавно.

Хотел сэкономить немного времени, но слишком уж оно накладно получается.
Но в любом случае спасибо за предложение.

Вот когда буду исправлять код электронной гитары для токарного станка, там можно будет поговорить о суммах и побольше, это будет целесообразно.

Самое правильное решение. Думаю, через год-два осилишь, если не будешь леницца.

5 лайков

а вы это… как ? тему в теме ищу исполнителя сами создали ?)) или изверги перекинули в этот раздел ?

компилияция кода вовсе минуты идет, но это же не значит что за минуту оплату надо получать… вникнуть в проблему, составить ТЗ стоит в десятки раз больше, это маловероятно что кому то интересно, и обычно покупают готовое, или платят по 100к+ …

так что это не аргументы, ваших аргументов с трудом на 100к оплаты пока что хватает…

вот вам код согласно ТЗ, и успехов!))))

// Определение пинов для индикации передач
#define GEAR_1_PIN 2
#define GEAR_2_PIN 3
#define GEAR_3_PIN 4
#define GEAR_4_PIN 5
// Передаточные числа
const float K = 2.57142857;    // Передаточное число коленвала к первичному
const float K1 = 3.17;         // 1 передача
const float K2 = 1.81;         // 2 передача
const float K3 = 1.26;         // 3 передача
const float K4 = 1.1;          // 4 передача
// Допустимая погрешность (так как значения могут немного отличаться)
const float TOLERANCE = 0.1;
// Переменные для хранения оборотов
volatile unsigned long rpm1 = 0;  // Обороты двигателя
volatile unsigned long rpm2 = 0;  // Обороты вторичного вала
// Переменные для измерения времени
unsigned long lastTime1 = 0;
unsigned long lastTime2 = 0;
// Для подсчета импульсов
volatile unsigned int pulseCount1 = 0;
volatile unsigned int pulseCount2 = 0;

void setup() {
// Настройка пинов как выходов
pinMode(GEAR_1_PIN, OUTPUT);
pinMode(GEAR_2_PIN, OUTPUT);
pinMode(GEAR_3_PIN, OUTPUT);
pinMode(GEAR_4_PIN, OUTPUT);
// Изначально все пины в LOW
digitalWrite(GEAR_1_PIN, LOW);
digitalWrite(GEAR_2_PIN, LOW);
digitalWrite(GEAR_3_PIN, LOW);
digitalWrite(GEAR_4_PIN, LOW);
// Настройка прерываний для датчиков (замените на реальные пины)
// attachInterrupt(digitalPinToInterrupt(2), countPulse1, RISING);  // Датчик RPM1
// attachInterrupt(digitalPinToInterrupt(3), countPulse2, RISING);  // Датчик RPM2
Serial.begin(9600);  // Для отладки
}
void loop() {
// Обновляем значения RPM каждые 500ms
static unsigned long lastUpdate = 0;
if (millis() - lastUpdate >= 500) {
lastUpdate = millis();
// Рассчитываем RPM (зависит от количества импульсов на оборот вашего датчика)
// Обычно 1-2 импульса на оборот для индуктивных датчиков
rpm1 = calculateRPM(pulseCount1, 500);  // 500ms период измерения
rpm2 = calculateRPM(pulseCount2, 500);
pulseCount1 = 0;
pulseCount2 = 0;
// Определяем текущую передачу
determineGear(); 
// Для отладки (можно удалить)
Serial.print("RPM1: "); Serial.print(rpm1); 
Serial.print(" RPM2: "); Serial.print(rpm2); 
Serial.print(" Ratio: ");
if (rpm2 > 0) { Serial.println((float)rpm1 / K / rpm2);
} else { Serial.println("N/A"); }
}
}

// Функция для расчета RPM
unsigned long calculateRPM(unsigned int pulses, unsigned long periodMs) {
if (pulses == 0) return 0;
// Предполагаем 1 импульс на оборот (измените если у вашего датчика другое значение)
return (pulses * 60000UL) / (periodMs * 1);
} // Функция определения передачи
void determineGear() {
// Проверяем, что оба датчика показывают ненулевые значения
if (rpm1 == 0 || rpm2 == 0) { allGearsOff(); return; } // Двигатель не работает или стоит на нейтрали
// Рассчитываем текущее передаточное отношение
float currentRatio = (float)rpm1 / K / rpm2; 
// Проверяем каждую передачу с учетом допустимой погрешности
if (abs(currentRatio - K1) <= TOLERANCE) { setGear(1); } 
else if (abs(currentRatio - K2) <= TOLERANCE) { setGear(2); }
else if (abs(currentRatio - K3) <= TOLERANCE) { setGear(3); }
else if (abs(currentRatio - K4) <= TOLERANCE) { setGear(4);
} else { allGearsOff(); }// Неизвестное передаточное отношение (нейтраль или между передачами)
}

// Установка конкретной передачи
void setGear(int gear) {
allGearsOff(); switch(gear) {
case 1: digitalWrite(GEAR_1_PIN, HIGH); break;
case 2: digitalWrite(GEAR_2_PIN, HIGH); break;
case 3: digitalWrite(GEAR_3_PIN, HIGH); break;
case 4: digitalWrite(GEAR_4_PIN, HIGH); break; }
} // Выключение всех индикаторов передач
void allGearsOff() {
digitalWrite(GEAR_1_PIN, LOW); digitalWrite(GEAR_2_PIN, LOW);
digitalWrite(GEAR_3_PIN, LOW); digitalWrite(GEAR_4_PIN, LOW);
} // Обработчики прерываний для подсчета импульсов
void countPulse1() { pulseCount1++; }
void countPulse2() { pulseCount2++; }

бабос может и не такое, и его крохи не интересуют! я лучше после ремонта буду собирать автоматическую чесалку пятки! а не понятно что…

следующий код будет после оплаты первого в виде 5к, и так до бесконечности))) ну или пока что не будет подробного ТЗ…

2 лайка

Непонятно, зачем нужна эта индикация на 4-х скоростях. Только запутаться можно. Немного поездить, и сам будешь знать, какая скорость включена. По характеру езды понятно.(ИМХО)
Хотя на современных не ездил, только на советских.

1 лайк

А для чего?
Сигнал то будет линейный.
Если условия совпадают, то получается High, с помощью реле делаем из 5 вольт 12 и отправляем в панель на соответствующий контакт, как с физического датчика, а та в свою очередь включает нужный символ, который запрограммирован в нейна этом контакте.
Всё ведь просто.

Димыч, здесь не больше чем вопрос эстетики.
Панель симпатичная, информативная и хочется чтобы на ней работало все, а не висела эта ошибка.
С остальными указателями проблем не возникло.

Да, Вы совершенно правы :neutral_face:

Не то напровление. Надо к педали цеплять датчик( например через тросик концевики) по срабатыванию одного передача -1, другого +1, по датчику нетралки збрасывать ошибки(обнулять)
Через обороты это бесполезная светомузыка. Подезжая к перекрестку выжмиш сцеплеие- у двигателя ±холостые, у колеса стремиться к нулю и заработает герлянда передач, но в кпп то что было и останиться. А для того что-бы дальше ехать первую обычным способом искать глядя на бесполезную герлянду. И так всегда на выжетом сцеплении, проскочил ту что хотел или нет? - жми до первой и считай с начала.
При движении какая передача и так понятно, а если нет то куда в низ или в верх подсознательно нажмёш.

Ну ты просто капитан очевидность.
А не хватает мозга на то что если данная функция имеет на табло, то приятней когда она функционирует, а не просто висит бесполезным сектором?
Думаю что у тебя получится реализовать идею с гирляндами в педале, как сделаешь - похвались.
Что за детский сад?
Людей с мозгами здесь оказывается не так уж и много, остальные только говна на вентилятор накидывают. Это вы таким образом на себя внимание хотите обратить? Напрасно. Есть другие, более удачные и перспективные способы это сделать.

Уж кто бы говорил…
Заварил кашу, тебе идей накидали и даже код - а сам слился на каких-то пяти тысячах.

1 лайк

Думаю что у тебя получится реализовать идею с гирляндами в педале, как сделаешь - похвались.
Она реализованна в педали тормаза. там один концевик, по этому же принцыпу два не сложно сделать. Третий уже есть на нетраль.

const int ledPins[] = {2, 3, 4, 5, 6}; // Пины для 5 диодов
const int buttonNextPin = 7;           // Пин для кнопки "Следующий"
const int buttonPrevPin = 8;           // Пин для кнопки "Предыдущий"
const int buttonSetPin = 9;            // Пин для кнопки "Установить"

// Переменные для управления состоянием
int currentLed = 0;  // Индекс текущего активного диода (начинаем с первого)

// Для хранения состояния кнопок
bool lastButtonNextState = LOW;
bool lastButtonPrevState = LOW;
bool lastButtonSetState = LOW;

void setup() {
  // Инициализация пинов
  for (int i = 0; i < 5; i++) {
    pinMode(ledPins[i], OUTPUT);  // Устанавливаем пины для диодов как выходы
  }

  pinMode(buttonNextPin, INPUT_PULLUP);  // Кнопка "Следующий" с подтягивающим резистором
  pinMode(buttonPrevPin, INPUT_PULLUP);  // Кнопка "Предыдущий" с подтягивающим резистором
  pinMode(buttonSetPin, INPUT_PULLUP);   // Кнопка "Установить" с подтягивающим резистором

  // Изначально выключаем все диоды
  for (int i = 0; i < 5; i++) {
    digitalWrite(ledPins[i], LOW);
  }
  digitalWrite(ledPins[currentLed], HIGH);  // Включаем первый диод
}

void loop() {
  // Чтение состояния кнопок
  bool buttonNextState = digitalRead(buttonNextPin);
  bool buttonPrevState = digitalRead(buttonPrevPin);
  bool buttonSetState = digitalRead(buttonSetPin);

  // Кнопка "Следующий" (переключаем на следующий диод)
  if (buttonNextState == LOW && lastButtonNextState == HIGH) {
    // Если кнопка была нажата и текущий диод не 5-й, переходим к следующему
    if (currentLed < 4) {  // Диод 5 игнорирует кнопку "Следующий"
      digitalWrite(ledPins[currentLed], LOW);  // Выключаем текущий диод
      currentLed = (currentLed + 1) % 5;      // Переходим к следующему диоду
      digitalWrite(ledPins[currentLed], HIGH); // Включаем следующий диод
      delay(200);  // Задержка для предотвращения дребезга кнопки
    }
  }

  // Кнопка "Предыдущий" (переключаем на предыдущий диод)
  if (buttonPrevState == LOW && lastButtonPrevState == HIGH) {
    // Если кнопка была нажата и текущий диод не 1-й, переходим к предыдущему
    if (currentLed > 0) {  // Диод 1 игнорирует кнопку "Предыдущий"
      digitalWrite(ledPins[currentLed], LOW);  // Выключаем текущий диод
      currentLed = (currentLed + 4) % 5;      // Переходим к предыдущему диоду
      digitalWrite(ledPins[currentLed], HIGH); // Включаем предыдущий диод
      delay(200);  // Задержка для предотвращения дребезга кнопки
    }
  }

  // Кнопка "Установить" (зажигаем диод 2)
  if (buttonSetState == LOW && lastButtonSetState == HIGH) {
    // Если кнопка была нажата, зажигаем диод под номером 2
    digitalWrite(ledPins[currentLed], LOW);  // Выключаем текущий диод
    currentLed = 1;  // Устанавливаем диод 2 (индекс 1)
    digitalWrite(ledPins[currentLed], HIGH); // Включаем диод 2
    delay(200);  // Задержка для предотвращения дребезга кнопки
  }

  // Обновляем состояние кнопок
  lastButtonNextState = buttonNextState;
  lastButtonPrevState = buttonPrevState;
  lastButtonSetState = buttonSetState;
}

ДипСик спалился :)))))

ну чо, код почти рабочий… правда при старте будет глючить.

Это просто пример gpt. При старте на нетралке всё сразу выстовиться, на первой тоже 1горит, а с другой в любом случае через 0 надо пройти. Если чо-то в процесе собьёться то при проходе через нетраль исправиться. В любом случае очень редко этот “показометр” будет погоду показывать в отличии от идеи с оборотами, там когда щелкаеш педалью- сцепление выжето и не какого передаточного числа нет, истину покажет только в движении после полного отпускания сцепления и до того как опять выжмеш. Смотреть на мигалку когда ловиш передачу весело будет.

Для ГПТ вполне неплохо, как стартовый вариант пойдет.

Поясните про интерфейс панели - номер показываемой передачи выбирается одним пином или надо управлять каждым сегментом семисегментного индикатора, как обычно?

Управление сегментами происходит непосредственно в панели приборов, а на неё 6 сигнальный проводов под +12 в

Что в понели не знаю.

Это с каких пор датчики холла у нас редкость?

Так это ты не у меня спрашивай. Это не мои слова. Как по мне так этого говна валом разных.

Не всё так просто.

  1. Звезда медленно вращаеться, надо большие промежутки времени не милисы а минутосы. Иначе будет >5 но <6 импульсов с такой точностью и разницей между передаточными числами 0,16 гдето между 1и4 передачей. Можно увеличить число импульсов на оборот ×20–×30, но наврятли поможет и сможет.
  2. Обороты не постоянные с разгоном и замедлением что тоже даст погрешность больше разницы передаточных чисел.