помогите, пожалуйста, с кодом

Тема в разделе "Arduino & Shields", создана пользователем Hank Hill, 15 сен 2017.

  1. Hank Hill

    Hank Hill Нерд

    Схват манипулятора выполняет операции на нескольких высотах, для которых определены глобальные константы в самом начале (перед setup-ом)
    В рамках выполнения одной команды, полученной от оператора, схват должен несколько раз подняться-опуститься между рабочими высотами, для чего есть функция action_s1_m4()

    Два вопроса:
    1. Почему данные функции не крутят ШД ?
    2. Как можно ли сократить код, засунув команду присвоения нового значения переменной zCurrPos (текущее положение рабочего органа по оси Zв функцию driveZ, а не action_s1_m4() ?
    спасибо заранее
    Код (C++):

    #define Z_STANDS_HEIGHT       0     //координата по оси Z подставок
    #define Z_SKIDS_HEIGHT       20     //координата по оси Z брусьев
    #define Z_MAGNET_HEIGHT      40     //координата по оси Z точки примагничивания
    #define Z_MOVE_LOADED_HEIGHT 30     //координата по оси Z высоты перемещения загруженного схвата
    #define Z_HOME_HEIGHT       260     //координата по оси Z высоты перемещения пустого схвата

    void action_s1_m4()
    {
            driveX(xCurrPos, X_DROP_POINT_DIST);       // Проехать до 0 по оси Х  
            driveZ(zCurrPos, Z_SKIDS_HEIGHT)   ;       //  Опуститься до H один  
        zCurrPos = Z_SKIDS_HEIGHT;                     // Обновляем значение текущего положения по оси Z
            closeGraber()                      ;      //  Закрыть схват  
            driveZ(zCurrPos, Z_MOVE_LOADED_HEIGHT);   //  Подняться до Н перемещений
           zCurrPos = Z_SKIDS_HEIGHT;                // Обновляем значение текущего положения по оси Z
            driveX(xCurrPos, X_MAIN_RES_DIST) ;      //  Проехать до 520 по оси Х
            driveZ(zCurrPos, Z_STANDS_HEIGHT)  ;    //  Опуститься до Н ноль  
           zCurrPos = Z_STANDS_HEIGHT;              // Обновляем значение текущего положения по оси Z
            openGraber()                        ;   //  Открыть схват  
            driveZ(zCurrPos, Z_HOME_HEIGHT)     ;   //  Подняться до Н три    
          zCurrPos = Z_HOME_HEIGHT;
    }

    // Пишем функцию движения по оси Z с двумя входными параметрами: текущее положение (zCurrPos) и требуемое командой (zComPos)

    void driveZ (int zCurrPos, int zComPos)
    {
      if (zCurrPos > zComPos)
         {         digitalWrite(DIR_Z_PIN, HIGH);             //задаем направление
          for (int i = zCurrPos; i <= zComPos; i--)          //задаем количество шагов
     
        digitalWrite(STEP_Z_PIN, HIGH);
        delay(STEP_Z_MILLIS);

        digitalWrite(STEP_Z_PIN, LOW);
        delay(STEP_Z_MILLIS);
      }      
        else if (zCurrPos <= zComPos);
         {         digitalWrite(DIR_Z_PIN, LOW);             //задаем направление
      for (int i = zCurrPos; i <= zComPos; i++)             //задаем количество шагов
     
        digitalWrite(STEP_Z_PIN, HIGH);
        delay(STEP_Z_MILLIS);

        digitalWrite(STEP_Z_PIN, LOW);
        delay(STEP_Z_MILLIS);
      }
      }
     
     
  2. ORLENOK

    ORLENOK Гик

    Точно так же, как сделано это в driveX();
    У вас же есть глобальная переменная zCurrPos. Я думаю можно в метод передавать только переменную, в которой будет значение куда перейти. И в конце метода сделать zCurrPos = zComPos;
    Если сделаете это сейчас, то работать не будет. Int передается по значению, а не по ссылке (это можно поменять)
     
    Hank Hill нравится это.
  3. Tomasina

    Tomasina Сушитель лампочек Модератор

    Вот это выполняется n количество раз
    Код (C++):
    for (int i = zCurrPos; i <= zComPos; i--)
     digitalWrite(STEP_Z_PIN, HIGH);
    а вот это только один раз
    Код (C++):
    delay(STEP_Z_MILLIS);
    digitalWrite(STEP_Z_PIN, LOW);
    delay(STEP_Z_MILLIS);
     
  4. Hank Hill

    Hank Hill Нерд

    при таком написании шаговик начинает гудеть и по-прежнему не крутиться
     
  5. Tomasina

    Tomasina Сушитель лампочек Модератор

    Так это и есть твоё написание, я от себя ничего не добавил.
    У тебя скобки для цикла пропущены.
     
    Hank Hill нравится это.
  6. Hank Hill

    Hank Hill Нерд

    переписал таким образом, ШД крутится, но с нездоровым треском и рывками и медленнее. Хотя при тестовом скече и таком же подключении все Ok.
    Код (C++):
    // Пишем функцию движения по оси Z с одним входным параметром: полученное командой (требуемое) положение по оси Z
      // текущее положение не передаем, поскольку это глобальная переменная
    void driveZ (int zComPos)
    {
            digitalWrite(EN_Z_PIN, HIGH);                   //подача напряжения на enable драйвера
      if (zCurrPos > zComPos)
         {
           digitalWrite(DIR_Z_PIN, HIGH);                //задаем направление    
               
          for (int i = zCurrPos; i <= zComPos; i--)          //задаем количество шагов
                   
                    digitalWrite(STEP_Z_PIN, HIGH);
                    delay(STEP_Z_MILLIS);

                    digitalWrite(STEP_Z_PIN, LOW);
                    delay(STEP_Z_MILLIS);
        }      
     
        else if (zCurrPos <= zComPos);
         {         digitalWrite(DIR_Z_PIN, LOW);             //задаем направление
                                 
          for (int i = zCurrPos; i <= zComPos; i++)             //задаем количество шагов
         
                    digitalWrite(STEP_Z_PIN, HIGH);
                    delay(STEP_Z_MILLIS);

                    digitalWrite(STEP_Z_PIN, LOW);
                    delay(STEP_Z_MILLIS);
                                               
         }
          zCurrPos = zComPos;  //обновляем значение переменной zCurrPos    
                 
      }
     
  7. Hank Hill

    Hank Hill Нерд

    Точно, спасибо!!!!
    Заработало
     
  8. Tomasina

    Tomasina Сушитель лампочек Модератор

    Для невнимательных упрощу:
    Код (C++):
    int a = 0;
    int b = 0;
    for (int i = 0; i <= 8; i++)
      a = a + 1; // digitalWrite(STEP_Z_PIN, HIGH);
      delay(STEP_Z_MILLIS);
      b = b + 1; // digitalWrite(STEP_Z_PIN, LOW);
      delay(STEP_Z_MILLIS);
    Чему будут равны a и b после прогона?
     
  9. 6umer

    6umer Нуб

    Здравствуйте. Собрал вытяжку в душевую комнату, воспользовался скетчем взятым с интернета, в статье автора точно было изложено все по компановке и наименованию деталей arduino, а вот с кодом хотя он и простой я по не грамотности разобраться ещё не смог. Подскажите пожалуйста, суть такая, при достижении влажности более 40% включается вентилятор когда влажность становится менее 37% вытяжка отключается, присутствует ещё одно условие вентилятор отключается когда включается свет, тоесть вытяжка работает только в темноте какая бы не была влажность при включении света всё отключается. Собрав и подключив все датчики и реле согласно скетчу, моя вытяжка включается на постоянную и отключается при включении света, а на влажность ей почему-то пофиг. Думал может подключил не правильно, но просмотрев монитор порта я вижу показания влажности, и они как бы говорят что вытяжке порабы отключится , но она молотит.
    Подскажите пожалуйста, что нужно изменить.
    ventilyator-v-vannoj.jpg
     

    Вложения:

    Последнее редактирование: 20 сен 2017
  10. Tomasina

    Tomasina Сушитель лампочек Модератор

    Аппаратное решение - клавиша выключателя разрывает цепь вентилятора. 100% надежно.
     
    DIYMan и Limoney нравится это.
  11. 6umer

    6umer Нуб

    Ну Вы правы да. И все же когда всё собрано уже по схеме этой ?
     
  12. 6umer

    6umer Нуб

    И что за народ кругом, на улице и в интернете. Я ведь с вопросом с конкретным, а тут На! Клавишу надо было вешать, и всё) а остальные потдерживают. А возможности клавишу то повесить или реле возможности на месте нет, так как освещение будет переделываться другими людьми и разбираться не станут они. Я же говорю кругом важные все и знающие, работу друг друга не уважающие. А теперь минусите..

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

    ImrDuke Гик

    Добавьте вывод в монитор порта состояние флагов и посмотрите что происходит.
     
  14. 6umer

    6umer Нуб

    Извините. Можно подробнее?
    В мониторе в данный момент рядом нет ноутбука точно сказать не могу, есть информация по какой причине в данный момент не крутится вентилятор, тоесть или Свет или Влажность менее 37%.
    А Вы наверное не об этом ?
     
  15. ImrDuke

    ImrDuke Гик

    Это даже уже есть. Какие там данные получаются?
    Код (C++):
      Serial.print("T: ");
      Serial.println(vent);
     
  16. DIYMan

    DIYMan Guest

    В прошивке присутствуют флаги: vent, Hidrvent и т.п. Выведите их в монитор порта и гляньте - что происходит по флагам.
     
  17. Tomasina

    Tomasina Сушитель лампочек Модератор

    Код (C++):
    void loop()
    {
      DHT11.acquireAndWait(); // не знаю зачем это
      hidr = DHT11.getHumidity();

      if (hidr >= 40 && hidr <= 37)
      {
        if (!digitalRead(LightPin)) digitalWrite(VentPin, HIGH);
        else digitalWrite(VentPin, LOW);
      }
      else digitalWrite(VentPin, LOW);

      digitalWrite(RedLedPin, digitalRead(VentPin));
      digitalWrite(GreenLedPin, !digitalRead(VentPin));
    }
    По-моему, этого вполне достаточно.
     
    DIYMan нравится это.
  18. DIYMan

    DIYMan Guest

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

    Смотрите: у вас есть несколько условий:

    1. Вентилятор выключается, когда горит свет;
    2. Вентилятор включается при влажности >= 40%;
    3. Вентилятор выключается при влажности <= 37%.

    По сути, это все условия, насколько я понял. В псевдокоде скетч выглядит довольно просто:

    Код (C++):
    #define READ_SENSOR_INTERVAL 1000 // через какое время читать из датчика

    bool isVentOn = false; // флаг того, что вентилятор включен
    unsigned long readSensorTimer = 0; // таймер чтения с датчика

    void loop()
    {
       
        unsigned long curMillis = millis();
        if(curMillis - readSensorTimer > READ_SENSOR_INTERVAL)
        {
            // настало время читать с датчика
            int currentHumidity = readHumidity();
           
            // проверяем, что там с влажностью?
            if(currentHumidity >= 40)
            {
                // влажность высокая
                // читаем наличие света
                bool isLightOn = readLightState();
               
                if(!isLightOn)
                {
                        // только если свет выключен - включаем вентилятор
                        if(!isVentOn)
                        {
                            // если вентилятор уже не включён - включаем
                            isVentOn = true;
                            turnVentOn();
                        }
                }
            }
            else if(currentHumidity <= 37)
            {
                // влажность маленькая, по-любому выключаем вентилятор
                if(isVentOn)
                {
                    isVentOn = false;
                    turnVentOff();
                }
            }
           
        }
    }
    Обновление - раз в секунду, для бытовой задачи - более чем, максимум, что произойдёт - после включения света вентилятор выключится максимум через секунду. Естественно, это лишь набросок, демонстрация, для понимания того, что и как работает.
     
    Tomasina нравится это.
  19. DIYMan

    DIYMan Guest

    Согласен. У мну, правда, есть привычка (не знаю, дурная или нет) - писать в порты только при изменении состояния системы, поэтому я всегда с флагами заморачиваюсь :)
     
  20. 6umer

    6umer Нуб

    Спасибо! Приеду проверю, что я понял, и данные по порту выложу, о которых ранее говорили.
    Спасибо.