ARRAY массивы
- Войдите на сайт для отправки комментариев
Пт, 24/10/2014 - 15:30
Нужен код, который бы снимал показания с датчика температуры в течении пулучаса, а потом вычислял среднюю. Я сделал это:
float twArray[10]={0,0,0,0,0,0,0,0,0,0}; long previousMillis = 0; // храним время изменения long interval = 4000; //интервал float tw = 0; //Температура трубы int m = 0; // Переменная считающая циклы массива void setup() { Serial.begin (9600); } void loop() { unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) //проверяем не прошел ли нужный интервал, если прошел то { previousMillis = currentMillis; // сохраняем время twArray[m] = tw; //пишем текушее значение температруры в массив в ячейку с номером "m" m++; if(m>=10) // если записана последняя девятая ячейка, обнуляем, и начинаем писать с нулевой ячейки { m = 0; } } Serial.print(" m = "); Serial.print(m); Serial.println(" "); Serial.print("["); Serial.print(twArray[0]); Serial.print("] "); Serial.print("["); Serial.print(twArray[1]); Serial.print("] "); Serial.print("["); Serial.print(twArray[2]); Serial.print("] "); Serial.print("["); Serial.print(twArray[3]); Serial.print("] "); Serial.print("["); Serial.print(twArray[4]); Serial.print("] "); Serial.print("["); Serial.print(twArray[5]); Serial.print("] "); Serial.print("["); Serial.print(twArray[6]); Serial.print("] "); Serial.print("["); Serial.print(twArray[7]); Serial.print("] "); Serial.print("["); Serial.print(twArray[8]); Serial.print("] "); Serial.print("["); Serial.print(twArray[9]); Serial.println("]"); }
А вот лог:
TW = 26.75 m = 0 [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] TW = 27.25 m = 1 [27.25] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] TW = 27.94 m = 2 [27.25] [27.94] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] TW = 28.37 m = 3 [27.25] [27.94] [28.37] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] TW = 28.69 m = 4 [27.25] [27.94] [28.37] [28.69] [0.00] [0.00] [0.00] [0.00] [0.00] [0.00] TW = 28.87 m = 5 [27.25] [27.94] [28.37] [28.69] [28.87] [0.00] [0.00] [0.00] [0.00] [0.00] TW = 29.00 m = 6 [27.25] [27.94] [28.37] [28.69] [28.87] [29.00] [0.00] [0.00] [0.00] [0.00] TW = 29.12 m = 7 [27.25] [27.94] [28.37] [28.69] [28.87] [29.00] [29.12] [0.00] [0.00] [0.00] TW = 29.19 m = 8 [27.25] [27.94] [28.37] [28.69] [28.87] [29.00] [29.12] [29.19] [0.00] [0.00] TW = 29.19 m = 9 [27.25] [27.94] [28.37] [28.69] [28.87] [29.00] [29.12] [29.19] [29.19] [0.00] TW = 29.19 m = 0 [27.25] [27.94] [28.37] [28.69] [28.87] [29.00] [29.12] [29.19] [29.19] [29.19] TW = 28.56 m = 1 [28.56] [27.94] [28.37] [28.69] [28.87] [29.00] [29.12] [29.19] [29.19] [29.19] TW = 27.94 m = 2 [28.56] [27.94] [28.37] [28.69] [28.87] [29.00] [29.12] [29.19] [29.19] [29.19]
Почему за первый проход при m=0 в ячейку ноль ничего не пишется? А при m=1 запись идёт не в первую ячейку, а в нулевую? Откуда отставиние взялось?
По моему при первом проходе это условие выполняется всегда:
if(currentMillis - previousMillis > interval)
мне кажется копать надо здесь.
Почему за первый проход при m=0 в ячейку ноль ничего не пишется?
Может 4-ре секунды еще не прошло ?
А при m=1 запись идёт не в первую ячейку, а в нулевую? Откуда отставиние взялось?
Вы сначала пишете в массив (m=0), потом изменяете m (m=1), потом выводите новое значение - Serial.print(m);
Я думаю что расчет среднего можно свести к паре условий и формуле:
[среднее] = ([среднее]*[число измерений]+[текущие показания])/([число измерений] + 1)
И не тратить на это массив.
Вы сначала пишете в массив (m=0), потом изменяете m (m=1), потом выводите новое значение - Serial.print(m);
Точно!
Я думаю что расчет среднего можно свести к паре условий и формуле:
[среднее] = ([среднее]*[число измерений]+[текущие показания])/([число измерений] + 1)
И не тратить на это массив.
Не совсем понял, как это среднее получиь без массива?
А очень просто:
Посчитав среднее и умножив его на какое-то число измерений мы как-бы знаем что наш "массив" состоит из этого количества измерений и все измерения равны среднему. Поэтому зачем помнить каждое измерение?
Они все равны среднему...
NeiroN прав , но более "читабельно и понятно "
[среднее] = ( [среднее] * [число измерений - 1] + [ текущее показание ] ) / ( [число измерений] )
А очень просто:
Посчитав среднее и умножив его на какое-то число измерений мы как-бы знаем что наш "массив" состоит из этого количества измерений и все измерения равны среднему. Поэтому зачем помнить каждое измерение?
Они все равны среднему...
А как среднее посчитать? Сложить, например, десять значений, и разделить на десять. Будет среднее. Но ведь эти десять значений, которые нужно сложить, нужно где-то хранить. Как их хранить, если не в массиве? Я чёт не улавливаю Вашу мысль.
Мне нужно каждые 20 минут отправлять значения на сервер. Я не могу отправлять текущие значения, ибо иногда они выбиваются из нормы случайным образом. Так я решил делать 10 измерений, каждые две минуты, потом высчитывать среднее за эти 20 минут и слать в БД.
Как это решить не массивами, просто не пойму. Может Вы и правы, но я чёт не догоняю.
Делаем первое измерение. Так как оно у нас одно то и его среднее значение ему и равно.
Следующее измерение считаем по "формуле" .
Причём " количество измерений " можем брать ЛЮБОЕ!!!!! ( это всё условно...., хоть мильён ) . Главное помнить о возможности переполнения, поэтому float вам в руки
От выбора "количества измерений" зависит "скорость изменения" среднего: при двух она максимальна, а при миллионе-миллиарде - сами понимаете .....
http://arduino.ru/forum/proekty/dosvetka-v-teplitse#comment-49692
Делаем первое измерение. Так как оно у нас одно то и его среднее значение ему и равно.
Следующее измерение считаем по "формуле" .
Причём " количество измерений " можем брать ЛЮБОЕ!!!!! ( это всё условно...., хоть мильён ) . Главное помнить о возможности переполнения, поэтому float вам в руки
От выбора "количества измерений" зависит "скорость изменения" среднего: при двух она максимальна, а при миллионе-миллиарде - сами понимаете .....
http://arduino.ru/forum/proekty/dosvetka-v-teplitse#comment-49692
Ваша схема выдаст только общее среднее, например если первые пол часа имеют показания -10, а вторые пол часа +10 то среднее за вторые пол часа высчитать не получится, у нас будет только общее значение равное 0
Ваша схема выдаст только общее среднее, например если первые пол часа имеют показания -10, а вторые пол часа +10 то среднее за вторые пол часа высчитать не получится, у нас будет только общее значение равное 0
Эта "схема" выдает скользящее среднее в диапазоне из число_измерений замеров. "Среднее за вторые полчаса" вы получите, если число_измерений укладывается в полчаса (ровно) один раз. Т.е. при частоте n замеров в час в качестве диапазона вычисления среднего следует взять число_измерений=n/2.
Логично, но кто вам мешает каждые полчаса начать подсчёт сначала?
Логично, но кто вам мешает каждые полчаса начать подсчёт сначала?
А может ему нужно знать среднее значение за последние пол часа?
А я что написал?
http://arduino.ru/forum/programmirovanie/array-massivy#comment-86104
А я что написал?
http://arduino.ru/forum/programmirovanie/array-massivy#comment-86104
Начать каждые пол часа с начала или иметь данные за последние пол часа это разные вещи. Например, начиная каждые пол часа сначала, на 35 минуте мы сможем иметь данные лишь за последние 5 минут, как ему узнать по вашему среднее за периуд с 5 по 35 минуту?
Нужен код, который бы снимал показания с датчика температуры в течении пулучаса, а потом вычислял среднюю.
А зачем накапливать сумму измерений и только на десятый раз получать наше среднее?
А если измереня идут раз в минуту? И если это газовый котёл? Он за десять минут работы так всё прогреет...
Вся вкусность подсчёта среднего сразу- легко регулировать время реакции сменой " количества измерений" и возможность установить порог допустим 0.1 градуса, а не 2-3, как обычно ставят гистерезис в терморегуляторах и при этом средняя температура действительно будет +- 0.1
Да согласен, можно не накапливать.
Это так сказать проба пера, я из класса начинающих.
Просто задача не регулировать , а считать среднее.
"Нужен код, который бы снимал показания с датчика температуры в течении пулучаса, а потом вычислял среднюю."
Хм. Спасибо за ответы. Нарисовалось два способа, осталось выбрать приемлимый. Цель - хранить историю температуры. Из проведённого опыта видно, что температура при самом резком изменении меняется на 2 градус не чаще раза в 20 минут. Тоесть максимальная скорость изменения температуры примерно 6 градусов в час. При таких вялотекущих процессах не вижу смысла засирать БД показаниями чаще чем в 20 минут. Знающие люди вообще посоветовали раз в час писать.
Таким образом цель одна - максимально сгладить показания, высчитав среднюю температуру за промежуток времени в 20 минут и внести её в БД.
Запись в БД идёт так: ардуино с изернет модулем меняет на своей веб страничке показания раз в 20 минут. (20 минут утрировано, на самом деле 19.5 минут). А скрипт сервера заходит на ардуинку по http, и спарсивает оттуда показания, занося их в базу.
Сейчас это делается массивами. Раз в 19,5 минут меняется веб страничка ардуины, раз в 20 минут скрипт забирает эти данные.
В моём методе получается, что температура храниться только за 20 минут, следущие 20 минут начинается новое накапливание.
Второй способ в любой момент даёт среднее число, с каждым пришедшим значением пересчитывая его. Я пока ещё не знаю, что именно больше подойдёт для моей задачи. Но оба варианта имеют право на жизнь.