Измерение времени соударения металлических шаров

lev39
Offline
Зарегистрирован: 14.08.2012

Уважаемые Гуру. Мне надо измерить  время соударения металлических шаров ( несколько микросекунд).

Решил использовать pulseIn. Взял демо программу. Добавил Serial для вывод на монитор.

Но сколько ни бился ничего не получается. Дребезг удалял аппаратно с помощью триггеров. Все равно ничего не помогло. Может нужна какя-либо библиотека ? Скетч взял из Интернета.

int pin = 2;
unsigned long duration;

void setup()
{
pinMode(pin, INPUT);
Serial.begin(9600);
}

void loop()
{
duration = pulseIn(pin, HIGH,);
Serial.println(duration);
}

lev39
Offline
Зарегистрирован: 14.08.2012

Лев Васильевич Пигалицын. Учитель физики.

leshak
Offline
Зарегистрирован: 29.09.2011

 

lev39 пишет:

Лев Васильевич Пигалицын. Учитель физики.

А это к чему? ;)

Читаете (либо поручаете ученикам ;)  : 

Вешаетесь на прерывание, в массив запоминаете "когда оно произошло" (и увеличиваете счетчик сколько событий поймали). Не забываете про слово volatile для переменных которые меняются в обработчике прерывания. Время от времени (или когда заполнитеся) в loop() выводите этот массив в Serial.

Смотрите на "то что получилось", чешите маковку.... ну и дальше начинаете "игратся". Вместо записи в массив "когда произошло" - пишете "интервалы" ( micros()-prevMicro), боретесь с "дребезгом" (игнорируете события меньше какой-то длины) и т.п.

P.S. Только обратите внимание что замерять точнее чем  4 микросекунды не получится никак.

maksim
Offline
Зарегистрирован: 12.02.2012

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

lev39
Offline
Зарегистрирован: 14.08.2012

Спасибо. Попробую. Только хотелось бы через pulseIn.

Неужели эта функция ни у кого не работает ? Ведь по идее с ней проще. Можно вообще забыть о прерываниях.

А себя рассекретил случайно при регистрации. Не обращайте внимания.

maksim
Offline
Зарегистрирован: 12.02.2012

 Для этого прерывания и нужны... 

lev39
Offline
Зарегистрирован: 14.08.2012

Извините, но в описании о применении puselIn и в его скетче даже нет упоминаний о прерываниях. Поэтому я и писал о том, что может быть для pulseIn есть какая-нибудь библиотека, в которой эти прерывания и зарыты.

Меня подкупила в pulseIn внешняя простота ( как оказалось это не так).

Ну что же Вам спасибо за совет, а я еще подожду - может кто-то и отклинется на pulseIn.

 

maksim
Offline
Зарегистрирован: 12.02.2012

 Да не мучайтесь вы с пульсином, прерывания в разы лучше, с прерыванием вы точно не пропустите срабатывание. Пользоваться прерываниями тоже очень просто.

lev39
Offline
Зарегистрирован: 14.08.2012

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

maksim
Offline
Зарегистрирован: 12.02.2012

Ладно, вот вам готовое решение

#define PIN 2 // 0 прерывание должно быть обязательно на 2 цифровом выводе
unsigned long micros_old = 0;
volatile unsigned int time = 0;
volatile boolean enable = 0;

void setup(){ 
  Serial.begin(9600);
  //digitalWrite(PIN, 1);  // Подтягивающий резистор к +5V
  //attachInterrupt(0, RPM, FALLING);  // срабатывание по заднему фронту
  //attachInterrupt(0, RPM, RISING);  // срабатывание по переднему фронту
  attachInterrupt(0, RPM, CHANGE);  // срабатывание при любом изменении
}

void loop() {
  if(enable){
    Serial.println(time, DEC);
    enable = 0; 
  }
}

void RPM (){
  time = micros() - micros_old;
  micros_old = micros();
  enable = 1;
}

выберите нужный тип прерывания - одну из строк 9,10,11 остальные две закоментируйте и не забывайте про подтягивеющие резисторы, подтяжку к питанию можно включить програмно.

lev39
Offline
Зарегистрирован: 14.08.2012

Maksim ! Большое спасибо. Вы правы. Прерывния это не сложно.

