Форум программистов, компьютерный форум, киберфорум
Наши страницы
Arduino
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.85/47: Рейтинг темы: голосов - 47, средняя оценка - 4.85
amator1
0 / 0 / 0
Регистрация: 27.03.2017
Сообщений: 8
1

Arduino nano в качестве блока зажигания

27.03.2017, 15:49. Просмотров 8779. Ответов 18

Здравствуйте, уважаемые форумчане. Я впервые держу в руках ардуинку, представление о том что она умеет имею только самое начальное, но учитывая то, какой мк она несет на борту, сразу стало понятно что эта штуковина должна без проблем справиться с моей задачей (так как видел блоки зажигания на меге8, а тут у нас 328). В программировании я профан вообще (не более школьного курса по паскалю и немного vbasic) поэтому прошу пинать меня, но не сильно, и если кто-то поможет в реализации проекта, буду очень обязан вам.

Итак что нужно получить от ардуино:

Двигатель внутреннего сгорания имеет момент зажигания, для того чтоб топливо успевало вовремя сгорать и эффективно отдавать энергию, момент зажигания должен быть заблаговременным, для этого есть понятие Угол Опережения Зажигания (далее просто УОЗ), дело в том что для нормальной работы двигателя нужно чтобы этот УОЗ изменялся в зависимости от оборотов коленвала.

Устройство это должно работать по такому принципу:
на коленвале стоит металлическая пластина с вырезанными секторами 60 градусов и 120 градусов металла

0_5bd59_d887d1af_-1-L.jpg
При вращении коленвала с этой шторкой, металлический сектор шторки входит в датчик (например оптический) после этого ардуино должно начать считать время нахождения сектора в датчике до момента выхода сектора из датчика, и из полученных данных (время прохождения 120 градусов через датчик) посчитать обороты двигателя в данный момент.

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

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

Задача ардуино вклиниться между датчиком и коммутатором, чтоб управлять сигналом заряда и разряда катушки в зависимости от того какие обороты коленвала в данный момент (то есть динамически изменяющийся сигнал от датчика на коммутатор)

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

Добавлено через 7 минут
Еще добавлю что изначально у нас уже имеется определенный угол опережения зажигания (он заранее стоит максимальный для максимальных оборотов двигателя, и именно его далее надо убавлять ардуинкой если обороты ниже максимальных)
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.03.2017, 15:49
Ответы с готовыми решениями:

Arduino Nano+ Bluetooth HC-05
Здравствуйте. Есть aрдуино нано и блютуз hc 05. Мало знаю по электронике, но приходится работать ...

Тестировщик на Arduino Nano
Доброго времени, нужен элементарный скетч на тестировщик, однако по алгоритму и уточнить ряд...

Кардиодатчик + Arduino Nano
Проблема такая есть arduino nano и не то что бы кардиодатчик(его подобие своими руками) хочу...

Кодовый замок на Arduino nano
Видает ошибку при компиляции данного кода, уже всё что знал перепробовал ничего не получается, не...

Arduino nano v 3.0 и светодиодные ленты
Здравствуйте, у меня есть arduino nano и 4 свет. Аналоговые ргб ленты и включатель/выключатель. Мне...

18
ValeryS
Модератор
7960 / 5929 / 785
Регистрация: 14.02.2011
Сообщений: 20,405
Завершенные тесты: 1
27.03.2017, 20:53 2
amator1, картинки загружайте сюда
0
Сергей 190
334 / 323 / 67
Регистрация: 18.03.2015
Сообщений: 1,118
28.03.2017, 13:53 3
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//оптический датчик ня пятом аналоговом пине
int Spool_Output = 2; //Катушка на втором цифровом пине
unsigned long time; //Для определения времени оборота коленвала
int Status=0; //предыдущее положение шторки
int Porog = 500; //пороговое значение с оптического датчика подбирается экспериментально
int Pause; //время задержки выключения катушки в зависимости от оборота коленвала
 
void setup() {
  pinMode(Spool_Output, OUTPUT);
  time = micros();
}
 
