Светодиодный тахометр

avo74i2
Offline
Зарегистрирован: 25.03.2016

Доброго времени суток! Хочу сделать на мотоцикл тахометр из светодиодов. Прилагаю фотография для наглядности того что примерно я хочу получить. Сегодня пришла UNO3. Подключил к ПК - все видит все мигает. Пока шла плата изучал программирование, написал первый скетч. Конечно же он не компилируется из за ошибок. Прошу помощи, а именно, кому не лень посмотрите мой скетч, он не большой много времени для опытных программистов не отнимет. Укажите мне на мои основные ошибки, и вообще оцените ход мысли, будет ли этот скетч реально считать обороты и зажигать светодиоды. Или может есть проще путь к реализации моей задумки.... Вообщем кто может поможет)))

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

[code]
int kat = 15;
int greenLED1 = 1;
int greenLED2 = 2;
int greenLED3 = 3;
int greenLED4 = 4;
int greenLED5 = 5;
int yellowLED6 = 6;
int yellowLED7 = 7;
int redLED8 = 8;
int PRM = 0;

void setup() {
  // Инициализируем цифровые вход/выход
  pinmode(kat, INPUT);
  pinmode(greenLED1, OUTPUT);
  pinmode(greenLED2, OUTPUT);
  pinmode(greenLED3, OUTPUT);
  pinmode(greenLED4, OUTPUT);
  pinmode(greenLED5, OUTPUT);
  pinmode(yellowLED6, OUTPUT);
  pinmode(yellowLED7, OUTPUT);
  pinmode(redLED8, OUTPUT);
}


void loop() {



  if (digitalread(kat)) == HIGH    // если на катушке сигнал
  { unsigned long;   } //запускаем отсчет времени
  if (digitalread(kat)) == HIGH //если на катушке снова сигнал
  {PRM = 60000000\micros} //обороты равны минуту делим на подсчитанное время между сигналами с катушки

  if PRM = < 1000
{digitalwrite(greenLED1, HIGH}

if 1000 < PRM <= 2000
{ digitalwrite(greenLED1, HIGH);
    digitalwrite(greenLED2, HIGH);}

  if 2000 < PRM <= 3000
{ digitalwrite(greenLED1, HIGH);
    digitalwrite(greenLED2, HIGH);
    digtalwrite(greenLED3, HIGH);   }

  if 3000 < PRM <= 4000
{ digitalwrite(greenLED1, HIGH);
    digitalwrite(greenLED2, HIGH);
    digtalwrite(greenLED3, HIGH);
    digitalwrite(greenLED4, HIGH);    }

  if 4000 < PRM <= 5000
{ digitalwrite(greenLED1, HIGH);
    digitalwrite(greenLED2, HIGH);
    digtalwrite(greenLED3, HIGH);
    digitalwrite(greenLED4, HIGH);}

  if 5000 < PRM <= 6000
{ digitalwrite(greenLED1, HIGH);
    digitalwrite(greenLED2, HIGH);
    digtalwrite(greenLED3, HIGH);
    digitalwrite(greenLED4, HIGH);
    digitalwrite(greenLED5, HIGH);
    digitalwrite(yellowLED6, HIGH);
  }
  if 6000 < PRM <= 7000
{ digitalwrite(greenLED1, HIGH);
    digitalwrite(greenLED2, HIGH);
    digtalwrite(greenLED3, HIGH);
    digitalwrite(greenLED4, HIGH);
    digitalwrite(greenLED5, HIGH);
    digitalwrite(yellowLED6, HIGH);
    digitalwrite(yellowLED7, HIGH);
  }
  if 7000 < PRM <= 8000
{
  digitalwrite(greenLED1, HIGH);
    digitalwrite(greenLED2, HIGH);
    digtalwrite(greenLED3, HIGH);
    digitalwrite(greenLED4, HIGH);
    digitalwrite(greenLED5, HIGH);
    digitalwrite(yellowLED6, HIGH);
    digitalwrite(yellowLED7, HIGH);
    digitalwrite(redLED8, HIGH);
  }

  delay(500);


  digitalwrite(greenLED1, LOW);
  digitalwrite(greenLED2, LOW);
  digtalwrite(greenLED3, LOW);
  digitalwrite(greenLED4, LOW);
  digitalwrite(greenLED5, LOW);
  digitalwrite(yellowLED6, LOW);
  digitalwrite(yellowLED7, LOW);
  digitalwrite(redLED8, LOW)
}





}
[/code]

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Строки 2-13 и 27 без ошибок.

avo74i2
Offline
Зарегистрирован: 25.03.2016
int kat = 15;
int greenLED1 = 1;
int greenLED2 = 2;
int greenLED3 = 3;
int greenLED4 = 4;
int greenLED5 = 5;
int yellowLED6 = 6;
int yellowLED7 = 7;
int redLED8 = 8;
int PRM = 0;

void setup() {
  // Инициализируем цифровые вход/выход
  pinMode(kat, INPUT);
  pinMode(greenLED1, OUTPUT);
  pinMode(greenLED2, OUTPUT);
  pinMode(greenLED3, OUTPUT);
  pinMode(greenLED4, OUTPUT);
  pinMode(greenLED5, OUTPUT);
  pinMode(yellowLED6, OUTPUT);
  pinMode(yellowLED7, OUTPUT);
  pinMode(redLED8, OUTPUT);
}


void loop() {



  if (digitalread(kat) == LOW)    // если на катушке сигнал
  { unsigned long;   } //запускаем отсчет времени
  if (digitalread(kat) == LOW) //если на катушке снова сигнал
  {PRM = 60000000\micros} //обороты равны минуту делим на подсчитанное время между сигналами с катушки

  if (PRM = < 1000)
{digitalWrite(greenLED1, HIGH}

if (1000 < PRM <= 2000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);}

  if (2000 < PRM <= 3000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);   }

  if (3000 < PRM <= 4000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);    }

  if (4000 < PRM <= 5000) 
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);}

  if (5000 < PRM <= 6000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
  }
  if (6000 < PRM <= 7000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
    digitalWrite(yellowLED7, HIGH);
  }
  if (7000 < PRM <= 8000)
{
  digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
    digitalWrite(yellowLED7, HIGH);
    digitalWrite(redLED8, HIGH);
  }

  delay(500);


  digitalWrite(greenLED1, LOW);
  digitalWrite(greenLED2, LOW);
  digitalWrite(greenLED3, LOW);
  digitalWrite(greenLED4, LOW);
  digitalWrite(greenLED5, LOW);
  digitalWrite(yellowLED6, LOW);
  digitalWrite(yellowLED7, LOW);
  digitalWrite(redLED8, LOW)
}





}

