Как подключить к Arduino эхолот Humminbird?

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем Bif+, 12 фев 2019.

  1. Bif+

    Bif+ Гик

    Конфликт, паразитный сигнал на том же уровне и серва не работает.
     
  2. Airbus

    Airbus Радиохулиган Модератор

    То есть все как и было?
     
  3. Bif+

    Bif+ Гик

    Да. Я уже это пробовал раньше. Эхолот можно не подключать и без него на осциллограмме широкий импульс.
     
  4. Airbus

    Airbus Радиохулиган Модератор

    Тогда надо код ковырять.Конфликта библиотек щас нет.
     
  5. Bif+

    Bif+ Гик

    Как только я подключаю myservo.attach, сразу идет сигнал 80 гц и почти 5v.
     
  6. Airbus

    Airbus Радиохулиган Модератор

    Лана.Бум думать
     
  7. Bif+

    Bif+ Гик

    А как контролировать на мониторе? Мне надо еще подключить компас, гироскоп и LCD 16x2. Наверно нужна Мега 2560.
    Еще: раньше помеха была 50гц, сейчас 80гц. 0,011 s, скважность 15-17%. Что это может быть?
     
    Последнее редактирование: 30 мар 2019
  8. Bif+

    Bif+ Гик

    От МАХ 232 дым пошел.
     
  9. Bif+

    Bif+ Гик

    Сгорела!
     
  10. NoViChok+

    NoViChok+ Нерд

    У меня тоже нана сгорела, все из за спешки и криворукости моей.
     
  11. Bif+

    Bif+ Гик

    Добрый день!
    Приобрел новую Мегу 2560 и MAX232. Макетка была в проводах, как ежик в иголках.
    Разделил питание. Мега позволяет вторым Serial контролировать на мониторе. Все разобрал и собрал заново.
    Код (C++):
    #include <Servo.h>
    #define servoPin                   9
    #define servoMinImp               20                     //600
    #define servoMaxImp              170                     //2200
    Servo myservo;


    // Включаем отладку.
    #define DEBUG

    #define POTENTIOMETER_R1_PIN      A0
    #define POTENTIOMETER_R2_PIN      A1

    #define BUFFER_SIZE 15
    char serialBuffer[BUFFER_SIZE + 1];

    // Текущая глубина.
    int lastDeep = 0;
    // Предыдущая глубина.
    int previousDeep = 0;

    // Частота получения значений от компаса и управления мотором.
    const int intervalMainBlock = 1000;

    void setup()
    {

      // put your setup code here, to run once:
      Serial.begin(9600);
      Serial1.begin(4800);
      while (!Serial1)

      {
        ; // wait for serial port to connect. Needed for native USB port only
      }

       myservo.attach(servoPin, servoMinImp, servoMaxImp);
    }

    void loop()
    {
      static byte finishComand = 0;

      // Получение глубины.
      GetDeep(&finishComand);

      // Предыдущее значение системного таймера.
      static unsigned long previousSystickMainBlock = 0;
      // Текущее значение системного таймера.
      unsigned long currentSystickMainBlock = millis();

      // Запускаем с интервалом intervalMainBlock и проверяем значение глубины.
      if ((currentSystickMainBlock - previousSystickMainBlock) >= intervalMainBlock
          && lastDeep != 0)
      {
        previousSystickMainBlock  = millis();

    #ifdef DEBUG
        //Serial.println("BeginMainBloack");
    #endif

        // Получение текущее значения угла от компаса.
        int angle = GetAngleFromCompass();

        // Управление мотором.
        MotorControl(angle);

    #ifdef DEBUG
        //Serial.println("EndMainBloack");
    #endif

      }
    }

    // Функция получения глубины.
    void GetDeep(byte* finishComand)
    {
      if (Serial1.available() > 0)
      {
        static byte saveInBuffer = 0;
        static byte commandCorrect = 0;

        char lastChar = Serial1.read();
        static byte indexBuffer = 0;
        switch (lastChar)
        {
          case '$':
            memset(serialBuffer, 0, sizeof(serialBuffer));
            indexBuffer = commandCorrect = finishComand = 0;

            // Сохраняем предыдущую глубину.
            previousDeep = lastDeep;

            serialBuffer[indexBuffer] =  lastChar;

            saveInBuffer = 1;
            break;
          default:
            if (commandCorrect == 1 && lastChar == ',')
            {
              finishComand = 1;
              saveInBuffer = 0;

              // Умножаем глубину на 10, для удобной работы в дальнейшем.
              lastDeep = (int)(atof(&serialBuffer[7]) * 10);

              // Если есть переменная DEBUG.
    #ifdef DEBUG
              Serial.print("lastDeep - ");
              Serial.println(lastDeep);

              // Serial.print("previousDeep - ");
              //Serial.println(previousDeep);                 //предыдущая глуб
    #endif
            }

            if (indexBuffer < BUFFER_SIZE && saveInBuffer == 1)
            {
              indexBuffer = indexBuffer + 1;
              serialBuffer[indexBuffer] =  lastChar;
            }
            break;
        }

        if (indexBuffer == 6)
        {
          if (strstr(serialBuffer, "$INDPT,") > 0)
          {
            commandCorrect = 1;
          }
          else
          {
            saveInBuffer = 0;
          }
        }
      }
    }

    // Получение текущее значения угла от компаса.
    int GetAngleFromCompass()
    {
      int angle = 0;

      // Вставляем нужный код.

      return angle;
    }

    // Управление мотором.
    void MotorControl(int angle)
    {
      //myservo.attach(servoPin, servoMinImp, servoMaxImp);

      // Общая идея, valR1 и valR2 настраивают глубину, от 0 до 10 метров с шагом 0,1 метра.
      // Диапазон valR1 и valR2 от 0 до 100, что соответствует глубине от 0 до 10 метров с шагом 0,1 метра.
      // Где 1 равно 0,1 метра, а 35 соответствует глубине 3,5 метра.
     
      int valR1 = analogRead(POTENTIOMETER_R1_PIN);        // запомнить показания с  R1
      valR1 = map(valR1, 0, 1023, 0, 100);                 // перевести в диапазон 0.. 100

    #ifdef DEBUG
      Serial.print("valR1 - ");
      Serial.println(valR1);
    #endif

      int valR2 = analogRead(POTENTIOMETER_R2_PIN);       // запомнить показания с  R2
      valR2 = map(valR2, 0, 1023, 0, 100);                // перевести в диапазон 0.. 100

    #ifdef DEBUG
      Serial.print("valR2 - ");
      Serial.println(valR2);
    #endif

      if (lastDeep < valR1)
      {
               myservo.write(150);                         // Microseconds(1970);                                  

               Serial.println("x<a");
           
      }

      else if (lastDeep >= valR1 & previousDeep <= valR1)
      {
               myservo.write(20);                           // Microseconds(1000); перо руля до конца в обратную сторону
                                                                        // для выравнивания по курсу (здесь бы задать время!)
               Serial.println("x=a");
             
      }

      else if  (lastDeep > valR1 && lastDeep < valR2)    
      {
                Serial.println("x");

                myservo.write(90);                           //Microseconds(1570);
           
      }

      if (lastDeep > valR2)
      {
                myservo.write(30);                           //Microseconds(1200);

                Serial.println("x>b");
             
      }

      else if (lastDeep <= valR2 & previousDeep >= valR2)
      {
               myservo.write(160);                           //Microseconds(2000); перо руля до конца в обратную сторону
                                                                        // для выравнивания по курсу (здесь бы задать время!)

               Serial.println("x=b");

      }
    }
    Заработало как надо.
    Хочу выразить особую признательность tpolimer и Airbus за терпение и оказанную помощь в реализации данного проекта.
    Мне по данному проекту необходимо еще кое-что доделать:
    - подключить LSDдля контроля задаваемой глубины R1 и R2;
    - подружить компас и гироскоп с тем, что на сегодняшний день сделано;
    - этот код работает только, когда берег слева, а надо доделать каскад управления серводвигателем , чтобы автомат работал и при движении в обратную сторону, т.е. когда берег справа.
    Много работы с докаткой, а так же с герметизацией электродвигателя и сервы.
    Наверное, займусь пока механикой. До навигации осталось два месяца, хотелось бы успеть.
     
  12. tpolimer

    tpolimer Нерд

    Отлично. Что касается кода, то он нормальный. Переход на Мегу 2560, дал возможность уйти от SoftwareSerial, что не хуже.

    Спасибо, увы сейчас нет возможности быть активным участником, очень много работы.

    Удачи в проекте!
     
    Bif+ нравится это.
  13. Bif+

    Bif+ Гик

    Добрый вечер!
    Долго возился, но всё-таки добил код для движения вперед и обратно.
    Код (C++):
      int valR2 = analogRead(POTENTIOMETER_R2_PIN);       // запомнить показания с  R2
      valR2 = map(valR2, 0, 1023, 0, 100);                // перевести в диапазон 0.. 100

    #ifdef DEBUG
      Serial.print("valR2 - ");
      Serial.println(valR2);
    #endif

      if (valR1 < valR2)
         {

         if (lastDeep < valR1)
             {
               myservo.write(150);                 // Microseconds(1970);                                  

               Serial.println("x<a");
           
             }

         else if (lastDeep >= valR1 & previousDeep <= valR1)
             {
               myservo.write(20);                   // Microseconds(1000);здесь бы задержку 3-5 сек, подбирать опытным путем
                                                    // перо руля до конца в обратную сторону для выравнивания по курсу
               Serial.println("x=a");
             
             }

         else if  (lastDeep > valR1 && lastDeep < valR2)    
             {
                Serial.println("x");

                myservo.write(90);                  // Microseconds(1570);
           
             }

         if (lastDeep > valR2)
             {
                myservo.write(30);                  // Microseconds(1200);

                Serial.println("x>b");
             
            }

         else if (lastDeep <= valR2 & previousDeep >= valR2)
            {
               myservo.write(160);                  // Microseconds(2000);здесь бы задержку 3-5 сек, подбирать опытным путем
                                                    // перо руля до конца в обратную сторону для выравнивания по курсу
               Serial.println("x=b");

            }
          }
     
    if (valR2 < valR1)        //ЧАСТЬ 2
      {
         if (lastDeep < valR2)
            {
                myservo.write(30);                   // Microseconds(1200);

                Serial.println("x2<b");
             
            }
         else if ( lastDeep >= valR2 &  previousDeep <= valR2)
            {
               myservo.write(160);                   // Microseconds(1000);здесь бы задержку 3-5 сек, подбирать опытным путем
                                                     // перо руля до конца в обратную сторону для выравнивания по курсу
               Serial.println("x2=b");
             
            }

          else if  (lastDeep > valR2 && lastDeep < valR1)      
            {
                Serial.println("x2");

                myservo.write(90);                    // Microseconds(1570);
           
            }

          if (lastDeep > valR1)
            {
                myservo.write(150);                   // Microseconds(1200);

                Serial.println("x2>a");
             
            }

          else if (lastDeep <= valR1 & previousDeep >= valR1)
            {
               myservo.write(20);                     // Microseconds(2000); здесь бы задержку 3-5 сек, подбирать опытным путем
                                                      // перо руля до конца в обратную сторону для выравнивания по курсу
               Serial.println("x2=a");
            }
         }
      }
     
    Всё правильно работает.
    Если кто-то захочет повторить или помочь в дальнейшей разработке проекта, как говорится - добро пожаловать! Хотелось бы подключить LSD для контроля задаваемой глубины и освободиться от необходимости использования ноутбука как монитора.
     
  14. Bif+

    Bif+ Гик

    Добрый вечер!
    Купил LCD 16x2 с конвертером и сегодня подключил.

    Код (C++):
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    //#include <LiquidCrystal_PCF8574.h> // Подключение альтернативной библиотеки
    LiquidCrystal_I2C lcd(0x27,16,2);    // Указан I2C адрес (может быть0х20 или 0х3F), а также парам экрана LCD 1602 - 2 стр по 16 симв в кажд
                                         // LCD подключен Mega2560 к 20 и 21, если Nano -к D4 и D5
    //LiquidCrystal_PCF8574 lcd(0x27);   // Вариант для библиотеки PCF8574
    #include <Servo.h>                   //эхолот подключен на вход к 8 ноге MAX232, с 9 ноги выход- на Mega2560 на pin 19
    #define servoPin                   9
    #define servoMinImp               20                     //700 ограничение min
    #define servoMaxImp              170                     //2200 и max поворота сервы (170 градусы, 2200 микрсекунды)
    Servo myservo;
    Код (C++):
     int valR1 = analogRead(POTENTIOMETER_R1_PIN);  // запомнить показания с  R1
      valR1 = map(valR1, 0, 1023, 0, 100);           // перевести в диапазон 0.. 100

    #ifdef DEBUG                                     // выводим на LCD

      lcd.setCursor(0,0);                            // Установка курсора в начало первой строки LCD
      lcd.print("R1= ");                             // вывод текста на первой строке
      lcd.print(valR1);

      lcd.print("  Glub ");                           // вывод текста на первой строке после R1 -глубина
      lcd.println(lastDeep);                         //текущая глубина с эхолота,
                                                     // при глубине 100 и более(>=10м), третья цифра не стирается, поэтому println
     
    // Serial.print("valR1 - ");
    // Serial.println(valR1);
    #endif

      int valR2 = analogRead(POTENTIOMETER_R2_PIN);  // запомнить показания с  R2
      valR2 = map(valR2, 0, 1023, 0, 100);           // перевести в диапазон 0.. 100

    #ifdef DEBUG                                     // выводим на LCD

      lcd.setCursor(0,1);                            // Установка курсора в начало второй строки LCD
      lcd.print("R2= ");                             // вывод текста на второй строке R2
      lcd.print(valR2);
    Теперь не нужен монитор ноутбука.
    Эхолот в режиме эмуляции, поэтому видео не очень выразительно, но всё удобно контролировать на LSD.
    vimple.co/c170e91d4c074766bfb8a8d16b7c77eb
     
  15. NoViChok+

    NoViChok+ Нерд

    Glub- это эхолот?
    А почему R2 на видео меняется?
     
  16. Airbus

    Airbus Радиохулиган Модератор

    Bif+ заработало?Поздравляю!
     
  17. Bif+

    Bif+ Гик

    Спасибо! Если бы не ВЫ, до сих пор бы мучился. Ваше участие дало хороший импульс. Потихоньку, но движемся вперед!
     
  18. Bif+

    Bif+ Гик

    Glub- это эхолот. R2 меняется из-за плохого контакта в потенциометре. Надо поменять.
     
  19. NoViChok+

    NoViChok+ Нерд

    Вижу дело движется!
    Хотел бы помочь, но пока слабо понимаю чток чему. Одним словам -пионэр!
     
  20. Bif+

    Bif+ Гик

    Теперь надо подключить компас.