Управление авто спидометром Arduino

Roman89
Offline
Зарегистрирован: 30.03.2017

Здравствуйте.

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

Предистория такова, заменил на любимом авто (Jeep Cherokee) ДВС и КПП с бензинового на дизель. Вылезла проблема снять показания спидометра т.к. на предыдущем агрегате показания для спидометра считывались датчиком на эффекте холла, а на вновь установленной привод для торсикового спидометра. 

Вопрос в следующем.

Я установил датчик холла, подключил на мекетной плате к Arduino Nano спидометр.

Собрал из кусков кода на просторах интернета скетч для вывода показаний спидометра, положения селектора АКПП и тахометра на Oled диспей. Код для вывода показаний спидометра на дисплей такой:

#include "U8glib.h"
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NO_ACK);

unsigned long lastturn, time_press; //переменные хранения времени
float SPEED; //переменная хранения скорости в виде десятичной дроби
float w_length=2.050; //длина окружности колеса в метрах


void setup() {
 
  attachInterrupt(0,sens,RISING); //подключить прерывание на 2 пин при повышении сигнала

}

void sens() {
  if (millis()-lastturn > 80) {  //защита от случайных измерений (основано на том, что велосипед не будет ехать быстрее 120 кмч)
    SPEED=w_length/((float)(millis()-lastturn)/1000)*3.6;  //расчет скорости, км/ч
    lastturn=millis();  //запомнить время последнего оборота
  }
}

void loop() {
 

  u8g.firstPage();  
  do {
    u8g.setFont(u8g_font_unifont);
     u8g.setPrintPos(0, 20);
     u8g.print(SPEED);
  } while( u8g.nextPage() );
  
  // rebuild the picture after some delay
  delay(50);


  if ((millis()-lastturn)>2000){ //если сигнала нет больше 2 секунды
    SPEED=0;  //считаем что SPEED 0
  }

 
  
  }

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

выяснил при помощи данного кода:

// программа генератор 1 до 50 герц 
/*
  генератор сигнал -> 13
            земля  -> GND
   потенциметр верхн выв -> =5в
               сред выв  -> A0
             нижний выв  -> GND              
*/
const int out_pin=13;// нога генератора
const int analogInPin = A0;// нога потенциометра
int frequency = 1; // частота от 1 до 50

void non_stop_program1(uint16_t span) {
  static uint32_t future = 0;
  static uint8_t stat = 0;  
  if (millis()<future) return ;
  future += span;
  stat =!stat;
  digitalWrite(out_pin, stat);
}
void setup() {

  pinMode(out_pin, OUTPUT);
}
void loop() {
  frequency = map(analogRead(analogInPin), 0, 1023, 1, 170);
  non_stop_program1(500/frequency);
}

, что  при частоте 18 Гц показания спидометра равны 10 км/ч.

Далее не хватает мозгов, чтоб показания км/ч с цифрового дисплея, превести в понятные для стрелочного.

Буду признателен за подсказкку.

Alex_Sk
Offline
Зарегистрирован: 06.01.2015

Если 18Гц это 10км/ч то 360Гц-200км/ч край шкалы спидометра.

Настраиваете таймер на частоту скажем в 10 раз больше края шкалы - 278мкс и по каждому тику в прерывании вызываете функцию в которой подсчитывается число тиков обратно-пропорциональное скорости и по ним переключается выход к которому подключен спидометр.

Roman89
Offline
Зарегистрирован: 30.03.2017

Спасибо. Направление понятно.

Valerich-tex
Offline
Зарегистрирован: 10.08.2019

Ну как собрал спидометр для индейца? расскажи что сделал, как запустил, тоже есть необходимость для дизеля сделать одометр, только обратный, чтобы считал когда менять масло/расходники по пробегу

Roman89
Offline
Зарегистрирован: 30.03.2017

