Генератор сигнала Коленвала и распредвала

MaksVV
Offline
Зарегистрирован: 06.08.2015

Мой друг попросил меня сделать преобразователь сигнала коленчатого вала. Т.к. ему поменяли двигатель на не родной. А чтобы панель приборов показывала обороты нужно подать сигнал от старого двигателя. (Сигнал по CAN Шине в панель идет, поэтому пришлось оставить старый ЭБУ для этого)

Ардуина будет от нового двигателя получить сигнал просто тахосигнала определённой частоты.

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

Возможно ли такое сделать на ардуине. Вот требуемые сигналы:

Скетч я конечно сделал, но это конечно говновод ещё тот. Работает, но в зависимости от разных оборотов нижний сигнал смещается, особенно после 5000 об/мин. 

Подскажите такое возможно на ардуино? если да, готов заплатить за реализацию. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

вот мой мега скетч ) там каждый элемент сигнала на отдельном таймере на millis. 

#define CMP 4
#define ckp 2
volatile unsigned int int_tic=0; 
volatile unsigned long tic; 
float k=0.4;
 unsigned long prevMillisfrec = 0;


long mnog;
int RPM = 8000;
int val;
int K =100; 
unsigned long Time23, timer23 = 0;
bool timerenabled23 = 0;
#define TIMEREXPIRED23 (Time23-timer23)>12*mnog

unsigned long Time156, timer156 = 0;
bool timerenabled156 = 0;
#define TIMEREXPIRED156 (Time156-timer156)>157*mnog

unsigned long Time40_1, timer40_1 = 0;
bool timerenabled40_1 = 0;
#define TIMEREXPIRED40_1 (Time40_1-timer40_1)>29*mnog

unsigned long Time40_2, timer40_2 = 0;
bool timerenabled40_2 = 0;
#define TIMEREXPIRED40_2 (Time40_2-timer40_2)>29*mnog

unsigned long Time40_3, timer40_3 = 0;
bool timerenabled40_3 = 0;
#define TIMEREXPIRED40_3 (Time40_3-timer40_3)>29*mnog

unsigned long Time40_4, timer40_4 = 0;
bool timerenabled40_4 = 0;
#define TIMEREXPIRED40_4 (Time40_4-timer40_4)>29*mnog

unsigned long Time210_1, timer210_1 = 0;
bool timerenabled210_1 = 0;
#define TIMEREXPIRED210_1 (Time210_1-timer210_1)>196*mnog

unsigned long Time210_2, timer210_2 = 0;
bool timerenabled210_2 = 0;
#define TIMEREXPIRED210_2 (Time210_2-timer210_2)>196*mnog

unsigned long Time210_3, timer210_3 = 0;
bool timerenabled210_3 = 0;
#define TIMEREXPIRED210_3 (Time210_3-timer210_3)>196*mnog

unsigned long Time36, timer36 = 0;
bool timerenabled36 = 0;
#define TIMEREXPIRED36 (Time36-timer36)> 27*mnog


////////CKP
unsigned long ckpTime1, ckptimer1 = 0;
bool ckptimerenabled1 = 0;
#define ckpTIMEREXPIRED1 (ckpTime1-ckptimer1)>5*mnog   *k    // 1

unsigned long ckpTime2, ckptimer2 = 0;
bool ckptimerenabled2 = 0;
#define ckpTIMEREXPIRED2 (ckpTime2-ckptimer2)>20*mnog    *k  //25

unsigned long ckpTime3, ckptimer3 = 0;
bool ckptimerenabled3 = 0;
#define ckpTIMEREXPIRED3 (ckpTime3-ckptimer3)>5*mnog       *k//2

unsigned long ckpTime4, ckptimer4 = 0;
bool ckptimerenabled4 = 0;
#define ckpTIMEREXPIRED4 (ckpTime4-ckptimer4)>32*mnog     *k//65

unsigned long ckpTime5, ckptimer5 = 0;
bool ckptimerenabled5 = 0;
#define ckpTIMEREXPIRED5 (ckpTime5-ckptimer5)>6*mnog   *k  //3

unsigned long ckpTime6, ckptimer6 = 0;
bool ckptimerenabled6 = 0;
#define ckpTIMEREXPIRED6 (ckpTime6-ckptimer6)>32*mnog    *k//102

unsigned long ckpTime7, ckptimer7 = 0;
bool ckptimerenabled7 = 0;
#define ckpTIMEREXPIRED7 (ckpTime7-ckptimer7)>6*mnog     *k//4

unsigned long ckpTime8, ckptimer8 = 0;
bool ckptimerenabled8 = 0;
#define ckpTIMEREXPIRED8 (ckpTime8-ckptimer8)>32*mnog    *k//139

unsigned long ckpTime9, ckptimer9 = 0;
bool ckptimerenabled9 = 0;
#define ckpTIMEREXPIRED9 (ckpTime9-ckptimer9)>6*mnog    *k//5

unsigned long ckpTime10, ckptimer10 = 0;
bool ckptimerenabled10 = 0;
#define ckpTIMEREXPIRED10 (ckpTime10-ckptimer10)> 32*mnog*k//173

unsigned long ckpTime11, ckptimer11 = 0;
bool ckptimerenabled11 = 0;
#define ckpTIMEREXPIRED11 (ckpTime11-ckptimer11)>5*mnog*k//6

unsigned long ckpTime12, ckptimer12 = 0;
bool ckptimerenabled12 = 0;
#define ckpTIMEREXPIRED12 (ckpTime12-ckptimer12)>32*mnog*k//210

unsigned long ckpTime13, ckptimer13 = 0;
bool ckptimerenabled13 = 0;
#define ckpTIMEREXPIRED13 (ckpTime13-ckptimer13)> 5*mnog*k//7

unsigned long ckpTime14, ckptimer14 = 0;
bool ckptimerenabled14 = 0;
#define ckpTIMEREXPIRED14 (ckpTime14-ckptimer14)>32*mnog*k//247

unsigned long ckpTime15, ckptimer15 = 0;
bool ckptimerenabled15 = 0;
#define ckpTIMEREXPIRED15 (ckpTime15-ckptimer15)>6*mnog*k//8

unsigned long ckpTime16, ckptimer16 = 0;
bool ckptimerenabled16 = 0;
#define ckpTIMEREXPIRED16 (ckpTime16-ckptimer16)>32*mnog*k//284

unsigned long ckpTime17, ckptimer17 = 0;
bool ckptimerenabled17 = 0;
#define ckpTIMEREXPIRED17 (ckpTime17-ckptimer17)>6*mnog*k//9

unsigned long ckpTime18, ckptimer18 = 0;
bool ckptimerenabled18 = 0;
#define ckpTIMEREXPIRED18 (ckpTime18-ckptimer18)>32*mnog*k//321

unsigned long ckpTime19, ckptimer19 = 0;
bool ckptimerenabled19 = 0;
#define ckpTIMEREXPIRED19 (ckpTime19-ckptimer19)>6*mnog*k//10

unsigned long ckpTime20, ckptimer20 = 0;
bool ckptimerenabled20 = 0;
#define ckpTIMEREXPIRED20 (ckpTime20-ckptimer20)>32*mnog*k//358

unsigned long ckpTime21, ckptimer21 = 0;
bool ckptimerenabled21 = 0;
#define ckpTIMEREXPIRED21 (ckpTime21-ckptimer21)>5*mnog*k//11

unsigned long ckpTime22, ckptimer22 = 0;
bool ckptimerenabled22 = 0;
#define ckpTIMEREXPIRED22 (ckpTime22-ckptimer22)>32*mnog*k//395

unsigned long ckpTime23, ckptimer23 = 0;
bool ckptimerenabled23 = 0;
#define ckpTIMEREXPIRED23 (ckpTime23-ckptimer23)> 5*mnog*k//12

unsigned long ckpTime24, ckptimer24 = 0;
bool ckptimerenabled24 = 0;
#define ckpTIMEREXPIRED24 (ckpTime24-ckptimer24)>32*mnog*k//432

unsigned long ckpTime25, ckptimer25 = 0;
bool ckptimerenabled25 = 0;
#define ckpTIMEREXPIRED25 (ckpTime25-ckptimer25)>5*mnog*k//13

