поставил датчик на двигатель с плавной регулировкой оборотов на границе 250+-10 оборотов реле начинает пульсировать и задержка 30 сек не действует. время задержки при запуске работает хорошо
#define rele 10
volatile unsigned long time = 0; //Время срабатывания датчика
volatile unsigned long time_old = 0; //предыдущее время
int speeed = 0;
void setup(){
delay(120000); //подождем 2 мин на начальном этапе
Serial.begin(9600);
attachInterrupt(0, impuls, RISING); //Прерывание по нарастающему фронту на D2
pinMode(rele, OUTPUT);
digitalWrite(rele, LOW);
}
void loop(){
speeed = 60000/(time-time_old); //вычисляем скорость в об/мин
надо чтоб реле сработало на 250 об, увело актуатор и ждало 30 сек после этого делало проверку сколько оборотов если меньше 250 возврашало реле в начальное положение
в данный момент когда обороты 250-260 реле пульсирует меняет полярность
показывает постоянную скорость (двигатель зафиксирован на 380 об поднял для удобства регулировки а в проге установил порог 450) примерно через определенный период происходит скачек380.... -1....5000.....15000......-5000....-5500.....380 этот скачек длительностью примерно 3-5 сек
не может быть у него быть больше 32000 оборотов. стало быть может ошибка в монтаже, или пин не тот подключил и это наводки (у себя проверял когда хронометр делал на наводки хорошо реагирует ардуина)
1. схему не меняли? пины подключены туда же куда и ранее? датчик на 2 (D2), а реле на 10
2. землю датчика подключили?
3. датчик не меняли?
4. Показания вашего тахометра соответствуют показаниям в терминале, он же монитор порта
5. эти значения "380.... -1....5000.....15000......-5000....-5500.....380" были в терминале? если да то "Да скорость показывает правильно" не может быть верно, если конечно ваш тахометр не показывает тоже самое, что врядли. или вы тут писали о тахометре. впреть попрошу конкретнее писать, а то непонятно кто именно правильно показывает скорость
6. питание тоже? то есть внешнее питание подаете на Vin?
Схема подключения без изменений. Сравнивал табло датчика и данные с монитором и ручным измерителем скорости все показывают точное число оборотов отклонения показаний +- 3 оборота между всеми измерителями
а скачки показывает только терминал компа и в это время реле начинает трещать
Схема подключения без изменений. Сравнивал табло датчика и данные с монитором и ручным измерителем скорости все показывают точное число оборотов отклонения показаний +- 3 оборота между всеми измерителями
а скачки показывает только терминал компа и в это время реле начинает трещать
загрузите этот код. реле не будет ничего щелкать. просто проверить измерение скорости ардуиной. сравните показания в терминале и на своем тахометре. желательно со скриншотами.должны быть одинаковые значения плюс минус разброс
Да тут как бы вообще подход лучше другой использовать. Не время между срабатываниями вычислять, а за определенный промежуток времени надо срабатывания считать.
максим не совсем понял каким образом у вас посчитается количество импульсов? за 200мс при максимальных 300об/мин (5об/с) посчитается 1 импульс, при меньших не факт вообще что поймает
павел попробуйте код что я выложил. измеряет правда раз в 6 сек для большего количества импульсов. хотя не знаю насколько быстро разгоняется ваш мотор, и может что 6 сек будет критичным. если да то только время считать. буду дальше думать как избавиться от ошибок. плохие контакты мы уже исключили насколько понял
хотя точность в нем низкая. лучше наверно сразу думать в сторону улучшения программы
01
#define rele 10
02
volatile unsigned
long
time = 0;
//Время срабатывания датчика
03
volatile unsigned
long
time_old = 0;
//предыдущее время
04
int
speeed = 0;
05
06
void
setup
(){
07
Serial
.begin(9600);
08
attachInterrupt(0, impuls, RISING);
//Прерывание по нарастающему фронту на D2
09
pinMode(rele, OUTPUT);
10
digitalWrite(rele, LOW);
11
delay(120000);
//подождем 2 мин на начальном этапе
12
}
13
void
loop
(){
14
speeed = 60000/(time-time_old);
//вычисляем скорость в об/мин
15
if
(speeed >= 250){
16
digitalWrite(rele, HIGH);
17
//delay(30000);
18
}
19
else
{
20
digitalWrite(rele, LOW);
21
}
22
Serial
.println(speeed);
23
}
24
void
impuls(){
// сработал датчик
25
time_old = time;
26
time = millis();
27
}
только сейчас задержка на 30сек закоментирована, и значит не работает, как проверите раскоментируйте
нет изменений. подключаю питание через несколько сек подаеться питание на реле и оно включаеться.
ждет 2 мин и после начинает нервно пульсировать доли сек +-+-+-+-+.
плата сгорела гдето провод коротнул пошел покупать новую
Задержку перенесите в начало функции setup.
да кстати лучше перенести в начало задержку
поставил датчик на двигатель с плавной регулировкой оборотов на границе 250+-10 оборотов реле начинает пульсировать и задержка 30 сек не действует. время задержки при запуске работает хорошо
Так она (задержка) же у вас //закомментирована...
надо чтоб реле сработало на 250 об, увело актуатор и ждало 30 сек после этого делало проверку сколько оборотов если меньше 250 возврашало реле в начальное положение
в данный момент когда обороты 250-260 реле пульсирует меняет полярность
как это убрать
Ну я же вам написал выше. Надо раскоментировать задержку. А именно:
1
//delay(30000);
заменить на
1
delay(30000);
то есть убрать две палочки.
И почитайте Вставка программного кода в тему/комментарий.
павел я же писал. надо раскоментировать задержку когда протестите
я не програмист и терминологии не знаю
раскоментировал задержку реле не включилось (не сработало) осталось в начальном положении
закоментировал обратно работает но на границе оборотов реле начинает пульсировать
может надо вставить время в эту строку?
digitalWrite(rele, LOW .... время);
01
#define rele 10
02
volatile unsigned
long
time = 0;
//Время срабатывания датчика
03
volatile unsigned
long
time_old = 0;
//предыдущее время
04
int
speeed = 0;
05
06
void
setup
(){
07
delay(120000);
//подождем 2 мин на начальном этапе
08
Serial
.begin(9600);
09
attachInterrupt(0, impuls, RISING);
//Прерывание по нарастающему фронту на D2
10
pinMode(rele, OUTPUT);
11
digitalWrite(rele, HIGH);
12
13
}
14
void
loop
(){
15
speeed = 60000/(time-time_old);
//вычисляем скорость в об/мин
16
if
(speeed >= 250){
17
digitalWrite(rele, LOW);
18
delay(30000);
19
}
20
else
{
21
digitalWrite(rele, HIGH);
22
}
23
Serial
.println(speeed);
24
}
25
void
impuls(){
// сработал датчик
26
time_old = time;
27
time = millis();
28
}
пробуйте
при достижении 250-300об реле не сработало
после подключения ждет 2 мин потом каждые 30 сек посылает одиночный сигнал на реле один щелчок
при повышении оборотов довел до 600 реле не срабатыват.
проверьте подключение датчика
в терминале ардуины скорость показывает?
выводит скорость раз в 30 сек
убрал задержку. на мониторе показывает скорость онлайн
если раз в 30 сек значит считает что скорость постоянно выше 250об
показывает что меньше
показывает постоянную скорость (двигатель зафиксирован на 380 об поднял для удобства регулировки а в проге установил порог 450) примерно через определенный период происходит скачек380.... -1....5000.....15000......-5000....-5500.....380 этот скачек длительностью примерно 3-5 сек
а минусы это такие показания в терминале?
так давайте поконкретнее. скорость в терминале показывает правильно или нет?
Минусы могут быть по одной причине - переполнения переменной
int
speeed
, обьявите ее тоже какunsigned
long
.не может быть у него быть больше 32000 оборотов. стало быть может ошибка в монтаже, или пин не тот подключил и это наводки (у себя проверял когда хронометр делал на наводки хорошо реагирует ардуина)
надо проверять монтаж
Да скорость показывает правильно
давайте все уточним:
1. схему не меняли? пины подключены туда же куда и ранее? датчик на 2 (D2), а реле на 10
2. землю датчика подключили?
3. датчик не меняли?
4. Показания вашего тахометра соответствуют показаниям в терминале, он же монитор порта
5. эти значения "380.... -1....5000.....15000......-5000....-5500.....380" были в терминале? если да то "Да скорость показывает правильно" не может быть верно, если конечно ваш тахометр не показывает тоже самое, что врядли. или вы тут писали о тахометре. впреть попрошу конкретнее писать, а то непонятно кто именно правильно показывает скорость
6. питание тоже? то есть внешнее питание подаете на Vin?
Схема подключения без изменений. Сравнивал табло датчика и данные с монитором и ручным измерителем скорости все показывают точное число оборотов отклонения показаний +- 3 оборота между всеми измерителями
а скачки показывает только терминал компа и в это время реле начинает трещать
Схема подключения без изменений. Сравнивал табло датчика и данные с монитором и ручным измерителем скорости все показывают точное число оборотов отклонения показаний +- 3 оборота между всеми измерителями
а скачки показывает только терминал компа и в это время реле начинает трещать
загрузите этот код. реле не будет ничего щелкать. просто проверить измерение скорости ардуиной. сравните показания в терминале и на своем тахометре. желательно со скриншотами.должны быть одинаковые значения плюс минус разброс
01
volatile unsigned
long
time = 0;
//Время срабатывания датчика
02
volatile unsigned
long
time_old = 0;
//предыдущее время
03
int
speeed = 0;
04
05
void
setup
(){
06
delay(120000);
//подождем 2 мин на начальном этапе
07
Serial
.begin(9600);
08
attachInterrupt(0, impuls, RISING);
//Прерывание по нарастающему фронту на D2
09
}
10
void
loop
(){
11
speeed = 60000/(time-time_old);
//вычисляем скорость в об/мин
12
Serial
.println(speeed);
13
delay(200);
14
}
15
void
impuls(){
// сработал датчик
16
time_old = time;
17
time = millis();
18
}
показания датчика тахометра, монитора и дигитального датчика скорости идентичны разброс +-3 оборота
за период проверки на мониторе(терминале) было 2 одиночных скачка один 3000 второй 5000 после идет стабильно проверка идет уже 5 мин
произошел еще скачек 2307..-1...-1...495...-5536..-1...2727...стабилизировался
странно. у меня пока возникают мысли о некачественных контактах. вы можете их исключить?
скачки разовые через большой промежуток
сейчас переберу все соединения на пайку
да сделайте на пайку. ошибки нестабильные и кажется дело в монтаже. в программе ошибки не вижу пока
а промежуток между ошибками одинаковый или случайный?
случайный
время ошибка
5 с 15000
2с -1
2 с -1
3 с 20000
8с -1...800...1300
3,41 мин 8500
0,42 7500
5,27 15000
0,24 1428
время - срабатывание между ошибками
Я бы попробовал изменить строку 11 из сообщения #77 http://arduino.ru/forum/ishchu-ispolnitelya/napisanie-sketcha-dlya-upravleniya-oborotami-dvigatelya?page=1#comment-52982
Т.е. перед ней запретить прерывания, после неё - разрешить. Предполагаю, что это избавит от резких изменений.
Дело в том, что при вычислении выражения, возникающие прерывания могут сильно попортить значения, учитывая, что значения 4 байтовые.
Попробуйте - это недолго, зато это исключит коллизии использования переменных в loop() и в прерываниях. Не понравится - уберете.
Да тут как бы вообще подход лучше другой использовать. Не время между срабатываниями вычислять, а за определенный промежуток времени надо срабатывания считать.
01
#define rele 10
02
volatile unsigned
long
count = 0;
03
unsigned
int
speeed = 0;
04
05
void
setup
()
06
{
07
delay(120000);
//подождем 2 мин на начальном этапе
08
Serial
.begin(9600);
09
digitalWrite(rele, HIGH);
10
digitalWrite(2, 1);
11
attachInterrupt(0, impuls, RISING);
//Прерывание по нарастающему фронту на D2
12
}
13
14
void
loop
()
15
{
16
static
unsigned
long
millis_prev = 0;
17
unsigned
long
time = millis() - millis_prev;
18
unsigned
int
speeed = count/(60000UL/time);
//вычисляем скорость в об/мин
19
count = 0;
20
Serial
.println(speeed);
21
if
(speeed >= 250)
22
{
23
digitalWrite(rele, LOW);
24
delay(30000);
25
}
26
else
digitalWrite(rele, HIGH);
27
28
delay(200);
29
}
30
31
void
impuls()
// сработал датчик
32
{
33
count++;
34
}
И, кстати, так и не ясно digitalWrite(rele, HIGH) - это реле включено и двигатель раскручивается или наоборот останавливается?
01
volatile unsigned
int
number = 0;
//количество импульсов
02
unsigned
long
time = 0;
//Время начала измерения
03
int
speeed = 0;
04
05
void
setup
(){
06
delay(120000);
//подождем 2 мин на начальном этапе
07
Serial
.begin(9600);
08
attachInterrupt(0, impuls, RISING);
//Прерывание по нарастающему фронту на D2
09
time = millis();
10
}
11
void
loop
(){
12
if
(millis() >= (time+6000)){
//здесь для точности можно будет внести корректировку
13
//измерять будем каждые 6 секунд
14
speeed = number*10;
15
time = millis();
16
number = 0;
17
}
18
19
Serial
.println(speeed);
20
}
21
void
impuls(){
// сработал датчик
22
number++;
23
}
попробуйте скорость корректно считает или нет
максим не совсем понял каким образом у вас посчитается количество импульсов? за 200мс при максимальных 300об/мин (5об/с) посчитается 1 импульс, при меньших не факт вообще что поймает
Да, при таких оборотах не прокатит... значит только высчитавать время между импульсами.
да при HIGH реле включено двигатель работает
при LOW реле выключено двигатель должен остановиться
павел попробуйте код что я выложил. измеряет правда раз в 6 сек для большего количества импульсов. хотя не знаю насколько быстро разгоняется ваш мотор, и может что 6 сек будет критичным. если да то только время считать. буду дальше думать как избавиться от ошибок. плохие контакты мы уже исключили насколько понял
хотя точность в нем низкая. лучше наверно сразу думать в сторону улучшения программы
см. ниже
соберу все программы в кучу. попробуйте 1 чисто для теста
1. считаем обороты за еденицу времени
01
volatile unsigned
int
number = 0;
//количество импульсов
02
unsigned
long
time = 0;
//Время начала измерения
03
int
speeed = 0;
04
05
void
setup
(){
06
delay(120000);
//подождем 2 мин на начальном этапе
07
Serial
.begin(9600);
08
attachInterrupt(0, impuls, RISING);
//Прерывание по нарастающему фронту на D2
09
time = millis();
10
}
11
void
loop
(){
12
if
(millis() >= (time+6000)){
//здесь для точности можно будет внести корректировку
13
//измерять будем каждые 6 секунд
14
speeed = number*10;
15
time = millis();
16
number = 0;
17
}
18
19
Serial
.println(speeed);
20
}
21
void
impuls(){
// сработал датчик
22
number++;
23
}
2. предложение kisoft
01
volatile unsigned
long
time = 0;
//Время срабатывания датчика
02
volatile unsigned
long
time_old = 0;
//предыдущее время
03
int
speeed = 0;
04
05
void
setup
(){
06
delay(120000);
//подождем 2 мин на начальном этапе
07
Serial
.begin(9600);
08
attachInterrupt(0, impuls, RISING);
//Прерывание по нарастающему фронту на D2
09
}
10
void
loop
(){
11
detachInterrupt(0);
12
speeed = 60000/(time-time_old);
//вычисляем скорость в об/мин
13
attachInterrupt(0, impuls, RISING);
14
Serial
.println(speeed);
15
delay(200);
16
}
17
void
impuls(){
// сработал датчик
18
time_old = time;
19
time = millis();
20
}
3. отключаем прерывания в момент передачи в serial (возможно это изза прерываний приходит белеберда) а также считаем в прерываниях скорость
01
volatile unsigned
long
time = 0;
//Время срабатывания датчика
02
volatile unsigned
long
time_old = 0;
//предыдущее время
03
volatile unsigned
int
speeed = 0;
04
05
void
setup
(){
06
delay(120000);
//подождем 2 мин на начальном этапе
07
Serial
.begin(9600);
08
attachInterrupt(0, impuls, RISING);
//Прерывание по нарастающему фронту на D2
09
}
10
void
loop
(){
11
detachInterrupt(0);
12
Serial
.println(speeed);
13
attachInterrupt(0, impuls, RISING);
14
delay(200);
15
}
16
void
impuls(){
// сработал датчик
17
time_old = time;
18
time = millis();
19
speeed = 60000/(time-time_old);
//вычисляем скорость в об/мин
20
}
немного доработал 3 вариант. убрал одно приравнивание для уменьшения времени обработки прерывания
01
volatile unsigned
long
time = 0;
//Время срабатывания датчика
02
volatile unsigned
int
speeed = 0;
03
04
void
setup
(){
05
delay(120000);
//подождем 2 мин на начальном этапе
06
Serial
.begin(9600);
07
attachInterrupt(0, impuls, RISING);
//Прерывание по нарастающему фронту на D2
08
}
09
void
loop
(){
10
detachInterrupt(0);
11
Serial
.println(speeed);
12
attachInterrupt(0, impuls, RISING);
13
delay(200);
14
}
15
void
impuls(){
// сработал датчик
16
speeed = 60000/(millis() - time);
//вычисляем скорость в об/мин
17
time = millis();
18
}
установил двигатель на постоянные обороты 330 об.мин погрешность 330-350 на дисплее ардуино
уменьшил обороты двигателя до 300 об.мин на дисплее 290-310 иногда выскакивает 380 об.мин
это в каком варианте?
вот может исправит если 3 вариант
01
volatile unsigned
long
time = 0;
//Время срабатывания датчика
02
volatile unsigned
int
speeed = 0;
03
04
void
setup
(){
05
delay(120000);
//подождем 2 мин на начальном этапе
06
Serial
.begin(9600);
07
attachInterrupt(0, impuls, RISING);
//Прерывание по нарастающему фронту на D2
08
}
09
void
loop
(){
10
detachInterrupt(0);
11
Serial
.println(speeed);
12
delay(200);
13
attachInterrupt(0, impuls, RISING);
14
}
15
void
impuls(){
// сработал датчик
16
speeed = 60000/(millis() - time);
//вычисляем скорость в об/мин
17
time = millis();
18
}
в последнем варианте стабильные обороты 297-300 за 8 мин проверки было 4-5 одиночных скачков вниз до 149 об
из 97 поста или 95?
в сообщении 88 погрешность +0+20 об. скачки разовые 380об
в сообщении 94 (первый вариант) погрешность +-10 об. скачки разовые 350 об
в сообщении 94 (вариант 2) погрешность оборотов +-3 об разовые скачки 555 об.
в сообщении 95 скачки до 65535 примерно каждые 2 мин
в сообщении 97 погрешность +-2 об. разовые скачки вниз на 149 об