Нужна помощь со скетчем (Реле и кнопки )

vk007
Offline
Зарегистрирован: 16.06.2015

Теперь я уже что-то не пойму. Задача была поставлена:

Lexan пишет:
И по условиям должно сработать реле2 в том случае (Если Число1 больше или меньше Числа2 более чем на 5)

Я ее понимаю так. Допустим, Число1=180 и, в зависимости от Числа2 (а точнее от их разницы Число2-Число1):

Число2   Разница
 ...      ...       реле сработало
 173       -7       реле сработало
 174       -6       реле сработало
 175       -5
 176       -4
 177       -3
 178       -2
 179       -1
 180        0
 181        1
 182        2
 183        3
 184        4
 185        5
 186        6       реле сработало
 187        7       реле сработало
 ...      ...       реле сработало

Но, если просто от Числа2 вычитать Число1, то разница может быть и положительной, и отрицательной (см.табличку). А abs просто отбрасывает знак. Таким образом, неважно в какую сторону получилось отклонение в плюс или в минус реле сработает. Так понятно?

 

vk007
Offline
Зарегистрирован: 16.06.2015

Lexan пишет:

Ребят а как обьяснить переменной kalXold что она должна обнулится?

Клапауций 322 и Клапауций 232 уже несколько раз отправляли почитать, извини, но отправлю и я тебя туда же. Конкретно по этому вопросу читай тут. Как начитаешься и, если останутся дельные вопросы, возвращайся, продолжим.

Lexan
Offline
Зарегистрирован: 12.02.2016

Ну вроде бы получилось обнулять с помощью кнопки2

 

if (BUTTON_01.click_down) /*кнопка1 включает реле1 и запускает сравнение переменных, и в случае разницы + или -5 включает реле2, буззер*/
   {        
    digitalWrite(RELAY_01, HIGH);
    Serial.println("Relay1 ON\n"); 
    kalXold = kalAngleX; 
    if (kalXold - kalAngleX >= 5)
      {
        digitalWrite(RELAY_02, HIGH);
        digitalWrite(BUZZER, HIGH);
      }
    if (kalXold - kalAngleX <= 5)
      {
        digitalWrite(RELAY_02, HIGH);
        digitalWrite(BUZZER, HIGH);
      }
      
    }                                  
     
      
  if (BUTTON_02.click_down) {           //кнопка2 выключает реле1, реле2, бузер и обнуляет kalXold
    kalXold = 0;
    digitalWrite(RELAY_01, LOW);
    digitalWrite(RELAY_02, LOW);
    digitalWrite(BUZZER, LOW);
      Serial.println("Relay1 OFF\n");
      Serial.println("Relay2 OFF\n");
      Serial.println("BUZZER OFF\n");
     }
  

 

vk007
Offline
Зарегистрирован: 16.06.2015

Не вижу смысла в строках 06-15 - реле включится при любых значениях разницы.

Lexan
Offline
Зарегистрирован: 12.02.2016

Попробавал сделать так но почемуто светодиод на 13 PIN (он вместо реле02 пока) не срабатывает:

 

