написание скетча для управления оборотами двигателя

Pavlo
Offline
Зарегистрирован: 18.12.2013

последний вариант 97

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

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

я честно сказать уже хз что тут еще сделать. может позже еще что нибудь придумаю

скачки также случайные или через определенный промежуток времени?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Мое предложение несколько другое, не отключать обработчик (это важно), а запрещать прерывания, а это разные вещи:

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
} 
void loop(){ 
  noInterrupts();
  speeed = 60000/(time-time_old);          //вычисляем скорость в об/мин
  interrupts();
  Serial.println(speeed);
  delay(200);
}
void impuls(){ // сработал датчик 
  time_old = time; 
  time = millis(); 
}

В моем случае прерывание в момент рассчета не произойдет, а произойдет оно ПОСЛЕ рассчета. Т.е. разумеется это не очень хорошо, но скачков быть не должно.

 

Pavlo
Offline
Зарегистрирован: 18.12.2013

это вариант оказался лучшим. такой скачек вниз я думаю не будет мешать. попробовать теперь добавить реле и посмотреть  как себя поведет 

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

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

volatile unsigned long time = 0;        //Время срабатывания датчика
volatile unsigned int speeed = 0;
 
void setup(){
  delay(120000);                        //подождем 2 мин на начальном этапе
  Serial.begin(9600);
  attachInterrupt(0, impuls, RISING);   //Прерывание по нарастающему фронту на D2
} 
void loop(){ 
  noInterrupts();
  Serial.println(speeed);
  delay(200);
  interrupts();
}
void impuls(){ // сработал датчик 
  speeed = 60000/(millis() - time);     //вычисляем скорость в об/мин
  time = millis(); 
}

попробуй это а потом уже реле подцепим

Pavlo
Offline
Зарегистрирован: 18.12.2013

сообщение 103 стабильны показания разовые не частые скачки -1 и 560

Pavlo
Offline
Зарегистрирован: 18.12.2013

подождал 2 мин на дисплее выдал ряд единиц в конце 3750 и завис 

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

а из 105?

уже голова не работает. может так стабильнее будет

volatile unsigned long time = 0;        //Время срабатывания датчика
volatile unsigned int speeed = 0;
 
void setup(){
  delay(120000);                        //подождем 2 мин на начальном этапе
  Serial.begin(9600);
  attachInterrupt(0, impuls, RISING);   //Прерывание по нарастающему фронту на D2
} 
void loop(){ 
  noInterrupts();
  Serial.println(speeed);
  delay(200);
  interrupts();
  attachInterrupt(0, impuls, RISING);
}
void impuls(){ // сработал датчик 
  speeed = 60000/(millis() - time);     //вычисляем скорость в об/мин
  time = millis(); 
}

 

Pavlo
Offline
Зарегистрирован: 18.12.2013

из 105 я написал в 107

Pavlo
Offline
Зарегистрирован: 18.12.2013

108 выдал единицы и завис(не меняет значения)

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

ну хорошо 108

если нет остановимся на том со скачком вниз. если меня позже еще не осенит

 

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

из 97 протестируйте подольше и будем уже реле юзать

Pavlo
Offline
Зарегистрирован: 18.12.2013

у меня на плате какойто баг . как обнулить память платы?

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

в смысле обнулить? при програмировании все затирается кроме бутлоадера

Pavlo
Offline
Зарегистрирован: 18.12.2013

уже разобрался спасибо тестирую заново

Pavlo
Offline
Зарегистрирован: 18.12.2013

протестировал заново

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

пункт 94(1)   тоже что и в пункте 88

пункт 94(2)   скорость меняеться сразу бывают разовые скачки

пункт 95      скорость регулируеться нормально дает высокие скачки часто но не подряд

пункт 97 скорость показывает 290-300 при регулеровке скорости значения на мониторе остаються неизменными теже 300. если понижаю обороты на двигателе меньше 300 выдает разовые скачки (на мониторе)  150 если поднимаю выше 300 скачков нет.

