#c #arrays #pointers #arduino #bluetooth-lowenergy
#c #массивы #указатели #arduino #bluetooth — низкое энергопотребление
Вопрос:
ОБНОВЛЕНИЕ 16.4. 11:02
Привет, Том! Я попробовал ваше изменение кода, которое вы предоставили, и оно выводит интересные значения. Я немного поэкспериментировал с изменением размера цикла for и числа, которое умножается i
внутри txString[]
, и это то, что я наблюдал:
**CONDITIONS:**
char tamp[20];
char txString[32];
for (unsigned int i=0; i<3; i ){
char tamp[20];
dtostrf(coordArray[i], 7, 2, tamp); //convert one of your coordinates
for (unsigned int j=0;j<5;j ) {txString[5*i j] = tamp[j];} //concatenate it inside txString
}
**OUTPUT:**
10:32:06.052 -> Yaw:
10:32:06.052 -> 311.44
10:32:06.052 -> , Pitch:
10:32:06.052 -> -0.03
10:32:06.052 -> , Roll:
10:32:06.052 -> 179.99
10:32:06.052 -> *****txString****
10:32:06.052 -> 311. -0. 179.
10:32:06.052 -> ************
----------------------------
dtostrf(coordArray[i], 7, 2, tamp);
for (unsigned int j=0;j<6;j ) {txString[6*i j] = tamp[j];
OUTPUT:
10:43:55.371 -> Yaw:
10:43:55.371 -> 310.51
10:43:55.371 -> , Pitch:
10:43:55.371 -> 0.38
10:43:55.371 -> , Roll:
10:43:55.371 -> -179.64
10:43:55.371 -> *****txString****
10:43:55.371 -> 310.5 0.3-179.6ART HELMET //Here it outputs name of the BLE device I gave it in upper part of code I didnt mention here BLEDevice::init("SMART HELMET");
10:43:55.371 -> ************
-----------------------------
dtostrf(coordArray[i], 6, 2, tamp); //here I changed the string width and it outputted only Yaw data
for (unsigned int j=0;j<7;j ) {txString[7*i j] = tamp[j];
OUTPUT:
10:49:58.993 -> Yaw:
10:49:59.027 -> 311.95
10:49:59.027 -> , Pitch:
10:49:59.027 -> 1.91
10:49:59.027 -> , Roll:
10:49:59.027 -> -178.10
10:49:59.027 -> *****txString****
10:49:59.027 -> 311.95
10:49:59.027 -> ************
--------------------------------
dtostrf(coordArray[i], 16, 2, tamp);
10:58:43.547 -> Yaw:
10:58:43.547 -> 314.31
10:58:43.547 -> , Pitch:
10:58:43.547 -> -0.08
10:58:43.547 -> , Roll:
10:58:43.547 -> 179.93
10:58:43.547 -> *****txString****
10:58:43.547 -> HELMET
10:58:43.547 -> ************
Ответ №1:
возврат локального массива (объявленного внутри функции) вызовет у вас проблемы, потому что он выходит за рамки, как только функция завершается. Чтобы вернуть локальный массив, он должен быть динамически распределен, чтобы он мог пережить функцию
float* result (float x, float y, float z)
{
float* coordArray=malloc(3*sizeof(float));
coordArray[0] = x;
coordArray[1] = y;
coordArray[2] = z;
return coordArray;
}
Комментарии:
1. Спасибо за ваш быстрый ответ! Могу я спросить вас, как это будет выглядеть, когда я захочу вызвать функцию? Извините, я не упомянул, какие типы данных являются моими переменными. значение float txValue = 0; двойной крен, тангаж, рыскание;
2. в вашем основном у вас будет массив с плавающей запятой, указывающий на возвращаемый массив из вашей функции, например: float * myarray =result (the_valueof_x, valueof_y, valueof_z)
Ответ №2:
Как было сказано в другом ответе, как coordArray
было выделено в вашей функции, оно будет выходить из области видимости всякий раз, когда ваша программа выходит из этой функции, поэтому значения, указанные вашим указателем, больше не будут правильными.
Если вам нужно вызвать эту функцию несколько раз и вы хотите избежать утечек памяти из malloc
вы можете объявить float coordArray[3]
как глобальную переменную, обновите ее в своей функции result
, которая затем будет void
функцией.
Что-то вроде
//global declaration
float coordArray[3]
/*
Setup and other code
*/
void result (float x, float y, float z)
{
coordArray[0] = x;
coordArray[1] = y;
coordArray[2] = z;
}
Таким образом, вы избежите своей ошибки.
Примечание: глобальные переменные обычно считаются нечистыми в C / C , однако для встроенных систем с низкими требованиями к памяти и где утечка памяти будет иметь серьезные последствия очень быстро, обычно рекомендуется не использовать динамическое распределение.
Надеюсь, это поможет!
** РЕДАКТИРОВАТЬ **
Как ваш результат void
, вы не должны присваивать его возвращаемое значение чему-либо, оно ничего не возвращает. Просто вызов result(yaw, pitch, roll);
обновит coordArray
.
Чтобы преобразовать этот массив в строку, вы должны делать это последовательно, как dtostrf
ожидается double
, и у вас их несколько:
for (unsigned int i=0; i<3;i ){
char tamp[4];
dtostrf(coordArray[i], 1, 3, tamp); //convert one of your coordinates
for (unsigned int j=0;j<3;j ) txStringYaw[4*i j] = tamp[j]; //concatenate it inside txStringYaw
}
Я не проверял это, хотя может быть небольшая синтаксическая ошибка.
Примечание: я не знаю, хорошо ли я понял вашу проблему, но в моем коде txStringYaw
будут содержаться ваши три координаты. Вы можете легко адаптировать его, чтобы иметь только рыскание, если хотите!
Комментарии:
1. Спасибо, Том, за твои советы, они были полезными и функциональными до сих пор. Но теперь я получаю ошибку такого рода: не удается преобразовать ‘double *’ в ‘double’ для аргумента ‘1’ в ‘char * dtostrf (double, signed char, unsigned char, char *)’
2. Я отредактировал свой ответ, дайте мне знать, решил ли он вашу проблему!
3. Я допустил ошибку в своем предыдущем редактировании, правильный синтаксис должен быть
char tamp[4];
4. Спасибо, это работает! Данные отправляются, и выходной терминал что-то показывает, но выходные данные (формат) немного отклонены… Возможно, это связано с тем, что данные отправляются без какого-либо разделителя и склеиваются вместе. Есть ли какой-нибудь способ их разделить?
5. Пожалуйста, опубликуйте пример вашего вывода, чтобы мы могли точно понять, что происходит. Как дикое предположение, я думаю, вы хотите добавить пробел между данными, возможно, изменение на
for (unsigned int j=0;j<4;j ) txStringYaw[i j] = tamp[j];
сделает это. Возможно, вам потребуется настроить размерtamp
, однако…