а сейчас))? больше что то не могу найти пока, да и нашел только грамматические ошибки... 

Больше интересно что значит "error: stray '\' in program"

И Еще я так понимаю вот этот кусок у меня выделяет красным так как присвоение значения переменной это не есть выполнение какого то действия? или что тут не так?

 if (digitalread(kat) == LOW) //если на катушке снова сигнал
  {PRM = 60000000\micros} //обороты равны минуту делим на подсчитанное время между сигналами с катушки

 

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Стало получше.

 if (digitalread(kat) == LOW)    // если на катушке сигнал
  { unsigned long;   } //запускаем отсчет времени
  if (digitalread(kat) == LOW) //если на катушке снова сигнал
  {PRM = 60000000\micros} //обороты равны минуту делим на подсчитанное время между сигналами с катушки

Строки 30 и 32: digitalRead

Строка 31: что это?

Строка 33: что такое \micros?

В строке 36 не хватает );

В строке 98 нет ;

Все if (1000 < PRM <= 2000) приведут к ошибке при работе проги. Надо писать так: if (PRM > 1000 && PRM <= 2000)

avo74i2
Offline
Зарегистрирован: 25.03.2016

Хорошо ошибки учту и поправлю, спасибо!)

ну а на счет строки 31 и 33 вот тут начитался http://arduino.ru/Reference/Micros

 как я понял 31 строка запустит отсчет времени командой unsigned long а 33 строка это я присваиваю к переменно PRM значение  равное 60000000 поделить на micros.

 if (digitalRead(kat) == LOW)    // если на катушке сигнал
  { unsigned long time;   } //запускаем отсчет времени
  if (digitalRead(kat) == LOW) //если на катушке снова сигнал
  {PRM = 60000\micros();} //обороты равны минуту делим на подсчитанное время между сигналами с катушки

Вот так правильнее или не в этом дело и я не понял как пользоваться микрос? 60000000 обсчитался, это минута в милисекундах у меня такая)))

 

alex0
Offline
Зарегистрирован: 14.12.2015

avo74i2 пишет:

Хорошо ошибки учту и поправлю, спасибо!)

ну а на счет строки 31 и 33 вот тут начитался http://arduino.ru/Reference/Micros

 как я понял 31 строка запустит отсчет времени командой unsigned long а 33 строка это я присваиваю к переменно PRM значение  равное 60000000 поделить на micros.

 if (digitalRead(kat) == LOW)    // если на катушке сигнал
  { unsigned long time;   } //запускаем отсчет времени
  if (digitalRead(kat) == LOW) //если на катушке снова сигнал
  {PRM = 60000\micros();} //обороты равны минуту делим на подсчитанное время между сигналами с катушки

Вот так правильнее или не в этом дело и я не понял как пользоваться микрос? 60000000 обсчитался, это минута в милисекундах у меня такая)))

 

Unsigned long используется для хранения положительных целых чисел в диапазоне от 0 до 4,294,967,295 (2^32 - 1) изанимает 32 бита (4 байта) в памяти.

 

micros() это время СО СТАРТА СКЕТЧА в микросекундах. Зачем на него делить?!

 

 

if (digitalRead(kat) == LOW) {

long time = micros();

if (digitalRead(kat) == HIGH) {

if (digitalRead(kat) == LOW) {

time = micros() - time;

PRM = 60000000 / time;

}

}

}

Вроде так норм должно быть.


avo74i2
Offline
Зарегистрирован: 25.03.2016

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

alex0
Offline
Зарегистрирован: 14.12.2015

Вчера сонный немного ошибся.

 

int a ;

if (digitalRead(kat) == LOW && a == 0) long time = micros();

if (digitalRead(kat) == HIGH)  a =1;

if (digitalRead(kat) == LOW && a == 1) {

time = micros() - time;

PRM = 60000000 / time;

a = 0;

}

HIGH e тебя должен появляться иначе получается что пин "болтается в воздухе" и собирает наводки что преведет к ложным срабатываниям.

Тоесть ты получаешь сигнал LOW с катушки и запоминаешь время, потом получаешь сигнал HIGH чтобы знать что не считываешь время между одним и тем же LOW, и когда  снова получаешь LOW вычитаешь из текущего времени время предидущего Low и считаешь сколько оборотов при такой паузе между тактами.

 

avo74i2
Offline
Зарегистрирован: 25.03.2016

Я правильно понимаю что когда пин 15 будет соединен с землей это будет сигнал LOW? А как на этом же пине получать сигнал HIGH? Там должно появляться 5v?или можно другое напряжение запрограммировать на сигнал HIGH? И еще не совсем понял что такое "а"?

alex0
Offline
Зарегистрирован: 14.12.2015

low да когда сигнал близок к нулю, меньше чем 0.4 вольта. High когда сигнал выше 2.4 вольта. Больше 5 вольт подавать на вход нельзя, если высокий уровень с катушки больше 5 вольт для уменьшения нужно использовать резистивный делитель.

avo74i2
Offline
Зарегистрирован: 25.03.2016
я тут подумал, а не так случайно?)
int a ;

if (digitalRead(kat) == LOW && a == 0) long time = micros();

if (digitalRead(kat) == HIGH)  a =1;

if (digitalRead(kat) == LOW && a == 1) {

time = micros() -  long time;

PRM = 60000000 / time;

a = 0;

}

 

avo74i2
Offline
Зарегистрирован: 25.03.2016

Привет всем кто откликнулся (и тем кто еще только собирается) на мой зов помощи новичка) итак мой первый в жизни скетч скомпилировался и я очень рад) получил удовольствие огромное от написания и от разбирательств со всеми скобочками точечками))) кто же мог подумать что деление это не "\" а "/"  и прочие как казалось мелочи).... Вообщем ребят посмотрите на код и выразите свое мнение будет ли он работать и есть ли недостатки какие то скрытые от моего неопытного взора. И по возможности дайте ответы:

