DIY: делаем боевого робота в домашних условиях. Часть 2 «Epic Fail»

#include <math.h>

#define STEP_PIN1  12
#define STEP_PIN2  10

#define RELEPIN0 2
#define RELEPIN1 3
#define RELEPIN2 4
#define RELEPIN3 5
#define RELEPIN4 6
#define RELEPIN5 7
#define RELEPIN6 8
#define RELEPIN7 9
     
#define a0 = A0;
#define a1 = A1;
#define a2 = A2;
#define a3 = A3;
#define a4 = A4;
#define a5 = A5;
//Второй пульт
//Временного отключили второй пульт
//#define a6 = A8;
//#define a7 = A9;
int ch0,ch1,ch2,ch3,ch4,ch5,ch6,ch7;
//Задаем максимум и минимум для ШИМа с первого приемника
const int min0=1094;
const int  min1=1094;
const int  max0=813;
const int  max1=813;
int speed1,speed2,speedmot1,speedmot2,sd1,sd2;
byte ch2st,ch3st,ch4st,ch5st,ch6st,ch7st;
byte tormozcount1=0;
byte tormozcount2=0;
byte wasdir1=2;
byte wasdir2=2;
byte skolkotormozit = 7;
int skolkotormozim=0;

void setup() {
  Serial.begin(9600); 
  Serial.println("start");  
 
  pinMode(a0, INPUT);
  pinMode(a1, INPUT);
  pinMode(a2, INPUT);
  pinMode(a3, INPUT);
  pinMode(a4, INPUT);
  pinMode(a5, INPUT);  
  //Временного отключили второй пульт
  //pinMode(a6, INPUT);
  //pinMode(a7, INPUT);
  
  pinMode(STEP_PIN1, OUTPUT);
  pinMode(STEP_PIN2, OUTPUT);
  pinMode(RELEPIN0,  OUTPUT);
  pinMode(RELEPIN1,  OUTPUT);
  pinMode(RELEPIN2,  OUTPUT);
  pinMode(RELEPIN3,  OUTPUT);
  pinMode(RELEPIN4,  OUTPUT);
  pinMode(RELEPIN5,  OUTPUT);
  pinMode(RELEPIN6,  OUTPUT);
  pinMode(RELEPIN7,  OUTPUT);
}