if (BUTTON_01.click_down) //кнопка1 включает реле1 и запускает сравнение переменных, и в случае разницы + или -5 включает реле2, буззер
   {        
    digitalWrite(RELAY_01, HIGH);
    Serial.println("Relay1 ON\n"); 
    kalXold = kalAngleX; 
    if (abs(kalXold - kalAngleX) > 5)
    {
      digitalWrite(RELAY_02, HIGH);
      digitalWrite(BUZZER, HIGH);
      Serial.println("Relay2 ON\n");
    }
   }                                  
     
      
   if (BUTTON_02.click_down)   //кнопка2 выключает реле1, реле2, бузер и обнуляет kalXold
   {           
    kalXold = 0;
    digitalWrite(RELAY_01, LOW);
    digitalWrite(RELAY_02, LOW);
    digitalWrite(BUZZER, LOW);
      Serial.println("Relay1 OFF\n");
      Serial.println("Relay2 OFF\n");
      Serial.println("BUZZER OFF\n");

 

Lexan
Offline
Зарегистрирован: 12.02.2016

А вот так при нажатии на кнопку1,  почемуто вместе с реле1 включается сразу реле2 хотя по условию не должно (так как отклонения от градусов не происходило)...

 

if (BUTTON_01.click_down) {        
    digitalWrite(RELAY_01, HIGH);
    Serial.println("Relay1 ON\n"); 
    kalXold = kalAngleX; 
    
    if (kalXold - kalAngleX >= 5) {
        digitalWrite(RELAY_02, HIGH);
        digitalWrite(BUZZER, HIGH);
      }
      
    if (kalXold - kalAngleX <= 5)
      {
        digitalWrite(RELAY_02, HIGH);
        digitalWrite(BUZZER, HIGH);
      }
      
    }                                  
     
      
  if (BUTTON_02.click_down) {        
    kalXold = 0;
    digitalWrite(RELAY_01, LOW);
    digitalWrite(RELAY_02, LOW);
    digitalWrite(BUZZER, LOW);
      Serial.println("Relay1 OFF\n");
      Serial.println("Relay2 OFF\n");
      Serial.println("BUZZER OFF\n");
     }

 

vk007
Offline
Зарегистрирован: 16.06.2015

Lexan пишет:

Попробавал сделать так но почемуто светодиод на 13 PIN (он вместо реле02 пока) не срабатывает

Как быстро меняется значение kalAngleX? Если успеет поменяться за время, прошедшее между выполнением строки 05 и строки 06, то все будет ОК. Но я в этом очень и очень сомневаюсь. При таком алгоритме работы, как сейчас, kalAngleX будет сравниваться практически само с собой.

vk007
Offline
Зарегистрирован: 16.06.2015

Lexan пишет:

А вот так при нажатии на кнопку1,  почемуто вместе с реле1 включается сразу реле2 хотя по условию не должно (так как отклонения от градусов не происходило)...

Об этом я уже упоминал в сообщении #55.

Lexan
Offline
Зарегистрирован: 12.02.2016

vk007 пишет:

Lexan пишет:

А вот так при нажатии на кнопку1,  почемуто вместе с реле1 включается сразу реле2 хотя по условию не должно (так как отклонения от градусов не происходило)...

Об этом я уже упоминал в сообщении #55.

 

Да действительно второе реле перестает включатся от кнопки1 если использовать abs. 

Так теперь мне там между 05 и 06 нужна задержка по времени? Изза этого значит и не срабатывает реле2 во время отклонения на 5 и более градусов.

А сколько примерно миллисикунд?

vk007
Offline
Зарегистрирован: 16.06.2015

Lexan пишет:

А сколько примерно миллисикунд?

Откуда мне знать. Я потому и спрашивал, как быстро меняется значение kalAngleX.

Для того чтобы посмотреть, что оно действительно ловит изменение, паузу и через delay() поставить можно. Но для готового устройства от delay лучше отказаться и поменять алгоритм работы тоже.

Lexan
Offline
Зарегистрирован: 12.02.2016

Пробовал и delay (1000); добовлял, не получается, не срабатывает реле2... 

#include <Wire.h>
#include <class_BUTTON.h>
BUTTON BUTTON_01(2);  // Кнопка1 для Включения реле1 и запуска сравнения переменных Оси X
BUTTON BUTTON_02(3);  // Кнопка2 для Отключения реле1 и реле2 и буззера
#include "Kalman.h"
Kalman kalmanX;
Kalman kalmanY;
uint8_t IMUAddress = 0x68;
/* IMU Data */
int16_t accX;
int16_t accY;
int16_t accZ;
int16_t tempRaw;
int16_t gyroX;
int16_t gyroY;
int16_t gyroZ;
double accXangle; // Angle calculate using the accelerometer
double accYangle;
double temp;
double gyroXangle = 180; // Angle calculate using the gyro
double gyroYangle = 180;
double compAngleX = 180; // Calculate the angle using a Kalman filter
double compAngleY = 180;
double kalAngleX; // Calculate the angle using a Kalman filter
double kalAngleY;
uint32_t timer;
#define RELAY_01 13
#define RELAY_02 5
#define BUZZER 6
double kalXold;


void setup() {
  Wire.begin();
  Serial.begin(9600);
  pinMode(RELAY_01, OUTPUT);
  pinMode(RELAY_02, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  i2cWrite(0x6B,0x00); // Disable sleep mode      
  kalmanX.setAngle(180); // Set starting angle
  kalmanY.setAngle(180);
  timer = micros();
}
void loop() {
  BUTTON_01.read();
  BUTTON_02.read();

  
  if (BUTTON_01.click_down) 
   {        
    digitalWrite(RELAY_01, HIGH);    //включаем реле1
    Serial.println("Relay1 ON\n");   // пишем в порт
    kalXold = kalAngleX;               //копируем значение X по нажатию и отдаем его переменной kalXold
    
    if (abs(kalXold - kalAngleX) > 5)   // есле kalXold бельше или меньше 5 то...
    {
      digitalWrite(RELAY_02, HIGH);    // включаем реле2
      digitalWrite(BUZZER, HIGH);      // включаем буззер
      Serial.println("Relay2 ON\n");   // пишем в порт
    }
   }                                  
     
      
   if (BUTTON_02.click_down)            
   {
     kalXold = 0;                        //обнуляем переменную
    digitalWrite(RELAY_01, LOW);         //выключаем реле1
    digitalWrite(RELAY_02, LOW);         //выключаем реле2
    digitalWrite(BUZZER, LOW);            //выключаем буззер
      Serial.println("Relay1 OFF\n");     // пишем в порт
      Serial.println("Relay2 OFF\n");    // пишем в порт
      Serial.println("BUZZER OFF\n");    // пишем в порт
                
   }
    
  
  uint8_t* data = i2cRead(0x3B,14);
  accX = ((data[0] << 8) | data[1]);
  accY = ((data[2] << 8) | data[3]);
  accZ = ((data[4] << 8) | data[5]);
  tempRaw = ((data[6] << 8) | data[7]);
  gyroX = ((data[8] << 8) | data[9]);
  gyroY = ((data[10] << 8) | data[11]);
  gyroZ = ((data[12] << 8) | data[13]);
  /* Calculate the angls based on the different sensors and algorithm */
  accYangle = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
  accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG;  
  double gyroXrate = (double)gyroX/131.0;
  double gyroYrate = -((double)gyroY/131.0);
  gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
  gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);
  kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter
  kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000);
  timer = micros();
Serial.println();
    Serial.print("X:");
    Serial.print(kalAngleX,0);
    Serial.print(" ");
    Serial.print("Y:");
    Serial.print(kalAngleY,0);
    Serial.println(" ");
    Serial.println("oldX:");
    Serial.println(kalXold,0);
    Serial.println(" ");
  // The accelerometer's maximum samples rate is 1kHz
}
void i2cWrite(uint8_t registerAddress, uint8_t data){
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.write(data);
  Wire.endTransmission(); // Send stop
}
uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) {
  uint8_t data[nbytes];
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.endTransmission(false); // Don't release the bus
  Wire.requestFrom(IMUAddress, nbytes); // Send a repeated start and then release the bus after reading
  for(uint8_t i = 0; i < nbytes; i++)
    data [i]= Wire.read();
  return data;
}

 