1)Загрузив скетч в плату он там сохранится даже после потери питания платой?  задаю этот вопрос потому что заливал простой скетч мигания светодиодом, все получалось, но после того как отключал от ПК плату и подключал снова скетч не выполнялся.

2)При подаче питания на плату(включаю зажигание на байке) скетч сразу начнет выполняться ?

3)можно ли посмотреть какой скетч залит в плату ?

4)вообщем то ответив на первый вопрос на второй может и не потребуется отвечать но вы поняяли меня надеюсь)

int kat = 15;
int greenLED1 = 1;
int greenLED2 = 2;
int greenLED3 = 3;
int greenLED4 = 4;
int greenLED5 = 5;
int yellowLED6 = 6;
int yellowLED7 = 7;
int redLED8 = 8;
int PRM = 0;
int a=0;
int time1=0;
int time2=0;

void setup() {
  // Инициализируем цифровые вход/выход
  pinMode(kat, INPUT);
  pinMode(greenLED1, OUTPUT);
  pinMode(greenLED2, OUTPUT);
  pinMode(greenLED3, OUTPUT);
  pinMode(greenLED4, OUTPUT);
  pinMode(greenLED5, OUTPUT);
  pinMode(yellowLED6, OUTPUT);
  pinMode(yellowLED7, OUTPUT);
  pinMode(redLED8, OUTPUT);
}


void loop() {



  if (digitalRead(kat) == LOW && a == 0)    // если на катушке сигнал low1
  {time1=micros();   } 
  if (digitalRead(kat) == HIGH ) //если на катушке  сигнал high
  {a=1;}
   if (digitalRead(kat) == LOW && a == 1)    // если на катушке сигнал low2
  {time2=micros()-time1;  
  PRM = 60000/time2;
   a=0;}
if (PRM<=1000)
{digitalWrite(greenLED1, HIGH);}

if (PRM > 1000 &&  PRM <= 2000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);}

  if (PRM > 2000 &&  PRM <= 3000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);   }

  if (PRM > 3000 &&  PRM <= 4000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);    }

  if (PRM > 4000 &&  PRM <= 5000) 
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);}

  if (PRM > 5000 &&  PRM <= 6000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
  }
  if (PRM > 6000 &&  PRM <= 7000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
    digitalWrite(yellowLED7, HIGH);
  }
  if (PRM > 7000 &&  PRM <= 8000)
{
  digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
    digitalWrite(yellowLED7, HIGH);
    digitalWrite(redLED8, HIGH);
  }

  delay(500);


  digitalWrite(greenLED1, LOW);
  digitalWrite(greenLED2, LOW);
  digitalWrite(greenLED3, LOW);
  digitalWrite(greenLED4, LOW);
  digitalWrite(greenLED5, LOW);
  digitalWrite(yellowLED6, LOW);
  digitalWrite(yellowLED7, LOW);
  digitalWrite(redLED8, LOW);
}

 

alex0
Offline
Зарегистрирован: 14.12.2015
01 я тут подумал, а не так случайно?)
02 int a ;
03  
04 if (digitalRead(kat) == LOW && a == 0) long time = micros();
05  
06 if (digitalRead(kat) == HIGH)  a =1;
07  
08 if (digitalRead(kat) == LOW && a == 1) {
09  
10 time = micros() -  long time;

  

11  
12 PRM = 60000000 / time;
13  
14 a = 0;
15  
16 }

слово long задает тип переменной, в 10 строке оно не нужно.

http://arduino.ru/Reference  выучите всё что там есть.

 

1 - да, скетч находится в энергонезависимой памяти

2 - да

3 - вроде бы да, но  сложно и не скетч а Ассемблированый код в котором вы не слова не поймёте.

4 - может потребуется а может и нет, хотя наверно да на 51 процент)))

 

 

avo74i2
Offline
Зарегистрирован: 25.03.2016

Спасибо за советы и помощ) все сразу выучить не получится конечно) но я стараюсь) да и учить на практике лучше получается)

alex0
Offline
Зарегистрирован: 14.12.2015
 
// Скетч тахометр мотоцикла
 
int kat = 15; // COIL
int greenLED1 = 1;
int greenLED2 = 2;
int greenLED3 = 3;
int greenLED4 = 4;
int greenLED5 = 5;
int yellowLED6 = 6;
int yellowLED7 = 7;
int redLED8 = 8;
int PRM = 0;
int a=0;
int time1=0;   // ????  как ты в 4 байта запихаешь 8 байт???
int time2=0;    // ???? тоже самое, зачем две переменные, одной хватит как я писал
 
void setup() {
  // Инициализируем цифровые вход/выход
  pinMode(kat, INPUT);  // катушка Coil по англиски
  pinMode(greenLED1, OUTPUT);
  pinMode(greenLED2, OUTPUT);
  pinMode(greenLED3, OUTPUT);
  pinMode(greenLED4, OUTPUT);
  pinMode(greenLED5, OUTPUT);
  pinMode(yellowLED6, OUTPUT);
  pinMode(yellowLED7, OUTPUT);
  pinMode(redLED8, OUTPUT);
}
 
 
void loop() {
 
 
 
  if (digitalRead(kat) == LOW && a == 0)    // если на катушке сигнал low1
  {time1=micros();   } // Скобки не нужны, зачем micros если хватит и millis ??
  if (digitalRead(kat) == HIGH ) //если на катушке  сигнал high
  {a=1;}  // Скобки не нужны, для кого я код писал
   if (digitalRead(kat) == LOW && a == 1)    // если на катушке сигнал low2
  {time2=micros()-time1;  
  PRM = 60000/time2;
   a=0;}
 
// Что за огород???? ппц. оптимизируй, 
 
if (PRM<=1000)
{digitalWrite(greenLED1, HIGH);}
 
if (PRM > 1000 &&  PRM <= 2000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);}
 
  if (PRM > 2000 &&  PRM <= 3000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);   }
 
  if (PRM > 3000 &&  PRM <= 4000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);    }
