При определенных оборотах включить реле

Barabakan
Offline
Зарегистрирован: 10.08.2014

Всем привет.

Я пока новичок.

Суть задания такова.

Имеется: Arduino Nano, Реле с развязкой.

Имеется карбюраторный ДВС. Надо при оборотах более 2700 об/мин включить соленоид фазовращателя на впускном распредвале (замкнуть реле по сути). Соответственно при менее 2700 выключить.

Сигнал буду брать с коммутатора зажигания (импульсы +12В).

Двигатель четырехтактный четырехцилиндровый. То есть 2 искры за оборот, то есть при более чем 90 имп/с надо замкнуть реле. При менее разомкнуть.

Копался в нескольких темах на форуме, в частности:

http://arduino.ru/forum/programmirovanie/pomogite-vyschitat-oboroty

http://arduino.ru/forum/programmirovanie/podschet-oborotov

http://arduino.ru/forum/ishchu-ispolnitelya/napisanie-sketcha-dlya-uprav...

 

Все вроде понятно, но мне нужна максимальное быстродейтвие, без всяких задержек (а там в скетчах народ их использует активно).

Может кто посоветует как поступить правильно?

Спасибо.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

надо использовать прерывания. датчик к ардуине надеюсь подключите

1/90об=11,1мс

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

должно получится что то вроде этого


volatile unsigned long time = 0;        
#define Rele 5

void Start(){
  if(millis()-time <= 11) digitalWrite(Rele, 1);
  else digitalWrite(Rele, 0);
  time=millis();
}

  
void setup(){
  attachInterrupt(0, Start, RISING);     //Прерывание по нарастающему фронту на D2
  pinMode(Rele, OUTPUT);
}

void loop(){
  
}

хотя я бы заменил digitalWrite на более быстрое прямое управление портом

Barabakan
Offline
Зарегистрирован: 10.08.2014

Спасибо. Завтра проверю на генераторе частоты и отпишусь что и как.

Leshiy
Offline
Зарегистрирован: 19.07.2014

А не ли смысла ввести гистерезис на отключение?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

имеет. но я просто подал идею как делать и набросал код

Barabakan
Offline
Зарегистрирован: 10.08.2014

Я не знаток в данном программировании, но вы уверены, что код верный? Реакции ноль на программу.

Почему кусок loop пустой?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а в loop что делать если все делается в прерывании

а вы точно все правильно подключили?

если да просто увеличьте время между тиками с 11 до 100 например и проверьте

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
volatile unsigned int NclkTCNT1 = 0;
volatile byte RPM500 = 0;
#define RelayPin 7
boolean Relay [] PROGMEM =
{
  1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ,
  1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 ,
  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
  0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
  0
};
//==============================================================================================================================
void setup( )
{
// Timer/Counter_1
  DDRB = DDRB | B00000000;
  PORTB = PORTB | B00000001;
  TIMSK1 = ( 1 << ICIE1 ) | ( 0 << OCIE1B ) | ( 0 << OCIE1A ) | ( 0 << TOIE1 );
  TCCR1A = ( 0 << COM1A1 ) | ( 0 << COM1A0 ) | ( 0 << COM1B1 ) | ( 0 << COM1B0 ) | ( 0 << WGM11 ) | ( 0 << WGM10 );
  TCCR1B = ( 0 << ICNC1 ) | ( 1 << ICES1 ) | ( 0 << WGM13 ) | ( 0 << WGM12 ) | ( 0 << CS12 ) | ( 1 << CS11 ) | ( 1 << CS10 );
//  TCCR1C = ( 0 << FOC1A ) | ( 0 << FOC1B );
//  TCNT1
//  OCR1A , OCR1B
//  ICR1
//  TIFR1 = ( 5=ICF1 ) , ( 2=OCF1B ) , ( 1=OCF1A ) , ( 1=TOV1 );
  TCNT1  = 0;
  
}
//==============================================================================================================================
ISR( TIMER1_CAPT_vect )
{
  TCNT1 = 0;
  NclkTCNT1 = ICR1 + 34;
  RPM500 = NclkTCNT1 / 500;
  digitalWrite( RelayPin , Relay [ RPM500 ] );
}
//==============================================================================================================================
void loop( )
{

}
//==============================================================================================================================

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

только таблицу надо переделать ( с двухтактной таблицы просто так 0/1 расставил )

датчик искрообразования на датчике Холла ? и какие максимальные обороты движка ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

вообще таблицу надо убрать.... оборот - 11111 mkS, счётчик за это время насчитает 2778 тиков по 4 mkS