unsigned long ckpTime26, ckptimer26 = 0;
bool ckptimerenabled26 = 0;
#define ckpTIMEREXPIRED26 (ckpTime26-ckptimer26)> 7*mnog*k//

unsigned long ckpTime27, ckptimer27 = 0;
bool ckptimerenabled27 = 0;
#define ckpTIMEREXPIRED27 (ckpTime27-ckptimer27)> 5*mnog*k//14

unsigned long ckpTime28, ckptimer28 = 0;
bool ckptimerenabled28 = 0;
#define ckpTIMEREXPIRED28 (ckpTime28-ckptimer28)> 20*mnog*k//482

unsigned long ckpTime29, ckptimer29 = 0;
bool ckptimerenabled29 = 0;
#define ckpTIMEREXPIRED29 (ckpTime29-ckptimer29)> 5*mnog*k//15



unsigned long ckpTime30, ckptimer30 = 0;
bool ckptimerenabled30 = 0;
#define ckpTIMEREXPIRED30 (ckpTime30-ckptimer30)> 32*mnog*k

unsigned long ckpTime31, ckptimer31 = 0;
bool ckptimerenabled31 = 0;
#define ckpTIMEREXPIRED31 (ckpTime31-ckptimer31)> 6*mnog*k//16
unsigned long ckpTime32, ckptimer32 = 0;
bool ckptimerenabled32 = 0;
#define ckpTIMEREXPIRED32 (ckpTime32-ckptimer32)> 32*mnog*k
unsigned long ckpTime33, ckptimer33 = 0;
bool ckptimerenabled33 = 0;
#define ckpTIMEREXPIRED33 (ckpTime33-ckptimer33)> 6*mnog*k//17

unsigned long ckpTime34, ckptimer34 = 0;
bool ckptimerenabled34 = 0;
#define ckpTIMEREXPIRED34 (ckpTime34-ckptimer34)> 32*mnog*k

unsigned long ckpTime35, ckptimer35 = 0;
bool ckptimerenabled35 = 0;
#define ckpTIMEREXPIRED35 (ckpTime35-ckptimer35)> 6*mnog*k//18

unsigned long ckpTime36, ckptimer36 = 0;
bool ckptimerenabled36 = 0;
#define ckpTIMEREXPIRED36 (ckpTime36-ckptimer36)> 32*mnog*k

unsigned long ckpTime37, ckptimer37 = 0;
bool ckptimerenabled37 = 0;
#define ckpTIMEREXPIRED37 (ckpTime37-ckptimer37)> 5*mnog*k//19

unsigned long ckpTime38, ckptimer38 = 0;
bool ckptimerenabled38 = 0;
#define ckpTIMEREXPIRED38 (ckpTime38-ckptimer38)> 32*mnog*k

unsigned long ckpTime39, ckptimer39 = 0;
bool ckptimerenabled39 = 0;
#define ckpTIMEREXPIRED39 (ckpTime39-ckptimer39)> 5*mnog*k//20

unsigned long ckpTime40, ckptimer40 = 0;
bool ckptimerenabled40 = 0;
#define ckpTIMEREXPIRED40 (ckpTime40-ckptimer40)> 32*mnog*k

unsigned long ckpTime41, ckptimer41 = 0;
bool ckptimerenabled41 = 0;
#define ckpTIMEREXPIRED41 (ckpTime41-ckptimer41)> 6*mnog*k//21

unsigned long ckpTime42, ckptimer42 = 0;
bool ckptimerenabled42 = 0;
#define ckpTIMEREXPIRED42 (ckpTime42-ckptimer42)> 32*mnog*k

unsigned long ckpTime43, ckptimer43 = 0;
bool ckptimerenabled43 = 0;
#define ckpTIMEREXPIRED43 (ckpTime43-ckptimer43)> 6*mnog*k//22

unsigned long ckpTime44, ckptimer44 = 0;
bool ckptimerenabled44 = 0;
#define ckpTIMEREXPIRED44 (ckpTime44-ckptimer44)> 32*mnog*k

unsigned long ckpTime45, ckptimer45 = 0;
bool ckptimerenabled45 = 0;
#define ckpTIMEREXPIRED45 (ckpTime45-ckptimer45)> 6*mnog*k//23

unsigned long ckpTime46, ckptimer46 = 0;
bool ckptimerenabled46 = 0;
#define ckpTIMEREXPIRED46 (ckpTime46-ckptimer46)> 32*mnog*k

unsigned long ckpTime47, ckptimer47 = 0;
bool ckptimerenabled47 = 0;
#define ckpTIMEREXPIRED47 (ckpTime47-ckptimer47)> 5*mnog*k//24

unsigned long ckpTime48, ckptimer48 = 0;
bool ckptimerenabled48 = 0;
#define ckpTIMEREXPIRED48 (ckpTime48-ckptimer48)> 32*mnog*k

unsigned long ckpTime49, ckptimer49 = 0;
bool ckptimerenabled49 = 0;
#define ckpTIMEREXPIRED49 (ckpTime49-ckptimer49)> 5*mnog*k//25

unsigned long ckpTime50, ckptimer50 = 0;
bool ckptimerenabled50 = 0;
#define ckpTIMEREXPIRED50 (ckpTime50-ckptimer50)> 32*mnog*k

unsigned long ckpTime51, ckptimer51 = 0;
bool ckptimerenabled51 = 0;
#define ckpTIMEREXPIRED51 (ckpTime51-ckptimer51)> 5*mnog*k
unsigned long ckpTime52, ckptimer52 = 0;
bool ckptimerenabled52 = 0;
#define ckpTIMEREXPIRED52 (ckpTime50-ckptimer50)> 7*mnog  *k//900




bool t1=0;
bool t1end = 0;
bool t2=0;
bool t2end = 0;
bool t3=0;
bool t3end = 0;
bool t4=0;
bool t4end = 0;
bool t5=0;
bool t5end = 0;
bool t6=0;
bool t6end = 0;
bool t7=0;
bool t7end = 0;
bool t8=0;
bool t8end = 0;
bool t9=0;
bool t9end = 0;
bool t10=0;
bool t10end = 0;



bool tt1=0;
bool tt1end = 0;
bool tt2=0;
bool tt2end = 0;
bool tt3=0;
bool tt3end = 0;
bool tt4=0;
bool tt4end = 0;
bool tt5=0;
bool tt5end = 0;
bool tt6=0;
bool tt6end = 0;
bool tt7=0;
bool tt7end = 0;
bool tt8=0;
bool tt8end = 0;
bool tt9=0;
bool tt9end = 0;
bool tt10=0;
bool tt10end = 0;
bool tt11=0;
bool tt11end = 0;
bool tt12=0;
bool tt12end = 0;
bool tt13=0;
bool tt13end = 0;
bool tt14=0;
bool tt14end = 0;
bool tt15=0;
bool tt15end = 0;
bool tt16=0;
bool tt16end = 0;
bool tt17=0;
bool tt17end = 0;
bool tt18=0;
bool tt18end = 0;
bool tt19=0;
bool tt19end = 0;
bool tt20=0;
bool tt20end = 0;
bool tt21=0;
bool tt21end = 0;
bool tt22=0;
bool tt22end = 0;
bool tt23=0;
bool tt23end = 0;
bool tt24=0;
bool tt24end = 0;
bool tt25=0;
bool tt25end = 0;
bool tt26=0;
bool tt26end = 0;
bool tt27=0;
bool tt27end = 0;
bool tt28=0;
bool tt28end = 0;
bool tt29=0;
bool tt29end = 0;
bool tt30=0;
bool tt30end = 0;
bool tt31=0;
bool tt31end = 0;
bool tt32=0;
bool tt32end = 0;
bool tt33=0;
bool tt33end = 0;
bool tt34=0;
bool tt34end = 0;
bool tt35=0;
bool tt35end = 0;
bool tt36=0;
bool tt36end = 0;
bool tt37=0;
bool tt37end = 0;
bool tt38=0;
bool tt38end = 0;
bool tt39=0;
bool tt39end = 0;
bool tt40=0;
bool tt40end = 0;
bool tt41=0;
bool tt41end = 0;
bool tt42=0;
bool tt42end = 0;
bool tt43=0;
bool tt43end = 0;
bool tt44=0;
bool tt44end = 0;
bool tt45=0;
bool tt45end = 0;
bool tt46=0;
bool tt46end = 0;
bool tt47=0;
bool tt47end = 0;
bool tt48=0;
bool tt48end = 0;
bool tt49=0;
bool tt49end = 0;
bool tt50=0;
bool tt50end = 0;
bool tt51=0;
bool tt51end = 0;
bool tt52=0;
bool tt52end = 0;

