Terminato Progetto Hovercraft

salve a tutti,
ho finalmente terminato il mio primo progetto con Arduino (realizzazione di un Hovercraft) e volevo ringraziare chi mi ha dato consigli sui vari componenti che ho utilizzato.

Ho utilizzato

  • Arduino UNO,
  • un motore brushless 1100 kV con elica per spinta in avanti,
  • una turbina per creare un cuscino d'aria sottostante (trattenuta mediante un involucro forato),
  • due ESC come controllori di velocità per i due motorini,
  • un servo motore per la direzionalità,
  • un sensore di distanza a ultrasuoni per evitare che vada a sbattere,
  • una batteria da 5Ah e
  • un modulo HC-05 Bluetooth che consente la connessione con il mio smartphone, su cui ho fatto un'app con cui piloto l'hovercraft.
    La parte hardware è stata fatta in modo artigianale con tavolette di legno leggero, polistirolo e un pezzo di plexiglass traforato con cui ho realizzato il timone.
    Ho dei problemi per farlo andare diritto, nel senso che non è facile distribuire i pesi in modo che riesca ad andare dritto, ma nel complesso sono contenta, funziona.
    grazie a tutti

un videino sarebbe interessante :slight_smile:

Complimenti Luis67 per la realizzazione del progetto.
Sarebbe carino vedere almeno un'immagine del prodotto, gli schemi e lo sketch!! Magari può servire a qualche altro utente.

Ciao

Meluino

provo ad allegare la foto

non so se si vede lo schema
avrei voluto farlo con Fritzing, ma non sono riuscita ad aggiungere i componenti che non sono di default nel programma, come immagine, quindi l'ho fatto con powerpoint

ci riprovo

Le immagini che hai su disco fisso NON puoi inserirle nel corpo del messaggio, li puoi metterci solo quelle raggiungibili via internet.

Le devi mettere come allegato ... guarda in basso, sotto la finestra del testo (Attachments ...) ... :wink:

Guglielmo

provato a inserire come attachment

il file di prima era di 1 MB, l’ho ridotto, adesso va bene
… non guardiamo l’estetica, mi rendo conto che non sia bello, infatti volevo anche nascondere i fili con una sorta di ‘cofano’ di plastica, ma per adesso …
ora allego lo schema elettrico fatto con power point, invece che con Fritzing
come si fa ad aggiungere elementi non presenti di default su Fritzing ?

Molto interessante, un video del funzionamento a gonnella gonfia? Sarebbe anche interessante un dettaglio dei costi.

questi sono gli elementi che ho acquistato:

TURBINA 18,64 euro (+iva + dogana) http://www.hobbyking.com/hobbyking/store/_22947__HobbyKing_8482_50mm_Alloy_EDF_4800kv_3s_Version.html

2 ESC 9,19 euro (+iva + dogana) * 2 http://www.hobbyking.com/hobbyking/store/__15205__Hobby_King_30A_ESC_3A_UBEC.html

MOTORINO 14,44 (+iva + dogana) http://www.hobbyking.com/hobbyking/store/__18225__Turnigy_D3530_14_1100KV_Brushless_Outrunner_Motor.html

SERVO MOTORE 5,06 (+iva + dogana) https://www.hobbyking.com/hobbyking/store/__42370__Turnigy_8482_DRFT_303_1_10th_D_Spec_Steering_Servo_4_5kg_0_10Sec_39g.html

BATTERIA 23,30 euro (+iva + dogana)http://www.hobbyking.com/hobbyking/store/__9183__Turnigy_5000mAh_3S_25C_Lipo_Pack.html

CARICABATTERIA 21,16 euro (+iva + dogana) http://www.hobbyking.com/hobbyking/store/_76462__IMAX_B6_AC_DC_Charger_5A_50W_With_US_Plug_Copy.html

SRF05 4 euro http://www.ebay.it/itm/HY-SRF05-MISURATORE-DISTANZA-ULTRASUONI-5-PIN-MODULO-SENSORE-PER-ROBOT-E-ARDUINO-/121744123057?hash=item1c5883e4b1

HC05 8,69 euro http://www.ebay.it/itm/Wireless-Serial-6Pin-Bluetooth-Transceiver-Module-HC-05-Master-Slave-Cable-TE119-/201311867357?hash=item2edf1f51dd:g:ALwAAOSw37tWA9U4

qui riporto lo sketch che ho usato su Arduino che riceve comandi dall’app sotto forma di stringhe che terminano con il char ‘&’:

#include <SoftwareSerial.h>
#include <Servo.h>
#define DISTANZA_OSTACOLO 50

/* LED */
int REDled = 13 ;
int GREENled = 12 ;

/* HC05 BLUETOOTH */
int RX_Arduino = 10 ;   // RX Arduino collegato direttamente con il cavetto al TX di HC05
int TX_Arduino = 11 ;   // TX Arduino collegato mediante partitore di tensione al RX di HC05

SoftwareSerial bluetooth (RX_Arduino, TX_Arduino) ;