volatile unsigned int NclkTCNT1 = 0;
// датчик Холла - пин 8
// реле - пин 7
//==============================================================================================================================
void setup( )
{
  DDRB = DDRB | B00000000;  // pinMode( 8 , INPUT );
  PORTB = PORTB | B00000001;  // digitalWrite( RelayPin , LOW );
  TIMSK1 = ( 1 << ICIE1 ) | ( 0 << OCIE1B ) | ( 0 << OCIE1A ) | ( 0 << TOIE1 );
  TCCR1A = ( 0 << COM1A1 ) | ( 0 << COM1A0 ) | ( 0 << COM1B1 ) | ( 0 << COM1B0 ) | ( 0 << WGM11 ) | ( 0 << WGM10 );
  TCCR1B = ( 0 << ICNC1 ) | ( 1 << ICES1 ) | ( 0 << WGM13 ) | ( 0 << WGM12 ) | ( 0 << CS12 ) | ( 1 << CS11 ) | ( 1 << CS10 );
  TCNT1  = 0;
  DDRD = DDRD | B10000000;  // pinMode( 7 , OUTPUT );
  PORTD = PORTD | B00000000;  // digitalWrite( 7 , LOW );
}
//==============================================================================================================================
ISR( TIMER1_CAPT_vect )
{
  TCNT1 = 0;
  NclkTCNT1 = ICR1 + 34;
  if ( NclkTCNT1 < 2778 )   // RPM > 2700
    {
      PORTD = PORTD | B10000000;
    }
  if ( NclkTCNT1 > 2830 )   // RPM < 2650
    {
      PORTD = PORTD | B00000000;
    }
}
//==============================================================================================================================
void loop( )
{

}
//==============================================================================================================================

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
volatile unsigned int NclkTCNT1 = 0;
// датчик Холла - пин 8
// реле - пин 7
//==============================================================================================================================
void setup( )
{
  DDRB != ( 1 << 0 );  // pinMode( 8 , INPUT );
  PORTD != ( 1 << 0 );  // digitalWrite( 8 , HIGH );
  TIMSK1 = ( 1 << ICIE1 ) | ( 0 << OCIE1B ) | ( 0 << OCIE1A ) | ( 0 << TOIE1 );
  TCCR1A = ( 0 << COM1A1 ) | ( 0 << COM1A0 ) | ( 0 << COM1B1 ) | ( 0 << COM1B0 ) | ( 0 << WGM11 ) | ( 0 << WGM10 );
  TCCR1B = ( 0 << ICNC1 ) | ( 1 << ICES1 ) | ( 0 << WGM13 ) | ( 0 << WGM12 ) | ( 0 << CS12 ) | ( 1 << CS11 ) | ( 1 << CS10 );
  TCNT1  = 0;
  DDRD != ( 1 << 7 );  // pinMode( 7 , OUTPUT );
  PORTD &= ~( 1 << 7 );  // digitalWrite( 7 , LOW );
}
//==============================================================================================================================
ISR( TIMER1_CAPT_vect )
{
  TCNT1 = 0;
  NclkTCNT1 = ICR1 + 34;
  if ( NclkTCNT1 < 2778 )   // RPM > 2700
    {
      PORTD != ( 1 << 7 );
    }
  if ( NclkTCNT1 > 2830 )   // RPM < 2650
    {
      PORTD &= ~( 1 << 7 );
    }
}
//==============================================================================================================================
void loop( )
{

}
//==============================================================================================================================

 

Barabakan
Offline
Зарегистрирован: 10.08.2014

jeka_tm пишет:

а в loop что делать если все делается в прерывании

а вы точно все правильно подключили?

если да просто увеличьте время между тиками с 11 до 100 например и проверьте

Все нормально, только на частоте 82-97 Гц реле постоянно щелкает.

Barabakan
Offline
Зарегистрирован: 10.08.2014
volatile unsigned long time = 0;        
#define Rele 13
void Start(){
  if(millis()-time <= 10) digitalWrite(Rele, 1);
  if(millis()-time >= 13) digitalWrite(Rele, 0);
  time=millis();
}
void setup(){
  attachInterrupt(0, Start, RISING);
  pinMode(Rele, OUTPUT);
}
void loop(){
  }

Вот так работает прекрасно.

Barabakan
Offline
Зарегистрирован: 10.08.2014

SU-27-16 пишет:

только таблицу надо переделать ( с двухтактной таблицы просто так 0/1 расставил )

датчик искрообразования на датчике Холла ? и какие максимальные обороты движка ?

Сигнал беру с выхода коммутатора, что идет на катушку зажигания.