// Килдык
  if (PRM > 4000 &&  PRM <= 5000) 
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);}
 
  if (PRM > 5000 &&  PRM <= 6000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
  }
  if (PRM > 6000 &&  PRM <= 7000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
    digitalWrite(yellowLED7, HIGH);
  }
  if (PRM > 7000 &&  PRM <= 8000)
{
  digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
    digitalWrite(yellowLED7, HIGH);
    digitalWrite(redLED8, HIGH);
  }
 
  delay(500);   // Аааааааааааааа
 
 
  digitalWrite(greenLED1, LOW);
  digitalWrite(greenLED2, LOW);
  digitalWrite(greenLED3, LOW);
  digitalWrite(greenLED4, LOW);
  digitalWrite(greenLED5, LOW);
  digitalWrite(yellowLED6, LOW);
  digitalWrite(yellowLED7, LOW);
  digitalWrite(redLED8, LOW);
}
alex0
Offline
Зарегистрирован: 14.12.2015

avo74i2 пишет:

Спасибо за советы и помощ) все сразу выучить не получится конечно) но я стараюсь) да и учить на практике лучше получается)

 

Сам это всё проходил, до сих пор та страница в быстрых закладках))

avo74i2
Offline
Зарегистрирован: 25.03.2016

все проходили) скорей бы пройти уже))

avo74i2
Offline
Зарегистрирован: 25.03.2016
int coil = 14;
int greenLED1 = 1;
int greenLED2 = 2;
int greenLED3 = 3;
int greenLED4 = 4;
int greenLED5 = 5;
int yellowLED6 = 6;
int yellowLED7 = 7;
int redLED8 = 8;


void setup() {
  // Инициализируем цифровые вход/выход
  pinMode(coil, INPUT);
  pinMode(greenLED1, OUTPUT);
  pinMode(greenLED2, OUTPUT);
  pinMode(greenLED3, OUTPUT);
  pinMode(greenLED4, OUTPUT);
  pinMode(greenLED5, OUTPUT);
  pinMode(yellowLED6, OUTPUT);
  pinMode(yellowLED7, OUTPUT);
  pinMode(redLED8, OUTPUT);
}


void loop() {
int PRM = 0;
int a;



if (digitalRead(coil) == LOW && a == 0) long time = millis();
if (digitalRead(coil) == HIGH)  a =1;
if (digitalRead(coil) == LOW && a == 1) 
{
time = millis() - time;
PRM = 60000 / time;
a = 0;
}
if (PRM<=1000)
{digitalWrite(greenLED1, HIGH);}

if (PRM > 1000 &&  PRM <= 2000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);}

  if (PRM > 2000 &&  PRM <= 3000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);   }

  if (PRM > 3000 &&  PRM <= 4000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);    }

  if (PRM > 4000 &&  PRM <= 5000) 
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);}

  if (PRM > 5000 &&  PRM <= 6000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
  }
  if (PRM > 6000 &&  PRM <= 7000)
{ digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
    digitalWrite(yellowLED7, HIGH);
  }
  if (PRM > 7000 &&  PRM <= 8000)
{
  digitalWrite(greenLED1, HIGH);
    digitalWrite(greenLED2, HIGH);
    digitalWrite(greenLED3, HIGH);
    digitalWrite(greenLED4, HIGH);
    digitalWrite(greenLED5, HIGH);
    digitalWrite(yellowLED6, HIGH);
    digitalWrite(yellowLED7, HIGH);
    digitalWrite(redLED8, HIGH);
  }

  delay(500);


  digitalWrite(greenLED1, LOW);
  digitalWrite(greenLED2, LOW);
  digitalWrite(greenLED3, LOW);
  digitalWrite(greenLED4, LOW);
  digitalWrite(greenLED5, LOW);
  digitalWrite(yellowLED6, LOW);
  digitalWrite(yellowLED7, LOW);
  digitalWrite(redLED8, LOW);
}

 

avo74i2
Offline
Зарегистрирован: 25.03.2016

чет ему 36 строка не нравится( 

 
exit status 1
'time' was not declared in this scope
 
alex0
Offline
Зарегистрирован: 14.12.2015

avo74i2 пишет:

чет ему 36 строка не нравится( 

 
exit status 1
'time' was not declared in this scope
 

 

задаешь переменную не там. 

32 строка, убери long, и задай переменную вначале со всеми осталными.

Эта ошибка значит что переменная не задекларированна)

avo74i2
Offline
Зарегистрирован: 25.03.2016

все задекларировал)) а без long что плохого будет?) micros не влезет а millis влезет?) и что такое килдык))?

alex0
Offline
Зарегистрирован: 14.12.2015

avo74i2 пишет:

все задекларировал)) а без long что плохого будет?) micros не влезет а millis влезет?) и что такое килдык))?

 

зачем микросекунды если и с миллисекундами точность достаточно для твооей версии тахометра, при 8000 тысячах оборотов один оборот КВ происходит за 7 милисекунд, 

дальше, int рассчитан на макс значение 32 768 соответсвтенно твой скетч начнет неккоректно работать через 32.7 секунды, а лонг хватит на 2,147,483,648 милисекунд или 2147483 секунд.  

Килдык значит что вместо того чтобы писать огромный код для каждого промежутка оборотов можно его оптимизировать до 10 строк))

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

avo74i2, поздравляю с начинанием. Очень неплохо для начала.

А теперь давайте обдумаем ваш вариант. Вы же хотите как на картинке, чтобы светодиодики зажигались по кругу в зависимости от оборотов, так? И ещё один моментик: 3000 оборотов, всяко больше 2000 или даже 1000, так? То есть, если мы проверили и узнали что оборотов больше 5000, то зачем проверять меньшие значения "ранее" (как у вас)?

Предлагаю пойти "обратным счетом" и начинать с больших цифирек, типа такого:

if (PRM > 8000){  digitalWrite(redLED9, HIGH);}
else           {  digitalWrite(redLED9, LOW); }

if (PRM > 7000){  digitalWrite(redLED8, HIGH);}
else           {  digitalWrite(redLED8, LOW); }

if (PRM > 6000){  digitalWrite(redLED7, HIGH);}
else           {  digitalWrite(redLED7, LOW); }