пункт 103    скорость регулируеться нормально скачков нет

 

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

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

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

пробуйте

#define rele 10
volatile unsigned long time = 0;        //Время срабатывания датчика
volatile unsigned long time_old = 0;             //предыдущее время
int speeed = 0;

void setup(){
  delay(120000); //подождем 2 мин на начальном этапе
  pinMode(rele, OUTPUT);
  digitalWrite(rele, HIGH);
  Serial.begin(9600);
  attachInterrupt(0, impuls, RISING);   //Прерывание по нарастающему фронту на D2
} 
void loop(){ 
  noInterrupts();
  speeed = 60000/(time-time_old);          //вычисляем скорость в об/мин
  if(speeed >= 250){ 
    digitalWrite(rele, LOW); 
    delay(30000); 
  } 
  else{ 
    digitalWrite(rele, HIGH); 
  } 
  interrupts();
  Serial.println(speeed);
  delay(200);
}
void impuls(){ // сработал датчик 
  time_old = time; 
  time = millis(); 
}

 

Pavlo
Offline
Зарегистрирован: 18.12.2013

Спасибо в воскресенье буду проверять

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

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

Запрет прерываний нужен только для того, чтобы в момент расчета speeed, не изменилось значение переменных time & time_old. Запрещать прерывания ДОЛЬШЕ расчета - чревато увеличением нелинейности рассчета, пусть небольшой, но это лишнее. Потому, запрет пререваний нужен только на время использования переменных time & time_old, после чего нужно их быстро разрешить, т.е. должно быть просто запрет прерываний, расчет speeed и обратно разрешение прерываний, все остальные варианты - некорректны.

Для тех, кто не совсем понимает, посмотрите ассемблерный листинг и увидите, что расчет speeed происходит за несколько команд, таким образом, например, МК может считать во внутренние регистры значение time, а потом происходит прерывание и значение переменной time изменяется, но МК в регистрах использует старое и уже некорректное значение.

 

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

kisoft пишет:

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

Запрет прерываний нужен только для того, чтобы в момент расчета speeed, не изменилось значение переменных time & time_old. Запрещать прерывания ДОЛЬШЕ расчета - чревато увеличением нелинейности рассчета, пусть небольшой, но это лишнее. Потому, запрет пререваний нужен только на время использования переменных time & time_old, после чего нужно их быстро разрешить, т.е. должно быть просто запрет прерываний, расчет speeed и обратно разрешение прерываний, все остальные варианты - некорректны.

Для тех, кто не совсем понимает, посмотрите ассемблерный листинг и увидите, что расчет speeed происходит за несколько команд, таким образом, например, МК может считать во внутренние регистры значение time, а потом происходит прерывание и значение переменной time изменяется, но МК в регистрах использует старое и уже некорректное значение.

 

спасибо за объяснение

Pavlo
Offline
Зарегистрирован: 18.12.2013

Спасибо

Pavlo
Offline
Зарегистрирован: 18.12.2013

проверял 118 дает сбои частые высокие скачки

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
#define rele 10
volatile unsigned long time = 0;        //Время срабатывания датчика
volatile unsigned long time_old = 0;             //предыдущее время
int speeed = 0;

void setup(){
  delay(120000); //подождем 2 мин на начальном этапе
  pinMode(rele, OUTPUT);
  digitalWrite(rele, HIGH);
  Serial.begin(9600);
  attachInterrupt(0, impuls, RISING);   //Прерывание по нарастающему фронту на D2
} 
void loop(){ 
  noInterrupts();
  speeed = 60000/(time-time_old);          //вычисляем скорость в об/мин
  interrupts();
  if(speeed >= 250){ 
    digitalWrite(rele, LOW); 
    delay(30000); 
  } 
  else{ 
    digitalWrite(rele, HIGH); 
  } 
  
  Serial.println(speeed);
  delay(200);
}
void impuls(){ // сработал датчик 
  time_old = time; 
  time = millis(); 
}

 

