Re: Датчик холла 12В использование с ардуино
	
	
		Chip
Я сегодня замерил с помощью старой программы и методом подбора выяснил, что сигнал на комбинации приборов, от которого я пляшу, имеет 24 импульса на 1 оборот колеса - видимо это после преобразования контроллера или датчик такой...или передаточное число в КПП.
В результате получил вполне приемлемые данные, соответствующие показанию спидометра.
Единственно бывает, что скорость отличается на 3-4 км между соседними срабатываниями таймера, например 39 и 36, на самом деле скорость ~40. Выбивание из ряда объясняю тем, что граничные импульсы попали в соседнее срабатывание таймера.
В принципе код вполне устраивает
	Код:
	
#include <MsTimer2.h>
int ledPin = 13; // контакт для светодиода
int switchPin = 30; // контакт для кнопки
int RelayPin = 14; // Контакт для реле
int HallPin = 3; // Контакт для датчика холла
int SpeakerPin=8; // Контакт для динамика
boolean RelayOn = false;
unsigned long speedtime = 0; 
int count = 0; 
unsigned long time; 
float lkolesa;
float Speed;
float  TimerInterval=500;
void setup() 
{
Serial.begin(115200);
pinMode(SpeakerPin, OUTPUT); // для динамика
pinMode(ledPin, OUTPUT); // для светодиода
pinMode(switchPin, INPUT); //  для кнопки
pinMode(RelayPin, OUTPUT); // для реле
pinMode(HallPin, INPUT); // датчик холла
digitalWrite(HallPin, HIGH); //внутренняя подтяжка входа датчика холла
  attachInterrupt(1, int_on, RISING);
MsTimer2::set(TimerInterval, flash); // таймер будет срабатывать через каждые 500ms 
MsTimer2::start();//запустить таймер
 
}
void loop()
{
}
void  int_on() 
{ 
count++; //увеличить счетчик
}  
void flash() //обработка прерывания таймера
{
lkolesa=0.686;
Speed=lkolesa*count*(2400/TimerInterval);
Serial.flush(); 
Serial.println(count);
Serial.println(Speed); 
count=0;
}
 Также проверил и более старый код:
	Код:
	
