Велоспидометр

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

jeka_tm ,   извини за вопрос , влез неправомерно конечно....

//==================================================================
//   
//==================================================================
void vivod(int n)
{
  if((n!=1)&&(n!=4))digitalWrite(sim_A,1);                     // сегмент A
  else digitalWrite(sim_A,0);
  if((n!=5)&&(n!=6))digitalWrite(sim_B,1);                     // сегмент B
  else digitalWrite(sim_B,0);
  if(n!=2)digitalWrite(sim_C,1);                               // сегмент C
  else digitalWrite(sim_C,0);
  if((n!=1)&&(n!=4)&&(n!=7))digitalWrite(sim_D,1);             // сегмент D
  else digitalWrite(sim_D,0);
  if((n==0)||(n==2)||(n==6)||(n==8))digitalWrite(sim_E,1);     // сегмент E
  else digitalWrite(sim_E,0);
  if((n!=1)&&(n!=2)&&(n!=3)&&(n!=7))digitalWrite(sim_F,1);     // сегмент F
  else digitalWrite(sim_F,0);
  if((n!=0)&&(n!=1)&&(n!=7))digitalWrite(sim_G,1);             // сегмент G
  else digitalWrite(sim_G,0);
}
//==================================================================

это знакогенератор ? башка от t не варит почти :(

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

спасибо ! норм код ! :)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

можно на сдвигах переписать, а выводы в массиве прописывать. но разницы не будет особо. чуть быстрее, но тоже самое

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

SU-27-16 пишет:

там нет ДХ , два провода = питалово , кулер с ДХ - три проводка !

Ага, конечно нет, там наверное коллектор с щетками стоит...

next-999
Offline
Зарегистрирован: 30.09.2013

maksim пишет:

SU-27-16 пишет:

там нет ДХ , два провода = питалово , кулер с ДХ - три проводка !

Ага, конечно нет, там наверное коллектор с щетками стоит...

 

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

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

не боевой , пока вывод в Сериал , кот индикатор куда-то утащил ( раньше за 328 в DIP надо было глаз да глаз ).....
на входе с другой ардуины отрицательные импулься - LOW=10 , HIGH=156 mS ( пероид 166 mS   >>>>>   45 km/h )
340 mS   >>>>>   22 km/h

#define pinSegA  4 
#define pinSegB  5 
#define pinSegC  6 
#define pinSegD  7 
#define pinSegE  8 
#define pinSegF  9 
#define pinSegG  10 
#define pinSegH  11
#define pinDig1  12 
#define pinDig2  13
#define pinDH    2         // пин датчика Холла
                           // сигнал с датчика Холла   ->   ----_-----------_-----------_-----------_-----------_-----------_----
