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;