void  int_on() 
{ 
count++; //увеличить счетчик volatile
if (count >=24)
  {
speedtime = micros()-time;  //время прихода 6-ти импульсов
time = micros(); //обнулить
lkolesa=0.686;
Speed=((lkolesa*3600000*4)/speedtime);
Serial.println(speedtime);
Serial.println(Speed); 
 count = 0;
  }
 он выдает более точные данные, но реже, только после получения 24 импульсов...
Над твоим новым кодом думаю... учитывая мои 24 импульса.
	Код:
	
void  int_on() 
{ 
  delta=3030*(micros()-micross);// тут 1 имульс и время за которое он произошел
  micross = micros(); //обнулить
}
 Мне кажется по одному импульсу судить нельзя, не точно получится
У меня выше тоже самое, но за 24 импульса, возможно стоит за 4 или 6 импульсов судить о скорости
	 
	
	
	
		Re: Датчик холла 12В использование с ардуино
	
	
		
	Цитата:
	
		
		
			Мне кажется по одному импульсу судить нельзя, не точно получится
			
		
	
 Можно и по одному импульсу рассчитывать
	 
	
	
	
		Re: Датчик холла 12В использование с ардуино
	
	
		Кажись я ошибся, не 24 импульса, а все-таки 6... или 8
Я забыл умножить диаметр=0,686 на число пи.
Кстати, почему-то везде пишут, что 6 импульсов не на оборот колеса, а на 1 м пробега - хотя наверное для какого-то колеса оно так и есть - 1м пробега соответствует одному обороту, но только не моему - 1 об. = 2,15м
	 
	
	
	
		Re: Датчик холла 12В использование с ардуино
	
	
		Считаем так;
Колесный диск и/или посадочный размер шины обычно имеет размер в дюймах, например для расчета возьмем 15 дюймов.
Дюймы переводим в миллиметры, т.е. умножаем на 25,4 (1 дюйм = 25,4 мм). Д=D*25,4
Размерность шины обычно указывается двумя числами через косую черту, например, 185/70 или 195/60.
Первый параметр - это ширина протектора шины в мм. 
Второй параметр определяет высоту профиля шины относительно ширины (в процентах), т.е. "70% от 185мм" или "60% от 195мм".
Т.е. чтобы узнать высоту профиля шины надо первый параметр шины (ширину шины в мм) умножить на второй параметр шины (проценты) и разделить на 100.
П=W*H/100
Высота колеса в сборе - это диаметр диска (он же посадочный диаметр шины) плюс две высоты профиля шины (если внимательно посмотреть на колесо, то очевидно, что шина есть и сверху и снизу диска).
В=Д+2*П=D*25,4+2*W*H/100
результат получается в мм (т.к. обычно сантиметрами меряются портные, а инженеры - мм :-).
Пример:
195/65 R15
(15*25,4+2*195*65/100)*3,14=1993мм пробег колеса за один оборот
	 
	
	
	
		Re: Датчик холла 12В использование с ардуино
	
	
		Выяснил окончательно, у нас движок и коробка японские и датчик японский: 2500 импульсов на километр, 2.5 импульса на метр.
Посему код выглядит так:
	Код:
	
void  int_on() 
{ 
count++; //увеличить счетчик volatile
if (count >=2) //ждем 2 импульса  - 2имп=0,8м
  {
speedtime = micros()-time;  //время прихода 2 импульсов
time = micros(); //обнулить
Speed=((0.8*3600000)/speedtime); //перевод в км/ч
Serial.println(speedtime);
   Serial.println(Speed); 
 count = 0;
  }  
}
 Единственный ньюанс:
Значение micros() переполняется и сбрасывается на ноль, приблизительно через 70 минут.
То есть после часа поездки, произойдет сбой или это программно обработать придется...
	 
	
	
	
		Re: Датчик холла 12В использование с ардуино
	
	
		Если пугает что один замер проскочит сбойный , то можно следить за переполнением или делать два замера и сравнивать между собой с допуском (+)(-)
можно использовать таймер счетчик и после каждого замера обнулять его
	 
	
	
	
		Re: Датчик холла 12В использование с ардуино
	
	
		Хочу подобрать замену датчику что в первом посту http://www.compcar.ru/forum/showpost...16&postcount=1
с учетом цитаты
	Цитата:
	
		
		
			
				Сообщение от 
Chip
				 
			Это датчик с открытым коллектором, подключи сопротивление 10к на вых. и на +12в
Если сопротивление повесить на Выход датчика и на +5в то ни какого делителя не понадобится
			
		
	 
 Какой выбрать http://www.newic.ru/catalog/sensors/magnetic/hall/
NPN нормально открытый 
или
PNP нормально открытый
и являются ли они датчиками с отрытым коллектором?
Ну грубо говоря смогу я подключить их также к первый?
	 
	
	
	
		Re: Датчик холла 12В использование с ардуино
	
	
	
	
	
		Re: Датчик холла 12В использование с ардуино
	
	
		
	PHP код:
	
void  int_on() 
{ 
count++; //увеличить счетчик volatile
if (count >=2) //ждем 2 импульса  - 2имп=0,8м
  {
speedtime = micros()-time;  //время прихода 2 импульсов
time = micros(); //обнулить
Speed=((0.8*3600000)/speedtime); //перевод в км/ч
Serial.println(speedtime);
   Serial.println(Speed); 
 count = 0;
  }  
} 
 При скорости 5 км/ч., ты два импульса, целую вечность будешь ждать!!!
Надо один импульс мерить (и то долго)!
С диаметром колеса тоже не к чему заморачиваться, я взял скорость с GPS и корректировал числитель (650000).
Убери лишнее вычисление Speed=((0.8*3600000)/speedtime);  0.8*3600000 = 2880000.
Получится  Speed = (2880000 / speedtime);
И всю дьявольщину (Serial.println(speedtime);  Serial.println(Speed); ) тоже убери из прерывания ))))))))))))
	PHP код:
	