#define lengthWheel  2075  // длина окружности колеса по резине , mm
volatile byte flag = 0;
unsigned long oldMicros;
unsigned long time = 0;
float speedVelo = 0;
byte decimalDot = 0;       // индикация десятичной точки , сегмент H
//==================================================================
//   обработчик прерывания "0"
//==================================================================
void StartMeasurement()
{
  if( ! flag ) { oldMicros = micros(); }
  else         { time = micros() - oldMicros; }
  flag = ! flag;
}
//==================================================================
//   установки
//==================================================================
void setup()
{
  pinMode( pinSegA, OUTPUT );
  pinMode( pinSegB, OUTPUT );
  pinMode( pinSegC, OUTPUT );
  pinMode( pinSegD, OUTPUT );
  pinMode( pinSegE, OUTPUT );
  pinMode( pinSegF, OUTPUT );
  pinMode( pinSegG, OUTPUT );
  pinMode( pinSegH, OUTPUT );
  pinMode( pinDig1, OUTPUT );
  pinMode( pinDig2, OUTPUT );
  pinMode( pinDH, INPUT );
  digitalWrite( pinDH, HIGH );
  attachInterrupt( 0, StartMeasurement, FALLING );   // прерывание по спадающему фронту на pinDH
  Serial.begin( 9600 );
}
//==================================================================
//   основная
//==================================================================
void loop()
{
  byte dig3 = 0;
  byte dig2 = 0;
  byte dig1 = 0;
  float speedVeloTemp = 0;
  speedVelo = 36000.0 * lengthWheel / time;
  dig3 = speedVelo / 100;
  speedVeloTemp = speedVelo - dig3 * 100;
  dig2 = speedVeloTemp / 10;
  speedVeloTemp = speedVeloTemp - dig2 * 10;
  dig1 = ( byte ) speedVeloTemp % 10;
Serial.println( speedVelo );
Serial.print( dig3 );
Serial.print( dig2 );
Serial.println( dig1 );
  if( speedVelo > 9.9 )              // индикация "27." - 27 км/ч
  {
    if( dig1 >= 5 ) dig2++;
    OutSevSegmentLED( dig3 );
    digitalWrite( pinDig2, 0 );
    delay(5);
    digitalWrite( pinDig2, 1 );
    OutSevSegmentLED( dig2 );
    decimalDot = 1;
    digitalWrite( pinDig1, 0);
    delay(5);
    digitalWrite( pinDig1, 1);
    decimalDot = 0;
Serial.print( dig3 );
Serial.println( dig2 );
  }
  else
  {
    OutSevSegmentLED( dig2 );        // индикация "2.7" - 2,7 км/ч
    decimalDot = 1;
    digitalWrite( pinDig2, 0 );
    delay(5);
    digitalWrite( pinDig2, 1 );
    decimalDot = 0;
    OutSevSegmentLED( dig1 );
    digitalWrite( pinDig1, 0);
    delay(5);
    digitalWrite( pinDig1, 1);
Serial.print( dig2 );
Serial.println( dig1 );
  }
}
//==================================================================
//   знакогенератор
//==================================================================
void OutSevSegmentLED( byte _n )
{
  if( ( _n != 1 ) && ( _n != 4 ) ) digitalWrite( pinSegA, 1 );                               // сегмент A
  else digitalWrite( pinSegA, 0 );
  if( ( _n != 5 ) && ( _n != 6 ) ) digitalWrite( pinSegB, 1 );                               // сегмент B
  else digitalWrite( pinSegB, 0 );
  if( _n != 2 ) digitalWrite( pinSegC, 1 );                                                  // сегмент C
  else digitalWrite( pinSegC, 0 );
  if( ( _n != 1 ) && ( _n != 4 ) && ( _n != 7 ) ) digitalWrite( pinSegD, 1 );                // сегмент D
  else digitalWrite( pinSegD, 0 );
  if( ( _n == 0 ) || ( _n == 2 ) || ( _n == 6 ) || ( _n == 8 ) ) digitalWrite( pinSegE, 1 ); // сегмент E
  else digitalWrite( pinSegE, 0 );
  if( ( _n != 1 ) && ( _n != 2 ) && ( _n != 3 ) && ( _n != 7 ) ) digitalWrite( pinSegF, 1 ); // сегмент F
  else digitalWrite( pinSegF, 0 );
  if( ( _n != 0 ) && ( _n != 1 ) && ( _n != 7 ) ) digitalWrite( pinSegG, 1 );                // сегмент G
  else digitalWrite( pinSegG, 0 );
  if( decimalDot ) digitalWrite( pinSegH, 1 );                                               // сегмент H
  else digitalWrite( pinSegH, 0 );
}
//==================================================================

