Но, если просто от Числа2 вычитать Число1, то разница может быть и положительной, и отрицательной (см.табличку). А abs просто отбрасывает знак. Таким образом, неважно в какую сторону получилось отклонение в плюс или в минус реле сработает. Так понятно?
Ребят а как обьяснить переменной kalXold что она должна обнулится?
Клапауций 322 и Клапауций 232 уже несколько раз отправляли почитать, извини, но отправлю и я тебя туда же. Конкретно по этому вопросу читай тут. Как начитаешься и, если останутся дельные вопросы, возвращайся, продолжим.
А вот так при нажатии на кнопку1, почемуто вместе с реле1 включается сразу реле2 хотя по условию не должно (так как отклонения от градусов не происходило)...
Попробавал сделать так но почемуто светодиод на 13 PIN (он вместо реле02 пока) не срабатывает
Как быстро меняется значение kalAngleX? Если успеет поменяться за время, прошедшее между выполнением строки 05 и строки 06, то все будет ОК. Но я в этом очень и очень сомневаюсь. При таком алгоритме работы, как сейчас, kalAngleX будет сравниваться практически само с собой.
А вот так при нажатии на кнопку1, почемуто вместе с реле1 включается сразу реле2 хотя по условию не должно (так как отклонения от градусов не происходило)...
А вот так при нажатии на кнопку1, почемуто вместе с реле1 включается сразу реле2 хотя по условию не должно (так как отклонения от градусов не происходило)...
Откуда мне знать. Я потому и спрашивал, как быстро меняется значение kalAngleX.
Для того чтобы посмотреть, что оно действительно ловит изменение, паузу и через delay() поставить можно. Но для готового устройства от delay лучше отказаться и поменять алгоритм работы тоже.
kalXold = kalAngleX; //копируем значение X по нажатию и отдаем его переменной kalXold
if (abs(kalXold - kalAngleX) > 5) // есле kalXold бельше или меньше 5 то...
Мне непонятен ее загадочный смысл в таком виде. Снова повторюсь - kalAngleX сравнивается практически само с собой. Ну не успеет оно так быстро поменяться.
И, кстати, не "есле kalXold бельше или меньше 5 то...", а "отклонение kalAngleX от kalXold..."
kalXold = kalAngleX; //копируем значение X по нажатию и отдаем его переменной kalXold
if (abs(kalXold - kalAngleX) > 5) // есле kalXold бельше или меньше 5 то...
Мне непонятен ее загадочный смысл в таком виде. Снова повторюсь - kalAngleX сравнивается практически само с собой. Ну не успеет оно так быстро поменяться.
И, кстати, не "есле kalXold бельше или меньше 5 то...", а "отклонение kalAngleX от kalXold..."
так, ну... отклонение это же тоже подходит. Суть же таже.
Непойму почему неуспеет то? Получается же так: нажимаю кнопку1, значение kalAngleX скопировалось в переменную kalXold и сохранилось там. т.е kalAngleX живет своей жизнью и меняется в зависимости от наклона датчика, а kalXold можно сказать сфоткало число и больше его не меняет (kalXold остаётся таким каким было kalAngleX в момент нажатия на кнопку1)...
// допустим 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 в данный момент???
kalXold = kalAngleX; // то они будут всегда рввны друг другу? И каким бы не стало значение kalAngleX то значение kalXold тутже станет таким же?
ок. сначала - когда ты делаешь kalXold = kalAngleX; , что блин происходит?
прекрати относится к коду контроллера как к одушевлённому существу - если код в каком-то участке кода уравнивает две переменные, то нет смысла эти переменные сравнивать сразу же после уравнивания - ты должен понимать, что они всегда будут равны друг-другу.
kalXold = kalAngleX; // то они будут всегда рввны друг другу? И каким бы не стало значение kalAngleX то значение kalXold тутже станет таким же?
ок. сначала - когда ты делаешь kalXold = kalAngleX; , что блин происходит?
прекрати относится к коду контроллера как к одушевлённому существу - если код в каком-то участке кода уравнивает две переменные, то нет смысла эти переменные сравнивать сразу же после уравнивания - ты должен понимать, что они всегда будут равны друг-другу.
Вот засада! Значит нужно както по другому копировать значение (kalAngleX) в (kalXold) и при этом оно должно скопироватся только один раз и по нажатию кнопки...
Но я незнаю такой функцый ??? Это значит что сохронять надо в EEPROM чтоли???
Но ведь чтобы получать значение в градусах нужен фильтр Калмана? Так? а функция (na) будет считывать данные напрямую?
тоесть получается: (a) это (kalAngleX) тоесть обработанное фильтром число и переведённое в градусы,
А kalXold будет считывать значение c помощью функцыи (na) не обработанное фильтром Калмана.
Или я неправельно понимаю?
Просто гдето прочёл, что из mpu6050 выходят сырые данные и чтобы они приняли человеческий вид используют фильтр калмана или какойто внутренний встроенный вычеслитель.
а функция na считает градусы только один раз? или будит считывать их постоянно?
Или это тупой вопрос??? ))
смотри - у тебя было так:
kalXold = kalAngleX; //копируем значение X по нажатию и отдаем его переменной kalXold
if (abs(kalXold - kalAngleX) > 5) // есле kalXold бельше или меньше 5 то...
а нужно так
kalAngleX = [градусы];
if (abs(kalXold - kalAngleX) > 5) {kalXold = kalAngleX; // что-то делаем, когда больше 5}
я не знаю, как ты вычисляешь градусы и когда тебе нужно сравнивать отклонение - это ты сам реши:кнопка, условие, пр.
Возьми лист бумаги, карандаш и составь алгоритм (учил наверное на информатике, что это и для чего). Не обязательно красивый, с ромбиками и прямоугольничками, как на уроках, а простой в виде списка: 1) сделать то, 2) сделать другое, 3) сравнить что-то с чем-то, 4) если получилось одно то перейти на п.10, иначе на п.32 и т.д.
А уже потом, когда несколько раз пройдешся по нему и поймешь, что он составлен правильно, так как надо, берись за программу.
Лучше пиши по кусочкам. Сделай одну программу - обработка кнопок, потом еще одну - вычисление угла, дальше еще одна - еще что-то. И пока не обкатаешь каждую таку минипрограмку и не поймешь, как она работает, за новую не берись.
Извини, но с такими знаниями сразу писать сложную программу и пытаться что-то выдумывать на ходу - это тупик.
а функция 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.
У меня ведь kalAngleX это и есть переменная которая отображает градусы в реальном времени...
Ну как ты не можешь понять, нету у тебя реального времени в твоем понимании!
Чтобы в kalAngleX появилось новое значение, его туда кто-то должен поместить, посчитать и поместить. kalAngleX - это всего-лишь обычная переменная, содержащая какое-то значание, но это значение там само собой не появляется.
Если бы к твоей ардуине было прицеплено еще какое-то устройство, имеющее доступ к ее ОЗУ, и постоянно с бешенной скоростью записывающее в ячейку памяти, соответствующей kalAngleX, нужное число, то тогда да, ты бы мог расслабиться и только читать его постоянно. Или взведен таймер, который бы только и делал, что постоянно по прерываниям также с бешенной частотой отвлекал контроллер от основного цикла и вычислял kalAngleX.
А так это несчастное kalAngleX перед его проверкой надо откудато брать.
В который раз я замечаю, что ты совсем не обращаешь внимание на то, что тебе советуют, пока несколько раз тебе не напишешь.
В преведенной выше программе сравнивание значений происходит только тогда, когда нажимается кнопка 1. если вынести ее из этого цикла то она будет сравниваться каждый проход лупа. А сейчас только когда нажата кнопка...
Говоря проще перенеси фигурную скобку из 90 строки в 83
В преведенной выше программе сравнивание значений происходит только тогда, когда нажимается кнопка 1. если вынести ее из этого цикла то она будет сравниваться каждый проход лупа. А сейчас только когда нажата кнопка...
Говоря проще перенеси фигурную скобку из 90 строки в 83
Но мне и надо их сравнивать постоянно, но только после нажатия кнопки1.
boolean k= false;
void loop(){
if (k==true) {
if (abs(kalAngleX-kalXold)>5){
//действие когда разность больше 5
}
}
if(BUTTON_!1.click_down){
k=true;
kalXold=kalAngleX
//действие при нажатой кнопке 1
}
}
может с помощью флага? при нажатии кнопки мы записываем значение с датчика и выставляем флаг, потом на след такте мы его проверим и начнем уже сравнивать наше значение
boolean k= false;
void loop(){
if (k==true) {
if (abs(kalAngleX-kalXold)>5){
//действие когда разность больше 5
}
}
if(BUTTON_!1.click_down){
k=true;
kalXold=kalAngleX
//действие при нажатой кнопке 1
}
}
может с помощью флага? при нажатии кнопки мы записываем значение с датчика и выставляем флаг, потом на след такте мы его проверим и начнем уже сравнивать наше значение
Спасибо друг!!! Всё получилось! Действительно функцию сравнения нужно было вынести за кнопку и использовать флаг :)
Теперь я уже что-то не пойму. Задача была поставлена:
Я ее понимаю так. Допустим, Число1=180 и, в зависимости от Числа2 (а точнее от их разницы Число2-Число1):
Но, если просто от Числа2 вычитать Число1, то разница может быть и положительной, и отрицательной (см.табличку). А abs просто отбрасывает знак. Таким образом, неважно в какую сторону получилось отклонение в плюс или в минус реле сработает. Так понятно?
Ребят а как обьяснить переменной kalXold что она должна обнулится?
Клапауций 322 и Клапауций 232 уже несколько раз отправляли почитать, извини, но отправлю и я тебя туда же. Конкретно по этому вопросу читай тут. Как начитаешься и, если останутся дельные вопросы, возвращайся, продолжим.
Ну вроде бы получилось обнулять с помощью кнопки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"); }Не вижу смысла в строках 06-15 - реле включится при любых значениях разницы.
Попробавал сделать так но почемуто светодиод на 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");А вот так при нажатии на кнопку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"); }Попробавал сделать так но почемуто светодиод на 13 PIN (он вместо реле02 пока) не срабатывает
Как быстро меняется значение kalAngleX? Если успеет поменяться за время, прошедшее между выполнением строки 05 и строки 06, то все будет ОК. Но я в этом очень и очень сомневаюсь. При таком алгоритме работы, как сейчас, kalAngleX будет сравниваться практически само с собой.
А вот так при нажатии на кнопку1, почемуто вместе с реле1 включается сразу реле2 хотя по условию не должно (так как отклонения от градусов не происходило)...
Об этом я уже упоминал в сообщении #55.
А вот так при нажатии на кнопку1, почемуто вместе с реле1 включается сразу реле2 хотя по условию не должно (так как отклонения от градусов не происходило)...
Об этом я уже упоминал в сообщении #55.
Да действительно второе реле перестает включатся от кнопки1 если использовать abs.
Так теперь мне там между 05 и 06 нужна задержка по времени? Изза этого значит и не срабатывает реле2 во время отклонения на 5 и более градусов.
А сколько примерно миллисикунд?
А сколько примерно миллисикунд?
Откуда мне знать. Я потому и спрашивал, как быстро меняется значение kalAngleX.
Для того чтобы посмотреть, что оно действительно ловит изменение, паузу и через delay() поставить можно. Но для готового устройства от delay лучше отказаться и поменять алгоритм работы тоже.
Пробовал и 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; }Я снова обращаю внимание на конструкцию:
Мне непонятен ее загадочный смысл в таком виде. Снова повторюсь - kalAngleX сравнивается практически само с собой. Ну не успеет оно так быстро поменяться.
И, кстати, не "есле kalXold бельше или меньше 5 то...", а "отклонение kalAngleX от kalXold..."
Я снова обращаю внимание на конструкцию:
Мне непонятен ее загадочный смысл в таком виде. Снова повторюсь - kalAngleX сравнивается практически само с собой. Ну не успеет оно так быстро поменяться.
И, кстати, не "есле kalXold бельше или меньше 5 то...", а "отклонение kalAngleX от kalXold..."
так, ну... отклонение это же тоже подходит. Суть же таже.
Непойму почему неуспеет то? Получается же так: нажимаю кнопку1, значение kalAngleX скопировалось в переменную kalXold и сохранилось там. т.е kalAngleX живет своей жизнью и меняется в зависимости от наклона датчика, а kalXold можно сказать сфоткало число и больше его не меняет (kalXold остаётся таким каким было kalAngleX в момент нажатия на кнопку1)...
Нет, так не получается. Сейчас получается так: при каждом нажатии на кнопку kalAngleX копируется в kalXold и тут же эти две переменные сравниваются.
Например, kalAngleX=150. Скопировали мы его в kalXold и теперь kalXold тоже =150. Далее их сравниваем. Что будет если сравнить 150 и 150?
Непойму почему неуспеет то?
В дополнение, перед тем, как сравнивать kalAngleX с предыдущим значением его надо вычислить!
Т.е. алгоритм работы должен быть примерно следующим:
1) вычислить kalAngleX;
2) сравнить его с предыдущим значением (т.е. с kalXold);
3) по результату сравнения сделать то, что требуется;
4) запомнить kalAngleX в kalXold для будущего сравнения.
Непойму почему неуспеет то?
Тоесть, я неправильно объясняю переменной kalXold как копировать число kalAngleX ? и если я пишу в кнопке1
kalXold = kalAngleX; // то они будут всегда рввны друг другу? И каким бы не стало значение kalAngleX то значение kalXold тутже станет таким же?
А то, что в порту пишет после нажатия кнопки1, к примеру oldX:178 и замерает, и, в то же время, ось X:190 показывает и меняется как хочет не влияя на показания oldX.
Это просто так т.е oldX пишет неправду??? Вернее, пишет не то что происходит с переменной kalXold в данный момент???
В дополнение, перед тем, как сравнивать 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; }kalXold = kalAngleX; // то они будут всегда рввны друг другу? И каким бы не стало значение kalAngleX то значение kalXold тутже станет таким же?
ок. сначала - когда ты делаешь kalXold = kalAngleX; , что блин происходит?
прекрати относится к коду контроллера как к одушевлённому существу - если код в каком-то участке кода уравнивает две переменные, то нет смысла эти переменные сравнивать сразу же после уравнивания - ты должен понимать, что они всегда будут равны друг-другу.
kalXold = kalAngleX; // то они будут всегда рввны друг другу? И каким бы не стало значение kalAngleX то значение kalXold тутже станет таким же?
ок. сначала - когда ты делаешь kalXold = kalAngleX; , что блин происходит?
прекрати относится к коду контроллера как к одушевлённому существу - если код в каком-то участке кода уравнивает две переменные, то нет смысла эти переменные сравнивать сразу же после уравнивания - ты должен понимать, что они всегда будут равны друг-другу.
Вот засада! Значит нужно както по другому копировать значение (kalAngleX) в (kalXold) и при этом оно должно скопироватся только один раз и по нажатию кнопки...
Но я незнаю такой функцый ??? Это значит что сохронять надо в EEPROM чтоли???
нет - тебе нужно инициализировать две переменные:
а и na
na = [функция считывания из гироскопа];
далее в лупе
if(abs(a - na) > 5) {a = na; // что-то делать, когда больше пяти}Но ведь чтобы получать значение в градусах нужен фильтр Калмана? Так? а функция (na) будет считывать данные напрямую?
тоесть получается: (a) это (kalAngleX) тоесть обработанное фильтром число и переведённое в градусы,
А kalXold будет считывать значение c помощью функцыи (na) не обработанное фильтром Калмана.
Или я неправельно понимаю?
Просто гдето прочёл, что из mpu6050 выходят сырые данные и чтобы они приняли человеческий вид используют фильтр калмана или какойто внутренний встроенный вычеслитель.
Но ведь чтобы получать значение в градусах нужен фильтр Калмана? Так? а функция (na) будет считывать данные напрямую?
не додумывай того, чего нет - делаешь na = градусы. всё. дальше всё сделается автоматом
как ты эти градусы вычисляешь - никому не интересно
Извиняюсь за любопыцтво :)
а функция na считает градусы только один раз? или будит считывать их постоянно?
Или это тупой вопрос??? ))
а функция na считает градусы только один раз? или будит считывать их постоянно?
Как сделаешь, так и будет.
Извиняюсь за любопыцтво :)
а функция na считает градусы только один раз? или будит считывать их постоянно?
Или это тупой вопрос??? ))
смотри - у тебя было так:
а нужно так
kalAngleX = [градусы]; if (abs(kalXold - kalAngleX) > 5) {kalXold = kalAngleX; // что-то делаем, когда больше 5}я не знаю, как ты вычисляешь градусы и когда тебе нужно сравнивать отклонение - это ты сам реши:кнопка, условие, пр.
Возьми лист бумаги, карандаш и составь алгоритм (учил наверное на информатике, что это и для чего). Не обязательно красивый, с ромбиками и прямоугольничками, как на уроках, а простой в виде списка: 1) сделать то, 2) сделать другое, 3) сравнить что-то с чем-то, 4) если получилось одно то перейти на п.10, иначе на п.32 и т.д.
А уже потом, когда несколько раз пройдешся по нему и поймешь, что он составлен правильно, так как надо, берись за программу.
Лучше пиши по кусочкам. Сделай одну программу - обработка кнопок, потом еще одну - вычисление угла, дальше еще одна - еще что-то. И пока не обкатаешь каждую таку минипрограмку и не поймешь, как она работает, за новую не берись.
Извини, но с такими знаниями сразу писать сложную программу и пытаться что-то выдумывать на ходу - это тупик.
Извиняюсь за любопыцтво :)
а функция na считает градусы только один раз? или будит считывать их постоянно?
Или это тупой вопрос??? ))
смотри - у тебя было так:
а нужно так
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.
Уффф.... :)
У меня ведь kalAngleX это и есть переменная которая отображает градусы в реальном времени...
ну, ок - я начинаю цитировать себя. цикл. раздупляйся
нет - тебе нужно инициализировать две переменные:
а и na
na = [функция считывания из гироскопа];
далее в лупе
if(abs(a - na) > 5) {a = na; // что-то делать, когда больше пяти}Упс ))
Тоесть 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);У меня ведь kalAngleX это и есть переменная которая отображает градусы в реальном времени...
Ну как ты не можешь понять, нету у тебя реального времени в твоем понимании!
Чтобы в kalAngleX появилось новое значение, его туда кто-то должен поместить, посчитать и поместить. kalAngleX - это всего-лишь обычная переменная, содержащая какое-то значание, но это значение там само собой не появляется.
Если бы к твоей ардуине было прицеплено еще какое-то устройство, имеющее доступ к ее ОЗУ, и постоянно с бешенной скоростью записывающее в ячейку памяти, соответствующей kalAngleX, нужное число, то тогда да, ты бы мог расслабиться и только читать его постоянно. Или взведен таймер, который бы только и делал, что постоянно по прерываниям также с бешенной частотой отвлекал контроллер от основного цикла и вычислял kalAngleX.
А так это несчастное kalAngleX перед его проверкой надо откудато брать.
В который раз я замечаю, что ты совсем не обращаешь внимание на то, что тебе советуют, пока несколько раз тебе не напишешь.
Вот эта (accXangle;) та функция которая считывает данные оси X и в итоге поподает в переменную kalAngleX??
В исходном коде это 50-я строка:
Упс ))
Тоесть 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);я же писал, что а = ГРАДУСЫ
В преведенной выше программе сравнивание значений происходит только тогда, когда нажимается кнопка 1. если вынести ее из этого цикла то она будет сравниваться каждый проход лупа. А сейчас только когда нажата кнопка...
Говоря проще перенеси фигурную скобку из 90 строки в 83
В преведенной выше программе сравнивание значений происходит только тогда, когда нажимается кнопка 1. если вынести ее из этого цикла то она будет сравниваться каждый проход лупа. А сейчас только когда нажата кнопка...
Говоря проще перенеси фигурную скобку из 90 строки в 83
Но мне и надо их сравнивать постоянно, но только после нажатия кнопки1.
Ребят, блин ничего не понимаю...
Это что получается градусы оси X которые и отображаются в kalAngleX это всё что находится после знака =
kalAngleX =
kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000)Ну не вижу я здесь никаких градусов отдельно ((Или их можно както подругому считывать?Ребят, блин ничего не понимаю...
подключи вместо гироскопа две кнопки "-" и "+" - рули переменной и отлаживай код, затем подрубишь гироскоп
boolean k= false; void loop(){ if (k==true) { if (abs(kalAngleX-kalXold)>5){ //действие когда разность больше 5 } } if(BUTTON_!1.click_down){ k=true; kalXold=kalAngleX //действие при нажатой кнопке 1 } }boolean k= false; void loop(){ if (k==true) { if (abs(kalAngleX-kalXold)>5){ //действие когда разность больше 5 } } if(BUTTON_!1.click_down){ k=true; kalXold=kalAngleX //действие при нажатой кнопке 1 } }