void loop() {
 
ch0 =pulseIn(a0, HIGH,30000);
if(ch0<900){
//Если нет сигнала с пульта
Serial.println("first no signal"); 
digitalWrite(STEP_PIN1,LOW);
digitalWrite(STEP_PIN2,LOW);
digitalWrite(RELEPIN0,LOW);  
digitalWrite(RELEPIN1,LOW);  
digitalWrite(RELEPIN2,LOW);  
digitalWrite(RELEPIN3,LOW);  
digitalWrite(RELEPIN4,LOW);  
digitalWrite(RELEPIN5,LOW);  
digitalWrite(RELEPIN6,LOW);  
digitalWrite(RELEPIN7,LOW);  

}
//Снимаем показания с ШИМа от первого приемника
ch1 =pulseIn(a1, HIGH);
ch2 =pulseIn(a2, HIGH);
ch3 =pulseIn(a3, HIGH);
ch4 =pulseIn(a4, HIGH);
ch5 =pulseIn(a5, HIGH);
//Временного отключили второй пульт
ch6 =1250; //pulseIn(a6, HIGH,2020);
ch7 =1250; //pulseIn(a7, HIGH,2020);

         if(ch2>1500){
          ch2st=1;
             }else{
                  ch2st=0;
                 }
         if(ch3>1500){
          ch3st=0;
             }else if(ch3>0){
                  ch3st=1;
                 }
         if(ch4>1500){
          ch4st=1;
             }else{
                  ch4st=0;
                 }
         if(ch5>1500){
          ch5st=1;
             }else{
                  ch5st=0;
                 }
         //Каждый канал второго пульта управляет двумя орудиями
         if(ch6>1800){
          ch6st=2;
             }else if(ch6<1200){
              ch6st=1;
                 }else{
                  ch6st=0;
                 }
         if(ch7>1800){
          ch7st=2;
             }else if(ch7<1200){
              ch7st=1;
                 }else{
                  ch7st=0;
                 }
                 


  //Первое орудие----------------------------------------------
if(ch2st==1 or ch6st==1){
     digitalWrite(RELEPIN0,HIGH); 
  }else{
     digitalWrite(RELEPIN0,LOW); 
}

 
 //Второе орудие----------------------------------------------
 if(ch3st==1 or ch6st==2){
     digitalWrite(RELEPIN1,HIGH); 
  }else {
    digitalWrite(RELEPIN1,LOW); 
}

//Третье орудие----------------------------------------------
 if(ch4st==1 or ch7st==1){
     digitalWrite(RELEPIN2,HIGH); 
  }else {
    digitalWrite(RELEPIN2,LOW); 
}

//Если есть сигнал с первого пульта
    if(ch0>0){  
    ch0=(ch0<55 && ch0>45)?50:ch0; 
    ch1=(ch1<55 && ch1>45)?50:ch1; 
           
    ch0 =ch0-min0;
    ch1 =ch1-min1;
    //Получаем данные о положении стиков управления от 0 до 100
    ch0 =map(ch0,0,max0,0,100);
    ch1 =100-map(ch1,0,max1,0,100);  

        //Превращаем данные о напралении движения в необходимые значения для каждого двигателя
        speed1=round((ch0-50)*(abs(ch1-50)+50)/50);
        speed2=round((ch1-50)*(abs(ch0-50)+50)/50);
        
        //корректируем значения и считаем скорость моторов
        speedmot1=speed1+speed2;
        speedmot2=speed1-speed2;        
            // Выставляем ограничения
        speedmot1=(speedmot1>100)?100:speedmot1;
        speedmot2=(speedmot2>100)?100:speedmot2;
        speedmot1=(speedmot1<-100)?-100:speedmot1;
        speedmot2=(speedmot2<-100)?-100:speedmot2;
        speedmot1=(speedmot1<20 && speedmot1>-20)?0:speedmot1;
        speedmot2=(speedmot2<20 && speedmot2>-20)?0:speedmot2;

              sd1=map(abs(speedmot1),0,100,0,255);
              sd2=map(abs(speedmot2),0,100,0,255);

              //Вывод значений для диагностики
              Serial.print(ch0);
              Serial.print(";");
              Serial.print(ch1);              
              Serial.print(";");              
              Serial.print(";");
              Serial.print(speed1);
              Serial.print(";");
              Serial.print(speed2);
              Serial.print(";");
              Serial.print(speedmot1);
              Serial.print(";");
              Serial.print(speedmot2);
              Serial.print(";");
              Serial.print(sd1);
              Serial.print(";");
              Serial.print(sd2);
              Serial.print(";wasdir");
              Serial.print(wasdir1);
              Serial.print(";");
              Serial.print(wasdir2);
              Serial.println(";");

              //Выдаем ШИМ для драйвера, если мы не в состоянии торможения
              if(tormozcount1==0 and tormozcount2==0){
                 if(sd1<220){
              analogWrite(STEP_PIN1,sd1);
                 }else{
              digitalWrite(STEP_PIN1,HIGH);
                 }

              if(sd2<220){   
              analogWrite(STEP_PIN2,sd2);
              }else{
              digitalWrite(STEP_PIN2,HIGH);
                 }
              
              }else{
              digitalWrite(STEP_PIN1,LOW);
              digitalWrite(STEP_PIN2,LOW);
              }

//торможение, выбег ротора
        if(speedmot1<40 and speedmot1>-40){
          Serial.println("Tormoz menshe 40 1 dvig;");
          digitalWrite(RELEPIN3,HIGH); 
          digitalWrite(STEP_PIN1,LOW); 
          tormozcount1=0;
        }else{
          digitalWrite(RELEPIN3,LOW);
          
        }
        if(speedmot2<40 and speedmot2>-40 ){ 
          Serial.println("Tormoz menshe 40 2 dvig;");
        digitalWrite(RELEPIN4,HIGH);  
        digitalWrite(STEP_PIN2,LOW);
        tormozcount2=0;
        }else{
          digitalWrite(RELEPIN4,LOW);
        }

//Если мы тормозим больше циклов, чем нужно для тормоза считаем, что мы неподвижны
if(speedmot1<40 and speedmot1>-40 and speedmot2<40 and speedmot2>-40){
skolkotormozim++;
}else{
 skolkotormozim=0; 
}

if( skolkotormozim>skolkotormozit){
  wasdir1=2;
  wasdir2=2;
  digitalWrite( RELEPIN5, LOW);
  digitalWrite( RELEPIN6, LOW);
  Serial.println("Stop for 10 cicles");
}

//смена направления хода
        if((speedmot1 < -10 and wasdir1==1) || (speedmot1 >=5 and wasdir1==0)){
          //Если новое направление не соответствует старому
              if(tormozcount1<=0){
                //если счетчик 0 тормозим
                Serial.println("Tormoz vibeg rotora 1 dvig;");
                digitalWrite(STEP_PIN1,LOW);
                digitalWrite(RELEPIN3,HIGH); 
                 tormozcount1=skolkotormozit;
              }
              if(tormozcount1>0){
                //Если уже тормозим
                digitalWrite(STEP_PIN1,LOW);
                tormozcount1--;
              }   
              if(tormozcount1==1){
                //если оттормозили
                tormozcount1--;
                digitalWrite(RELEPIN3,LOW); 
                Serial.println("Change 1dvig ");
                
                if(speedmot1 < 0){
                    wasdir1=0;
                    digitalWrite( RELEPIN5, HIGH);
                    Serial.println("vzad");
                  }else{
                    wasdir1=1;
                    digitalWrite( RELEPIN5, LOW);                    
                    Serial.println("vpered");
                 }
              }
        }

        if((speedmot2 < -10 and wasdir2==1) || (speedmot2 >=5 and wasdir2==0)){
          //Если новое направление не соответствует старому
              if(tormozcount2<=0){
                //если счетчик 0 тормозим
                Serial.println("Tormoz vibeg rotora 2 dvig;");
                digitalWrite(STEP_PIN2,LOW);
                digitalWrite(RELEPIN4,HIGH); 
                 tormozcount2=skolkotormozit;
              }
              if(tormozcount2>0){
                //Если уже тормозим
                digitalWrite(STEP_PIN2,LOW);
                tormozcount2--;
              }   
              if(tormozcount2==1){
                //если оттормозили
                tormozcount2--;
                digitalWrite(RELEPIN4,LOW); 
                 Serial.print("Change 2dvig ");
                
                  if(speedmot2 < 0){
                    wasdir2=0;
                    digitalWrite( RELEPIN6, HIGH);
                    Serial.println("vzad");
                  }else{
                    wasdir2=1;
                    digitalWrite( RELEPIN6, LOW);
                    Serial.println("vpered");
                    }
              }
        }

// Если долго никуда не ехали меняем направление сразу
if(speedmot1 < -40 and wasdir1==2){
wasdir1=0;
digitalWrite( RELEPIN5, HIGH); 
  Serial.println("Reverse 1 motor");
}

if(speedmot1 > 40 and wasdir1==2){
wasdir1=1;
digitalWrite( RELEPIN5, LOW); 
Serial.println("Forward 1 motor");
}

if(speedmot2 < -40 and wasdir2==2){
wasdir2=0;
digitalWrite( RELEPIN6, HIGH); 
Serial.println("Reverse 2 motor");
}

if(speedmot2 > 40 and wasdir2==2){
wasdir2=1;
digitalWrite( RELEPIN6, LOW); 
Serial.println("Forward 2 motor");
}
        
   /*   
//Диагностика
Serial.print(tormozcount1);
Serial.print(";");
Serial.print(tormozcount2); 
Serial.print(";");
Serial.print(wasdir1);
Serial.print(";");
Serial.print(wasdir2); 
Serial.print(";");
*/
//delay(1000);        
    }else{
//Если нет сигнала с пульта
    }
}


© Geektimes