if (PRM > 5000){  digitalWrite(redLED6, HIGH);}
else           {  digitalWrite(redLED6, LOW); }

if (PRM > 4000){  digitalWrite(redLED5, HIGH);}
else           {  digitalWrite(redLED5, LOW); }

if (PRM > 3000){  digitalWrite(redLED4, HIGH);}
else           {  digitalWrite(redLED4, LOW); }

if (PRM > 2000){  digitalWrite(redLED3, HIGH);}
else           {  digitalWrite(redLED3, LOW); }

if (PRM > 1000){  digitalWrite(redLED2, HIGH);}
else           {  digitalWrite(redLED2, LOW); }

if (PRM > 0){  digitalWrite(redLED1, HIGH);}
else        {  digitalWrite(redLED1, LOW); }

Стоит заметить, что все блоки стали как-бы "одинаковы", что навевает мыслю о "повторяющихся действиях", которые можно запихнуть в цикл.. нет? А давайте попробуем (да и ножки подобраны "подряд", я вам ещё добавил 9 пин..):

unsigned char led   = 9;
int           level = 8000;
do{
  if (PRM > level){  digitalWrite(led, HIGH);}
  else           {  digitalWrite(led, LOW); }
  level = level - 1000;
  led = led - 1;
} while( level >= 0);

Верно? Проверьте. Ну и теперь наглядно видно, что:

1. функция digitalRead() вызывается дважды, только с разным значением уровня, который в обоих случаях есть константа. В "С" есть тернарный оператор "?" который как раз возвращает одно из двух значений и можно с его помощью избавиться от второго вызова ..

2. Переменные level и i изменяют свои значения уменьшением от исходного, и обе они локальны, то есть кроме этого цикла и в общем-то и не нужны в скетче в других функциях .. у МК есть замечательные регистровые команды для таких действий и "С" их тоже умеет делать!

3. У нас есть некий "счетчик цикла" и в "С" есть замечательный цикл "for" как раз для таких повторов, ИТОГО:

unsigned char led=9;
int           level = 8000;
for(; level>=0; led--, level -= 1000){
  digitalWrite(led, (RPM>level? HIGH : LOW));
}

Ну вот. Теперь код не содержит большой избыточности, а константы компилятор посчитает и оптимизирует самостоятельно.

Так - лучше? :)

alex0
Offline
Зарегистрирован: 14.12.2015

Классно вы всё раззжевали, но мне кажется для ТС сложновато будет))

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

9 светодиод я вам добавил для того, чтобы отслеживать состояние "мотор выключен вовсе" .. в вашем варианте будет светиться led1.

Ну и ещё давайте внимательно посмотрим на ваш loop().

Вы измеряете период прихода метки за 1 оборот .. и, в то время пока у вас метки ещё нет .. светодиоды будут "переключаться" в странные режимы, ибо переменная RPM обнуляется в начале каждого вызова loop(). А это для вашего скетча - микросекунды.

Вы точно ТАК хотели? А может стоит не "дрочить" светодиоды попусту, а вызывать этот кусок по изменению их состояния только тогда, когда "замер произведен" и что зажигать, а что гасить уже стало понятно ..

Давайте попробуем:

void loop() {
  int PRM = 0;
  int a;

  if (digitalRead(coil) == LOW && a == 0) long time = millis();
  if (digitalRead(coil) == HIGH)  a =1;
  if (digitalRead(coil) == LOW && a == 1) 
  {
    time = millis() - time;
    PRM = 60000 / time;
    a = 0;
    { // получили обороты - можно менять картинку:
      unsigned char led=9;
      int           level = 8000;

      for(; level>=0; led--, level -= 1000)
        digitalWrite(led, (RPM>level? HIGH : LOW));
    }
  }
} // end loop()

И снова обнаруживаем аж 3 чтения датчика "подряд" .. с разрывом в пару микросекунд (Wiring - большой торомоз, но не спасает!). А если сделать наоборот? Сначала получить значение, а потом уже решать что с ним делать? Типа так:

unsigned long time;
void loop() {
  int PRM = 0;
  int a;

  switch (digitalRead(coil) )
  {
    case HIGH: a=1; break;
    case LOW:
      if( a == 0 ){ time = millis(); }
      else{
        time = millis() - time;
        PRM = 60000 / time;
        a = 0;
        { // получили обороты - можно менять картинку:
          unsigned char led=9;
          int           level = 8000;

          for(; level>=0; led--, level -= 1000)
          digitalWrite(led, (RPM>level? HIGH : LOW));
        }
      }
  }
} // end loop()

Так ещё лучше, нет? :)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну и напоследок. setup() тоже содержит установку пинов "подряд" .. это тоже можно запихать в цикл и упростить программку. Оставляю как "домашнее задание". Кстати, тогда и переменных потребуется определять меньше.

Ждем окончательный вариант вашего скетча. :)

avo74i2
Offline
Зарегистрирован: 25.03.2016

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

avo74i2
Offline
Зарегистрирован: 25.03.2016

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

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Это не проблема. Заведите массив для хранения номеров ножек и пользуйте их "подряд". Можно сразу, в таком случае хранить не номера ножек а правильные пары {порт, бит} и отказаться от тормозных функций digitalWrite() и digitalRead(). Программа в целом станет ещё и меньше по размеру и легко влезет даже в самую маленькую тиньку.

avo74i2
Offline
Зарегистрирован: 25.03.2016

Всем привет! сегодня собрал тестовую версию тахометра, подключил 5 светодиодов (вместо 14) и вместо катушки на 15 пин воткнул землю через кнопку(чтобы симулировать ее работу). Появились вопросы....вообщем то тыкаю кнопку и светодиоды не зажигаются , скорей всего потому что на смену сигналу LOW не приходит HIGH. вопрос почему? 

int coil = 15;
void setup() {
  pinMode(coil, INPUT);
  digitalWrite(coil, HIGH);
}
в аналоговом выводе есть возможность подключать подтягивающий резистор? меряю напряжение между землей и 15 пином -напряжение отсутствует. Что я упустил подскажите кто может)
yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Как вариант индикации

  int val = (RPM/1000);
  for (int i=0; i < 8; i++){
    if (i<=val){   
      digitalWrite(i,HIGH);//зажигаем      
    }
    else
    {
      digitalWrite(i,LOW);//гасим
    }
  }

 