/* SERVO MOTORE E MOTORI */
Servo servo ;
Servo turbina ;
Servo motore ;

int pinServo = 3 ;
int pinTurbina = 6 ;
int pinMotore = 9 ;

String msg ;
int angoloServoOLD ;
int velTurbinaOLD ;
int velMotoreOLD ;

/* SRF05 MODULO AD ULTRASUONI PER MISURARE LA DISTANZA  */
float duration, distanceCm, distanceOLD, distOLDER ;
int TRIG_PIN = 7;   // pin di collegamento del Trigger SRF05
int ECHO_PIN = 5;   // pin di collegamento dell'Echo SRF05
int T = 20 ;                // temperatura 
boolean ostacoli ;

void setup() {
  pinMode(REDled, OUTPUT) ;
  pinMode(GREENled, OUTPUT) ;
  
  Serial.begin(9600) ;
  bluetooth.begin(9600) ;

  servo.attach(pinServo) ;
  servo.write(90) ;
  angoloServoOLD = 90 ;

  turbina.attach(pinTurbina) ;
  turbina.write(20) ;
  velTurbinaOLD = 20 ;

  motore.attach(pinMotore) ;
  motore.write(20) ;
  velMotoreOLD = 20 ;

  pinMode(TRIG_PIN, OUTPUT);   // il Trigger SRF05 invia
  pinMode(ECHO_PIN, INPUT);    // l'Echo SRF05 riceve

  distanceOLD = 10000 ;
  distOLDER = 10000 ;

  Serial.println("SETUP") ;
}

void loop() {

  if ( controllaOstacoli() ) {        /* HA RILEVATO UN OSTACOLO */
    digitalWrite(REDled, HIGH) ;
    digitalWrite(GREENled, LOW) ;
    
    motore.write(20) ;
    velMotoreOLD = 20  ;
    turbina.write(20) ;
    velTurbinaOLD = 20 ;
    servo.write(90) ;
    angoloServoOLD = 90 ;

    Serial.print("TURBINA = = ") ; Serial.print(velTurbinaOLD) ; Serial.print(" MOTORE = ") ;Serial.print(velMotoreOLD) ; Serial.print(" SERVO = ");Serial.println(angoloServoOLD) ;
    
    /* L'APP DEVE ESSERE INFORMATA MEDIANTE L'INVIO TRAMITE BLUETOOTH DEL MESSAGGIO */
    String messaggio = " OSTACOLO" ; 
    bluetooth.print(messaggio) ;
    
    distOLDER = 10000 ;
    distanceOLD = 10000 ;
    distanceCm = 10000 ;
  } 
  else {
    digitalWrite(REDled, LOW) ;
    digitalWrite(GREENled, HIGH) ;
    
    if (bluetooth.available())  {      //Read from bluetooth and write to usb serial
      char toSend = (char)bluetooth.read();
      if ( toSend != '&')    msg += toSend ;
      else if ( toSend == '&' ) {    // con il char ‘;’ termina il messaggio ricevuto
        Serial.println("=================================") ;
        Serial.print("msg = ") ; Serial.println(msg) ;
        esegui(msg) ;  
        msg = "" ;
      }
    }

    if ( Serial.available() ) {
      char toSend = (char)Serial.read() ;
      Serial.println(toSend) ;
    }
  }
  delay(100) ;
}    // loop

boolean controllaOstacoli() {
  boolean ostacoli = false ;
  // dà un breve impulso LOW  in anticipo to ensure a clean HIGH pulse:
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  duration = pulseIn(ECHO_PIN, HIGH);

  // calcolo della velocità del suono VS Temperatura:
  float velS_ = 331.3 + 0.606 * T ;    // [m/s]
  float velS = velS_ / 10000 ;   // conversione [cm/micros]
  distanceCm = duration * velS / 2 ;
  if (distanceCm <= 0) {    Serial.println("Out of range");  }

  if ( distanceCm < DISTANZA_OSTACOLO ) {
    if ( distanceOLD < DISTANZA_OSTACOLO ) {
      if ( distOLDER < DISTANZA_OSTACOLO ) {
        Serial.print("OSTACOLO RILEVATO distance = ") ; Serial.print(distanceCm) ; Serial.print("   distanceOLD = ") ; Serial.println(distanceOLD) ;
        return true ;
      }
    } else {
      ostacoli = false ;
    }

    if ( distOLDER > DISTANZA_OSTACOLO && distanceOLD > DISTANZA_OSTACOLO )  distOLDER = distanceCm ;
    else if ( distOLDER < DISTANZA_OSTACOLO  && distanceOLD > DISTANZA_OSTACOLO) distanceOLD = distanceCm ;

  } else {
    return false ;
  }
  delay(100) ;
  return ostacoli ;
}

