увеличение значения переменной

alexey_and
Offline
Зарегистрирован: 03.03.2013

друзья, помогите пожалуйста перевести с человеческого языка на с++ такую функцию:

дан отрезок времени (допустим 30 сек) и переменная z. при вызове функции - переменная z должна увеличиться с 0 до 100 за эти 30 сек, без delay

буду дико благодарен за любую помощь :) 

"мигаем светодиодом без delay" видел :)

com
Offline
Зарегистрирован: 06.09.2013

если переменная увеличивается внутри функции и в эти 30 секунд нигде не используется, тогда зачем вообще функция?

alexey_and
Offline
Зарегистрирован: 03.03.2013

кто сказал что нигде не используется?

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

разделите участок времени 30сек на количество изменений в данном случае 100. получаем 300мс. увеличивать нужно каждые 300мс на 1.

int time = 30;      //время в секундах
int number = 100;   //количество изменений за время time
int z = 1;          //переменная которую увеличиваем
int segment;        //время между изменениями
unsigned long prev_time;

void setup(){
  segment = (time*1000)/number;
  prev_time = millis();
}

void loop(){
  if (((millis()-prev_time) >= segment) && z <= number){
    z++;
    prev_time = millis();
  }
//тут ваш код
}

каждые 300мс z будет увеличиваться пока не достигнет 100

ваш код не должен быть слишком долгим иначе вместо 30 секунд при z=100 получите например 32 секунды. если точность не важна то пожалуйста

alexey_and
Offline
Зарегистрирован: 03.03.2013

работает зачетно, спасибо :)

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

делаю так

      if(xyz == 10){
        if (((millis()-prev_time) >= segment) && b <= number){
    b++;
    prev_time = millis();
      Serial.println(b); 
        }
  }

        if(xyz == 0){

        if (((millis()-prev_time) >= segment) && b <= number){
    b--;
    prev_time = millis();
       Serial.println(b); 
        }
  }

по идее нужно - если xyz == 10 считаем от 0 до 10

а если xyz == 0, считаем от 10 до 0

от 0 до 10 работает, а наоборот - нет...

alexey_and
Offline
Зарегистрирован: 03.03.2013

сразу скажу, это некое подобие эмулятора энкодера/датчика положения привода :)

точность не нужна, просто примерная оценка положения

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

xyz == 10 запускает привод в одном направлении, xyz == 0 - в обратном

было бы шикарно, задав например xyz == 8 или любое другое промежуточное положение, получить соответствующее положение привода

например, если xyz == 8, запускаем привод на 30/10*8 cек

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

вот так уменьшается

int number = 100;   //количество изменений за время time
int z = 100;        //переменная которую уменьшаем
int segment;        //время между изменениями
unsigned long prev_time;

void setup(){
  segment = (time*1000)/number;
  prev_time = millis();
}

void loop(){
  if (((millis()-prev_time) >= segment) && z >= 0){
    z--;
    prev_time = millis();
  }
//тут ваш код
}

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

alexey_and
Offline
Зарегистрирован: 03.03.2013

да, теперь считает в обе стороны, но почему-то от -1 до 10 и обратно до -1. откуда -1 берется?

-1
0
1
2
3
4
5
6
7
8
9
10
9
8
7
6
5
4
3
2
1
0
-1

делаю так:

int time = 20;      //время в секундах
int number = 9;   //количество изменений за время time
int b = 0;          //переменная которую увеличиваем
int segment;        //время между изменениями
unsigned long prev_time;


void setup()
{

  segment = (time*1000)/number;
  prev_time = millis();
}

void loop()
{ 
      if(xyz == 10){
        if (((millis()-prev_time) >= segment) && b <= number){
           b++;
           prev_time = millis();
           Serial.println(b); 
        }
  }

       if(xyz == 0){

        if (((millis()-prev_time) >= segment) && b >= 0){
           b--;
           prev_time = millis();
           Serial.println(b); 
        }
  }
}

 

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

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

alexey_and
Offline
Зарегистрирован: 03.03.2013