Pavlo
Offline
Зарегистрирован: 18.12.2013

 в 124 при низких оборотах каждые 30 сек дает скачек. при поднятии оборотов выше 250 проверки нет и реле не реагирует

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
#define rele 10
volatile unsigned long time = 0;        //Время срабатывания датчика
volatile unsigned long time_old = 0;             //предыдущее время
int speeed = 0;

void setup(){
  delay(120000); //подождем 2 мин на начальном этапе
  pinMode(rele, OUTPUT);
  digitalWrite(rele, HIGH);
  //Serial.begin(9600);
  attachInterrupt(0, impuls, RISING);   //Прерывание по нарастающему фронту на D2
} 
void loop(){ 
  noInterrupts();
  speeed = 60000/(time-time_old);          //вычисляем скорость в об/мин
  interrupts();
  if(speeed >= 250){ 
    digitalWrite(rele, LOW); 
    //delay(30000); 
  } 
  else{ 
    digitalWrite(rele, HIGH); 
  } 
  
  //Serial.println(speeed);
  //delay(200);
}
void impuls(){ // сработал датчик 
  time_old = time; 
  time = millis(); 
}

попробуем без 30 сек задержки

Pavlo
Offline
Зарегистрирован: 18.12.2013

126 ПРИ НИЗКИХ ОБОРОТАХ НАЧИНАЕТ СХОДИТЬ С УМА ВПЕРЕД НАЗАД. ПРИ ВЫСОКИХ ОБОРОТАХ ФИКСИРУЕТЬСЯ В ПОЛОЖЕНИИ РЕЛЕ HIGH КАК ДОЛЖНО БЫТЬ ПРИ НИЗКИХ ОБОРОТАХ

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

мотор к реле поключен к нормлально разомкнутым контактам?

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

Pavlo
Offline
Зарегистрирован: 18.12.2013

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

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

если наоборот получается нормально замкнутое

#define rele 10
volatile unsigned long time = 0;        //Время срабатывания датчика
volatile unsigned long time_old = 0;             //предыдущее время
int speeed = 0;

void setup(){
  delay(120000); //подождем 2 мин на начальном этапе
  pinMode(rele, OUTPUT);
  digitalWrite(rele, LOW);
  //Serial.begin(9600);
  attachInterrupt(0, impuls, RISING);   //Прерывание по нарастающему фронту на D2
} 
void loop(){ 
  noInterrupts();
  speeed = 60000/(time-time_old);          //вычисляем скорость в об/мин
  interrupts();
  if(speeed >= 250){ 
    digitalWrite(rele, HIGH); 
    //delay(30000); 
  } 
  else{ 
    digitalWrite(rele, LOW); 
  } 
  
  //Serial.println(speeed);
  //delay(200);
}
void impuls(){ // сработал датчик 
  time_old = time; 
  time = millis(); 
}

 

Pavlo
Offline
Зарегистрирован: 18.12.2013

130  работает почти нормально.

при достижении 250 об срабатывает реле и фиксируеться. 

при быстром понижении на 220 об реле переключаеться и фиксируеться.

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

выход из этого состояния:

1:  поднять обороты до 250 тогда происходит переключение и работа возобновляеться в нормальном режиме

2: выключить питание платы

Pavlo
Offline
Зарегистрирован: 18.12.2013

 в промежутке 220-250 об работает не стабильно

при поднятии оборотов от 0 до промежутка 220-245 об первое время мин 10 работает нормально потом начинает давать сбои примерно каждые 5-10 мин длительностью 30-60 сек.

при понижении оборотов с 260 до 220 постоянные сбои очень длительные доходит до залипания контактов реле если в течении до 3 мин не понизить обороты до 217

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

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

Pavlo
Offline
Зарегистрирован: 18.12.2013