Собрал. Считывает обороты с ТНВД, скорость с РК, и положение селектора АКПП, ещё добавил сенсор окружающей t. Микросхему на которой собирал не помню, она с двумя входами для считывания импульсов с датчиков холла. Сейчас у меня РК отГаз 66, надо делать зубчатое колесо для датчика считывающего обороты кардана, на этом месте остановился. Я сейчас далеко от дома, буду к середине октября, могу точно сказать марку микросхемы и скинуть скетч.

Roman89
Offline
Зарегистрирован: 30.03.2017

После замены двигателя и трансмиссии на Jeep XJ на двигатель от Toyota и РК от Газ 66, потребовалось считывать обороты и скорость с датчиков отличных от джиповских, пришлось вмонтировать в панель приборов Jeep Oled дисплей управляемый контроллером Arduino. Как это работает видно на видео https://youtu.be/wujMAIK6Yr8 Для считывания оборотов двигателя с ТНВД и скорости пришлось сделать плату на микросхеме  MAX9924, на РК установил датчик с ABS для считывания оборотов с карданного вала. Но на карданный вал необходимо устанавливать зубчатый венец, вот на изготовлении зубчатого венца пока работа остановилась, импульсы с датчика скорости решил подать прямо на пин (он воспринимает 5V импульсы) стрелочного указателя скорости, требуется только правильно рассчитать количество зубьев на венце кардана. На данный момент реализованы: показания t-двигателя; t-воздуха за бортом; вывод положения селектора АКПП; вывод оборотов двигателя. В планах вывод положений РК и реализация показаний скорости стрелочным указателем.

Я не программист и Jeep это не основная машина, а больше хобби по этому проект затянулся. Если кто укажет на косяки в коде, буду признателен.

#include "U8glib.h"
#include "logo.h"
#include <OneWire.h>
#include <DallasTemperature.h>

//------------датчики температуры---------------
OneWire oneWire(12); // вход датчиков 18b20
DallasTemperature ds(&oneWire);

DeviceAddress sensor1 = {
  0x28, 0x7C, 0xA, 0xBB, 0x8, 0x0, 0x0, 0x66
};  // адрес сенсора t-двигателя
DeviceAddress sensor2 = {
  0x28, 0xB0, 0x3B, 0xBA, 0x8, 0x0, 0x0, 0x42
}; // адрес сенсора t-акпп

//-------------тип дисплея----------------------
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NO_ACK);	// Display which does not send ACK


//-------------для тахометра-------------------------
volatile float time = 0;
volatile float time_last = 0;
volatile int rpm_array[5] = {0, 0, 0, 0, 0};

void taho()
{
  time = (micros() - time_last);
  time_last = micros();
}



//------функция вывода положения селектора акпп-----------

void draw(void) {

  int s;  //A0
  s = analogRead(0);
  int x;
  int w;
  int draw_speed;
  char* gear[7] = {
    " 2DNRP", "L DNRP", "L2 NRP", "L2D RP", "L2DN P", "L2DNR ", "L2DNRP"
  };


  if (s > 890 && s < 990) //parking
  {
    x = 76;
    w = 15;
    draw_speed = 5;
  }
  else if (s > 750 && s < 850) //rear
  {
    x = 60;
    w = 16;
    draw_speed = 4;
  }
  else if (s > 610 && s < 710) //neutral
  {
    x = 46;
    w = 15;
    draw_speed = 3;
  }
  else if (s > 405 && s < 500) //drive
  {
    x = 30;
    w = 16;
    draw_speed = 2;
  }
  else if (s > 300 && s < 400) //2
  {
    x = 16;
    w = 14;
    draw_speed = 1;
  }
  else if (s > 90 && s < 190) //1
  {
    x = 1;
    w = 14;
    draw_speed = 0;
  }
  else {

    x = 128;
    draw_speed = 6;
  }
  u8g.setColorIndex(1);

  u8g.drawBox(x, 0, w, 21);
  u8g.setColorIndex(0);
  u8g.drawStr( 1, 18, "L2DNRP");
  u8g.setColorIndex(1);
  u8g.drawStr(1, 18, gear[draw_speed]);
}

//---------входы положений РК------------