/////////////// СПИДОМЕТР//////////////////////////////////////
    dinaimpulsov = pulseIn(3, HIGH, 100000);  // Считывание длительности 
    ValSpCurr = (650000 / dinaimpulsov); // Перевод в км/ч
  if (dinaimpulsov > 120000 || ValSpCurr > 350)
  {
    ValSpCurr = 0;
  } 
  if (ValSpCurr > peakspeed) //pikspeed
  {  
    peakspeed = ValSpCurr; 
 И функция pulseIn(); не очень подходит для этих целей, при низкой скорости авто она всю программу тормозит, пока ждёт конца импульса.
Сделал на прерывании.
	PHP код:
	
void  int_on() 
   { 
      spidometr = micros()-time;  //время прихода  импульсa
      time = micros(); //обнулить
      ValSpCurr = (1450000 / spidometr);
    }
 } 
 А чтоб не было вот этого: (я с этим тоже столкнулся)
	Цитата:
	
		
		
			Единственно бывает, что скорость отличается на 3-4 км между соседними срабатываниями таймера, например 39 и 36, на самом деле скорость ~40
			
		
	
 Я думаю надо при скорости свыше 20 км/ч. , брать три-четыре последних значения и выводить среднее арифметическое, тогда наверно не будет разброса.
Сейчас проверить не могу, по причине поломки авто...
А на столе всё круто работает))))))
Вабще со скоростью запара, с оборотами всё проще гораздо))))))))
	PHP код:
	
void loop() 
//////////////////////////ТАХОМЕТР///////////////////////////////////////
{
if (taxometr > 6000)
{
 taxo = (80000000 / taxometr);
}
else 
{
  taxo = 0;
}  
if (taxo > peakrpm) //pikrpm
  {  
    peakrpm = taxo;
  }
void  int_on() 
{ 
count++; //увеличить счетчик volatile
if (count >= 4)
    {
      taxometr = micros()-time;  //время прихода 4-ти импульсов
      time = micros(); //обнулить
      count = 0;
    }  
} 
 
	 
	
	
	
		Re: Датчик холла 12В использование с ардуино
	
	
		Все это не правильно, нужно измерять в фоновом режиме и что бы измерения не зависели от выполняемого кода. В примере на выходе показывает частоту в Гц, минимально измеряемая частота 4Гц
Вот пример :
	Код:
	
#include <util/delay.h>  
volatile unsigned int tachBuf;  
unsigned long tachValue;  
ISR(TIMER1_CAPT_vect)  
{   
    TCNT1 = 0;    
    tachBuf = ICR1+2;  
}  
//********************************************************************  
void setup()      
{    
   pinMode(8, INPUT);  //Вход для импульсов тахометра  
   pinMode(6, OUTPUT);//выход ШИМ  
   TCCR0B = TCCR0B & 0b11111000 | 5;//частота ШИМ. Для проверки тахометра
   analogWrite(6, 128);  //Запустить ШИМ  
   digitalWrite(8, HIGH); // включить подтяжку входа  
   Serial.begin(115200);  
   TIM_Init();//инициализация таймера  
  _delay_ms(300);  
}    
//********************************************************************  
void loop()      
{  
  cli();    
  tachValue =250000/tachBuf;  
  Serial.print("freq=");  
  Serial.println(tachValue,DEC);  
  tachBuf=1;  
  sei();  
  _delay_ms(300);  
}     
//********************************************************************  
void TIM_Init(void)  
{  
   TIMSK1=(1<<ICIE1);   
   TCCR1A=(0<<COM1A1)|(0<<COM1A0)|(0<<WGM11)|(0<<WGM10);    
   TCCR1B=(1<<ICNC1)|(1<<ICES1)|(0<<WGM13)|(0<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10);  
   TCNT1 = 0;