Vincenzo G.
Published © GPL3+

DIY Thrust Station

Wondering which is the thrust of your brushless motors? Do you want to check the current absorption? Build your cheap thrust station!

IntermediateProtip2 hours7,107
DIY Thrust Station

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
ACS712 20/30A
×1
Temperature Sensor
Temperature Sensor
×1
XT60 connectors
×1
Load cell 2Kg
×1
HX711 ~
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×1

Story

Read more

Schematics

eagle schematics

eagle board

eagle epf

Code

arduino code

C/C++
#include <Servo.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <HX711.h>
#include "Streaming.h"

//#define PYTHON
#define SERIAL


//switches and others:
#define switch_1 12
#define switch_2 11
boolean state_1;
boolean state_2;
boolean setValues = false;
uint8_t mode;


//esc:
#define pwm_min 900
#define pwm_max 2100
#define pot A0
#define esc_signal 4
Servo esc;
int val;


//load cell
HX711 scale;
#define data 5
#define sck 6
#define gain 128
float thrust;


//temperature:
#define ONE_WIRE_BUS 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature dallas(&oneWire);


//lcd
LiquidCrystal_I2C lcd(0x3F, 20, 4);


//multimeter
#define voltmeter A6
#define acs A7
float acs_read;
int acs_offset = 0;
float amp;
float volt;
float watt;
//float watth todo

void setup() {

  Serial.begin(115200);

  lcd.init();
  lcd.backlight();
  lcd.clear();

  esc.attach(esc_signal, pwm_min, pwm_max);

  //temperature sensors
  dallas.begin();
  dallas.setResolution(10);           //default 12, decrease it for speed
  dallas.setWaitForConversion(false); //no blocking calculation

  //thrust
  scale.begin(data, sck, gain);
  scale.set_scale(1009.5);        //check the libray
  scale.tare();

  //auto-manual mode
  pinMode (switch_1, INPUT_PULLUP);
  pinMode (switch_2, INPUT_PULLUP);

  chooseMode();
  delay(1500);
  lcd.clear();

}


void chooseMode() {
  lcd.setCursor(0, 0); lcd.print (F("Thrust Station"));
  lcd.setCursor(0, 1); lcd.print (F("Choose Mode"));
  lcd.setCursor(0, 2); lcd.print (F("I: Auto"));
  lcd.setCursor(0, 3); lcd.print (F("II: Manual"));

  delay(2000);

  while (state_1 == 0 && state_2 == 0) {

    //wait until the mode is selected
    state_1 = !digitalRead(switch_1);
    state_2 = !digitalRead(switch_2);

  }

  lcd.clear();

  if (state_1) {
    mode = 1;
    lcd.setCursor(6, 0);
    lcd.print (F("AUTO MODE"));
    val = pwm_min;
  }

  else if (state_2) {
    mode = 2;
    lcd.setCursor(4, 0);
    lcd.print (F("MANUAL MODE"));
  }
}


void loop() {

  getTemp();
  getThrust();
  getMultimeter();

#ifdef SERIAL
  Serial << "PWM:\t" << (val) << newl;
  Serial << "Thrust:\t" << (thrust) << newl;
  Serial << "Current:\t" << (amp) << newl;
  Serial << "Volt:\t" << (volt) << newl;
  Serial << "Watt:\t" << (watt) << newl;
  Serial << "Temp:\t" << (dallas.getTempC(0)) << newl << newl;
  delay(50);
#endif

  if (mode == 1) {
    autoMode();
  } else {
    manualMode();
  }
}


void autoMode() {

  if (setValues == false) {

    lcd.setCursor(3, 1);
    lcd.print (F("Your data are"));
    lcd.setCursor(5, 2);
    lcd.print (F("on the PC"));
    setValues = true;

  }

  esc.writeMicroseconds(val);
  val += 10;

  //data to processing

  Serial.print(val); Serial.print(":");
  Serial.print(thrust); Serial.print(":");
  Serial.print(amp); Serial.print(":");
  Serial.print(volt); Serial.print(":");
  Serial.print(watt); Serial.print(":");
  Serial.print(dallas.getTemp(0));
  Serial.println("");

  delay(50);

  if (val >= pwm_max) {

    esc.writeMicroseconds(pwm_min); //disarm esc

    lcd.clear();
    lcd.setCursor (3, 1);
    lcd.print (F("Test Completed"));
    lcd.setCursor (5, 2);
    lcd.print (F("Thank you"));
    lcd.setCursor (0, 2);

    while (1) ; //block

  }
}


void manualMode() {

  val = analogRead(pot);
  val = map (val, 0, 1023, pwm_min, pwm_max);
  esc.writeMicroseconds(val);

  if (val <= pwm_min + 50) {
    scale.tare();
  }

  if (setValues == false) {
    // write only once in the screen the names and prefix of the values

    lcd.setCursor(0, 0);
    lcd.print(F("PWM:"));

    lcd.setCursor(0, 1);
    lcd.print(F("Thrust:"));

    lcd.setCursor(4, 2);
    lcd.print(F("V"));

    lcd.setCursor(12, 2);
    lcd.print(F("A"));

    lcd.setCursor(19, 2);
    lcd.print(F("W"));

    lcd.setCursor(0, 3);
    lcd.print(F("ESC:"));

    lcd.setCursor(8, 3);
    lcd.print(F("C  Mot:"));

    lcd.setCursor(19, 3);
    lcd.print(F("C"));

    setValues = true;
  }

  //now write for every loop the values
  lcd.setCursor(4, 0);
  lcd.print(val);
  if (val < 1000) lcd.print(" ");

  lcd.setCursor(7, 1);
  lcd.print(-thrust);

  lcd.setCursor(0, 2);
  lcd.print(volt);

  lcd.setCursor(7, 2);
  lcd.print(amp);

  lcd.setCursor(14, 2);
  lcd.print(watt);

  lcd.setCursor(4, 3);
  lcd.print(dallas.getTempCByIndex(0), 1);

  lcd.setCursor(15, 3);
  lcd.print(dallas.getTempCByIndex(1), 1);

#ifdef PYTHON
  Serial  << val << ":" << thrust << ":" << amp << ":" << volt << ":" << watt << ":" << dallas.getTemp(0) << newl;
  delay(50);
#endif

}


void getTemp() {
  dallas.requestTemperatures();
  // the calculation are performed in the background
}



void getMultimeter() {

  //volt
  volt = (analogRead(voltmeter) / 1024.0) * 10.0;

  //ampere
  while (acs_offset == 0) {
    for (int i = 0; i < 10; i++) {
      acs_offset += analogRead(acs);
    }
    acs_offset /= 10; //create the offset
  }
  acs_read = analogRead(acs);
  amp = abs((acs_read - acs_offset) / 17.06);

  //watt
  watt = volt * amp;

  //watt/h todo

}


void getThrust() {
  thrust = scale.get_units(3);  //average of tree measurements
}

Credits

Vincenzo G.

Vincenzo G.

7 projects • 50 followers
Please do not contact me via hackster.io use github

Comments