#include <class_BUTTON.h>
unsigned long previousMillis = 0;
BUTTON button (10);
void setup() {
TCCR1A=0; TIMSK1 = 1<<TOIE1; //прерывание по переполнению


pinMode (CMP, OUTPUT);
digitalWrite (CMP,1);

pinMode (ckp, OUTPUT);
pinMode (10, OUTPUT);
digitalWrite (10,1);
digitalWrite (ckp,1);
Serial.begin (9600);
}

ISR (TIMER1_OVF_vect){ int_tic++; }

void loop() {
  button.read();
if (button.click_down){k=k+0.01;}
  
 // unsigned long currentMillis = millis();

 // if(currentMillis - previousMillis > 1000){  Serial.println (K);
 //       previousMillis = currentMillis;}  
 // val = RPM;
 // val = map(val, 200, 1440, 105, 103);
 // K = val;
pinMode (5,INPUT); // вход сигнала T1 (only для atmega328)
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1


unsigned long curMillisfrec = millis();
if(curMillisfrec - prevMillisfrec > 1000){  TCCR1B=0;
tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
int_tic=0; TCNT1 = 0; 

Serial.print ("Frec  "); Serial.print (tic); Serial.print ("  RPM   ");Serial.print (RPM);
Serial.print ("  k= ");Serial.println (k);
prevMillisfrec = curMillisfrec;}  
  RPM = tic*120;
  mnog=120000L/RPM;
  
  ckpTime1 = micros();
  ckpTime2 = micros();
  ckpTime3 = micros();
  ckpTime4 = micros();
  ckpTime5 = micros();
  ckpTime6 = micros();
  ckpTime7 = micros();
  ckpTime8 = micros();
  ckpTime9 = micros();
  ckpTime10 = micros();
  ckpTime11 = micros();
  ckpTime12 = micros();
  ckpTime13 = micros();
  ckpTime14 = micros();
  ckpTime15 = micros();
  ckpTime16 = micros();
  ckpTime17 = micros();
  ckpTime18 = micros();
  ckpTime19 = micros();
  ckpTime20 = micros();
  ckpTime21 = micros();
  ckpTime22 = micros();
  ckpTime23 = micros();
  ckpTime24 = micros();
  ckpTime25 = micros();
  ckpTime26 = micros();
  ckpTime27 = micros();
  ckpTime28 = micros();
  ckpTime29 = micros();
  ckpTime30 = micros();
  ckpTime31 = micros();
  ckpTime32 = micros();
  ckpTime33 = micros();
  ckpTime34 = micros();
  ckpTime35 = micros();
  ckpTime36 = micros();
  ckpTime37 = micros();
  ckpTime38 = micros();
  ckpTime39 = micros();
  ckpTime40 = micros();
  ckpTime41 = micros();
  ckpTime42 = micros();
  ckpTime43 = micros();
  ckpTime44 = micros();
  ckpTime45 = micros();
  ckpTime46 = micros();
  ckpTime47 = micros();
  ckpTime48 = micros();
  ckpTime49 = micros();
  ckpTime50 = micros();
  ckpTime51 = micros();
  ckpTime52 = micros();
  
  

if (ckptimerenabled1) {if (ckpTIMEREXPIRED1){ckptimerenabled1=0; tt1end=1;}}

if (!tt2&& tt1end) {ckptimer2=ckpTime2; ckptimerenabled2 = 1; tt2=1; digitalWrite (ckp,1);}
if (ckptimerenabled2) {if (ckpTIMEREXPIRED2){ckptimerenabled2=0; tt2end=1;  }}

if (!tt3&& tt2end) {ckptimer3=ckpTime3; ckptimerenabled3 = 1; tt3=1; digitalWrite (ckp,0);}
if (ckptimerenabled3) {if (ckpTIMEREXPIRED3){ckptimerenabled3=0; tt3end=1;  }}

if (!tt4&& tt3end) {ckptimer4=ckpTime4; ckptimerenabled4 = 1; tt4=1; digitalWrite (ckp,1);}
if (ckptimerenabled4) {if (ckpTIMEREXPIRED4){ckptimerenabled4=0; tt4end=1; }}

if (!tt5&& tt4end) {ckptimer5=ckpTime5; ckptimerenabled5 = 1; tt5=1; digitalWrite (ckp,0);}
if (ckptimerenabled5) {if (ckpTIMEREXPIRED5){ckptimerenabled5=0; tt5end=1;  }}

if (!tt6&& tt5end) {ckptimer6=ckpTime6; ckptimerenabled6 = 1; tt6=1; digitalWrite (ckp,1);}
if (ckptimerenabled6) {if (ckpTIMEREXPIRED6){ckptimerenabled6=0; tt6end=1;  }}

if (!tt7&& tt6end) {ckptimer7=ckpTime7; ckptimerenabled7 = 1; tt7=1; digitalWrite (ckp,0);}
if (ckptimerenabled7) {if (ckpTIMEREXPIRED7){ckptimerenabled7=0; tt7end=1; }}

if (!tt8&& tt7end) {ckptimer8=ckpTime8; ckptimerenabled8 = 1; tt8=1; digitalWrite (ckp,1);}
if (ckptimerenabled8) {if (ckpTIMEREXPIRED8){ckptimerenabled8=0; tt8end=1;  }}

if (!tt9&& tt8end) {ckptimer9=ckpTime9; ckptimerenabled9 = 1; tt9=1; digitalWrite (ckp,0);}
if (ckptimerenabled9) {if (ckpTIMEREXPIRED9){ckptimerenabled9=0; tt9end=1;  }}

if (!tt10&& tt9end) {ckptimer10=ckpTime10; ckptimerenabled10 = 1; tt10=1; digitalWrite (ckp,1);}
if (ckptimerenabled10) {if (ckpTIMEREXPIRED10){ckptimerenabled10=0; tt10end=1; }}

if (!tt11&& tt10end) {ckptimer11=ckpTime11; ckptimerenabled11 = 1; tt11=1; digitalWrite (ckp,0);}
if (ckptimerenabled11) {if (ckpTIMEREXPIRED11){ckptimerenabled11=0; tt11end=1;  }}

if (!tt12&& tt11end) {ckptimer12=ckpTime12; ckptimerenabled12 = 1; tt12=1; digitalWrite (ckp,1);}
if (ckptimerenabled12) {if (ckpTIMEREXPIRED12){ckptimerenabled12=0; tt12end=1;  }}

if (!tt13&& tt12end) {ckptimer13=ckpTime13; ckptimerenabled13 = 1; tt13=1; digitalWrite (ckp,0);}
if (ckptimerenabled13) {if (ckpTIMEREXPIRED13){ckptimerenabled13=0; tt13end=1; }}

if (!tt14&& tt13end) {ckptimer14=ckpTime14; ckptimerenabled14 = 1; tt14=1; digitalWrite (ckp,1);}
if (ckptimerenabled14) {if (ckpTIMEREXPIRED14){ckptimerenabled14=0; tt14end=1;  }}

if (!tt15&& tt14end) {ckptimer15=ckpTime15; ckptimerenabled15 = 1; tt15=1; digitalWrite (ckp,0);}
if (ckptimerenabled15) {if (ckpTIMEREXPIRED15){ckptimerenabled15=0; tt15end=1;  }}

if (!tt16&& tt15end) {ckptimer16=ckpTime16; ckptimerenabled16 = 1; tt16=1; digitalWrite (ckp,1);}
if (ckptimerenabled16) {if (ckpTIMEREXPIRED16){ckptimerenabled16=0; tt16end=1;  }}

if (!tt17&& tt16end) {ckptimer17=ckpTime17; ckptimerenabled17 = 1; tt17=1; digitalWrite (ckp,0);}
if (ckptimerenabled17) {if (ckpTIMEREXPIRED17){ckptimerenabled17=0; tt17end=1;  }}

if (!tt18&& tt17end) {ckptimer18=ckpTime18; ckptimerenabled18 = 1; tt18=1; digitalWrite (ckp,1);}
if (ckptimerenabled18) {if (ckpTIMEREXPIRED18){ckptimerenabled18=0; tt18end=1;  }}

if (!tt19&& tt18end) {ckptimer19=ckpTime19; ckptimerenabled19 = 1; tt19=1; digitalWrite (ckp,0);}
if (ckptimerenabled19) {if (ckpTIMEREXPIRED19){ckptimerenabled19=0; tt19end=1;  }}

if (!tt20&& tt19end) {ckptimer20=ckpTime20; ckptimerenabled20 = 1; tt20=1; digitalWrite (ckp,1);}
if (ckptimerenabled20) {if (ckpTIMEREXPIRED20){ckptimerenabled20=0; tt20end=1;  }}

if (!tt21&& tt20end) {ckptimer21=ckpTime21; ckptimerenabled21 = 1; tt21=1; digitalWrite (ckp,0);}
if (ckptimerenabled21) {if (ckpTIMEREXPIRED21){ckptimerenabled21=0; tt21end=1;  }}

if (!tt22&& tt21end) {ckptimer22=ckpTime22; ckptimerenabled22 = 1; tt22=1; digitalWrite (ckp,1);}
if (ckptimerenabled22) {if (ckpTIMEREXPIRED22){ckptimerenabled22=0; tt22end=1; }}

if (!tt23&& tt22end) {ckptimer23=ckpTime23; ckptimerenabled23 = 1; tt23=1; digitalWrite (ckp,0);}
if (ckptimerenabled23) {if (ckpTIMEREXPIRED23){ckptimerenabled23=0; tt23end=1; }}

if (!tt24&& tt23end) {ckptimer24=ckpTime24; ckptimerenabled24 = 1; tt24=1; digitalWrite (ckp,1);}
if (ckptimerenabled24) {if (ckpTIMEREXPIRED24){ckptimerenabled24=0; tt24end=1; }}

if (!tt25&& tt24end) {ckptimer25=ckpTime25; ckptimerenabled25 = 1; tt25=1; digitalWrite (ckp,0);}
if (ckptimerenabled25) {if (ckpTIMEREXPIRED25){ckptimerenabled25=0; tt25end=1; }}

if (!tt26&& tt25end) {ckptimer26=ckpTime26; ckptimerenabled26 = 1; tt26=1; digitalWrite (ckp,1);}
if (ckptimerenabled26) {if (ckpTIMEREXPIRED26){ckptimerenabled26=0; tt26end=1; }}

if (!tt27&& tt26end) {ckptimer27=ckpTime27; ckptimerenabled27 = 1; tt27=1; digitalWrite (ckp,0);}
if (ckptimerenabled27) {if (ckpTIMEREXPIRED27){ckptimerenabled27=0; tt27end=1; }}

if (!tt28&& tt27end) {ckptimer28=ckpTime28; ckptimerenabled28 = 1; tt28=1; digitalWrite (ckp,1);}
if (ckptimerenabled28) {if (ckpTIMEREXPIRED28){ckptimerenabled28=0; tt28end=1; }}

if (!tt29&& tt28end) {ckptimer29=ckpTime29; ckptimerenabled29 = 1; tt29=1; digitalWrite (ckp,0);}
if (ckptimerenabled29) {if (ckpTIMEREXPIRED29){ckptimerenabled29=0; tt29end=1; }}

if (!tt28&& tt27end) {ckptimer28=ckpTime28; ckptimerenabled28 = 1; tt28=1; digitalWrite (ckp,1);}
if (ckptimerenabled28) {if (ckpTIMEREXPIRED28){ckptimerenabled28=0; tt28end=1; }}

if (!tt29&& tt28end) {ckptimer29=ckpTime29; ckptimerenabled29 = 1; tt29=1; digitalWrite (ckp,0);}
if (ckptimerenabled29) {if (ckpTIMEREXPIRED29){ckptimerenabled29=0; tt29end=1; }}

if (!tt28&& tt27end) {ckptimer28=ckpTime28; ckptimerenabled28 = 1; tt28=1; digitalWrite (ckp,1);}
if (ckptimerenabled28) {if (ckpTIMEREXPIRED28){ckptimerenabled28=0; tt28end=1; }}

if (!tt29&& tt28end) {ckptimer29=ckpTime29; ckptimerenabled29 = 1; tt29=1; digitalWrite (ckp,0);}
if (ckptimerenabled29) {if (ckpTIMEREXPIRED29){ckptimerenabled29=0; tt29end=1; }}

if (!tt28&& tt27end) {ckptimer28=ckpTime28; ckptimerenabled28 = 1; tt28=1; digitalWrite (ckp,1);}
if (ckptimerenabled28) {if (ckpTIMEREXPIRED28){ckptimerenabled28=0; tt28end=1; }}

if (!tt29&& tt28end) {ckptimer29=ckpTime29; ckptimerenabled29 = 1; tt29=1; digitalWrite (ckp,0);}
if (ckptimerenabled29) {if (ckpTIMEREXPIRED29){ckptimerenabled29=0; tt29end=1; }}

if (!tt28&& tt27end) {ckptimer28=ckpTime28; ckptimerenabled28 = 1; tt28=1; digitalWrite (ckp,1);}
if (ckptimerenabled28) {if (ckpTIMEREXPIRED28){ckptimerenabled28=0; tt28end=1; }}

if (!tt29&& tt28end) {ckptimer29=ckpTime29; ckptimerenabled29 = 1; tt29=1; digitalWrite (ckp,0);}
if (ckptimerenabled29) {if (ckpTIMEREXPIRED29){ckptimerenabled29=0; tt29end=1; }}

if (!tt28&& tt27end) {ckptimer28=ckpTime28; ckptimerenabled28 = 1; tt28=1; digitalWrite (ckp,1);}
if (ckptimerenabled28) {if (ckpTIMEREXPIRED28){ckptimerenabled28=0; tt28end=1; }}

if (!tt29&& tt28end) {ckptimer29=ckpTime29; ckptimerenabled29 = 1; tt29=1; digitalWrite (ckp,0);}
if (ckptimerenabled29) {if (ckpTIMEREXPIRED29){ckptimerenabled29=0; tt29end=1; }}

if (!tt28&& tt27end) {ckptimer28=ckpTime28; ckptimerenabled28 = 1; tt28=1; digitalWrite (ckp,1);}
if (ckptimerenabled28) {if (ckpTIMEREXPIRED28){ckptimerenabled28=0; tt28end=1; }}

if (!tt29&& tt28end) {ckptimer29=ckpTime29; ckptimerenabled29 = 1; tt29=1; digitalWrite (ckp,0);}
if (ckptimerenabled29) {if (ckpTIMEREXPIRED29){ckptimerenabled29=0; tt29end=1; }}

if (!tt28&& tt27end) {ckptimer28=ckpTime28; ckptimerenabled28 = 1; tt28=1; digitalWrite (ckp,1);}
if (ckptimerenabled28) {if (ckpTIMEREXPIRED28){ckptimerenabled28=0; tt28end=1; }}

if (!tt29&& tt28end) {ckptimer29=ckpTime29; ckptimerenabled29 = 1; tt29=1; digitalWrite (ckp,0);}
if (ckptimerenabled29) {if (ckpTIMEREXPIRED29){ckptimerenabled29=0; tt29end=1; }}

if (!tt30&& tt29end) {ckptimer30=ckpTime30; ckptimerenabled30 = 1; tt30=1; digitalWrite (ckp,1);}
if (ckptimerenabled30) {if (ckpTIMEREXPIRED30){ckptimerenabled30=0; tt30end=1; }}

if (!tt31&& tt30end) {ckptimer31=ckpTime31; ckptimerenabled31 = 1; tt31=1; digitalWrite (ckp,0);}
if (ckptimerenabled31) {if (ckpTIMEREXPIRED31){ckptimerenabled31=0; tt31end=1; }}

if (!tt32&& tt31end) {ckptimer32=ckpTime32; ckptimerenabled32 = 1; tt32=1; digitalWrite (ckp,1);}
if (ckptimerenabled32) {if (ckpTIMEREXPIRED32){ckptimerenabled32=0; tt32end=1; }}

if (!tt33&& tt32end) {ckptimer33=ckpTime33; ckptimerenabled33 = 1; tt33=1; digitalWrite (ckp,0);}
if (ckptimerenabled33) {if (ckpTIMEREXPIRED33){ckptimerenabled33=0; tt33end=1; }}

if (!tt34&& tt33end) {ckptimer34=ckpTime34; ckptimerenabled34 = 1; tt34=1; digitalWrite (ckp,1);}
if (ckptimerenabled34) {if (ckpTIMEREXPIRED34){ckptimerenabled34=0; tt34end=1; }}

if (!tt35&& tt34end) {ckptimer35=ckpTime35; ckptimerenabled35 = 1; tt35=1; digitalWrite (ckp,0);}
if (ckptimerenabled35) {if (ckpTIMEREXPIRED35){ckptimerenabled35=0; tt35end=1; }}

if (!tt36&& tt35end) {ckptimer36=ckpTime36; ckptimerenabled36 = 1; tt36=1; digitalWrite (ckp,1);}
if (ckptimerenabled36) {if (ckpTIMEREXPIRED36){ckptimerenabled36=0; tt36end=1; }}

if (!tt37&& tt36end) {ckptimer37=ckpTime37; ckptimerenabled37 = 1; tt37=1; digitalWrite (ckp,0);}
if (ckptimerenabled37) {if (ckpTIMEREXPIRED37){ckptimerenabled37=0; tt37end=1; }}

if (!tt38&& tt37end) {ckptimer38=ckpTime38; ckptimerenabled38 = 1; tt38=1; digitalWrite (ckp,1);}
if (ckptimerenabled38) {if (ckpTIMEREXPIRED38){ckptimerenabled38=0; tt38end=1; }}

if (!tt39&& tt38end) {ckptimer39=ckpTime39; ckptimerenabled39 = 1; tt39=1; digitalWrite (ckp,0);}
if (ckptimerenabled39) {if (ckpTIMEREXPIRED39){ckptimerenabled39=0; tt39end=1; }}

if (!tt40&& tt39end) {ckptimer40=ckpTime40; ckptimerenabled40 = 1; tt40=1; digitalWrite (ckp,1);}
if (ckptimerenabled40) {if (ckpTIMEREXPIRED40){ckptimerenabled40=0; tt40end=1; }}

if (!tt41&& tt40end) {ckptimer41=ckpTime41; ckptimerenabled41 = 1; tt41=1; digitalWrite (ckp,0);}
if (ckptimerenabled41) {if (ckpTIMEREXPIRED41){ckptimerenabled41=0; tt41end=1; }}

if (!tt42&& tt41end) {ckptimer42=ckpTime42; ckptimerenabled42 = 1; tt42=1; digitalWrite (ckp,1);}
if (ckptimerenabled42) {if (ckpTIMEREXPIRED42){ckptimerenabled42=0; tt42end=1; }}

if (!tt43&& tt42end) {ckptimer43=ckpTime43; ckptimerenabled43 = 1; tt43=1; digitalWrite (ckp,0);}
if (ckptimerenabled43) {if (ckpTIMEREXPIRED43){ckptimerenabled43=0; tt43end=1; }}

if (!tt44&& tt43end) {ckptimer44=ckpTime44; ckptimerenabled44 = 1; tt44=1; digitalWrite (ckp,1);}
if (ckptimerenabled44) {if (ckpTIMEREXPIRED44){ckptimerenabled44=0; tt44end=1; }}

if (!tt45&& tt44end) {ckptimer45=ckpTime45; ckptimerenabled45 = 1; tt45=1; digitalWrite (ckp,0);}
if (ckptimerenabled45) {if (ckpTIMEREXPIRED45){ckptimerenabled45=0; tt45end=1; }}

if (!tt46&& tt45end) {ckptimer46=ckpTime46; ckptimerenabled46 = 1; tt46=1; digitalWrite (ckp,1);}
if (ckptimerenabled46) {if (ckpTIMEREXPIRED46){ckptimerenabled46=0; tt46end=1; }}

if (!tt47&& tt46end) {ckptimer47=ckpTime47; ckptimerenabled47 = 1; tt47=1; digitalWrite (ckp,0);}
if (ckptimerenabled47) {if (ckpTIMEREXPIRED47){ckptimerenabled47=0; tt47end=1; }}

if (!tt48&& tt47end) {ckptimer48=ckpTime48; ckptimerenabled48 = 1; tt48=1; digitalWrite (ckp,1);}
if (ckptimerenabled48) {if (ckpTIMEREXPIRED48){ckptimerenabled48=0; tt48end=1; }}

if (!tt49&& tt48end) {ckptimer49=ckpTime49; ckptimerenabled49 = 1; tt49=1; digitalWrite (ckp,0);}
if (ckptimerenabled49) {if (ckpTIMEREXPIRED49){ckptimerenabled49=0; tt49end=1; }}

if (!tt50&& tt49end) {ckptimer50=ckpTime50; ckptimerenabled50 = 1; tt50=1; digitalWrite (ckp,1);}
if (ckptimerenabled50) {if (ckpTIMEREXPIRED50){ckptimerenabled50=0; tt50end=1; }}

if (!tt51&& tt50end) {ckptimer51=ckpTime51; ckptimerenabled51 = 1; tt51=1; digitalWrite (ckp,0);}
if (ckptimerenabled51) {if (ckpTIMEREXPIRED51){ckptimerenabled51=0; tt51end=1; }}

if (!tt52&& tt51end) {ckptimer52=ckpTime52; ckptimerenabled52 = 1; tt52=1; digitalWrite (ckp,1);}
if (ckptimerenabled52) {if (ckpTIMEREXPIRED52){ckptimerenabled52=0; tt52end=1; 


tt1=0; tt2=0; tt3=0; tt4=0; tt5=0; tt6=0; tt7=0; tt8=0; tt9=0; tt10=0; tt11=0; tt12=0; tt13=0; tt14=0; 
tt15=0; tt16=0; tt17=0; tt18=0; tt19=0; tt20=0; tt21=0; tt22=0; tt23=0; tt24=0; tt25=0; tt26=0; 
tt27=0; tt28=0; tt29=0; tt30=0; tt31=0; tt32=0; tt33=0; tt34=0; tt35=0; tt36=0; tt37=0; tt38=0;
tt39=0; tt40=0; tt41=0; tt42=0; tt43=0; tt44=0; tt45=0; tt46=0; tt47=0; tt48=0; tt49=0; tt50=0; tt51=0;tt52=0;   
tt1end=0; tt2end=0; tt3end=0; tt4end=0; tt5end=0; tt6end=0; tt7end=0; tt8end=0; tt9end=0; 
tt10end=0; tt11end=0; tt12end=0; tt13end=0; tt14end=0; tt15end=0; tt16end=0; tt17end=0; tt18end=0; 
tt19end=0; tt20end=0; tt21end=0; tt22end=0; tt23end=0; tt24end=0; tt25end=0;
tt26end=0; tt27end=0; tt28end=0;
tt29end=0; tt30end=0; tt31end=0; tt32end=0; tt33end=0; tt34end=0; tt35end=0;
tt36end=0; tt37end=0; tt38end=0; tt39end=0; tt40end=0; tt41end=0; tt42end=0;
tt43end=0; tt44end=0; tt45end=0; tt46end=0; tt47end=0; tt48end=0; tt49end=0;tt50end=0;tt51end=0;
 }}

CKP ();



}