lev39
Offline
Зарегистрирован: 14.08.2012

Maxim ! Извините за назойливость, но может подскажете как рациональнее в присланный Вами пример прмер вставить вот аткой алгоритм :

Пока кнопка к pin 2 не нажата время равно нулю, т.е micros обнулили. Кнопку нажали - время пошло. Кнопку отпустили - время нажатия кнопки на мониторе.

И еще - у меня почему-то максимальное время в micros - 40 mc, а в millis - 3 c, хотя в описаниях говорится о 3 часов и 30 суток соттветственно.

Спасибо.

step962
Offline
Зарегистрирован: 23.05.2011

Как-то так:

 if(!btnPressed) {
  if (timerOn) { // момент перехода из состояния нажато в ненажато, т.е. отпускание кнопки
    Show(micros()-micros_start);
  }
  timerOn=0;
}
else {
  if (!timerOn) { // момент перехода из состояния ненажато в нажато, т.е. нажатие кнопки
    micros_start=micros();
  }
  timerOn=1
}

 

Переменная btnPressed должна принимать значение 1, когда кнопка нажата, и 0 - когда отпущена.

Функцию Show() реализуете сами с учетом того, что и куда будете выводить.

step962
Offline
Зарегистрирован: 23.05.2011

lev39 пишет:

И еще - у меня почему-то максимальное время в micros - 40 mc, а в millis - 3 c, хотя в описаниях говорится о 3 часов и 30 суток соттветственно.

Код покажите.

maksim
Offline
Зарегистрирован: 12.02.2012

Если при нажатии на кнопку на 2 вывод подается 5 вольт, то вот так

#define PIN 2 // 0 прерывание должно быть обязательно на 2 цифровом выводе
unsigned long micros_old = 0;
volatile unsigned int time = 0;
volatile boolean enable = 0;

void setup(){ 
  Serial.begin(9600);
  //digitalWrite(PIN, 1);  // Подтягивающий резистор к +5V
  //attachInterrupt(0, RPM, FALLING);  // срабатывание по заднему фронту
  //attachInterrupt(0, RPM, RISING);  // срабатывание по переднему фронту
  attachInterrupt(0, RPM, CHANGE);  // срабатывание при любом изменении
}

void loop() {
  if(enable){
    Serial.println(time, DEC);
    enable = 0; 
  }
}

void RPM (){
  if(digitalRead(PIN)){
    micros_old = micros();   
  }
  else{
    time = micros() - micros_old;
    enable = 1;
  }
}

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

lev39
Offline
Зарегистрирован: 14.08.2012

Здравствуйте step962. Код Ваш, который Вы мне прислали.

За скетч спасибо.

lev39
Offline
Зарегистрирован: 14.08.2012

Step962 и maksim Большое спвсибо за помощь.

Все работает. Теперь буду избавляться от дребезга. Попробую и аппаратно и программно с помощью библиотеки Arduino Bounce .

Кстати какого Вы мнения об этой библиотеке ? Есть у нее подводные камни для чайника (меня) ? Если есть то сообщите. Или есть более лучший вариант ?

 

maksim
Offline
Зарегистрирован: 12.02.2012

Самые простые способы:
Аппаратно - можно поставить конденсатор.
Програмно - после первого срабатывания игнорировать последующие некоторое время, естественно это время должно быть меньше минимального возможного времени между срабатываниями, проще говоря поставить задержку.

Здесь на форуме вроде не одна тема есть по поводу дребезга контактов.

lev39
Offline
Зарегистрирован: 14.08.2012

Пробовал. Кондесатор и задержка съедают не только микросекунды, но миллисекунды.

И еще - рано обрадовался.

Плучается большой разброс прм выводе продолжительности одного и того же  импульса и при испопользовании micros и millis.

Одно и тоже время, выдаваемое в программах  c micros и millis отличается в разы.

И еще ( я уже писал)  - у меня почему-то максимальное время в micros - 40 mc, а в millis - 3 c, хотя в описаниях говорится о 3 часов и 30 суток соттветственно.

Проверял на двух  платах Freeduino.

 

Решил создать тему про pulseIn. Может у кого-то есть наработки.

