Здравствуйте ) Хочу записывать измерения с датчика HC-SR04 в массив, и после измерений, с этим массивом производить считывание переменных, и на основе этих переменных, принимать решение. Вот, что у меня есть сейчас: Код (C++): #include <Ultrasonic.h> float distance[5]; Ultrasonic us_1 (8,9); void setup() { Serial.begin(9600); for (byte i=0; i<5; i++) { float distance=us_1.Ranging(CM); } for (byte i=0; i<5; i++) { Serial.print(distance[i]); Serial.print(" "); i++; } } void loop() { } Пока что у меня выводятся только нули. Что почитать, чтобы понять где косяк?
https://yandex.ru/search/?lr=10758&text=c++ работа с массивами Вы в массив ничего не пишете. Первый цикл должен быть примерно таким: Код (C++): for (byte i=0; i<5; i++) { distance[i]=us_1.Ranging(CM); }
И учтите, что если вы оставите цикл работы с массивом в процедуре setup(), то он быть выполнен только 1 раз, после рестарта.
Да, это я знаю. Теперь другой вопрос. У меня возникла проблема с правильной реализацией чтения данных из массива и реагирования на них. Сейчас у меня это сделано таким образом: Код (C++): #include <Ultrasonic.h> float distance[5]; Ultrasonic us_1 (8,9); void setup() { Serial.begin(9600); for (byte i=0; i<5; i++) { distance[i]=us_1.Ranging(CM); } pinMode(A3, OUTPUT); } void loop() { boolean control=true; for (byte i=0; i<5; i++) { distance[i]=us_1.Ranging(CM); delay(150); // Serial.println(distance[i]); } for (byte i=0; i<5; i++) { Serial.print(distance[i]); Serial.print(" "); for (byte i=0; i<5; i++) { if (distance[i]<15){ control==false; } } if (control == true) { analogWrite(A3, 150); } else { digitalWrite(A3, LOW); } } } Но диод, напрямую подключенный к А3, почему-то не гаснет, когда я пододвигаю препятствие ближе 15 см. В чем проблема и как правильнее?
Код (C++): for (byte i=0; i<5; i++) { if (distance[i]<15){ control==false; // ОШИБКА!!!! Это не присвоение, а сравнение. } } PS: А Вы уверены, что Вам нужны массивы?
Мне нужно осваивать различные способы) В случае с 5 измерениями, не особо, но допустим если будет нужда увеличить количество измерений до n, то мне просто памяти не хватит писать в условиях if условия для всех n измерений)
Проблема в том, что иногда датчик выдает совершенно нереалистичные данные, и на их основе принимает решение. А потом, как только данные становятся реальными, вертает все обратно. Такие дергания мне не нужны совершенно. Поэтому я и хочу, чтобы решение принималось по массиву, причем, надо еще сделать, чтобы более новые измерения заменяли более старые значения без полного обновления массива. Надо еще помыслить над этим.
зачем какие то массивы усредняем данные за какой то промежуток времени выкидывая макс скачки значений
Вот, в общем, к чему я пришел Код (C++): #include <Ultrasonic.h> #define Deviation 3 float distance[6]; Ultrasonic us_1 (8, 9); void setup() { Serial.begin(9600); for (byte i = 0; i < 6; i++) { distance[i] = us_1.Ranging(CM); } pinMode(A3, OUTPUT); } void loop() { //boolean control=true; distance[0] = us_1.Ranging(CM); delay(150); byte previous = 4; byte current = 5; for (byte i = 1; i < 6; i++) { distance[current] = distance[previous]; previous--; current--; for (byte i = 0; i < 5; i++) { Serial.print(distance[i]); Serial.print(" "); } Serial.println(" "); } } И теперь у меня есть два вопроса: Почему, когда я вывожу функцию передвижения значений в массиве отдельно, с помощью void Код (C++): distance[0]=us_1.Ranging(CM); delay(150); changeVal; for(byte i=0; i<5; i++) { Serial.print(distance[i]); Serial.print(" "); } Serial.println(" "); } void getAvegage() { } void changeVal() { byte previous=4; byte current=5; for (byte i=1; i<6; i++) { distance[current]=distance[previous]; previous--; current--; } У перестает это адекватно работать? И второй, как мне реализовать отсев значений? К примеру, в новый массив - выборку, куда будут попадать только значения, отличающиеся от среднего значения(как его определять в начале работы? Что будет, если в это среднее значение попадет косячное измерение?) не более чем на 3(допустим) сантиметра.
Иными словами, относительно чего считать, прошел ли скачок измерения, или нет? Я очень смутно представляю, как сделать это надежным, кроме как при каждом перезапуске вручную подтверждать адекватность этого среднего значения
Вы читать умеете или только пишите как глухарь на току? Если лень спросить что такое медиана, погуглите ее в интернете и найдете ответ на вопрос как игнорировать "скачки измерения".
Виноват, дурак, исправлюсь))) Вопрос века - можно ли медиану рассчитывать из ряда неупорядоченных значений? Вроде как дискретный ряд - это то, что нужно, но меня терзают смутные сомненья. А если нельзя, то нужна функция сортировки массива по возрастанию, которую я сделал вот так: Код (C++): void sort() { bool leave=false; float temp; while (!leave) { leave=true; for (byte counter=0; counter<9; counter++) { byte i=0; if (distance[i]>distance[i+1]) { temp=distance[i]; distance[i]=distance[i+1]; distance[i+1]=temp; i++; leave=false; } } } } Но которая, почему-то, не работает выдает нули. Как быть?
Медиану надо вычислять из упорядоченных значений, в этом и смысл. Сперва массив сортируют "по росту", потом берут среднее или одно из средних, если количество данных четное. Способов сортировки несколько, самый простой и понятный "пузырьком", то есть запускается цикл от 0 до кол-во элементов, внутри него еще один такой же цикл и сравнивается значение первого со вторым, если одно больше другого то меняются местами, если нет то нет. В итоге получается упорядоченные данные. Например: Код (C++): int massiv[10] // массив из 10 элементов int swap; for (byte i = 0; i <= 9; i++) { for (byte j = 0; j <= 9; j++) { if (massiv[i] < massiv[j]) { swap = massiv[i]; massiv[i] = massiv[j]; massiv[j] = swap; } }
Сделал. Вот функция сортировки отдельно. Код (C++): bool leave=false; float temp; while (!leave) { leave=true; byte i=0; for (byte counter=0; counter<9; counter++) { if (distance[i]>distance[i+1]) { temp=distance[i]; distance[i]=distance[i+1]; distance[i+1]=temp; leave=false; } i++; } } Образец взят отсюда: http://cppstudio.com/post/457/ Вроде все работает) Еще вопрос, почему, когда я пытаюсь запихнуть этот код в void(), это перестает работать? DrProg, спасибо, за инфу)
Скорее всего потому, что переменные не видны. Они должны быть глобальными или передаваться в качестве параметров.
Блин. Вот, вывел переменные в глобальные.. Все равно не работает.. Что я забыл? Код (C++): #include <Ultrasonic.h> #define HIGH_LEVEL 15 #define LOW_LEVEL 201 #define Hole 9 #define Osmos_OUT #define lenght 10 //Размер массива, можно изменять. float distance[lenght]; float median_1; float median_2; byte update_step; byte sort_step; byte current = lenght-1; byte previous = current-1; byte sort_cycle_step; byte sort_parameter; Ultrasonic us_1 (8, 9); void setup() { Serial.begin(9600); for (byte i = 0; i < lenght; i++) { distance[i] = us_1.Ranging(CM); } } void update_() { byte current = lenght-1; byte previous = current-1; for (update_step = 1; update_step < lenght; update_step++) { distance[current] = distance[previous]; previous--; current--; } } void loop() { distance[0] = us_1.Ranging(CM); delay(150); /* Serial.println("Before update"); for (byte i=0; i<lenght; i++) { Serial.print (distance[i]); Serial.print (" "); } Serial.println (" ");*/ update_; bool leave=false; float temp; while (!leave) { leave=true; sort_parameter=0; for (byte counter=0; counter<lenght-1; counter++) { if (distance[sort_parameter]>distance[sort_parameter+1]) { temp=distance[sort_parameter]; distance[sort_parameter]=distance[sort_parameter+1]; distance[sort_parameter+1]=temp; leave=false; } sort_parameter++; } } float M1=(distance[4]+distance[5])/2; // Serial.println(M1); Serial.println("After update"); for (byte i=0; i<lenght; i++) { Serial.print (distance[i]); Serial.print (" "); } Serial.println (" "); }