корректор частоты

Xumuk
Xumuk аватар
Offline
Зарегистрирован: 03.03.2016

всем здрасти, пытаюсь сделать корректор частоты для спидомера, но никак не выходит( код писал пока что 1 к 1 частоту без коэфициэнта, подскажите советом, куда дальше копать? в данном скетче частота на выходе намного выше чем на входе,  // unsigned long out =(100000/(currentMillis - previousMillis)); а вот с этой строчкой не хочет работать , заранее спасибо

//********************************************************************
unsigned long micros_sp;
volatile int sz =0; //счетчик обнуления
volatile int sp = 0; //скорость
volatile boolean st = false;
const int ledPin =  13;      // номер выхода, подключенного к светодиоду
int ledState = LOW;             // этой переменной устанавливаем состояние светодиода 
long previousMillis = 0;        // храним время последнего переключения светодиода


//********************************************************************
void setup(){
Serial.begin(9600); //инициализация ком порта
attachInterrupt(1, speedometr, RISING); //прерывание спидометра по фронту импульса
pinMode(ledPin, OUTPUT); 
tone(7,100);
}
//********************************************************************
void loop(){
//////////////////////////////////////////////////////////////////////////////
 unsigned long currentMillis = micros();
 // unsigned long out =(100000/(currentMillis - previousMillis));
 // unsigned long out = sp;
  if((currentMillis - previousMillis) > sp) {
    // сохраняем время последнего переключения
    previousMillis = currentMillis;  

    // если светодиод не горит, то зажигаем, и наоборот
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // устанавливаем состояния выхода, чтобы включить или выключить светодиод
    digitalWrite(ledPin, ledState);
  }
//////////////////////////////////////////////////////////////////////////// 




//if (sz !=0){sz--;}else{sp = 0;};
//delay(50);
}
//********************************************************************
void speedometr(){ //измеряем частоту на входе спидометра по прерыванию
if(!st){micros_sp = micros();} //сохраняем текущее значение микросекунд

else  {sp = (1000000/(micros() - micros_sp)); ..вычисляем частоту

}; 

  
Serial.println (sp);//выводим в сериал порт
//else  {sp = (600000/(micros() - micros_sp));};
st = !st;
//sz = 30;
}

 

 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вы не могли бы вставлять код копипастом, а то он у Вас даже не компилируется. И заодно Ctrl+T делать иначе чёрт ногу в скобках сломит.

По коду.

1. Из каких соображений previousMillis объявлено как long, а currentMillis как unisgned long?

2. Названия переменных наподобие "currentMillis = micros();" используются для ввдения в заблуждение противника?

3. Вы считаете частоту целочисленным делением без компенасации отбрасывания остатка

sp = (1000000/(micros() - micros_sp));

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

Например, при при micros() - micros_sp, в диапазоне от 9805 до 9900 Ваша формула даст ровно одну и ту же частоту - 101 гц, хотя если посчитать 1000000/9805 получается 101,99 - практически 102!

Xumuk
Xumuk аватар
Offline
Зарегистрирован: 03.03.2016

ЕвгенийП пишет:

Вы не могли бы вставлять код копипастом, а то он у Вас даже не компилируется. И заодно Ctrl+T делать иначе чёрт ногу в скобках сломит.

По коду.

1. Из каких соображений previousMillis объявлено как long, а currentMillis как unisgned long?

2. Названия переменных наподобие "currentMillis = micros();" используются для ввдения в заблуждение противника?

3. Вы считаете частоту целочисленным делением без компенасации отбрасывания остатка

sp = (1000000/(micros() - micros_sp));

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

Например, при при micros() - micros_sp, в диапазоне от 9805 до 9900 Ваша формула даст ровно одну и ту же частоту - 101 гц, хотя если посчитать 1000000/9805 получается 101,99 - практически 102!


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

Xumuk
Xumuk аватар
Offline
Зарегистрирован: 03.03.2016
//********************************************************************
unsigned long micros_sp;
volatile int sz = 0; //счетчик обнуления
volatile int sp = 0; //скорость
volatile boolean st = false;
const int ledPin =  13;      // номер выхода, подключенного к светодиоду
int ledState = LOW;             // этой переменной устанавливаем состояние светодиода
long previousMillis = 0;        // храним время последнего переключения светодиода


//********************************************************************
void setup() {
  Serial.begin(9600); //инициализация ком порта
  attachInterrupt(1, speedometr, RISING); //прерывание спидометра по фронту импульса
  pinMode(ledPin, OUTPUT);
  tone(7, 100);
}
//********************************************************************
void loop() {
  //////////////////////////////////////////////////////////////////////////////
  unsigned long currentMillis = micros();
  // unsigned long out =(100000/(currentMillis - previousMillis));
  // unsigned long out = sp;
  if ((currentMillis - previousMillis) > sp) {
    // сохраняем время последнего переключения
    previousMillis = currentMillis;

    // если светодиод не горит, то зажигаем, и наоборот
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // устанавливаем состояния выхода, чтобы включить или выключить светодиод
    digitalWrite(ledPin, ledState);
  }
  ////////////////////////////////////////////////////////////////////////////




  //if (sz !=0){sz--;}else{sp = 0;};
  //delay(50);
}
//********************************************************************
void speedometr() { //измеряем частоту на входе спидометра по прерыванию
  if (!st) {
    micros_sp = micros(); //сохраняем текущее значение микросекунд
  }

  else  {
    sp = (1000000 / (micros() - micros_sp)); //..вычисляем частоту

  };


  Serial.println (sp);//выводим в сериал порт
  //else  {sp = (600000/(micros() - micros_sp));};
  st = !st;
  //sz = 30;
}

ЕвгенийП пишет:

Вы не могли бы вставлять код копипастом, а то он у Вас даже не компилируется. И заодно Ctrl+T делать иначе чёрт ногу в скобках сломит.

По коду.

1. Из каких соображений previousMillis объявлено как long, а currentMillis как unisgned long?

2. Названия переменных наподобие "currentMillis = micros();" используются для ввдения в заблуждение противника?

3. Вы считаете частоту целочисленным делением без компенасации отбрасывания остатка

sp = (1000000/(micros() - micros_sp));

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

Например, при при micros() - micros_sp, в диапазоне от 9805 до 9900 Ваша формула даст ровно одну и ту же частоту - 101 гц, хотя если посчитать 1000000/9805 получается 101,99 - практически 102!

нашел почему не компилируется в 49 не закоментирован коментарий