Arduino Basierter Schub/Motor Messstand.
Ermöglicht Messung und Logging der folgenden Parameter:
|
Status: In Arbeit
/***************************************************************************** * * Copyright (c) 2013 www.der-frickler.net * * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This software is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ***************************************************************************** * * Arduino Thrustmeter to measure * Throttle, Volts, Amperes, Thrust, RPM, Temp and Vibration of * Motor / Propeller Combinations. * * *****************************************************************************/ #include <LiquidCrystal.h> #include <Servo.h> #include "Wire.h" #include "I2Cdev.h" #include "BMA150.h" #include <Hx711.h> #define thrustPinDOUT 11 #define thrustPinSCK 12 #define currentPin A2 #define voltagePin A3 #define throttlePin 3 #define rpmPin 2 //#define CALIB_THROTTLE //#define CALIB_VOLT_AMPERE //#define CALIB_THRUST // define some values used by the panel and buttons #define btnRIGHT 0 #define btnUP 1 #define btnDOWN 2 #define btnLEFT 3 #define btnSELECT 4 #define btnNONE 5 int key, lastKey = 5; int adc_key_in = 0; // How often do we do print? long time = 0; // int timeBetweenPrinting = 500; // We want a print every 500 ms; // LCD panel LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // scale Stuff Hx711 scale(thrustPinDOUT, thrustPinSCK); // Throtle Stuff Servo throttleOut; int throttleMS = 0; // ACC stuff BMA150 accel; int16_t ax, ay, az, acc, accAverage; int16_t axOffset, ayOffset, azOffset; int tempRead; float temp; // Voltage Stuff float voltsA = 0.0; // Volts int analogVoltsA = 0; // analog reading volts float voltsB = 14.0; // Volts int analogVoltsB = 990; // analog reading volts float analogVoltsAverage = 0; int analogVoltsValue; float volts; // Current Stuff float currentA = 0.0; // Ampere int analogCurrentA = 510; // analog reading current float currentB = 7.01; // Ampere int analogCurrentB = 650; // analog reading current int analogCurrentValue; float analogCurrentAverage = 0; float amperes; // Watts float watts; // Thrust Stuff long scaleOffset = 0; float scaleScale = (1992.f/4)-35.0; //float thrustA = 0.0; // Grams //int analogThrustA = 170; // analog reading thrust //float thrustB = 1000.0; // Grams //int analogThrustB = 812; // analog reading thrust //int analogThrustValue; //float analogThrustAverage = 0; float thrust; // RPM volatile long rpmStart; volatile long rpm; float rpmAverage; int propBlades = 2; void setup() { // Init Throttle Servo throttleOut.attach(throttlePin); throttleOut.writeMicroseconds(throttleMS+1000); // init Serial Serial.begin(115200); Serial.println(); Serial.println("Motorteststand - der-Frickler.net"); Serial.println(); // Init LCD lcd.begin(16, 2); lcd.setCursor(0,0); lcd.print(" Motorteststand"); lcd.setCursor(0,1); lcd.print("der-Frickler.net"); // Init RPM attachInterrupt(0, measureRPM, RISING); // init Scale scale.setScale(scaleScale); // Init ACC / Temp Wire.begin(); accel.initialize(); // Serial.println(accel.testConnection() ? "BMA150 connection successful" : "BMA150 connection failed"); accel.setRange(2); // +- 8g accel.setBandwidth(2); // 100Hz // calc ACC Offsets for (int i=0; i <= 20; i++){ accel.getAcceleration(&ax, &ay, &az); axOffset += ax; ayOffset += ay; azOffset += az; } axOffset /= 20; ayOffset /= 20; azOffset /= 20; delay(1000); lcd.clear(); writeHeader(); } void writeHeader() { // write CSV Header Serial.print("Throttle(%);"); Serial.print("Voltage(V);"); Serial.print("Current(A);"); Serial.print("Watts(W);"); Serial.print("Thrust(g);"); Serial.print("RPM(krpm);"); Serial.print("TEMP(°C);"); Serial.print("ACC;"); Serial.print("Efficiency(g/W);"); Serial.println(); } void loop() { // read Button key = read_LCD_buttons(); // save old Keystate if (key != btnNONE) { lastKey = key; } if (key == btnRIGHT) { Serial.println(); Serial.println(); Serial.println(); writeHeader(); } // check for maunal inc./dec./reset if (key == btnUP) { throttleMS += 1; } else if (key == btnDOWN) { throttleMS -= 1; } else if (key == btnSELECT) { throttleMS = 0; } // check for automatic inc./dec. if (lastKey == btnRIGHT) { throttleMS += 1; } else if (lastKey == btnLEFT) { throttleMS -= 1; } // if (throttleMS < 1000) { // Serial.println(); // Serial.println(); // Serial.println(); // writeHeader(); // } // limit Throttle throttleMS = constrain(throttleMS, 0, 1000); // Start Measuring // get volts analogVoltsValue = analogRead(voltagePin); analogVoltsAverage = 0.5*analogVoltsAverage + 0.5*analogVoltsValue; // get current int curAvCount = 10; // sample current several times analogCurrentValue = 0; for (int i=0; i < curAvCount; i++){ analogCurrentValue += analogRead(currentPin); //Serial.println(analogCurrentValue); } analogCurrentValue = analogCurrentValue/curAvCount; //Serial.println(analogCurrentValue); //Serial.println(); analogCurrentAverage = 0.5*analogCurrentAverage + 0.5*analogCurrentValue; // // get thrust // analogThrustValue = analogRead(thrustPin); // analogThrustAverage = 0.5*analogThrustAverage + 0.5*analogThrustValue; // get ACC and Temp accel.getAcceleration(&ax, &ay, &az); ax -= axOffset; ay -= ayOffset; az -= azOffset; acc = max(abs(ax), abs(ay)); acc = max(acc, abs(az)); accAverage = 0.8*accAverage + 0.2*acc; tempRead = accel.getTemperature(); temp = 0.8*temp + 0.2*((tempRead * 0.5) - 30.0); // get RPM rpmAverage = 0.8*rpmAverage + 0.2*rpm; // set throttle throttleOut.writeMicroseconds(throttleMS+1000); #ifdef CALIB_VOLT_AMPERE lcd.clear(); lcd.setCursor(0,0); lcd.print(analogVoltsAverage); lcd.setCursor(8,0); lcd.print(analogToVolts(analogVoltsAverage),1); lcd.print("V"); lcd.setCursor(0,1); lcd.print(analogCurrentAverage); lcd.setCursor(8,1); lcd.print(analogToAmperes(analogCurrentAverage),1); lcd.print("A"); delay(250); #endif #ifdef CALIB_THRUST //thrust = analogToThrust(analogThrustAverage); thrust = scale.getGram(); lcd.clear(); lcd.setCursor(0,0); // lcd.print(analogVoltsAverage); // lcd.setCursor(8,0); lcd.print(thrust,1); lcd.print(" Gram"); delay(250); #endif #if !defined (CALIB_VOLT_AMPERE) && !defined (CALIB_THRUST) // Is it time to print? if(millis() > time + timeBetweenPrinting) { // print throttle lcd.setCursor(0,0); if (throttleMS < 1000) lcd.print(" "); if (throttleMS < 100) lcd.print(" "); lcd.print(throttleMS/10); lcd.print("% "); // print Temp // if (temp < 10) lcd.print(" "); // lcd.print(temp,1); // lcd.print("C "); // Print Thrust //thrust = analogToThrust(analogThrustAverage); thrust = scale.getGram(); //thrust = analogToThrust(analogThrustValue); if (thrust < 0) thrust = 0; //if (thrust < 1000) lcd.print(" "); if (thrust < 100) lcd.print(" "); if (thrust < 10) lcd.print(" "); lcd.print(thrust,1); lcd.print("g "); // Print RPM //if (rpm < 1000) lcd.print(" "); if (rpm < 100) lcd.print(" "); if (rpm < 10) lcd.print(" "); lcd.print(rpm,1); lcd.print("R "); // Print ACC // if (accAverage < 10) lcd.print(" "); // lcd.print(accAverage,1); // lcd.print("G "); // 2nd Line lcd.setCursor(0,1); // print voltage volts = analogToVolts(analogVoltsAverage); if (volts < 10) lcd.print(" "); lcd.print(volts,1); lcd.print("V"); // print current amperes = analogToAmperes(analogCurrentValue); if (amperes < 0 ) amperes = 0.0; if (amperes < 10) lcd.print(" "); lcd.print(amperes,1); lcd.print("A"); // Print Wat watts = volts * amperes; if (watts < 100) lcd.print(" "); if (watts < 10) lcd.print(" "); lcd.print(watts,1); lcd.print("W"); if (throttleMS > 0) { // write Values to Serial as CSV Serial.print(throttleMS/10); Serial.print(";"); Serial.print(volts); Serial.print(";"); Serial.print(amperes); Serial.print(";"); Serial.print(watts); Serial.print(";"); Serial.print(thrust); Serial.print(";"); Serial.print(rpm/1000); Serial.print(";"); Serial.print(temp); Serial.print(";"); Serial.print(accAverage); Serial.print(";"); Serial.print(thrust/watts); Serial.print(";"); Serial.println(); } time = millis(); } delay(50); #endif } // read the buttons int read_LCD_buttons() { adc_key_in = analogRead(0); // read the value from the sensor // my buttons when read are centered at these valies: 0, 144, 329, 504, 741 // we add approx 50 to those values and check to see if we are close if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result // For V1.1 us this threshold if (adc_key_in < 50) return btnRIGHT; if (adc_key_in < 250) return btnUP; if (adc_key_in < 450) return btnDOWN; if (adc_key_in < 650) return btnLEFT; if (adc_key_in < 850) return btnSELECT; // For V1.0 comment the other threshold and use the one below: /* if (adc_key_in < 50) return btnRIGHT; if (adc_key_in < 195) return btnUP; if (adc_key_in < 380) return btnDOWN; if (adc_key_in < 555) return btnLEFT; if (adc_key_in < 790) return btnSELECT; */ return btnNONE; // when all others fail, return this... } float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } float analogToVolts(float analogval){ float load = mapfloat(analogval, analogVoltsA, analogVoltsB, voltsA, voltsB); return load; } float analogToAmperes(float analogval){ float load = mapfloat(analogval, analogCurrentA, analogCurrentB, currentA, currentB); return load; } //float analogToThrust(float analogval){ // float load = mapfloat(analogval, analogThrustA, analogThrustB, thrustA, thrustB); // return load; //} void measureRPM() { rpm = 60000000 / ((micros() - rpmStart) * propBlades); rpmStart = micros(); }