void CKP (){
  
  Time23 = micros();
  Time156 = micros();
  Time40_1 = micros();
  Time40_2 = micros();
  Time40_3 = micros();
  Time40_4 = micros();
  Time210_1 = micros();
  Time210_2 = micros();
  Time210_3 = micros();
  Time36 = micros();
  
if (!t1){timer23=Time23; timerenabled23 = 1; ckptimer1=ckpTime1; ckptimerenabled1 = 1; t1=1; digitalWrite (CMP,0); digitalWrite (ckp,0);}
if (timerenabled23) {if (TIMEREXPIRED23){timerenabled23=0; t1end=1;}}

if (!t2 && t1end) {timer156=Time156; timerenabled156 = 1; t2=1; digitalWrite (CMP,1);}
if (timerenabled156) {if (TIMEREXPIRED156){timerenabled156=0; t2end=1;}}

if (!t3 && t2end) {timer40_1=Time40_1; timerenabled40_1 = 1; t3=1; digitalWrite (CMP,0);}
if (timerenabled40_1) {if (TIMEREXPIRED40_1){timerenabled40_1=0; t3end=1;}}

if (!t4 && t3end) {timer210_1=Time210_1; timerenabled210_1 = 1; t4=1; digitalWrite (CMP,1);}
if (timerenabled210_1) {if (TIMEREXPIRED210_1){timerenabled210_1=0; t4end=1; }}

if (!t5 && t4end) {timer40_2=Time40_2; timerenabled40_2 = 1; t5=1; digitalWrite (CMP,0);}
if (timerenabled40_2) {if (TIMEREXPIRED40_2){timerenabled40_2=0; t5end=1; }}

if (!t6 && t5end) {timer210_2=Time210_2; timerenabled210_2 = 1; t6=1; digitalWrite (CMP,1);}
if (timerenabled210_2) {if (TIMEREXPIRED210_2){timerenabled210_2=0; t6end=1; }}

if (!t7 && t6end) {timer40_3=Time40_3; timerenabled40_3 = 1; t7=1; digitalWrite (CMP,0);}
if (timerenabled40_3) {if (TIMEREXPIRED40_3){timerenabled40_3=0; t7end=1; }}

if (!t8 && t7end) {timer210_3=Time210_3; timerenabled210_3 = 1; t8=1; digitalWrite (CMP,1);}
if (timerenabled210_3) {if (TIMEREXPIRED210_3){timerenabled210_3=0; t8end=1; }}

if (!t9 && t8end) {timer40_4=Time40_4; timerenabled40_4 = 1; t9=1; digitalWrite (CMP,0);}
if (timerenabled40_4) {if (TIMEREXPIRED40_4){timerenabled40_4=0; t9end=1; }}

if (!t10 && t9end) {timer36=Time36; timerenabled36 = 1; t10=1; digitalWrite (CMP,1);}
if (timerenabled36) {if (TIMEREXPIRED36){timerenabled36=0; t10end=1; 
t1=0; t2=0; t3=0; t4=0; t5=0; t6=0; t7=0; t8=0; t9=0; t10=0; 
t1end=0; t2end=0; t3end=0; t4end=0; t5end=0; t6end=0; t7end=0; t8end=0; t9end=0;}}

}

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