jeka_tm пишет:

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

думаю смысл такой:

привод управляется реле, подачей HIGH или LOW на пин на 500мс, а останавливается подачей питания на два пина:

void leftRollUP(){
  digitalWrite(leftRollUpPIN, HIGH);   
    left_roll_state_prev = 10;
  delay(500);  
  digitalWrite(leftRollUpPIN, LOW);
}
void leftRollDOWN(){
  digitalWrite(leftRollDownPIN, HIGH);    
    left_roll_state_prev = 0;
  delay(500);
  digitalWrite(leftRollDownPIN, LOW);   
}
void leftRollSTOP(){
  digitalWrite(leftRollUpPIN, HIGH);
  digitalWrite(leftRollDownPIN, HIGH);              
  delay(500);
  digitalWrite(leftRollUpPIN, LOW);
  digitalWrite(leftRollDownPIN, LOW);    
}

left_roll_state_prev на данный момент показывает где последний раз был привод, для условия срабатывания вверх или вниз

  if(left_roll_state_prev < left_roll_state)  leftRollUP();
  if(left_roll_state_prev > left_roll_state)  leftRollDOWN();  

значение left_roll_state прилетает по http:

            if(strncmp(pch,"z=",2) == 0)
            {
              z = atoi(pch+2);
              left_roll_state = z;
            }

когда left_roll_state равен 0 - это крайнее нижнее положение привода, когда равен 10 - крайнее верхнее

когда мы получаем 0, двигаем привод вниз без задания ему времени на движение, 10 - аналогично вверх, тк в крайних положениях он отключится сам за счет встроенных концевиков

сейчас так и работает - прилетел 0 - вызываю функцию leftRollDOWN(), прилетело 10 - leftRollUP()

еще сейчас с помощью отсчета 0-10-0 движение привода отрисовывается графически (опрашиваю переменную b по http)

      if(left_roll_state_prev == 10){
        if (((millis()-prev_time) >= segment) && b <= number){
          b++;
          prev_time = millis();
          Serial.println(b); 
        }
  }

       if(left_roll_state_prev == 0){
         if (((millis()-prev_time) >= segment) && b >= 0){
           b--;
           prev_time = millis();
           Serial.println(b); 
        }
  }
void send_left_roll_state(EthernetClient thisClient) {
  char tBuf[64];
  strcpy_P(tBuf,PSTR("HTTP/1.1 200 OK\r\n"));
  thisClient.write(tBuf);
  strcpy_P(tBuf,PSTR("Content-Type: application/json\r\nConnection: close\r\n\r\n"));
  thisClient.write(tBuf);
  thisClient.println(b);
  thisClient.stop();
}

что хотелось бы: 

left_roll_state может принимать значения от 0 до 10 и от 10 до 0 (значение переменной прилетает по http)

надо ассоциировать значение с реальным временным отрезком. например, если сейчас 0 и прилетело 8, запускаем привод вверх на 30/10*8 cек

но если последнее положение привода не 0, то надо рассчитать на какое время включать привод

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

 

 

alexey_and
Offline
Зарегистрирован: 03.03.2013

jeka_tm пишет:

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

 

там просто рулон на 1240 строк... может проще на e-mail? 

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

leftRollUpPIN двигает вперед 

leftRollDownPIN двигает назад

если подать импульс на 500мс.

двигатель что то типа шагового?

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

или за 500мс он делает один шаг? и если держать 1000мс он сделает 2 шага. 

или нужно 2 раза подать импульс длиной 500мс и он сделает 2 шага

объясните конкретнее

alexey_and
Offline
Зарегистрирован: 03.03.2013

jeka_tm пишет:

leftRollUpPIN двигает вперед 

leftRollDownPIN двигает назад

если подать импульс на 500мс.

двигатель что то типа шагового?

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

или за 500мс он делает один шаг? и если держать 1000мс он сделает 2 шага. 

или нужно 2 раза подать импульс длиной 500мс и он сделает 2 шага

объясните конкретнее