leshak
Offline
Зарегистрирован: 29.09.2011

 Забудте про pulseIn оно применимо в давольно узком круге задач. Как правило только когда "мы точно знаем что в ближайшие микросекунды, по отношению ко времени выполнения этой срочке, будет импульс".

Все ваши разбросы возникают он того что какие-то импульсы - пропускаются. А с pulseIn шансы "проворонить импульс" в разы выше чем при использованни аппаратных прерываний (attachInterrupt). Он "слушает ногу" только в момент когда скетч выполняет строчку именно с pulseIn, причем еще и "слушает" ограниченное время. Если за это время "импульса небыло", то он "прекращает слушать" и идет дальше. Так что чем больше у вас написано кода помимо самого pulseIn тем больше шансов что он будет пропускать импульсы.

А еще проблема может быть вовсе не в скетче, а в подключении. Куда какой шар вы подключали? Максим говорил: " не забывайте про подтягивеющие резисторы". Если забыли - возможно у вас шар выступает в качестве антены и ловит наводки из эфира. И ловите вы их, а не только "соприкосновение шаров". А если шары толкаете руками - почти наверняка.

По поводу "дребезга". А нужно ли вам с ним боротся? Любая борьба с дребезгом (как аппаратная, так и програмная) сводится к "игнорировать импульсы меньше определенной длины". Если у вас сама замеряемая величина микросекунды, то вы имеете все шансы "выплеснуть ребенка". Попробуйте вначален добится "четко регистрируем все что происходит на пине", дребезг "фильтровать глазами" (типа "вот соударение, а вот пошел "дребезг"). Да и вообще я не уверен что у вас дребезг имеет месты быть. Это все-таки больше относится к кнопкам. А в вашем случае я бы его, все-таки, интерпретировал как "полезный сигнал". Возможно это не "дребезг", а "серия повторных соударений".

 

maksim
Offline
Зарегистрирован: 12.02.2012

Чтобы нам не гадать и хоть как-то помоч нарисуйте или опишите схему подключения и выложите свой код целиком. 
Сохранение картинок на форуме
Вставка программного кода в тему/комментарий

 

lev39
Offline
Зарегистрирован: 14.08.2012

Спасибо за совет.

Честно говоря я на шарах еще не пробовал. Отрабатываю продолжительность события на кнопке. 

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

На millis при быстром частом нажатии на кнопку ( пулеметная очередь пальцем) выдается наименьшее время 40-50 мс.

Кто-то съедает 20-30 мс. А кто ?

А так на миллис измеряет время неплохо. Сравнивал с секундомером.

А вот на microc творится странное  при пулеметной очереди выдает вот что ( фрагмент):

При каждом нажатии всегда !!!!!!! вылетает пара чисел :

Например (взял с монитора)

44

24840

Потом

40

31100

Потом

28

29076

и т.д.

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

Попробуйте разгадать мою головоломку. Подтягивающий резистор и подключал и отключал. Ничего не менялось.

Иначе мои школьники не смогут измерить скорость звука

Расчетное время прохождения звука на 1 метре в воздухе около 3 мс, тчто миллис им не поможет,

а в металле - 200 мкс, а микрос выдает ерунду.

Имейте ввиду, что у меня Pin 2 соединен с землей через резистор 10 к, а кнопкой я подаю 5 В на Pin 2 от Ардуино.

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

Так что если сможете, помогите моим одаренышам. Спасибо.

leshak
Offline
Зарегистрирован: 29.09.2011

 > Отрабатываю продолжительность события на кнопке.

Очень разумный подоход.

> при быстром частом нажатии на кнопку

Ну "пальцем жать" - в сторону micros можно особо даже не смотреть. Врать будет в любом случае. Пальцем+механика кнопки вы будете успевать работать только в диапазоне миллисекунд. Обычно при "пальцевом вводе", все что меньше 50-150 миллисекунд объявлется "дребегом". Так что ваши 44, 40, 28 - очень вероятно что это дребезг и есть. В момент когда контакт еще не установился четко происходит несколько срабатываний "туда-сюда", пока палец не дожмет кнопку до "четкого контакта".

И вы так и не ответили, как же у вас подключена кнопка. Подтягивающие есть? Куда она замыкает пин при нажатии кнопки? На землю или питание?

Каким скетчем вы, в итоге, пользуетесь?

>Так что если сможете, помогите моим одаренышам.

Так а где сами одареныши? :) Такая шикарная исследовательская задача. Попробовать кучу разных подходов.  Это же намного интересней чем тупо по шагам выполнить лабораторку подготовленную учителем.