vk007
Offline
Зарегистрирован: 16.06.2015

Я снова обращаю внимание на конструкцию:

kalXold = kalAngleX;               //копируем значение X по нажатию и отдаем его переменной kalXold

if (abs(kalXold - kalAngleX) > 5)   // есле kalXold бельше или меньше 5 то...

Мне непонятен ее загадочный смысл в таком виде. Снова повторюсь - kalAngleX сравнивается практически само с собой. Ну не успеет оно так быстро поменяться.

И, кстати, не "есле kalXold бельше или меньше 5 то...", а "отклонение kalAngleX от kalXold..."

Lexan
Offline
Зарегистрирован: 12.02.2016

vk007 пишет:

Я снова обращаю внимание на конструкцию:

kalXold = kalAngleX;               //копируем значение X по нажатию и отдаем его переменной kalXold

if (abs(kalXold - kalAngleX) > 5)   // есле kalXold бельше или меньше 5 то...

Мне непонятен ее загадочный смысл в таком виде. Снова повторюсь - kalAngleX сравнивается практически само с собой. Ну не успеет оно так быстро поменяться.

И, кстати, не "есле kalXold бельше или меньше 5 то...", а "отклонение kalAngleX от kalXold..."

 

так, ну... отклонение это же тоже подходит.  Суть же таже. 

Непойму почему неуспеет то? Получается же так: нажимаю кнопку1, значение kalAngleX скопировалось в переменную kalXold и сохранилось там. т.е kalAngleX живет своей жизнью и меняется в зависимости от наклона датчика, а kalXold можно сказать сфоткало число и больше его не меняет (kalXold остаётся таким каким было kalAngleX  в момент нажатия на кнопку1)...

 