avo74i2
Offline
Зарегистрирован: 25.03.2016

Чтото я не совсем понял, или ты меня не понял) вот полностью мой код, так понятней будет 


int coil = 15;
int ledmass[14]={0,1,2,3,4,5,6,7,8,9,10,11,12,14};

 
void setup() {
  pinMode(coil, INPUT);
  digitalWrite(coil, HIGH);
for (int i=0; i<15; i++) {
 pinMode(ledmass[i], OUTPUT);}
  
    for (int i=0; i<15; i++){
      digitalWrite(ledmass[i],HIGH);
      delay(300);}
    
   for (int i=0; i<15; i++){
      digitalWrite(ledmass[i],LOW);}
}


void loop() {

int PRM = 0;
int a=0;
long time;



  if (digitalRead(coil) == LOW && a == 0)    
  {time=millis();   } 
  if (digitalRead(coil) == HIGH )
  {a=1;}
   if (digitalRead(coil) == LOW && a == 1)   
{time = millis()-time;  
  PRM = 60000/time;
   a=0;}

   unsigned char i = 14;
   int level = 7000;
   do{
    if (PRM>level){digitalWrite(ledmass[i],HIGH);}
    else          {digitalWrite(ledmass[i],LOW);}
    level=level-500;
    i=i-1;
   }while(i>=0);

}

 

avo74i2
Offline
Зарегистрирован: 25.03.2016

на данный момент после загрузки скетча все светодиоды почередно зажигаются но не гаснут, если удаляю 37-44 строки то после запуска скетча они все поочередно загораются гаснут ну и все) что то в этих строках напутал я, все время 7000 оборотов постоянно думает мой тахометр) помогайте искать логическую ошибку)

James
Offline
Зарегистрирован: 26.02.2016

поставь строку 35 на  45. у тебя вышло что твое условие не вложенное 

avo74i2
Offline
Зарегистрирован: 25.03.2016

Понял, теперь гаснут но на кнопку не реагируют)...и еще такой вопрос: почему когла плату отключаю от питания(ЮСБ) и подключив снова начинает выполнятся скетч мигания светодиодом, который был залит изготовителем? а мой пока не залью снова не стартует

alex0
Offline
Зарегистрирован: 14.12.2015

А ты кнопку с частотой хотябы 200 тактов в секунду можешь нажимать? 

http://arduino.ru/forum/obshchii/prizrachnyi-blink

avo74i2
Offline
Зарегистрирован: 25.03.2016

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

avo74i2
Offline
Зарегистрирован: 25.03.2016

да мне хотя бы чтоб один-два диода загорались и гасли.... первый вкл при 500 об\мин.  это 8 раз в секунду а не 200...да и я специально для этого дела чтобы успевать тыкать добавил нолик к минуте тем самым делю 600000 на милис. но сейчас проблема не в этом, а в том что они либо сразу все мигают, либо все сразу горят либо ваще ни че не происхоит, башка кипит весь день уж с этим вожусь

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

avo74i2 пишет:
но сейчас проблема не в этом, а в том что они либо сразу все мигают, либо все сразу горят либо ваще ни че не происхоит, башка кипит весь день уж с этим вожусь
Размотай loop в линию и тогда все поймешь

//1 проход   ***** предположим пин coil = LOW ******
int PRM = 0;
int a=0;
long time;
if (digitalRead(coil) == LOW && a == 0)  //это условие выполняется
  {time=millis();   } 
if (digitalRead(coil) == HIGH ) //это условие не выполняется
  {a=1;}
if (digitalRead(coil) == LOW && a == 1)   //это условие не выполняется
{time = millis()-time;  PRM = 60000/time; a=0;}
do {}while(); // здесь ты что-то зажигаешь

//2 проход   ***** предположим пин coil = HIGH ******
int PRM = 0;
int a=0;
long time;
if (digitalRead(coil) == LOW && a == 0)    //это условие не выполняется
  {time=millis();   } 
if (digitalRead(coil) == HIGH ) //это условие выполняется
  {a=1;}
if (digitalRead(coil) == LOW && a == 1)   //это условие не выполняется
{time = millis()-time;  PRM = 60000/time; a=0;}
do {}while(); // здесь ты что-то зажигаешь

//3 проход   ****** предположим пин coil снова LOW ******
int PRM = 0;
int a=0;
long time;
if (digitalRead(coil) == LOW && a == 0)  //это условие выполняется
  {time=millis();   } 
if (digitalRead(coil) == HIGH ) //это условие не выполняется
  {a=1;}
if (digitalRead(coil) == LOW && a == 1)   //это условие не выполняется
{time = millis()-time;  PRM = 60000/time; a=0;}
do {}while(); // здесь ты что-то зажигаешь

//и т.д. третье условие никогда не выполняется

 

avo74i2
Offline
Зарегистрирован: 25.03.2016

спасибо что тыкнул куда глядеть, я и сам понял что в этом куске проблема, но вот так и не дошло как ее решить... думаю надо сделать так чтобы если услове не выполняется то следущее не проверялось, а снова проверялось первое пока не станет верным, как этого добиться? делать каждое следущее условие действием предыдущего? или есть какие то другие варианты не с оператором if?

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Andy, верно. потому что a=0 стоит в самом начале и сбрасывается КАЖДЫЙ раз. Его надо вынести в глобал и устанавливать один раз по запуску всего скетча. Тогда в процессе работы это будет нормальный флаг изменения состояния конечного автомата. :)

P.S. посмотрел .. в предложенном мною варианте так и прописано. "a" не задается внутри loop().

avo74i2
Offline
Зарегистрирован: 25.03.2016

Подскажите пожалуйста где я могу прочитать про такое выражение : (RPM>level? HIGH : LOW) 

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

T.Rook
Offline
Зарегистрирован: 05.03.2016

avo74i2 пишет:

Подскажите пожалуйста где я могу прочитать про такое выражение : (RPM>level? HIGH : LOW) 

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

Искать: оператор ? Си

ВИКИ 1  опрераторы в Си

ВИКИ 2 Тернарная условная операция

MagicianT
Offline
Зарегистрирован: 03.10.2015

