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

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

  1. Bif+

    Bif+ Гик

    Код (C++):

    //https://eax.me/arduino-gps/
    //рабочий, но выдает все NMEA

    #include <Arduino.h>
    #include <SoftwareSerial.h>
    //#include "LiquidCrystal_I2C.h"
    #include "TinyGPS++.h"

    const int DELAY = 1000;//0------
    const int SWITCH_TIME = 5000;

    //LiquidCrystal_I2C lcd(0x3F, 16, 2);
    SoftwareSerial gps_serial(8, 2);//(A3, A2); /* RX, TX */
    TinyGPSPlus gps_parser;

    void setup()
    {
        Serial.begin(9600);
        gps_serial.begin(9600);
        //lcd.begin();   //--------------
    }

    String twoDigits(int x) {
      if(x < 10) return "0" + String(x);
      else return String(x);
    }

    int currentModeTime = 0;
    bool showLocation = false;

    void loop() {
        while(gps_serial.available() > 0) {
            char temp = gps_serial.read();
            Serial.write(temp);
            gps_parser.encode(temp);
        }

        String lat  = "Unknown         ";
        String lng  = "location        ";
        if(gps_parser.location.isValid()) {

                 
            lat = "Lat: " + String(gps_parser.location.lat(), 6);
            lng = "Lng: " + String(gps_parser.location.lng(), 6);
        }

        String date = "Unknown date    ";
        if(gps_parser.date.isValid()) {
            date = twoDigits(gps_parser.date.day()) + "/" +
                   twoDigits(gps_parser.date.month()) + "/" +
                   String(gps_parser.date.year()) + "      ";
        }

        String time = "Unknown time    ";
        if(gps_parser.time.isValid()) {
            time = twoDigits(gps_parser.time.hour()) + ":" +
                   twoDigits(gps_parser.time.minute()) + ":" +
                   twoDigits(gps_parser.time.second()) + " UTC    ";
        }

        if(showLocation) {
          /*  lcd.setCursor(0, 0);
            lcd.print(lat);
            lcd.setCursor(0, 1);
            lcd.print(lng);
            */

            Serial.print("     ");//-----------
            //Serial.print (" Lat: ");
            Serial.print(lat);
            Serial.print("     ");//-----------
            //Serial.print(" Long: ");
            Serial.print(lng);
            Serial.println("     ");//-------------
        } else { // show date and time
           /* lcd.setCursor(0, 0);
            lcd.print(date);
            lcd.setCursor(0, 1);
            lcd.print(time);
            */

           // Serial.print(" Time: ");
            //Serial.println(time);
        }

        delay(DELAY);
        currentModeTime += DELAY;
        if(currentModeTime >= SWITCH_TIME) {
           // lcd.clear();//-------------
            showLocation = !showLocation;
            currentModeTime = 0;
        }
    }
    Смотреть на мониторе порта. Если хотите на LCD, то раскоментируйте и замените на свой LCD.
     
  2. Bif+

    Bif+ Гик

    Более удачный скетч мой пост 163. Там выдаёт чисто lat и lng в формате хх.хххххх хх.хххххх.
    Чтобы не скакали циферки для этого и нужно усреднение данных - в Вашем скетче - mean.
     
    Последнее редактирование: 2 апр 2020
  3. burd-ig

    burd-ig Нерд

    Адаптировал последний скетч с моим дисплеем SSD1306. Очень медленный вывод данных. Один раз в пол минуты.
     
  4. b707

    b707 Гуру

    если речь о коде из сообщения 181 - абсолютно неудивительно. Странно, что этот скетч вообще хоть что-нибудь выводит при таком кривом коде...
    Автор читает случайные обрывки данных из порта, без начала и конца, должно очень повезти, чтобы в них окались lon и lat
    Кроме того, в коде напиханы странные задержки - иногда между чтениями данных делается выдержка по 1 сек, а иногда по 5 сек...
     
    Последнее редактирование: 3 апр 2020
  5. b707

    b707 Гуру

    burd-ig, в плане кода вы в этой ветке ничего полезного не найдете, ТС в основном сосредоточился на моторредукторах и сервах, а кодом почти не занимался. Если вы хоть чуть-чуть понимаете в программировании - лучше не использовать скетчи из этой ветки, а написать код самому.

    Отвечая на ваш вопрос с прошлой страницы - конечно протокол NMEA можно обрабатывать и без библиотеки, как - легко найдете в гугле, если знаете Си - там все элементарно.
    Можно, кстати, просто открыть исходник TinyGPSPlus и посмотреть, как это делается там. Ничего сложного нет.
     
  6. Bif+

    Bif+ Гик

    Спасибо, злой филин!
    Код из сообщения 181 не мой, взят здесь:https://eax.me/arduino-gps/ , приведен для примера.
    Вы правы - у меня очень мало опыта в программировании. Сфера моей работы была очень далека от этого.
    Уважаемый Гуру, если Вам на трудно, посмотрите код из 163 сообщения. Какие там есть ошибки и можно ли его использовать?
     
  7. burd-ig

    burd-ig Нерд

    Я вот и пытаюсь идти в этом направлении. Код с библиотекой медленный, об этом писали в интернете и переходили на SMT32, нужно из нее выдрать только необходимое.
     
  8. Bif+

    Bif+ Гик

  9. b707

    b707 Гуру

    еще раз - если вы о коде в 181 - то он медленный не потому что "с библиотекой", а потому что кривой до ужаса.
    мало ли что писали, в интернете, на заборе тоже пишут. Я много пишу для СТМ32 и поверьте - применение СТМ32 тут в плане ускорения абсолютно ничего не даст, скорость обмена определяется медленным портом Сериал. Ардуина справляется с запасом.
    Преимущество СТМ32 в данном случае может быть только в том. что у СТМ 3 апппаратных сериала.
     
  10. burd-ig

    burd-ig Нерд

    А я и не спорю. Пока для меня вылезают все новые и новые возможности ардуино. Можно короткий вопрос?
    Если изменить частоту ШИМ на цифровых выходах до 15 или 30 кГц (понятно, что примерные цифры, не паспортные), это как-то сказывается на всю работу ардуино? Вроде как, тут просто тактовая частота делится с меньшим коэффициентом (в отличии от 500 Гц по умолчанию) и не должно ничего происходить другого. Но вдруг есть подводные камни.
     
  11. b707

    b707 Гуру

    если коротко, то нет.
    А так читайте что такой ШИМ и что такое таймеры. нюансов там очень много.
     
  12. burd-ig

    burd-ig Нерд

    Код (C++):
    #include <SoftwareSerial.h>

    // Connect the GPS RX/TX to arduino pins 3 and 5
    SoftwareSerial serial = SoftwareSerial(3,5);

    const unsigned char UBX_HEADER[] = { 0xB5, 0x62 };

    struct NAV_POSLLH {
      unsigned char cls;
      unsigned char id;
      unsigned short len;
      unsigned long iTOW;
      long lon;
      long lat;
      long height;
      long hMSL;
      unsigned long hAcc;
      unsigned long vAcc;
    };

    NAV_POSLLH posllh;

    void calcChecksum(unsigned char* CK) {
      memset(CK, 0, 2);
      for (int i = 0; i < (int)sizeof(NAV_POSLLH); i++) {
        CK[0] += ((unsigned char*)(&posllh))[i];
        CK[1] += CK[0];
      }
    }

    bool processGPS() {
      static int fpos = 0;
      static unsigned char checksum[2];
      const int payloadSize = sizeof(NAV_POSLLH);

      while ( serial.available() ) {
        byte c = serial.read();
        if ( fpos < 2 ) {
          if ( c == UBX_HEADER[fpos] )
            fpos++;
          else
            fpos = 0;
        }
        else {
          if ( (fpos-2) < payloadSize )
            ((unsigned char*)(&posllh))[fpos-2] = c;

          fpos++;

          if ( fpos == (payloadSize+2) ) {
            calcChecksum(checksum);
          }
          else if ( fpos == (payloadSize+3) ) {
            if ( c != checksum[0] )
              fpos = 0;
          }
          else if ( fpos == (payloadSize+4) ) {
            fpos = 0;
            if ( c == checksum[1] ) {
              return true;
            }
          }
          else if ( fpos > (payloadSize+4) ) {
            fpos = 0;
          }
        }
      }
      return false;
    }

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

    void loop() {
      if ( processGPS() ) {
        Serial.print("iTOW:");      Serial.print(posllh.iTOW);
        Serial.print(" lat/lon: "); Serial.print(posllh.lat/10000000.0f); Serial.print(","); Serial.print(posllh.lon/10000000.0f);
        Serial.print(" height: ");  Serial.print(posllh.height/1000.0f);
        Serial.print(" hMSL: ");    Serial.print(posllh.hMSL/1000.0f);
        Serial.print(" hAcc: ");    Serial.print(posllh.hAcc/1000.0f);
        Serial.print(" vAcc: ");    Serial.print(posllh.vAcc/1000.0f);
        Serial.println();
      }
    }
     
     
  13. burd-ig

    burd-ig Нерд

    Вот этот код я пробую запустить, но не понимаю, почему не работает второй serial порт от модуля Neo GPS. TX на ардуино молчит. Модуль активен и в фазе передачи данных.
    И еще вопрос, как отфильтровать сообщения, у которых начало $G×GGA ?
    Т.е. третий символ может быть любой.
     
    Последнее редактирование: 3 апр 2020
  14. b707

    b707 Гуру

    а вы уверены, что ваш Neo GPS выдает данные в этом формате? - судя по коду, это ведь совсем не NMEA-протокол
    NMEA - текстовой. а в этом коде вы пытаетесь читать из сериала бинарную структуру struct NAV_POSLLH

    ваш второй вопрос с учетом того, что я написал выше - тоже непонятен. Где вы собрались искать строчку $G×GGA ? - в этом протоколе таких строк нет.

    По-моему. либо я вас не понял. либо вы сами запутались.
     
  15. burd-ig

    burd-ig Нерд

    Я видео в 174 посте выложил, под ним этот код.
    А второй вопрос пока не настолько связан с первым.
    https://www.irz.ru/uploads/files/226_1.pdf
     
    Последнее редактирование: 3 апр 2020
  16. b707

    b707 Гуру

    поискал в гугле - да, этот модуль умеет выдавать данные в двух форматах - NMEA (текстовой) и U-blox (бинарный)
    Поскольку обе выдачи идут на один UART порт, то модулю явно надо дать какую-то команду для выбора нужного формата.
    И судя по тому, что код из сообщения 181 у вас работал - по умолчанию модуль настроен на NMEA.
    поэтому очевидно, что код из 192 просто так не заработает, он рассчитан на формат U-blox

    Как этот модуль переключается с одного формата на другой - ищите в описании, я с такими дела не имел
     
  17. burd-ig

    burd-ig Нерд

    Не получается у меня убрать сообщения NMEA перепрошивкой. Остаются оба протокола. В видео легко так у человека. У меня при повторном подключении оба. С прошивкой этих модулей беда, судя по форумам. Нужен правильный модуль. Жду, когда приедет другой с али.
     
  18. burd-ig

    burd-ig Нерд

    Можно поподробнее об этом. Все прикидки в проектах, описанных в интернете связанные с serial расплывчатые.
    Хотелось бы услышать вашу точку зрения, как бы правильнее сделать оценку быстродействия системы?
    В данном случае:
    1. Нужно дождаться нужной строки в протоколе NMEA (пусть ее длина будет равна 82) при потоке 9600
    2. Захватить эту строку методом сравнения по начальному префиксу
    3. Выделить из нее наконец-то нужные данные и по возможности усреднить значение
    4. Отправить эти данные в работу в своем проекте (задаче)
    5. И самый главный вопрос, сколько времени есть на эту свою задачу
    6. И как во времени распределить работу с тем же serial. Пока плохо представляю - это непрерывный поток,
    к которому идет дискретное обращение, из-за времени потраченным на операции с данными.
    Все равно получилось сумбурно, но думаю смысл вопроса понятен...
     
  19. b707

    b707 Гуру

    Прикинем скорость обработки NMEA на ардуине.
    Типичная частота измерений GPS - 1 гц или 10 Гц
    Рассмотрим случай с частотой 10 Гц как более сложный.
    Очевидно, что чтобы успевать обрабатывать все приходящие с GPS данные, пп 1-4 из вашего списка должны занимать не более 100 мс
    Время передачи строки в 82 символов на скорости 9600 - порядка 80-90мс (примерно 1 символ в мс).
    Вся остальная обработка строки (пп 2-4) при правильном написании кода занимают существенно меньше времени, чем пункт 1 и в любом случае укладываются 10мс
    То есть получается, что теоретически мы должны успевать обработать даже 10 координат в секунду, хотя время на пределе. Вывод же с частотой в 1 Гц или 3 Гц ардуина должна успевать с запасом.
     
  20. burd-ig

    burd-ig Нерд

    Спасибо!