void esegui(String msg) {
  // SERVO -------------------------------------------
  if ( msg == "c" ) {
    servo.write(90) ;
    angoloServoOLD = 90 ;
  }
  else if ( msg == "d" ) {
    if ( angoloServoOLD <= 170 ) {
      angoloServoOLD = angoloServoOLD + 10 ;
    }
    Serial.print("servo a ") ; Serial.println(angoloServoOLD) ;
    servo.write(angoloServoOLD) ;
  }
  else if ( msg == "s" ) {
    if ( angoloServoOLD >= 0  ) {
      angoloServoOLD = angoloServoOLD - 10 ;
    }
    Serial.print("servo a ") ; Serial.println(angoloServoOLD) ;
    servo.write(angoloServoOLD) ;
  }

  // TURBINA -----------------------------------------------------
  else if (msg.startsWith("T+", 0) ) {
    int velTurbina = velTurbinaOLD + 1 ;
    if (velTurbina >= 180 ) velTurbina = 179 ;
    else if ( velTurbina <= 0 ) velTurbina = 20 ;
    turbina.write(velTurbina) ;
    velTurbinaOLD = velTurbina ;
  }
  else if ( msg.startsWith("T-", 0) ) {
    int velTurbina = velTurbinaOLD - 1 ;
    if (velTurbina >= 180 ) velTurbina = 179 ;
    else if ( velTurbina <= 0 ) velTurbina = 20 ;
    turbina.write(velTurbina) ;
    velTurbinaOLD = velTurbina ;
  }
  else if ( msg.startsWith("T=", 0) ) {
    String vel = msg.substring(2) ;
    int velTurbina = vel.toInt() ;
    if (velTurbina >= 180 ) velTurbina = 179 ;
    else if ( velTurbina <= 0 ) velTurbina = 20 ;
    turbina.write(velTurbina) ;
    velTurbinaOLD = velTurbina ;
  }

  // MOTORE ---------------------------------------------------------
  else if (msg.startsWith("+", 0) ) {
    int velMotore = velMotoreOLD + 1 ;
    if (velMotore >= 180 ) velMotore = 179 ;
    else if ( velMotore <= 0 ) velMotore = 20 ;
    motore.write(velMotore) ;
    velMotoreOLD = velMotore ;
  }
  else if ( msg.startsWith("-", 0) ) {
    int velMotore = velMotoreOLD - 1 ;
    if (velMotore >= 180 ) velMotore = 179 ;
    else if ( velMotore <= 0 ) velMotore = 20 ;
    motore.write(velMotore) ;
    velMotoreOLD = velMotore ;
  }
  else if ( msg.startsWith("V=", 0) ) {
    String vel = msg.substring(2) ;
    int velMotore = vel.toInt() ;
    if (velMotore >= 180 ) velMotore = 179 ;
    else if ( velMotore <= 0 ) velMotore = 20 ;
    motore.write(velMotore) ;
    velMotoreOLD = velMotore ;
  }

  // COMPLESSIVAMENTE ----------------------------------------
  else if ( msg.startsWith ("stop", 0 ) ) {    // SI VUOLE FERMARE TUTTO, MOTORE E TURBINA E PORTARE AL CENTRO IL TIMONE
    motore.write(20) ;
    velMotoreOLD = 20  ;
    turbina.write(20) ;
    velTurbinaOLD = 20 ;
  }
  
  Serial.print("TURBINA = ") ; Serial.print(velTurbinaOLD) ; Serial.print(" MOTORE = ") ;Serial.print(velMotoreOLD) ; Serial.print(" SERVO = ");Serial.println(angoloServoOLD) ;
}

Sarebbe una uona idea usare i tag code per racchiudere il codice.

luis67:
qui riporto lo sketch che ho usato su Arduino che riceve comandi dall'app sotto forma di stringhe che terminano con il char '&':

Non sarebbe stato piu comodo usare una codifica binaria fatta su misura magari aggiungendo ridondanza o delle verifiche aggiuntive?

luis67:
TURBINA 18,64 euro (+iva + dogana) http://www.hobbyking.com/hobbyking/store/_22947__HobbyKing_8482_50mm_Alloy_EDF_4800kv_3s_Version.html

è possibile rovesciare la sola ventola? Risulterebbe piu semplice collegare i cavi lasciandoli verso l'alto.

Un giudizio complessivo sui componenti e sulle tecniche di costruzione adottate?

Scusa per le tante domande ma è un argomento che mi affascina molto :wink:

Grazie Roberto per i suggerimenti, ma qual è il vantaggio ad usare codifica binaria al posto di stringhe corte?
E poi non capisco la domanda relativa all'inversione della ventola, i cavi sono già verso l'alto, forse non si vede bene dalla foto. Piuttosto ho provato a invertire turbina e motore per mettere la turbina a spingere orizzontalmente per ridurre il baricentro e farlo più basso, ma la turbina non c'è la fa a spingere, ci vogliono delle pale più lunghe come quelle dell'etica usata, 9/7 inch. Ho trovato un sito che consente di calcolare la spinta in base all'etica usata.
Il problema più grosso è il peso della batteria, 450g sono tanti per la turbina, ma comunque riesco a farlo andare anche senza andare al max dei motori.