maksim
Offline
Зарегистрирован: 12.02.2012

 Честно говоря не представляю как вы хотите замерять скорость звука с помощью механических контактов...

leshak
Offline
Зарегистрирован: 29.09.2011

 Вообщем смотретие, все pulseIn и delay и т.п. - в "боевых задачах" использовать крайне затруднительно. Слишком много у них побочных эффектов в виде остановки скетча на время их выполнения. За "базу" лучше всего, все-таки, взять скетч максима из сообщения #9.

И попробовать устранить один его недостаток: если на пине что-то случится в момент когда выполняются строки 15-18 - мы можем получить невалидные данные. Нужно гарантировать что переменные "которые мы выводим" не могут в этот момент изменится. Достигнуть этого можно введением "массива-буффера" (я на это намекал в первом своем посте давая ссылку на массивы). То есть обработчик должен сохранять данные в буффер (накапливать их там), а loop должен, постепенно выплевыать их оттуда. При этом loop может "чуть-чуть опаздывать". Пока буфер не переполнился и обработчику "есть куда сохранять данные" - ничего терятся не будет.

Заодно и потерянный volatile у micros_old  допишем ;) (тоже мог вложить свою лепту в глюки)

#define PIN 2 // 0 прерывание должно быть обязательно на 2 цифровом выводе

volatile unsigned long micros_old = 0;


#define BUFFER_LENGTH 64 // размер буфера, сколько данных мы можем сохранить без потерь. даже если вывод не будет поспевать их выводить
volatile unsigned long intervals[BUFFER_LENGTH]; // объявляем сам буффер для хранения интервалов

volatile byte saveIndex=0; // индекс в массиве куда будет сохранен очередной интервал
volatile byte reportIndex=0; // индекс данных о которых "нужно отчитатся".

boolean pinState=1; // состояние пина при "не нажатой кнопке". не будем, для сокращения времени, взаправду читать состояние пина. просто при каждом "отчете" будем переключать эту переменную на противоположное значение.

void setup(){ 
  Serial.begin(57600); //ставим скорость повыше, что-бы Serial быстрее освобождал буфер
  //digitalWrite(PIN, 1);  // Подтягивающий резистор к +5V
  //attachInterrupt(0, RPM, FALLING);  // срабатывание по заднему фронту
  //attachInterrupt(0, RPM, RISING);  // срабатывание по переднему фронту
  attachInterrupt(0, RPM, CHANGE);  // срабатывание при любом изменении
  
  Serial.println("Device ready"); // готовы к принятию импульсов
}

void loop() {
  if(saveIndex!=reportIndex){ // в буфере есть данные о которых еще не отчитались

    Serial.print(pinState);Serial.print("="); // выводим "состояние" пина
    
    //выводим одну ячейку буффера
    Serial.println(intervals[reportIndex],DEC);

    pinState=!pinState; // "переключаем состояние пина" для следующего вывода

    reportIndex++; //в следующий раз выведем следующую ячейку
    if(reportIndex==BUFFER_LENGTH)reportIndex=0; // если дошли до конца буффера - опять начинаем сначала.
    
  }

}

void RPM (){
  
  intervals[saveIndex]=micros() - micros_old; // запомнили интервал от прошлого события в буффер
  micros_old = micros(); // запомнили время текущего события (будет использоватся при следующем вызове обработчика
  
  saveIndex++; // увеличили счетчик, следующие интервал сохраним в следующую ячейка
  
  if(saveIndex==BUFFER_LENGTH)saveIndex=0; // буффер закончился переходим опять на его начало


}

 

lev39
Offline
Зарегистрирован: 14.08.2012

Спасибо. Я думал мой ответ не ушел на форум и стал редактировать.

Я немного подредактировал послание на которое Вы ответили. Почитайте снова.

Вы правы. Это шикарная исследовательская задача.

