NXTBee and The Flying Fortress LEGO Blimp 3

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.

The Blimp Program:


#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 Programs\NXT\3rd Party Sensor Drivers\drivers\common.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
}

The Controller Program:

#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 Programs\NXT\3rd Party Sensor Drivers\drivers\common.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!

Did you like this? Share it:

Related Posts:

3 thoughts on “NXTBee and The Flying Fortress LEGO Blimp

  1. Pingback: MAKE | Mindstorms Blimp Drone

  2. Pingback: Build Your Own LEGO Drone Blimp Thanks To These Geniuses | Gizmodo Australia

  3. Pingback: This DIY LEGO Drone Blimp Could Be Watching You From The Sky « www.SteffanLewis.com

Leave a Reply

  

  

  


seven + = 8