Умножение вместо деления

kennspark
Offline
Зарегистрирован: 24.07.2015

Привет всем.

Наблюдается неадекватнная реакция ардуины на арифметические действия.

 

Вот код, по логике всё хорошо:

//********************************************************************
unsigned long millis_tah;
volatile int sz1=0;
volatile unsigned long tah;
unsigned long tah_new;
//********************************************************************
void setup(){

  attachInterrupt(1, tachometer, CHANGE); 
  pinMode(11, OUTPUT);
}

void loop() 
{ 
  { 
    digitalWrite(11, HIGH);  
    delay(tah_new); 
    digitalWrite(11, LOW);  
     delay(tah_new); 
  }  
}
void tachometer(){
 
  tah=((millis()- micros_tah)); //измеряем частоту на входе тахометра по прерыванию
  micros_tah= millis();
  tah_new=tah*1.5; //тут умножаем
  sz1=0;
}

Но, как только подаём 50Гц скетчу, начинается жесть... 50*1,5=33,3(3) для ардуины...

По идее 50/1,5=33,3...

Ок, проверяем в обратную сторону, 50/1,5=75 (опять же так считает ардуина)

Вопрос, что с ней блин не так?

Нижний график =50Гц, верхний =33,3Гц (после "умножения").

Есть идеи?

Radjah
Offline
Зарегистрирован: 06.08.2014

Разберись с типами.

Ты int на float умножаешь и записываешь в int

kennspark
Offline
Зарегистрирован: 24.07.2015

Ок, пусть коэффицент будет равен 2. Два не флоат? В итоге получаем 50*2=25 и 50/2=100 (по мнению Ардуины). Так что боюсь тут дело не в объявлении переменных...

Radjah
Offline
Зарегистрирован: 06.08.2014

Опиши словами алгоритм.

Еще у тебя переменные не инициализированы.

micros_tah нигде не объявлено.

2-5 - бредятина с объявлением.

kennspark
Offline
Зарегистрирован: 24.07.2015

Берём сигнал с мозга машины, пихаем его в ардуину, далее по изменению фронтов считаем время между импульсами, посчитанное время равно периоду сигнала, период умножаем на 1,5(да вообще без разницы) и подпихиваем его в луп, на подачу ШИМ с преобразованной частотой. Точка.

"переменные не инициализированы."  Как воспринимать сиё замечание?

Со второй по пятую включительно?

 

Извиняюсь, опечатка с micros_tah, она объявлена как millis_tah, пока редактировал упустил.

kennspark
Offline
Зарегистрирован: 24.07.2015
Вот код без ошибок. Над тем производились попытки реанимации, поэтому такой кривой...

//********************************************************************
unsigned long micros_tah;
volatile int tah;
int tah_new;
//********************************************************************
void setup(){

attachInterrupt(1, tachometer, RISING); 
pinMode(11, OUTPUT);
}

void loop() 
{ 

  { 
    digitalWrite(11, HIGH);  
    delay(tah_new); 
    digitalWrite(11, LOW);  
     delay(tah_new); 
  } 
} 

void tachometer(){
  tah=((micros()- micros_tah)); 
  micros_tah= micros();
  tah_new=(tah*1,5);
}

 

Logik
Offline
Зарегистрирован: 05.08.2014

Ну ты же период измерил. Не частоту. Умножил период на 1.5, увеличил значить и вывел. А значить частоту уменшил. Все норм...

kennspark
Offline
Зарегистрирован: 24.07.2015

Logik пишет:

Ну ты же период измерил. Не частоту. Умножил период на 1.5, увеличил значить и вывел. А значить частоту уменшил. Все норм...

Всё верно.... Спасибо, мозги не работают ничерта

Можно закрывать...

inspiritus
Offline
Зарегистрирован: 17.12.2012

Ченч в интеррапте сильно не люблю, предпочитаю райз , или фалл, как то олнозначнее...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Вообще-то если целую величину нужнор увеличить в 1.5 раза, то обычно сначала умножают ее на 3, а потом делят на 2.

(вместо деления на 2 можно сдвинуть на 1 вправо, но, по идее, компилятор должен это сделать сам)

Logik
Offline
Зарегистрирован: 05.08.2014

Если уж лезть в дебри оптимизации, а это иногда полезно, то умножение целого на 3 это сдвинуть его влево на 1 и прибавить исходное. После этого сдвинем вправо на 1, т.е. делим на 2. Вот и результат умножили на 1,5 без умножения. Так делают истиные ценители извращений :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Нет, любители извращений как раз масштабируют целые путем перевода их в вещественные и обратно.

kennspark
Offline
Зарегистрирован: 24.07.2015

andriano пишет:

Вообще-то если целую величину нужнор увеличить в 1.5 раза, то обычно сначала умножают ее на 3, а потом делят на 2.

(вместо деления на 2 можно сдвинуть на 1 вправо, но, по идее, компилятор должен это сделать сам)

Коэффицент равный 1,5 требуется использовать если в прерывании (CHANGE), а если (RISING или FALLING) то там уже будет 3, то есть целое число