Но одареныши пока отдыхают. В понедельник встретимся. ия их озадачу.

У меня методика такая ( я же учитель), сначала я разберусь сам до конца, а потом перед одаренышими ставлю проблемы. Когда они заходят в тупик я им дозированно подсказываю, подкидываю идеи, варианты, иногда тупиковые. Т.е. они проходят постепенно весь путь., который я прохожу с Вами. И у них постепенно вырастают крылья. Чтобы из ребенка что-то получилось, у него должна быть успешность. Но бывает и так, что они решают проблему сами , оригинально и очень быстро. В таком случае я говорю, что хороший учитель - это учитель которого превзошли его ученики.

А так-моя цель создать на Ардуино школьную физическую цифровую лабораторию. С аналоговыми портами и выводом аналоговой информации   в Процессинг я немного освоил. Так что если интересно - присоединяйтесь.

кСТАТИ, ТОЖЕ ВОЗНИКЛА ПРОБЛЕМА - float в int  пережу, а как сделать обратно - int во float. Искал - не нашел.

Если будет время посмотрите мои сайты - основной www.levpi.narod.ru ( а на нем адреса других моих сайтов).

lev39
Offline
Зарегистрирован: 14.08.2012

Идея измерения скорости звука элементарна.

Горизонтально расположен металлический стержень ( или труба с воздухом). С правой стороны стержня касается металлический шарик. Слева по стержню ударяет другой шарик. В стержне пошла звуковая волна. Когда она доходит до правого конца правый шарик отскакивает. Электрическая схема простая . Левый шарик висит на проволоке, соединенной с Pin 2. Правый шарик, тоже висящий на проволоке,  соединен с GND Ардуино. Когда левый шарик стукается о  трубу  - "кнопка" замыкается через трубу и левый шарик. Когда левый шарик отскакивает, "кнопка" размыкается. А программа измеряет время прохождения волны. Если в программу заранее ввести длину стержня, допусти 1 м , то поделив длину стержня на время получим скорость. Скорость большая  около 5000м/с. Так что время получается порядка 150-200 мкс. Поэтому нам и нужны микросекунды.

"

leshak
Offline
Зарегистрирован: 29.09.2011

lev39 пишет:

кСТАТИ, ТОЖЕ ВОЗНИКЛА ПРОБЛЕМА - float в int  пережу, а как сделать обратно - int во float. Искал - не нашел.

А в чем проблема?

float f;
int i;
void setup(){
  f=i;
  i=f;
}

void loop(){}

Компилится без звука.

maksim
Offline
Зарегистрирован: 12.02.2012

 А вы уверены, что когда шарик слева ударив металлический стержень, то не отскочит обратно тем самым разомкнув вашу цепь? Или это как раз та самая волна отталкнет шарик слева при возвращении обратно?

maksim
Offline
Зарегистрирован: 12.02.2012

 В таком случае, что бы исключить дребезг, можно шарики подключить к разным выводам. Тогда при первом же касании ударяющего шарика запускается таймер, а при первом же отрыве вторго шарика останавливается.

leshak
Offline
Зарегистрирован: 29.09.2011

 

lev39 пишет:

Электрическая схема простая . Левый шарик висит на проволоке, соединенной с Pin 2. Правый шарик, тоже висящий на проволоке, соединен с GND Ардуино.

Ну наконецто выдали тайну :) В этом варианте у вас Pin2 ловит "помехи из эфира". Махнули рукой возле шарика - получили кучу импульсов.

Вам нужно поставить либо внешний подтягивающий резистор. Приверно как тут http://arduino.cc/en/Tutorial/Button (только там он к земле, а вам нужно к питанию). Либо воспользоватся встроенным в контроллер. Включить его можно раскоментировав строку которую Максим отметил как "// Подтягивающий резистор к +5V"

Только боюсь, в этой схеме "дребезг" для вас, все-таки, будет фатальным. Пока первые шар "четко прижмется к трубе" - он даст много импульсов. Которые по времени соразмеримы с времени проходения импульса по трубе. И отличить одни от других - не представляю как это возможно.

Мне кажется тут нужно менять схему и использовать два пины. Один для одного шара, другой для другого. Мерять их независимо. Вообщем "оба шара на пины" (второй и третий пин). Землю - на трубу.

