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

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

  1. Den1975

    Den1975 Нерд

    Благодарю, сейчас буду экспериментировать. Напишу что получается.
     
  2. Alex19

    Alex19 Гуру

    Отписал, но вариант ARV лучшее не рассматривайте. Готовый, код увы нет времени, да и это не педагогично:).

    Дополнительные возможности.

    У контролера 1 поток, это не процессор компьютера.

    К примеру
    Код (Text):
    digitalWrite(2,1);
    digitalWrite(3,1);
    Выполнятся последовательно, но выполнение займет миллионные секунды.
    Но все равно это будет не одновременно. Так как 1 строка будет запущена первой, вторая - второй а не одновременно.

    Мне еще не встречались контролеры, которые могут работать параллельно, процессоры от компьютеров не в счет.

    Да, просто подставляем нужный порт, а дальше все как обычно.

    Позволю дать Вам один совет, остановитесь с этим проектом и почитайте хорошую книгу. Я сам сейчас, стараюсь систематизировать свои знания и читать хорошие книги. Это очень сильно экономит время, поверьте моему опыту.
     
  3. Den1975

    Den1975 Нерд

    Внимательно прочитав все Ваши советы, изложенные выше сделал следующее:
    1. Отогнул 12 и 13 выводы Easy Vr SHIELD и напрямую подключил их к Serial 2
    2. Также отогнул 0 и 1 выводы Easy Vr SHIELD, чтобы не занимали Serial
    3. Подключил RFID модуль к Serial1
    4. Подкорректировал скетч (прилагается)
    Все заработало совместно, но есть некоторые временные задержки в работе, как я понимаю из-за использования функции delay() в коде, которую нужно заменить на millis().
    Оставив Serial (0,1) в покое, на него выводится вся поступающая с подключенных модулей инфа.
    Может это не нужно делать и указать отдельный вывод по каждому порту на свой порт, тогда только не увижу что происходит на порту без преобразователя, но мне это и не нужно.
    Подскажите , что не так в скетче и как улучшить то, что есть и какие хорошие книги прочитать.

    Спасибо за помощь и советы.
     

    Вложения:

  4. Den1975

    Den1975 Нерд

    Код (Text):
    //Подключение библиотек

    #include <Wire.h>//библиотека I2c устройств
    #include <Multiservo.h>//библиотека для работы с мультисервошилд
    #include <EEPROM.h>
    #include <pitches.h>// библиотека работы со звуком

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

    #define SERVO1_PIN 11//к пину 11 подключена серва 1
    #define SERVO2_PIN 17// к пину 17 подключена серва 2
    //Объекты
    Multiservo myservo1;// сервопривод 1
    Multiservo myservo2;// сервопривод 2
    //Мелодия при включении питания
    int smallspeakerpin = 9;// пьезодинамик подключен к пину 9
    int length = 8; // число проигрываемых нот
    char notes[] = "cegCCgec "; // пробел - пауза
    int beats[] = { 1, 1, 1, 3, 1, 1, 1, 4 };
    int tempo = 400;// темп проигрывания мелодии

    void playTone(int tone, int duration)
    {
      for (long i = 0; i < duration * 1000L; i += tone * 2)
      {
        digitalWrite(smallspeakerpin, HIGH);
        delayMicroseconds(tone);
        digitalWrite(smallspeakerpin, LOW);
        delayMicroseconds(tone);
      }
    }
    void playNote(char note, int duration)
    {
      char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' };
      int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
        // проиграть тон, соответствующий ноте
      for (int i = 0; i < 8; i++) {
        if (names[i] == note) {
          playTone(tones[i], duration);
        }
      }
    }

    //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,
      };
    int8_t group, idx;


    // ИНИЦИАЛИЗАЦИЯ РОБОТА ПОСЛЕ ВКЛЮЧЕНИЯ ПИТАНИЯ
    void setup()
    {
    /* Инициализируем выводы контроллера, к которым подключены кнопки, в INPUT. */
      pinMode(vbtn[0], INPUT);
      pinMode(vbtn[1], INPUT);
    /* Устанавливаем выводы, к которым подключены светодиоды платы режимов,
      в OUTPUT. Далее зажигаем и гасим светодиоды с интервалом в 0.5 сек
      для проверки их работы */
        for (vmode = 0; vmode < 6; vmode = vmode + 1)
        {
        pinMode(vledpins[vmode], OUTPUT);
        digitalWrite(vledpins[vmode], HIGH);
        delay (500);
        digitalWrite(vledpins[vmode], LOW);
        }
    // Устанавливаем значение первого режима работы робота
      vmode = 0;
    // Настраиваем выводы контроллера №№ 8 и 50 на вывод сигналов на пьезоизлучатель и динамик
      pinMode(smallspeakerpin, OUTPUT);
      pinMode(bigspeakerpin, OUTPUT);

    //Инициализация пинов YES и NO светодиодов RFID модуля
      pinMode(yes, OUTPUT);
      pinMode(no, OUTPUT);
     
    //Иициализация порта I2C для мультисервошилда
    Wire.begin();
    // Назначаем вывод к которому подключен сервопривод 1
      myservo1.attach(SERVO1_PIN); // подключен ко 2 выводу МСШ
    // И подаем команду поворота сервопривода в положение 90 градусов при каждом включении
      myservo1.write(90);
    // Инициализация сервы 2 на 17 пине МСШ
      myservo2.attach(SERVO2_PIN);
     
    // Инициализация общения по Serial
        Serial.begin(9600);//0 (RX) и 1 (TX);
    // к порту 2 подключен Easy VR Shield (джампер режима на SW)
        Serial2.begin(9600);//17 (RX) и 16 (TX);
    // к порту 3 подключен RFID сканер  
        Serial3.begin(9600); //15 (RX) и 14 (TX);
    // Инициализация 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)

    /* Проигрываем мелодию по завершению инициализации робота */
      for (int i = 0; i < length; i++)
      {
        if (notes[i] == ' ')
        {
          delay(beats[i] * tempo); // пауза
        } else
        {
          playNote(notes[i], beats[i] * tempo);
        }
            // пауза между нотами
        delay(tempo / 2);
      }
    }

    // ИСПОЛНЯЕМЫЙ ПРОГРАММНЫЙ МОДУЛЬ
    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);
          //digitalWrite(A1, HIGH);
          //delay(2000);
          //digitalWrite(A1, LOW);
            break;
          case G1_SELF_CHECK:
          easyvr.playSound(4, EasyVR::VOL_FULL);
            //digitalWrite(A2, HIGH);
            //delay(2000);
            //digitalWrite(A2, LOW);
            break;
          }
          break;
        }
    }

    // Программный модуль считывания данных 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[i];
          tone(bigspeakerpin, j_melody[i],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[i];
          tone(bigspeakerpin, fail_melody[i],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;
      }
    }
     
  5. X-Dron

    X-Dron Гик

    Внимание вопрос: А как собираешься рабртать с EasyVR Commander?
     
  6. Den1975

    Den1975 Нерд

    согласен. вернул назад пины 0,1 Easy VR Shield
     
  7. Den1975

    Den1975 Нерд

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

    Alex19 Гуру

    Этого я не советовал, специально ссылался на Вас, чтобы подробнее просмотрел на Ваше сообщение.

    Самый простой способ нахождения ошибки, комментировать и/или разбить программу на части проверять их по отдельности. Проверяя переменные с помощью Serial.println

    Может тут
    Код (Text):

    easyvr.playSound(8, EasyVR::VOL_FULL);
    easyvr.playSound(17, EasyVR::VOL_FULL);
     
    Улучшить, выкидывать delay(), в setup() еще можно использовать, но в loop не желательно.

    По книгам, лучше посмотреть тут и тут.

    UPD. Просто книгу рекомендовать не рискну, начинал с небольшим опытом программирования, поэтому книги пропустил, о чем сейчас жалею. Сейчас читаю эту
     
    Последнее редактирование: 9 мар 2015
  9. Den1975

    Den1975 Нерд

    Повторы исключил. В коде вызывалась функция action().
    Попытаюсь осознать замену delay на millis.
    Спасибо за добрые советы, благодаря которым все в общем то удалось.