int h = 8;  //d4 вход parking
int l = 9;  //d5 вход rear
int t = 6;  //d6 вход neutral
int f = 7;  //d7 вход drive

//---------функция вывода положений РК 2-4------------

void trtf(void) {


  if (digitalRead(t) == LOW)
  {
    u8g.drawStr( 95, 18, "2");
  }
  else if (digitalRead(f) == LOW)
  {
    u8g.drawStr( 95, 18, "4");
  }
}

void trhl(void) {


  if (digitalRead(l) == LOW)
  {
    u8g.drawStr( 110, 18, "L");
  }
  else if (digitalRead(h) == LOW)
  {
    u8g.drawStr( 110, 18, "H");
  }
  else {
    u8g.drawStr( 110, 18, "N");
  }
}


//--------------------------------------------------

void setup(void) {

  //---вывод логотипа джип при запуске-----
  u8g.firstPage();
  do {
    u8g.drawBitmapP( 0, 0, 16, 64, jeep_logo);
  }
  while ( u8g.nextPage() );
  delay(1500);

  //--------активируем пины подключения положений РК--------------------

  digitalWrite (h, HIGH);
  digitalWrite (l, HIGH);
  digitalWrite (t, HIGH);
  digitalWrite (f, HIGH);

  //--------активируем пин подключения сигнала акпп----------


  pinMode(A0, INPUT);

  //----------для считывания показаний тахометра
  attachInterrupt(0, taho, RISING); //подключить прерывание на 2 пин при повышении сигнала


  //--------начинаем работу с датчиками температуры-------
  ds.begin();


void loop(void) {

  int rpm = 0;

  //Update The RPM
  if (time > 0)
  {
    //5 Sample Moving Average To Smooth Out The Data
    rpm_array[0] = rpm_array[1];
    rpm_array[1] = rpm_array[2];
    rpm_array[2] = rpm_array[3];
    rpm_array[3] = rpm_array[4];
    rpm_array[4] = 60 * (1000000 / (time * 20));
    //Last 5 Average RPM Counts Eqauls....
    rpm = (rpm_array[0] + rpm_array[1] + rpm_array[2] + rpm_array[3] + rpm_array[4]) / 5;


  }

  if ((micros() - time_last) > 1000000) //если сигнала нет больше секунды то RPM = 0
  {
    rpm = 0;

  }




  ds.requestTemperatures(); // считываем температуру с датчиков

  //------------работа с дисплеем---------------------

  u8g.firstPage();
  do {

    //-----чертим границы вывода-------------
    u8g.setColorIndex(1);
    u8g.drawFrame(0, 0, 128, 64);
    u8g.drawHLine(1, 20, 126);
    u8g.drawHLine(1, 41, 126);
    u8g.drawVLine(91, 1, 19);
    u8g.drawVLine(76, 21, 20);
    u8g.drawVLine(63, 42, 21);


    //------вывод пиктограмм на дисплей-------------
    u8g.drawXBMP( 59, 22, 16, 18, logo_rpm);
    u8g.drawXBMP( 109, 22, 16, 18, logo_km_h);
    u8g.drawXBMP( 2, 45, 16, 16, logo_t_ing);
    u8g.drawXBMP( 65, 45, 16, 16, logo_t_out);

    //--------вывод информации с датчиков-------------

    u8g.setFont(u8g_font_courB18);  // задаём шрифт

    u8g.setPrintPos(2, 39); //вывод оборотов на дисплей
    u8g.print(rpm / 28);



    //------вывод температуры на дисплей------------------------

    u8g.setPrintPos(19, 60);  //положение t-двигателя
    //u8g.print("-88");
    //u8g.print(ds.getTempC(sensor1),0); // отправляем T-двигателя на дисплей
    u8g.setPrintPos(83, 60);   //положение t-акпп
    //u8g.print("-88");
    u8g.print(ds.getTempC(sensor2), 0); // отправляем T- за бортом на дисплей

    draw(); //выводим положения селектора акпп



    //-----будет вывод положений рк---------------
    //trtf();
    //trhl();
  }
  while ( u8g.nextPage() );
}

 

Valerich-tex
Offline
Зарегистрирован: 10.08.2019

Roman89 пишет:

Для считывания оборотов двигателя с ТНВД и скорости пришлось сделать плату на микросхеме  MAX9924

Интересно)

