Делаю робота управляемого с компьютера через java приложение. Из приложения должна отравляться строка с командой через com порт на Arduino nano, а она должна её парсить и ретранслировать через nRF24 непосредственно роботу. До робота (com3) доходят числа от 0 до 1000 с шагом 6 в бесконечном цикле при том что передатчик ничего не передаёт.При отправки команд из монитора порта (com6) всё доходит. При отправке из приложение ничего не доходит и Arduino возвращает приложению null. Подскажите в чем дело. Код ретранслятора. Код (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(); } }
Ещё раз, в каком случае это происходит? ПРД не передаёт -> значит ПРМ что-то левое получает откуда-то со стороны. Ком6 это кто - прд (передатчик) или прм (приемник/робот)? У вас поток сразу из 10-ти посылок, каждые 2 сек, прм обрабатывает 1 посылку в секунду - он не захлебывается? Попробуйте отправлять не 10 посылок, а 1. В каком порядке включаются приборы? Временная синхронизация не лучшая идея, т.к. могут быть "недополученные" посылки. Рекомендую усложнить код, но реализовать передачу так: ПРД ждет от ПРМ разрешение на передачу. Если пришло, то отправлять данные. ПРМ если не получает данные дольше чем N мс (N > времени работы одного цикла ПРМ), то отправляет разрешение на передачу. После того как прм выполнил пришедшую команду он отправляет разрешение на передачу сразу. Естественно слушать надо тогда, когда устройства "свободны" от выполнения других операций.
этот шум появляется при включении питания от аккумулятора (и акум и usb) это передатчик(ретранслятор) попробывал результат тот же возвращатся null
У вас java-программа отправляет данные по проводам на ардуино-прд (ретранслятор) -> ардуино-прд передаёт данные ардуино-прм (робот) через nFR. да? Если убрать из цепочки java-программу, то проблем нет? Правильно ли идёт приём и обработка на ардуино-прд?
всё верно если напрямую на передатчик подать команду через монитор порта из IDE то всё работает не смотря на шум на приёмнике. я считаю что проблема на стыке приложение передатчик , но как понять что ардуина получает из приложения и получает ли вообще если она ничего не возвращает и одновременно с приложением нельзя открыть монитор
Так он есть когда и прд выключен? Попробуйте для отладки использовать программный сериал (если у вас есть 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-таблица.
да Побывал принимать и в варианте ascii значений и как int, а не string, но всё также только через монитор работает.
Если уж принимать пачку символов, то в ардуино-примерах есть вариант через прерывания. Пачку байт набираете и обрабатываете