вот что получилось с этого скетча на оборотах 1400, но если обороты менять, нижний график уплывает

Я так понимаю нужно делать прямое управление портами через регистры, и аппаратные таймеры использовать, прерывания ещё наверное. Я ещё не дорос до этого. 

 

Logik
Offline
Зарегистрирован: 05.08.2014

1. Получаете тахосигнал, измеряете его период

2. на основе периода расчитываете нужные длительности всех интервалов на диаграме.

3. формируете два сигнала начиная с момента где они совпадают, тем гарантируете их совпадение. Делантся без делеев на класической машинке состояний.

4. Обмываете результат за счет друга, публикуете на форуме, читаете восторженые отзывы.

ПС. в скетче позаменяйте строки вида

ckpTime1 = micros();
439   ckpTime2 = micros();
440   ckpTime3 = micros();

на

ckpTime1 = micros();
ckpTime2 = ckpTime1;
ckpTime3 = ckpTime1;
 
Может даже и поможет.
А вобще про массивы почитайте, сильно сократится и упростится все.
 
MaksVV
Offline
Зарегистрирован: 06.08.2015

спасибо попробую

MaksVV
Offline
Зарегистрирован: 06.08.2015

Не помогло. Спецы по таймерам, отзовитесь, плиз. Dimax ,как лучший в этом вопросе , прошу помощи.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Logik пишет:

