Полный текст

Antel
Offline
Зарегистрирован: 10.06.2012

Доброго времени суток!

У меня возникла проблема с обработкой данных посылаемых на Arduino. Посылаю "Test", а получаю каждый символ в ASCII кодировке, т.е.  84, 101, 115, 116. Можно ли как то от этого избавится и получить нормальное слово?

maksim
Offline
Зарегистрирован: 12.02.2012

А для чего вам нужно в дуине "нормальное слово" ? И как вы думаете что вы отсылаете в дуину на самом деле?

Antel
Offline
Зарегистрирован: 10.06.2012

maksim пишет:

А для чего вам нужно в дуине "нормальное слово" ? 

Для того чтобы точно определить к какому, устройству\дадчику\мотору\сервоприводу обращяюсь

Цитата:

И как вы думаете что вы отсылаете в дуину на самом деле?

100% Посылаю "Test"

84, 101, 115, 116 это кодировка ASCII

T, e, s, t это уже нормальная кодировка

Сейчас пытаюсь запихнуть приходящие значени в массив, после это кажды элемент массива декодировать из ASCII в норм кодировку, но из-за того что знаний работы с Arduino слишком мало застрял на пихании посылаемых значений в массив)) Вроде корректно все обьяснил))

maksim
Offline
Зарегистрирован: 12.02.2012

А чем вас не устраивюет коды аски???

И тогда перефразирую - Вы понимаете, что вы отправляете те же коды аски, а не слово?

step962
Offline
Зарегистрирован: 23.05.2011

Antel пишет:

100% Посылаю "Test"

84, 101, 115, 116 это кодировка ASCII

T, e, s, t это уже нормальная кодировка

А почему вы думаете, что послав "Test", вы получаете 84, 101,115,116, а не T, e, s, t?

Может приведете соответствующий кусок скетча?

maksim
Offline
Зарегистрирован: 12.02.2012

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

И вот здесь, здесь и здесь еще почитайте.

Antel
Offline
Зарегистрирован: 10.06.2012

В общем сделал программку на Access, которая передает и принимает сигналы от\к Arduino. Когда я передаю Arduino слово TEST то получаю в ответ 84, 101,115,116. И сама плата обрабатывает сигналы именно в этой последовательности.

maksim
Offline
Зарегистрирован: 12.02.2012

А код?

 

maksim
Offline
Зарегистрирован: 12.02.2012

Только весь, а не только "важную" часть кода

Antel
Offline
Зарегистрирован: 10.06.2012

Все что есть на Arduino 

void setup()
{
  Serial.begin(9600);
}
void loop()
{
    Serial.println(Serial.read());
    delay(1000);
}

 ссылка на архив с MDB файлом через который работаю http://zalil.ru/33422241

maksim
Offline
Зарегистрирован: 12.02.2012

Если вы запустите сериал-монитор, то дуина будет возвращать именно то что вы шлете и каждую секунду игрик с двумя точками (255). Что бы избавиться от чтения пустого буфера нужно делать так:

void setup()
{
  Serial.begin(9600);
}
void loop()
{
  if(Serial.available){
    delay(2);
    Serial.println(Serial.read());
  }
}

А проблема у вас в принимающей программе, которая вместо символа показывает вам его код.

 

step962
Offline
Зарегистрирован: 23.05.2011

 2 Maksim:

Не совсем так - проблема все же в скетче.

2 Antel:

Попробуйте так:

void setup()
{
  Serial.begin(9600);
}
void loop()
{
    Serial.println((char)Serial.read());
    delay(1000);
}

 или так:

void setup()
{
  Serial.begin(9600);
}
void loop()
{
    char c;
    c = Serial.read();
    Serial.println(c);
    delay(1000);
}

 2 all:

Не забываем, что для Serial.read():

"Возвращаемое значение
Следующий доступный байт или -1 если его нет (int)"

maksim
Offline
Зарегистрирован: 12.02.2012

Сейчас не на чем проверить, но как я помню не обязательно отправлять имеено тип char, даже если будет тип byte он все равно вернет в сериал монитор символ, т.к. Serial.print() отправляет те же 8 бит (тот же байт) информации, которые приняла Serial.read().

maksim
Offline
Зарегистрирован: 12.02.2012

Так , что дело не в скейтче 

Antel
Offline
Зарегистрирован: 10.06.2012

Вот это похоже на правду, возвращяет именно те символы которые я передаю, НО каждый символ в отдельной строке, следовательно либо передача идет посимвольно, либо обработка.

Antel
Offline
Зарегистрирован: 10.06.2012

 Вот что показывает мониторинг порта http://zalil.ru/33422489

Я не знаю имеет ли это значение но у меня MEGA 2560

maksim
Offline
Зарегистрирован: 12.02.2012

Antel пишет:

НО каждый символ в отдельной строке

Читайте про Serial.print() и Serial.println()

