Сярэдняе арыфметычнае для датчыка

Гэта код, я ў дадзены момант, але я хачу, каб дадаць арыфметыка значыць, да яго. Мая мэта: калі штыфт A0 чытае 5 значэнняў, я атрымліваю сярэдняе на якой вентылятар і вадзіць будзе залежаць быць уключаны і выключаны, а 5 асобных вымярэнняў.

int tempPin = A0;
int fan = 3;
int led = 8;
int temp;
int tempreal;
int tempMin = 20;
int tempMax = 30;

void setup() 
{
  Serial.begin(9600);
  pinMode(fan, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(tempPin, INPUT);
}

void loop() 
{
  temp = analogRead(tempPin);
  tempreal = temp * 0.48828125;
  delay(1);
  if(tempreal > tempMax)
  {
    digitalWrite(fan,HIGH);
    digitalWrite(led,LOW);
    delay(1);
  } 
  else if (tempreal < tempMin)
  {
    digitalWrite(fan,LOW);
    digitalWrite(led,HIGH);
    delay(1);
  } 
  else if (tempreal >  tempMin && tempreal <  tempMax)   
  {
    digitalWrite(fan,LOW);
    digitalWrite(led,LOW);
    delay(1);
  }
}

Edit by Edgar Bonet – The OP added in a comment to my answer:

«Я спрабаваў [усярэдненне паслядоўных чытанняў]. Ён працаваў, як і варта было чакаць але гэта яшчэ не вырашае маю праблему. Мой датчык толькі атрымлівае права значэння ў пачатку сканавання, а затым яна змяняецца. Вось чаму Я хацеў, каб сярэдняе значэнне, але яна па-ранейшаму не працуе. На жаль, я думаю, Я не змагу змяніць датчык, але ці ёсць іншы спосаб маскіруюць гэтую праблему? »

Ніжэй прыведзены скрыншот, які паказвае, як правільна (✓) і няправільнае (✗) паказанні:

Example readings

2

5 адказы

Здаецца, занадта проста. я нешта адсутнічае?

--- arithmetic-mean.ino.orig    2017-04-27 19:37:01.386458500 +0200
+++ arithmetic-mean.ino 2017-04-27 19:38:14.458114972 +0200
@@ -16,8 +16,11 @@

 void loop() 
 {
-  temp = analogRead(tempPin);
-  tempreal=temp * 0.48828125;
+  temp = 0;
+  for (int i = 0; i < 5; i++) {
+    temp += analogRead(tempPin);
+  }
+  tempreal = temp * 0.48828125/5;
   delay(1);
   if(tempreal > tempMax)
   {
1
дададзена
Я паспрабаваў тое, што вы сказалі, што працавалі, як вы whoud чакаць, але ён па-ранейшаму не вырашае маю праблему. Мой датчык атрымлівае толькі правільныя значэння ў begenening ў сканавальным, а затым яна мяняецца. Вось чаму я хацеў зрабіць сярэдняе значэнне, але яна па-ранейшаму не працуе. На жаль, я думаю, што я не зможам змяніць датчык, але ці ёсць іншы спосаб camuflage гэтай праблемы? [Спасылка] prntscr.com/f1kzrv
дададзена аўтар Richard Haven, крыніца
@najkulime: Тады вы павінны перапісаць сваё пытанне. Вы пыталіся пра сярэдняе арыфметычнае, але гэта не тое, што вы хочаце: вы хочаце, каб разабрацца ў сапраўднай ад несапраўдных паказанняў, што з'яўляецца цалкам іншым пытаннем.
дададзена аўтар Sprogz, крыніца
Можа быць, дадаць маленькую затрымку пасля analogRead. Было б карысна, калі б вы маглі б надрукаваць значэння, атрыманыя праз паслядоўны порт, і паказаць нам, што.
дададзена аўтар Al., крыніца

Акно фіксаванай выбаркі можа быць цяжка кіраваць, асабліва калі вы хочаце разлік рэкурсіўнай, для прасторы і хуткасці меркаванні.

Вы можаце дасягнуць падобных вынікаў праз экспанентнае згладжванне.

Yn = (1−α) Yn−1 + α Xn

Калі Y <�суб> п </суб> з'яўляецца згладжаны вынік, Х <�суб> п </суб> з'яўляецца вымярэнне току, і α з'яўляецца вагу.

З некаторымі думкамі, гэта можа быць зроблена з цэлымі лікамі і без страты дакладнасці.

Рэдагаванне: я правёў параўнанне экспанентна згладжвання VS. (фіксаванае акно) слізгальнай сярэдняй. Слізгальнае сярэдняе алгарытм быў напісаны рэкурсыўнай для максімальнай хуткасці.

дискретизированные дадзеныя мадэляваных сінусоіда:

1000 * Sin (2р * п/100) + 100 * шум. п = 0..19999, і шум = -0,5 ... + 0,5.

So snr = 1000/50 = 20:1, or about 5 digits. far worse than what you would encounter in a 10-bit adc. enter image description here

акно я выбраў гэта 4.

Як вы можаце бачыць, што абодва падыходу вельмі падобныя адзін на аднаго. экспанентнае згладжванне выкарыстоўвае нашмат менш аператыўнай памяці, а таксама нашмат хутчэй. старыя дадзеныя маюць меншы вага на выхадзе, то звычайна пажадана ў большасці прыкладанняў.

1
дададзена
@dannyfI паспрабаваў тое, што вы прапанавалі, але ім атрымліваць рэальныя вымярэння занадта павольна, яна займае 10-15 секунд, каб ацаніць стабілізавацца. Гэта больш падобна на гэта, але гэта занадта павольна. спасылка рэдагавання: можа быць, я Шоўду змяніць значэнне альфа?
дададзена аўтар Richard Haven, крыніца
Памяць не з'яўляецца вялікай праблемай, калі вы толькі асерадненнем 5 значэнняў. І праблема ў OP не можа быць вырашана шляхам асерадненні: гл абноўленага пытання.
дададзена аўтар Sprogz, крыніца

Вы можаце выкарыстоўваць слізгальнае сярэдняе. Ён будзе абнаўляцца пры кожным цыкле, калі вы бераце новае чытанне. Выкажам здагадку, вы хочаце, каб асерадніць N паказанняў:

double moving_average(double old_average, double new_value) {
    double new_average = old_average;
    new_average -= old_average/N;
    new_average += new_value/N;
    return new_average;
}

Я рэдагаваў функцыю вышэй. Я надрукаваў адзін з аргументаў няправільна.

0
дададзена
Я ўзяў на сябе смеласць выправіць свой код, як вы забыліся абвясціць new_average . Звычайнае значэнне « слізгальнага сярэдняга » з'яўляецца адзін дадзены ў @ DavidJ адказвае. Тое, што вы прапануеце тут замест гэтага <�я> экспанентна узважанае слізгальная сярэдняя. Па сутнасці, рэалізацыя адказу @ dannyf ст. Але зьвярніце ўвагу, што праблема ў OP не можа быць вырашана шляхам асерадненні: гл абноўленага пытання.
дададзена аўтар Sprogz, крыніца
Просьба ўдакладніць, чаму ён не будзе працаваць
дададзена аўтар Alexandru Luchian, крыніца
Вы кажаце, код <�б> не будзе працаваць , таму што выклік павінен быць зроблены з двума аргументамі?
дададзена аўтар Alexandru Luchian, крыніца
яна не будзе працаваць.
дададзена аўтар dannyf, крыніца
«Просьба ўдакладніць, чаму ён не будзе працаваць" даволі просты: як стары і новы код пакутуе ад адной праблемы - трэба адсочваць old_average экзагеннага, які большая частка праблем у такой рэалізацыі. вы маглі б зрабіць, што карэнныя так што ваш карыстальнік павінен толькі карміць код з new_value і дасць у сярэднім адзін выклік.
дададзена аўтар dannyf, крыніца
<�Р> Мой датчык атрымлівае толькі правільныя значэння ў пачатку сканавання, а затым яна змяняецца. Менавіта таму я хацеў бы зрабіць сярэдняе значэнне, але яна па-ранейшаму не працуе.

У мяне была аналагічная праблема. Аказалася, што я чытаў лісты і перадачы занадта хутка. Гэта азначае, што, так як гэта здаецца, што чытанне і запіс могуць быць перапыненыя падчас «іх працы», калі вы чытаеце зменную і ў той жа час хто-то пішуць на тым, што вы чытаеце смецце. На мой погляд, гэта можа быць выпраўлена шляхам прымянення «семафораў» або мьютекса або памяншаючы выклік чытання. Выпадковым гэта здарыцца зноў, але радзей.

Ідэю можна знайсці тут https://forum.arduino.cc/index.php?topic=132813.0

лепшы

Gian Maria

0
дададзена

See Arduino Tutorials Smoothing https://www.arduino.cc/en/tutorial/smoothing

Стварыць масіў для захоўвання серыі вымярэнняў. А пераменная для ўтрымання сумы.

Інкрэментаванага цыкл праз масіў, адымаючы самае старое значэнне з сумы і замяніць яго ў масіве з бягучым значэннем. Падзяліць на лік паказанняў для сярэдняга.

Памятаеце, каб ўлічыць затрымку ў кожным чытанні, як падыходзіць для датчыка.

0
дададзена
Няма неабходнасці тут для слізгальнага сярэдняга: гэта прасцей, каб проста ўзяць N чытанне і атрымаць іх сярэдняе значэнне, так як у маёй абароне. Але зьвярніце ўвагу, што праблема ў OP не можа быць вырашана шляхам асерадненні: гл абноўленага пытання.
дададзена аўтар Sprogz, крыніца