если б это было так, было бы совсем просто :)

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

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

это время (500мс) нужно чтоб двигатель увидел что ему нажали кнопку

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

в конце сам может останавливаться?

если правлиьно понял нажал кнопку и держишь, а двигатель будет ехать до конца. так?

alexey_and
Offline
Зарегистрирован: 03.03.2013

нажал, держишь 500мс, отпустил - двигатель едет до конца. в конце останавливается сам за счет встроенного концевика

 

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

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

alexey_and
Offline
Зарегистрирован: 03.03.2013

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

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

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

int time = 30;      //время в секундах
int number = 100;   //количество изменений за время time
int z = 0;          //начальное положение равно нулу (мотор должен стоять в начале)
int prev_z = 0;     //последнее положение
boolean napr = 1;   //1 вперед 0 назад

int segment;        //время между изменениями
unsigned long prev_time;
unsigned long next_time;


void setup(){
  segment = (time*1000)/number;
  prev_time = millis();
  prev_z = z;
}

void loop(){
  if (((millis()-prev_time) >= segment) && z <= number){
    z++;
    prev_time = millis();
  }
//тут ваш код
}

void dvig(boolean napr, int length){
  if (napr == 1){
   motor_UP(); 
   
  }
  
    


void motor_UP(){
  digitalWrite(leftRollUpPIN, HIGH);   
  delay(500);  
  digitalWrite(leftRollUpPIN, LOW);
}
void motor_DOWN(){
  digitalWrite(leftRollDownPIN, HIGH);    
  delay(500);
  digitalWrite(leftRollDownPIN, LOW);   
}
void motor_STOP(){
  digitalWrite(leftRollUpPIN, HIGH);
  digitalWrite(leftRollDownPIN, HIGH);              
  delay(500);
  digitalWrite(leftRollUpPIN, LOW);
  digitalWrite(leftRollDownPIN, LOW);    
}

код не дописал. домой пора. дома может допишу. сюда скину чтобы сначала не начинать

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

вот попробуйте отдельно без вашего кода.

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

количество отсчетов 100 (меняйте на что хотите)

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

dvig(1, 50); //отправить актуатор вперед на 50 едениц
dvig(0, 20); //отправить актуатор назад на 20 едениц

программа не отслеживает может он дальше двигаться или нет. тут используется концевой выключатель актуатора. z запоминается в крайнем положении даже если например сейчас на 90 едениц (до конца остальсь 10 едениц), а отправили на 20 вперед. он отправит вперед на 20, но в z запишет 100

 

int time_all = 30;      //время в секундах
int number = 100;   //количество изменений за время time
int z = 0;          //текущее положение
boolean napr = 1;   //1 вперед 0 назад

int segment;        //время между изменениями
unsigned long time;

#define  leftRollUpPIN    2    //тут должны быть ваши пины
#define  leftRollDownPIN  3  //тут должны быть ваши пины



void setup(){
  segment = (time_all*1000)/number;
  pinMode(leftRollUpPIN, OUTPUT);
  pinMode(leftRollDownPIN, OUTPUT);
}

void loop(){
  if (millis() >= time){
    motor_STOP();
  }

  //тут ваш код

}

void dvig(boolean napr, int length){
  if (napr == 1){
    motor_UP(); 
  }
  if (napr == 0){
    motor_DOWN(); 
  }
  time = millis()+(segment*length);
  if ((z+length) >= number){
    z = number;
  }
  if ((z-length) <= 0){
    z = 0;
  }
}




void motor_UP(){
  digitalWrite(leftRollUpPIN, HIGH);   
  delay(500);  
  digitalWrite(leftRollUpPIN, LOW);
}
void motor_DOWN(){
  digitalWrite(leftRollDownPIN, HIGH);    
  delay(500);
  digitalWrite(leftRollDownPIN, LOW);   
}
void motor_STOP(){
  digitalWrite(leftRollUpPIN, HIGH);
  digitalWrite(leftRollDownPIN, HIGH);              
  delay(500);
  digitalWrite(leftRollUpPIN, LOW);
  digitalWrite(leftRollDownPIN, LOW);    
}

 

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

вот попробуйте. должен проехать вперед. подождать. вернуться немного назад. подождать. проехать немного вперед. подождать и по новой

int time_all = 30;      //время в секундах
int number = 100;   //количество изменений за время time
int z = 0;          //текущее положение
boolean napr = 1;   //1 вперед 0 назад

int segment;        //время между изменениями
unsigned long time;

#define  leftRollUpPIN    2    //тут должны быть ваши пины
#define  leftRollDownPIN  3  //тут должны быть ваши пины



void setup(){
  segment = (time_all*1000)/number;
  pinMode(leftRollUpPIN, OUTPUT);
  pinMode(leftRollDownPIN, OUTPUT);
}

void loop(){
  if (millis() >= time){
    motor_STOP();
  }

  dvig(1, 50);
  delay(30000);
  dvig(0, 30);
  delay(30000);
  dvig(1, 60);
  delay(30000);

}

void dvig(boolean napr, int length){
  if (napr == 1){
    motor_UP(); 
  }
  if (napr == 0){
    motor_DOWN(); 
  }
  time = millis()+(segment*length);
  if ((z+length) >= number){
    z = number;
  }
  if ((z-length) <= 0){
    z = 0;
  }
}




void motor_UP(){
  digitalWrite(leftRollUpPIN, HIGH);   
  delay(500);  
  digitalWrite(leftRollUpPIN, LOW);
}
void motor_DOWN(){
  digitalWrite(leftRollDownPIN, HIGH);    
  delay(500);
  digitalWrite(leftRollDownPIN, LOW);   
}
void motor_STOP(){
  digitalWrite(leftRollUpPIN, HIGH);
  digitalWrite(leftRollDownPIN, HIGH);              
  delay(500);
  digitalWrite(leftRollUpPIN, LOW);
  digitalWrite(leftRollDownPIN, LOW);    
}

 

alexey_and
Offline
Зарегистрирован: 03.03.2013

едет до конца наверх, потом до конца вниз, потом опять до конца наверх

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

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

то есть не 30 сек а 28 например.

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

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

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
int time_all = 28;  //время в секундах
int number = 100;   //количество изменений за время time
int z = 0;          //текущее положение
boolean napr = 1;   //1 вперед 0 назад

int segment;        //время между изменениями
unsigned long time;

#define  leftRollUpPIN    2    //тут должны быть ваши пины
#define  leftRollDownPIN  3  //тут должны быть ваши пины



void setup(){
  segment = (time_all*1000)/number;
  pinMode(leftRollUpPIN, OUTPUT);
  pinMode(leftRollDownPIN, OUTPUT);
}

void loop(){
  dvig(1, 50);
  delay(50*segment);
  motor_STOP();
  dvig(0, 30);
  delay(30*segment);
  motor_STOP();
  dvig(1, 60);
  delay(60*segment);
  motor_STOP();

}

void dvig(boolean napr, int length){
  if (napr == 1){
    motor_UP(); 
  }
  if (napr == 0){
    motor_DOWN(); 
  }
  time = millis()+(segment*length);
  if ((z+length) >= number){
    z = number;
  }
  if ((z-length) <= 0){
    z = 0;
  }
}




void motor_UP(){
  digitalWrite(leftRollUpPIN, HIGH);   
  delay(500);  
  digitalWrite(leftRollUpPIN, LOW);
}
void motor_DOWN(){
  digitalWrite(leftRollDownPIN, HIGH);    
  delay(500);
  digitalWrite(leftRollDownPIN, LOW);   
}
void motor_STOP(){
  digitalWrite(leftRollUpPIN, HIGH);
  digitalWrite(leftRollDownPIN, HIGH);              
  delay(500);
  digitalWrite(leftRollUpPIN, LOW);
  digitalWrite(leftRollDownPIN, LOW);    
}

void stop_m(){
  if (millis() >= time){
    motor_STOP();
  }
}

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

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

alexey_and
Offline
Зарегистрирован: 03.03.2013

ну да, время-то исправляю.

в ручном режиме поедет назад

alexey_and
Offline
Зарегистрирован: 03.03.2013

jeka_tm пишет:

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

 

 

#define leftRollUpPIN    30
#define leftRollDownPIN  31
jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

на 22 пост ответьте пожалуйста

alexey_and
Offline
Зарегистрирован: 03.03.2013

попробовал, вышло так, %% на глаз :)