1. Получаете тахосигнал, измеряете его период

2. на основе периода расчитываете нужные длительности всех интервалов на диаграме.

3. формируете два сигнала начиная с момента где они совпадают, тем гарантируете их совпадение. Делантся без делеев на класической машинке состояний.

4. Обмываете результат за счет друга, публикуете на форуме, читаете восторженые отзывы.

 

я не знаю че такое машинка состояний, но  код немного переделал.

Измеряется частота (ну или период), другой ардуиной кстати.

Передаётся на эту дуню по сериал.

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

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

В зависимости от номера зуба коленвала создается второй сигнал - зубья распредавала - на micros()

В зависимости от номера зуба коленвала создается третий сигнал - доп. зуб коленвала - на micros()

первый и третий сигналы хочу соединить на лог элементе "И"  (К555ЛИ1 ?)

PS использовал теперь низкоуровневое управление портами. 

Стало работать гораздо лучше, но всё равно есть нюансы

Код


#include <PWM.h>
#define ckp  9   //пин для генератора сигналов (не менять)
       
//для считываения приёма из сериала частоты taho
#include <SoftwareSerial.h>
SoftwareSerial Serial100(10,11);



unsigned int taho=0;

byte b0;
byte b1;
byte b2;
bool byte1read=0;
bool byte2read=0;
bool byteEnd=0;

//////



bool flag=0;


int PWM = 200;//стартовое значение ШИМ от 0 до 255        
int32_t frequency = 0; //стартовое значение частоты в Гц
float K;



volatile int impulse = 0;

//#include <class_BUTTON.h>
//BUTTON button_plus (3);
//BUTTON button_minus (2);


unsigned long ckpTime1, ckptimer1 = 0;
bool ckptimerenabled1 = 0;
#define ckpTIMEREXPIRED1 (ckpTime1 - ckptimer1)>(1000000L/frequency*0.12)//*0.10) // длина паузы в HIGH до доп зубьев

unsigned long ckpTime2, ckptimer2 = 0;
bool ckptimerenabled2 = 0;
#define ckpTIMEREXPIRED2 (ckpTime2 - ckptimer2)>(1000000L/frequency*0.15)//*0.10)// длина допзуба коленвала

unsigned long cmpTime2, cmptimer2 = 0;
bool cmptimerenabled2 = 0;
#define cmpTIMEREXPIRED2 (cmpTime2 - cmptimer2)>(1000000L*K/frequency*0.4) // длина допзуба распредвала

unsigned long cmpTime3, cmptimer3 = 0;
bool cmptimerenabled3 = 0;
#define cmpTIMEREXPIRED3 (cmpTime3 - cmptimer3)>(1000000L*K/frequency*0.36)// длина паузы в HIGH до зубьев распредвала

unsigned long cmpTime4, cmptimer4 = 0;
bool cmptimerenabled4 = 0;
#define cmpTIMEREXPIRED4 (cmpTime4 - cmptimer4)>(1000000L/frequency*0.94) //длина зуба распредвала


bool ckpT1=0;
bool ckpT1end=0;
bool ckpT2=0;
bool cmpT3=0;
bool cmpT3end=0;
bool cmpT4=0;

bool flag12=0;
bool flag24=0;
bool flag4=0;
bool flag10=0;
bool flag16=0;
bool flag22=0;

bool metka =0;


void IMPULSE (){
  impulse++;
  if (impulse==25) impulse=1; 
}





unsigned long prev = 0;
void setup()
{
Serial100.begin (19200);
Serial.begin(9600);
pinMode (12,OUTPUT);
pinMode (13,OUTPUT);
pinMode (13,1);
DDRD  |= (1 << 7);
DDRD  |= (1 << 6);
DDRD  |= _BV(PD3);

attachInterrupt (0, IMPULSE, FALLING);


 InitTimersSafe(); 
 bool success = SetPinFrequencySafe(ckp, frequency); 

delay (300);
    }   

