We recently discovered this fantastic video of a LEGO MINDSTORMS creation: The Flying Fortress LEGO Blimp. The project is a fantastic two-ballooned flying blimp made of LEGOs and controlled with a pair of NXTBees.
Youtuber Tyler shared the code, written in RobotC with us. You can see the video below; it looks like a fun test flight in a high school gym. The balloon is controlled using two NXTBees and powered with adjustable, rotatable propellers.
#pragma config(Sensor, S1, Ultra, sensorSONAR) #pragma config(Sensor, S2, SoundSensor, sensorSoundDBA) #pragma config(Sensor, S3, HTIRL, sensorI2CCustom) #pragma config(Motor, motorB, Tilt, tmotorNXT, PIDControl, reversed, encoder) #pragma config(Motor, motorC, Light, tmotorNXT, PIDControl, encoder) //*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//
//#include "drivers/hitechnic-irlink.h" #include "Sample ProgramsNXT3rd Party Sensor Driversdriverscommon.h" //Xander's #include "hitechnic-irlink.h" task Estop { wait1Msec(500); while (SensorValue(SoundSensor) < 50) { //nxtDisplayCenteredTextLine(1, "%d", SensorValue(SoundSensor)); wait1Msec(25); }; nxtDisplayCenteredTextLine(3, "AHHHHH!"); StopAllTasks(); } //// Stop the motors //void stopMotors() { // PFcomboDirectMode(HTIRL, 0, CDM_MOTOR_BRAKE, CDM_MOTOR_BRAKE); //} int IncMess = 0;
bool Run_EStop = false; // True for testing, False when flying task main() { //Initialize nxtEnableHSPort(); //Enable High Speed Port #4 nxtSetHSBaudRate(9600); //Xbee Default Speed nxtHS_Mode = hsRawMode; //Set to Raw Mode (vs. Master/Slave Mode) short bytesRead; ubyte incomingData;
eraseDisplay(); if (Run_EStop == true) StartTask(Estop); nMotorEncoder[Tilt]=0; //bFloatDuringInactiveMotorPWM = true;
//11, 12, 13 //21, 22, 23 //31, 32, 33 //40 to 49 byte speed = 5; byte Brake = 8; // Reverse speed byte FWspeed = speed;// Forward speed byte RVspeed = 16 - speed; // Reverse speed
int Position = 0; //current position int TargetPosition = 0; const int Factor = 125; int TiltMotorSpeed = 20; int Thresh = 5; int count = 0; int PreviousSignal = 0; int Timeout = 1250; int CrashTime = 4000; int CrashDistance = 15;
tPFmotor BluePort = pfmotor_S3_C1_B; //PFMotor(BluePort, (ePWMMotorCommand)7); tPFmotor RedPort = pfmotor_S3_C1_A; //PFMotor(BluePort, (ePWMMotorCommand)7);
//Blimp time1[T2] = 0; while(true) { time1[T1] = 0; while (nxtGetAvailHSBytes() == false && time1[T1] < CrashTime); //Check to see if we have any data coming in if (time1[T1] >= CrashTime){ // Crash sequence StopTask(Estop); motor[Tilt] = TiltMotorSpeed; while(nMotorEncoder[Tilt] < 5*Factor); motor[Tilt] = 0; while (nxtGetAvailHSBytes() == false){ while (SensorValue[Ultra] > CrashDistance && nxtGetAvailHSBytes() == false){ PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)FWspeed, (ePWMMotorCommand)FWspeed); } PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)Brake, (ePWMMotorCommand)Brake); } if (Run_EStop == true) StartTask(Estop); }
nxtDisplayCenteredBigTextLine(6, "CT:%i", count++); nxtReadRawHS(&incomingData, 1); IncMess = (int)incomingData; nxtDisplayTextLine(0, "Message: %i", IncMess); //PreviousSignal = IncMess; time1[T2] = 0; switch (IncMess) { case 11: PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)FWspeed, (ePWMMotorCommand)Brake); break; case 12: PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)FWspeed, (ePWMMotorCommand)FWspeed); break; case 13: PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)Brake, (ePWMMotorCommand)FWspeed); break; case 21: PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)FWspeed, (ePWMMotorCommand)RVspeed); break; case 22: PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)Brake, (ePWMMotorCommand)Brake); break; case 23: PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)RVspeed, (ePWMMotorCommand)FWspeed); break; case 31: PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)RVspeed, (ePWMMotorCommand)Brake); break; case 32: PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)RVspeed, (ePWMMotorCommand)RVspeed); break; case 33: PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)Brake, (ePWMMotorCommand)RVspeed); break;
case 40: TargetPosition = -5*Factor; break; case 41: TargetPosition = -4*Factor; break; case 42: TargetPosition = -3*Factor; break; case 43: TargetPosition = -2*Factor; break; case 44: TargetPosition = -1*Factor; break; case 45: TargetPosition = 0*Factor; break; case 46: TargetPosition = 1*Factor; break; case 47: TargetPosition = 2*Factor; break; case 48: TargetPosition = 3*Factor; break; case 49: TargetPosition = 4*Factor; break; case 50: TargetPosition = 5*Factor; break;
default: PFcomboPwmMode(HTIRL, 0, (ePWMMotorCommand)Brake, (ePWMMotorCommand)Brake); motor[Tilt] = 0; }
if (IncMess >= 40 && IncMess= TargetPosition - Thresh && Position motor[Tilt] = 0; } else if (Position < TargetPosition + Thresh){ motor[Tilt] = TiltMotorSpeed; while(TargetPosition > nMotorEncoder[Tilt] && IncMess == PreviousSignal){ nxtReadRawHS(&incomingData, 1); IncMess = (int)incomingData; } motor[Tilt] = 0; } else if (Position > TargetPosition - Thresh){ motor[Tilt] = -TiltMotorSpeed; while(TargetPosition < nMotorEncoder[Tilt] && IncMess == PreviousSignal){ nxtReadRawHS(&incomingData, 1); IncMess = (int)incomingData; } motor[Tilt] = 0; } } } StopTask(Estop); nxtDisableHSPort(); //Disable HS Port #4 } [/sourcecode]
The Controller Program:
[sourcecode language="cpp"] #pragma config(Sensor, S1, Button, sensorTouch) #pragma config(Motor, motorA, ForRev, tmotorNXT, openLoop, reversed, encoder) #pragma config(Motor, motorB, LeftRight, tmotorNXT, openLoop, reversed, encoder) #pragma config(Motor, motorC, Tilt, tmotorNXT, PIDControl, encoder) //*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//
//#include "drivers/lego-touch.h" #include "Sample ProgramsNXT3rd Party Sensor Driversdriverscommon.h" //Xander's #include "lego-touch.h" task main() { // Initialize nxtEnableHSPort(); //Enable High Speed Port #4 nxtSetHSBaudRate(9600); //Xbee Default Speed nxtHS_Mode = hsRawMode; //Set to Raw Mode (vs. Master/Slave Mode)
bFloatDuringInactiveMotorPWM = true; nMotorPIDSpeedCtrl[ForRev] = mtrSpeedReg; nMotorPIDSpeedCtrl[LeftRight] = mtrSpeedReg; nMotorEncoder[ForRev] = 0; nMotorEncoder[LeftRight] = 0; nMotorEncoder[Tilt] = 0;
motor[ForRev] =10; while(nMotorEncoder[ForRev] < 40); motor[ForRev] = 0; nMotorEncoder[ForRev] = 0;
motor[LeftRight] =10; while(nMotorEncoder[LeftRight] < 30); motor[LeftRight] = 0; nMotorEncoder[LeftRight] = 0; bFloatDuringInactiveMotorPWM = true;
nMotorPIDSpeedCtrl[ForRev] = mtrNoReg; nMotorPIDSpeedCtrl[LeftRight] = mtrNoReg; int LR_ME = 0; int FR_ME = 0; int TiltAngle = 0; int Cont_Message = 0; int LRMssg = 0; int FRMssg = 0; int Factor = 20; ubyte myChar;
//Controller while(true){ if(TSreadState(Button) == 1){ LR_ME = nMotorEncoder[LeftRight]; FR_ME = nMotorEncoder[ForRev];
if(LR_ME < -20){ LRMssg = 1; } else if (LR_ME >= -20 && LR_ME +20){ LRMssg = 3; }
if(FR_ME < -20){ FRMssg = 30; } else if (FR_ME >= -20 && FR_ME +20){ FRMssg=10; } Cont_Message = LRMssg + FRMssg; }
else if (TSreadState(Button) == 0){
TiltAngle = nMotorEncoder[Tilt]; if (TiltAngle > -6*Factor && TiltAngle -5*Factor && TiltAngle -4*Factor && TiltAngle -3*Factor && TiltAngle -2*Factor && TiltAngle -1*Factor && TiltAngle 1*Factor && TiltAngle 2*Factor && TiltAngle 3*Factor && TiltAngle 4*Factor && TiltAngle 5*Factor && TiltAngle 6*Factor){ Cont_Message = 50; } else if (TiltAngle < -6*Factor){ Cont_Message = 40; } } eraseDisplay(); myChar = (ubyte)Cont_Message; nxtWriteRawHS(&myChar, 1); //Write the data (paras: char to send, length of data) nxtDisplayCenteredBigTextLine(1, "%d", Cont_Message); wait1Msec(250); } nxtDisableHSPort(); //Disable HS Port #4 }
Got a project to share? Contact us through Facebook, Twitter, or our website!
3 Comments
Leave a reply
You must be logged in to post a comment.