Помогите объединить два и более скетчей в один

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем CasperSimfer, 7 дек 2014.

  1. CasperSimfer

    CasperSimfer Нуб

    Помогите пожалуйста объединить два скетча воедино. Такая ситуация. Сделал автоматически включающуюся лампу при наступлении темноты. Хочу добавить к этому скетчу ультразвуковой дальномер и еще ИК приемник. По какому принципу объединить все эти три скетча?
     
  2. acos

    acos Официальный гик Администратор

    Эм... Программирование это такая штука, в которой многое зависит от контекста) Что сделать хотите?)
     
  3. CasperSimfer

    CasperSimfer Нуб

    Эт я понимаю, что программирование дело такое. Хочу чтобы ИК приемник включал выключал лампу, когдя я захочу, независимо от дальномера, он должен будет включать лампу только тогда, когда будет ему помеха, а вот фоторезистор включал ее, когда стемнеет.
     
  4. CasperSimfer

    CasperSimfer Нуб

    так то по отдельности все работает, есть готовые скетчи
     
  5. Salk

    Salk Гик

    Давайте начнем с того, что вы один за одним выложите все скетчи с пометками/комментариями. Чтобы было нагляднее. И вместе начнем объединять, так чтобы и Вы сами поняли, что ничего сложного в этом нет. На примерах легче учится, чем писать "тонны" теории.
     
    acos нравится это.
  6. CasperSimfer

    CasperSimfer Нуб

    #include <IRremote.h>

    int RECV_PIN = 9;

    int Relay = 8;
    int redStat = 0;
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    void setup()
    {
    Serial.begin(9600);
    irrecv.enableIRIn(); // Запуск приемника
    pinMode(Relay, OUTPUT);
    }

    void loop() {
    if (irrecv.decode(&results)) {
    Serial.println(results.value);

    //красный
    if (results.value == 0x6F8877 && redStat == 0)
    {
    digitalWrite(Relay, HIGH);
    redStat = 1;
    }
    else
    if (results.value == 0x6F08F7 && redStat == 1)
    {
    digitalWrite(Relay, LOW);
    redStat = 0;
    }
    irrecv.resume(); // Получить слудующее значение
    }
    }

    это на ИК приемник
     
  7. CasperSimfer

    CasperSimfer Нуб

    #define Trig 9
    #define Echo 8
    #define Relay 10

    void setup()
    {
    pinMode(Trig, OUTPUT); //инициируем как выход
    pinMode(Echo, INPUT); //инициируем как вход
    pinMode(Relay, OUTPUT);
    Serial.begin(9600);
    /* задаем скорость общения. В нашем случае с компьютером */
    }
    unsigned int impulseTime=0;
    unsigned int distance_sm=0;

    void loop()
    {
    digitalWrite(Trig, HIGH);
    /* Подаем импульс на вход trig дальномера */
    delayMicroseconds(10); // равный 10 микросекундам
    digitalWrite(Trig, LOW); // Отключаем
    impulseTime=pulseIn(Echo, HIGH); // Замеряем длину импульса
    distance_sm=impulseTime/58; // Пересчитываем в сантиметры
    Serial.println(distance_sm); // Выводим на порт
    if (distance_sm<100) // Если расстояние менее 30 сантиметром
    {
    digitalWrite(Relay, LOW);
    delay(7000);
    }
    else
    {
    digitalWrite(Relay, HIGH);
    }
    delay(100);
    }
     
  8. CasperSimfer

    CasperSimfer Нуб

    И последний

    int sensePin = 0;
    int Relay = 10;



    void setup()
    {
    pinMode(Relay, OUTPUT);
    }

    void loop()
    {
    int val = analogRead(sensePin);
    if(val < 600) digitalWrite(Relay, HIGH);
    else digitalWrite(Relay, LOW);
    analogRead(sensePin);
    }



    По отдельности все работает. я вот что не могу понять, как их вместе соединить ?
     
  9. vvr

    vvr Инженерище

    В скетче с дальномером используется delay - будет тормозится работа других систем.
    для начала нужно от этих задержек избавится.
     
  10. vvr

    vvr Инженерище

    Раскидываем одинаковые пины

    Код (Text):

    #include <IRremote.h>

    int RECV_PIN = 7;  /// был пин 9

    int Relay1 = 12;  //// был пин 8
    int redStat = 0;
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    #define Trig 9
    #define Echo 8
    #define Relay 10
    unsigned int impulseTime=0;
    unsigned int distance_sm=0;


    int sensePin = 0;
    int Relay2 = 11;  //// был пин 10


    void setup()
    {
    ......

    }

    void loop()
    {
    .......
     
    }
     
  11. Salk

    Salk Гик

    Я так понимаю, что 1 код - это вкл/выкл реле с ИК-пульта
    2 код - ультразвуковой датчик
    3 код - датчик света

    И, что Вы хотите в итоге получить? Я так понимаю, реле одно, которое управляет лампой? И Вы хотите, чтобы при наступлении темноты лампа включалась, а так же можно было управлять ей с пульта, независимо от времени суток, а также, если расстояние менее 100 см до датчика, то тоже включалась лампа?

    vvr меня опередили :) Я так понял, что реле все таки будет одно. Тогда как-то так:
    Код (Text):
    // Здесь пишутся библиотеки
    #include <IRremote.h>
    // Здесь назначаются пины
    #define RECV_PIN 7 // IR будет на 7 пине
    #define Trig 9 // ультразвуковой датчик
    #define Echo 8
    #define Relay 10 // Реле на 10 пине
    #define sensePin 1 // Датчик света
    // Переменные
    int redStat; // "= 0" можно не писать, т.к. программа автоматически подставит 0
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    unsigned int impulseTime=0;
    unsigned int distance_sm=0;

    #define UD_UPDATE_TIME  100 // Время в мс, вместо delay
    unsigned long UDLastUpdateTime = 0;

    void setup()
    {
      Serial.begin(9600); // инициализация сериал монитора

      pinMode(Trig, OUTPUT); //инициируем как выход
      pinMode(Echo, INPUT); //инициируем как вход
      pinMode(RECV_PIN, INPUT); // ИК
      // Реле
      pinMode(Relay, OUTPUT);

      irrecv.enableIRIn(); // Запуск приемника
    }

    void loop()
    {
      if (irrecv.decode(&results))
      {
        Serial.println(results.value);
        //красный
        if (results.value == 0x6F8877 && redStat == 0)
        {
          digitalWrite(Relay, HIGH);
          redStat = 1;
        }
        else
          if (results.value == 0x6F08F7 && redStat == 1)
          {
            digitalWrite(Relay, LOW);
            redStat = 0;
          }
        irrecv.resume(); // Получить слудующее значение
      }

      if (millis() - UDLastUpdateTime > UD_UPDATE_TIME)
      {
        UDLastUpdateTime = millis();
        // Получаем данные с дальномера
        digitalWrite(Trig, HIGH);
        /* Подаем импульс на вход trig дальномера */
        delayMicroseconds(10); // равный 10 микросекундам
        digitalWrite(Trig, LOW); // Отключаем
        impulseTime=pulseIn(Echo, HIGH); // Замеряем длину импульса
        distance_sm=impulseTime/58; // Пересчитываем в сантиметры
        Serial.println(distance_sm); // Выводим на порт

        if (distance_sm<100) // Если расстояние менее 30 сантиметром
        {
          digitalWrite(Relay, LOW);
        }
        else
        {
          digitalWrite(Relay, HIGH);
        }
      }

        int val = analogRead(sensePin);
        if(val < 600)
        {
          digitalWrite(Relay, HIGH);
        }
        else
        {
          digitalWrite(Relay, LOW);
        }
    }
    Но это грубый пример, т.к. условия могут друг другу противоречить, с пульта реле не выключится, если расстояние датчика меньше 100 см, к примеру. Но, как пример объединения кода, вполне.
     
    Последнее редактирование: 7 янв 2015
    Игорюшка Владимирович и roni нравится это.
  12. YAN

    YAN Нуб

    Доброго времени суток, вопрос у меня похожий , поэтому не создаю новую тему (да простит меня топикстартер)... итак есть 2 скетча, каждый из них работает так как мне надо но как их объединить в один , но не просто объединить , а чтобы можно было запускать независимо либо один либо другой, например включаем контроллер появляется менюшка - типа ЧТО ЗАПУСКАЕМ? №1 или №2.
     
  13. Creator

    Creator Нерд

    Правильно ли понимаю - избавиться можно через использование обработчиков аппаратных прерываний?
     
  14. vvr

    vvr Инженерище

    millis()
     
    roni нравится это.
  15. Creator

    Creator Нерд

    Так себе решение, на мой взгляд.
    Получается, мне в коде надо время от времени проверять текущее время, сравнивать с отметкой и т.д.
    А если по объективным причинам до измерений дело просто-напросто вовремя не дойдёт?
     
  16. robokop

    robokop Гик

    Тоже самое. Помогите соединить 2 кода :
    Код (Text):
     /*
    * IR-led & phototransistor
    * тестовый скетч для работы с фототранзистором
    * замер разности освещённости
    *
    * http://robocraft.ru
    */

    int photoPin = 0;  // фоторезистор подключен 0-му аналоговому входу
    int ledPin = 13;  // светодиод подключается к digital pin 9
    int val = 0;      // переменная для хранения значения входного напряжения

    void setup()
    {
      Serial.begin(9600);
    }

    void loop()
    {
      digitalWrite(ledPin, HIGH);    // зажигаем
      delay(2);
      val = analogRead(photoPin);    // считываем значение с фототранзистора

      digitalWrite(ledPin, LOW);    // гасим
      delay(2);
      val = val - analogRead(photoPin);  // считываем значение с фототранзистора
     
      Serial.println(val);

      delay(200);
    }
    и :
    Код (Text):
     #include <Servo.h> // Добавляем библиотеку
       
        Servo myservoH; // Горизонтальная серва углы от 25 до 145 (центровка 85)
        Servo myservoV; // Вертикальная серва углы от 0 до 35
        const int H_SERVO_PIN = 9 ; // Горизонтальная серва подключена к пину 11
        const int V_SERVO_PIN = 10; //Пин вертикального сервопривода
        const float H_L_ANGLE = 145; // Максимальные угл поворота башни налево
        const float H_R_ANGLE = 25;  // Максимальные угл поворота башни направо
        const float H_DEF_ANGLE = 85; // Дефолтный угол (центровка)
        const float V_U_ANGLE = 55;  // Максимальные угл поворота башни вверх
        const float V_D_ANGLE = 0; // Максимальные угл поворота башни вниз
        const float V_DEF_ANGLE = 25; // Дефолтный угол (центровка)
        //Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв
        const float V_STEP = 0.007; // Шаг - знаение отвечающее за скорость вращения по вертикали.
        const float H_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по горизонтали
        float curVAngle = V_DEF_ANGLE; //Переменная текущего угла верт. сервы
        float curHAngle = H_DEF_ANGLE; //Переменная текущего угла гор. сервы
        bool moveServoVUp = false; //Флаг движения верт. сервы вверх
        bool moveServoVDown = false; //Флаг движения верт. сервы вниз
        bool moveServoHLeft = false; //Флаг движения гор. сервы влево
        bool moveServoHRight = false; //Флаг движения гор. сервы вправо
       
        const int TIMEOUT_TIME_MS = 150;
        unsigned long lastPilotSymbolTime;
        char symbol;
       
        int val;
        // Выводы шилда привязываются к Arduino
        int IN1 = 8 ;
        int IN2 = 7 ;
        int EN1 = 11 ;
        int EN2 = 3 ;
        // Для удобства подключения, затвор мосфета подключен к аналоговому входу A0, однако,
        // входы A0-A6 можно использовать как цифровые, в коде будут нумероваться как 14-19
        int SHOT = 14;
        int LED = 13; // Используем встроенный светодиод для индикации работы
       
        enum States
        {
          WAITING,
          READING,
          RUNNING,
          ERROR,
          TIMEOUT
        };
       
        States state;
        States onWait();
        States onRead();
        States onRun();
        States onError();
       
        States onTimeout();
       
        void performServo();
       
        void setup()
        {
          Serial.begin(9600);      // crjhjcnm cdzpb c rjvgm.nthjv
          lastPilotSymbolTime = 0;
          pinMode(IN1, OUTPUT);
          pinMode(IN2, OUTPUT);
          pinMode(EN1, OUTPUT);
          pinMode(EN2, OUTPUT);
          pinMode(SHOT, OUTPUT);
          // устанавливаем пин как вывод управления сервой
          myservoH.attach(H_SERVO_PIN);
          myservoV.attach(V_SERVO_PIN);
          myservoH.write(curHAngle);
          myservoV.write(curVAngle);
          //используем 13 пин как индикатор включённой ардуины
          pinMode(LED, OUTPUT);
          digitalWrite(LED, HIGH);
        }
       
        void loop()
        {
          switch (state)
          {
          case WAITING:
            state = onWait();
            break;
          case READING:
            state = onRead();
            break;
          case RUNNING:
            state = onRun();
            break;
          case TIMEOUT:
            state = onTimeout();
            break;
          default:
            state = onError();
          }
          //Вызываем функцию управление сервами
          performServo();
        }
       
        States onWait()
        {
          if (Serial.available() > 0)
          {
            return READING;
          }
          if (lastPilotSymbolTime && (millis() - lastPilotSymbolTime > TIMEOUT_TIME_MS))
          {
            return TIMEOUT;
          }
          return WAITING;
        }
       
        States onRead()
        {
          symbol = Serial.read();
          return RUNNING;
        }
       
        States onRun()
        {
          switch (symbol)
          {
          case 'W':
            //начало действий при полученном символе 'W' (вперед)
            //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
            digitalWrite(EN1, HIGH);
            digitalWrite(EN2, HIGH);
            digitalWrite(IN1, LOW);
            digitalWrite(IN2, LOW);
            break;
            //начало действий при полученном символе 'S' (назад)
            //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
          case 'S':
            digitalWrite(EN1, HIGH);
            digitalWrite(EN2, HIGH);
            digitalWrite(IN1, HIGH);
            digitalWrite(IN2, HIGH);
            break;
            //начало действий при полученном символе 'D' (вправо)
            //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
          case 'D':
            digitalWrite(EN1, HIGH);
            digitalWrite(EN2, HIGH);
            digitalWrite(IN1, LOW);
            digitalWrite(IN2, HIGH);
            break;
            //начало действий при полученном символе 'A' (влево)
            //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
          case 'A':
            digitalWrite(EN1, HIGH);
            digitalWrite(EN2, HIGH);
            digitalWrite(IN1, HIGH);
            digitalWrite(IN2, LOW);
            break;
          case 'E':
            //начало действий при полученном символе 'E' (остановка)
            //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
            digitalWrite(SHOT, HIGH);
            break;  
       
            ////////////////////////////// Сервы
          case 'I': //servoV вверх
            moveServoVUp = true;
            break;
          case 'K': //servoV вниз
            moveServoVDown = true;
            break;
          case 'i': //servoV стоп
            moveServoVUp = false;
            moveServoVDown = false;
            break;
          case 'L': //servoH движется к 25
            moveServoHRight = true;
            break;
          case 'J': //servoH движется к 145
            moveServoHLeft = true;
                break;
          case 'l': //servoH стоп
            moveServoHLeft = false;
            moveServoHRight = false;
            break;  
          case 'U':
            curVAngle = V_DEF_ANGLE;
            curHAngle = H_DEF_ANGLE;
            myservoV.write(curVAngle);
            myservoH.write(curHAngle);
            break;
            //////////////////////////////

          case 'T':
            //начало действий при полученном символе 'T' (остановка)
            //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
            digitalWrite(EN1, LOW);
            digitalWrite(EN2, LOW);
            digitalWrite(SHOT, LOW);
            break;
          case 'P':
            //получили контрольный символ, не изменяйте этот код
            lastPilotSymbolTime = millis();
            break;
          default:
            return ERROR;
          }
          return WAITING;
        }
       
        States onError()
        {
          //Получены неоговоренные символы. Очищаем ввод и продолжаем.
          //Здесь можно добавить какие-то действия для этой ситуации.
          //...
          while (Serial.available())
          {
            Serial.read();
          }
          return WAITING;
        }
       
        States onTimeout()
        {
          //Действия при таймауте.
          //Вероятно, связь утеряна,
          //но при получении контрольного символа она будет восстановлена.
          //Здесь, например, уместно выключить двигатели
          //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
          digitalWrite(EN1, LOW); // На выводы ENABLE поданы сигналы низкого уровня, моторы не работают
          digitalWrite(EN2, LOW);
          digitalWrite(SHOT, LOW);
          if (Serial.available())
          {
            return READING;
          }
          return TIMEOUT;
        }
       
        //Функция управления сервоприводами (вызывается в теле loop на каждой итерации)
        //Выполняет изменения положения серв на подобранный шаг согласно установленным флагам движения
        //Флаги устанавливаются согласно поступившим символам управления сервами
        void performServo()
        {
          //Установлен флаг движения вверх и текущий угол не максимальный
          if (moveServoVUp && curVAngle + V_STEP <= V_U_ANGLE)
          {
            //К текущему верт. углу прибавляем шаг
            curVAngle += V_STEP;
          }
          //Установлен флаг движения вниз и текущий угол не минимален
          else if (moveServoVDown && curVAngle - V_STEP >= V_D_ANGLE)
          {
            //От текущего верт. угла отнимаем шаг
            curVAngle -= V_STEP;
          }
          //Установлен флаг движения влево и текущий угол не максимален
          if (moveServoHLeft && curHAngle + H_STEP <= H_L_ANGLE)
          {
            //К текущему гор. углу прибавляем гор. шаг
            curHAngle += H_STEP;
          }
          //Установлен флаг движения вправо и текущий угол не минимален
          else if (moveServoHRight && curHAngle - H_STEP >= H_R_ANGLE)
          {
            //От текущего угла отнимаем гор. шаг
            curHAngle -= H_STEP;
          }
       
          //Если было движние по вертикали
          if (moveServoVUp || moveServoVDown)
          {
                myservoV.write(curVAngle);
          }
          //Если было движение по горизонтали
          if (moveServoHLeft || moveServoHRight)
          {
            myservoH.write(curHAngle);
          }
        }
     
  17. Alex19

    Alex19 Гуру

    Не очень понятно, что именно у Вас не получается.

    Возьмите за базу 2 код, объявите глобальные переменные
    Код (Text):
    int photoPin = 0;  // фоторезистор подключен 0-му аналоговому входу
    int ledPin = 13;  // светодиод подключается к digital pin 9
    int val = 0;      // переменная для хранения значения входного напряжения
     
    Уберите ledPin, во втором коде он уже объявлен как LED и переименуйте int val = 0; на photoVal, чтобы не было конфликта.

    Затем вынесите данный код, в отдельную функцию
    Код (Text):

      digitalWrite(ledPin, HIGH);    // зажигаем
      delay(2);
      val = analogRead(photoPin);    // считываем значение с фототранзистора

      digitalWrite(ledPin, LOW);    // гасим
      delay(2);
      val = val - analogRead(photoPin);  // считываем значение с фототранзистора
       Serial.println(val);
     
    А в loop вызывайте ее после performServo();, каждые 0,2 секунды без delay. Смотрите пример - https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay.

    Примерно так.
    Код (Text):
    #include <Servo.h> // Добавляем библиотеку

    int photoPin = 0;  // фоторезистор подключен 0-му аналоговому входу
    //int ledPin = 13;  // светодиод подключается к digital pin 9
    int photoVal = 0;      // переменная для хранения значения входного напряжения

    unsigned long previousMillis = 0;       // https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay.
    unsigned long interval = 200;    // https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay.

    Servo myservoH; // Горизонтальная серва углы от 25 до 145 (центровка 85)
    Servo myservoV; // Вертикальная серва углы от 0 до 35
    const int H_SERVO_PIN = 9 ; // Горизонтальная серва подключена к пину 11
    const int V_SERVO_PIN = 10; //Пин вертикального сервопривода
    const float H_L_ANGLE = 145; // Максимальные угл поворота башни налево
    const float H_R_ANGLE = 25;  // Максимальные угл поворота башни направо
    const float H_DEF_ANGLE = 85; // Дефолтный угол (центровка)
    const float V_U_ANGLE = 55;  // Максимальные угл поворота башни вверх
    const float V_D_ANGLE = 0; // Максимальные угл поворота башни вниз
    const float V_DEF_ANGLE = 25; // Дефолтный угол (центровка)
    //Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв
    const float V_STEP = 0.007; // Шаг - знаение отвечающее за скорость вращения по вертикали.
    const float H_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по горизонтали
    float curVAngle = V_DEF_ANGLE; //Переменная текущего угла верт. сервы
    float curHAngle = H_DEF_ANGLE; //Переменная текущего угла гор. сервы
    bool moveServoVUp = false; //Флаг движения верт. сервы вверх
    bool moveServoVDown = false; //Флаг движения верт. сервы вниз
    bool moveServoHLeft = false; //Флаг движения гор. сервы влево
    bool moveServoHRight = false; //Флаг движения гор. сервы вправо

    const int TIMEOUT_TIME_MS = 150;
    unsigned long lastPilotSymbolTime;
    char symbol;

    int val;
    // Выводы шилда привязываются к Arduino
    int IN1 = 8 ;
    int IN2 = 7 ;
    int EN1 = 11 ;
    int EN2 = 3 ;
    // Для удобства подключения, затвор мосфета подключен к аналоговому входу A0, однако,
    // входы A0-A6 можно использовать как цифровые, в коде будут нумероваться как 14-19
    int SHOT = 14;
    int LED = 13; // Используем встроенный светодиод для индикации работы

    enum States
    {
      WAITING,
      READING,
      RUNNING,
      ERROR,
      TIMEOUT
    };

    States state;
    States onWait();
    States onRead();
    States onRun();
    States onError();

    States onTimeout();

    void performServo();

    void setup()
    {
      Serial.begin(9600);      // crjhjcnm cdzpb c rjvgm.nthjv
      lastPilotSymbolTime = 0;
      pinMode(IN1, OUTPUT);
      pinMode(IN2, OUTPUT);
      pinMode(EN1, OUTPUT);
      pinMode(EN2, OUTPUT);
      pinMode(SHOT, OUTPUT);
      // устанавливаем пин как вывод управления сервой
      myservoH.attach(H_SERVO_PIN);
      myservoV.attach(V_SERVO_PIN);
      myservoH.write(curHAngle);
      myservoV.write(curVAngle);
      //используем 13 пин как индикатор включённой ардуины
      pinMode(LED, OUTPUT);
      digitalWrite(LED, HIGH);
    }

    void loop()
    {
      switch (state)
      {
      case WAITING:
        state = onWait();
        break;
      case READING:
        state = onRead();
        break;
      case RUNNING:
        state = onRun();
        break;
      case TIMEOUT:
        state = onTimeout();
        break;
      default:
        state = onError();
      }
      //Вызываем функцию управление сервами
      performServo();
     
      // https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay.
      unsigned long currentMillis = millis();
      if(currentMillis - previousMillis > interval)
      {
        previousMillis = currentMillis;
        sendData();
      }
    }

    void sendData()
    {
      digitalWrite(LED, HIGH);    // зажигаем
      delay(2);
      photoVal = analogRead(photoPin);    // считываем значение с фототранзистора

      digitalWrite(LED, LOW);    // гасим
      delay(2);
      photoVal = photoVal - analogRead(photoPin);  // считываем значение с фототранзистора
      Serial.println(photoVal);
    }

    States onWait()
    {
      if (Serial.available() > 0)
      {
        return READING;
      }
      if (lastPilotSymbolTime && (millis() - lastPilotSymbolTime > TIMEOUT_TIME_MS))
      {
        return TIMEOUT;
      }
      return WAITING;
    }

    States onRead()
    {
      symbol = Serial.read();
      return RUNNING;
    }

    States onRun()
    {
      switch (symbol)
      {
      case 'W':
        //начало действий при полученном символе 'W' (вперед)
        //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
        digitalWrite(EN1, HIGH);
        digitalWrite(EN2, HIGH);
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, LOW);
        break;
        //начало действий при полученном символе 'S' (назад)
        //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
      case 'S':
        digitalWrite(EN1, HIGH);
        digitalWrite(EN2, HIGH);
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, HIGH);
        break;
        //начало действий при полученном символе 'D' (вправо)
        //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
      case 'D':
        digitalWrite(EN1, HIGH);
        digitalWrite(EN2, HIGH);
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, HIGH);
        break;
        //начало действий при полученном символе 'A' (влево)
        //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
      case 'A':
        digitalWrite(EN1, HIGH);
        digitalWrite(EN2, HIGH);
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, LOW);
        break;
      case 'E':
        //начало действий при полученном символе 'E' (остановка)
        //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
        digitalWrite(SHOT, HIGH);
        break;

        ////////////////////////////// Сервы
      case 'I': //servoV вверх
        moveServoVUp = true;
        break;
      case 'K': //servoV вниз
        moveServoVDown = true;
        break;
      case 'i': //servoV стоп
        moveServoVUp = false;
        moveServoVDown = false;
        break;
      case 'L': //servoH движется к 25
        moveServoHRight = true;
        break;
      case 'J': //servoH движется к 145
        moveServoHLeft = true;
        break;
      case 'l': //servoH стоп
        moveServoHLeft = false;
        moveServoHRight = false;
        break;
      case 'U':
        curVAngle = V_DEF_ANGLE;
        curHAngle = H_DEF_ANGLE;
        myservoV.write(curVAngle);
        myservoH.write(curHAngle);
        break;
        //////////////////////////////

      case 'T':
        //начало действий при полученном символе 'T' (остановка)
        //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
        digitalWrite(EN1, LOW);
        digitalWrite(EN2, LOW);
        digitalWrite(SHOT, LOW);
        break;
      case 'P':
        //получили контрольный символ, не изменяйте этот код
        lastPilotSymbolTime = millis();
        break;
      default:
        return ERROR;
      }
      return WAITING;
    }

    States onError()
    {
      //Получены неоговоренные символы. Очищаем ввод и продолжаем.
      //Здесь можно добавить какие-то действия для этой ситуации.
      //...
      while (Serial.available())
      {
        Serial.read();
      }
      return WAITING;
    }

    States onTimeout()
    {
      //Действия при таймауте.
      //Вероятно, связь утеряна,
      //но при получении контрольного символа она будет восстановлена.
      //Здесь, например, уместно выключить двигатели
      //[ДОБАВИТЬ СВОЙ КОД НИЖЕ]
      digitalWrite(EN1, LOW); // На выводы ENABLE поданы сигналы низкого уровня, моторы не работают
      digitalWrite(EN2, LOW);
      digitalWrite(SHOT, LOW);
      if (Serial.available())
      {
        return READING;
      }
      return TIMEOUT;
    }

    //Функция управления сервоприводами (вызывается в теле loop на каждой итерации)
    //Выполняет изменения положения серв на подобранный шаг согласно установленным флагам движения
    //Флаги устанавливаются согласно поступившим символам управления сервами
    void performServo()
    {
      //Установлен флаг движения вверх и текущий угол не максимальный
      if (moveServoVUp && curVAngle + V_STEP <= V_U_ANGLE)
      {
        //К текущему верт. углу прибавляем шаг
        curVAngle += V_STEP;
      }
      //Установлен флаг движения вниз и текущий угол не минимален
      else if (moveServoVDown && curVAngle - V_STEP >= V_D_ANGLE)
      {
        //От текущего верт. угла отнимаем шаг
        curVAngle -= V_STEP;
      }
      //Установлен флаг движения влево и текущий угол не максимален
      if (moveServoHLeft && curHAngle + H_STEP <= H_L_ANGLE)
      {
        //К текущему гор. углу прибавляем гор. шаг
        curHAngle += H_STEP;
      }
      //Установлен флаг движения вправо и текущий угол не минимален
      else if (moveServoHRight && curHAngle - H_STEP >= H_R_ANGLE)
      {
        //От текущего угла отнимаем гор. шаг
        curHAngle -= H_STEP;
      }

      //Если было движние по вертикали
      if (moveServoVUp || moveServoVDown)
      {
        myservoV.write(curVAngle);
      }
      //Если было движение по горизонтали
      if (moveServoHLeft || moveServoHRight)
      {
        myservoH.write(curHAngle);
      }
    }
     
     
    roni и buktopz нравится это.
  18. buktopz

    buktopz Нерд

    Не сочтите за наглость, я тоже хочу вам два скетча подбросить.
    Первый - датчик газа:
    #include <LiquidCrystal.h> // добавляем библиотеку для работы с LCD

    LiquidCrystal lcd(12, 11, 6, 4, 3, 2); // определяем наш LCD(числа в скобках это наши пины на Arduino)
    const int analogInPin = A0; // определяем наш датчик(A0 - аналоговый вход куда подключен наш датчик)
    int sensorValue = 0; //объявляем переменную для работы с датчиком

    void setup() {
    Serial.begin(9600); //это для работы с Serial. В нашем случае он не обязателен, но пускай будет для вывода ошибок
    lcd.begin(16, 2); //наш размер LCD. Мой LCD поддерживает 16 символов и две строки.
    }

    void loop() {
    sensorValue = analogRead(analogInPin); // считываем значения с датчика в переменную sensorValue
    Serial.println(sensorValue); // выводим в Serial значения с датчика на всякий случай если вдруг не заработает LCD

    if (sensorValue >= 500) {
    lcd.setCursor(0, 0); // ставим курсор на 0 символ и 0 строку. Отсчет идет с нуля.
    lcd.clear(); // очищаем экран LCD
    lcd.print("Gas!"); // если значение с датчика будет свыше чем 500, то на LCD появится надпись "Gas!"
    digitalWrite(9, HIGH); // сигнал тревоги на модем с вывода 9 Ардуино
    delay(1000); // длительность сигнала тревоги
    digitalWrite(9, LOW);
    delay(10000); // длительность паузы сигнала тревоги

    }
    else {
    lcd.setCursor(0, 0);
    lcd.clear();
    lcd.print("Normal!"); // если датчик выдает меньше 500, то на экран нам показывается "Normal!"

    }
    lcd.setCursor(0, 1); // ставим курсор на вторую строку
    lcd.print("Sensor = "); // на второй строке печатаем "Sensor = "
    lcd.print(sensorValue); // показуем сколько нам выдает датчик
    lcd.setCursor(0, 1);
    delay(1000); // повтор каждые 300 миллисекунд
    }



    //Сюда я добавил сигнал тревоги на модем с вывода 9 Ардуино, ну и избавился от одинаковых пинов

    //Второй скетч - сигнализация на GSM модеме, на него должен приходить сигнал с вывода 9 Ардуино.
    //Вот его код:
    #include <SoftwareSerial.h>
    SoftwareSerial gsm(7, 8); // RX, TX
    //#define gsm Serial1

    #define LED 13
    #define pinBOOT 5 // нога BOOT или K на модеме
    #define wakeUpPin 2 /// нога на растяжку
    #define TELLNUMBER "ATD+70001112233;" // номер на который будем звонить

    boolean flag = 0;

    void modemOFF(){
    digitalWrite(pinBOOT, HIGH);
    delay(10);
    gsm.println("AT+CPWROFF");
    }

    void modemON(){
    digitalWrite(pinBOOT, LOW);
    delay(10);
    while(!gsm.find("+PBREADY"));
    }


    void setup(){
    Serial.begin(9600);
    gsm.begin(9600); /// незабываем указать скорость работы UART модема
    Serial.println("ard_start");

    pinMode(LED, OUTPUT);
    pinMode(pinBOOT, OUTPUT); /// нога BOOT на модеме
    pinMode(wakeUpPin, INPUT_PULLUP); /// нога на растяжку

    digitalWrite(pinBOOT, LOW); /// включаем модем, для проверки.
    /// !!! при подачи питания, нужно надавить на ресет ардуины,
    /// !!! модем при включении может просадить питание и ардуина не стартанет
    while(!gsm.find("+PBREADY")); /// при включении ждем готовность модема

    gsm.println("ATE0"); // выключаем эхо

    Serial.println("modemOFF");
    modemOFF(); /// и выключаем модем


    }

    void loop() {



    digitalWrite(LED, HIGH); /// можно закомментировать, показываем что не висим.
    delay(25);
    digitalWrite(LED, LOW);
    /////////////
    if (digitalRead(wakeUpPin) && flag == 0){ /// проверяем и если оборвали растяжку
    modemON(); /// включаем модема
    while(1){ // ждем подключение модема к сети
    gsm.println("AT+COPS?");
    if (gsm.find("+COPS: 0")) break;
    delay(500);
    }
    delay(100);
    /////////////////////// звоним по указаному номеру
    gsm.println(TELLNUMBER);
    delay(100);
    if (gsm.find("OK")) Serial.println("ATD+OK!");

    while(1){ // проверяем готовность модема, ждем сброс вызова
    gsm.println("AT+CPAS");
    if (gsm.find("0")) break;
    delay(100);
    }

    delay(10000);
    Serial.println("FULL_OFF!");

    modemOFF(); /// выключаем модем,
    flag = 1; /// останавливаем прогу

    }

    Знаю точно, что сам не смогу, но с вашей помощью постараюсь понять как это делать в дальнейшем самому. Заранее благодарен
     
  19. Alex19

    Alex19 Гуру

    Ближе к вечеру гляну.

    На будущие, просьба:
    Чтобы можно было лучше разобраться в коде, желательно использовать теги CODE и /CODE (поместив их в квадратные скобки) для обрамления программы или специальную кнопку на странице, на которой (кнопке) угловые скобки на листке с хинтом (высвечивающейся при наведении мыши надписью) "код". Причем перед вставкой очень желательно оформить код с отступами.
     
    buktopz нравится это.
  20. buktopz

    buktopz Нерд

    спасибо, понял, учту
    я пробовал объединить, перекинул еще один пин повторяющийся, ошибок нет, но нет ничего на дисплее