Типы данных Arduino
Я работаю над рабочим листом для начала с arduino. У меня есть предыдущий опыт работы с ардуино, но проблема является новой для моей области знаний. Любая помощь будет хорошо оценена (нужна помощь, пожалуйста, uwu)
Постановка проблемы:
Я пробовал разные методы, чтобы получить эти значения, но все напрасно.
Методы, которые я пробовал до сих пор:
- используя ограничения.h, плавает.h и встроенные переменные этой библиотеки -- Проблема: я получаю неправильные минимальные и максимальные значения для float и double: Код:
#include <stdio.h>
#include <limits.h>
#include <float.h>
#include <math.h>
char fltmax[250];
char fltmin[250];
char dblmax[250];
char dblmin[250];
void sint() {
Serial.print("Range of signed int: ");
Serial.print(INT_MIN);
Serial.print(" to ");
Serial.print(INT_MAX);
Serial.print(", which has a storage size of ");
Serial.print(sizeof(int));
Serial.println(" bytes");
}
void usint() {
Serial.print("Range of unsigned int: 0 to ");
Serial.print(UINT_MAX);
Serial.print(", which has a storage size of ");
Serial.print(sizeof(unsigned int));
Serial.println(" bytes");
}
void schar() {
Serial.print("Range of signed char: ");
Serial.print(SCHAR_MIN);
Serial.print(" to ");
Serial.print(SCHAR_MAX);
Serial.print(", which has a storage size of ");
Serial.print(sizeof(signed char));
Serial.println(" bytes");
}
void uschar() {
Serial.print("Range of unsigned char: 0 to ");
Serial.print(UCHAR_MAX);
Serial.print(", which has a storage size of ");
Serial.print(sizeof(unsigned char));
Serial.println(" bytes");
}
void slong() {
Serial.print("Range of signed long: ");
Serial.print(LONG_MIN);
Serial.print(" to ");
Serial.print(LONG_MAX);
Serial.print(", which has a storage size of ");
Serial.print(sizeof(signed long));
Serial.println(" bytes");
}
void uslong() {
Serial.print("Range of unsigned long: 0 to ");
Serial.print(ULONG_MAX);
Serial.print(", which has a storage size of ");
Serial.print(sizeof(unsigned long));
Serial.println(" bytes");
}
void sshort() {
Serial.print("Range of signed short: ");
Serial.print(SHRT_MIN);
Serial.print(" to ");
Serial.print(SHRT_MAX);
Serial.print(", which has a storage size of ");
Serial.print(sizeof(signed short));
Serial.println(" bytes");
}
void usshort() {
Serial.print("Range of unsigned long: 0 to ");
Serial.print(USHRT_MAX);
Serial.print(", which has a storage size of ");
Serial.print(sizeof(unsigned short));
Serial.println(" bytes");
}
void flt() {
Serial.print("Range of float: ");
dtostrf(FLT_MIN, -1, 50, fltmin);
Serial.print(fltmin);
Serial.print(" to ");
sprintf(fltmax,"%e", FLT_MAX);
puts(fltmax);
Serial.print(", which has a storage size of ");
Serial.print(sizeof(float));
Serial.println(" bytes");
}
void dbl() {
Serial.print("Range of double: ");
dtostrf(DBL_MIN, -1, 50, dblmin);
Serial.print(dblmin);
Serial.print(" to ");
dtostrf(DBL_MAX, -1, 0, dblmax);
Serial.print(dblmax);
Serial.print(", which has a storage size of ");
Serial.print(sizeof(double));
Serial.println(" bytes");
}
void setup() {
Serial.begin(115200);
sint();
usint();
schar();
uschar();
slong();
uslong();
sshort();
usshort();
flt();
dbl();
}
void loop() {
}
- Помимо использования dtostrf(), я также нашел лучшие альтернативы на exchange здесь, такие как: Печать без знака long long в ESP8266 и https://www.tutorialspoint.com/c_standard_library/c_function_sprintf.htm
Я попытался объединить оба, где тестовый код, который я использовал до фактической реализации:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <float.h>
#include <limits.h>
void setup () {
char str[30];
Serial.begin(115200);
snprintf(str, 30, "Значение float max = %e", FLT_MAX);
/*puts(str);*/
Serial.print(str);
return(0);
}
void loop(){
}
Но puts(str)
не печатается на последовательном мониторе. Затем щелкнуло, что я должен использовать Serial.(код), чтобы он был напечатан в serial monitor, но в итоге код Serial.puts(str)
не найден. Затем я попробовал просто Serial.print(str)
, но он просто выводит значение float max = ?
(Изначально, до того, как я написал эту проблему здесь, она выводила только Va, и я понятия не имею, как она изменилась, но все равно это неправильно). Что мне теперь делать? кроме того, почему я не могу использовать puts для печати на последовательном мониторе?
Плата, которую я использую для этого, - Arduino UNO (ATmega328P)
@UnfreeHeX, 👍2
1 ответ
Лучший ответ:
Здесь есть две проблемы.
Одна заключается в том, что в Arduino Core использует последовательный
для обработки последовательного ввода/вывода, а
чем традиционные библиотеки libc интерфейс (функции printf()
, помещает()
и co.). В
АВР-библиотеки libc обеспечивает традиционные функции stdio, но они будут
не получится, пока вы не скажете, где стандартный вывод
, который является немного сложным.
Вывод состоит в том, чтобы просто использовать методы последовательного
доступа для доступа к
последовательному порту.
Тогда возникает вопрос: почему он напечатал “Значение float max = ?”.
Причина в том, что avr-libc по умолчанию не поддерживает
форматирование чисел с плавающей запятой с помощью sprintf()
. Эта поддержка
довольно дорога во флэш-памяти, и она отсутствует, если вы не свяжетесь с
определенной версией avr-libc. Простые обходные пути заключаются в следующем:
- Используйте
Serial.print()
как для форматирования, так и для печати чисел с плавающей запятой, что неудобно для очень маленьких или очень больших чисел. - Используйте
dtostre()
илиdtostrf()
для их форматирования.
В вашем случае dtostre()
лучше подходит:
void setup() {
char val[40];
Serial.begin(9600);
Serial.print("Range of float: ");
dtostre(FLT_MIN, val, 5, 0);
Serial.print(val);
Serial.print(" to ");
dtostre(FLT_MAX, val, 5, 0);
Serial.print(val);
Serial.println();
}
void loop(){}
отпечатки пальцев:
Range of float: 1.17549e-38 to 3.40282e+38
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
- Не удается снова загрузиться после смены платы
- Генерация стабильной частоты
- В чем разница между ATMEGA32 и ATMEGA328?
- Arduino UNO для получения подписи чипа ATmega328P-PU
- Последовательная связь ESP8266 с ATMega328P
- Каково время нарастания выходного вывода atmega328, изменяющего свое состояние?
- Нужна помощь в программировании ардуино на ассемблере
Ах, я вижу, я прочитаю документацию dtostre (), я думаю, она похожа на dtostrf (), но вывод скорее %e вместо %f, но я прочитаю на всякий случай. Кроме того, я только что узнал, что DBL_MIN и FLT_MIN не обеспечивают абсолютный минимум типа данных, а скорее положительное минимальное значение :) Я просто добавлю символ тире вручную и использую DBL/FLT_MAX для минимального значения. Хотя это не этично/кодекс stackexchange, чтобы сказать спасибо в комментариях, я все равно буду благодарен вам, я застрял на этом вопросе на прошлой неделе :'(, @UnfreeHeX