vk007
Offline
Зарегистрирован: 16.06.2015

Нет, так не получается. Сейчас получается так: при каждом нажатии на кнопку kalAngleX копируется в kalXold и тут же эти две переменные сравниваются.

Например, kalAngleX=150. Скопировали мы его в kalXold и теперь kalXold тоже =150. Далее их сравниваем. Что будет если сравнить 150 и 150?

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

Lexan пишет:

Непойму почему неуспеет то? 

// допустим kalXold = 1000
kalXold = kalAngleX; // теперь kalXold = kalAngleX = 1000
if (abs(kalXold - kalAngleX) > 5)   // если kalXold = kalAngleX, то kalXold - kalAngleX = 0 ВСЕГДА!

 

vk007
Offline
Зарегистрирован: 16.06.2015

В дополнение, перед тем, как сравнивать kalAngleX с предыдущим значением его надо вычислить!

Т.е. алгоритм работы должен быть примерно следующим:

1) вычислить kalAngleX;

2) сравнить его с предыдущим значением (т.е. с kalXold);

3) по результату сравнения сделать то, что требуется;

4) запомнить kalAngleX в kalXold для будущего сравнения.

Lexan
Offline
Зарегистрирован: 12.02.2016

Клапауций 232 пишет:

Lexan пишет:

Непойму почему неуспеет то? 

// допустим kalXold = 1000
kalXold = kalAngleX; // теперь kalXold = kalAngleX = 1000
if (abs(kalXold - kalAngleX) > 5)   // если kalXold = kalAngleX, то kalXold - kalAngleX = 0 ВСЕГДА!

 

Тоесть, я неправильно объясняю переменной kalXold как  копировать число kalAngleX ? и если я пишу в кнопке1

 kalXold = kalAngleX;  // то они будут всегда рввны друг другу? И каким бы не стало значение kalAngleX то значение kalXold тутже станет таким же?

А то, что в порту пишет после нажатия кнопки1, к примеру oldX:178 и замерает, и, в то же время, ось X:190 показывает и меняется как хочет не влияя на показания oldX.

Это просто так т.е oldX пишет неправду??? Вернее, пишет не то что происходит с переменной kalXold в данный момент???

Lexan
Offline
Зарегистрирован: 12.02.2016

vk007 пишет:

В дополнение, перед тем, как сравнивать kalAngleX с предыдущим значением его надо вычислить!

Т.е. алгоритм работы должен быть примерно следующим:

1) вычислить kalAngleX;

2) сравнить его с предыдущим значением (т.е. с kalXold);

3) по результату сравнения сделать то, что требуется;

4) запомнить kalAngleX в kalXold для будущего сравнения.

 

Значит должно быть так? И я в начале преравнял переменную kalXold к нулю это правельно?

#include <Wire.h>
#include <class_BUTTON.h>
BUTTON BUTTON_01(2);  // Кнопка1 для Включения реле1 и запуска сравнения переменных Оси X
BUTTON BUTTON_02(3);  // Кнопка2 для Отключения реле1 и реле2 и буззера
#include "Kalman.h"
Kalman kalmanX;
Kalman kalmanY;
uint8_t IMUAddress = 0x68;
/* IMU Data */
int16_t accX;
int16_t accY;
int16_t accZ;
int16_t tempRaw;
int16_t gyroX;
int16_t gyroY;
int16_t gyroZ;
double accXangle; // Angle calculate using the accelerometer
double accYangle;
double temp;
double gyroXangle = 180; // Angle calculate using the gyro
double gyroYangle = 180;
double compAngleX = 180; // Calculate the angle using a Kalman filter
double compAngleY = 180;
double kalAngleX; // Calculate the angle using a Kalman filter
double kalAngleY;
uint32_t timer;
#define RELAY_01 13
#define RELAY_02 5
#define BUZZER 6
double kalXold = 0;