в ветке if( speedVelo > 9.9 ) .... else - косяк :( 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

за датчик Холла работает ардуина мини

#define pinOutGenerator 13
int timeHIGH = 0;
byte timeLOW = 10;
//==================================================================
//
//==================================================================
void setup()
{
  Serial.begin( 9600 );
  pinMode( pinOutGenerator, OUTPUT );
  digitalWrite( pinOutGenerator, HIGH );
}
//==================================================================
//
//==================================================================
void loop()
{
  for( timeHIGH = 1500; timeHIGH > 74; timeHIGH = timeHIGH - 50 )
  {
    for( byte n = 0; n < 10; n++ )
    {
      delay( timeHIGH );
      digitalWrite( pinOutGenerator, LOW );
      delay( timeLOW );
      digitalWrite( pinOutGenerator, HIGH );
      Serial.println( n );
      Serial.println( timeHIGH );
    }
  }
}
//==================================================================

основной код на ардуине уно ( без индикатора )


#define pinSegA  4 
#define pinSegB  5 
#define pinSegC  6 
#define pinSegD  7 
#define pinSegE  8 
#define pinSegF  9 
#define pinSegG  10 
#define pinSegH  11
#define pinDig1  12 
#define pinDig2  13
#define pinDH    2         // пин датчика Холла
                           // сигнал с датчика Холла   ->   ----_-----------_-----------_-----------_-----------_-----------_----
#define lengthWheel  2075  // длина окружности колеса по резине , mm
volatile byte flag = 0;
volatile unsigned long oldMicros;
volatile unsigned long time = 0;
//==================================================================
//   обработчик прерывания "0"
//==================================================================
void StartMeasurement()
{
  if( ! flag ) { oldMicros = micros(); }
  else         { time = micros() - oldMicros; }
  flag = ! flag;
}
//==================================================================
//   SETUP
//==================================================================
void setup()
{
  pinMode( pinSegA, OUTPUT );
  pinMode( pinSegB, OUTPUT );
  pinMode( pinSegC, OUTPUT );
  pinMode( pinSegD, OUTPUT );
  pinMode( pinSegE, OUTPUT );
  pinMode( pinSegF, OUTPUT );
  pinMode( pinSegG, OUTPUT );
  pinMode( pinSegH, OUTPUT );
  pinMode( pinDig1, OUTPUT );
  pinMode( pinDig2, OUTPUT );
  pinMode( pinDH, INPUT );
  digitalWrite( pinDH, HIGH );
  attachInterrupt( 0, StartMeasurement, FALLING );   // прерывание по спадающему фронту на pinDH
  Serial.begin( 9600 );
}
//==================================================================
//   LOOP
//==================================================================
void loop()
{
  byte dig3 = 0;
  byte dig2A = 0;
  byte dig2 = 0;
  byte dig1 = 0;
  float speedVelo = 0;
  float speedVeloTemp = 0;
  speedVelo = 36000.0 * lengthWheel / time;
  dig3 = speedVelo / 100;
  speedVeloTemp = speedVelo - dig3 * 100;
  dig2 = speedVeloTemp / 10;
  speedVeloTemp = speedVeloTemp - dig2 * 10;
  dig1 = ( byte ) speedVeloTemp % 10;
  if( dig1 >= 5 )
  {
    dig2A = dig2 + 1;
  }
  else
  {
    dig2A = dig2;
  }  
Serial.println( "==================================" );  
Serial.println( speedVelo );
Serial.print( dig3 ); Serial.print( " " );
Serial.print( dig2A ); Serial.print( " " );
Serial.print( dig2 ); Serial.print( " " );
Serial.println( dig1 ); Serial.print( " " );
Serial.println( "==================================" );
  if( dig3 != 0 )                      // индикация "27." - 27 км/ч
  {
    OutSevSegmentLED( dig3, 0 );
    OutDig2LED();
    OutSevSegmentLED( dig2A, 1 );
    OutDig1LED();
Serial.print( " We observe the indicator = " );
Serial.print( dig3 );
Serial.println( dig2A );
  }
  else
  {
    OutSevSegmentLED( dig2, 1 );       // индикация "2.7" - 2,7 км/ч
    OutDig2LED();
    OutSevSegmentLED( dig1, 0 );
    OutDig1LED();
Serial.print( " We observe the indicator = " );
Serial.print( dig2 );
Serial.print( "." );
Serial.println( dig1 );
  }
}
//==================================================================
//   знакогенератор
//==================================================================
void OutSevSegmentLED( byte _n, byte _dot )
{
  if( ( _n != 1 ) && ( _n != 4 ) ) digitalWrite( pinSegA, 1 );                               // сегмент A
  else digitalWrite( pinSegA, 0 );
  if( ( _n != 5 ) && ( _n != 6 ) ) digitalWrite( pinSegB, 1 );                               // сегмент B
  else digitalWrite( pinSegB, 0 );
  if( _n != 2 ) digitalWrite( pinSegC, 1 );                                                  // сегмент C
  else digitalWrite( pinSegC, 0 );
  if( ( _n != 1 ) && ( _n != 4 ) && ( _n != 7 ) ) digitalWrite( pinSegD, 1 );                // сегмент D
  else digitalWrite( pinSegD, 0 );
  if( ( _n == 0 ) || ( _n == 2 ) || ( _n == 6 ) || ( _n == 8 ) ) digitalWrite( pinSegE, 1 ); // сегмент E
  else digitalWrite( pinSegE, 0 );
  if( ( _n != 1 ) && ( _n != 2 ) && ( _n != 3 ) && ( _n != 7 ) ) digitalWrite( pinSegF, 1 ); // сегмент F
  else digitalWrite( pinSegF, 0 );
  if( ( _n != 0 ) && ( _n != 1 ) && ( _n != 7 ) ) digitalWrite( pinSegG, 1 );                // сегмент G
  else digitalWrite( pinSegG, 0 );
  if( _dot ) digitalWrite( pinSegH, 1 );                                                     // сегмент H
  else digitalWrite( pinSegH, 0 );
}
//==================================================================
//   ключ на цифру 1
//==================================================================
void OutDig1LED()
{
  digitalWrite( pinDig1, 0);
  delay( 5 );
  digitalWrite( pinDig1, 1);
}
//==================================================================
//   ключ на цифру 2
//==================================================================
void OutDig2LED()
{
  digitalWrite( pinDig2, 0 );
  delay( 5 );
  digitalWrite( pinDig2, 1 );
}
//==================================================================
BlockThor
BlockThor аватар
Offline
Зарегистрирован: 08.08.2014

Из темы "Я бы сделал по другому". Собственно уже сделал.
У меня код получился такой:

/*
 *  Велосипедный спидометр с выводом на семисегментный индикатор
 *  BlockDuino / Block7Seg / CleCloLED / CleCloReed
 *  May 2015, Vasyl Yudin
 */
#include <PrintTo7Seg.h>

const float radius = .34;// радиус колеса в метрах ВАШЕГО велосипеда
const float magnets = 1;
const int timeout = 1000; // (миллисекунд) масимальное время ожидания
const float circumference = TWO_PI*radius; // расстояние одного оборота колеса
const float RPMtoKMH = circumference * 0.06 / magnets; // коэф перевода (об/мин) в (км/ч)
const int debounce = 100; // защита от дребезга контактов

const int sensorPin = A5;   // порт для датчика
const int ledPin = 10;      // порт для светодиода

long timer = 0;   // для замера времи одного оборота (в миллисекундах)
long measuredTimer = 100000;   // время одного оборота (в миллисекундах)
float rpm = 0.0;  // оборотов в минуту
long counter = 0; // счетчик оборотов

boolean state = LOW;
boolean prevState = LOW;

byte numOfDigits = 4; // количество цифр в семисегментром дисплее
// digitPins - LSB to MSB
byte digPins[] = {3, 7, 8, A0 }; // порта подключенные к общим выводам цифр
// segmentPins - Dp, A to G
byte ledPins[] = {6, 4, 9, A2, A3, 2, 5, A1}; // порта подключенные к сегментам

PrintTo7Seg Seg7(numOfDigits, digPins, ledPins); // по умолчанию общий катод
//PrintTo7Seg Seg7(digPins, ledPins, COMMON_ANODE); // для дисплея с общим анодом

void setup() {
  pinMode(sensorPin, INPUT);
  pinMode(ledPin, OUTPUT);
  
  // TIMER - выставляем таймер с частотой прерывания в 1 кГц
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 1999;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  // END
  
  //Serial.begin(9600);
  
//  Seg7.print("test"); // тест дисплея при запуске
//  delay(250);
}

ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz to measure sensor
  prevState = state;
  state = digitalRead(sensorPin);// считываем датчик
  if (state == HIGH && prevState == LOW && timer > debounce){//если датчик сработал
//    rpm = digitalLowPass(rpm, 60000.0 /timer, 0.75);
    measuredTimer = timer; //фиксируем результат замера
    timer = 0; //обнуляем счетчик времени
    counter++; //увеличиваем счетчик оборотов на единицу
  }

  timer++;  
  if (timer > timeout){//если импульсов долго нет, значит стоим
    measuredTimer = measuredTimer + 100; 
  }

  digitalWrite(ledPin, state); // зажигаем/гасим светодиод по датчику
}

