Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
| ||||||
|
The existing motor tests benchs, thrust and power analyzer, are very expensive, I tried to make one at low cost, less than 30 €
In addition I created an Android application for the real-time display of the parameters:
Battery voltage
Rotation Speed
Thrust
Amperage
Power
I also wanted to make a simple fixing system allowing to test the various brushless motors or Electric Ducted Fan (EDF) with fast assembly and disassembly.
The test bench allows easy use of ESCs of different powers in order to adapt to the motors to be tested.
With this test bench you can choose your engine / propeller / ESC or EDF / ESC torque according to the characteristics of the aircraft you are building and check that the choice made will allow the aircraft to fly, you need a weight / traction power ratio greater than 1 and even 1.5.
The created application saves the data for storage and for later analysis
and the results
another test with two EDF and one brushless motor
a fine example of achievement by a pilot Mr. Mihály Váradi from Hungary Who compete in the free flight categories F1Q and F1B
#define cs 10
#define dc 9
#define rst 8
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
//hx711 capteur de force
#include <HX711.h>
const int DOUT=A1;
const int CLK=A0;
HX711 balance;
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
int sensorPinV = A3;// lecture tension aprs division
int sensorPinA = A4;// lecture amperage capteur de courant
float sensorValueV = 0;
float sensorValueA = 0;
float sensorValueT = 0;
int sensorValueR = 0;
int watts=0;
float maxT = 0, highT = 0;
float maxA = 0, highA = 0;
float maxV = 0, highV = 0;
float maxR = 0, highR = 0;
int maxW=0 ;
int highW = 0;
int x=80;
int xh=80;
//tachymetre
float value=0 ;
float rev=0 ;
int rpm ;
int oldtime=0 ;
int time ;
void isr() //interrupt service routine
{
rev++ ;
}
void setup(){
attachInterrupt(0,isr,RISING) ;
Serial.begin(9600);
//capteur de force
balance.begin(DOUT, CLK);
balance.set_scale(408582.25);
balance.tare(20);
// initialisation ecran
tft.initR(INITR_GREENTAB);
tft.fillScreen(ST7735_BLACK);
tft.setTextSize(2);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
//ecran d'accueuil
tft.setCursor(30, 1);
tft.print("THRUST ");
tft.setCursor(35, 30);
tft.print("STAND");
tft.setCursor(50, 60);
tft.print("YM");
tft.setCursor(8, 80);
tft.setTextSize(1);
tft.setTextColor(ST7735_YELLOW,ST7735_BLACK);
tft.print("mesures : ");
tft.setCursor(10, 100);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print("thrust G ");
tft.setCursor(10, 110);
tft.print("tension batterie V ");
tft.setCursor(10, 120);
tft.print("Amperage A ");
tft.setCursor(10, 130);
tft.print("v rotation T/min ");
tft.setCursor(10, 140);
tft.print("puissance W ");
delay (500);
//ecran d'avertissement de danger
for (int i=0; i <= 10; i++){
tft.fillScreen(ST7735_BLACK);
tft.setTextSize(2);
tft.setTextColor(ST7735_RED,ST7735_BLACK);
tft.setCursor(10, 10);
tft.print("ATTENTION ");
tft.setCursor(25, 50);
tft.print("DANGER");
tft.setCursor(10, 70);
tft.print("ELOIGNER ");
tft.setCursor(40, 90);
tft.print("VOUS");
tft.setCursor(50, 110);
tft.print("DE");
tft.setCursor(10, 130);
tft.print(" L'HELICE ");
delay (50);
}
tft.fillScreen(ST7735_BLACK);
}
void loop(){
delay(1000);
// tachymetre
detachInterrupt(0) ; //detaches the interrupt
time=millis()-oldtime ; //finds the time
rpm=(rev/time)*60000*2 ;
oldtime=millis() ; //saves the current time
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.setCursor(33, 44);
tft.print(" ");
//
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
sensorValueV = analogRead(sensorPinV); //lecture de la tension
sensorValueA = analogRead(sensorPinA); //lecture de l'amperage
sensorValueR = (rpm); //lecture vitesse rotation
cadre();
//affichage ecran batterie
tft.setCursor(5, 7);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("Vbat ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(sensorValueV/1023*23.9,2);
//Serial.print("Vbat");
// Serial.println(sensorValueV/1023*23.9,2);
tft.setCursor(5, 20);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("maxV ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxV,2);
//Serial.print("Vbatmax");
// Serial.println(maxV,2);
//affichage ecran vitesse rotation
tft.setCursor(5, 44);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("V rot");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(sensorValueR);tft.print(" ");
tft.setCursor(5, 57);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("maxR ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxR,0);
//affichage ecran Thrust
tft.setCursor(5, 80);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("TActu:");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print (balance.get_units()*1000,0);tft.print(" ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.setCursor(5, 95);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("T max ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxT,0);tft.print(" ");
courbeA();
//affichage ecran Amperage Amperage = lecture Ax/22.5 selon etalonnage capteur
tft.setCursor(5, 115);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("A Act:");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print ((sensorValueA/22.5),1);
Serial.print("#");
Serial.println(int(balance.get_units()*1000));
Serial.print("");
Serial.println(sensorValueR);
Serial.print("%");
Serial.println((sensorValueA/22.5),1);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
tft.setCursor(5, 130);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("Amax:");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxA,1);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
//affichage ecran puissance max
watts=(sensorValueA/22.5)*(sensorValueV/1023*23.9);
tft.setCursor(5, 148);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("watts ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(watts);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print(" max ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxW);
tft.print(" ");
maxiR();
maxiA();
maxiV();
maxiT();
maximumW();
rev=0 ;
attachInterrupt(0,isr,RISING) ;//tacymetre
}
void cadre() {
// affichage ecran
//cadre
tft.drawLine(0,0,130,0,ST7735_RED);
tft.drawLine(0,1,130,1,ST7735_RED);
tft.drawLine(0,158,130,158,ST7735_RED);
tft.drawLine(0,142,130,142,ST7735_RED);
tft.drawLine(0,141,130,141,ST7735_RED);
tft.drawLine(0,107,130,107,ST7735_RED);
tft.drawLine(0,108,130,108,ST7735_RED);
tft.drawLine(80,1,80,140,ST7735_RED);
tft.drawLine(81,1,81,140,ST7735_RED);
tft.drawLine(0,159,130,159,ST7735_RED);
tft.drawLine(0,0,0,156,ST7735_RED);
tft.drawLine(1,1,1,157,ST7735_RED);
tft.drawLine(127,0,127,156,ST7735_RED);
tft.drawLine(126,0,126,156,ST7735_RED);
tft.drawLine(0,35,130,35,ST7735_RED);
tft.drawLine(0,36,130,36,ST7735_RED);
tft.drawLine(0,70,130,70,ST7735_RED);
tft.drawLine(0,71,130,71,ST7735_RED);
}
void courbeA() {
float nouvelleValeurA;
float nouvelleValeurV;
float nouvelleValeurT;
float nouvelleValeurR;
// converison Ampere voltage et thrust en pixel
nouvelleValeurA = map((sensorValueA/22.5), 0, 8, 137, 110); // car l'cran a 64 pixels de haut
nouvelleValeurV = map((sensorValueV/1023*23.9), 0, 20, 33,3); // car l'cran a 64 pixels de haut
nouvelleValeurT = map(balance.get_units()*1000, 0, 400, 104, 72); // car l'cran a 64 pixels de haut
nouvelleValeurR = map(rpm, 0, 30000, 68, 40); // car l'cran a 64 pixels de haut
x++;
tft.drawPixel(x,nouvelleValeurA,ST7735_CYAN);
tft.drawPixel(x,nouvelleValeurV,ST7735_CYAN);
tft.drawPixel(x,nouvelleValeurT,ST7735_CYAN);
tft.drawPixel(x,nouvelleValeurR,ST7735_CYAN);
if (x>123) {
x=80;
tft.fillRect(82,110,43,30,ST7735_BLACK);
tft.fillRect(82,1,43,33,ST7735_BLACK);
tft.fillRect(82,72,43,35,ST7735_BLACK);
tft.fillRect(82,38,43,33,ST7735_BLACK);
}
}
void maxiV() {
// calcul voltage maximum
highV = (sensorValueV/1023*23.9);
if (highV > maxV) {
maxV = highV;
}
}
void maxiA() {
// calcul amperage maximum
highA = (sensorValueA/22.5);
if ( highA > maxA) {
maxA = highA;
}
}
void maxiR() {
// calcul rotation maximum
highR = (rpm);
if (highR > maxR) {
maxR = highR;
}
}
void maximumW() {
// calcul rotation maximum
highW = (watts);
if (highW > maxW) {
maxW = highW;
}
}
void maxiT() {
// calcul voltage maximum
highT = (balance.get_units()*1000);
if (highT > maxT) {
maxT = highT;
}
}
//tachymetre
#define INTERRUPT_PIN 0 // Arduino Mega digital pin 2
volatile int interruptCount;
float rpm = 0;
float numpoles = 14; //Change value to the number of magnets
#define cs 10
#define dc 9
#define rst 8
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
//hx711 capteur de force
#include <HX711.h>
const int DOUT=A1;
const int CLK=A0;
HX711 balance;
Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);
int sensorPinV = A3;// lecture tension aprs division
int sensorPinA = A4;// lecture amperage capteur de courant
float sensorValueV = 0;
float sensorValueA = 0;
float sensorValueT = 0;
int sensorValueR = 0;
int watts=0;
float maxT = 0, highT = 0;
float maxA = 0, highA = 0;
float maxV = 0, highV = 0;
float maxR = 0, highR = 0;
int maxW=0 ;
int highW = 0;
int x=80;
int xh=80;
void setup(){
Serial.begin(9600);
// RPM COUNTER INIT tachymetre
pinMode(INTERRUPT_PIN, INPUT);
attachInterrupt(INTERRUPT_PIN, interruptFired, CHANGE);
//capteur de force
balance.begin(DOUT, CLK);
balance.set_scale(408582.25);
balance.tare(20);
// initialisation ecran
tft.initR(INITR_GREENTAB);
tft.fillScreen(ST7735_BLACK);
tft.setTextSize(2);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
//ecran d'accueuil
tft.setCursor(30, 1);
tft.print("THRUST ");
tft.setCursor(35, 30);
tft.print("STAND");
tft.setCursor(50, 60);
tft.print("YM");
tft.setCursor(8, 80);
tft.setTextSize(1);
tft.setTextColor(ST7735_YELLOW,ST7735_BLACK);
tft.print("mesures : ");
tft.setCursor(10, 100);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print("thrust G ");
tft.setCursor(10, 110);
tft.print("tension batterie V ");
tft.setCursor(10, 120);
tft.print("Amperage A ");
tft.setCursor(10, 130);
tft.print("v rotation T/min ");
tft.setCursor(10, 140);
tft.print("puissance W ");
delay (500);
//ecran d'avertissement de danger
for (int i=0; i <= 10; i++){
tft.fillScreen(ST7735_BLACK);
tft.setTextSize(2);
tft.setTextColor(ST7735_RED,ST7735_BLACK);
tft.setCursor(10, 10);
tft.print("ATTENTION ");
tft.setCursor(25, 50);
tft.print("DANGER");
tft.setCursor(10, 70);
tft.print("ELOIGNER ");
tft.setCursor(40, 90);
tft.print("VOUS");
tft.setCursor(50, 110);
tft.print("DE");
tft.setCursor(10, 130);
tft.print(" L'HELICE ");
delay (50);
}
tft.fillScreen(ST7735_BLACK);
char buffer[15];
String valeurThrust = "";
}
void loop(){
checkRPM();
delay(10);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.setCursor(33, 44);
tft.print(" ");
//
tft.setTextSize(1);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
sensorValueV = analogRead(sensorPinV); //lecture de la tension
sensorValueA = analogRead(sensorPinA); //lecture de l'amperage
sensorValueR = (rpm); //lecture vitesse rotation
cadre();
//affichage ecran batterie
tft.setCursor(5, 7);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("Vbat ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(sensorValueV/1023*23.9,2);
//Serial.print("Vbat");
// Serial.println(sensorValueV/1023*23.9,2);
tft.setCursor(5, 20);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("maxV ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxV,2);
//Serial.print("Vbatmax");
// Serial.println(maxV,2);
//affichage ecran vitesse rotation
tft.setCursor(3, 44);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("V rot:");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(sensorValueR);tft.print(" ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.setCursor(5, 57);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("maxR ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxR,0);
//affichage ecran Thrust
tft.setCursor(5, 80);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("TActu:");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print (balance.get_units()*1000,0);tft.print(" ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.setCursor(5, 95);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("T max ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxT,0);tft.print(" ");
courbeA();
//affichage ecran Amperage Amperage = lecture Ax/22.5 selon etalonnage capteur
tft.setCursor(5, 115);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("A Act:");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print ((sensorValueA/22.5),1);
Serial.print("#");
Serial.println(int(balance.get_units()*1000));
Serial.print("");
Serial.println(sensorValueR);
Serial.print("%");
Serial.println((sensorValueA/22.5));
Serial.print("");
Serial.println((sensorValueV/1023*23.9));
Serial.print("/");
String separateur = ",";
String voltage = String((sensorValueV/1023*23.9),2);
String voltagemax = String((maxV), 2);
String thrust = String (balance.get_units()*1000);
String thrustmax = String (maxT);
String rotation = String(sensorValueR);
String rotationmax = String(maxR);
String ampere = String(sensorValueA/22.5);
String amperemax = String((maxA), 2);
Serial.print(",");
Serial.println (voltage+separateur+voltagemax+separateur+thrust+separateur+thrustmax+separateur +rotation+separateur+rotationmax+separateur+ ampere+separateur+amperemax);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(" ");
tft.setCursor(5, 130);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("Amax:");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxA,1);
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
//affichage ecran puissance max
watts=(sensorValueA/22.5)*(sensorValueV/1023*23.9);
tft.setCursor(5, 148);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print("watts ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(watts);
tft.setTextColor(ST7735_GREEN,ST7735_BLACK);
tft.print(" max ");
tft.setTextColor(ST7735_CYAN,ST7735_BLACK);
tft.print(maxW);
tft.print(" ");
maxiR();
maxiA();
maxiV();
maxiT();
maximumW();
}
void cadre() {
// affichage ecran
//cadre
tft.drawLine(0,0,130,0,ST7735_RED);
tft.drawLine(0,1,130,1,ST7735_RED);
tft.drawLine(0,158,130,158,ST7735_RED);
tft.drawLine(0,142,130,142,ST7735_RED);
tft.drawLine(0,141,130,141,ST7735_RED);
tft.drawLine(0,107,130,107,ST7735_RED);
tft.drawLine(0,108,130,108,ST7735_RED);
tft.drawLine(80,1,80,140,ST7735_RED);
tft.drawLine(81,1,81,140,ST7735_RED);
tft.drawLine(0,159,130,159,ST7735_RED);
tft.drawLine(0,0,0,156,ST7735_RED);
tft.drawLine(1,1,1,157,ST7735_RED);
tft.drawLine(127,0,127,156,ST7735_RED);
tft.drawLine(126,0,126,156,ST7735_RED);
tft.drawLine(0,35,130,35,ST7735_RED);
tft.drawLine(0,36,130,36,ST7735_RED);
tft.drawLine(0,70,130,70,ST7735_RED);
tft.drawLine(0,71,130,71,ST7735_RED);
}
void courbeA() {
float nouvelleValeurA;
float nouvelleValeurV;
float nouvelleValeurT;
float nouvelleValeurR;
// converison Ampere voltage et thrust en pixel
nouvelleValeurA = map((sensorValueA/22.5), 0, 8, 137, 110); // car l'cran a 64 pixels de haut
nouvelleValeurV = map((sensorValueV/1023*23.9), 0, 20, 33,3); // car l'cran a 64 pixels de haut
nouvelleValeurT = map(balance.get_units()*1000, 0, 400, 104, 72); // car l'cran a 64 pixels de haut
nouvelleValeurR = map(rpm, 0, 30000, 68, 40); // car l'cran a 64 pixels de haut
x++;
tft.drawPixel(x,nouvelleValeurA,ST7735_CYAN);
tft.drawPixel(x,nouvelleValeurV,ST7735_CYAN);
tft.drawPixel(x,nouvelleValeurT,ST7735_CYAN);
tft.drawPixel(x,nouvelleValeurR,ST7735_CYAN);
if (x>123) {
x=80;
tft.fillRect(82,110,43,30,ST7735_BLACK);
tft.fillRect(82,1,43,33,ST7735_BLACK);
tft.fillRect(82,72,43,35,ST7735_BLACK);
tft.fillRect(82,38,43,33,ST7735_BLACK);
}
}
void maxiV() {
// calcul voltage maximum
highV = (sensorValueV/1023*23.9);
if (highV > maxV) {
maxV = highV;
}
}
void maxiA() {
// calcul amperage maximum
highA = (sensorValueA/22.5);
if ( highA > maxA) {
maxA = highA;
}
}
void maxiR() {
// calcul rotation maximum
highR = (rpm);
if (highR > maxR) {
maxR = highR;
}
}
void maximumW() {
// calcul rotation maximum
highW = (watts);
if (highW > maxW) {
maxW = highW;
}
}
void maxiT() {
// calcul voltage maximum
highT = (balance.get_units()*1000);
if (highT > maxT) {
maxT = highT;
}
}
void checkRPM() {
noInterrupts() ;
interruptCount = 0; // set variable in critical section
interrupts() ;
delay (100);
noInterrupts() ;
int critical_rpm = interruptCount ; // read variable in critical section
interrupts() ;
rpm = ((critical_rpm)*(60))/(numpoles)*10;
}
void interruptFired()
{
interruptCount++;
}
Comments