вверх на 50%

вниз на 25%

вверх на 80%

вверх до конца

вобщем похоже соответствует программе :)

команды будут отсылаться не особо часто

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

чаще чем каждые 28 секунд будут отсылаться?

+ программу надо переделывать. не очень удачное изначально решение

alexey_and
Offline
Зарегистрирован: 03.03.2013

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

к тому же пользоваться будет еще жена, а она вообще не задумываясь может натыкать :)

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

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

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

вот набросал. проверяйте. в терминале отправляйте число от 0 до 100  где должен встать мотор

если число даже не из диапазона от 0 до 100 например 120. он доедет до конца а z должен быть 100

в ответ постоянно должно приходить текущее положение

основной программе не должно мешать

int  time_all = 28;             //время в секундах
int  number = 100;              //количество изменений за время time_all
int z = 0;                      //текущее положение
int next = 0;                   //будущее положение
boolean napr = 1;               //1 вперед 0 назад
boolean start_stop = 0;         //0 стоит 1 едет
int segment;                    //время между изменениями
unsigned long time;

#define  leftRollUpPIN    30     //вперед
#define  leftRollDownPIN  31     //назад




void setup(){
  Serial.begin(9600);
  segment = (time_all*1000)/number;
  pinMode(leftRollUpPIN, OUTPUT);
  pinMode(leftRollDownPIN, OUTPUT);
}