void loop() {

  while (1){
unsigned long cur = millis();
frequency = taho*4.33;
if (taho>300){K=0.7;PWM=190;}
else {K=1; PWM=200;}
if (taho==0) PWM=0;

SerialREAD();


if (byteEnd) {taho = ( ( unsigned int )b1 << 8 ) | b2; byteEnd=0;}


//if (cur-prev>100) { Serial.print (impulse); Serial.print ("   "); Serial.println (taho); prev=cur;} 

bool success = SetPinFrequencySafe(ckp, frequency);
pwmWrite(ckp, PWM); 

ckpTime1 = micros();
ckpTime2 = ckpTime1;
cmpTime2 = ckpTime1;
cmpTime3 = ckpTime1;
cmpTime4 = ckpTime1;


//если посчитали 4,10,16 или 22 маркер запускаем таймер задержки в HIGH для зубьев распредвала
if (((impulse==4&&!flag4)||(impulse==10&&!flag10)||(impulse==16&&!flag16)||(impulse==22&&!flag22)) && !cmpT3 && PWM!=0)  {cmptimer3=cmpTime3; cmptimerenabled3=1; cmpT3=1; }    
if (impulse!=4)flag4=0; 
if (impulse!=10)flag10=0;
if (impulse!=16)flag16=0; 
if (impulse!=22)flag22=0;

if (cmptimerenabled3) {if (cmpTIMEREXPIRED3) {cmptimerenabled3=0; cmpT3end=1;}}

// когда таймер задержки в HIGH кончился, запускаем таймер зуба распредвала, во время которого выход находится в LOW
if (!cmpT4 && cmpT3end)  { cmptimer4=cmpTime4; cmptimerenabled4=1; cmpT4=1;  PORTD &=~ _BV(PD7); }
// когда таймер зуба распредвала истек, переводим вывод в HIGH
if (cmptimerenabled4) {if (cmpTIMEREXPIRED4) { PORTD |= _BV(PD7); cmptimerenabled4=0;  cmpT3=0; cmpT3end=0; cmpT4=0;}}

// если посчитали 12 маркер запускаем таймер задержки в HIGH, флаг метки ВМТ такт сжатия 1-го ц. (МПЦ) НЕ ТРОГАЕМ
if (impulse==12 && !flag12 && !ckpT1&& PWM!=0) {ckptimer1=ckpTime1; ckptimerenabled1=1; ckpT1=1; flag12=1;}
if (impulse!=12)flag12=0;
if (impulse!=24)flag24=0;

// если посчитали 24 маркер, запускаем таймер задержки в HIGH, флаг метки МПЦ в true
if (impulse==24 && !flag24 && !ckpT1 && PWM!=0)  {ckptimer1=ckpTime1; ckptimerenabled1=1; ckpT1=1; metka=1;flag24=1;}    
if (ckptimerenabled1) {if (ckpTIMEREXPIRED1) {ckptimerenabled1=0; ckpT1end=1;}}

// когда таймер задержки в HIGH кончился, запускаем таймеры, во время которых выходы находятся в LOW
// если сейчас присутствует метка МПЦ, запускаем доболнительный зуб и на коленвале и на распредвале, после чего сбрасываем метку МПЦ
if (!ckpT2 && ckpT1end && metka)  {ckptimer2=ckpTime2; ckptimerenabled2=1; ckpT2=1; cmptimer2=cmpTime2; cmptimerenabled2=1; 
PORTD &=~ _BV(PD7); PORTD &= ~(1 << PD3);   metka=0;}

// если метки МПЦ НЕТ, запускаем доболнительный только на коленвале
if (!ckpT2 && ckpT1end && !metka)  {ckptimer2=ckpTime2; ckptimerenabled2=1; ckpT2=1; PORTD &= ~(1 << PD3);   }

// когда таймеры дополнительных зубов истекли, переводим выводы в HIGH
if (ckptimerenabled2) {if (ckpTIMEREXPIRED2) {    PORTD |= (1 << PD3); ckptimerenabled2=0;  ckpT1=0; ckpT1end=0; ckpT2=0;}}
if (cmptimerenabled2) {if (cmpTIMEREXPIRED2) {PORTD |= _BV(PD7); cmptimerenabled2=0; }}


//byte k; k=PIND;
//if (!((1 << PD4) & k) || !((1 << PD5) & k)) {PORTD  &=~ _BV(PD6);} 
//if (((1 << PD4) & k) && ((1 << PD5) & k)) {PORTD  |= _BV(PD6);} 



}}

void SerialREAD (){
if (!Serial100.available()) return;

 
 b0 = Serial100.read();
if (byte1read){ if (b0!=0x31 && b0!=0x32 && b0!=0x33) {b1=b0; byte1read=0;} }
if (byte2read){ if (b0!=0x31 && b0!=0x32 && b0!=0x33) {b2=b0; byte2read=0;} }

if (b0==0x31) byte1read=1;
if (b0==0x32) byte2read=1;
if (b0==0x33) byteEnd=1;
Serial.println (b0,HEX);
}

 

 

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

получилось настроить таймер 1 ардуино чтобы получить такие сигналы. Работает гораздо более стабильно. Кто нибудь подскажите как сделать дополнительные зубья? можно на других пинах, т.к. К555ЛИ1 хорошо сигналы соединяет, попробовал. 

 



bool high;
volatile bool falsetooth=0; 

int shet=0;
bool flagshet=0;

uint8_t dutyA=83;
uint8_t dutyB=8;
static uint32_t enc = 0;
volatile int impulse;

void IMPULSE (){
  impulse++;
  if (impulse==25) impulse=1; 
  if (impulse==6||impulse==12||impulse==18||impulse==24) falsetooth=1;
  if (impulse==2||impulse==8||impulse==14||impulse==20)falsetooth=0; 
}

void setup() {

pinMode (9,OUTPUT); // выход генератора PB2
pinMode (10,OUTPUT); // выход генератора 
pinMode (4,OUTPUT); //
pinMode (2,INPUT); //
digitalWrite (2,1); // 


TCCR1A=1<<COM1A1|1<<COM1B1; //подключить выход OC1A и OC1Bпервого таймера
TCCR1B=0;//

attachInterrupt (0, IMPULSE, RISING);
}

void loop() {
  while (1){



uint32_t icr=ICR1;
uint16_t divider=1; //переменная коэфф. деления прескалера
enc = 400;
icr = (F_CPU / enc /2 /divider); 
 byte shifts[] = {3,3,2,2};
  for(byte i = 0; i < 4; i++){
      if (icr > 65536) {
          divider <<= shifts[i];
          icr = F_CPU / enc /2 /divider;
         }
    else {  //запись в регистр прескалера
        TCCR1B = (i+1)|(1<<WGM13);  break;
         }
    }
ICR1=icr-1;
 OCR1A=(uint32_t)ICR1*dutyA/100; 
 
 OCR1B=(uint32_t)ICR1*dutyB/100; 
 

if (impulse == 2||impulse == 3||impulse == 4||impulse == 5||impulse == 8||impulse == 9||impulse == 10||impulse == 11||impulse == 14||impulse == 15||impulse == 16||impulse == 17||impulse == 20||impulse == 21||impulse == 22||impulse == 23){ 
  TCCR1A=1<<COM1A1|0<<COM1B1; PORTB = _BV(PB2); high = 1;}
else {TCCR1A=1<<COM1A1|1<<COM1B1; high=0;}
byte k; k=PINB;
 if (falsetooth &&  !flagshet &&  ((1 << PB2) & k))   {shet++; flagshet=1;}
 if (falsetooth && flagshet && !((1 << PB2) & k))   {flagshet=0; }
 if (!falsetooth) shet=0;

 


if (!high && !((1 << PB2) & k) && shet==1) {PORTD  &=~ _BV(PD4);} 
if (((1 << PB2) & k) ) {PORTD  |= _BV(PD4);} 

 
}}

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

поспешил, на частоте более 600 лажа потому что измерение в лупе, надо на второе внешнее прерывание вешать

MaksVV
Offline
Зарегистрирован: 06.08.2015

Вот исправил, теперь вроде как до 1400 Гц стабильный сигнал. Вопрос как создать дополнительный зуб у распредвала и коленвала, не используя micros() остаётся открытым.

 

получилось вот так 