leshak
Offline
Зарегистрирован: 29.09.2011

 Serila.println замените на Serial.write и будет вам в ответ "test"

Antel
Offline
Зарегистрирован: 10.06.2012

Блин может я как то не так обьясняю чего хочу. Мне нужно чтобы в какой нибудь переменной осталось ПОЛНОЕ слово, в мониторинге порта оно формируется по средством цикла.

maksim
Offline
Зарегистрирован: 12.02.2012

Я вам давал выше ссылки в каких переменных все это можно хранить

step962
Offline
Зарегистрирован: 23.05.2011

maksim пишет:

Сейчас не на чем проверить, но как я помню не обязательно отправлять имеено тип char, даже если будет тип byte он все равно вернет в сериал монитор символ, т.к. Serial.print() отправляет те же 8 бит (тот же байт) информации, которые приняла Serial.read().

Byte - да. будет выведен символ.

Но проблема исходного скетча в том, что в Serial.print() подается значение, возвращаемое функцией Serial.read(). А эта функция возвращает значение типа int. Ну а дальше включается механизм перегрузки функций и имеем, что имеем.

step962
Offline
Зарегистрирован: 23.05.2011

maksim пишет:

Сейчас не на чем проверить, но как я помню не обязательно отправлять имеено тип char, даже если будет тип byte он все равно вернет в сериал монитор символ, т.к. Serial.print() отправляет те же 8 бит (тот же байт) информации, которые приняла Serial.read().

Byte - да. будет выведен символ.

Но проблема исходного скетча в том, что в Serial.print() подается значение, возвращаемое функцией Serial.read(). А эта функция возвращает значение типа int. Ну а дальше включается механизм перегрузки функций и имеем, что имеем.

step962
Offline
Зарегистрирован: 23.05.2011

maksim пишет:

Сейчас не на чем проверить, но как я помню не обязательно отправлять имеено тип char, даже если будет тип byte он все равно вернет в сериал монитор символ, т.к. Serial.print() отправляет те же 8 бит (тот же байт) информации, которые приняла Serial.read().

Byte - да. будет выведен символ.

Но проблема исходного скетча в том, что в Serial.print() подается значение, возвращаемое функцией Serial.read(). А эта функция возвращает значение типа int. Ну а дальше включается механизм перегрузки функций и имеем, что имеем.

maksim
Offline
Зарегистрирован: 12.02.2012

Удобно использовать класс String
 

String slovo;
boolean read_end = 0;

