Управление Arduino из приложения через com порт

Тема в разделе "Arduino & Shields", создана пользователем Goblin, 18 ноя 2018.

  1. Goblin

    Goblin Нуб

    Делаю робота управляемого с компьютера через java приложение. Из приложения должна отравляться строка с командой через com порт на Arduino nano, а она должна её парсить и ретранслировать через nRF24 непосредственно роботу. До робота (com3) доходят числа от 0 до 1000 с шагом 6 в бесконечном цикле при том что передатчик ничего не передаёт.При отправки команд из монитора порта (com6) всё доходит. При отправке из приложение ничего не доходит и Arduino возвращает приложению null. Подскажите в чем дело.
    com3com6.png
    Код ретранслятора.
    Код (C++):
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    #include "Wire.h"
    const uint64_t pipe2 = 0xF0F1F2F3F1LL;
    RF24 radio(9, 10); // CE, CSN
    int data = 0;
    String flags = " ";
    int flag  = 0;
    void setup() {
      // put your setup code here, to run once:
    Serial.begin(9600);
    radio.begin();
      delay(2);
      radio.setChannel(9);
      radio.setDataRate(RF24_1MBPS);
     
        radio.setPALevel(RF24_PA_HIGH);  
      radio.openWritingPipe(pipe2);
    }

    void loop() {
     
    if (Serial.available())
    {
       flags = Serial.readString();
       data=flags.toInt();
       Serial.write(data);
       radio.write(&data, sizeof(data));
       Serial.println(data);
    }
       delay(50);
    }
     
    Код приложения.
    Код (Java):
    package test;
    import jssc.SerialPort;
    import jssc.SerialPortEvent;
    import jssc.SerialPortEventListener;
    import jssc.SerialPortException;

    /**
    *
    * @author Goblin
    */

    class Wait {
      public static void bySeconds(long s) {
        try {
          Thread.currentThread().sleep(s * 1000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }

    public class Test {
    //private static SerialPort serialPort;
        public static void main(String[] args) {
                  //В конструктор класса передаём имя порта с которым мы будем работать
            SerialPort serialPort = new SerialPort("COM6");      
            Wait.bySeconds(2);//пауза
            try {
                //Открываем порт
                serialPort.openPort();
                //Выставляем параметры. Можно использовать и такую строку serialPort.setParams(9600, 8, 1, 0);
                serialPort.setParams(SerialPort.BAUDRATE_9600,
                                     SerialPort.DATABITS_8,
                                     SerialPort.STOPBITS_1,
                                     SerialPort.PARITY_NONE);          
                for(int i=0;i<10;i++){
                serialPort.writeString("101");          
                String data = serialPort.readString();
                System.out.println(data);
                }
                serialPort.closePort();
            }
            catch (SerialPortException ex) {
                System.out.println(ex);
            }
            }
        }
    Код робота.

    Код (C++):
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    #include "I2Cdev.h"
    #include <SoftwareSerial.h>
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
    #endif
    //#define OUTPUT_READABLE_ACCELGYRO

    const uint64_t pipe2 = 0xF0F1F2F3F1LL;// индитификатор передачи, "труба"

    RF24 radio(9, 10); // CE, CSN
    int data = 0;

    #define FORW 101
    #define BACK 111
    #define STOP 0
    #define LEFTT 121
    #define RIGHTT 131
    #define OFFSTOP 141
    int IN3 = 5; // Input3
    int IN4 = 4; //задний двигатель
    int ENB = 3;
    int IN1 = 8; // Input1
    int IN2 = 7; //передний двигатель
    int ENA = 6;
    int flag = 141;
    boolean stopflag = 0;
    int OutputSignal;
    unsigned long currentMillis;
    long previousMillis1 = 0;
    //long previousMillis2 = 0;
    int time1 = 0;
    String ss = "L128/T13/1235";
    String resut = "";

    void setup() {
     
      Serial.begin(9600);
      // пины драйвера
      pinMode (ENB, OUTPUT);
      pinMode (IN3, OUTPUT);
      pinMode (IN4, OUTPUT);
      pinMode (IN1, OUTPUT);
      pinMode (IN2, OUTPUT);
      pinMode (ENA, OUTPUT);
      //начало радиосвязи
       radio.begin();
      delay(2);
      //выбор канала радиосвязи
      radio.setChannel(9); // (0-127)
         // скорость, RF24_250KBPS, RF24_1MBPS или RF24_2MBPS
          // RF24_250KBPS на nRF24L01 (без +) неработает.
          // меньше скорость, выше чувствительность приемника.
      radio.setDataRate(RF24_1MBPS);
     
       // мощьность передатчика RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_MED=-6dBM,
      radio.setPALevel(RF24_PA_HIGH);  
    // открывает режим передачи
    //открывает режим прослушки
       radio.openReadingPipe(1,pipe2);
       //начинаем с прослушки
      radio.startListening();
    }

    // подпрограмма перезапуска ардуино
    void(* resetFunc) (void) = 0;

    void loop() {
        RADIO();
    TIMEBREAK();
    //получение времени
         currentMillis = millis();

       if (flag == FORW) {
          RotationForw();  
        }
           if  (flag == BACK) {
          RotationBack();
        }
          if  (flag == LEFTT) {        
          RotationLeft();
        }
           if  (flag == RIGHTT) {
          RotationRight();    
        }
             if  (flag == OFFSTOP) {
          RotationStop();
        }
      }
    void RotationForw() {
      digitalWrite(IN1,HIGH);
      digitalWrite(IN2,LOW);
      analogWrite(ENA,105);
      digitalWrite(IN3,LOW);
      digitalWrite(IN4,HIGH);
      analogWrite(ENB,105);
    }
      void RotationBack() {
      digitalWrite(IN1,LOW);
      digitalWrite(IN2,HIGH);
      analogWrite(ENA,105);
      digitalWrite(IN3,HIGH);
      digitalWrite(IN4,LOW);
      analogWrite(ENB,105);
    }
    void RotationLeft() {
      digitalWrite(IN1,HIGH);
      digitalWrite(IN2,LOW);
      analogWrite(ENA,105);
      digitalWrite(IN3,HIGH);
      digitalWrite(IN4,LOW);
      analogWrite(ENB,105);
    }
      void RotationRight() {
      digitalWrite(IN1,LOW);
      digitalWrite(IN2,HIGH);
      analogWrite(ENA,105);
      digitalWrite(IN3,LOW);
      digitalWrite(IN4,HIGH);
      analogWrite(ENB,105);
    }
    void RotationStop() {
      digitalWrite(IN1,LOW);
      digitalWrite(IN2,LOW);
      digitalWrite(IN3,LOW);
      digitalWrite(IN4,LOW);
    }
    void RADIO() {

       if (radio.available()){ // проверяем не пришло ли чего в буфер.
        radio.read(&data, sizeof(data));
        // читаем данные, указываем сколько байт читать
        flag = data;
         previousMillis1 = currentMillis;
     
        Serial.println(flag);
      }
    }
      void TIMEBREAK() {
         time1 = currentMillis - previousMillis1;
         Serial.println(time1);
        if ( time1 > 1000) {
          resetFunc();
      }
      }
     
  2. Daniil

    Daniil Гуру

    Ещё раз, в каком случае это происходит? ПРД не передаёт -> значит ПРМ что-то левое получает откуда-то со стороны.
    Ком6 это кто - прд (передатчик) или прм (приемник/робот)?

    У вас поток сразу из 10-ти посылок, каждые 2 сек, прм обрабатывает 1 посылку в секунду - он не захлебывается?
    Попробуйте отправлять не 10 посылок, а 1.

    В каком порядке включаются приборы? Временная синхронизация не лучшая идея, т.к. могут быть "недополученные" посылки.
    Рекомендую усложнить код, но реализовать передачу так:
    ПРД ждет от ПРМ разрешение на передачу. Если пришло, то отправлять данные.
    ПРМ если не получает данные дольше чем N мс (N > времени работы одного цикла ПРМ), то отправляет разрешение на передачу.
    После того как прм выполнил пришедшую команду он отправляет разрешение на передачу сразу.
    Естественно слушать надо тогда, когда устройства "свободны" от выполнения других операций.
     
  3. Goblin

    Goblin Нуб

    этот шум появляется при включении питания от аккумулятора (и акум и usb)
    это передатчик(ретранслятор)
    попробывал результат тот же возвращатся null
     
  4. Daniil

    Daniil Гуру

    У вас java-программа отправляет данные по проводам на ардуино-прд (ретранслятор) -> ардуино-прд передаёт данные ардуино-прм (робот) через nFR. да?
    Если убрать из цепочки java-программу, то проблем нет?
    Правильно ли идёт приём и обработка на ардуино-прд?
     
  5. Goblin

    Goblin Нуб

    всё верно если напрямую на передатчик подать команду через монитор порта из IDE то всё работает не смотря на шум на приёмнике. я считаю что проблема на стыке приложение передатчик , но как понять что ардуина получает из приложения и получает ли вообще если она ничего не возвращает и одновременно с приложением нельзя открыть монитор
     
  6. Daniil

    Daniil Гуру

    Так он есть когда и прд выключен?
    Попробуйте для отладки использовать программный сериал (если у вас есть uart-usb переходник).

    Точно!
    Тут вы отправляете 3 байта:
    символ = код_10 = код_16
    "1" = 49 = 0х31
    "0" = 48 = 0х30
    "1" = 49 = 0х31
    "\n" = 13 = 0х0D - конец строки, в Си строка этим и отличается от массива, наличием в конце символа "конец строки". Не знаю как обрабатывает это дело java-serial, но в любом случае проблема может быть в том, что вы отправляете не то, что нужно.
    А вам надо отправить 1 байт:
    код_10 = код_16 = символ
    101 = 0х64 = "e" - английская "е". (не копируйте от из этого сообщения, вы ведь не знаете я написал "е" или "e":))
    см. функции char и ord и ascii-таблица.
     
    Последнее редактирование: 18 ноя 2018
  7. Goblin

    Goblin Нуб

    да
    Побывал принимать и в варианте ascii значений и как int, а не string, но всё также только через монитор работает.
     
  8. Daniil

    Daniil Гуру

    Если уж принимать пачку символов, то в ардуино-примерах есть вариант через прерывания. Пачку байт набираете и обрабатываете