Чтение 64 битной переменной с Serial

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Пробую написать програмку для чтения 64 битной переменной с последовательного порта и с дальнейшим ее делением этой переменной на два 32 битных пакета.Рыся в гугле ,но решений и подсказок не нашел.

Задача :есть переменная вида 397F5550822DFFE9 -ее буду вбивать в терминале,arduino слушает ком порт и при приходе такой переменной разбивает ее в 2 переменные   по 32 бита типа long -Code1,Code2

Подскажите где можно ознакомиться с решением моей задачки

mixail844
Offline
Зарегистрирован: 30.04.2012

1.принять просто как текстовую строку и сохранить в переменную типа string

2.потом 8 нижних байтов копируете в одну переменную типа string и 8 верхних байтов копируете во вторую переменную типа string

3.далее  : содержание переменных типа string из пункта 2, переводите в формат типа long с именами Code1 и Code2 соответсвенно(тут прийдеться писать отдельную функцию,либо искать уже готовые в документации Wiring)

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Да была идея что строковую переменную можно использовать.Вот бы наглядно на wiringe реализацию посомтреть

 

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Нарыл вот такую функцию,но как применить пока не понимаю,слабоват в программинге


tatic long SCode1 = 0;    // first part
static long SCode2 = 0;    // last part 
static long ch = 0;
String code = "";


 
void setup() {
    Serial.begin(9600); // устанавливаем последовательное соединение
}
void s_dump(){

 int i;
    unsigned long tempCode = 0;
    for(i = 0; i < 32; i++){
      ch = (SCode2 >> i) & 1;
      tempCode |= ch << (32 - i - 1);
    }
    SCode2 = tempCode;
    tempCode = 0;
    for(i = 0; i < 32; i++){
      ch = (SCode1 >> i) & 1;
      tempCode |= ch << (32 - i - 1);
    }
    SCode1 = tempCode;
    tempCode = 0;
  }

 
void loop() {
    if (Serial.available() > 0) {  //если есть доступные данные
        // считываем байт
      s_dump= Serial.read();
 
        
    }
}

Вот так попробовал применив найденную функцию-вылезает ошибка при присваивании данных  s_dump =Serial.read()

mixail844
Offline
Зарегистрирован: 30.04.2012

во первых есть разница между String и string,

String - это целый класс(понятие из обьектно ориентировочного программирования)

string  -это тип переменной.

разница между классом и типом -  мега огромная ,самая  явная в том что при использовании класса используеться значительно большее количество памяти.В мелких функциях типа "скопировать строчку","найти тот или иноой символ в строчке" использование класса это "из пушки по воробьям"

простой способ считывания и разделения по 8 байт : 



char buffer[16]=null;
char temp1[8]=null;
char temp2[8]=null;
long code1;
long code2;

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

void loop()
{
while(serial.avialable())
buffer  = strcat(buffer,serial.read());//ваша строка из serial сейчас в buffer'e
for(int i = 0;i<16;i++) //
{
if(i<8) // " разбиение" полученной строки на 2 перменные.
  temp1[i] = buffer[i];
else
   temp2[i] = buffer[i];
}
code1 = strtol(temp1,NULL,16);//перевод из временной строки в long
code2 = strtol(temp2,NULL,16); // перевод из временной строки в long
}

 

maksim
Offline
Зарегистрирован: 12.02.2012
uint32_t SCode1 = 0;
uint32_t SCode2 = 0;

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

void loop() {
  if(Serial.available()) 
  {
    byte *temp = (byte*)&SCode1;
    for(byte i = 0; i < 4; i++)
    {
      temp[i] = Serial.read();
      delay(2);
    }
    temp = (byte*)&SCode2;
    for(byte i = 0; i < 4; i++)
    {
      temp[i] = Serial.read();
      delay(2);
    }
    Serial.println(SCode1);
    Serial.println(SCode2);
  }
}

или

uint64_t Code = 0;

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

void loop() {
  if(Serial.available()) 
  {
    byte *temp = (byte*)&Code;
    for(byte i = 0; i < 8; i++)
    {
      temp[i] = Serial.read();
      delay(2);
    }
  }
}

Во втором только случае не получится вывести в сериал, так как нет такой перегрузки метода print.

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

maksim пишет:

Во втором только случае не получится вывести в сериал, так как нет такой перегрузки метода print.

Благодарю за скорые ответы!!

Нет потом я просто на пин порта буду выводить эти 64 бита кодируя 1 и 0 по типу манчестера -но это в проекте-пока надо разобраться с вводом в ком порт.Опять же, я так понимаю,что наверно можно не разбивая  число на 2 пакета можно им оперировать?

 

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

Можно.

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013
void loop() {

  if(Serial.available())

  {

    byte *temp = (byte*)&Code;

    for(byte i = 0; i < 8; i++)

    {

      temp[i] = Serial.read();

      delay(2);

Получается что данные теперь находятся в массиве temp[i] и уже надо с этим массивом работать?

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

нет, данные находятся в 64-битной переменной Code.

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Спасибо maksim!Век живи век учись.Последовательность кода не так понял.

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Вот попробовал код -передается не то ,что принимается помоему.

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Забыл добавить вывод вот так переделал 

}

    Serial.println(SCode1, HEX);

    Serial.println(SCode2, HEX);

  }

 

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

Потому что в сериал-монитор вы передаете коды аски, а не 64 бита (8 байт). Вы для начала определитесь в каком выиде данные приходят по серал.

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

maksim пишет:

Потому что в сериал-монитор вы передаете коды аски, а не 64 бита (8 байт). Вы для начала определитесь в каком выиде данные приходят по серал.

Ну как в первом сообщении написал,так и надо,просто хотел ее и по UART проконтролировать

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

Изучите типы данных в разделе Программирование.

Вот так выглядит 64-битная переменная:

uint64_t Code = 0x397F5550822DFFE9LL;

а вот так то что вы отправляете в монитор:

char* Code = "397F5550822DFFE9";  //  без признака конца строки - 0

разницу видите?

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Да видимо я не правильный подход выбрал к решению задачи,то есть можно просто использовать тип char для ввода кода в терминал?

mixail844
Offline
Зарегистрирован: 30.04.2012

я так и не понял как данные оказались в переменной Code.присвоение же постоянно идет в temp[i] или в *temp

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

Вот простой пример кода:

byte a = 0;
byte &b = a;

void setup() 
{
  Serial.begin(9600);
  b = 23;
  a = 102;
  Serial.println(b);
}

void loop() {}

Как думаете что покажет сериал монитор? 23 ? Проверьте.

Почитайте ссылки и указатели.

mixail844
Offline
Зарегистрирован: 30.04.2012

С указателями знаком,уже два года на информатике,просто давненько не пользовался

Просто с первого раза строчку 

byte *temp = (byte*)&Code;

Неправильно понял,я с чего то решил что там идет побитовое И,а после вашего примера стало понятно,спасибо