Arduino - Processing. Обмен данными через один COM-порт.

Тема в разделе "Проводная и беспроводная связь", создана пользователем Eariel, 21 июл 2017.

  1. Eariel

    Eariel Нуб

    Вопрос из разряда "для начинающих", однако если бы сам мог решить, не написал бы.
    В идеале хотелось бы следущее:
    1. В окне Процессинга тыкаем мышкой. Процессинг отсылает строку в COM порт.
    2. Ардуино принимает строку, в ответ на нее выводит свою строку в тот же COM порт.
    Короче смысл в том, чтобы организовать работу с МК через компьютер.
    Проблемы возникли уже на стадии примера скетча с инета. Попытался воспроизвести скетч из статьи с инета (много копий нашел, суть одна и та же): http://developer.alexanderklimov.ru/arduino/processing.php
    Конкретно раздел "Отправка данных". Выполнил все в точности, как в статье - ноль результата. Процессинг передает единицу в порт - ардуино НЕ включает светодиод. Пробовал отправлять строку, менять что-то - результату ноль! Светодиод загорается сразу после запуска скетча на процессинге (ардуино уже прошит и работает к тому моменту). То ли я что-то делаю неправильно, то ли пример кривой - я не знаю.
    В частности, мне не понятны следующие вещи:
    1. if (Serial.available()) { или if (Serial.available() > 0) { в чем разница и есть ли она?
    2. в чем разница между serial.write('1'); serial.write("1"); serial.write(1);
    3. как мне проверить, что вообще передается в порт?
    4. ну и самое главное - как сделать так, чтобы оба скетча как-то уже научились работать и передавать данные в один порт? Он ведь один, не так ли? Тогда почему при попытке что-то передать из одного из скетчей другая программа орет, что порт занят и все?
    Может я плохо искал, но в наших интернетах я не нашел никаких ответов на эти вопросы. Как и рабочего скетча на совместную работу через один порт.
     
  2. sslobodyan

    sslobodyan Гик

    Не известно, что там у вас за железо. Но если б я ковырялся с портами, то подключил бы примитивный юсб-ком преобразователь на 2102 и через него сериальный порт ардуинки. На преобразователе есть светодиоды приема и передачи. По ним достаточно просто понять, шлются данные или нет. А дальше уже дело техники - настроить одинаково скорость, четность, битность.
     
  3. shpock

    shpock Гик

    [QUOTE="sslobodyan, post: 124556, member: 10892" настроить одинаково скорость, четность, битность.[/QUOTE]
    с этого наверное нужно начать, да и номер порта не мешало бы.
     
  4. Eariel

    Eariel Нуб

    В общем решение найдено. Как выяснилось, проблем в аппаратной части не было, единственное что для чистоты эксперимента подключил отдельно светодиод на 5-й пин (через резистор 0,2кОм). Сложности заключались в специфике работы библиотеки serial языка processing, а именно: команда записи в порт write оперирует байтами. И, кроме того, помогло явное указание типа данных, которые передавались в порт. Как следует из описания команды write, передаваемые данные могут быть разных типов (https://processing.org:8443/reference/libraries/serial/Serial_write_.html).
    Короче, задал я в процессинге пару переменных типа int, и присвоил им значения, которые вполне адекватно считались Ардуино (там принимающая переменная того же типа). Главное помнить, что это число должно быть в диапазоне от 0 до 255, потому что для передачи таких чисел достаточно того самого одного байта.
    И еще важный момент - после открытия порта в скетче процессинга необходимо выждать секунду, перед тем как приступать к отправке данных, иначе ничего не работает вообще.

    Код скетча Processing:

    Код (C++):
      import processing.serial.*;

      Serial myPort;  //  создаем объект класса Serial
      String val;     //  данные, получаемые из порта Serial (строка)
      int src1, src2;

      void setup(){
        src1 = 245;
        src2 = 255;
        size(200, 200);  //  размеры окна в пикселях
        //  выводим инфу об имеющихся портах
        printArray(Serial.list());
        //  сохраняем в переменную название порта [1]
        String portName = Serial.list()[1];
        print("portName = ");  println(portName);
        //  открываем порт под номером [1]
        myPort = new Serial(this, portName, 9600);
        //  начало передачи данных
        print("[prgr_msg] start of data transfer");
        println();
        //  задержка не менее 1сек, иначе ничего не заработает
        delay(1000);
      }


      void draw(){
        if (mousePressed == true){  //  если есть клик мышкой в пределах окна
          myPort.write(src1);          //  отсылаем 245
          println("245");
      }
        if (mousePressed == false){  //  если клика не было
          myPort.write(src2);          //  отсылаем 255
          println("255");
        }
        delay(500);
      }

    Код скетча Arduino:

    Код (C++):
      #include <Wire.h>
      //  задание констант
      const int ledPin =  5;   //  номер пина, к которому подключен светодиод
      int val;

      void setup(){
        //  настраиваем вывод, к которому подключён светодиод, как выход
        pinMode(ledPin, OUTPUT);
        //  открываем порт
        Serial.begin(9600);
        digitalWrite(ledPin, LOW);
        //  задержка 1сек на всякий случай
        delay (1000);
      }

      void loop(){
        val = 0;
        if (Serial.available() > 0){  // если данные можно прочитать,
          val = Serial.read();        // считываем их и передаем на хранение в val
        }
        if (val == 245){  //  если получили 245,
          digitalWrite(ledPin, HIGH); // включаем светодиод
        }
        if (val == 255){  //  если получили 255,
          digitalWrite(ledPin, LOW); // отключаем светодиод
        }
        //  задержка на всякий случай
        delay(50);
      }
     
    Последнее редактирование: 30 июл 2017