Возврат значения в функции

br0lviv
Offline
Зарегистрирован: 11.06.2018

Всем привет. Прошу совет, достигну ли я возврат значения с функции вот таким методом. Использую под датчик лм35.

[code]void loop()
{
int t2 = check_temp2(2);
}
byte check_temp2(byte temp_pin2)
{
int raw = 0;
float temp = 0;
raw = analogRead(temp_pin2);
temp = ( raw/1023.0 )*5.0*1000/10;
Serial.println(temp);
delay(1000);
return temp;
}[/code]

renoshnik
Offline
Зарегистрирован: 11.04.2013

Всегда озадачивали подобные вопросы... неужели трудно ПОПРОБОВАТЬ !?!? самостоятельно...

br0lviv
Offline
Зарегистрирован: 11.06.2018

Путает byte , можно заменить его на int?
Дело в том, что я просто спросил, не нужно агрится. Пройди мимо...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

br0lviv пишет:
Путает byte , можно заменить его на int? Дело в том, что я просто спросил, не нужно агрится. Пройди мимо...

Да что проходить мимо. У вас в скече больше ошибок чем самого скетча.

/**/
float check_temp2(byte pin) {
  float temp =  (float)analogRead(pin) * 500 / 1023.0  ;
  Serial.println(temp);
  return temp;
}
//-----------------------------------
void setup() {
  Serial.begin(9600);
}
void loop() {
  int t2 = check_temp2(2);
  delay(1000);
}
/**/

Да и код криво выложен на форум. Жрите форумчане да не обляпайтесь.

5N62V
Offline
Зарегистрирован: 25.02.2016

Пух, объясните плз. Вот Вы делаете явое приведение:

  float temp =  (float)analogRead(pin) * 500 / 1023.0  ;

Это Вы просто перестраховываетесь или это какое-то правило, и так нужно делать?

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

5N62V пишет:

Пух, объясните плз. Вот Вы делаете явое приведение:

  float temp =  (float)analogRead(pin) * 500 / 1023.0  ;

Это Вы просто перестраховываетесь или это какое-то правило, и так нужно делать?

Хотя делаю не я, объясню:

если не сделать приведение, может наступить переполнение.

Правда, если приводить к longint, будет выполняться чуточку быстрее. Но не намного.

5N62V
Offline
Зарегистрирован: 25.02.2016

ага, то есть умножая int на int нужно следить чтобы не выскочить за пределы. 

А как правильнее , так как написано, или так:

float temp =  analogRead(pin) * 500. / 1023  ;

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

5N62V, функция возвращает int. А это значит будет считать все в int, отбрасывая всю дробную часть. Вот (float) я заставил считать после равно в float .

int analogRead(uint8_t pin)
{
	uint8_t low, high;

#if defined(analogPinToChannel)
#if defined(__AVR_ATmega32U4__)
	if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#endif
	pin = analogPinToChannel(pin);
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
	if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega32U4__)
	if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
	if (pin >= 24) pin -= 24; // allow for channel or pin numbers
#else
	if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif

#if defined(ADCSRB) && defined(MUX5)
	// the MUX5 bit of ADCSRB selects whether we're reading from channels
	// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
	ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#endif
  
	// set the analog reference (high two bits of ADMUX) and select the
	// channel (low 4 bits).  this also sets ADLAR (left-adjust result)
	// to 0 (the default).
#if defined(ADMUX)
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
	ADMUX = (analog_reference << 4) | (pin & 0x07);
#else
	ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif
#endif

	// without a delay, we seem to read from the wrong channel
	//delay(1);

#if defined(ADCSRA) && defined(ADCL)
	// start the conversion
	sbi(ADCSRA, ADSC);

	// ADSC is cleared when the conversion finishes
	while (bit_is_set(ADCSRA, ADSC));

	// we have to read ADCL first; doing so locks both ADCL
	// and ADCH until ADCH is read.  reading ADCL second would
	// cause the results of each conversion to be discarded,
	// as ADCL and ADCH would be locked when it completed.
	low  = ADCL;
	high = ADCH;