спасибо

 

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

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

#define rele 10
volatile unsigned long time = 0;        //Время срабатывания датчика
volatile unsigned long time_old = 0;             //предыдущее время
int speeed = 0;
boolean flag = 0;

void setup(){
  delay(120000); //подождем 2 мин на начальном этапе
  pinMode(rele, OUTPUT);
  digitalWrite(rele, LOW);
  Serial.begin(9600);
  attachInterrupt(0, impuls, RISING);   //Прерывание по нарастающему фронту на D2
} 
void loop(){
  if(flag == 1){
    speeed = 60000/(time-time_old);          //вычисляем скорость в об/мин
    if(speeed >= 250){ 
      digitalWrite(rele, HIGH); 
      //delay(30000); 
    } 
    else{ 
      digitalWrite(rele, LOW); 
    } 
    flag = 0;
    Serial.println(speeed);
  }
}
void impuls(){ // сработал датчик 
  time_old = time; 
  time = millis(); 
  flag = 1;
}

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

Pavlo
Offline
Зарегистрирован: 18.12.2013

пока дает пульсации в пределах 230-250 об. 

может попробовать алгоритм при достижении 250 об сработало реле и ждет пока обороты не упадут до 210 об. (сработало реле).

сделать систему пожестче.

 

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

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

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

Pavlo
Offline
Зарегистрирован: 18.12.2013

обороты поднимаються до 250 об нормально. на 250 сработало реле (замкнуло цепь на увод хвоста) пока обороты 250+ реле замкнуто в этом положении. все нормально.

начинаю медленно понижать обороты. вне зависимости за сколько времени понижаются обороты 15 сек или 3 мин и более. с верхней границы 249 и до нижней границы 230 оборотов. реле пульсирует (меняет полярность) и актуатор поворачивает хвост рывками (длина выдвижения штока актуатора 100 мм) периодами выдвигается шток до конца и сразу задвигаеться до конца в промежутках между такими периодами выдвигаеться примерно на 5-10 мм задвигаеться обратно. (по принципу 2 шага вперед 1 назад 2 вперед 3 назад). и таким образом пока не доходит до 230 оборотов.

дошло до 230 об стабилизировалось и ждет пока обороты не поднимуться до 250 об

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

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

 если уменьшилось  до 230 включается  пока не увеличатся обороты до 250

так?

если так. все нормлаьно работает,  но в диапазоне от 249 до 230 (только при понижении) реле туда сюда переключается. правильно?

 

Pavlo
Offline
Зарегистрирован: 18.12.2013

да

 

ivan_admin
Offline
Зарегистрирован: 09.01.2014

Pavlo пишет:

обороты поднимаються до 250 об нормально. на 250 сработало реле (замкнуло цепь на увод хвоста) пока обороты 250+ реле замкнуто в этом положении. все нормально.

начинаю медленно понижать обороты. вне зависимости за сколько времени понижаются обороты 15 сек или 3 мин и более. с верхней границы 249 и до нижней границы 230 оборотов. реле пульсирует (меняет полярность) и актуатор поворачивает хвост рывками (длина выдвижения штока актуатора 100 мм) периодами выдвигается шток до конца и сразу задвигаеться до конца в промежутках между такими периодами выдвигаеться примерно на 5-10 мм задвигаеться обратно. (по принципу 2 шага вперед 1 назад 2 вперед 3 назад). и таким образом пока не доходит до 230 оборотов.

дошло до 230 об стабилизировалось и ждет пока обороты не поднимуться до 250 об

А не могли бы вы схему нарисовать, хотя бы на бумажке(сфоткать и выложить сюда)

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

Особенно про актуатор, хвост поподробнее. Что к чему у вас подключено...

Pavlo
Offline
Зарегистрирован: 18.12.2013

ivan_admin
Offline
Зарегистрирован: 09.01.2014

а как взаимосвязаны двигатель-генератор -- блок управления актуатором -- редуктор -- ховст ?

