Помогите разобраться в коде (указатели, копирование данных и т.п.)
- Войдите на сайт для отправки комментариев
Втр, 08/05/2012 - 09:24
Есть два устройства на ардуино, общаются по беспроводной технологии.
Для "общения" объявлены структуры:
typedef struct _AS_ANSWER { byte Status; //Статус float Value; //Значение byte Comment[CommentLen]; //Описание }AS_Answer; typedef struct _AS_SENSORSTATUS { byte Status; //Статус float Value; //Значение byte Comment[CommentLen]; //Описание }AS_SensorStatus;
СommentLen - определена (20, для определенности).
На стороне передатчика есть вот такой массив:
AS_SensorStatus MySensors[NumSensors] = { 0,0,"DHT_temp(C)", 0,0,"DHT_hidm(%)", 0,0,"Batt_pow(V)", 0,0,"Moisture(?)"};
И при передаче используется вот такой код:
MyAnswer.Status = MySensors[MyCommand.Parametr].Status; MyAnswer.Value = MySensors[MyCommand.Parametr].Value; memcpy(&MyAnswer.Comment,&MySensors[MyCommand.Parametr].Comment, CommentLen);
Теперь перейдем к приемнику... Когда данные приходят их просто пуляем на ком-порт (или выводим на дисплей, суть не в этом):
Serial.print(MyAnswer.Value); Serial.print((char *)MyAnswer.Comment);
А теперь собственно, сама проблема: комментарий не выводится.
Числовые данные передаются без проблем (статусы и значения), а вот строки - еще ни разу не видел. К сожалению, сам с этим пока разобратся не могу, поэтому прошу "помощь зала".
Похоже дело не в выводе коментария, а в том как данные отправляются/принимаются.
Вот такой код
У меня нормально выводит "my test comment".
Как видите, при memcpy (строка 23) я не использовал &, но и с ним - работает также. Видимо компилятор сам догадывается о его необходимости.
Кстати, если поле коммент, объявить не как "byte Comment[CommentLen]", а "char byte Comment[CommentLen]", то можно будет выводить просто "Serial.println(ans.Comment);" без необхоимости засорять код "char *".
Если это текст, символы, то зачем его объявлять byte?
Вообщем нужно смотреть как "отправляет/принимает". Особено "отправляет".
Направления "копания":
СommentLen - определена (20, для определенности).
Набрать тут в имени переменной первую букву русской эС, вместо латинской Cи - это был тонкий садизм. Взял copy-past-том и чуть мозги не вывихнул пытась понять почему же "константа не определена".
Похоже дело не в выводе коментария, а в том как данные отправляются/принимаются.
Так и оказалось - проблема была в том, что отправлялась посылка меньшей длинны, поэтому комментарию банально н хватало "места" при отправке.
Кстати, если поле коммент, объявить не как "byte Comment[CommentLen]", а "char byte Comment[CommentLen]", то можно будет выводить просто "Serial.println(ans.Comment);" без необхоимости засорять код "char *".
Если это текст, символы, то зачем его объявлять byte?
Это связано с тем, что передатчик отправляет именно байты:
Вообщем нужно смотреть как "отправляет/принимает". Особено "отправляет".
Направления "копания":
СommentLen - определена (20, для определенности).
Набрать тут в имени переменной первую букву русской эС, вместо латинской Cи - это был тонкий садизм. Взял copy-past-том и чуть мозги не вывихнул пытась понять почему же "константа не определена".
Это я не специально, сорри :)
Спасибо за помощь! Направления мысли были очень правильные!
Кстати, если поле коммент, объявить не как "byte Comment[CommentLen]", а "char byte Comment[CommentLen]", то можно будет выводить просто "Serial.println(ans.Comment);" без необхоимости засорять код "char *".
Если это текст, символы, то зачем его объявлять byte?
Это связано с тем, что передатчик отправляет именно байты:
Это не важно. Принимающий скетч все равно ничего не знает об типах данных в отправляющем.
В конечном итоге мы всегда передаем и храним в памяти только байты. Когда мы объявляем какой-то тип, то фактически просто "даем компилятору подсказку" - какой смысл имеют эти байты, что мы в них собираемся хранить. и не более того.
Когда вы в Serial.println передаете массив byte ans.Comment[], и впереди дописываете (char *), вы, фактически говорите: "вот массив. это массив символов. я раньше, зачем-то, сказал что там будут числовые значения, но в данном случае не обращай внимания на то что я говорил раньше. их нужно обрабатывать как символы". Поэтому можно сразу сказать "тут будут символы".
Представте что у вас есть картонные коробки (ячейки памяти), одинакового размера (в них можно положить восемь предметов). Объявления типа - это наклейка на коробочку. Объяснение самому себе и компилятору вы в ней собираетесь хранить "подарок жене" или "мусор на выброс", или "ценная фигня". Наклейки вы можете переклеивать (приведение типа). Наклейка влияет только на то как другие люди (компилятор) будут обращатся с этой коробкой, но не влияет на ее содержимое.
Ваш отправляющий скетч, просто "отправляет коробочки". Без наклеек. Вы принимаете их и лепите на них наклейки, типа "первые четыре коробоки - хранят части длинного числа, а следующие 20-ть коробок - это коды символов".