Код




 
volatile int tic=0;
volatile int impulse;


uint8_t dutyA=83;
uint8_t dutyB=8;
static uint32_t enc = 0;

//unsigned long prev=0;

void IMPULSE (){
  impulse++;
  if (impulse==25) impulse=1; 
  
}

void TIC (){
 tic++;
  if (tic==13) tic=1; 
}


void setup() {

pinMode (9,OUTPUT); // выход генератора PB2
pinMode (10,OUTPUT); // выход генератора 
pinMode (4,OUTPUT); //
pinMode (2,INPUT); //
digitalWrite (2,1); // 
pinMode (3,INPUT); //
digitalWrite (3,1); // 

Serial.begin(9600);

TCCR1A=1<<COM1A1|1<<COM1B1; //подключить выход OC1A и OC1Bпервого таймера
TCCR1B=0;//

attachInterrupt (0, IMPULSE, RISING);
attachInterrupt (1, TIC, FALLING);
}

void loop() {
  while (1){
//int val = analogRead(0);
//unsigned long cur = millis();
//if (cur - prev>200){Serial.print (val); Serial.print ("   "); Serial.println (enc); prev=cur;}


 // val = map(val, 0, 1023, 0, 1400);
  
  
uint32_t icr=ICR1;
uint16_t divider=1; //переменная коэфф. деления прескалера
enc = 800;
icr = (F_CPU / enc /2 /divider); 
 byte shifts[] = {3,3,2,2};
  for(byte i = 0; i < 4; i++){
      if (icr > 65536) {
          divider <<= shifts[i];
          icr = F_CPU / enc /2 /divider;
         }
    else {  //запись в регистр прескалера
        TCCR1B = (i+1)|(1<<WGM13);  break;
         }
    }
ICR1=icr-1;
 OCR1A=(uint32_t)ICR1*dutyA/100; 
 
 OCR1B=(uint32_t)ICR1*dutyB/100; 
 

if (impulse == 2||impulse == 3||impulse == 4||impulse == 5||impulse == 8||impulse == 9||impulse == 10||impulse == 11||impulse == 14||impulse == 15||impulse == 16||impulse == 17||impulse == 20||impulse == 21||impulse == 22||impulse == 23){ 
  TCCR1A=1<<COM1A1|0<<COM1B1; PORTB = _BV(PB2);}
else {TCCR1A=1<<COM1A1|1<<COM1B1;}

 if (tic==3||tic==6||tic==9||tic==12)PORTD  &=~ _BV(PD4);
 else PORTD  |= _BV(PD4);



 
}}

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

Продолжаю монолог. Всем спасибо за неоценимую "помощь" в освоении таймеров и прерываний. Изначально тахосигнал, с которого нужно было измерять обороты, был такой 

т.е. я сначала пытался измерить частоту тахосигнала, а затем выдать свою частоту на сигнал коленвала (т.е. на три импульса тахосигнала нужно выдать 12 импульсов коленвала). Боролся , боролся, все "помогали". Т.е. сгенерировать сигнал то более менее получилось, но вот адектватно измерить часототу тахосигнала не вышло, т.к. все методы либо медленно мереют, либо при прекращении сигнала показывают предыдуще измеренную частоту, а мне надо ноль. 

Короче вышел из положения. На установленном двигателе кроме тахосигнала нашел сигнал первичного вала АКПП. На нём гораздо больше импульсов на один оборот коленвала.

Плохо только что немного отличается частота вращения, т.к. гидротрансформатор АКПП немного скользит, да и фиг с ним, не сильно как мне кажется. Зато пропала необходимость измерения частоты. Сигнал этот 5В в отличие от тахосигнала (он на 14В) - пропала необходимость в преобразователе напряжения (до этого использовал оптопару).

В прерывании подсчитываю количество импульсов сигнала этого первичного  вала КПП. И в зависимости от номера имульса рулю тупо ногами МК низкоуровнево. Код сократился до нельзя и работает стабильно хоть до 10000 RPM.

Всего одна переменная и луп пустой. 

volatile int impulse=0;

void IMPULSE (void){
impulse++;
if (impulse==85) impulse=1; 
if (impulse == 1||impulse==8||impulse==15||impulse==22||impulse==29||impulse==36||impulse==43||impulse==50||impulse==57||impulse==64||impulse==71||impulse==78)PORTB &=~ _BV(PB2);
else PORTB |= _BV(PB2);
if (impulse == 34||impulse==76) PORTD &=~ _BV(PD7);
if (impulse == 39||impulse==81) PORTD |= _BV(PD7);

}

void setup () {

pinMode (10,OUTPUT); // выход сигнала коленвала 
pinMode (7,OUTPUT); // выход сигнала распредвала 
pinMode (3,INPUT); // вход частоты
digitalWrite (3,1); // 
attachInterrupt (1, IMPULSE, CHANGE);
}

void loop(){}

ПС. Информация будет полезна тем, кто на хонде решил поменять рядный 4 цил двигатель К20 или К24 на V6 J30 или J35

chiptuningnt
chiptuningnt аватар
Offline
Зарегистрирован: 22.01.2018

Привет. Можешь немного пояснить, только пытаюсь вникнуть в МК, архитектуру и язык С. 
 

pinMode (3,INPUT); // вход частоты
digitalWrite (3,1); 
attachInterrupt (1, IMPULSE, CHANGE);

01: назначаем порт 3 на вход
02: устанавливаем на входе 3 значение 1
03: запускаем функцию IMPULSE по изменению состаяния на входе

не могу понять с командой attachInterrupt, а именно с единицей, как понял здесь назначается порт по которому идут прерывания, почему 1? 
 

chiptuningnt
chiptuningnt аватар
Offline
Зарегистрирован: 22.01.2018

И еще вопрос. Этой прогой ты имитируешь работу датчиков КВ и РВ синхранизируясь по датчику входного вала АКП. Зная к-во зубьев за оборот мы имеем один оборот коленчатого вала (не беря в расчет вероятность проскальзывания муфты). Два оборота вала АКП получаем полный цикл, 2 поворота КВ и один РВ. Хорошо, сигналы этих датчиков мы с имитировали. А как выполняется синхранизация по положению КВ? Те начиная считать зубья с вала АКП программе без разницы фактическое поожение КВ, на каком такте работы находится тот или иной цилиндр. Или я не совсем правильно что то понял

MaksVV
Offline
Зарегистрирован: 06.08.2015

chiptuningnt пишет:

Те начиная считать зубья с вала АКП программе без разницы фактическое поожение КВ, на каком такте работы находится тот или иной цилиндр. Или я не совсем правильно что то понял

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

MaksVV
Offline
Зарегистрирован: 06.08.2015

chiptuningnt пишет:

03: запускаем функцию IMPULSE по изменению состаяния на входе

не могу понять с командой attachInterrupt, а именно с единицей, как понял здесь назначается порт по которому идут прерывания, почему 1? 
 

в ардуино уно, нано, мини есть два аппаратных прерывания (прерывание - это когада МК прекращает выполенени основной программы и переходит в функцию прерывания, она называется обработчик прерывания, в данном случае назвал её IMPULSE. Цифра 1 это номер прерывания, точнее будет int1 , как я сказал их два. То есть первое будет 0. Для прерывания 0 используется 2 пин ардуино, для прерывания 1 - 3 пин. Вообще про это смотрим тут)

oshiman
Offline
Зарегистрирован: 28.01.2018

А зачем такой огород городить ради тахометра. Вам нужно просто знать обороты двигателя. Если датчик коленвала типа Холла - взять сигнал с него, посчитать количество импульсов за оборот. Еще проще взять сигнал управления катушкой зажигания. Можно и с форсунки, но в некоторых режимах форсунки могут отключаться. 

Если приборка действительно CAN-овая, то больше сложностей передать сигнал в шину.

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

oshiman пишет:
Если приборка действительно CAN-овая, то больше сложностей передать сигнал в шину.

В том то и дело, что я на тот момент не умел обращаться с CAN шиной и решено было оставить старый ЭБУ двигателя который будет посылать на панель обороты. Но этот блок оказался капризный и ему нужны были точные сигналы коленвала и распредвала с "родного" двигателя.