Странно, что никто не посоветовал изучить ардуиновский встроеный пример, Файл/Примеры/7-дисплей/барГраф. Там в точности алгоритм, который тут как велосипед, изобретается.

avo74i2
Offline
Зарегистрирован: 25.03.2016

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

MagicianT
Offline
Зарегистрирован: 03.10.2015

Так импульсы надо по другому считать, через прерывание, так точнее будет - attachInterrupt(). Примеры поищите сами, по теме раходомеры или счётчики оборотов, их пруд пруди.

alex0
Offline
Зарегистрирован: 14.12.2015

А я вот так считал обороты,довольно точно и  никаких глюков, тестировал с помощью NE555

tahoHigh = pulseIn(tahoPin, HIGH, 500000); // Время срабатывания катушки зажигания в микросекундах
  tahoLow = pulseIn(tahoPin, LOW, 500000);  // Время паузы катушки зажигания в микросекундах

  if (tahoHigh != lastTahoHigh && tahoLow != lastTahoLow) {
    lastTahoHigh = tahoHigh;
    lastTahoLow = tahoLow;
    RPM = 30000000 / (tahoHigh + tahoLow);  // обороты в мниуту = 60 * 1000 * 1000 / (длительность такта) * 2 такта за один оборот

 

slmvd
Offline
Зарегистрирован: 20.09.2016

alex0 пишет:

А я вот так считал обороты,довольно точно и  никаких глюков, тестировал с помощью NE555

tahoHigh = pulseIn(tahoPin, HIGH, 500000); // Время срабатывания катушки зажигания в микросекундах
  tahoLow = pulseIn(tahoPin, LOW, 500000);  // Время паузы катушки зажигания в микросекундах

  if (tahoHigh != lastTahoHigh && tahoLow != lastTahoLow) {
    lastTahoHigh = tahoHigh;
    lastTahoLow = tahoLow;
    RPM = 30000000 / (tahoHigh + tahoLow);  // обороты в мниуту = 60 * 1000 * 1000 / (длительность такта) * 2 такта за один оборот

 

можно увидеть весь код?

alex0
Offline
Зарегистрирован: 14.12.2015

slmvd пишет:

alex0 пишет:

А я вот так считал обороты,довольно точно и  никаких глюков, тестировал с помощью NE555

tahoHigh = pulseIn(tahoPin, HIGH, 500000); // Время срабатывания катушки зажигания в микросекундах
  tahoLow = pulseIn(tahoPin, LOW, 500000);  // Время паузы катушки зажигания в микросекундах

  if (tahoHigh != lastTahoHigh && tahoLow != lastTahoLow) {
    lastTahoHigh = tahoHigh;
    lastTahoLow = tahoLow;
    RPM = 30000000 / (tahoHigh + tahoLow);  // обороты в мниуту = 60 * 1000 * 1000 / (длительность такта) * 2 такта за один оборот

 

можно увидеть весь код?

Да, только он испытывался только в лабораторных условиях.

// Скетч бортового компьютера  для ВАЗ 21013 //
// alex0@bk.ru //
// 2016 //
// EEPROM //
// 100-150 Настройки
// 1000 - записать в ЕЕПРОМ, 1001 - минимальный угол серво подсоса, 1002 - максимальный угол серво подсоса
// 901 - количество срабатываний ошибки номер 1, 902 - кол сраб ошибки номер 2, 903 - кол сраб ошибки номер 3
// 200+1 номер ошибки, 200+2 обороты, 200+3 температура, 200+4 угол серво, 200+5 напряжение....
// Занятые буквы i, e, b, x, a

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include <EEPROM.h>

Servo servopodsos; // Назначаем серво подсоса
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Назначаем дисплей

byte err[1000];  // Массив ошибок
int errMax = 0;  // Число ошибок
byte errSave = 0; // Сохранять ли в ЕЕПРОМ
/* Ошибки:
  3 - Низкая стабильность при максимальных оборотах ХХ
*/

byte saveSettings = 0;
byte a = 0;

int regulPodsosPin = 0;  // Пин  переменного резистора
int regulPodsos[5];  // Переменная считывания резистора
byte stepPodsos; // Увеличить или уменьшить угол
byte lastStepPodsos; // Последнее изменение угла заслонки (только авто)
int podsosServoPin = 30;  // Пин серво подсоса
int ygolPodsos = 150;  // Угол серво подсоса
byte podsosServoMin;  // Угол серво мин
byte podsosServoMax;  // Угол серво макс
byte autoPodsos = 0; // Автоматический подсос до температуры двигателя 70*
byte manualPodsos = 2; // Ручное включение подсоса

byte tahoPin = 26;  // Пин с катушки зажигания через оптрон
long tahoHigh = 0;  // Длительность сигнала HIGH
long lastTahoHigh = 0; //Предыдущая Длительность сигнала HIGH
long tahoLow = 0;   // Длительность сигнала LOW
long lastTahoLow = 0;   //Предыдущая Длительность сигнала LOW
int RPM = 0;    // Обороты коленвала в минуту
int RPMmas[4];  // Массив значений оборотов двигателя за один оборот КВ
int RPMrazn[3]; // Разница между значениями оборотов двигателя за один оборот КВ
int RPMraznF; // Сумма разниц между значениями оборотов двигателя за один оборот КВ
byte b = 0;
byte e = 0;
int stabMin = 70; // Если нестабильность ниже этого числа, работа двигателя стабильна.
int stabMax = 120; // Если нестабильность выше этого числа, работа двигателя НЕстабильна.
int RPMmax = 5000; // Максимальные обороты автоподсоса, зависят от температуры
int RPMmin = 0; // Минимальные обороты автоподсоса, зависят от температуры

int temp = 0;  // Температура двигателя
byte tempPin = 1; // Пин считывания температуры

byte button1 = 22;
byte reset = 40;  // Пин перезагрузки платы
byte reboot;  // Бит перезагрузки

int beeper = 0;  // Бит пищалки
byte beeperPin = 38;  // Пин пищалки
int beeperFreq = 1000; // Частота пищалки

// Таймеры
unsigned long timer101 = 0; // Таймер прерываний  1 на 0.1 каждые секунды
unsigned long timer205 = 0; // Таймер прерываний  2 на 0.1 каждые секунды
byte timer1 = 0;
byte timer2 = 0;
int resetTimer = 10000; // Обратный отсчет до перезагрузки

void setup() {

  servopodsos.attach(podsosServoPin);  // Назначаем серво на подсос
  lcd.begin(20, 4); // Назначаем размер дисплея

  lcd.setCursor(7, 1);
  lcd.print("LOADING");

  // Настройки в EEPROM

  if (EEPROM.read(1000) == 255 && EEPROM.read(1001) == 255 && EEPROM.read(1002) == 255 ) {  // Проверка первый ли запуск скетча
    EEPROM.write(1000, 0);  // Отключение запустит при первом старте
    EEPROM.write(1001, 15);  // Сохранение минимального угла серво подсоса
    EEPROM.write(1002, 165); // Сохранение максимального угла серво подсоса
  }
  if (EEPROM.read(1000) == 0 && EEPROM.read(1001) != 0 && EEPROM.read(1002) != 0 ) { // Если не первый запуск взять значения углов подсоса из памяти
    podsosServoMin = EEPROM.read(1001);
    podsosServoMax = EEPROM.read(1002);
  }

  // Загрузка настроек
  if (EEPROM.read(100) == 1) {
    stabMin = EEPROM.read(101);
    stabMax = EEPROM.read(102);
    RPMmax = EEPROM.read(103) * 100;
    RPMmin = EEPROM.read(104) * 100;
    errSave = EEPROM.read(105);
  }

  pinMode(tahoPin, INPUT);
  pinMode(reset, OUTPUT);
  digitalWrite(reset, HIGH);

  tone(beeperPin, beeperFreq, 200); // Сигнал загрузки  tone(pin, frequency, duration)
}
void loop() {
  // НАЧАЛО ЦИКЛА

  // Сохранение настроек

  if (EEPROM.read(100) < 0) {
    EEPROM.write(100, 0);
    EEPROM.write(101, stabMin);
    EEPROM.write(102, stabMax);
    EEPROM.write(103, (RPMmax / 100));
    EEPROM.write(104, (RPMmin / 100));
    EEPROM.write(105, errSave);
  }

  // Проверка таймера
  if ((timer101 + 100) < millis() ) timer1 = 1;
  if ((timer205 + 500) < millis() ) timer2 = 1;


  if (timer2 == 1 ) {


    // Управление подсосом полностью ручное
    if (autoPodsos == 0 || manualPodsos == 2) {
      if ((timer101 + 100) < millis() ) {

        for (int i = 0; i <= 4; i++) {
          regulPodsos[i] = analogRead(regulPodsosPin);
          if (i == 4) {
            regulPodsos[0] =  (regulPodsos[0] + regulPodsos[1] + regulPodsos[1] + regulPodsos[3] + regulPodsos[4]) / 5;
          }
        }

        ygolPodsos = map(regulPodsos[0], 0, 1023, podsosServoMin, podsosServoMax);
        servopodsos.write(ygolPodsos);
        timer101 = millis();
      }
    }

    // Автоматическое управление подсосом
    if (autoPodsos == 1 || manualPodsos == 0) {
      if (RPMraznF > stabMax &&  RPM < RPMmax) {
        ygolPodsos = ygolPodsos + 1;
      }
      if (RPMraznF < stabMin &&  RPM < RPMmax) {
        ygolPodsos = ygolPodsos - 1;
      }
      if (RPMraznF > stabMax &&  RPM > RPMmax) {
        ygolPodsos = ygolPodsos - 1;

        // ERROR START
        err[errMax] = 3; // Ошибка 3;
        errMax++;
        beeper = 100;
        // ERROR END

      }
      if (RPMraznF < stabMin &&  RPM > RPMmax) {
        ygolPodsos = ygolPodsos - 1;
      }
      servopodsos.write(ygolPodsos);
      stepPodsos = 0;
    }
  }
  // Вычисление температуры и установка оборотов ХХ
  temp = analogRead(tempPin);


  //Тахометр
  tahoHigh = pulseIn(tahoPin, HIGH, 100000); // Время срабатывания катушки зажигания в миксросекундах
  tahoLow = pulseIn(tahoPin, LOW, 100000);  // Время паузы катушки зажигания в миксросекундах

  if (tahoHigh != lastTahoHigh && tahoLow != lastTahoLow) {
    lastTahoHigh = tahoHigh;
    lastTahoLow = tahoLow;
    RPM = 30000000 / (tahoHigh + tahoLow);  // обороты в мниуту = 60 * 1000 * 1000 / (длительность такта) * 2 такта за один оборот

    if (RPM != RPMmas[e]) {
      switch (e) {
        case 3:
          e = 0;
          break;
        default:
          e++;
      }
      RPMmas[e] = RPM;
      if (e == 3) {

        for (b = 0; b <= 2; b++) {
          RPMrazn[b] = RPMmas[b + 1] - RPMmas[b]; // Если RPMrazn меньше нуля обороты растут
          RPMraznF = RPMraznF + RPMrazn[b]; //
        }
      }
    }
  }


  // Перезагрузка
  if (reboot == 1) resetTimer = (millis() + 10000); // Если нужна перезагрузка то включить отсчет
  if (resetTimer < millis() && reboot == 1 ) digitalWrite(reset, LOW); // Перезагрузка по окончании таймера


  // ВЫВОД НА ЭКРАН
  if ( timer2 == 1 ) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(ygolPodsos);
    lcd.setCursor(4, 1);
    lcd.print(RPM);


    if (reboot == 1) {
      lcd.setCursor(1, 2);
      lcd.print(" Reset after ");
      lcd.print((resetTimer - millis()) / 1000);
    }
  }

  // Обнуление таймера
  if (timer1 == 1) {
    timer1 = 0;
    timer101 = millis();
  }
  if (timer2 == 1) {
    timer2 = 0;
    timer205 = millis();
  }

  // BEEPER
  if (beeper > 0) {
    tone(beeperPin, beeperFreq, beeper);
    beeper = 0;
  }

  // КОНЕЦ ЦИКЛА
}

 

Gameking
Offline
Зарегистрирован: 10.05.2019

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