Страница 3 из 3 ПерваяПервая 123
Показано с 31 по 40 из 40
Like Tree2Спасибо

Тема: Arduin

  1. #31
    Экстра-класс Аватар для R3DE
    Регистрация
    16.02.2015
    Сообщений
    2,854
    Поблагодарили
    650
    Поблагодарил
    167
    Цитата Сообщение от YL2QN Посмотреть сообщение
    [CODE]
    /**

    Примерно так, но я не тестировал. Если с пол пинка не запустится - пишите на что ругается.
    Запускается и работает, но кое что не понятно.
    В Serial1.println(send_data); убрал ln, иначе, пока нет данных, непрерывно гонит в порт 0D 0A...
    Serial1.print(send_data); выдает ДВОЙНУЮ последовательность xyz
    У меня данные приходят из другого порта, и в этом случае Serial1.println(send_data); выдает аж ЧЕТВЕРНУЮ последовательность xyz.
    Почему, не пойму.
    Ниже, то что у меня:
    #include <AltSoftSerial.h>
    AltSoftSerial altSerial;
    /**
    *
    */
    const int SERIAL_DATA_DELAY = 5;

    /**
    * Startup events.
    */
    void setup() {
    init_serial();
    }

    /**
    * Init serial port communication.
    */
    void init_serial() {
    Serial.begin(9600);
    Serial1.begin(9600);
    altSerial.begin(9600);
    }

    /**
    * Main loop procedure.
    */
    void loop() {
    serial_forward();
    }

    /**
    * Read data from serial port 0, parse string and send over serial 1.
    */
    void serial_forward() {
    String read_data;
    String send_data;
    int read_data_len;

    while (altSerial.available() > 0) {
    delay(SERIAL_DATA_DELAY);
    char c = altSerial.read();
    Serial.print(c);
    read_data += c;
    }

    do {
    read_data_len = read_data.length();
    int endIndex = read_data.indexOf("C");
    if (read_data.startsWith("A>B:") && endIndex >= 0) {
    send_data = read_data.substring(4, endIndex);
    read_data.remove(0, endIndex + 1);
    }
    Serial1.print(send_data);
    Serial.print(send_data);
    if (read_data_len == read_data.length()) {
    read_data.remove(0, 1);
    }
    } while (read_data_len != read_data.length());
    }

  2. #32
    Экстра-класс
    Регистрация
    30.11.2012
    Возраст
    47
    Сообщений
    1,223
    Поблагодарили
    657
    Поблагодарил
    1000
    Цитата Сообщение от R3DE Посмотреть сообщение
    В Serial1.println(send_data); убрал ln, иначе, пока нет данных, непрерывно гонит в порт 0D 0A...
    Serial1.print(send_data); выдает ДВОЙНУЮ последовательность xyz
    У меня данные приходят из другого порта, и в этом случае Serial1.println(send_data); выдает аж ЧЕТВЕРНУЮ последовательность xyz.
    Почему, не пойму.
    А зачем вам AltSoftSerial и три сериал порта
    Код:
    void init_serial() {
      Serial.begin(9600);
      Serial1.begin(9600);
      altSerial.begin(9600);
    }
    Зачем тут Serial.print?
    Код:
    while (altSerial.available() > 0) {
    delay(SERIAL_DATA_DELAY);
    char c = altSerial.read();
    Serial.print(c); // Зачем вам это?
    read_data += c;
    }
    И тут вы шлёте в два порта. Вы в портах не запутались
    Код:
    Serial1.print(send_data);
    Serial.print(send_data);

  3. #33
    Экстра-класс
    Регистрация
    30.11.2012
    Возраст
    47
    Сообщений
    1,223
    Поблагодарили
    657
    Поблагодарил
    1000
    Цитата Сообщение от R3DE Посмотреть сообщение
    наверное бы устроило, довел бы до конца, но посылает только цифру, если вставить типа 55:12y3, то всё плохо.
    Лучше не надо так делать....
    Тем более, что вы сами делаете перевод в цифру

    Ваш код можно дописать, но он не предусматривает,
    1. Обработку, если в буфере будет два или три нужных вам стринга
    2. Обработку, если в буфере будет "мусор"

    Цитата Сообщение от R3DE Посмотреть сообщение
    убрал ln, иначе, пока нет данных, непрерывно гонит в порт 0D 0A...
    Скорее всего Serial.print(c);
    или оберните отправку проверкой на наличее данных (хотя дико сомневаюсь, что это там)
    Код:
        if (send_data.length() > 0) {
          Serial1.println(send_data);  
        }

  4. #34
    Экстра-класс Аватар для R3DE
    Регистрация
    16.02.2015
    Сообщений
    2,854
    Поблагодарили
    650
    Поблагодарил
    167
    Цитата Сообщение от YL2QN Посмотреть сообщение
    А зачем вам AltSoftSerial и три сериал порта

    Зачем тут Serial.print?


    while (altSerial.available() > 0) {

    Serial.print(c); // Зачем вам это?


    И тут вы шлёте в два порта. Вы в портах не запутались
    [CODE]


    Serial1.print(send_data);
    Serial.print(send_data);
    - Почему AltSoftSerial? - так сложилось, раньше писал для UNO, а там нет Serial1 2, 3. Если это принципиально то уберу, заменю на Serial2
    - Нужны данные только на железных портах и в этом смысле просто Serial не подходитэ
    - Serial.print везде добавил чтобы посмотреть, что идет в этих местах. Когда заработает - конечно уберу.
    - С портами пока вроде не запутался.

    Скорее всего Serial.print(c);
    Нет, именно Serial1

    или оберните отправку проверкой на наличее данных
    Ну, так я вроде это и сделал дописав
    Serial1.print(send_data);
    Serial.print(send_data);
    Или нет? Как сделать?


    Думаю( может не прав), что вы не видите бесконечное 0D 0A потому что Serial монитор IDE не показывает, а Serial1 - железный и терминал видит.
    Но это мне не так страшно, плохо, что идёт дублирование.

    ...Есть подозрение, что исходная A>B:xyzC на самом деле может на конце иметь 0D 0A или 0D 0A 0D 0A. Проверю.

  5. #35
    Экстра-класс
    Регистрация
    30.11.2012
    Возраст
    47
    Сообщений
    1,223
    Поблагодарили
    657
    Поблагодарил
    1000
    Цитата Сообщение от R3DE Посмотреть сообщение
    Думаю( может не прав), что вы не видите бесконечное 0D 0A потому что Serial монитор IDE не показывает, а Serial1 - железный и терминал видит.
    Но это мне не так страшно, плохо, что идёт дублирование.
    Ну на самом деле я ничего вообще не вижу, так как написал этот код в слепую и не проверял его. Я об этом написал в самом начале.

    Если я не ошибаюсь, Mega имеет 4 UART порта: Serial, Serial1, Serial2, Serial3. Используя AltSoftSerial вы можете сделать ещё на свободных пинах эмуляцию дополнительных портов. Но лучше использовать готовые UART.

    Согласно вашему коду, вы слушаете altSerial и побайтно транслируете, то что получаете в Serial.
    Потом парсите данные (вырезаете лишнее) и шлёте данные в Serial и Serial1.

    Вопрос: какой порт вы мониторите? Если Serial, то там и будет двойной набор данных.

    Если бы в конце были бы получены 0D 0A - то парсер их как раз должен был бы вырезать. Скорее всего, это какие-то служебные символы. Их мониторинг (отображение) зависит от настроек COM PORT терминала, которым вы смотрите данные.

    P.S. Ещё в терминале может быть включено echo, тогда вы будете тоже видеть двойной набор данных.

  6. #36
    Экстра-класс
    Регистрация
    30.11.2012
    Возраст
    47
    Сообщений
    1,223
    Поблагодарили
    657
    Поблагодарил
    1000
    Цитата Сообщение от R3DE Посмотреть сообщение
    или оберните отправку проверкой на наличее данных
    Ну, так я вроде это и сделал дописав
    Serial1.print(send_data);
    Serial.print(send_data);
    Или нет? Как сделать?
    Нет, не обернули.

    Двойная отправка, на самом деле, мой косяк - там do-while делает ещё один проход после отправки, а send_data не обнуляется. Извините.
    Вот так будет правильно:
    Код:
    /**
     *
     */
    const int SERIAL_DATA_DELAY = 5;
    
    /**
     * Startup events.
     */
    void setup() {
      init_serial();
    }
    
    /**
     * Init serial port communication.
     */
    void init_serial() {
      Serial.begin(9600);
      Serial1.begin(9600);
    }
    
    /**
     * Main loop procedure.
     */
    void loop() {
      serial_forward();
    }
    
    /**
     * Read data from serial port 0, parse string and send over serial 1.
     */
    void serial_forward() {
      String read_data;
      String send_data;
      int read_data_len;
    
      while (Serial.available() > 0) {
        delay(SERIAL_DATA_DELAY);
        char c = Serial.read();
        read_data += c;
      }
      
      do {
        read_data_len = read_data.length();
        int endIndex = read_data.indexOf("C");
        if (read_data.startsWith("A>B:") && endIndex >= 0) {
          send_data = read_data.substring(4, endIndex);
          read_data.remove(0, endIndex + 1);
        }    
        if (send_data.length() > 0) {
          Serial1.print(send_data);
          send_data = "";
        }
        if (read_data_len == read_data.length()) {
          read_data.remove(0, 1);
        }    
      } while (read_data_len != read_data.length());
    }

  7. #37
    Экстра-класс Аватар для R3DE
    Регистрация
    16.02.2015
    Сообщений
    2,854
    Поблагодарили
    650
    Поблагодарил
    167
    Ok, спасибо , шас попробую.

    И еще. Как обычно изменились условия. Действительно реально последовательность оказалась с 0D 0A на конце. И именно это надо также обрезать, а С оставить. То есть на входе (на altSerial) A>B:xyzC.. (где две точки это 0D 0A), а на выход( с Serial1) должно уйти xyzC

    Как это прописать... видимо в int endIndex = read_data.indexOf("С"); ?

  8. #38
    Экстра-класс
    Регистрация
    30.11.2012
    Возраст
    47
    Сообщений
    1,223
    Поблагодарили
    657
    Поблагодарил
    1000
    Цитата Сообщение от R3DE Посмотреть сообщение
    Как это прописать... видимо в int endIndex = read_data.indexOf("С"); ?
    Простейший вариант да, заменить C на нужную вам последовательность символов окончания. Должно работать, правда не оптимально, так как парсер сделает дополнительно несколько прогонов do-while по количеству символов. Но в вашем случае, это не будет являться проблемой, если, конечно, траффик по com port не сильно большой (десятки сообщений в секунду).

    Лучше подправьте ещё одну строчку:
    было: read_data.remove(0, endIndex + 1);
    надо: read_data.remove(0, endIndex + 4);
    Т.е. увеличили длину конечного стринга.

  9. #39
    Экстра-класс Аватар для R3DE
    Регистрация
    16.02.2015
    Сообщений
    2,854
    Поблагодарили
    650
    Поблагодарил
    167
    Цитата Сообщение от YL2QN Посмотреть сообщение

    Лучше подправьте ещё одну строчку:
    было: read_data.remove(0, endIndex + 1);
    надо: read_data.remove(0, endIndex + 4);
    Т.е. увеличили длину конечного стринга.
    Проверил, работает как надо, всё устраивает. Я правда подправил в другом месте: int endIndex = read_data.indexOf(";")+1;
    Только вот, если не трудно, напишите как именно прописать вместо С эти самые 0D 0A, так сказать... на будущее.

  10. #40
    Экстра-класс
    Регистрация
    30.11.2012
    Возраст
    47
    Сообщений
    1,223
    Поблагодарили
    657
    Поблагодарил
    1000
    Цитата Сообщение от R3DE Посмотреть сообщение
    Я правда подправил в другом месте: int endIndex = read_data.indexOf(";")+1;
    Где и почему вы так сделали - я не понимаю. У вас в стринге не было ";" как разделителя данных, если только входные условия опять не поменялись

    0D 0A - это carriage return. Можно на него в принципе не обращать внимания.

    Цитата Сообщение от R3DE Посмотреть сообщение
    напишите как именно прописать вместо С эти самые 0D 0A, так сказать... на будущее.
    "\r\n"

Социальные закладки

Социальные закладки

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •  
Похоже, что вы используете блокировщик рекламы :(
Форум QRZ.RU существует только за счет рекламы, поэтому мы были бы Вам благодарны если Вы внесете сайт в список исключений!
как отключить
×
Рейтинг@Mail.ru
eXTReMe Tracker
Яндекс.Метрика