#else
	// we dont have an ADC, return 0
	low  = 0;
	high = 0;
#endif

	// combine the two bytes
	return (high << 8) | low;
}

 

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

5N62V пишет:

ага, то есть умножая int на int нужно следить чтобы не выскочить за пределы. 

А как правильнее , так как написано, или так:

float temp =  analogRead(pin) * 500. / 1023  ;

И в том, и в другом случае результата analogRead будет перед умножением преобразован к float. Так что по сути - одинаково.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Программа

/**/

//-----------------------------------
void setup() {
  Serial.begin(9600);
  float tmp1 = 10 / 4;
  float tmp2 = (float)10 / 4;
  Serial.println(tmp1);
  Serial.println(tmp2);
}
void loop() {

}
/**/

Результат 

2.00
2.50

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

br0lviv пишет:
Путает byte , можно заменить его на int?

Можно. Особенно, учитывая то, что реально Вы возвращаете float - можете менять, хуже не будет.

5N62V
Offline
Зарегистрирован: 25.02.2016

qwone пишет:

Программа


Результат 


Наверное, это не совсем корректная иллюстрация. С делением int-ов  все понятно. Вы же, явно привели один из множителей числителя, хотя в знаменателе стояло / 1023.0 , т.е. результат все равно неявно привелся бы к float.  Объяснение Андриано звучит исчерпывающе.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

5N62V, я не говорю что правильно или неправильно говорит andriano . Я объсняю почему я поставил (float). 

/**/
//-----------------------------------
int fun() {
  return 10;
}
void setup() {
  Serial.begin(9600);
  float tmp1 = fun()/4;
  float tmp2 = (float)fun()/4;
  Serial.println(tmp1);
  Serial.println(tmp2);
}
void loop() {

}
/**/

результат 

2.00
2.50

Хотя так 

/**/
//-----------------------------------
int fun() {
  return 10;
}
void setup() {
  Serial.begin(9600);
  float tmp1 = fun()/4.0;
  float tmp2 = (float)fun()/4.0;
  Serial.println(tmp1);
  Serial.println(tmp2);
}
void loop() {

}
/**/
результат 
2.50
2.50

 

 

5N62V
Offline
Зарегистрирован: 25.02.2016

qwone пишет:

5N62V, я не говорю что правильно или неправильно говорит andriano . Я объсняю почему я поставил (float). 


 

Хм.  Я немного не о том спрашивал. 

br0lviv
Offline
Зарегистрирован: 11.06.2018

Спасибо большое ) я только учусь. А мой пример я скопипастил где то в инете. Интересно познавать что то новое) Эту функцию можно применить и к другим для вычисления целых чисел, верно?)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

5N62V пишет:
Хм.  Я немного не о том спрашивал.

// a о чем?
// есть функция   operator / и она перегружена
int operator / (const int &v1, const int &v2);
float operator / (const float &v1, const int &v2);
float operator / (const int &v1, const float &v2);
// то есть, если где-то мелькнуло float то результат float
// a так как у меня нет привычки писать 1023 так  1023.0 , то пишу (float) на всякий случай.
// тем более скетч я не проверял в работе.

 

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

Тем более, что analogRead(pin)*500/1023.0 здесь не поможет - первая операция будет выполнена в int и она приведет к переполнению. И только потом неправильное значение будет преобразовано в float и поделено на 1023.

br0lviv
Offline
Зарегистрирован: 11.06.2018

Кстате, а byte можно использувать если надо вернуть правду или ложь?

5N62V
Offline
Зарегистрирован: 25.02.2016

br0lviv пишет:
Кстате, а byte можно использувать если надо вернуть правду или ложь?
можно. А можно вернуть степень соответствия правде в пределах 8ми бит.