void loop(){
  proverka();
  if (Serial.available() > 0) {
    dvig(constrain(Serial.read(), 0, number));
  }
  Serial.print("z = ");
  Serial.println(z);
}

//=============================================================================
//                      Управление куда и насколько ехать
void dvig(int length){
  if(length > z){
    napr = 1;
  }
  if(length < z){
    napr = 0;
  }
  time = millis();
  start_stop = 1;
  next = length;
  if (napr == 1){
    motor_UP(); 
  }
  if (napr == 0){
    motor_DOWN(); 
  }
}


//=============================================================================
//                     Управление двигателем вперед назад стоп

void motor_UP(){
  digitalWrite(leftRollUpPIN, HIGH);   
  delay(500);  
  digitalWrite(leftRollUpPIN, LOW);
}
void motor_DOWN(){
  digitalWrite(leftRollDownPIN, HIGH);    
  delay(500);
  digitalWrite(leftRollDownPIN, LOW);   
}
void motor_STOP(){
  digitalWrite(leftRollUpPIN, HIGH);
  digitalWrite(leftRollDownPIN, HIGH);              
  delay(500);
  digitalWrite(leftRollUpPIN, LOW);
  digitalWrite(leftRollDownPIN, LOW); 
  start_stop = 0;  
}

//=============================================================================
//                     Проверка не достигли нужного положения, 
//                     а также определение текущего положения

void proverka(){
  if (z == next){
    motor_STOP();
  }
  if ( start_stop == 1 && (millis() - time) >= segment && napr == 1){
    z++;
    time = millis();
  }
  if ( start_stop == 1 && (millis() - time) >= segment && napr == 0){
    z--;
    time = millis();
  }
}

 

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

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

int  time_all = 28;             //время в секундах
int  number = 100;              //количество изменений за время time_all
int z = 0;                      //текущее положение
int next = 0;                   //будущее положение
boolean napr = 1;               //1 вперед 0 назад
boolean start_stop = 0;         //0 стоит 1 едет
int segment;                    //время между изменениями
unsigned long time;

#define  leftRollUpPIN    30     //вперед
#define  leftRollDownPIN  31     //назад




