Подключение двух Serial устройств к Arduino Mega

Тема в разделе "Arduino & Shields", создана пользователем Den1975, 4 мар 2015.

  1. Den1975

    Den1975 Нерд

    Имею Arduino Mega 2560, RFID модуль 125 kHz, EasyVR Shield V2.0
    Хочу сделать кодовый замок с голосовым управлением.
    Arduino Mega 2560 несет на себе 4 Serial porta
    Один из них имеет USB выход на компьютер, другие нет.
    Easy VR Shield как указано в описании подключается через свою библиотеку с использование функции BRIDGE, то есть данная функция при установке джампера на данном модуле в положении SW делает программное соединение Serial 0 и 1 пинов на 12 и 13 пины arduino.
    Я хотел использовать библиотеку Softserial для одновременного подключения двух Serial устройств, но ничего не выходит.
    Также пытаюсь подключить указанные устройства как обычно путем использования обычных функций Serial, Serial, но тоже ничего не выходит.
    RFID сканер видно, Easy VR shield не работает. Меняю местами, ничего не меняется.

    Вопросы:

    1.Подскажите как написать или где посмотреть программный код для одновременного использования двух Serial устройств указанных выше. Как я понимаю должен сначала опрашиваться порт 1, потом 2 и т. д. по очереди.

    2.Можно ли одновременно подключить два Serial устройства через библиотеку SoftSerial и какой при этом будет программный код.

    3.Как подключить Easy VR Shield с использованием обычного Serial соединения.
     
  2. Den1975

    Den1975 Нерд

    В дополнении к указанному хочу добавить - речь вообще идет о возможности одновременного подключения любых сериал устройств к ардуино мега (до 4-х) и каким образом это сделать.
     
  3. X-Dron

    X-Dron Гик

    А набрать в Google "arduino mega serial"????
    В первых же 4-х ссылках
    http://arduino.cc/en/reference/serial
    http://arduino.ru/Serial/Begin
    По-моему все понятно.
    В первой ссылке написано, но еще раз заострю внимание. Не вздумайте подключать TX-RX напрямую к RS-портам, можете повредить плату. На плате Serial на TTL уровнях 5В. Используйте переходники. Связать, например, две ардуины можно без переходников.
    SoftSerial используется для реализации второго Serial на Uno. В меге она бессымесленна.
     
  4. Tomasina

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

  5. X-Dron

    X-Dron Гик

    Можно и не паять самому, а купить модуль.
    Но у Амперки в магазине на такой модуль цены просто заоблачные.
    Платить за http://amperka.ru/product/rs232-ttl-converter почти 900руб?
    У китайцев такой пожно найти за $1,22, средняя цена около $2.
    http://www.aliexpress.com/item-img/...rd-MAX232CSE-Transfer-Chip-TX/1797666206.html
    За 3 таких просят $7,19
    http://www.aliexpress.com/item-img/-/1992487773.html
    Есть в Москве магазин (адрес только через личку), где первый китайский адаптер стоит 188 руб за штуку. Самовывоз со склада в Москве - бесплатно. Доставка в точку выдачи заказов мне обошлась в 140 руб. Доставляли 3 дня. Оплата в точке доставки наличными. За амперкины 900руб я получу 4 адаптера с доставкой почти до дома.
    Хотя, что-то мы разошлись. Для совместной работы RFID модуль 125 kHz, EasyVR Shield V2.0 никакие переходники никуда не нужны, все цепляется по UART.
     
    Последнее редактирование: 6 мар 2015
  6. X-Dron

    X-Dron Гик

    Ерунду, какую то писал раньше. Все стер.
     
    Последнее редактирование: 6 мар 2015
  7. Den1975

    Den1975 Нерд

    Целую теорию развили и ушли в сторону. А вопрос был всего навсего в помощи написания программного кода для одновременной работы двух Serial устройств, неважно каких. Главная задача сделать так, чтобы все работало. У меня пока не получается, не могу понять в чем проблема. Понял одно, что используя библиотеку SoftSerial выполнить мою задачу не получится. Только либо SoftSerial + Serial, либо Serial ,коих на Mega аж 4 штуки. Помогите пожалуйста, любители Arduino.
     
  8. Alex19

    Alex19 Гуру

    Если честно, не очень понятно, что Вам нужно. Если исходить из этого
    То, ответы были выше.

    Выглядит так, настройка всех портов
    Код (Text):

    void setup()
    {
      Serial.begin(9600);  //  0 (RX) и 1 (TX);
      Serial1.begin(9600);  // 1: 19 (RX) и 18 (TX);
      Serial2.begin(9600);  // 2: 17 (RX) и 16 (TX);
      Serial3.begin(9600);  // 3: 15 (RX) и 14 (TX)
    }
     
    А дальше, хотим отправить на 3 Serial, код
    Код (Text):
    Serial3.print("Hello");
    Проверка 1 Serial
    Код (Text):
    while(Serial1.available())
    {

    }
    Вообщем все, как и с обычным Serial, просто подставляем Serial для 0 (RX) и 1 (TX), Serial1 для 19 (RX) и 18 (TX) и т.д., то есть порт с которым хотим работать.

    Сложно понять, что у Вас не получается, покажите код.

    По данным датчикам, сказать ни чего не могу, не работал.
     
  9. Unixon

    Unixon Оракул Модератор

    ТС, зачем вам на меге SoftSerial? Используйте сначала все аппаратные UARTы.
     
  10. Den1975

    Den1975 Нерд

    Уважаемый Alex19, спасибо за отклик.
    В моем понимании, я четко сформулировал, что мне нужно, а нужно вот что, еще раз.
    Ардуино Mega, как указано в описании, позволяет подключить до 4-х "Serial" устройств одновременно.
    Единственное "но" заключается в том, что используя Serial monitor я буду видеть то, что происходит на основном порту, ( пины 0,1), а для всех остальных нужно подключение Serial адаптера.
    Но не в этом суть. Мне нужно обеспечить одновременную работу двух любых Serial устройств, подключенных к arduino mega. Первое устройство подключено к Serial (пины 0,1), второе к Serial3 (пины14,15). В моем случае к Serial подключен модуль голосового управления, а к Serial3 RFID сканер.
    Схему подключения и скетч прилагаю. Не могу понять почему не работает, хотя компилируется без ошибок. Мне нужна помощь в написании скетча, который бы позволил одновременно использовать в работе два Serial устройства, подключенных к MEGA. Хочу в итоге сделать кодовый замок с голосовым управдением. Принцип - подходим к двери, говорим "дверь откройся"- голосовая плата воспроизводит "поднесите вашу идентификационную карту к считывателю"- подносим RFID карту - работаем RDIF сканер, если код правильный, то разрешается доступ - идет голосовой сигнал и сигнал на сервопривод открытия замка. Если код неверный голосовая плата сигнализирует "Код не верный, доступ не разрешен".

    Это в моем случае, а так как использовать одновременно 2, 3, 4 Serial устройства и чтобы все корректно работало ?

    Мой скетч:

    //Подключение библиотек
    #include <Wire.h>//библиотека I2c устройств
    #include <Multiservo.h>//библиотека для работы с мультисервошилд
    #define SERVO1_PIN 11//к пину мультисервошилд 11 подключена серва 1
    #define SERVO2_PIN 17// к пину 17 мультисервошилд подключена серва 2
    #include <pitches.h>// библиотека работы со звуком

    //Подключение библиотек Easy VR Shield + SoftSerial
    #if defined(ARDUINO) && ARDUINO >= 100
    #include "Arduino.h"
    #else // Arduino 0022 - use modified NewSoftSerial
    #include "WProgram.h"
    #endif
    #include "EasyVR.h"
    EasyVR easyvr(Serial);

    //Объекты
    Multiservo myservo1;// сервопривод 1
    Multiservo myservo2;// сервопривод 2

    //RFID модуль
    int data1 = 0;
    int ok = -1;
    int yes = 32;// пин с зелеными ОК светодиодами
    int no = 33;// пин с красными NOT OK светодиодами
    int data[14]; //Переменная для хранения информации с RFID карты
    int val = 0;
    // use first sketch in http://wp.me/p3LK05-3Gk to get your tag numbers
    int tag1[14] = {2,54,54,48,48,53,67,68,65,67,49,50,49,3};// Карта 1 ОК
    int tag2[14] = {2,54,54,48,48,53,67,68,53,50,69,67,49,3};// Карта 2 ОК
    int newtag[14] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // используется для сравнения
    int j_melody[] = {NOTE_G4,0,NOTE_A4,0, NOTE_B4,0,NOTE_A4,0,NOTE_B4,0, NOTE_C5,0};
    int j_noteDurations[] = {8,8,8,8,8,4,8,8,8,8,8,4};
    int d_melody[] = {NOTE_C4,0,NOTE_D4,0,NOTE_F4,0,NOTE_D4,0,NOTE_F4,0,NOTE_G4,0};
    int d_noteDurations[] = {8,8,8,8,8,4,8,8,8,8,8,4};
    int fail_melody[] = {NOTE_G2,0,NOTE_F2,0,NOTE_D2,0};
    int fail_noteDurations[] = {8,8,8,8,8,4};
    int bigspeakerpin = 8;

    //Easy VR модуль
    //Groups and Commands
    enum Groups
    {
    GROUP_0 = 0,
    GROUP_1 = 1,
    };
    enum Group0
    {
    ACTIVATE = 0,
    };
    enum Group1
    {
    G1_HELLO = 0,
    G1_HOW_ARE_YOU = 1,
    G1_SELF_CHECK = 2,
    };

    EasyVRBridge bridge;
    int8_t group, idx;


    // ИНИЦИАЛИЗАЦИЯ ПОСЛЕ ВКЛЮЧЕНИЯ ПИТАНИЯ

    void setup()

    {

    // Инициализация общения с RFID модулем и EasyVR модулем
    Serial.begin(9600);// к порту подключен Easy VR Shield (джампер режима на HW Serial)
    Serial3.begin(9600); // к порту подключен RFID сканер

    // Настраиваем выводы контроллера на вывод сигналов на пьезоизлучатели
    {
    pinMode(bigspeakerpin, OUTPUT);
    }

    //Иициализация порта I2C
    Wire.begin();
    // Назначаем вывод к которому подключен сервопривод УЗ дальномера
    myservo1.attach(SERVO1_PIN); // подключен ко 2 выводу МСШ
    // И подаем команду поворота сервопривода в положение 90 градусов при каждом включении
    myservo1.write(90);
    // Инициализация сервы емкости с лекарствами на 17 пине МСШ
    myservo2.attach(SERVO2_PIN);


    // Инициализация EasyVR Shield
    if (!easyvr.detect())
    {
    Serial.println("EasyVR not detected!");
    for (;;);
    }
    easyvr.setPinOutput(EasyVR::IO1, LOW);
    Serial.println("EasyVR detected!");
    easyvr.setTimeout(5);
    easyvr.setLanguage(EasyVR::ENGLISH);
    group = EasyVR::TRIGGER; //<-- start group (customize)

    }

    void action();

    // Программный модуль считывания данных c RFID карт
    boolean comparetag(int aa[14], int bb[14])
    {
    boolean ff = false;
    int fg = 0;
    for (int cc = 0 ; cc < 14 ; cc++)
    {
    if (aa[cc] == bb[cc])
    {
    fg++;
    }
    }
    if (fg == 14)
    {
    ff = true;
    }
    return ff;
    }

    void checkmytags() // compares each tag against the tag just read
    {
    ok = 0; // this variable helps decision-making,
    // if it is 1 we have a match, zero is a read but no match,
    // -1 is no read attempt made
    if (comparetag(newtag, tag1) == true)
    {
    ok++;
    }
    if (comparetag(newtag, tag2) == true)
    {
    ok++;
    }
    }

    void readTags()
    {
    ok = -1;

    if (Serial3.available() > 0)
    {
    // read tag numbers
    delay(100); // needed to allow time for the data to come in from the serial buffer.

    for (int z = 0 ; z < 14 ; z++) // read the rest of the tag
    {
    data1 = Serial3.read();
    newtag[z] = data1;
    }
    Serial3.flush(); // stops multiple reads

    // do the tags match up?
    checkmytags();
    }

    // now do something based on tag type
    if (ok > 0) // if we had a match
    {
    Serial.println("Accepted");
    digitalWrite(yes, HIGH);
    //delay(3000);

    for (int i = 0; i < 12; i++)
    {
    int j_noteDuration = 1000/j_noteDurations;
    tone(bigspeakerpin, j_melody,j_noteDuration);
    int j_pauseBetweenNotes = j_noteDuration * 1.30;
    delay(j_pauseBetweenNotes);
    noTone(bigspeakerpin);
    }
    easyvr.playSound(8, EasyVR::VOL_FULL);
    easyvr.playSound(17, EasyVR::VOL_FULL);
    {
    myservo2.write(90);
    delay(5000);
    easyvr.playSound(6, EasyVR::VOL_FULL);
    myservo2.write(10);
    digitalWrite(yes,LOW);
    }
    ok = -1;
    }
    else if (ok == 0) // if we didn't have a match
    {
    Serial.println("Rejected");
    digitalWrite(no, HIGH);
    //delay(3000);
    for (int i = 0; i < 6; i++)
    {
    int fail_noteDuration = 1000/fail_noteDurations;
    tone(bigspeakerpin, fail_melody,fail_noteDuration);
    int fail_pauseBetweenNotes = fail_noteDuration * 1.30;
    delay(fail_pauseBetweenNotes);
    noTone(bigspeakerpin);
    }
    easyvr.playSound(9, EasyVR::VOL_FULL);
    digitalWrite(no, LOW);

    ok = -1;
    }
    }

    // ИСПОЛНЯЕМЫЙ ПРОГРАММНЫЙ МОДУЛЬ

    void loop()

    {

    // Программный модуль работы с Easy VR Shield
    easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)
    Serial.print("Say a command in Group ");
    Serial.println(group);
    easyvr.recognizeCommand(group);
    do
    {
    // can do some processing while waiting for a spoken command
    }
    while (!easyvr.hasFinished());
    easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off
    idx = easyvr.getWord();
    if (idx >= 0)
    {
    // built-in trigger (ROBOT)
    // group = GROUP_X; <-- jump to another group X
    return;
    }
    idx = easyvr.getCommand();
    if (idx >= 0)
    {
    // print debug message

    uint8_t train = 0;
    char name[32];
    Serial.print("Command: ");
    Serial.print(idx);
    if (easyvr.dumpCommand(group, idx, name, train))
    {
    Serial.print(" = ");
    Serial.println(name);
    }
    else
    Serial.println();
    easyvr.playSound(0, EasyVR::VOL_FULL);
    // perform some action
    action();
    }
    else // errors or timeout
    {
    if (easyvr.isTimeout())
    Serial.println("Timed out, try again...");
    int16_t err = easyvr.getError();
    if (err >= 0)
    {
    Serial.print("Error ");
    Serial.println(err, HEX);
    }
    }
    }

    //Действия при голосовом управлении
    void action()
    {
    switch (group)
    {
    case GROUP_0:
    switch (idx)
    {
    case ACTIVATE:
    group = GROUP_1;
    break;
    }
    break;

    case GROUP_1:
    switch (idx)
    {

    case G1_HELLO:
    easyvr.playSound(13, EasyVR::VOL_FULL);
    break;

    case G1_HOW_ARE_YOU:
    easyvr.playSound(14, EasyVR::VOL_FULL);
    break;

    case G1_SELF_CHECK:
    easyvr.playSound(4, EasyVR::VOL_FULL);
    break;
    }
    break;
    }
    }
     

    Вложения:

  11. Den1975

    Den1975 Нерд

    Благодарю Вас, я уже от идеи SoftSerial отказался и пытаюсь подключиться к обычным UART
     
  12. Den1975

    Den1975 Нерд

    Посмотрите, может Вы что то подскажете по указанному выше скетчу.
     
  13. Unixon

    Unixon Оракул Модератор

    А что именно сейчас не работает?
     
  14. Unixon

    Unixon Оракул Модератор

    Подключите свои модули к Serial1/2/3, самый первый Serial оставьте для вывода отладочных сообщений.
     
  15. X-Dron

    X-Dron Гик

    Вчера тоже писал всякую ахинею, но почитав мануалы все поудалял.
    Проблемы ТС полностью решить можно, но только хирургическим путем.
    EasyVR Shield V2.0 - это самый настоящий шилд, и подключить по другому его не получится.
    С ардуинами он общается либо через пины 0-1(J12 положение HW), либо через пины 12-13 (J12 положение SW), при этом на ардуине должен имитироваться SoftSerial.
    При подключении к Меге пины 12-13 на шилде я бы загнул, или откусил и сверху кинул бы перемычку на 16-17 (Serial2). При этом
    J12 положение PC - Use it for direct connection with the EasyVR Commander. In this mode, the Arduino controller is held in reset and only the embedded USB/Serial adapter is used. Используются в моем понимании пины 0-1.
    J12 положение SW - нормальный режим работы, мега и шилд работают по Serial2. Serial свободен для мониторинга с компа и закачки скетчей в мегу.
    RFID вешается на Serial3, тут вроде вопросов нет.
    Совет ТС - разбейте программу на куски и отлаживайте по отдельности. Представленная прога да еще не заключенная в тег CODE вообще не удобочитабельна.
     
    Последнее редактирование: 9 мар 2015
  16. Alex19

    Alex19 Гуру

    Пользуйтесь вставкой кода, а не вставляйте как текст. Читать не возможно, приходится форматировать, вот Ваш код.

    Код (Text):
    //Подключение библиотек
    #include <Wire.h>//библиотека I2c устройств
    #include <Multiservo.h>//библиотека для работы с мультисервошилд
    #define SERVO1_PIN 11//к пину мультисервошилд 11 подключена серва 1
    #define SERVO2_PIN 17// к пину 17 мультисервошилд подключена серва 2
    #include <pitches.h>// библиотека работы со звуком

    //Подключение библиотек Easy VR Shield + SoftSerial
    #if defined(ARDUINO) && ARDUINO >= 100
    #include "Arduino.h"
    #else // Arduino 0022 - use modified NewSoftSerial
    #include "WProgram.h"
    #endif
    #include "EasyVR.h"
    EasyVR easyvr(Serial);

    //Объекты
    Multiservo myservo1;// сервопривод 1
    Multiservo myservo2;// сервопривод 2

    //RFID модуль
    int data1 = 0;
    int ok = -1;
    int yes = 32;// пин с зелеными ОК светодиодами
    int no = 33;// пин с красными NOT OK светодиодами
    int data[14]; //Переменная для хранения информации с RFID карты
    int val = 0;
    // use first sketch in http://wp.me/p3LK05-3Gk to get your tag numbers
    int tag1[14] = {2,54,54,48,48,53,67,68,65,67,49,50,49,3};// Карта 1 ОК
    int tag2[14] = {2,54,54,48,48,53,67,68,53,50,69,67,49,3};// Карта 2 ОК
    int newtag[14] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // используется для сравнения
    int j_melody[] = {NOTE_G4,0,NOTE_A4,0, NOTE_B4,0,NOTE_A4,0,NOTE_B4,0, NOTE_C5,0};
    int j_noteDurations[] = {8,8,8,8,8,4,8,8,8,8,8,4};
    int d_melody[] = {NOTE_C4,0,NOTE_D4,0,NOTE_F4,0,NOTE_D4,0,NOTE_F4,0,NOTE_G4,0};
    int d_noteDurations[] = {8,8,8,8,8,4,8,8,8,8,8,4};
    int fail_melody[] = {NOTE_G2,0,NOTE_F2,0,NOTE_D2,0};
    int fail_noteDurations[] = {8,8,8,8,8,4};
    int bigspeakerpin = 8;

    //Easy VR модуль
    //Groups and Commands
    enum Groups
    {
        GROUP_0 = 0,
        GROUP_1 = 1,
    };
    enum Group0
    {
        ACTIVATE = 0,
    };
    enum Group1
    {
        G1_HELLO = 0,
        G1_HOW_ARE_YOU = 1,
        G1_SELF_CHECK = 2,
    };

    EasyVRBridge bridge;
    int8_t group, idx;


    // ИНИЦИАЛИЗАЦИЯ ПОСЛЕ ВКЛЮЧЕНИЯ ПИТАНИЯ

    void setup()

    {

        // Инициализация общения с RFID модулем и EasyVR модулем
        Serial.begin(9600);// к порту подключен Easy VR Shield (джампер режима на HW Serial)
        Serial3.begin(9600); // к порту подключен RFID сканер

        // Настраиваем выводы контроллера на вывод сигналов на пьезоизлучатели
        {
            pinMode(bigspeakerpin, OUTPUT);
        }

        //Иициализация порта I2C
        Wire.begin();
        // Назначаем вывод к которому подключен сервопривод УЗ дальномера
        myservo1.attach(SERVO1_PIN); // подключен ко 2 выводу МСШ
        // И подаем команду поворота сервопривода в положение 90 градусов при каждом включении
        myservo1.write(90);
        // Инициализация сервы емкости с лекарствами на 17 пине МСШ
        myservo2.attach(SERVO2_PIN);


        // Инициализация EasyVR Shield
        if (!easyvr.detect())
        {
            Serial.println("EasyVR not detected!");
            for (;;);
        }
        easyvr.setPinOutput(EasyVR::IO1, LOW);
        Serial.println("EasyVR detected!");
        easyvr.setTimeout(5);
        easyvr.setLanguage(EasyVR::ENGLISH);
        group = EasyVR::TRIGGER; //<-- start group (customize)

    }

    void action();

    // Программный модуль считывания данных c RFID карт
    boolean comparetag(int aa[14], int bb[14])
    {
        boolean ff = false;
        int fg = 0;
        for (int cc = 0 ; cc < 14 ; cc++)
        {
            if (aa[cc] == bb[cc])
            {
                fg++;
            }
        }
        if (fg == 14)
        {
            ff = true;
        }
        return ff;
    }

    void checkmytags() // compares each tag against the tag just read
    {
        ok = 0; // this variable helps decision-making,
        // if it is 1 we have a match, zero is a read but no match,
        // -1 is no read attempt made
        if (comparetag(newtag, tag1) == true)
        {
            ok++;
        }
        if (comparetag(newtag, tag2) == true)
        {
            ok++;
        }
    }

    void readTags()
    {
        ok = -1;

        if (Serial3.available() > 0)
        {
            // read tag numbers
            delay(100); // needed to allow time for the data to come in from the serial buffer.

            for (int z = 0 ; z < 14 ; z++) // read the rest of the tag
            {
                data1 = Serial3.read();
                newtag[z] = data1;
            }
            Serial3.flush(); // stops multiple reads

            // do the tags match up?
            checkmytags();
        }

        // now do something based on tag type
        if (ok > 0) // if we had a match
        {
            Serial.println("Accepted");
            digitalWrite(yes, HIGH);
            //delay(3000);

            for (int i = 0; i < 12; i++)
            {
                int j_noteDuration = 1000/j_noteDurations;
                tone(bigspeakerpin, j_melody,j_noteDuration);
                int j_pauseBetweenNotes = j_noteDuration * 1.30;
                delay(j_pauseBetweenNotes);
                noTone(bigspeakerpin);
            }
            easyvr.playSound(8, EasyVR::VOL_FULL);
            easyvr.playSound(17, EasyVR::VOL_FULL);
            {
                myservo2.write(90);
                delay(5000);
                easyvr.playSound(6, EasyVR::VOL_FULL);
                myservo2.write(10);
                digitalWrite(yes,LOW);
            }
            ok = -1;
        }
        else if (ok == 0) // if we didn't have a match
        {
            Serial.println("Rejected");
            digitalWrite(no, HIGH);
            //delay(3000);
            for (int i = 0; i < 6; i++)
            {
                int fail_noteDuration = 1000/fail_noteDurations;
                tone(bigspeakerpin, fail_melody,fail_noteDuration);
                int fail_pauseBetweenNotes = fail_noteDuration * 1.30;
                delay(fail_pauseBetweenNotes);
                noTone(bigspeakerpin);
            }
            easyvr.playSound(9, EasyVR::VOL_FULL);
            digitalWrite(no, LOW);

            ok = -1;
        }
    }

    // ИСПОЛНЯЕМЫЙ ПРОГРАММНЫЙ МОДУЛЬ

    void loop()

    {

        // Программный модуль работы с Easy VR Shield
        easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)
        Serial.print("Say a command in Group ");
        Serial.println(group);
        easyvr.recognizeCommand(group);
        do
        {
            // can do some processing while waiting for a spoken command
        }
        while (!easyvr.hasFinished());
        easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off
        idx = easyvr.getWord();
        if (idx >= 0)
        {
            // built-in trigger (ROBOT)
            // group = GROUP_X; <-- jump to another group X
            return;
        }
        idx = easyvr.getCommand();
        if (idx >= 0)
        {
            // print debug message

            uint8_t train = 0;
            char name[32];
            Serial.print("Command: ");
            Serial.print(idx);
            if (easyvr.dumpCommand(group, idx, name, train))
            {
                Serial.print(" = ");
                Serial.println(name);
            }
            else
                Serial.println();
            easyvr.playSound(0, EasyVR::VOL_FULL);
            // perform some action
            action();
        }
        else // errors or timeout
        {
            if (easyvr.isTimeout())
                Serial.println("Timed out, try again...");
            int16_t err = easyvr.getError();
            if (err >= 0)
            {
                Serial.print("Error ");
                Serial.println(err, HEX);
            }
        }
    }

    //Действия при голосовом управлении
    void action()
    {
        switch (group)
        {
        case GROUP_0:
            switch (idx)
            {
            case ACTIVATE:
                group = GROUP_1;
                break;
            }
            break;

        case GROUP_1:
            switch (idx)
            {

            case G1_HELLO:
                easyvr.playSound(13, EasyVR::VOL_FULL);
                break;

            case G1_HOW_ARE_YOU:
                easyvr.playSound(14, EasyVR::VOL_FULL);
                break;

            case G1_SELF_CHECK:
                easyvr.playSound(4, EasyVR::VOL_FULL);
                break;
            }
            break;
        }
    }
    Замечания
    Код (Text):
    // Настраиваем выводы контроллера на вывод сигналов на пьезоизлучатели

    {
          pinMode(bigspeakerpin, OUTPUT);
    }
    Замените на
    Код (Text):
    // Настраиваем выводы контроллера на вывод сигналов на пьезоизлучатели
          pinMode(bigspeakerpin, OUTPUT);
     
    Убрать все delay(), заменив их на проверку через millis(), смотрите пример. Почитайте, чем не приятен delay(), тут и тут.

    Кроме данного блока
    Код (Text):

    if (Serial3.available() > 0)
        {
            // read tag numbers
            delay(100); // needed to allow time for the data to come in from the serial buffer.

            for (int z = 0 ; z < 14 ; z++) // read the rest of the tag
            {
                data1 = Serial3.read();
                newtag[z] = data1;
            }
            Serial3.flush(); // stops multiple reads

            // do the tags match up?
            checkmytags();
        }
     
    Его надо менять, об этом вечером.

    Теперь немного, по тексту
    Да переходник usb - uart ttl.

    Вот тут начинаются нюансы, контролер не может обрабатывать 2 потока одновременно.

    Зачастую одновременная работа не требуется. А просто достаточно проверять каждый порт по очереди. Это зависит от логики программы, скорости, интенсивности передачи данных, а так же насколько критичные данные Вы получаете.

    Если же, сошлись все звезды, тогда AVR+прерывания+кольцевой буфер.

    Сейчас нет, времени, постараюсь вечером изучить Ваш код и подумать, можно ли обойтись без AVR. И надо посмотреть EasyVR Shield V2.0 и библиотеку для нее, судя по всему работа с Serial зашита в ней.

    UPD. И почитайте, что писали выше по подключению.
     
    Последнее редактирование: 9 мар 2015
  17. Den1975

    Den1975 Нерд

    В мануале по EasyVR Shield указано, что ставя джампер в положение HW используется обычный Serial режим pin(0,1). Как можно общаться через пины 1,2 ? А через Sofserial и программную функцию bridge происходит переключение пинов 0,1 на 12,13, при этом используется джампер в положении SW.

    Попробую повесить Easy VR на Serial 2, RFID на Serial3.
     
  18. X-Dron

    X-Dron Гик

    Опечатался, естественно 0-1
     
  19. Den1975

    Den1975 Нерд

    Буду весьма Вам благодарен, если Вы найдете решение для одновременного подключения. Вопрос - а зачем тогда на MEGA 4 Serial ? То есть они есть, а контроллер потоки с них не обрабатывает одновременно ?
    И еще вопрос - Serial.print и Serial.println также следует заменить допустим на Serial3.print и Serial3.println ?
     
  20. Alex19

    Alex19 Гуру

    Не влазит, видимо я не поэт.

    Появляются окна, буду писать, разберемся с подключением EasyVR Shield V2.0. Буду говорить плате которая продается в Амперке, библиотека скачана от туда.

    Само подключение верно, но есть нюансы.

    Как уже писал X-Dron
    Он только ошибся в пинах для режима HW,PC, UP, они 0-1 (см. http://files.amperka.ru/datasheets/easyvr_user_manual.pdf стр. 20).

    У Вас есть 2 варианта, первый использовать SoftwareSerial на 12-13 пинах, о нем можно прочесть тут, режим J12 положение SW. И тогда не потребуется хирургическое вмешательство.

    Второй
    J12 положение SW, сам бы остановился на втором.

    После этого меняем код
    Код (Text):
    EasyVR easyvr(Serial2);
    И добавляем в setup
    Код (Text):
    Serial2.begin(9600);
    Теперь все подключено верно.
    Возможно, Ваш код заработает. Вы сможете проверять шаги при помощи Serial.print().

    Моя идея убрать, delay + переписать проверку Serial3, сделать все правильно, потребует существенно переделать программу. Поэтому пока остановлюсь, вдруг будет работать и так:).

    Теперь по поводу одновременности прочтения данных из Serial, без привязки к конкретному решению, коду, датчикам и т.д.

    Первый вариант перебора, вот упрощенный код
    Код (Text):

    /// <summary>
    /// Переменная хранящая индекс текущего char в массиве хранящего пакет данных
    /// </summary>
    int indexCharInArray;

    /// <summary>
    /// Константа хранящая мак. размер массива хранящего пакет данных
    /// </summary>
    #define receiveSizeArrayCOM 100
    /// <summary>
    /// Массив хранящий пакет данных
    /// </summary>
    char receiveCharArrayCOM[receiveSizeArrayCOM];

    /// <summary>
    /// Константа - Символ новой строки
    /// </summary>
    #define newLine '\n'

    /// <summary>
    /// Константа - Символ для очистки значения char
    /// </summary>
    #define clearChar '\0'

    /// <summary>
    /// Переменная хранящая завершено ли получения данных
    /// </summary>
    boolean finishReceiveData = false;

    void setup()
    {
      Serial.begin(9600);  // 0 (RX) и 1 (TX);
      Serial1.begin(9600);  // 1: 19 (RX) и 18 (TX);
      Serial2.begin(9600);  // 2: 17 (RX) и 16 (TX);
      Serial3.begin(9600);  // 3: 15 (RX) и 14 (TX)
    }

    void loop()
    {
      // Получение данных с Arduino - Serial
      GetDataFromSerial();
      /*
     GetDataFromSerial1();
     GetDataFromSerial2();
      и т.д.
      */

      if (finishReceiveData)
      {
        // Тут делаем анализ данных
        Serial.println(receiveCharArrayCOM);
     
        // Очистка переменных получения данных, после получения данный
        ClearReceiveDataVariable();
      }
    }

    /// <summary>
    /// Получение данных с Arduino
    /// </summary>
    void GetDataFromSerial()
    {
        while(Serial.available())
        {
            char incomingChar = (char)Serial.read();
     
            if(incomingChar != newLine &&
              incomingChar != clearChar)
            {
                receiveCharArrayCOM[indexCharInArray] = incomingChar;
                indexCharInArray++;
            }
            else
            {
                receiveCharArrayCOM[indexCharInArray] = clearChar;
     
                finishReceiveData = true;
            }
        }
    }

    /// <summary>
    /// Очистка переменных получения данных, после получения данный
    /// </summary>
    void ClearReceiveDataVariable()
    {
      indexCharInArray = 0;
      memset(receiveCharArrayCOM,clearChar,receiveSizeArrayCOM);

      finishReceiveData = false;
    }
     
    Надо второй порт, копируем GetDataFromSerial1, переменные которые используются или заносим все в массивы, вариантов оптимизации масса.

    Общая идея.
    В каждом цикле loop мы делаем проверку, всех портов, и продолжаем выполнение программы, без задержек. Как только мы получаем последний символ (в данном примере или новая строка или пустой символ), мы взводим флажок, о том, что пакет получен и обрабатываем его.

    В большинстве случаев, этого достаточно.

    Есть еще, решение на основании SerialEvent но им не пользовался, ни чего не скажу. В теории он должен быть по шустрее.

    Второй вариант AVR+прерывания+кольцевой буфер (Если не знакомы с AVR, не тратьте время).
    Готовый код, правда там используется формат пакета, но все же
    http://forum.amperka.ru/threads/ard...ick-serial-между-2-ардуинами.4053/#post-34697

    Ни первый не второй вариант, не одновременный. Первый вариант, позволяет в большинстве случаев не пропустить данные, при условии, что программа написана правильно.

    Второй более скоростной (почти одновременный :)), так как использует прерывания и занимает меньше места, за счет прямой работы с регистрами.

    Если ошибся или упустил какое-то решение, надеюсь коллеги подправят.