IR через Ethernet. Конвертация данных

patriot_stv
Offline
Зарегистрирован: 19.02.2018

Добрый день!

Коллеги, подскажите как решить вопрос или где и о чем почитать, чтобы приблизиться к решению. 

Суть вопроса такая. Пытаю сделать устройство для передачи ИК команд с одного контроллера на другой через Ehernet. Первый их передает(предварительно считанные с пульта посредством IRremote), второй принимает и отправляет на ик-эммитер. В качестве приемного устройства выступает Arduino nano + W5100.

У меня получилось это реализовать, если протокол команды с пульта (при считывании) распознался библиотекой IRremote и команда имеет вид "38863BD2". (как это реализовано покажу ниже) Проблема начинается, если при считываниее протокол не распознался и нужно отправлять RAW команду.

Работа с RAW в библиотеке на приемной строне выглядит так (например):

unsigned int  rawData[] = {450,250, 200,250, 200,550, 200,400, 200,400, 200,250, 200,250, 200,250, 200,250, 200,550, 200,550, 250,400, 200,550, 200,400, 200,400, 250,350, 250,250, 200};
int khz = 38;
irsend.sendRaw(rawData, sizeof(rawData) / sizeof(rawData[0]), khz);

Ну, думаю это и так вам известно! ))

Получается, что мне нужно отправить строку в виде "450,250, 200,250, 200,550 ... итд", принять ее и обработав превратить в массив INT. У меня получилось это сделать только при помощи цикла, но это неприемлемо долгий в обработке вариант и создает сильные задержки в работе.

Может кто подскажется как самым безболезненым образом превратить String SerialDataIn = "111,222,333,444" в int RawData [] = {111,222,333,444} ?? 

Читал и форум и гуглил...много разной информации есть, но так и не смог собрать в рабочий вариант...очень много нюансов, которые не могу понять! )) 

Теперь о том, как сделал, если протокол при считывании распознался. Может быть есть варианты как-то оптимизироваться (хотя, относительно быстро работает)

void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 200) {
          readString +=c;         
        }        
         //Serial.println(readString); 
        //if HTTP request has ended
        if (c == '\n') {
         
        serialDataIn = String("");

        startIRcode = readString.indexOf('='); //находим позицию начала команды
        endIRcode   = readString.indexOf('!'); //находим позицию окончания команды

        irprotocol = readString.substring(startIRcode-3,startIRcode); //вытаскиваем из строки протокол
        serialDataIn = readString.substring(startIRcode+1,endIRcode); //вытаскиваем из строки команду

        
       constcomm = serialDataIn.c_str(); //конвертация String в const char для работы strtoul     

       IRcomm =  strtoul(constcomm,NULL, 16); //преобразование из текста в HEX
 
 //отправляем команду
          digitalWrite(STATUS_PIN, HIGH); 
           if (irprotocol == "NEC") { irsend.sendNEC(IRcomm, 32);}
          digitalWrite(STATUS_PIN, LOW);

          Serial.println("Sent IR signals from LED at Pin 3 (PWM)");
          
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

 //stopping client
          client.stop();

          readString="";
          serialDataIn = String("");
          counter=0;
        }
      }
    }
  }
} 

Команду я отправляю в виде "GET /NEC=38863BD2! HTTP/1.1 HOST: 192.168.1.223 \0D\0A"

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

А сколько миллисекунд сейчас занимает обработка? Вы уверенеы что задержка именно в обработке, а не в передаче по интернету?

patriot_stv
Offline
Зарегистрирован: 19.02.2018

Честно говоря, я не знаю как в этой среде посмотреть время .. Я ориентируюсь на время вывода результата в монитор порта ... команда принимается быстро, а вот обработка команды (если делать циклом, как я говорил) ..ммм..секунда+-. Я думаю это вполне логично, кучу символов перебрать по одному.

Интуиция подсказывает, то наверняка есть спобобы конвертации char массива в int массив без использования (во всяком случае явного) цикла... просто, его нужно найти. ДУмаю, спецы по СИ++ должны знать!

b707
Offline
Зарегистрирован: 26.05.2017

patriot_stv пишет:

Интуиция подсказывает, то наверняка есть спобобы конвертации char массива в int массив без использования (во всяком случае явного) цикла... просто, его нужно найти. ДУмаю, спецы по СИ++ должны знать!

вы бы код своего цикла показали - сдается. что дело там совсем не в обработке символов.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015
Serial.println(micros());

Вставьте эту строчку перед началом цикла и после и посмотрите какие числа в мониторе выведет.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Вот такая ерунда из разряда "решение в лоб" на уно прокручивается за 3,4мс. Я сомневаюсь что у Вас там намного больше (если вообще больше) и сомневаюсь что там на глаз заметно будет :)

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  String SerialDataIn = "450,250, 200,250, 200,550, 200,400, 200,400, 200,250, 200,250, 200,250, 200,250, 200,550, 200,550, 250,400, 200,550, 200,400, 200,400, 250,350, 250,250, 200";
  int delimeter_pos = -1;
  int code_count = 0;
  Serial.println(micros());
  do
  {
    delimeter_pos = SerialDataIn.indexOf(',', delimeter_pos+1);
    code_count++;
  } while(delimeter_pos > 0);
  int RawData[code_count];

  for(int i=0; i<code_count; i++)
  {
    RawData[i] = SerialDataIn.toInt();
    SerialDataIn.remove(0, SerialDataIn.indexOf(',', 0)+1);
    SerialDataIn.trim();
  }
  Serial.println(micros());
  delay(20000);
}

 

patriot_stv
Offline
Зарегистрирован: 19.02.2018

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

По измерениям получилось 7-10мс от момента получения пакета до отправки на ИК. Не идеальное время, но с ним уже можно жить!))