void setup() {
  Wire.begin();
  Serial.begin(9600);
  pinMode(RELAY_01, OUTPUT);
  pinMode(RELAY_02, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  i2cWrite(0x6B,0x00); // Disable sleep mode      
  kalmanX.setAngle(180); // Set starting angle
  kalmanY.setAngle(180);
  timer = micros();
}
void loop() {
  BUTTON_01.read();
  BUTTON_02.read();
   
  
  uint8_t* data = i2cRead(0x3B,14);
  accX = ((data[0] << 8) | data[1]);
  accY = ((data[2] << 8) | data[3]);
  accZ = ((data[4] << 8) | data[5]);
  tempRaw = ((data[6] << 8) | data[7]);
  gyroX = ((data[8] << 8) | data[9]);
  gyroY = ((data[10] << 8) | data[11]);
  gyroZ = ((data[12] << 8) | data[13]);
  /* Calculate the angls based on the different sensors and algorithm */
  accYangle = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
  accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG;  
  double gyroXrate = (double)gyroX/131.0;
  double gyroYrate = -((double)gyroY/131.0);
  gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
  gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);
  kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter
  kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000);
  timer = micros();
Serial.println();
    Serial.print("X:");
    Serial.print(kalAngleX,0);
    Serial.print(" ");
    Serial.print("Y:");
    Serial.print(kalAngleY,0);
    Serial.println(" ");
    Serial.println("oldX:");
    Serial.println(kalXold,0);
    Serial.println(" ");

     if (BUTTON_01.click_down) 
   {        
    digitalWrite(RELAY_01, HIGH);    //включаем реле1
    Serial.println("Relay1 ON\n");   // пишем в порт
    kalXold = kalAngleX;               //копируем значение X по нажатию и отдаем его переменной kalXold
    
    if (abs(kalXold - kalAngleX) > 5)   // есле kalXold бельше или меньше 5 то...
    {
      digitalWrite(RELAY_02, HIGH);    // включаем реле2
      digitalWrite(BUZZER, HIGH);      // включаем буззер
      Serial.println("Relay2 ON\n");   // пишем в порт
    }
   }                                  
     
      
   if (BUTTON_02.click_down)            
   {
     kalXold = 0;                        //обнуляем переменную
    digitalWrite(RELAY_01, LOW);         //выключаем реле1
    digitalWrite(RELAY_02, LOW);         //выключаем реле2
    digitalWrite(BUZZER, LOW);            //выключаем буззер
      Serial.println("Relay1 OFF\n");     // пишем в порт
      Serial.println("Relay2 OFF\n");    // пишем в порт
      Serial.println("BUZZER OFF\n");    // пишем в порт
                
   }
    
  // The accelerometer's maximum samples rate is 1kHz
}
void i2cWrite(uint8_t registerAddress, uint8_t data){
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.write(data);
  Wire.endTransmission(); // Send stop
}
uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) {
  uint8_t data[nbytes];
  Wire.beginTransmission(IMUAddress);
  Wire.write(registerAddress);
  Wire.endTransmission(false); // Don't release the bus
  Wire.requestFrom(IMUAddress, nbytes); // Send a repeated start and then release the bus after reading
  for(uint8_t i = 0; i < nbytes; i++)
    data [i]= Wire.read();
  return data;
}

 

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

Lexan пишет:

kalXold = kalAngleX;  // то они будут всегда рввны друг другу? И каким бы не стало значение kalAngleX то значение kalXold тутже станет таким же?

ок. сначала - когда ты делаешь kalXold = kalAngleX; , что блин происходит?

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

Lexan
Offline
Зарегистрирован: 12.02.2016

Клапауций 232 пишет:

Lexan пишет:

kalXold = kalAngleX;  // то они будут всегда рввны друг другу? И каким бы не стало значение kalAngleX то значение kalXold тутже станет таким же?

ок. сначала - когда ты делаешь kalXold = kalAngleX; , что блин происходит?

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

Вот засада! Значит нужно както по другому копировать значение  (kalAngleX) в (kalXold) и при этом оно должно скопироватся только один раз и по нажатию кнопки...

Но я незнаю такой функцый ??? Это значит что сохронять надо в EEPROM чтоли???

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

нет - тебе нужно инициализировать две переменные:

а и na

na = [функция считывания из гироскопа];

далее в лупе