Максимальные обороты около 8000 об/мин.

Выше написал - все работает отлично, всем спасибо.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Barabakan пишет:

SU-27-16 пишет:

только таблицу надо переделать ( с двухтактной таблицы просто так 0/1 расставил )

датчик искрообразования на датчике Холла ? и какие максимальные обороты движка ?

Сигнал беру с выхода коммутатора, что идет на катушку зажигания.

опасно... в этой точке может быть до 400 V в амплитуде... не лучше ли брать сигнал со входа коммутатора ?

Valentinych
Offline
Зарегистрирован: 13.08.2014

Обязательно на входе Ардуины предусмотреть простенький RC-фильтр, и (крайне важно!) 5-вольтовый стабилитрончик, дабы отсекать ВЧ взбрыки, которых в моторном отсеке живет не мало.

При съеме сигнала с выхода коммутатора лучше предусмотреть "гальваноразвязку" - просто намотать на провод, идущий от коммутатора к бобине несколько витков изолированного провода, например МГТФ 0,15-0,25 (сечение). Число витков подобрать по гарантированному срабатыванию системы с учетом фильтра и стабилитрона на входе, а потом закрепить термоусадкой.  Но сигнал с датчика Холла все таки кошернее.

Ардуину связать с массой автомобиля проводом к точке подключения массы акку. Питание - через стабилизатор 7809 (или аналогичный) , с двумя кондеями на выходе - электролит 47-100 мкф 16 вольт и параллельно керамику 0,1 мкф. Если все-таки будут лупить помехи по цепи питания (что вполне вероятно), последовательно в цепь питания, идущую непосредственно на Ардуину (поближе к ней), воткнуть любой дросселек на феррите, и после него поставить еще одну керамику на 0,1 мкф.  Разумеется, Ардуина на борту дожна быть в металлическом корпусе. Метода многократно проверена на спортивных моторах. Просто, не дорого, надежно, и ремонтабельно.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Но сигнал с датчика Холла все таки кошернее.

.....однако тоже через оптопару - приведение импульсов 12..15 V к 5 V....  всё что выше 5 V на пине - когда-нить убъёт пин ардуины :(

Valentinych
Offline
Зарегистрирован: 13.08.2014

Не обязательно через оптопару (но не повредит) - достаточно описанной постом выше цепи из RC и стабилитрона.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

рад что работает как надо

тут СУ27 предлагал код голый на си не тестировали?

ragraff
Offline
Зарегистрирован: 17.02.2017

Привет Ребята! Мне тоже нужно такое устройство!

скиньте пожалуйста схему и прошивку. благодарю!

vvadim
Offline
Зарегистрирован: 23.05.2012

ragraff пишет:

Привет Ребята! Мне тоже нужно такое устройство!

скиньте пожалуйста схему и прошивку. благодарю!

вы не обратили внимания что теме уже третий год)))

ragraff
Offline
Зарегистрирован: 17.02.2017

Обратил))...Но необходимость появилась сейчас!. может кто помочь?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Так "помочь" или "скинуть схему и прошивку"?

ragraff
Offline
Зарегистрирован: 17.02.2017

Привет! И то и другое и третье)), готов заплатить за оказанную помощь!

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Тогда в раздел "Ищу исполнителя".

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ragraff пишет:
Привет! И то и другое и третье)), готов заплатить за оказанную помощь!

а вы тоже маховик перетачивали на холостые в райне 2500? ЭПХХ меняете?

прошивка - пост 13

volatile unsigned long time = 0;        
#define Rele 13
void Start(){
  if(millis()-time <= 10) digitalWrite(Rele, 1);
  if(millis()-time >= 13) digitalWrite(Rele, 0);
  time=millis();
}
void setup(){
  attachInterrupt(0, Start, RISING); //Прерывание по нарастающему фронту на D2
  pinMode(Rele, OUTPUT);
}
void loop(){
  }

Вход - //Прерывание по нарастающему фронту на D2
 

ragraff
Offline
Зарегистрирован: 17.02.2017

Огромное спасибо! А что такое d2? Может схемку черканете. Мне не для авто. Хочу на фрезерный станочек поставить.

ragraff
Offline
Зарегистрирован: 17.02.2017

В качестве базовой платы брать arduino nano 3.0?

ragraff
Offline
Зарегистрирован: 17.02.2017

На вход D2 подаем импульсный сигнал? Я правильно понял?

ragraff
Offline
Зарегистрирован: 17.02.2017

прием...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

это пин на котором фиксируется нарастающий фронт

смотрим распиновку - да nano v3