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

Некоторое время назад собирал электронный уровень на базе ардуино нано и гироскопа (GY-521, MPU-6050) в целях самообразования. В проекте использовалось всего две оси, показания отклонений которых выводились на LCD – 1602 c последовательным интерфейсом I2C. Сделал одностороннюю печатную плату, распаял на ней все элементы и поместил в корпус, напечатанный на 3D принтере. Чуть с поделкой поигрался и убрал в ящик.
Собственно, на этом можно закончить, больше нет интриги. J
В виду того, что сейчас на улице лето и в разгаре строительный сезон, обратился ко мне один знакомый товарищ, как раз специализирующийся на фундаментах, с вопросом о разработке устройства для отслеживания углов отклонения бура при его углублении в грунт. Разумеется, первым делом я у него спросил о наличии готовых устройств в свободной продаже, на что он мне ответил, что есть, но очень дорого. Сам лично не проверял, но прозвучала сумма в несколько сотен тысяч рублей.
Так как у меня уже имелись выше описанные наработки, то я без особых раздумий взялся за реализацию проекта, которая по большому счету свелась к отдаленной установке дисплея с батарейным отсеком. То есть сам датчик с микроконтроллером должны быть закреплены на свободно болтающемся на стреле гидравлическом буре, а дисплей, установленный в кабине, соединен с контроллером через провод. Далее распечатал дополнительный корпус под датчик с микроконтроллером, установил их в него, вывел провод и залил все силиконом для изготовления форм. Длину провода взял с запасом (довольно большим), около десяти метров длиной. Дисплей оставил в старом корпусе, единственное - из него вывел отдельный провод для подключения батарейки (PowerBank).

#include <Wire.h> #include <LiquidCrystal_I2C.h> // Using version 1.2.1 #include "Kalman.h" Kalman kalmanX; Kalman kalmanY; uint8_t IMUAddress = 0x68; // The LCD constructor - address shown is 0x27 - may or may not be correct for yours // Also based on YWRobot LCM1602 IIC V1 LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // адрес, En, Rw, Rs, d4, d5, d6, d7, backlighPin, backlighPol pol /* 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; double X, XSumm; double Y, YSumm; int count = 0; void setup() { lcd.begin(16,2); // sixteen characters across - 2 lines lcd.backlight(); lcd.setCursor(0,0); lcd.print("CybernetSystems"); lcd.setCursor(1,1); lcd.print("you can do it!"); Wire.begin(); Serial.begin(9600); i2cWrite(0x6B,0x00); // Disable sleep mode kalmanX.setAngle(180); // Set starting angle kalmanY.setAngle(180); timer = micros(); delay(1000); lcd.setCursor(0,0);lcd.print(" "); lcd.setCursor(0,1);lcd.print(" "); XSumm=0; YSumm=0; } void loop() { 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 delete [] data; X= 180-kalAngleX; Y= 180-kalAngleY; if (count!=10) { count++; XSumm = XSumm + X; YSumm = YSumm + Y; delay(100); } else { lcd.setCursor(4,0); lcd.print(" "); lcd.setCursor(4,1); lcd.print(" "); lcd.setCursor(0,0); lcd.print("X= "); lcd.print(floor(XSumm/count), 0); lcd.setCursor(0,1); lcd.print("Y= ");lcd.print(floor(YSumm/count), 0); XSumm = 0; YSumm = 0; count = 0; } } 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 = new uint8_t [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; }
К сожалению, этот тракторишка все время находится на каком-либо из объектов и на нем довольно часто меняется навесное оборудование: ковш, бур. Так что пока нет возможности показать, как работает прибор на тракторе.
Конечно, в идеале хотелось бы избавиться от провода и дисплея в салоне, а информацию с датчика выводить в приложение на телефон, но тут моих знаний пока недостаточно и проект мог бы затянуться.
Спасибо за внимание!
