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(); }
Ich garantiere bei meinen Bauberichten und Teilelisten keine Vollständigkeit etc...es wird aus den Teilen gebastelt die gerade herumliegen.
Bitte keine Anfragen zum Bau/Fräsen von Frames, Teilen oder sonstigen Aufträgen. Ich betreibe die Seite rein als Hobby und nutze die zur Verfügung stehende Zeit gerne für meine eigenen Projekte.
Bei einigen Projekten werde ich zu gegebener Zeit die Pläne veröffentlichen - aber auch hier lasse ich mich ungern hetzten ;-)
No waranties for completeness of any contructions, part lists etc.. I build from party i have just lying around in my workshop.
Please, No requests to buy frames, builds, etc.. I run this page in my spare-time and as hobby only. Want to keep my free time to work on my own projects - sorry
I will release the plans for some build at some point in time, but again, please don't ask for unreleased plans, i don't want to get rushed ;-)