void setup()
{
  Serial.begin(9600);
}
void loop()
{
  if(Serial.available()){
    delay(2);
    slovo += Serial.read();  
    read_end = 1; 
  }
  else if(read_end){
    Serial.println(slovo);
    read_end = 0;
  }
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

Удобно использовать класс String
 

String slovo;
boolean read_end = 0;

void setup()
{
  Serial.begin(9600);
}
void loop()
{
  if(Serial.available()){
    delay(2);
    slovo += Serial.read();  
    read_end = 1; 
  }
  else if(read_end){
    Serial.println(slovo);
    read_end = 0;
  }
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

Сайт мозг парит 

maksim
Offline
Зарегистрирован: 12.02.2012

step962 пишет:

maksim пишет:

Сейчас не на чем проверить, но как я помню не обязательно отправлять имеено тип char, даже если будет тип byte он все равно вернет в сериал монитор символ, т.к. Serial.print() отправляет те же 8 бит (тот же байт) информации, которые приняла Serial.read().

Byte - да. будет выведен символ.

Но проблема исходного скетча в том, что в Serial.print() подается значение, возвращаемое функцией Serial.read(). А эта функция возвращает значение типа int. Ну а дальше включается механизм перегрузки функций и имеем, что имеем.

Там переполнения не может быть. Может  Serial.read() и возвращает int, но при этом она не возвратит больше, чем b11111111 что есть -1 для char и 255 для byte или int

maksim
Offline
Зарегистрирован: 12.02.2012

step962 пишет:

maksim пишет:

Сейчас не на чем проверить, но как я помню не обязательно отправлять имеено тип char, даже если будет тип byte он все равно вернет в сериал монитор символ, т.к. Serial.print() отправляет те же 8 бит (тот же байт) информации, которые приняла Serial.read().

Byte - да. будет выведен символ.

Но проблема исходного скетча в том, что в Serial.print() подается значение, возвращаемое функцией Serial.read(). А эта функция возвращает значение типа int. Ну а дальше включается механизм перегрузки функций и имеем, что имеем.

Там переполнения не может быть. Может  Serial.read() и возвращает int, но при этом она не возвратит больше, чем b11111111  что есть -1 для char и 255 для byte или int

Antel
Offline
Зарегистрирован: 10.06.2012

 

String slovo;
boolean read_end = 0;

void setup()
{
  pinMode(13,OUTPUT);
  pinMode(8,OUTPUT);
  Serial.begin(9600);
}
void loop()
{
  if(Serial.available())
  {
    delay(2);
    slovo += (char)Serial.read();  
    read_end = 1; 
  }
  else if(read_end)
  {
    if(slovo.substring(0,3) == "asd")
    {
        digitalWrite(13,HIGH);
        delay(200);
        digitalWrite(13,LOW);
        delay(200);
    }
    else if (slovo.substring(0,3) == "dsa")
    {
        digitalWrite(8,HIGH);
        delay(200);
        digitalWrite(8,LOW);
        delay(200);
    }
    Serial.println(slovo);
    read_end = 0;
    slovo = "";
  }
}

Большое спасибо! Все прекрасно работает!

step962
Offline
Зарегистрирован: 23.05.2011

maksim пишет:

Там переполнения не может быть. Может  Serial.read() и возвращает int, но при этом она не возвратит больше, чем b11111111 что есть -1 для char и 255 для byte или int

Я говорил не о переполнении, а о перегрузке функций. В данном конкретном случае она проявляется в том, что существуют две (скорее всего их больше) функции с одним и тем же именем:

Serial.print(int) и

Serial.print(char)

Компилятор берет ту или иную функцию в зависимости от того, аргумент какого типа указать в скобках. Скормили функции тип char (byte) - будет сгенерирован вызов второго варианта функции и принимающая программа получит ASCII-код соответствующего символа (например, 84 для "T"). Ну а если в скобках стоит переменная целого типа (или как у топикстартера - функция, возвращающая целое), то в объектном коде будет сгенерирован вызов первого варианта и принимающая программа получит не один симол 'T' (84), а строку "84" (символьное представление соответствующего ASCII-кода) 

Antel
Offline
Зарегистрирован: 10.06.2012

В общем совместными усилиями получили вот такой код обработки посылаемого сообщения через COM порт. 

String slovo, Device, Value;
boolean read_end = 0;

void setup()
{
  Serial.begin(9600);
}
void loop()
{
  if(Serial.available())
  {
    delay(2);
    slovo += (char)Serial.read();  
    read_end = 1; 
  }
  else if(read_end)
  {
    Device = slovo.substring(0,8);
    Value = slovo.substring(8);
    Serial.print(Device);
    Serial.print("-");
    Serial.println(Value);
    read_end = 0;
    slovo = "";
  }
}

А подскажмите пожалуйста как теперь получить из перемиенной Value не String, a int. (если послать SensorID350, то в переменную Value попадает именного - 350)

maksim
Offline
Зарегистрирован: 12.02.2012

Вот есть тема 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

У класса String есть метод toInt. В справках нигде нету, но если почитать в исходниках, то есть :) Возвращает тип Long. Но в строковой переменной ничего больше не должно быть кроме цифр (допускается только знак "-" перед цифрами), функция прекращает работу на первом же "неправильном" символе:

String str;
str="123";
i=str.toInt(); //даст 123
str="-12.3";
i=str.toInt(); //даст -12
str="1e12";
i=str.toInt(); //даст 1, экспоненту не понимает :)
str="A123";
i=str.toInt(); //даст 0

 

maksim
Offline
Зарегистрирован: 12.02.2012

В данном случае человеку прийдется сначала из общей команды (например: SensorID350) вытащить строку только с цифрами, что бы воспользоваться str.toInt();, а это только лишний геморой.

Antel
Offline
Зарегистрирован: 10.06.2012

В переменной Value и так только цифры и вытаскивается это без гемороя совсем 

Value = slovo.substring(8);

Т.е. выдергиваем все символы из переменной slovo после 8 симлова и получаем как раз 350 (если шлем SensorID350)

Antel
Offline
Зарегистрирован: 10.06.2012
String slovo, Value;
boolean read_end = 0;
int i = 0;

void setup()
{
  Serial.begin(9600);
}
void loop()
{
  if(Serial.available())
  {
    delay(2);
    slovo += (char)Serial.read();  
    read_end = 1; 
  }
  else if(read_end)
  {
    Value = slovo.substring(8);
    i = Value.toInt();
    Serial.println(i * 2);
    read_end = 0;
    slovo = "";
  }
}

Все прекрасно работает. Выдает 700 (при посылке SensorID350). Я пытался как то "понасиловать"  toInt, НО писал его как ToInt и код компиляцию не проходил)))

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Сделайте функцию "вытаскивания цифр для случая, если цифры могут быть в разных позициях:

long ToInt(String InStr)
{
  int i=0;
  String OutStr="";
  while (InStr[i]){
    if (isDigit(InStr[i])) OutStr+=InStr[i];
    i++;
  }
  return(OutStr.toInt());
}

 

Antel
Offline
Зарегистрирован: 10.06.2012

 Большое спасибо, но цифр в случайном месте не будет, я это отслеживать хочу на ПК. т.е. к Arduino уже будут поступать правильно  скоректированные данные.