void setup(){
  Serial.begin(9600);
  segment = (time_all*1000)/number;
  pinMode(leftRollUpPIN, OUTPUT);
  pinMode(leftRollDownPIN, OUTPUT);
}

void loop(){
  proverka();
  if (Serial.available() > 0) {
    dvig(constrain(Serial.read(), 0, number));
  }
  Serial.print("z = ");
  Serial.println(z);
}

//=============================================================================
//                      Управление куда и насколько ехать
void dvig(int length){
  if(length > z){
    napr = 1;
  }
  if(length < z){
    napr = 0;
  }
  time = millis();
  start_stop = 1;
  next = length;
  if (napr == 1){
    motor_UP(); 
  }
  if (napr == 0){
    motor_DOWN(); 
  }
}


//=============================================================================
//                     Управление двигателем вперед назад стоп

void motor_UP(){
  digitalWrite(leftRollUpPIN, HIGH);   
  delay(500);  
  digitalWrite(leftRollUpPIN, LOW);
}
void motor_DOWN(){
  digitalWrite(leftRollDownPIN, HIGH);    
  delay(500);
  digitalWrite(leftRollDownPIN, LOW);   
}
void motor_STOP(){
  digitalWrite(leftRollUpPIN, HIGH);
  digitalWrite(leftRollDownPIN, HIGH);              
  delay(500);
  digitalWrite(leftRollUpPIN, LOW);
  digitalWrite(leftRollDownPIN, LOW); 
  start_stop = 0;  
}

//=============================================================================
//                     Проверка не достигли нужного положения, 
//                     а также определение текущего положения

void proverka(){
  if (z == next || z == 0 || z == 100){
    motor_STOP();
  }
  
  if (start_stop == 1){
    if((millis() - time) >= segment){
      if (napr == 1){
        z++;
        time = millis();
      }
      if (napr == 0){
        z--;
        time = millis();
      }
    }
  }
}

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

alexey_and
Offline
Зарегистрирован: 03.03.2013

выглядит сурово :) тестить буду уже завтра 

спасибо!

alexey_and
Offline
Зарегистрирован: 03.03.2013

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

это да. но ведь в крайних положениях будет своеобразная калибровка тк отсчет будет стартовать заново? 

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

да не сурово. нормлаьно. в вашем коде 1200 строк. вот это сурово

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

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

да не сурово. нормлаьно. в вашем коде 1200 строк. вот это сурово

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

alexey_and
Offline
Зарегистрирован: 03.03.2013

поменял на 

if (z == next)

все равно постоянно жмет стоп

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

странно . что отправляешь в uart? что получаешь?

alexey_and
Offline
Зарегистрирован: 03.03.2013

ну стоп жмется прям с момента включения питания ардуины

отправляю от 0 до 100, но воспринимает и считает максимум до 10. при этом двигается, на глаз - реально процентов на 10

то есть если кинуть 5 - посчитает до 10, следом кинуть 1 - посчитает до 0, и потом -1

а у тебя нормально считает от 0 до 100 и обратно? и до числа, которое кидаешь?

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

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

 

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

потестил. сначала не допер че за фигня. все оказалось просто.

из uart считывает только 1 цифру от 0 до 9

если отправить 23 из uart придет 2 а потом 3

с помощью подпрограммы собираем все вместе и уже в основную программу

int  time_all = 28;             //время в секундах
int  number = 100;              //количество изменений за время time_all
int z = 0;                      //текущее положение
int prev_z = 0;                 //предыдущее положение
int next = 0;                   //будущее положение
boolean napr = 1;               //1 вперед 0 назад
boolean start_stop = 0;         //0 стоит 1 едет
int segment;                    //время между изменениями
unsigned long time;

#define  leftRollUpPIN    30     //вперед
#define  leftRollDownPIN  31     //назад


void setup(){
  Serial.begin(9600);
  segment = (time_all*1000)/number;
  pinMode(leftRollUpPIN, OUTPUT);
  pinMode(leftRollDownPIN, OUTPUT);
}