Почемуто всё это мне напоминает ветрогенератор, хотя наверное и ошибаюсь

Pavlo
Offline
Зарегистрирован: 18.12.2013

так оно и есть это система управления поворотом ветрогенератора. увода из под ветра при увеличении оборотов генератора

Pavlo
Offline
Зарегистрирован: 18.12.2013

это не редуктор а актуатор

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Pavlo пишет:

так оно и есть это система управления поворотом ветрогенератора. увода из под ветра при увеличении оборотов генератора

Насколько я в курсе ротор поворачивают редко,

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

нагрузкой (или даже закорачивают выход). И это  делает обычный контроллер заряда.

Может быть вам надо пойти по этому пути, а  не крутить его?

Например

http://www.ebay.com/itm/Wind-Charge-Controller-for-100W-200W-300W-12V-fo...

1 .Automatic dump load while the wind turbine generator overload.

2. Batteries overcharge or over discharge protection.

3. Battery reverse connection protection, Lightning protection

4. Wind turbine current limiting, Wind turbine automatic brake and manual brake

5. Protect cable connect to batteries inverse.

6. Protect electric shock.

7. Water proof

System voltage

12V

Rated power for wind turbine

100~300W

Brake Start Voltage

15V

Brake Recover Voltage

13.5V

Brake Start Current

15A

Display Model

LED

Output route

single way

Ambient temperature

-35 - +75 °c

Size

96X76X21mm

Safe degree

IP67

 

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

попробуйте так. ввел усреднение и "жесткие условия"

#define rele 10
volatile unsigned long time = 0;        //Время срабатывания датчика
volatile unsigned long time_old = 0;             //предыдущее время
int speeed = 0;
boolean flag = 0;

int mass[5] = {0,0,0,0,0};   
byte first = 0;

void setup(){
  delay(120000); //подождем 2 мин на начальном этапе
  pinMode(rele, OUTPUT);
  digitalWrite(rele, LOW);
  attachInterrupt(0, impuls, RISING);   //Прерывание по нарастающему фронту на D2
} 
void loop(){
  if(flag == 1){
    speeed = 60000/(time-time_old);     //вычисляем скорость в об/мин
    
//========================================================================
//  Первый раз заполняем массив одинаковыми значениями измеренной скорости
//             Выполняется только 1 раз после первого измерения

    if( first == 1){
       for(int i=0; i<5; i++){
          mass[i] = speeed;
          first++;
       }  
    }  
    
//========================================================================
//                        Вычисляем среднее
    for(int i=0; i<4; i++){
      mass[i] = mass[i+1];
    }
    mass[4] = speeed;
    for(int i=0; i<5; i++){ 
      speeed += mass[i];
    }
    speeed /= 5;
//========================================================================
//                          Управляем реле    
    
    if(speeed >= 250){ 
      digitalWrite(rele, HIGH); 
    } 
    if(speeed <= 210){ 
      digitalWrite(rele, LOW); 
    } 
    flag = 0;
  }
}

//========================================================================
//                      Подпрограмма прерывания    
void impuls(){
  time_old = time; 
  time = millis(); 
  flag = 1;
  if(first == 0){
     first++;
  }
}

 

Pavlo
Offline
Зарегистрирован: 18.12.2013

на сигнальном проводе у меня 3.5 В и табло показывает обороты. когда подаю питание от АКБ на плату на сигнальном проводе получаю 245 мВ и на табло пропадают обороты(показывает 0). 

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

а на плату куда подаете питание? на какой вывод?

или на разъем?

плата не должна влиять. там работает в режиме входа

Pavlo
Offline
Зарегистрирован: 18.12.2013

сигнальный на D2. питание на VIN и GND 12В. схему подключения не менял. до этого работало нормально. сегодня подключаю сигнал пропадает. убираю питание с платы, а сигнальный остаеться подключенным к плате, на табло появляються обороты.