yvesmorele
Published © CC BY-NC

Thrust Stand and Power Analyser low cost

The commercial existing Thrust Stand and Power Analyser is very expensive, I tried to make one at low cost, less than 30€.

BeginnerFull instructions provided2 hours2,989
Thrust Stand and Power Analyser low cost

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
current sensor
×1
infrared obstacle sensor
×1
st7735
×1
HC-05 Bluetooth Module
HC-05 Bluetooth Module
×1
Resistor 1k ohm
Resistor 1k ohm
×1
Resistor 10k ohm
Resistor 10k ohm
×1

Software apps and online services

MIT App Inventor 2
MIT App Inventor 2
Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Solder Wire, Lead Free
Solder Wire, Lead Free
Soldering iron (generic)
Soldering iron (generic)
10 Pc. Jumper Wire Kit, 5 cm Long
10 Pc. Jumper Wire Kit, 5 cm Long

Story

Read more

Custom parts and enclosures

android App

Schematics

WIRING

Code

arduino code

Arduino
 


#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;
         
      }
  }

V8 wih bluetooth

Arduino
for dispay on phone
//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++;
}

Credits

yvesmorele

yvesmorele

9 projects • 45 followers
chemical scientist

Comments