void loop(){
  proverka();
  if (Serial.available() > 0) {
    dvig(serReadInt());
  }
  if(prev_z != z){
    Serial.print("z = ");
    Serial.println(z);
  }
}

//=============================================================================
//                      Управление куда и насколько ехать
void dvig(int length){
  next = length;
  if(length > z){
    napr = 1;
  }
  if(length < z){
    napr = 0;
  }
  time = millis();
  start_stop = 1;
  
  if (napr == 1){
    motor_UP(); 
  }
  if (napr == 0){
    motor_DOWN(); 
  }
  Serial.println(next);
}


//=============================================================================
//                     Управление двигателем вперед назад стоп

void motor_UP(){
  Serial.println("UP");
  digitalWrite(leftRollUpPIN, HIGH);   
  delay(500);  
  digitalWrite(leftRollUpPIN, LOW);
}
void motor_DOWN(){
  Serial.println("DOWN"); 
  digitalWrite(leftRollDownPIN, HIGH);    
  delay(500);
  digitalWrite(leftRollDownPIN, LOW);
}
void motor_STOP(){
  Serial.println("STOP"); 
  digitalWrite(leftRollUpPIN, HIGH);
  digitalWrite(leftRollDownPIN, HIGH);              
  delay(500);
  digitalWrite(leftRollUpPIN, LOW);
  digitalWrite(leftRollDownPIN, LOW); 
  start_stop = 0;
  prev_z = z; 
  
}

//=============================================================================
//                     Проверка не достигли нужного положения, 
//                     а также определение текущего положения

void proverka(){
  if (z == next && start_stop == 1){
    motor_STOP();
  }
  
  if (start_stop == 1){
    if((millis() - time) >= segment){
      if (napr == 1){
        prev_z = z;
        z++;
        time = millis();
      }
      if (napr == 0){
        prev_z = z;
        z--;
        time = millis();
      }
    }
  }
}

//=============================================================================
//                     подпрограмма сборки чисел из uart
int serReadInt()
{
  int i, serAva;
  char inputBytes [7]; // массив для хранения байтов
  char * inputBytesPtr = &inputBytes[0]; // указатель на первый элемент массива

  if (Serial.available()>0) // проверяем есть ли данные
 {
    delay(5);//чутка ждем, чтобы все данные прошли
    serAva = Serial.available(); // получаем количество доступных байт
    for (i=0; i<serAva; i++) // загружаем байты в массив
      inputBytes[i] = Serial.read();

    inputBytes[i] = '\0'; // дописываем NULL в конец массива
    return atoi(inputBytesPtr); // Вызываем atoi функцию, стандартная функция С
  }
  else
    return -1; // Возвращаем -1, если ничего не получили
}

 

alexey_and
Offline
Зарегистрирован: 03.03.2013

ага, ясненько :) завтра протестирую

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

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

alexey_and
Offline
Зарегистрирован: 03.03.2013

вроде все четко работает!

с основной прогой пока не скрещивал, но думаю особых проблем не возникнет

еще есть второй такой же двигатель, попробую его тоже подцепить :)

спасибо!

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

удачи в проекте

mag155
Offline
Зарегистрирован: 21.12.2017

Доброго времени суток .! Такой вопрос. Как написать условие : если одна переменная больше другой на 10 то третья переменная увеличивается с шагом 20. Типа так if (Val >val1 )на 10? { val2 ++} но с шагом 20.?

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

вроде так, не проверял

if((val-val1)>10) val+=20;

 

mag155
Offline
Зарегистрирован: 21.12.2017

if(( val>val1)>10) {val2 +=20}; я че то думал что надо вот так .?

mag155
Offline
Зарегистрирован: 21.12.2017

Или все таки val -val1 будет лучше ?

mag155
Offline
Зарегистрирован: 21.12.2017

Надо понимать не просто разницу между ними а именно если первая больше второй ?

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

Почитай еще раз про условия, в симуляторе поиграйся или на ардуине. Коды чужие посмотри