Roman89 пишет:

на РК установил датчик с ABS для считывания оборотов с карданного вала.

А что , абс датчик (Индейский) дайет 5в? я не пробовал с ним ничего вообще

Roman89 пишет:

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

почему бы просто не проточить в нужном месте кардан, нарезать шлицевую? хотя он в движении (вперед, взад, вверх, вниз) постоянно и показания на скорости и в горной местности будут брехать

Roman89 пишет:

импульсы с датчика скорости решил подать прямо на пин (он воспринимает 5V импульсы) стрелочного указателя скорости

Так и не понял от куда взял импульсы?  

Roman89 пишет:

Я не программист и Jeep это не основная машина, а больше хобби по этому проект затянулся. Если кто укажет на косяки в коде, буду признателен.

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

Roman89
Offline
Зарегистрирован: 30.03.2017

Микросхема MAX9924 преобразует синусоидальные импульсы от датчиков холла (датчиков ABS и ТНВД) с выходом 0,3-0,5В в прямоугольные импульсы 5В понятные микроконтроллеру.

Про установку на кардан не правильно выразился, на флянец карданного вала. Импульсы с установленного датчика ABS (в моём случае это уже датчик скорости) на флянце кардана, поступают на микросхему MAX9924 и уже усиленный сигнал можно подавать на стрелочный указатель скорости Jeep минуя микроконтроллер, но при этом надо рассчитать количество импульсов (зубцов на венце) для правильного отображения скорости.

Думаю установить на флянец кардана венец с колеса который даёт импульсы датчику ABS, но требуются токарные работы, а руки пока не дошли до этого.

С оригинальным Джиповским датчиком скорости не имел дела. Надо смотреть не сколько вольт подаётся на питание, а смотреть осцилографом импульсы которые он выдаёт на бортовой компьютер, возможно ли их использовать для считывания микроконтроллером. Если у вас машина с ABS можно попробовать подключиться параллельно к датчику ABS и преобразованный MAX9924 подавать на микроконтроллер, но в этом случае надо смотреть, чтоб не было влияния на работу самой системы ABS.

 

Valerich-tex
Offline
Зарегистрирован: 10.08.2019

Почему бы тогда вам не расчитать сколько импульсов на метр и не вывести на этом свою схему расчета. ну или проехать со скоростью 10 км/ч (с gps) и 50км/ч и посмотреть сколько импульсов на какой скорости выдает, затем вывести таблицу и приказать  сравнивать дуинке показания с таблицей и выводить уже готовые показания на монитор. 

ну я как закуплюсь электроникой, тогда уже пробовать, сейчас тоже все только в теории да на словах

b707
Offline
Зарегистрирован: 26.05.2017

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

Roman89
Offline
Зарегистрирован: 30.03.2017

To b707: 

В начале, думал так как Вы, установив датчик холла на вращающуюся "фигню", но для того чтоб выдать корректное число импульсов для стрелочного указателя от переходника и нужен был микроконтроллер, т.к. переходники заточены под определённые марки машин и выдают некорректное для моего указателя число импульсов. Но решил не городить "фигню", т.к. вращающийся флянец на РК уже есть, датчик холла от ABS гораздо надежней чем всякие копеечные переходники и необходимость в МК отпадает сама собой. Но без электроники не обойтись, датчик холла от ABS выдаёт синус с амплитудой 0,3-0,5В, а для указателя нужен прямоугольный сигнал, можно конечно установить активный датчик холла с 5В импульсами, тогда электроника не потребуется. Осталось реализовать все механические части.

To Valerich-tex:

Примерное число импульсов рассчитывается исходя из диаметра колеса и передаточного числа главной пары, а подкорректирую уже при помощи GPS, просто реализация пока остановилась.