Давай!!!!
А я вот так меряю скорость и расстояние :
PHP код:
const int DsaPin = 8;
int DsaPulseCounter = 0;
int DsaState = 0;
int LastDsaState = 0;
int meters;
unsigned long pulseTime = 0;
unsigned long thisTime = 0;
unsigned long lastTime = 0;
unsigned long mySpeed = 0;
void setup()
{
pinMode(DsaPin, INPUT);
Serial.begin(9600);
}
void loop()
{
odometer();
}
void odometer()
{
DsaState = digitalRead(DsaPin);
if (DsaState != LastDsaState)
{
if (DsaState == HIGH)
{
lastTime = thisTime;
thisTime = micros();
pulseTime = thisTime - lastTime;
int mySpeed = (3600000000/pulseTime*15)/100000;
DsaPulseCounter++;
meters = DsaPulseCounter/6.66;
Serial.println(meters, DEC);
Serial.println(mySpeed);
}
}
LastDsaState = DsaState;
}
Liliput 629 GL, Intel Atom N230 1.6, HDD 200 GB, ОЗУ 2GB, Globalsat GT-100.
Хоть и старая тема, но всё равно отпишусь
По-моему проще и надежней всего сделать так:
для одновременной реализации спидометра и одометра (первый - как следствие второго) нужно 3-4 переменных, задействовать одно внешнее прерывание и еще 3 переменных для формирования простых отрезков времени:
или если без одометра (т.е. не сохранять/извлекать из eeprom), то чуть проще:PHP код:
unsigned long cur_ms = 0; //переменная для отслеживания натикавших миллисекунд с момента пуска МК
unsigned long prev_ms = 0; //переменная для вычисления отрезков времени
int ms = 0; //сам отрезок времени
unsigned long m; //одометр, значение, по-идее, считывается из EEPROM при включении и потом туда же записывается при выключении МК
unsigned long m_temp = 0; //переменная для вычисления пройденного пути за отрезок времени
int speed = 0; //переменная для хранения скорости
void setup() {
pinMode(20, INPUT);
digitalWrite(20, HIGH);
attachInterrupt(3, odom, RISING);
}
void odom() {
m++;
}
void loop() {
cur_ms = millis(); //сколько прошло мс с момента включения
ms = cur_ms - prev_ms; //сколько прошло мс с последнего срабатывания расчета
if (ms > 500) {
prev_ms = cur_ms; //ставим метку когда было срабатывание
speed = (m - m_temp) * 3600 / ms; //вычисляем скорость км в час по кол-ву пройденных метров за отрезок времени ms
m_temp = m; //ставим метку когда было вычисление
ms=0; //обнуляем отрезок времени
}
}
Множитель при вычислении скорости подбираем под свою "систему".PHP код:
unsigned long cur_ms = 0; //переменная для отслеживания натикавших миллисекунд с момента пуска МК
unsigned long prev_ms = 0; //переменная для вычисления отрезков времени
int ms = 0; //сам отрезок времени
int m = 0; //пройденное расстояние
int speed = 0; //переменная для хранения скорости
void setup() {
pinMode(20, INPUT); //включаем 20й порт на Ардуино Мега2560 на чтение
digitalWrite(20, HIGH); //включаем подтягивающий резистор
attachInterrupt(3, odom, RISING); //включаем внешнее прерывание
}
void odom() {
m++; //добавляем 1 при каждом срабатывании
}
void loop() {
cur_ms = millis(); //сколько прошло мс с момента включения
ms = cur_ms - prev_ms; //сколько прошло мс с последнего расчета
if (ms > 500) {
prev_ms = cur_ms; //ставим метку когда было срабатывание
speed = m * 3600 / ms; //вычисляем скорость км в час по кол-ву пройденных метров за отрезок времени ms
m = 0; //обнуляем пройденное расстояние
ms=0; //обнуляем отрезок времени
}
}
Если учесть, что на каждые 1,5 метра приходится примерно 5 срабатываний, а точность на скорости ниже 20км/ч не важна, то отрезки можно делать по 500мс и будет достаточно.
На 54км/ч, т.е. 15м/с - это 50 срабатываний в секунду. А при отрезке 500мс - 25 срабатываний. Т.е. может произойти 24-25 срабатываний (отклонение всегда в меньшую сторону, если нет дребезга) и погрешность будет -2,16..0 км/ч. С увеличением скорости точность увеличивается.
С учетом того, что редкий зверь разгоняется за 5с до сотни, грубо говоря за 0,5с можно добавить не более 10км/ч (а большинство машин и 5км/ч вряд-ли добавят).
ЗЫ: а можно включить прерывание по изменению ( attachInterrupt(3, odom, CHANGE); ) и тогда точность будет в 2 раза выше
Последний раз редактировалось melvladimir; 20.10.2013 в 21:05.
Код спидометра для 6-ти импульсного датчика скорости. 2 две переменные
PHP код:
unsigned long micros_sp = 0;
volatile int sp;
void setup(){
attachInterrupt(0, speedometr, RISING);
}
void loop(){
............................
............................
}
void speedometr(){
sp = (600000.0 / (micros() - micros_sp)); //600000.0 - 6 имп./м 1000000.0 - 10 имп./м и т.д
micros_sp = micros();
}
Последний раз редактировалось Frud; 24.10.2013 в 14:29.
А че ее рисовать? На второй цифровой пин подаешь сигнал датчика, ограничив амплитуду сигнала до 4,5 В делителем или оптопарой и притянув вход к земле. Этот код работает с датчиками у которых прямоугольный сигнал, и частота сигнала соотносится со скоростью.
Последний раз редактировалось Frud; 24.10.2013 в 17:08.
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)