if (abs(a - na) > 5) {a = na; // что-то делать, когда больше пяти}

Lexan
Offline
Зарегистрирован: 12.02.2016

Но ведь чтобы получать значение в градусах нужен фильтр Калмана? Так? а функция (na) будет считывать данные напрямую?

тоесть получается: (a) это  (kalAngleX) тоесть обработанное фильтром число и переведённое в градусы, 

А  kalXold будет считывать значение c помощью функцыи (na) не обработанное фильтром Калмана.

 

Или я неправельно понимаю?

Просто гдето прочёл, что из mpu6050 выходят сырые данные и чтобы они приняли человеческий вид используют фильтр калмана или какойто внутренний встроенный вычеслитель.

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

Lexan пишет:

Но ведь чтобы получать значение в градусах нужен фильтр Калмана? Так? а функция (na) будет считывать данные напрямую?

не додумывай того, чего нет - делаешь na = градусы. всё. дальше всё сделается автоматом

как ты эти градусы вычисляешь - никому не интересно

Lexan
Offline
Зарегистрирован: 12.02.2016

Извиняюсь за любопыцтво :)

а функция na считает градусы только один раз? или будит считывать их постоянно?

Или это тупой вопрос??? ))

vk007
Offline
Зарегистрирован: 16.06.2015

Lexan пишет:

а функция na считает градусы только один раз? или будит считывать их постоянно?

Как сделаешь, так и будет.

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

Lexan пишет:

Извиняюсь за любопыцтво :)

а функция na считает градусы только один раз? или будит считывать их постоянно?

Или это тупой вопрос??? ))

смотри - у тебя было так:

kalXold = kalAngleX;               //копируем значение X по нажатию и отдаем его переменной kalXold

if (abs(kalXold - kalAngleX) > 5)   // есле kalXold бельше или меньше 5 то...

а нужно так

kalAngleX = [градусы];
if (abs(kalXold - kalAngleX) > 5) {kalXold = kalAngleX; // что-то делаем, когда больше 5}

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

vk007
Offline
Зарегистрирован: 16.06.2015

Возьми лист бумаги, карандаш и составь алгоритм (учил наверное на информатике, что это и для чего). Не обязательно красивый, с ромбиками и прямоугольничками, как на уроках, а простой в виде списка: 1) сделать то, 2) сделать другое, 3) сравнить что-то с чем-то, 4) если получилось одно то перейти на п.10, иначе на п.32 и т.д.

А уже потом, когда несколько раз пройдешся по нему и поймешь, что он составлен правильно, так как надо, берись за программу.

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

Извини, но с такими знаниями сразу писать сложную программу и пытаться что-то выдумывать на ходу - это тупик.

Lexan
Offline
Зарегистрирован: 12.02.2016

Клапауций 232 пишет:

Lexan пишет:

Извиняюсь за любопыцтво :)

а функция na считает градусы только один раз? или будит считывать их постоянно?

Или это тупой вопрос??? ))

смотри - у тебя было так:

kalXold = kalAngleX;               //копируем значение X по нажатию и отдаем его переменной kalXold

if (abs(kalXold - kalAngleX) > 5)   // есле kalXold бельше или меньше 5 то...

а нужно так

kalAngleX = [градусы];
if (abs(kalXold - kalAngleX) > 5) {kalXold = kalAngleX; // что-то делаем, когда больше 5}

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

Стоп, я чегото непонял?? 

У меня ведь kalAngleX это и есть переменная которая отображает градусы в реальном времени...

А переменная kalXold должна принять значение kalAngleX в точке времени момента нажатия кнопки1. Тоесть kalXold не имеет постоянного градуса. Он зависит от положения датчика в момент нажатия кнопки1. Нажал кнопку1 и тем самым сфотографировал значение kalAngleX в память kalXold.

Тоесть нажал кнопку1 и kalXold запомнил каким был тогда kalAngleX и таким и остался. А уже после сравниваем сохронившееся kalXold с kalAngleX в настоящем времени.

Тоесть, выходит что по сути сравниваем два kalAngleX Один из прошлого другой из настоящего ))

Просто того kalAngleX из прошлого надо сохранить в переменную kalXold нажатием кнопки1. и после сравнивать с настоящим изменяющимся от движения датчика kalAngleX.

Уффф.... :)

 

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

Lexan пишет:

У меня ведь kalAngleX это и есть переменная которая отображает градусы в реальном времени...

ну, ок - я начинаю цитировать себя. цикл. раздупляйся

Клапауций 232 пишет:

нет - тебе нужно инициализировать две переменные:

а и na

na = [функция считывания из гироскопа];

далее в лупе

if (abs(a - na) > 5) {a = na; // что-то делать, когда больше пяти}

Lexan
Offline
Зарегистрирован: 12.02.2016

Упс ))

Тоесть na это просто переменная и писать нужно так:

double kalXold = [kalAngleX];