Первый шар делать attachInterupt на FAILING, второй на RISING. Каждый обработчик ловит только "первое срабатывание". Все остальное игнорит - это дребезг. Разница между ними - ваше время прохождения.

leshak
Offline
Зарегистрирован: 29.09.2011

 В такм случае "буфферы" не нужны. Нам нужно ловить только "первое касание" и "первый отрыв". Тогда дребезг нас не будет волновать.

#define BALL_1_PIN 2 // первый шар на втором пине 
#define BALL_2_PIN 3 // второй шар на третем пине

volatile unsigned long time1=0; // время первого шара
volatile unsigned long time2=0; // время второго шара

void setup(){ 
  Serial.begin(57600); //ставим скорость повыше, что-бы Serial быстрее освобождал буфер
  digitalWrite(BALL_1_PIN, 1);  // Подтягивающий резистор к +5V для первого шара
  digitalWrite(BALL_2_PIN, 1);  // Подтягивающий резистор к +5V для второго  шара
  
  attachInterrupt(0, ball_1_handler, FALLING);  // для первого шара ловим прикосновение
  attachInterrupt(1, ball_2_handler, RISING);  // для второго "отрыв"
  

  Serial.println("Device ready"); // готовы мерять
}

void loop() {
  if(time1 && time2){ // оба шара зарегистрировали событие
  
    // выводим время и интервал
    Serial.print(time2,DEC); 
    Serial.print("-");    
    Serial.print(time1,DEC);
    Serial.print("=");    
    Serial.println(time2-time1,DEC);
    
    
    delay(5000); // даем шарам успокоется. 5 секунд
    // все сбросили опять готовы ловить собыитя.
    time1=0;
    time2=0;
     Serial.println("Device ready"); // опять готовы к подвигам
  }

}

void ball_1_handler (){
   if(time1==0){ // ловим только первое касание
     time1=micros();
   }

}

