drexel_coax_copter_code
no way to compare when less than two revisions
Differences
This shows you the differences between two versions of the page.
— | drexel_coax_copter_code [2016/11/09 16:32] (current) – created dwallace | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Co-Axial Helicopter with IR Elevation Control Code ====== | ||
+ | ===== Code to send IR pulses ===== | ||
+ | |||
+ | <code c IRPulses.c> | ||
+ | #include < | ||
+ | |||
+ | //comment this out to see the demodulated waveform | ||
+ | //it is useful for debugging purpose. | ||
+ | #define MODULATED 1 | ||
+ | |||
+ | const int IR_PIN = 3; | ||
+ | const int IR_PIN2 = 4; | ||
+ | const int IR_PIN3 = 5; | ||
+ | const unsigned long DURATION = 180000l; | ||
+ | const int HEADER_DURATION = 2000; | ||
+ | const int HIGH_DURATION = 380; | ||
+ | const int ZERO_LOW_DURATION = 220; | ||
+ | const int ONE_LOW_DURATION = 600; | ||
+ | const byte ROTATION_STATIONARY = 60; | ||
+ | const byte CAL_BYTE = 52; | ||
+ | |||
+ | int Throttle, LeftRight, FwdBack; | ||
+ | |||
+ | void sendHeader() | ||
+ | { | ||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | digitalWrite(IR_PIN2, | ||
+ | digitalWrite(IR_PIN3, | ||
+ | #else | ||
+ | TCCR2A |= _BV(COM2B1); | ||
+ | #endif | ||
+ | |||
+ | delayMicroseconds(HEADER_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | digitalWrite(IR_PIN2, | ||
+ | digitalWrite(IR_PIN3, | ||
+ | #else | ||
+ | TCCR2A &= ~_BV(COM2B1); | ||
+ | #endif | ||
+ | |||
+ | delayMicroseconds(HEADER_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | digitalWrite(IR_PIN2, | ||
+ | digitalWrite(IR_PIN3, | ||
+ | #else | ||
+ | TCCR2A |= _BV(COM2B1); | ||
+ | #endif | ||
+ | |||
+ | delayMicroseconds(HIGH_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | digitalWrite(IR_PIN2, | ||
+ | digitalWrite(IR_PIN3, | ||
+ | #else | ||
+ | TCCR2A &= ~_BV(COM2B1); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | void sendZero() | ||
+ | { | ||
+ | delayMicroseconds(ZERO_LOW_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | digitalWrite(IR_PIN2, | ||
+ | digitalWrite(IR_PIN3, | ||
+ | #else | ||
+ | TCCR2A |= _BV(COM2B1); | ||
+ | #endif | ||
+ | |||
+ | delayMicroseconds(HIGH_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | digitalWrite(IR_PIN2, | ||
+ | digitalWrite(IR_PIN3, | ||
+ | #else | ||
+ | TCCR2A &= ~_BV(COM2B1); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | void sendOne() | ||
+ | { | ||
+ | delayMicroseconds(ONE_LOW_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | digitalWrite(IR_PIN2, | ||
+ | digitalWrite(IR_PIN3, | ||
+ | #else | ||
+ | TCCR2A |= _BV(COM2B1); | ||
+ | #endif | ||
+ | |||
+ | delayMicroseconds(HIGH_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | digitalWrite(IR_PIN2, | ||
+ | | ||
+ | #else | ||
+ | TCCR2A &= ~_BV(COM2B1); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | void sendCommand(int throttle, int leftRight, int forwardBackward) | ||
+ | { | ||
+ | byte b; | ||
+ | |||
+ | sendHeader(); | ||
+ | |||
+ | for (int i = 7; i >=0; i--) | ||
+ | { | ||
+ | b = ((ROTATION_STATIONARY + leftRight) & (1 << i)) >> i; | ||
+ | if (b > 0) sendOne(); else sendZero(); | ||
+ | } | ||
+ | |||
+ | for (int i = 7; i >=0; i--) | ||
+ | { | ||
+ | b = ((63 + forwardBackward) & (1 << i)) >> i; | ||
+ | if (b > 0) sendOne(); else sendZero(); | ||
+ | } | ||
+ | |||
+ | for (int i = 7; i >=0; i--) | ||
+ | { | ||
+ | b = (throttle & (1 << i)) >> i; | ||
+ | if (b > 0) sendOne(); else sendZero(); | ||
+ | } | ||
+ | |||
+ | for (int i = 7; i >=0; i--) | ||
+ | { | ||
+ | b = (CAL_BYTE & (1 << i)) >> i; | ||
+ | if (b > 0) sendOne(); else sendZero(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | pinMode(IR_PIN, | ||
+ | digitalWrite(IR_PIN, | ||
+ | | ||
+ | pinMode(IR_PIN2, | ||
+ | digitalWrite(IR_PIN2, | ||
+ | | ||
+ | pinMode(IR_PIN3, | ||
+ | digitalWrite(IR_PIN3, | ||
+ | |||
+ | //setup interrupt interval: 180ms | ||
+ | Timer1.initialize(DURATION); | ||
+ | Timer1.attachInterrupt(timerISR); | ||
+ | |||
+ | //setup PWM: f=38Khz PWM=0.5 | ||
+ | byte v = 8000 / 38; | ||
+ | TCCR2A = _BV(WGM20); | ||
+ | TCCR2B = _BV(WGM22) | _BV(CS20); | ||
+ | OCR2A = v; | ||
+ | OCR2B = v / 2; | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | |||
+ | void timerISR() | ||
+ | { | ||
+ | //read control values from potentiometers | ||
+ | Throttle = analogRead(0); | ||
+ | LeftRight = analogRead(1); | ||
+ | FwdBack = analogRead(2); | ||
+ | |||
+ | Throttle = 100;// | ||
+ | LeftRight = 0;// | ||
+ | FwdBack = 0;//FwdBack / 4 - 128; //convert to -128 to 127 | ||
+ | |||
+ | sendCommand(Throttle, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Code to get Ultrasonic readings ===== | ||
+ | |||
+ | <code c Ultrasonic.c> | ||
+ | #include < | ||
+ | |||
+ | byte clockPin = 4; | ||
+ | byte buf[9];// | ||
+ | byte addr = 0x02;// | ||
+ | byte distance; | ||
+ | |||
+ | void setup() | ||
+ | { | ||
+ | i2c_init();// | ||
+ | Serial.begin(115200); | ||
+ | printUltrasonicCommand(0x00);// | ||
+ | printUltrasonicCommand(0x08);// | ||
+ | printUltrasonicCommand(0x10);// | ||
+ | printUltrasonicCommand(0x14);// | ||
+ | } | ||
+ | |||
+ | void loop() | ||
+ | { | ||
+ | // printUltrasonicCommand(0x42);// | ||
+ | distance = readDistance(); | ||
+ | if(distance == 0xFF) | ||
+ | Serial.println(" | ||
+ | else | ||
+ | Serial.println(distance, | ||
+ | } | ||
+ | byte readDistance() | ||
+ | { | ||
+ | delay(100);// | ||
+ | byte cmd = 0x42;//Read Measurement Byte 0 | ||
+ | |||
+ | pinMode(clockPin, | ||
+ | digitalWrite(clockPin, | ||
+ | |||
+ | if(i2c_start(addr+I2C_WRITE))// | ||
+ | { | ||
+ | Serial.println(" | ||
+ | i2c_stop(); | ||
+ | return 0xFF; | ||
+ | } | ||
+ | if(i2c_write(cmd))// | ||
+ | { | ||
+ | Serial.println(" | ||
+ | i2c_stop(); | ||
+ | return 0xFF; | ||
+ | } | ||
+ | i2c_stop(); | ||
+ | |||
+ | delayMicroseconds(60);// | ||
+ | pinMode(clockPin, | ||
+ | digitalWrite(clockPin, | ||
+ | delayMicroseconds(34); | ||
+ | pinMode(clockPin, | ||
+ | digitalWrite(clockPin, | ||
+ | delayMicroseconds(60); | ||
+ | |||
+ | if(i2c_rep_start(addr+I2C_READ))// | ||
+ | { | ||
+ | Serial.println(" | ||
+ | i2c_stop(); | ||
+ | return 0xFF; | ||
+ | } | ||
+ | for(int i = 0; i < 8; i++) | ||
+ | buf[i] = i2c_readAck(); | ||
+ | buf[8] = i2c_readNak(); | ||
+ | i2c_stop(); | ||
+ | |||
+ | return buf[0]; | ||
+ | } | ||
+ | |||
+ | void printUltrasonicCommand(byte cmd) | ||
+ | { | ||
+ | delay(100);// | ||
+ | |||
+ | pinMode(clockPin, | ||
+ | digitalWrite(clockPin, | ||
+ | |||
+ | if(i2c_start(addr+I2C_WRITE))// | ||
+ | { | ||
+ | Serial.println(" | ||
+ | i2c_stop(); | ||
+ | return; | ||
+ | } | ||
+ | if(i2c_write(cmd))// | ||
+ | { | ||
+ | Serial.println(" | ||
+ | i2c_stop(); | ||
+ | return; | ||
+ | } | ||
+ | i2c_stop(); | ||
+ | |||
+ | delayMicroseconds(60);// | ||
+ | pinMode(clockPin, | ||
+ | digitalWrite(clockPin, | ||
+ | delayMicroseconds(34); | ||
+ | pinMode(clockPin, | ||
+ | digitalWrite(clockPin, | ||
+ | delayMicroseconds(60); | ||
+ | |||
+ | if(i2c_rep_start(addr+I2C_READ))// | ||
+ | { | ||
+ | Serial.println(" | ||
+ | i2c_stop(); | ||
+ | return; | ||
+ | } | ||
+ | for(int i = 0; i < 8; i++) | ||
+ | buf[i] = i2c_readAck(); | ||
+ | buf[8] = i2c_readNak(); | ||
+ | i2c_stop(); | ||
+ | |||
+ | if(cmd == 0x00 || cmd == 0x08 || cmd == 0x10 || cmd == 0x14) | ||
+ | { | ||
+ | for(int i = 0; i < 9; i++) | ||
+ | { | ||
+ | if(buf[i] != 0xFF && buf[i] != 0x00) | ||
+ | Serial.print(buf[i]); | ||
+ | else | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | else | ||
+ | Serial.print(buf[0], | ||
+ | |||
+ | Serial.println("" | ||
+ | } | ||
+ | /* | ||
+ | ' Wires on NXT jack plug. | ||
+ | ' Wire colours may vary. Pin 1 is always end nearest latch. | ||
+ | ' 1 White +9V | ||
+ | ' 2 Black GND | ||
+ | ' 3 Red GND | ||
+ | ' 4 Green +5V | ||
+ | ' 5 Yellow SCL - also connect clockpin to give a extra low impuls | ||
+ | ' 6 Blue SDA | ||
+ | ' Do not use i2c pullup resistor - already provided within sensor. | ||
+ | */ | ||
+ | </ | ||
+ | |||
+ | ===== Final Code ===== | ||
+ | |||
+ | <code c Final.c> | ||
+ | #include < | ||
+ | |||
+ | //comment this out to see the demodulated waveform | ||
+ | //it is useful for debugging purpose. | ||
+ | #define MODULATED 1 | ||
+ | |||
+ | //Pins | ||
+ | const int IR_PIN = 3; //Infrared LED pin | ||
+ | const int vIn = 8; //Green Wire of GP2D02 | ||
+ | const int vOut = 9; //Yellow Wire of GP2D02 | ||
+ | |||
+ | //For signal generation. Lengths are in microseconds. | ||
+ | const int HEADER_DURATION = 2000; //Length of header pulse | ||
+ | const int HIGH_DURATION = 380; //Length of high part of 0/1-pulse | ||
+ | const int ZERO_LOW_DURATION = 220; //Length of low part of 0-pulse | ||
+ | const int ONE_LOW_DURATION = 600; //Length of low part of 1-pulse | ||
+ | const byte ROTATION_STATIONARY = 60; // Trim | ||
+ | const byte CAL_BYTE = 52; //Trailing pulse signature | ||
+ | |||
+ | //For fitness calculation | ||
+ | int heightCM = 12; //Input the height you want the program to attempt to reach | ||
+ | int heightIRvalue = 447.54*pow(heightCM, | ||
+ | int bestFitness = 1000; // starting best fitness is far from zero | ||
+ | int currentFitness = 1000; // starting fitness is far from zero | ||
+ | int runNum = 0; //Tracks number of runs | ||
+ | int currentIRValue = 0; //Store GP2D02 IRValue | ||
+ | int minIR = 0; //Minimum position IR Value | ||
+ | int maxIR = 0; //Maximum position IR Value | ||
+ | int lastHighThrottle = 255; // Starts last fit high throttle at max range | ||
+ | int lastLowThrottle = 0; // Starts last low high throttle at min range | ||
+ | int lastThrottle = 0; // The value of the throttle on the last run | ||
+ | |||
+ | //For timed loop of one run | ||
+ | int starttime = 0; | ||
+ | int endtime = 0; | ||
+ | |||
+ | //For intial SYMA 107 signal parameters | ||
+ | int Throttle = 0; | ||
+ | int LeftRight = 0;//-64 to 63 | ||
+ | int FwdBack = 0;//-128 to 127 | ||
+ | |||
+ | // | ||
+ | GP2D02 sensor(vIn, | ||
+ | |||
+ | void sendHeader() //Sends the header pulse that singals the begining of a command | ||
+ | { | ||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | #else | ||
+ | TCCR2A |= _BV(COM2B1); | ||
+ | #endif | ||
+ | |||
+ | delayMicroseconds(HEADER_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | #else | ||
+ | TCCR2A &= ~_BV(COM2B1); | ||
+ | #endif | ||
+ | |||
+ | delayMicroseconds(HEADER_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | #else | ||
+ | TCCR2A |= _BV(COM2B1); | ||
+ | #endif | ||
+ | |||
+ | delayMicroseconds(HIGH_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | #else | ||
+ | TCCR2A &= ~_BV(COM2B1); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | void sendZero() //Sends one 0 pulse | ||
+ | { | ||
+ | delayMicroseconds(ZERO_LOW_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | #else | ||
+ | TCCR2A |= _BV(COM2B1); | ||
+ | #endif | ||
+ | |||
+ | delayMicroseconds(HIGH_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | #else | ||
+ | TCCR2A &= ~_BV(COM2B1); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | void sendOne() //Sends one 1 pulse | ||
+ | { | ||
+ | delayMicroseconds(ONE_LOW_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | #else | ||
+ | TCCR2A |= _BV(COM2B1); | ||
+ | #endif | ||
+ | |||
+ | delayMicroseconds(HIGH_DURATION); | ||
+ | |||
+ | #ifndef MODULATED | ||
+ | digitalWrite(IR_PIN, | ||
+ | #else | ||
+ | TCCR2A &= ~_BV(COM2B1); | ||
+ | #endif | ||
+ | } | ||
+ | |||
+ | void sendCommand(int throttle, int leftRight, int forwardBackward) | ||
+ | { //Converts SYMA Parameters to a signal | ||
+ | //For loops convert decimal numbers to binary numbers | ||
+ | //Sends a pulse for each 0 or 1. | ||
+ | byte b; | ||
+ | |||
+ | sendHeader(); | ||
+ | |||
+ | for (int i = 7; i >=0; i--) | ||
+ | { // Yaw part of signal | ||
+ | b = ((ROTATION_STATIONARY + leftRight) & (1 << i)) >> i; | ||
+ | if (b > 0) sendOne(); else sendZero(); | ||
+ | } | ||
+ | |||
+ | for (int i = 7; i >=0; i--) | ||
+ | { //Pitch part of signal | ||
+ | b = ((63 + forwardBackward) & (1 << i)) >> i; | ||
+ | if (b > 0) sendOne(); else sendZero(); | ||
+ | } | ||
+ | |||
+ | for (int i = 7; i >=0; i--) | ||
+ | { //Throttle part of signal | ||
+ | b = (throttle & (1 << i)) >> i; | ||
+ | if (b > 0) sendOne(); else sendZero(); | ||
+ | } | ||
+ | |||
+ | for (int i = 7; i >=0; i--) | ||
+ | { //Trailing Pulses | ||
+ | b = (CAL_BYTE & (1 << i)) >> i; | ||
+ | if (b > 0) sendOne(); else sendZero(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void setup() | ||
+ | { // | ||
+ | Serial.begin(9600); | ||
+ | pinMode(IR_PIN, | ||
+ | digitalWrite(IR_PIN, | ||
+ | |||
+ | //setup PWM: f=38Khz PWM=0.5 | ||
+ | byte v = 8000 / 38; | ||
+ | TCCR2A = _BV(WGM20); | ||
+ | TCCR2B = _BV(WGM22) | _BV(CS20); | ||
+ | OCR2A = v; | ||
+ | OCR2B = v / 2; | ||
+ | minIR = sensor.getRawRange(); | ||
+ | maxIR = 3000000*pow(minIR, | ||
+ | maxIR = 447.54*pow(maxIR, | ||
+ | Serial.println(" | ||
+ | Serial.print(" | ||
+ | Serial.println(heightIRvalue); | ||
+ | } | ||
+ | |||
+ | void loop() //main program loop | ||
+ | { | ||
+ | randomSeed(millis()); | ||
+ | runNum = runNum + 1; | ||
+ | if(runNum> | ||
+ | Serial.println(" | ||
+ | if(bestFitness> | ||
+ | Throttle = random(lastThrottle, | ||
+ | lastLowThrottle = lastThrottle; | ||
+ | Serial.println(" | ||
+ | } | ||
+ | else if(bestFitness< | ||
+ | Throttle = random(lastLowThrottle, | ||
+ | lastHighThrottle = lastThrottle; | ||
+ | | ||
+ | } | ||
+ | else{ // 0 is the best fitness, this is the final part of the program | ||
+ | Serial.println(" | ||
+ | Serial.print(" | ||
+ | Serial.println(lastThrottle); | ||
+ | Serial.print(" | ||
+ | Serial.println(runNum); | ||
+ | while(1){ | ||
+ | sendCommand(lastThrottle, | ||
+ | //end of program | ||
+ | //hangs indefinately | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | else{ //Initial Run | ||
+ | Serial.println(" | ||
+ | Throttle = random(255); | ||
+ | } | ||
+ | Serial.print(" | ||
+ | Serial.println(runNum); | ||
+ | Serial.print(" | ||
+ | Serial.println(Throttle); | ||
+ | | ||
+ | lastThrottle = Throttle; | ||
+ | starttime = millis(); | ||
+ | endtime = starttime; | ||
+ | // do this loop for up to 5000mS | ||
+ | while ((endtime - starttime) < | ||
+ | { //Runs take place over a period of 5 seconds | ||
+ | sendCommand(Throttle, | ||
+ | endtime = millis(); | ||
+ | currentIRValue = sensor.getRawRange(); | ||
+ | currentFitness = currentIRValue-heightIRvalue; | ||
+ | } | ||
+ | if(abs(currentFitness)< | ||
+ | bestFitness = currentFitness; | ||
+ | } | ||
+ | Serial.print(" | ||
+ | Serial.println(currentIRValue); | ||
+ | Serial.print(" | ||
+ | Serial.println(bestFitness); | ||
+ | delay(3000); | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Libraries ===== | ||
+ | |||
+ | * [[http:// | ||
+ | * [[https:// |
drexel_coax_copter_code.txt · Last modified: 2016/11/09 16:32 by dwallace