void loop(){
  //print mph once a second
  showSpeed  (); // рассчитываем и выводим скорость
  delay(100);    // каждые 0.1 секунду
}

void showSpeed(void){
  Seg7.clear();  // очищаем дисплей
  
    rpm = digitalLowPass(rpm, 60000.0 /measuredTimer, 0.75); 
    // рассчитываем обороты в секунду и сглаживаем низкочастотным фильтром
    //  (чем больше коэф (к единице) тем плавнее значения)
  Seg7.print(rpm * RPMtoKMH, 1); // выводим скорость в км/ч с точностью до одного знака после запятой
//  Serial.println(rpm);
}

/*
void showDist(void){
  Seg7.clear();  // очищаем дисплей
  Seg7.print(counter * circumference / magnets); // віводим пройденное расстояние от включения
}
*/

//Digital low pass filter - цифровой низкочастотный фильтр, коэф фильтра до единицы (чем ближе к единице тем выше фильтрация)
float digitalLowPass(float last_smoothed, float new_value, float filterVal)
{
  return (new_value * (1 - filterVal)) + (last_smoothed * filterVal);
}

Датчик считывается в прерываниях с частотой в 1 кГц, т.е. 1000 раз в секунду. Программно отсекается дребезг контактов. Встроенный низкочастотный фильтр, для сглаживания показаний скорости. Плавный уход в ноль, при остановке.

На велик не ставил, но есть работающий прототип: http://blockduino.blogspot.com/2015/06/bike-speedometer-7segment-display.html

зы Библиотеку можно взять тут: https://codebender.cc/personallibrary/PrintTo7Seg