void ball_2_handler(){
  if(time1){ // пока первый шар не "тюкнул", на второй можно не смотреть
     if(time2==0){ // ловим только первый отрыв
      time2=micros();
     }
  }
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

 Не нужно использовать подтягивающие резисторы, так как подтяжка к 5 вольтам включена програмно. Просто соберите по этой схеме и все (НЕ ДОБАВЛЯЙТЕ НИЧЕГО В СХЕМУ):

Программа будет делать один замер, после чего нажимаете на дуине кнопочку "RESET" и можно делать следующий замер.

#define Pin1 2
#define Pin2 3

unsigned long micros_start, time = 0;

void setup() {
  Serial.begin(9600);
  digitalWrite(Pin1, 1);
  digitalWrite(Pin2, 1);   
  Serial.println("Distance: 1 m");
  
  while(digitalRead(Pin1));
  micros_start = micros();
  while(!digitalRead(Pin2));
  time = micros() - micros_start;
  unsigned long speed = 1000000.0/time;
  
  Serial.print("Time: ");
  Serial.print(time, DEC);
  Serial.println(" mcs");  
  Serial.print("Speed: ");
  Serial.print(speed, DEC);
  Serial.println(" m/c");
  Serial.println();
}

void loop() {
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

 Добавил вычисление скорости на длинну стержня в 1 метр.

lev39
Offline
Зарегистрирован: 14.08.2012

Спасибо. Попробую.

lev39
Offline
Зарегистрирован: 14.08.2012

Внешний подтягивающий резистор я всегда ставлю. Я уже писал про это. И то что еслт добавляю программно внутренний - ничего не меняется. По сути и не должно, потому что он насколько я понимаю соединяются паралллельно.

maksim
Offline
Зарегистрирован: 12.02.2012

maksim пишет:
НЕ ДОБАВЛЯЙТЕ НИЧЕГО В СХЕМУ

специально написал большими буквами, дабы вы не ставили подтягивающие резисторы, которые будут "тянуть" пин к земле! Можно подтягивать к +5 вольт, но НЕ НУЖНО.

И еще раз НЕ ДОБАВЛЯЙТЕ НИЧЕГО В СХЕМУ!!!

lev39
Offline
Зарегистрирован: 14.08.2012

Спасибо за схему. Хороший вариант.

Но что-то в скетче.

При нажатии первой кнопки сразу ВСЕГДА выдается - вторую кнопку не ждет и потом не реагирует на нее:

Distance : 1 m

Time : 8 mcs

Speed : 125000 m/c

lev39
Offline
Зарегистрирован: 14.08.2012

Скетч работает нормально. Только минимальное время, которое я засек 3024 мкс, т.е порядка 3 мс.

Эксперимент делал так. В гезда Pin 2 и 3 вставил иголки и очень быстро "ерзал" по ним проводом соединенным с землей. Иголки в гнездах находятся на расстоянии около 2 мм. Мне кажется что время измеренное дуиной завышено.

А так здорово. Ребята. Скоро  Вы научите меня программировать на Ардуино. Спасибо.

Осталось доделать чуть-чуть.

Если Вам интересно, то вот задачка попроще. На ось потенциометра насаживаем колесо. Потенциометр подключаем к земле, плюсу и средний контакт к аналоговому входу. Катим колесо по столу - напряжение подается на аналоговый вход от 0 до 5 В. map - преобразует напряжение  в расстояние ( максимум - длина окружности колеса - у меня 30 см). Во время движения колеса в программе берем первую и вторую производные от пути, пройденного колесом и в монитор выводятся значения пути, скорости и ускорения., причем скорость и ускорения со знаками проекций, т.е если тело движется вдоль оси ОХ, то проекция скорости положительна, а если против то отрицательна. А если тело движется равноускоренно вдоль оси Х то опроекция положительна, а если равнозамедленно, то отрицательна. При движении против оси знаки у ускорения будут противоположны.

У меня это все есть в железячном варианте. Дифференциаторы собраны на ОУ. На уроках это проходит здорово. Теперь я хочу все это выводить через видеопроектор на экран ( через Процессинг). Но программы пока нет.  Слабо подарить школьникам такую игрушку.

 

maksim
Offline
Зарегистрирован: 12.02.2012

lev39 пишет:

Спасибо за схему. Хороший вариант.

Но что-то в скетче.

При нажатии первой кнопки сразу ВСЕГДА выдается - вторую кнопку не ждет и потом не реагирует на нее:

Distance : 1 m

Time : 8 mcs

Speed : 125000 m/c

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

maksim
Offline
Зарегистрирован: 12.02.2012

lev39 пишет:

Скетч работает нормально. Только минимальное время, которое я засек 3024 мкс, т.е порядка 3 мс.

Эксперимент делал так. В гезда Pin 2 и 3 вставил иголки и очень быстро "ерзал" по ним проводом соединенным с землей. Иголки в гнездах находятся на расстоянии около 2 мм. Мне кажется что время измеренное дуиной завышено.

Ну неужели вы не понимаете, что ручками вы никогда не добьетесь таких скоростей...

maksim
Offline
Зарегистрирован: 12.02.2012

 А по поводу измерения скорости, ускорения и пройденного пути объекта могу посоверовать вам дальномер и тогда можно будет не колесо об стол крутить, а например, машинку катать.

lev39
Offline
Зарегистрирован: 14.08.2012

Да, пожалуй Вы правы. Сделал на кнопках - одна работает на замыкание,  а другая на размыкание.

Все получется. Только действительно ручками меньше 150 мс не получается.

Выйду на работу попробую с шарами.

Извините за беспокойство и определенную тупость.

Большое спасибо за помощь и терпение. Всего доброго.

 

maksim
Offline
Зарегистрирован: 12.02.2012

lev39 пишет:

Если Вам интересно, то вот задачка попроще. На ось потенциометра насаживаем колесо. Потенциометр подключаем к земле, плюсу и средний контакт к аналоговому входу. Катим колесо по столу - напряжение подается на аналоговый вход от 0 до 5 В. map - преобразует напряжение  в расстояние ( максимум - длина окружности колеса - у меня 30 см). Во время движения колеса в программе берем первую и вторую производные от пути, пройденного колесом и в монитор выводятся значения пути, скорости и ускорения., причем скорость и ускорения со знаками проекций, т.е если тело движется вдоль оси ОХ, то проекция скорости положительна, а если против то отрицательна. А если тело движется равноускоренно вдоль оси Х то опроекция положительна, а если равнозамедленно, то отрицательна. При движении против оси знаки у ускорения будут противоположны.

У меня это все есть в железячном варианте. Дифференциаторы собраны на ОУ. На уроках это проходит здорово. Теперь я хочу все это выводить через видеопроектор на экран ( через Процессинг). Но программы пока нет.  Слабо подарить школьникам такую игрушку.

Нет не слабо, как будете готовы к созданию сего девайса и все необходимые приспособления и материалы будут на руках заведите новую тему.

lev39
Offline
Зарегистрирован: 14.08.2012

Здравствуй Максим. Девайс есть. На мультиметре все работает. Хочу подключить выходы дифференциаторов к 1-му и 2-му аналоговым входам. А сам датчик расстояния подключен к 0-му входу. Я думаю все получится. Только будет проблема со знаками у проекции скорости и ускорения. Наверно придется отслеживать - когда координата увеличивается, то знак у проекции скорости +, а когда уменьшается, то -. А при выводе ускорения отслеживать изменение также скорости.

А вообще-то хотелось сделать программно. У меня есть дальномер Sharp. Вот к нему бы это пригодилось.

Хотел выложить схему в комментарий, а он требует URL. А инструкцию о том как разместить рисунок с ПК сюда я не нашел.

Внизу есть строчка "Подробнее о форматировании" но она выдает пустое окно. Если будет время, то подскажите где найти инструкцию по вводу в комментарий картинки.

Спасибо за участие. Всего доброго.

Л.В.

maksim
Offline
Зарегистрирован: 12.02.2012

lev39 пишет:

Хотел выложить схему в комментарий, а он требует URL. А инструкцию о том как разместить рисунок с ПК сюда я не нашел.

Прочитайте Сохранение картинок на форуме там написано как разместить рисунок с ПК.

 

maksim
Offline
Зарегистрирован: 12.02.2012

lev39 пишет:
У меня есть дальномер Sharp.

ИК дальномер SHARP 2Y0A02 ?

lev39
Offline
Зарегистрирован: 14.08.2012

 

Спасибо за совет. Оказывается все просто.

А дальномер такой как Вы написали. ИК дальномер SHARP 2Y0A02 F 11. Он выдает аналог 0-5 В. Так вот я думаю в Processing надо вствить код, который берет первую производную, а потом вторую - и на экране будут выводиться все три величины - координата, скорость и ускорение без всяких дополнительных железяк.

Код для вывода расстояния ( а не координаты ) я написал. С шрифтами порядок.

К аналоговым портам Ардуино подключаются провода идущие к вольтметрам. Первый вольтметр измеряет расстояние ( координату + и -), второй проекцию скорости, а третий проекцию ускорения, со знаками + и - как я писал.

Вот так это выглядит с вольметрами, а внизу схема.

maksim
Offline
Зарегистрирован: 12.02.2012

Все расчеты надо делать в дуине, а в процессинг отправлють только результаты.
Можно подробнее про расчеты?

lev39
Offline
Зарегистрирован: 14.08.2012

Ну с тремя напряжениями я думаю будет просто ( завтра попробую) и конечно все расчеты можно сделать в Ардуине. Но можно просто послать в процессинг три напряжения в условных единицах от 0 до 1023 ( разрядность АЦП). И там сделать расчеты. Я наверное так и сделаю.

Но  вообщето  я имел ввиду, что в процессинг подается только информация об одном  напряжении от 0 до 1023, несущим информацию только о расстояннии ( координате).

Например в  скетче для измерения растояния  от 0 до 30 см ( от колеса) функцией  map, преобразуется  диапазон 0...1023 преращает в 0-30 см. И в процессинге с помощью дифференцирования появится информация о скорости и ускорении.

Тогда можно отказаться от девайса, что мне и хочется.

 

 

maksim
Offline
Зарегистрирован: 12.02.2012

 Делая расчет в процессинге нет гарантий, что вы будете получать данные вовремя, (а скорее всего не будете получать их вовремя) именно поэтому нужно делать расчет в дуине.  Так как комп помимо получения с СОМ-порта данных занят еще много чем и данные будут буферизоваться и приходить не вовремя.