Здравствуйте, уважаемые! Помогите мне, пожалуйста. Вот программа для гироскопа, взятая с этого сайта https://arduinoplus.ru/podkluchaem-akselerometr-k-arduino/ Код отлично работает, но мне нужно сделать так, чтобы когда X и Y в мониторинге порта были равны 150 начинал светиться светодиод. Нет необходимого опыта работы с ардуино, не могу найти нужную переменную и написать правильную программу, поэтому обращаюсь к вам. Ниже код программы. Код (C++): #include <Wire.h> #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; void setup() { Wire.begin(); Serial.begin(9600); i2cWrite(0x6B,0x00); // Disable sleep mode kalmanX.setAngle(180); // Set starting angle kalmanY.setAngle(180); timer = micros(); } void loop() { /* Update all the values */ 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(" "); // 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; }
Так её там нет, переменной для включения светодиода. Её нужно создать, например Код (C++): uint8_t ledStatus; Потом включить порт светодиода на выход Код (C++): #define pinNumber 13 pinMode(pinNumber, OUTPUT); А потом менять статус светодиода, в зависимости от значений kalAngleX и kalAngleY. Если расположите эти строки в программе правильно, помогу дальше.
1. Возьмите любой скетч, типа Blink, где мигают светодиодами. Задайте точку подключения светодиода в своей программе. 2. Получили данные из гироскопа. Вам нужно на них отреагировать должным образом. По-человечески - Если X=A - сделать то, если Y=B - сделать это. По-Ардуиньи - If (X==A) {....} // ("==" а не "=") и тд. А уж потом передавать в монитор. 3. Истина - Если хочешь научиться программировать - программируй !!! ПС. Не забудьте поставить ограничительный резистор 150- 330 ом последовательно со светодиодом, чтоб не спалить Ардуину.
По моему, Вы излишне усложняете простую задачу. Зачем сохранять статус светодиода? KatanaDie Учтите при проверке условия, что kalAngleX и kalAngleY вещественные переменные (т. е. имеют дробную часть). Светодиод должен включиться когда оба значения равны 150° или когда хотя бы одно из них? В каком состоянии должен быть светодиод, если значения будут больше или меньше 150° ? В общем виде, управлять светодиодом можно так, например: Код (C++): // вставить в конец функции loop() // pinLED - пин светодиода // вкл. - когда оба угла больше или равны 150° // выкл. - если оба или один из них меньше digitalWrite(pinLED, kalAngleX >= 150.0 && kalAngleY >= 150.0);
Почти то, что нужно. Светодиод должен быть выключен, если X и Y не равны 150. Как только оба значения становятся равны 150 - светодиод горит. Поменял знак >= на ==, но это так не работает. Ну я же не сразу на форум полез, я предпочитаю всё делать самостоятельно, но тут я впал в ступор и не знаю, что делать дальше.
Как вариант: Код (C++): floor(kalAngleX) == 150.0 && floor(kalAngleY) == 150.0 Или как советовали выше: Код (C++): (kalAngleX >= 150.0 && kalAngleX < 151.0) && (kalAngleY >= 150.0 && kalAngleY < 151.0)
Спасибо большое, второй код помог, заработало, только вот диод начинает гореть очень-очень слабо, можно совет по поводу того как это исправить?
С другим скетчем, наприер стандартный Blink, светодиод горит ярко? Как подключили светодиод, может номинал токоограничивающего резистора слишком большой?
1.Правильно - включать светодиод между +5В и выводом. То есть включением будет digitalWrite(pin, LOW). Потому, что "нижний" транзистор вывода мощнее "верхнего", из-за технологии производства этих микросхем. 2.Пробуйте разные выводы. Встречаются дохловатые. Не тянут нагрузку, хотя работают. 3. Светодиоды попадаются дохлые, хотя редко. 4. Резистор проверяйте прибором, а не по маркировке. ПС. Я встречался с такими "подвохами" в технике и деталях, что глаза на лоб... Отсюда и советы.
Не скажу - давно знаю. Молодые Самоделкины могут провести эксперименты. Признаю неправоту, - если докажут. Вообще - тема широкая - не для этой ветки.
Всего лишь забыл написать pinMode на выход, хех. Всё работает как надо, спасибо большое всем за помощь!
В даташите указано четко - 40 мА. Про то, что через нижний ключ можно ещё поддать - ни слова. У Attiny441/841 есть пара выводов под названием Extra High Sink I/O Pins. Разница в том, что "0" на таких выводах немного ближе к нулевому потенциалу, чем у остальных. Про ток - ни слова.