Вопрос: Возможно ли сделать вывод данных Serial port не целочисленных, а с плавающей точкой до сотых.

xruss
Offline
Зарегистрирован: 20.03.2016

Всем привет! Я новичок в программировании Arduino / Просьба о помощи.

Я подключил датчик - резистор давления (через делитель напряжения) и добился его корректной работы. Но стандартный листинг пример AnalogReadSerial предполагает вывод значений в integer.

...
void loop() {
  // read the input on analog pin 0:
  double sensorValue = analogRead(A0); /* double не помог((*/
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
...

Можно ли сделать так, чтобы данные получались (может быть через map(...)) в виде целого числа и его дробной части. Например 5.25, 5. 99, 6.34 ... и.т.д?

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

можно - делай.

xruss
Offline
Зарегистрирован: 20.03.2016

а как? ведь, как я понимаю, данные с датчика приходят как целое(( и как написать округление до сотых, чтобы не было тысячных или десятых, а именно сотые?

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Как вариант, конвертировать в строку и добавить точку...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

xruss, в каких единицах Вы получаете информацию с аналогового датчика? В каком диапазоне?

И второй вопрос: в каких единицач измеряется Ваша физическая величина? И, опять же, в каком дивпазоне?

Перевод из первого во второе осуществляется (в простейшем случае линейной зависимости) домножением на размерный коэффициент. Т.е. масштабированрем. В общем случае коэффициент - вещественное число. Соответственно, и результат масштабирования - вещественное число. Поэтому на вопрос "что делать с целыми?" ответ очевиден.

Округление до сотых можно сделать, например, так: ((int)(value*100))/100.0

axill
Offline
Зарегистрирован: 05.09.2011

xruss пишет:

Всем привет! Я новичок в программировании Arduino / Просьба о помощи.

Я подключил датчик - резистор давления (через делитель напряжения) и добился его корректной работы. Но стандартный листинг пример AnalogReadSerial предполагает вывод значений в integer.

...
void loop() {
  // read the input on analog pin 0:
  double sensorValue = analogRead(A0); /* double не помог((*/
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
...

Можно ли сделать так, чтобы данные получались (может быть через map(...)) в виде целого числа и его дробной части. Например 5.25, 5. 99, 6.34 ... и.т.д?

сначала расскажите нам откуда должна взяться дробная часть

analogRead возвращает значение преобразование АЦП, это целое число от 0 до 1023

оно не может быть дробным

дробь может взяться если на самом деле ваша физическая величина это производная от значения АЦП, и у вас есть формула с делением и умножением

вот если так, то дробная часть у нас появляется

но прежде чем выводить сотые доли еще надо прикинуть, а дает ли в вашем случае 10ти битный АЦП точность достаточную для учета сотых долей

a5021
Offline
Зарегистрирован: 07.07.2013

float a = 5.25;
int b = a;  // в переменной b будец целая часть числа
int c = a * 100 % 100; // в переменной с будут два знака после запятой (25)
serial.print("a = ");
serial.print(b);
serial.print(".");
serial.print(c);

 

axill
Offline
Зарегистрирован: 05.09.2011

a5021 пишет:


float a = 5.25;
int b = a;  // в переменной b будец целая часть числа
int c = a * 100 % 100; // в переменной с будут два знака после запятой (25)
serial.print("a = ");
serial.print(b);
serial.print(".");
serial.print(c);

 

этот способ отличный когда плавающая точка вообще не используется (что есть правильно чаще всего). Например температуру с датчика можно считать в виде целого, но умноженного на 10 или 100. Тоесть например 25.7 градуса будут представлены как 257. Вот тогда ваш способ самое то.

для float мне больше нравится старый Сишный способ:

float x = 5.25;
char str[16];

sprintf_P(str, PSTR("%.2f"), x);
Serial.println(str);

 

xruss
Offline
Зарегистрирован: 20.03.2016

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

xruss
Offline
Зарегистрирован: 20.03.2016

У меня получилось так:  float result = sensorValue / 100;

/*
  AnalogReadSerial
  Reads an analog input on pin 0, prints the result to the serial monitor.
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
 
 This example code is in the public domain.
 */

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  float sensorValue = analogRead(A0);
  sensorValue = map(sensorValue, 0, 527, 0, 1000); 
  // print out the value you read:
  float result = sensorValue / 100;
  Serial.println(result);
  delay(1);        // delay in between reads for stability
}

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

a5021
Offline
Зарегистрирован: 07.07.2013

Я бы даже хуже сказал. Использовать здесь тип float нет никакой нужды. Весь код вырождается до

Serial.println(map(analogRead(A0), 0, xxx, 0, yyy));

 

Logik
Offline
Зарегистрирован: 05.08.2014

xruss пишет:

Можно ли сделать так, чтобы данные получались (может быть через map(...)) в виде целого числа и его дробной части. Например 5.25, 5. 99, 6.34 ... и.т.д?

И это же надо было шоб именно сегодня я выдерал с одного проекта опрос температуры из одного проекта в другой! И походу подумал что десятые не помешают))

Было. 

 Serial.print("T=");Serial.println(Termo1Val>>4); 

А для самогонного аппарата ;) стало с десятыми.

      char s[10];
      ltoa(Termo1Val*10>>4,s,10);
      byte l=strlen(s);
      s[l]=s[l-1];s[l-1]='.';s[l+1]=0;
     Serial.print("T=");Serial.println(s); 

Очень лоботомическое решение. Недостаток в том, что  в strlen(s); скрывается цикл поиска конца, это медленоватенько (хотя по сравнению с map то очень быстро). Но работает, и в принципе подсказывает интересный подход к задаче формирования строк для вывода. Надо всегда иметь указатель на конец строки. Тогда имея набор функций принимающих указатель на первый символ  и возвращающий указатель на последний можна чудеса творить, причем быстро, без копирований и даже почти без буферов, по типу потокового формирования.

ПС. Сотые из десятых сами сделаете легко, если идею поймете.

releyshic
Offline
Зарегистрирован: 20.11.2015

Ребята Дружно курим Сериал !!!

http://arduino.ru/Reference/Serial/Print