next-999
Offline
Зарегистрирован: 30.09.2013

Немогу разобратся как подключать, выложите схему плиз

 

BlockThor пишет:

Из темы "Я бы сделал по другому". Собственно уже сделал.
У меня код получился такой:

/*
 *  Велосипедный спидометр с выводом на семисегментный индикатор
 *  BlockDuino / Block7Seg / CleCloLED / CleCloReed
 *  May 2015, Vasyl Yudin
 */
#include <PrintTo7Seg.h>

const float radius = .34;// радиус колеса в метрах ВАШЕГО велосипеда
const float magnets = 1;
const int timeout = 1000; // (миллисекунд) масимальное время ожидания
const float circumference = TWO_PI*radius; // расстояние одного оборота колеса
const float RPMtoKMH = circumference * 0.06 / magnets; // коэф перевода (об/мин) в (км/ч)
const int debounce = 100; // защита от дребезга контактов

const int sensorPin = A5;   // порт для датчика
const int ledPin = 10;      // порт для светодиода

long timer = 0;   // для замера времи одного оборота (в миллисекундах)
long measuredTimer = 100000;   // время одного оборота (в миллисекундах)
float rpm = 0.0;  // оборотов в минуту
long counter = 0; // счетчик оборотов

boolean state = LOW;
boolean prevState = LOW;

byte numOfDigits = 4; // количество цифр в семисегментром дисплее
// digitPins - LSB to MSB
byte digPins[] = {3, 7, 8, A0 }; // порта подключенные к общим выводам цифр
// segmentPins - Dp, A to G
byte ledPins[] = {6, 4, 9, A2, A3, 2, 5, A1}; // порта подключенные к сегментам

PrintTo7Seg Seg7(numOfDigits, digPins, ledPins); // по умолчанию общий катод
//PrintTo7Seg Seg7(digPins, ledPins, COMMON_ANODE); // для дисплея с общим анодом

void setup() {
  pinMode(sensorPin, INPUT);
  pinMode(ledPin, OUTPUT);
  
  // TIMER - выставляем таймер с частотой прерывания в 1 кГц
  cli();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  OCR1A = 1999;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11);
  TIMSK1 |= (1 << OCIE1A);
  sei();
  // END
  
  //Serial.begin(9600);
  
//  Seg7.print("test"); // тест дисплея при запуске
//  delay(250);
}

ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz to measure sensor
  prevState = state;
  state = digitalRead(sensorPin);// считываем датчик
  if (state == HIGH && prevState == LOW && timer > debounce){//если датчик сработал
//    rpm = digitalLowPass(rpm, 60000.0 /timer, 0.75);
    measuredTimer = timer; //фиксируем результат замера
    timer = 0; //обнуляем счетчик времени
    counter++; //увеличиваем счетчик оборотов на единицу
  }

  timer++;  
  if (timer > timeout){//если импульсов долго нет, значит стоим
    measuredTimer = measuredTimer + 100; 
  }

  digitalWrite(ledPin, state); // зажигаем/гасим светодиод по датчику
}

void loop(){
  //print mph once a second
  showSpeed  (); // рассчитываем и выводим скорость
  delay(100);    // каждые 0.1 секунду
}

void showSpeed(void){
  Seg7.clear();  // очищаем дисплей
  
    rpm = digitalLowPass(rpm, 60000.0 /measuredTimer, 0.75); 
    // рассчитываем обороты в секунду и сглаживаем низкочастотным фильтром
    //  (чем больше коэф (к единице) тем плавнее значения)
  Seg7.print(rpm * RPMtoKMH, 1); // выводим скорость в км/ч с точностью до одного знака после запятой
//  Serial.println(rpm);
}

/*
void showDist(void){
  Seg7.clear();  // очищаем дисплей
  Seg7.print(counter * circumference / magnets); // віводим пройденное расстояние от включения
}
*/

//Digital low pass filter - цифровой низкочастотный фильтр, коэф фильтра до единицы (чем ближе к единице тем выше фильтрация)
float digitalLowPass(float last_smoothed, float new_value, float filterVal)
{
  return (new_value * (1 - filterVal)) + (last_smoothed * filterVal);
}

Датчик считывается в прерываниях с частотой в 1 кГц, т.е. 1000 раз в секунду. Программно отсекается дребезг контактов. Встроенный низкочастотный фильтр, для сглаживания показаний скорости. Плавный уход в ноль, при остановке.

На велик не ставил, но есть работающий прототип: http://blockduino.blogspot.com/2015/06/bike-speedometer-7segment-display.html

зы Библиотеку можно взять тут: https://codebender.cc/personallibrary/PrintTo7Seg