2016-04-15 4 views
1

Итак, я начинаю возиться с емкостными датчиками и все потому, что это довольно классный материал.Расчет среднего значения данных датчика (емкостного датчика)

Я следил за некоторыми учебниками в Интернете о том, как настроить его и использовать библиотеку CapSense для Arduino, и у меня просто был быстрый вопрос об этом коде, который я написал здесь, чтобы получить среднее значение для этих данных.

void loop() {      
    long AvrNum; 
    int counter = 0; 

    AvrNum += cs_4_2.capacitiveSensor(30); 
    counter++; 

    if (counter = 10) { 
    long AvrCap = AvrNum/10; 
    Serial.println(AvrCap); 
    counter = 0; 
    } 
} 

Это мой оператор цикла и последовательный, кажется, как и его работа, но цифры просто выглядят подозрительно низки для меня. Я использую резистор 10M (коричневый, черный, черный, зеленый, коричневый) и касаюсь части фольги, к которой прикреплены как штыри для отправки, так и приема (изолента), и я получаю номера около 650, даю или принимаю 30.

В принципе, я спрашиваю, выглядит ли этот код правильно и если эти цифры имеют смысл ...?

+2

Нет, это не так. 'AvrNum' используется uninitalised, поэтому приводит к Undefined Behavior. И 'counter = 10' должен быть' counter == 10'. – kaylum

+0

и, строго говоря, код будет лучше с 'long AvrCap = AvrNum/counter;' –

ответ

1

язык, используемый в среда Arduino на самом деле является просто ненасильственным подмножеством C++ с функцией main(), скрытой внутри кода рамки, предоставленной IDE. Ваш код - это модуль, который будет скомпилирован и связан с каркасом. Когда среда начинает работать, она сначала инициализирует себя, а затем ваш модуль, вызывая функцию setup(). После инициализации структура входит в бесконечный цикл, вызывая функцию ваших модулей loop() на каждой итерации.

Ваш код использует локальные переменные в loop() и ожидает, что они будут хранить свои значения от вызова до вызова. Хотя это может произойти на практике (и, скорее всего, так как эта часть фреймворка main(), вероятно, всего лишь while(1) loop();), это вызывает демонов неопределенного поведения. C++ не дает никаких обещаний о ценности неинициализированной переменной, и даже чтение может привести к чему-либо. Даже, по-видимому, работает.

Чтобы исправить это, аккумулятор AvrNum и counter должны храниться где-то, кроме стопки loop(). Они могут быть объявлены static или перемещены в модуль снаружи. Снаружи лучше ИМХО, особенно в ограниченной среде Arduino.

Вам также необходимо очистить аккумулятор после завершения среднего. Это простейшая форма фильтра усреднения, где вы суммируете блоки фиксированной длины из N выборок, а затем используйте этот средний каждый N-й образец.

Я считаю, что этот фрагмент (непроверенные) будет работать для вас:

long AvrNum; 
int counter; 

void setup() { 
    AvrNum = 0; 
    counter = 0; 
} 

void loop() {      

    AvrNum += cs_4_2.capacitiveSensor(30); 
    counter++; 

    if (counter == 10) { 
    long AvrCap = AvrNum/10; 
    Serial.println(AvrCap); 
    counter = 0; 
    AvrNum = 0; 
    } 
} 

Я предоставил setup(), хотя дублирует гарантию языка C++, что глобальные переменные начинают жизнь инициализируется 0.

+0

Похоже, что он все правильно читает! Спасибо за помощь. Использование глобальной переменной имеет большой смысл. Я нашел другое решение с этим для цикла, не могли бы вы сказать мне, что это проверяет ... Я сказал, что это еще один ответ ... – KellysOnTop23

+0

Да, это мое плохо. Я отправил его в качестве ответа, это круто? – KellysOnTop23

2

Ваша строка if (counter = 10) недействительна. Это должно быть if (counter == 10)

Первые счётчики против 10 и будут (конечно) оцениваться как истинные.
Вторые тесты для счетчика, равное 10, и не будет оценивать с истинным до тех пор, пока счетчик не является, по сути, равно 10.

Кроме того, kaylum упоминает другую проблему, ни инициализации AvrNum

+0

Хорошо, я сделал все эти вещи, кроме инициализации 'AvrNum', потому что если я инициализирую его до 0, тогда он не будет возвращаться и удалять ранее сохраненные данные датчика? Я хотел получить в среднем около десяти показаний или около того. – KellysOnTop23

+0

Инициализация 'AvrNum' является необходимостью. Да, вы потеряете свои предыдущие данные - для решения этой проблемы выполните 'if ((counter% 10) == 0)' и 'AvrCap = AvrNum/counter;') – KevinDTimm

0

Это то, что я в конечном итоге придумал, потратив еще немного времени на это. После некоторого ручного вычисления он получает все данные.

long AvrArray [9]; 

     for(int x = 0; x <= 10; x++){ 
     if(x == 10){ 
      long AvrMes = (AvrArray[0] + AvrArray[1] + AvrArray[2] + AvrArray[3] + AvrArray[4] + AvrArray[5] + AvrArray[6] + AvrArray[7] + AvrArray[8] + AvrArray[9]); 
      long AvrCap = AvrMes/x; 
      Serial.print("\t"); 
      Serial.println(AvrCap); 
      x = 0; 
     } 

     AvrArray[x] = cs_4_2.capacitiveSensor(30); 
     Serial.println(AvrArray[x]); 

     delay(500); 
+0

Это плохо сломано и заслуживает собственного вопроса, так что его можно расчленить и объяснить, почему. Вы можете связать этот вопрос с этим вопросом, что является обычным способом, с помощью которого последующие вопросы лучше всего обрабатывать на SO. – RBerteig

+0

Gotcha! Я сделаю это всего за секунду – KellysOnTop23

Смежные вопросы