Académique Documents
Professionnel Documents
Culture Documents
Living
Outside
Play
Technology
Workshop
Step 6: The receiver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Step 7: Top assemby & cable routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Step 8: The skirt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Related Instructables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Advertisements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
Image Notes 1. 16x2 LCD header 2. nRF24L01 radio module header 3. Thumbstick header 4. Atmega chip socket 5. push-buttons
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
--- THE REMOTE CONTROLLER CODE --// include the library code: #include <LiquidCrystal.h> #include <SPI.h> #include "nRF24L01.h" #include "RF24.h"
/* ---------------------- MY CUSTOM-MADE 'ENVELOPE' STRUCTS ---------------------- */ // struct to carry messages typedef struct{ int X; int Y; boolean buttons[4]; } Payload; // struct to get // telemetric data typedef struct{ int rudderAng; int Z; int S; } Feedback; /* ---------------------- BATTERY MONITORING RELATED VARIABLES ---------------------- */ // analog pin reading V_out/V2 from voltage divider const int battPin = A5; // default reference on circuit used (5.0, 3.3, 1.1) const double refV = 5.0; // How many volts does 1 ADC measure? const double V_incr = refV/1024.0; // values of resistances used for voltage divider const double R1 = 68.4; const double R2 = 46.6; // determine voltage divider ratio const double voltageRatio = (R2/(R1 + R2));
/* --------------------------- BUTTON-RELATED VARIABLES --------------------------- */ // button 'pad' pin const int buttonPin = A3; // Button setup schematics // Analog pin 5 // | //Ground--1K--|--------|--------|-------| // | | | | // btn1 btn2 btn3 btn4 // | | | | // 220 Ohm 390 Ohm 680 Ohm 2.2K // |--------|--------|-------|-- +5V int j = 1; // 'j' is the integer used in scanning the array designating column number // these ranges below are dependent on the schematics above and may // need to be adjusted manually to compensate for various factors int Button[15][3] = {{1, 836, 840}, // button 1 {2, 732, 738}, // button 2 {3, 600, 625}, // button 3 {4, 310, 335}, // button 4
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
{5, 890, 900}, // button 1 + 2 {6, 870, 880}, // button 1 + 3 {7, 840, 860}, // button 1 + 4 {8, 810, 830}, // button 2 + 3 {9, 760, 780}, // button 2 + 4 {10, 665, 685} // button 3 + 4 }; int label = 0; // for reporting the button label int counter = 0; // how many times we have seen new value long time = 0; // the last time the output pin was sampled int debounce_count = 5; // number of millis/samples to consider before declaring a debounced input int current_state = 0; // the debounced input value int ButtonVal; /* ---------------------------------------------------------------------------------------------------- */ // initialize the library with the numbers of the interface pins LiquidCrystal lcd(8, 7, 5, 4, 3, 2); // initialize radio with CE, CN pin numbers RF24 radio(9,10); const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; // OUT-'pigeon' Payload package; // IN-'pigeon' Feedback telemetrics; long previousMillis = 0; long interval = 25; /* ---------------------------------------------------------------------------------------------------- */ /* SETUP */ void setup() { Serial.begin(57600); radio.begin(); radio.openWritingPipe(pipes[0]); radio.openReadingPipe(1,pipes[1]); radio.startListening(); pinMode(buttonPin, INPUT); // set up the LCD's number of COLUMNS and ROWS: lcd.begin(16, 2); } /* ------------------------------------------------------------------------ */ /* ---------------- WELCOME TO THE LOOP ------------------ */ /* ------------------------------------------------------------------------ */ void loop() { // monitor battery voltage on remote int val = analogRead(battPin); double battV = VoltageCheck(val); package.X = analogRead(A0); delay(1); package.Y = analogRead(A1); delay(1);
/* ------------------- HANDLE BUTTON PRESSES -------------------------- */ // If we have gone on to the next millisecond if (millis() != time) { // check analog pin for the button value and save it to ButtonVal ButtonVal = analogRead(buttonPin); delay(1);
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
//Serial.println(ButtonVal); // DEBUG if(ButtonVal == current_state & counter >0) { counter--; } if(ButtonVal != current_state) { counter++; } // If ButtonVal has shown the same value for long enough let's switch it if (counter >= debounce_count) { counter = 0; current_state = ButtonVal; //Checks which button or button combo has been pressed if (ButtonVal > 100){ ButtonCheck();}else{ package.buttons[0] = 0; package.buttons[1] = 0; package.buttons[2] = 0; package.buttons[3] = 0;} } time = millis(); } /* --------------- RADIO 'TOWER' GROUND CONTROL -------------------- */ if ( radio.available() ) { bool done = false; while (!done) { done = radio.read( &elemetrics , sizeof(telemetrics) ); } radio.stopListening(); bool ok = radio.write( &ackage, sizeof(package) ); radio.startListening(); }
/* ------------------- HANDLE LCD DISPLAY -------------------------- */ /* LINE 1 */ lcd.setCursor(0,0); // dirty hard-coded hack below if(telemetrics.Z < 100){ lcd.setCursor(2,0); lcd.print(" "); lcd.setCursor(0,0); } lcd.print(telemetrics.Z); lcd.setCursor(6,0); // dirty hard-coded hack below if(telemetrics.rudderAng < 100){ lcd.setCursor(8,0); lcd.print(" "); lcd.setCursor(6,0); } lcd.print(telemetrics.rudderAng); lcd.setCursor(12,0); if(telemetrics.S < 100){ lcd.setCursor(14,0); lcd.print(" "); lcd.setCursor(12,0); } lcd.print(telemetrics.S); /* LINE 2 */ lcd.setCursor(0, 1); lcd.print("X: ");
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
lcd.setCursor(2, 1); lcd.print(package.X); lcd.setCursor(6, 1); lcd.print("Y: "); lcd.setCursor(8, 1); lcd.print(package.Y); lcd.setCursor(12,1); lcd.print(battV); /* --------------------------------------------------------------------------- */ } // close loop()
/* ------------------------------ HELPING FUNCTIONS ------------------------------ */ // read that battery voltage double VoltageCheck(int v){ double pinV = v * V_incr; double volts_in = pinV * 1/voltageRatio; return volts_in; } // checks which button (or combo of 2) has been pressed, if any... void ButtonCheck() { // loop for scanning the button array. for(int i = 0; i <= 10; i++) { // checks the ButtonVal against the high and low vales in the array if(ButtonVal >= Button[i][j] & ButtonVal <= Button[i][j+1]) { // stores the button number to a variable label = Button[i][0]; switch (label) { case 1: package.buttons[0] = 1; package.buttons[1] = 0; package.buttons[2] = 0; package.buttons[3] = 0; //Serial.println("button 1"); break; case 2: package.buttons[0] = 0; package.buttons[1] = 1; package.buttons[2] = 0; package.buttons[3] = 0; //Serial.println("button 2"); break; case 3: package.buttons[0] = 0; package.buttons[1] = 0; package.buttons[2] = 1; package.buttons[3] = 0; //Serial.println("button 3"); break; case 4: package.buttons[0] = 0; package.buttons[1] = 0; package.buttons[2] = 0; package.buttons[3] = 1; //Serial.println("button 4"); break; case 5: //Serial.println("button 1 + 2"); package.buttons[0] = 1; package.buttons[1] = 1; package.buttons[2] = 0; package.buttons[3] = 0; break; case 6: //Serial.println("button 1 + 3"); package.buttons[0] = 1; package.buttons[1] = 0; package.buttons[2] = 1; package.buttons[3] = 0;
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
break; case 7: //Serial.println("button 1 + 4"); package.buttons[0] = 1; package.buttons[1] = 0; package.buttons[2] = 0; package.buttons[3] = 1; break; case 8: //Serial.println("button 2 + 3"); package.buttons[0] = 0; package.buttons[1] = 1; package.buttons[2] = 1; package.buttons[3] = 0; break; case 9: //Serial.println("button 2 + 4"); package.buttons[0] = 0; package.buttons[1] = 1; package.buttons[2] = 0; package.buttons[3] = 1; break; case 10: //Serial.println("button 3 + 4"); package.buttons[0] = 0; package.buttons[1] = 0; package.buttons[2] = 1; package.buttons[3] = 1; break; } // close switch } } }
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
you'll probably will need to modify the ESC arming code. If you haven't work with Arduino + ESC before I heavily recommend you test them standalone, arming procedures vary from ESC to ESC. The code below works well for two Mystery brand ESCs rated for 30A. For other ESCs you might have to investigate to some length on how to properly arm them.
#include <Servo.h> #include <SPI.h> #include "nRF24L01.h" #include "RF24.h" /* ------------- TRAVELLING DATA STRUCTS -------------- */ // commands goes inside typedef struct{ int X; int Y; boolean buttons[4]; } Payload; // feedback goes inside typedef struct{ int rudderAng; int Z; int S; } Feedback; /* -------------- DEBOUNCING VARIABLES ------------------------- */ long previousMillis = 0; // timer for servo long previousButtonMillis = 0; // timer for buttons //long previousTX = 0; // timer for transmissions //long TXinterval = 25; // interval to transmit telemetry const int interval = 30; // interval to update servo const int binterval = 70; // interval for debouncing const int TX_timeout = 100; // remote - craft link timeout /* ------------------------------------------------------------- */ Servo thrust; Servo lift; Payload package; Feedback telemetrics; Servo rudder; int oldAngle, newAngle = 0; // servo positions int lift_ang; // lift motor pseudo-'angular' velocity int vel; // thrust pseudo-'angular' velocity boolean run = false; RF24 radio(9, 10); const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; /* ----------------------------------------------------- */ /* SET UP THE RECEIVER NODE */ void setup(void) { Serial.begin(57600); radio.begin(); radio.openWritingPipe(pipes[1]); radio.openReadingPipe(1,pipes[0]); radio.startListening(); rudder.attach(7); // It is important to arm // EACH ESC sequentially lift.attach(5); armESC(lift); lift_ang = 50;
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
delay(100); thrust.attach(6); armESC(thrust); vel = 50; } void loop(void) { unsigned long started_waiting_at = millis(); boolean timeout = false; while ( ! radio.available() && ! timeout ) if (millis() - started_waiting_at > TX_timeout ) timeout = true; if ( timeout ){ //Serial.println("Failed, response timed out."); run = false; } else{ radio.read( &ackage, sizeof(package) ); run = true; }
// if TX-RX link is alive () then... if(run) { /* ------------ RUN RECEIVED COMMANDS ---------------- */ int X = package.X; int Y = package.Y; // RUDDER CONTROL // -----------------------------------------------------------if (X > 480 & X < 530 ){ newAngle = 90; // 90 = servo in center position } if (X < 480){ newAngle = (map(X, 480, 155, 91, 150)); } if (X > 530){ newAngle = (map(X, 530, 815, 89, 30)); } // FORWARD THRUST CONTROL... VROOOOMMMMMMM // --------------------------------------------------------------------if (Y > 550 & Y < 635 ){ thrust.write(50); // neutral position -- motor not spinning telemetrics.S = 50; } if (Y >= 635){ vel = (map(Y, 635, 925, 60, 90)); thrust.write(vel); telemetrics.S = vel; } unsigned long currentMillis = millis(); // Issue rudder repositioning command only if desired // position changes and (debouncing) interval is over if(oldAngle != newAngle && currentMillis - previousMillis > interval) { previousMillis = currentMillis; oldAngle = newAngle; rudder.write(newAngle); // tell servo to go to position in variable 'pos' } // close if millis-land (for rudder servo) // HANDLE BUTTON PRESSES // -----------------------------------------------------------------currentMillis = millis(); if (currentMillis - previousButtonMillis > binterval) { // button press for instant MIN (none) lift speed (NO throtle) if (package.buttons[0] == 1){ lift_ang = 50; } // button press for lift speed INCREMENT if (package.buttons[1] == 1){ if( lift_ang < 120 ){ lift_ang += 5; }
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
} // button press for instant (sort of) "stationary safe" hovering if (package.buttons[2] == 1){ lift_ang = 90; } // button press for lift speed DECREMENT if (package.buttons[3] == 1){ if( lift_ang > 50 & lift_ang <= 115 ){ lift_ang -= 5; } } previousButtonMillis = currentMillis; lift.write(lift_ang); } // close if "millis-land" (secundary test) -- button millis debounce /* ---------------------------------------------------------------------- */ // Set telemetry data to send telemetrics.Z = lift_ang; telemetrics.rudderAng = newAngle; } // close "if(run)" statement else{ //Serial.println("No radio available"); emergencyStop(); } // TO transmit TELEMETRICS use this: radio.stopListening(); bool ok = radio.write( &elemetrics, sizeof(telemetrics) ); radio.startListening(); // OR this: (need to uncomment variables previousTX & TXinterval // if using this option) // unsigned long currentMillis = millis(); // // if(currentMillis - previousTX > TXinterval) { // previousTX = currentMillis; // // radio.stopListening(); // bool ok = radio.write( &elemetrics, sizeof(telemetrics) ); // radio.startListening(); // }
// Accessory functions void emergencyStop() { thrust.write(50); lift.write(50); } void armESC(Servo esc) { esc.write(10); delay(2000); esc.write(50); delay(1000); }
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
So, after your hover is properly dressed ;-) It's just time to go out and have some fun. :-)
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/
Related Instructables
Advertisements
http://www.instructables.com/id/RC-Hovercraft-Customized-Remote-control/