void loop() {

BUTTON_01.read();

 if (BUTTON_01.click_down) 
   { 
    digitalWrite(RELAY_01, HIGH);    //включаем реле1
    Serial.println("Relay1 ON\n");   // пишем в порт
    
  if (abs(kalAngleX - kalXold) > 5) 
  {
  kalAngleX = kalXold; 
  digitalWrite(RELAY_02, HIGH);
vk007
Offline
Зарегистрирован: 16.06.2015

Lexan пишет:

У меня ведь kalAngleX это и есть переменная которая отображает градусы в реальном времени...

Ну как ты не можешь понять, нету у тебя реального времени в твоем понимании!

Чтобы в kalAngleX появилось новое значение, его туда кто-то должен поместить, посчитать и поместить. kalAngleX - это всего-лишь обычная переменная, содержащая какое-то значание, но это значение там само собой не появляется.

Если бы к твоей ардуине было прицеплено еще какое-то устройство, имеющее доступ к ее ОЗУ, и постоянно с бешенной скоростью записывающее в ячейку памяти, соответствующей kalAngleX, нужное число, то тогда да, ты бы мог расслабиться и только читать его постоянно. Или взведен таймер, который бы только и делал, что постоянно по прерываниям также с бешенной частотой отвлекал контроллер от основного цикла и вычислял kalAngleX.

А так это несчастное kalAngleX перед его проверкой надо откудато брать.

В который раз я замечаю, что ты совсем не обращаешь внимание на то, что тебе советуют, пока несколько раз тебе не напишешь.

Lexan
Offline
Зарегистрирован: 12.02.2016

Вот эта (accXangle;) та функция которая считывает данные оси X и в итоге поподает в переменную kalAngleX??

 

vk007
Offline
Зарегистрирован: 16.06.2015

В исходном коде это 50-я строка:

kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter

 

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

Lexan пишет:

Упс ))

Тоесть na это просто переменная и писать нужно так:

double kalXold = [kalAngleX];

void loop() {

BUTTON_01.read();

 if (BUTTON_01.click_down) 
   { 
    digitalWrite(RELAY_01, HIGH);    //включаем реле1
    Serial.println("Relay1 ON\n");   // пишем в порт
    
  if (abs(kalAngleX - kalXold) > 5) 
  {
  kalAngleX = kalXold; 
  digitalWrite(RELAY_02, HIGH);

double kalXold = [kalAngleX]; // не заставляй меня материться.


я же писал, что а = ГРАДУСЫ

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

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

Говоря проще перенеси фигурную скобку из 90 строки в 83

Lexan
Offline
Зарегистрирован: 12.02.2016

Mr.Privet пишет:

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

Говоря проще перенеси фигурную скобку из 90 строки в 83

 

Но мне и надо их сравнивать постоянно, но только после нажатия кнопки1.

Lexan
Offline
Зарегистрирован: 12.02.2016

Ребят, блин ничего не понимаю...

Это что получается градусы оси X которые и отображаются в kalAngleX это всё что находится после знака =

 kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000)

Ну не вижу я здесь никаких градусов отдельно ((

Или их можно както подругому считывать?

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

Lexan пишет:

Ребят, блин ничего не понимаю...

подключи вместо гироскопа две кнопки "-" и "+" - рули переменной и отлаживай код, затем подрубишь гироскоп

James
Offline
Зарегистрирован: 26.02.2016
boolean k= false;
void loop(){
if (k==true) {
 if (abs(kalAngleX-kalXold)>5){
  //действие когда разность больше 5
}
}
if(BUTTON_!1.click_down){
k=true;
kalXold=kalAngleX
//действие при нажатой кнопке 1
}
}

 

 
может с помощью флага? при нажатии кнопки мы записываем значение с датчика и выставляем флаг, потом на след такте мы его проверим и начнем уже сравнивать наше значение
Lexan
Offline
Зарегистрирован: 12.02.2016

James пишет:

boolean k= false;
void loop(){
if (k==true) {
 if (abs(kalAngleX-kalXold)>5){
  //действие когда разность больше 5
}
}
if(BUTTON_!1.click_down){
k=true;
kalXold=kalAngleX
//действие при нажатой кнопке 1
}
}

 

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

 

Спасибо друг!!! Всё получилось! Действительно функцию сравнения нужно было вынести за кнопку и использовать флаг :)
тперь прикручу пару таймеров и бузер...