void loop() {
  if (analogRead(A5) > Porog && Status == 1) { //шторка открыла датчик
    Status = 0; //датчик открыт
    time = micros() - time; // определяем время оборота коленвала
Pause = здесь хитрая формула подсчета; //чтоб этим не забивать "голову" экселя считаем время задержки
    delay(Pause);//если миллисекунд много используем delayMicroseconds()
    digitalWrite (Spool_Output, LOW);// вЫключаем катушку
  }
 
  if (analogRead(A5) < Porog && Status == 0) { //шторка перекрыла датчик
    Status = 1; //датчик перекрыт
    digitalWrite (Spool_Output, HIGH);// Включаем катушку
  }
}
1
amator1
0 / 0 / 0
Регистрация: 27.03.2017
Сообщений: 8
28.03.2017, 22:13  [ТС] 4
Спасибо Вам, что отозвались на мою просьбу! Сейчас читаю Ваш код, и понимаю как я сильно сглупил, в самом корне задачи... задержку выключения катушки задать нужно определенным углом, а не временем, что было с моей головой когда я это писал... В общем нужно задать массив данных (зависимость "данные обороты - на сколько градусов раньше подать искру" допустим таких пар будет 11 (по 500 оборотов)
0
28.03.2017, 22:13
Сергей 190
334 / 323 / 67
Регистрация: 18.03.2015
Сообщений: 1,118
29.03.2017, 11:48 5
Если работать в градусах, необходимо дополнительное оборудование, которое будет проворачивать трамблер. Зачем это? Можно же посчитать время задержки (опережения). Допустим, один оборот происходит за 360 миллисекунд. Что бы изменить угол на 10 градусов, необходимо подать искру на 10 миллисекунд позже. Можно и раньше, но может возникнуть ошибка при резком изменении оборотов. Величину ошибки сами считайте. Мне лень.
1
amator1
0 / 0 / 0
Регистрация: 27.03.2017
Сообщений: 8
29.03.2017, 22:11  [ТС] 6
хм, логично, Спасибо!
учитывая, что мотор двухтактный и весьма древний, там кратность измерений и подбора угла, вполне достаточно равной 500 оборотам в минуту (на меге 8 работало так и вполне не плохо пока я его не спалил случайно по своей глупости) и то шикарно по сравнению с фиксированным УОЗ

Тогда получается надо задать зависимость как я понимаю, мк считает количество миллисекунд, за которые через датчик проходит шторка (120град). Например при 1000 об/мин получается что шторка 120град проходит за 20мс,
Правильно ли я понимаю что нужно задавать условие в программу, что если шторка прошла через датчик за 20мс, то значит мы понимаем что это 1000 оборотов в минуту, значит нужно принять отставание в данном случае 4,528мс

и таких условий надо составить как минимум 11 (от 500 до 5500 оборотов)

Вроде рассчитал время необходимого отставания к данным оборотам
Обороты Отставание
500 10.652 мс
1000 4.528 мс
1500 2.516 мс
и так далее

Как задать ему эти условия?

Добавлено через 2 часа 17 минут
Если я Вас правильно понял, то программа должна выглядеть примерно вот так, только вписать еще 10 оставшихся условий IF?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//оптический датчик ня пятом аналоговом пине
int Spool_Output = 2; //Катушка на втором цифровом пине
unsigned long time; //Для определения времени оборота коленвала
int Status=0; //предыдущее положение шторки
int Porog = 500; //пороговое значение с оптического датчика подбирается экспериментально
int Pause; //время задержки выключения катушки в зависимости от оборота коленвала
 
void setup() {
  pinMode(Spool_Output, OUTPUT);
  time = micros();
}
 
void loop() {
  if (analogRead(A5) > Porog && Status == 1) { //шторка открыла датчик
    Status = 0; //датчик открыт
    time = micros() - time; // определяем время оборота коленвала
        if ( time >=0 && time <=40)
           { Pause = 10.615; //чтоб этим не забивать "голову" экселя считаем время задержки
             delay(Pause);//если миллисекунд много используем delayMicroseconds()
             digitalWrite (Spool_Output, LOW);// вЫключаем катушку
        }
  }
 
  if (analogRead(A5) < Porog && Status == 0) { //шторка перекрыла датчик
    Status = 1; //датчик перекрыт
    digitalWrite (Spool_Output, HIGH);// Включаем катушку
  }
}
Добавлено через 53 минуты
Как я понял, оператор time ведет отсчет в микросекундах, а переменная Pause в миллисекундах ?
0
Сергей 190
334 / 323 / 67
Регистрация: 18.03.2015
Сообщений: 1,118
30.03.2017, 11:08 7
Цитата Сообщение от amator1 Посмотреть сообщение
мк считает количество миллисекунд, за которые через датчик проходит шторка (120град)
У меня время считается за пол оборота (180град) от открытия до следующего открытия шторки. Поэтому 1000 об/мин будет 30 мс.
Цитата Сообщение от amator1 Посмотреть сообщение
Как я понял, оператор time ведет отсчет в микросекундах, а переменная Pause в миллисекундах ?
time = millis (); отсчет в миллисекундах
time = micros(); отсчет в микросекундах
delay(Pause); пауза в миллисекундах
delayMicroseconds(Pause); пауза в микросекундах

Строка Pause = 10.615; работать не будет. Переменная Pause целая, а не дробная. int Pause;
delay() и delayMicroseconds() с дробными числами (числа с плавающей запятой) не работают.
Т.е. вместо delay(10.615) используйте delayMicroseconds(10615)
Цитата Сообщение от amator1 Посмотреть сообщение
Обороты Отставание
500 10.652 мс
1000 4.528 мс
1500 2.516 мс
и так далее
Откуда эти данные – посчитали по формуле или взяли из таблицы? В программу лучше формулу вставить.
Скетч для таблицы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//оптический датчик ня пятом аналоговом пине
int Spool_Output = 2; //Катушка на втором цифровом пине
unsigned long time; //Для определения времени оборота коленвала
int Status = 0; //предыдущее положение шторки
int Porog = 500; //пороговое значение с оптического датчика подбирается экспериментально
int Pause; //время задержки выключения катушки в зависимости от оборота коленвала
 
void setup() {
  pinMode(Spool_Output, OUTPUT);
  time = millis();
}
 
void loop() {
  if (analogRead(A5) > Porog && Status == 1) { //шторка открыла датчик
    Status = 0; //датчик открыт
    time = millis() - time; // определяем время оборота коленвала
       if ( time > 40) Pause = 10615;
       if ( time > 24 && time <= 40) Pause = 4528;
       if ( time > 17 && time <= 24) Pause = 2516;
    delayMicroseconds(Pause);
    digitalWrite (Spool_Output, LOW);// вЫключаем катушку
  }
 
  if (analogRead(A5) < Porog && Status == 0) { //шторка перекрыла датчик
    Status = 1; //датчик перекрыт
    digitalWrite (Spool_Output, HIGH);// Включаем катушку
  }
}
1
amator1
0 / 0 / 0
Регистрация: 27.03.2017
Сообщений: 8
30.03.2017, 21:29  [ТС] 8
Цитата Сообщение от Сергей 190 Посмотреть сообщение
Откуда эти данные – посчитали по формуле или взяли из таблицы? В программу лучше формулу вставить.
Это я считал в экселе, данные могут быть изменены, но пока не будут первые тесты данные оставлю эти, формула там очень большая получилась и я честно говоря не совсем понимаю даже как её сюда писать, там таблица в экселе из горы колонок, где одна выходит из другой и так далее, думаю что ардуино хватит и готовых данных, и так как полученные рассчетные данные у меня выходят из нескольких вводных, мне самому при корректировке проще будет в экселе пересчет делать если это потребуется

Цитата Сообщение от Сергей 190 Посмотреть сообщение
Скетч для таблицы
Большое спасибо! А насчет millis и micros я понял после того как написал сюда мысль в программе все не целые миллисекунды переведены уже в микросекунды, но только я сделал кучу IF ELSE, разве можно вводить несколько подряд IF не внедряя ELSE ? если условие IF не выполняется?

Добавлено через 12 минут
И еще хотел спросить, не нужно ли делать какой-то сброс для счетчика time ? или он после выполнения условий и перехода в луп сам сбросится? (Имею ввиду не будет ли переполнения?)
0
Сергей 190
334 / 323 / 67
Регистрация: 18.03.2015
Сообщений: 1,118
31.03.2017, 08:33 9
Цитата Сообщение от amator1 Посмотреть сообщение
разве можно вводить несколько подряд IF не внедряя ELSE ?
Можно.
Цитата Сообщение от amator1 Посмотреть сообщение
если условие IF не выполняется?
Если не выполнится ни одно условие, переменная Pause не изменится.
Цитата Сообщение от amator1 Посмотреть сообщение
не будет ли переполнения?
millis() - Возвращает количество миллисекунд с момента начала выполнения текущей программы на плате Arduino. Это количество сбрасывается на ноль, в следствие переполнения значения, приблизительно через 50 дней.
1
amator1
0 / 0 / 0
Регистрация: 27.03.2017
Сообщений: 8
01.04.2017, 17:08  [ТС] 10
Цитата Сообщение от Сергей 190 Посмотреть сообщение
millis() - Возвращает количество миллисекунд с момента начала выполнения текущей программы на плате Arduino. Это количество сбрасывается на ноль, в следствие переполнения значения, приблизительно через 50 дней.
То есть счетчик не сбрасывается даже при выключении устройства? Или 50 суток это запас, на протяжении которого можно работать программе до повтора в loop ?
0
Сергей 190
334 / 323 / 67
Регистрация: 18.03.2015
Сообщений: 1,118
02.04.2017, 09:38 11
50 суток с момента подачи питания.
Переменная time (строка 16) примет отрицательное значение, не выполнится ни одно условие (строки 17, 18, 19), переменная Pause не изменится. В следующие пол оборота коленвала все продолжится как обычно.
1
amator1
0 / 0 / 0
Регистрация: 27.03.2017
Сообщений: 8
03.04.2017, 15:38  [ТС] 12
Спасибо, теперь прояснилось, но тут в другом теперь вопрос, с повышением оборотов, время прохождения одного оборота например на 5000 и на 5500 отличается лишь микросекундами, то есть значение time нужно брать в micros, но насколько мне известно он обнуляется через 70 минут, то есть получится так что двигатель после 70 минут начнет работать с вероятными перебоями (если обнуление произойдет в момент подсчета оборота) или я снова не прав?
0
Сергей 190
334 / 323 / 67
Регистрация: 18.03.2015
Сообщений: 1,118
06.04.2017, 10:35 13
Цитата Сообщение от amator1 Посмотреть сообщение
если обнуление произойдет в момент...
Обнуление в любом случае произойдет.
Цитата Сообщение от amator1 Посмотреть сообщение
после 70 минут начнет работать с вероятными перебоями
Может произойти ошибка только на один такт. Следующие такты опять будут отрабатываться как обычно.
0
amator1
0 / 0 / 0
Регистрация: 27.03.2017
Сообщений: 8
26.05.2017, 20:14  [ТС] 14
Доброго времени суток, прошу прощения что не заходил. Был в отъезде. В общем вернувшись домой, как раз пришла плата и компоненты к ней. Проверяю программу, не работает, пробовал уже переназначить вход с датчика на цифровой пин вместо аналогового (чтоб минимизировать наводки) но ничего не помогает, сплошные прострелы зажигания, мотоцикл заводится с трудом, и стреляет в глушители. Лопатил форумы, но ничего толкового так и не нашел...
Я решил для отладки прокинуть вместо выхода на катушку, пьезоизлучатель, чтоб имитировать искру и должен сказать что этот процесс очень не стабильно выдает импульсы. Три дня копаюсь в коде и в других кодах что делают люди для авто, но так и не придумал ничего...
0
Сергей 190
334 / 323 / 67
Регистрация: 18.03.2015
Сообщений: 1,118
28.05.2017, 10:59 15
Цитата Сообщение от amator1 Посмотреть сообщение
стреляет в глушители
Ардуиновский код «задерживает» зажигание. Необходимо механически выставить завышенное опережение.
Цитата Сообщение от amator1 Посмотреть сообщение
процесс очень не стабильно выдает импульсы
Для начала необходимо подобрать пороговое значение с оптического датчика. int Porog = 500;

Напишите следующий код.
C++
1
2
3
4
5
6
7
8
void setup() {
  Serial.begin(9600);
}
 
void loop() {
  Serial.println(analogRead(A5));
  delay(300);
}
Подключите оптический датчик, запустите монитор порта, вращайте шторку вручную (открывайте/закрывайте оптопару).
Смотрите значения при открытой и закрытой шторке. Чем больше разница, тем лучше.
Если разница значений слишком маленькая, сложно будет найти середину. Мудрите с оптопарой.

Найдите среднее значение для переменной Porog. Поставьте в код полученное значение.

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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int Porog = ???; //пороговое значение с оптического датчика подбирается экспериментально
int Status = 0; // положение шторки
 
void setup() {
  Serial.begin(9600);
}
 
void loop() {
  if (analogRead(A5) > Porog) Status = 0;
  else Status = 1;
  Serial. println (Status);
  delay(300);
}
Какое получилось значение переменной Porog и какое значение переменной Status при открытой (закрытой) шторке?

Если Вы используете цифровой пин, воля Ваша. Главное, что бы переменная Status стабильно изменялась при открывании и закрывании шторки.
Цитата Сообщение от amator1 Посмотреть сообщение
прокинуть вместо выхода на катушку, пьезоизлучатель
Это как? Фотку покажите.

И еще:
Мой код не совсем правильно отрабатывал угол замкнутого состояния контактов (УЗСК).
У меня получилось, что УЗСК 120 градусов. Я не знаю, сколько он должен быть для двухтактных двигателей. Думаю в пределах 50 – 60 градусов. Для жигулевского двигателя 55 градусов.
Для этого необходимо знать, какое значение переменной Status при открытой (закрытой) шторке?
Т.е. «в какую сторону» работает оптопара.
0
PortAID
0 / 0 / 0
Регистрация: 28.11.2017
Сообщений: 1
28.11.2017, 15:47 16
Хочу присоединится к теме.
а почему не сделать отдельное отверстие и дополнительный датчик холла в качестве (только датчика тахометра)
?

p/s. нужен знающий человек который за денежку поможет сделать зажигание на базе АРдуин
0
Avazart
Эксперт С++
7999 / 5818 / 575
Регистрация: 10.12.2010
Сообщений: 26,830
Записей в блоге: 19
28.11.2017, 16:00 17
Цитата Сообщение от PortAID Посмотреть сообщение
p/s. нужен знающий человек который за денежку поможет сделать зажигание на базе АРдуин
Если за деньги то вам сюда http://www.cyberforum.ru/freelance/
0
fffaaa
0 / 0 / 0
Регистрация: 03.01.2019
Сообщений: 1
03.01.2019, 18:00 18
amator1, так что по итогу? получилось?
0
wasiliysoft
0 / 0 / 0
Регистрация: 05.11.2018
Сообщений: 2
15.02.2019, 09:32 19
Тоже интересно, планирую сделать на оптопаре для Юпитера 5, если все таки возьмусь то отпишу о результате
0
15.02.2019, 09:32
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.02.2019, 09:32

Arduino nano и дальномер HC-SR04
Добрый день. Я новичек в Ардуино. Приобрел дальномер HC-SR04, написал простенький скетч для него,...

Компьютер не видит Arduino Nano V3
Здравствуйте! ОС win7, только купить нану, подключил к компу и пишет что нету драйвера, установил...

Гирлянда на ws2811 и arduino nano
Всем привет. Имею диоды на контроллере ws2811 в количестве 50 шт Arduino nano Все собрано и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.