ROBOTC.net Blog  

ROBOTC News

Archive for March, 2011

2011 Summer Online Training schedule available!

without comments

The Robotics Academy has just released the Summer Online Training schedule for 2011. Take a look below for the dates:

For questions about payment, please email customerservice@robomatter.com.

For questions relating to training, please email training@rec.ri.cmu.edu, or you can comment on this post below.

Written by Vu Nguyen

March 23rd, 2011 at 2:56 pm

I2C on the VEX Cortex

with one comment

The VEX Cortex is a nice platform made by VEX Robotics. It is supported in two programming environments, one of which is ROBOTC. Much to my dismay, the master firmware does not support I2C, which is why ROBOTC does not support it. I don’t really like it when someone tells me I can’t do something, so I went ahead and remedied the situation.

Mindsensor Magic Wand controlled by VEX CortexMotor MUX and Servo Controller controlled by VEX Cortex

I spent a few evenings writing and tinkering in ROBOTC to write my own bit-banged I2C implementation, which much to my surprise, worked very well.  First I tested it with the Mindsensors Magic Wand (above left) and later also with the Holit Data Systems Motor MUX and Mindsensors NXT Servo Controller (above right).  Jesse Flot from Robotics Academy was kind enough to send me some old VEX cables so I could splice two of them into an NXT cable for I2C. I will post a HOWTO for that at a later date.

As you can see in the right picture, I was already contemplating controlling the omniwheeled robot with the Motor MUX and so I did.

The robot is remote controlled via VEXnet over Wifi (which is a totally awesome feature which I wish the NXT had). The short video was taken at the RobotMC meeting of 19 March 2011, which happened to coincide with an information day for the technical university where we hold our meetings.

The coolest part about it is that my driver suite is almost completely transparently portable to the VEX Cortex platform once you switch out the NXT I2C subsystem functions for the Cortex specific ones. Some NXT dependencies do need to be removed and made more generic.  I intend to work on that in the next few weeks.  That would make a very wide range of new sensors available to the VEX Cortex platform.

Original article: [LINK]

Written by Xander Soldaat

March 19th, 2011 at 12:59 pm

NXT Robot: PID Line Follower

with one comment

DiMastero is at it again…

This time he has created a robot that does some very fast line following.

Watch it in action


YouTube Direct Link 

Hardware

This line follower is equipped with three sensors: one light (port 3), one magnetic field (port 2) and one IR link, the last of which are by HiTechnic. The light sensor is used for the robot’s main purpose: line following, while the magnetic field sensor detects whether the robot needs to pause or keep going. The IR Link doesn’t have any function; it’s just there to keep the whole thing symmetrical.

rear view

Zoom on the magnet and magnetic field sensorside view

The robot moves using two independently moving motors connected to ports B and C. They form the follower’s back and sides. At the front, next to the light sensor is a caster wheel.

Detail of caster and light sensor

Programming

The robot was programmed in RobotC and runs on PID control.The motors’ built-in PID is off. When the code starts, it takes the black (line) and white (background) light values and averages them to get an offset. It then sets the bias of the HiTechnic magnetic field sensor to 0, while the magnet is in front of it. That way, the sensor’s value will change when the magnet is (re)moved.

Magnet is out of sensor's reach

Next, after a short wait, it starts driving around the NXT test paper, guided by the PID. It keeps on doing so until the magnet is removed, in which case it pauses the program and turns off the motors. Once the magnet is back in place, the robot keeps going, even if it’s been moved to somewhere else on the line. If the magnet stays away for too long (more than four seconds), the program shuts down.

You can download the latest version of the code on the downloads page or download version 2.1 (which was the latest version when this page was last updated) below.

Setup and Performance

To start the robot, place it above the middle of the black line you want to follow right after starting the program on the NXT. Then, when it bleeps, move the robot to the left of the line. Make sure you neither touch nor move the magnet.

After a split second, the robot will start to follow the line. To pause it, lift the “tail”, moving the magnet. To get it back on line, let go of the tail. To abort the entire program, hold the tail for four seconds, or until you see the light sensor turn off (it’s in active mode, so the LED will be on all the time when it’s operative).

The robot follows the black line pretty quickly and smoothly.

Written by Vu Nguyen

March 18th, 2011 at 12:03 pm

Posted in Cool projects,NXT

Cortex “View Mode” Program

without comments

In an earlier blog post, we introduced the VEX LCD and showed how to print custom messages and values to it. Being able to print messages and sensor values adds some awesome functionality to your robot… but why stop there, when there’s so much more potential?

Many NXT (and even RCX!) users  are familiar with the  “View Mode” on their microcontrollers, that allows them to specify what sensors are connected to which ports, and then view those values on the screen. Without a built-in screen, VEX users haven’t had access to this functionality… that is, until now! If you have the VEX LCD, the code in this post will allow you to specify a sensor, specify which port it’s on, and then watch the sensor values update in real-time.

Step 1: Download and run the sample program on your robot (see below).

Step 2: Select the type of sensor connected to your robot. The left and right buttons cycle through the options. The middle button selects the current sensor.

Step 3: Select the port the sensor is connected to. For sensors with more than one wire, choose the FIRST port the sensor is plugged into (remember, sensors with more than two wires must be plugged in on neighboring ports on the Cortex). There is also a “Back to Sensors” option that will take you back to the sensor option menu.

Step 4: View the sensor data! Pressing the center button will exit, and return you to the sensor selection menu.

The sample code can be copied into ROBOTC, or you can download a copy here. Note: This code has not been fully optimized, but should work fine as-is.

//Global Variable Declarations
const short leftButton = 1;
const short centerButton = 2;
const short rightButton = 4;
short sensorChoice;
short portChoice;
short count;

//Task and Function Prototypes
void waitForPress();
void waitForRelease();
void clearPorts();

task sensorChooser();
task digitalPortChooser();
task analogPortChooser();
void menuTracker();

task display();
void analogSensorSetup(tSensors sensorPort);
void digitalSensorSetup(tSensors sensorPort);

//Main------------------------------------------------------------
task main()
{
 StartTask(sensorChooser);
 while(true)
 {
 wait1Msec(50);
 }
}
//----------------------------------------------------------------

//sensorChooser - allows you to choose which sensor you'd like to pick
task sensorChooser()
{
 //Junk Cleanup from previous runs
 clearLCDLine(0);
 clearLCDLine(1);
 clearPorts();
 waitForRelease();
 StopTask(display);
 StopTask(digitalPortChooser);
 StopTask(analogPortChooser);

 hogCPU();

 count = 0;
 while(true)
 {
 switch(count){
 case 0:
 //Touch
 displayLCDCenteredString(0, "Touch Sensor");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 sensorChoice = 0;
 releaseCPU();
 StartTask(digitalPortChooser);
 }
 else if(nLCDButtons == leftButton)
 {
 waitForRelease();
 count = 6;
 }
 else if(nLCDButtons == rightButton)
 {
 waitForRelease();
 count++;
 }

 break;
 case 1:
 //Quadrature Encoder
 displayLCDCenteredString(0, "Quad Encoder");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 sensorChoice = 1;
 releaseCPU();
 StartTask(digitalPortChooser);
 }
 else
 menuTracker();
 break;
 case 2:
 //Ultrasonic
 displayLCDCenteredString(0, "Ultrasonic");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 sensorChoice = 2;
 releaseCPU();
 StartTask(digitalPortChooser);
 }
 else
 menuTracker();
 break;
 case 3:
 //Light
 displayLCDCenteredString(0, "Light Sensor");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 sensorChoice = 3;
 releaseCPU();
 StartTask(analogPortChooser);
 }
 else
 menuTracker();
 break;
 case 4:
 //Line Tracker
 displayLCDCenteredString(0, "Line Tracker");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 sensorChoice = 4;
 releaseCPU();
 StartTask(analogPortChooser);
 }
 else
 menuTracker();
 break;
 case 5:
 //Potentiometer
 displayLCDCenteredString(0, "Potentiometer");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 sensorChoice = 5;
 releaseCPU();
 StartTask(analogPortChooser);
 }
 else
 menuTracker();
 break;
 case 6:
 //Accelerometer
 displayLCDCenteredString(0, "Accelerometer");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 sensorChoice = 6;
 releaseCPU();
 StartTask(analogPortChooser);
 }
 else if(nLCDButtons == leftButton)
 {
 waitForRelease();
 count--;
 }
 else if(nLCDButtons == rightButton)
 {
 waitForRelease();
 count = 0;
 }
 break;
 }
 }
}
//----------------------------------------------------------------

//digitalPortChooser - allows you to choose which port you'd like to pick
task digitalPortChooser()
{
 StopTask(sensorChooser);
 hogCPU();

 count = 1;  //Chooses the starting point

 while(true)
 {
 switch(count){
 case 0:
 //Back Option
 displayLCDCenteredString(0, "Back to Sensors");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 releaseCPU();
 StartTask(sensorChooser);
 }
 else if(nLCDButtons == leftButton)
 {
 waitForRelease();
 count = 12;
 }
 else if(nLCDButtons == rightButton)
 {
 waitForRelease();
 count++;
 }
 break;
 case 1:
 //Digital 1
 displayLCDCenteredString(0, "DIGITAL 1");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 1;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 2:
 //Digital 2
 displayLCDCenteredString(0, "DIGITAL 2");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 2;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 3:
 //Digital 3
 displayLCDCenteredString(0, "DIGITAL 3");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 3;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 4:
 //Digital 4
 displayLCDCenteredString(0, "DIGITAL 4");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 4;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 5:
 //Digital 5
 displayLCDCenteredString(0, "DIGITAL 5");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 5;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 6:
 //Digital 6
 displayLCDCenteredString(0, "DIGITAL 6");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 6;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 7:
 //Digital 7
 displayLCDCenteredString(0, "DIGITAL 7");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 7;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 8:
 //Digital 8
 displayLCDCenteredString(0, "DIGITAL 8");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 8;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 9:
 //Digital 9
 displayLCDCenteredString(0, "DIGITAL 9");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 9;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 10:
 //Digital 10
 displayLCDCenteredString(0, "DIGITAL 10");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 10;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 11:
 //Digital 11
 displayLCDCenteredString(0, "DIGITAL 11");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 11;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 12:
 //Digital 12
 displayLCDCenteredString(0, "DIGITAL 12");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 12;
 releaseCPU();
 StartTask(display);
 }
 else if(nLCDButtons == leftButton)
 {
 waitForRelease();
 count--;
 }
 else if(nLCDButtons == rightButton)
 {
 waitForRelease();
 count = 0;
 }
 break;
 }
 }
}
//----------------------------------------------------------------

//analogPortChooser - allows you to choose which port you'd like to pick
task analogPortChooser()
{
 StopTask(sensorChooser);
 hogCPU();

 count = 1;//Chooses the starting point

 while(true)
 {
 switch(count){
 case 0:
 //Back Option
 displayLCDCenteredString(0, "Back to Sensors");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 releaseCPU();
 StartTask(sensorChooser);
 }
 else if(nLCDButtons == leftButton)
 {
 waitForRelease();
 count = 8;
 }
 else if(nLCDButtons == rightButton)
 {
 waitForRelease();
 count++;
 }
 break;
 case 1:
 //Analog 1
 displayLCDCenteredString(0, "ANALOG 1");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 13;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 2:
 //Analog 2
 displayLCDCenteredString(0, "ANALOG 2");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 14;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 3:
 //Analog 3
 displayLCDCenteredString(0, "ANALOG 3");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 15;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 4:
 //Analog 4
 displayLCDCenteredString(0, "ANALOG 4");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 16;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 5:
 //Analog 5
 displayLCDCenteredString(0, "ANALOG 5");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 17;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 6:
 //Analog 6
 displayLCDCenteredString(0, "ANALOG 6");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 18;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 7:
 //Analog 7
 displayLCDCenteredString(0, "ANALOG 7");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 19;
 releaseCPU();
 StartTask(display);
 }
 else
 menuTracker();
 break;
 case 8:
 //Analog 8
 displayLCDCenteredString(0, "ANALOG 8");
 displayLCDCenteredString(1, "<     Enter    >");
 waitForPress();

 if(nLCDButtons == centerButton)
 {
 waitForRelease();
 portChoice = 20;
 releaseCPU();
 StartTask(display);
 }
 if(nLCDButtons == leftButton)
 {
 waitForRelease();
 count--;
 }
 else if(nLCDButtons == rightButton)
 {
 waitForRelease();
 count = 0;
 }
 break;
 }
 }
}
//----------------------------------------------------------------

//Clear Ports-----------------------------------------------------
void clearPorts()
{
 hogCPU();
 SensorType[in1] = sensorNone;
 SensorType[in2] = sensorNone;
 SensorType[in3] = sensorNone;
 SensorType[in4] = sensorNone;
 SensorType[in5] = sensorNone;
 SensorType[in6] = sensorNone;
 SensorType[in7] = sensorNone;
 SensorType[in8] = sensorNone;

 SensorType[dgtl1] = sensorNone;
 SensorType[dgtl2] = sensorNone;
 SensorType[dgtl3] = sensorNone;
 SensorType[dgtl4] = sensorNone;
 SensorType[dgtl5] = sensorNone;
 SensorType[dgtl6] = sensorNone;
 SensorType[dgtl7] = sensorNone;
 SensorType[dgtl8] = sensorNone;
 SensorType[dgtl9] = sensorNone;
 SensorType[dgtl10] = sensorNone;
 SensorType[dgtl11] = sensorNone;
 SensorType[dgtl12] = sensorNone;
 releaseCPU();
}
//----------------------------------------------------------------

//Wait for Press--------------------------------------------------
void waitForPress()
{
 while(nLCDButtons == 0);
 {
 wait1Msec(5);
 }
}
//----------------------------------------------------------------

//Wait for Release------------------------------------------------
void waitForRelease()
{
 while(nLCDButtons != 0);
 {
 wait1Msec(5);
 }
}
//----------------------------------------------------------------

//Function to increment and decriment count - small savings on space
void menuTracker()
{
 if(nLCDButtons == leftButton)
 {
 waitForRelease();
 count--;
 }
 else if(nLCDButtons == rightButton)
 {
 waitForRelease();
 count++;
 }
}
//----------------------------------------------------------------

//Display---------------------------------------------------------
task display()
{
 StopTask(analogPortChooser);
 StopTask(digitalPortChooser);
 hogCPU();

 switch(portChoice){
 case 1:
 //Digital Port 1
 digitalSensorSetup(dgtl1);
 break;
 case 2:
 //Digital Port 2
 digitalSensorSetup(dgtl2);
 break;
 case 3:
 //Digital Port 3
 digitalSensorSetup(dgtl3);
 break;
 case 4:
 //Digital Port 4
 digitalSensorSetup(dgtl4);
 break;
 case 5:
 //Digital Port 5
 digitalSensorSetup(dgtl5);
 break;
 case 6:
 //Digital Port 6
 digitalSensorSetup(dgtl6);
 break;
 case 7:
 //Digital Port 7
 digitalSensorSetup(dgtl7);
 break;
 case 8:
 //Digital Port 8
 digitalSensorSetup(dgtl8);
 break;
 case 9:
 //Digital Port 9
 digitalSensorSetup(dgtl9);
 break;
 case 10:
 //Digital Port 10
 digitalSensorSetup(dgtl10);
 break;
 case 11:
 //Digital Port 11
 digitalSensorSetup(dgtl11);
 break;
 case 12:
 //Digital Port 12
 digitalSensorSetup(dgtl12);
 break;
 case 13:
 //Analog Port 1
 analogSensorSetup(in1);
 break;
 case 14:
 //Analog Port 2
 analogSensorSetup(in2);
 break;
 case 15:
 //Analog Port 3
 analogSensorSetup(in3);
 break;
 case 16:
 //Analog Port 4
 analogSensorSetup(in4);
 break;
 case 17:
 //Analog Port 5
 analogSensorSetup(in5);
 break;
 case 18:
 //Analog Port 6
 analogSensorSetup(in6);
 break;
 case 19:
 //Analog Port 7
 analogSensorSetup(in7);
 break;
 case 20:
 //Analog Port 8
 analogSensorSetup(in8);
 break;
 }
 releaseCPU();
 StartTask(sensorChooser);
}
//----------------------------------------------------------------

//Creates the analog sensor to be displayed
void analogSensorSetup(tSensors sensorPort)
{
 switch(sensorChoice){
 case 3:
 SensorType[sensorPort] = sensorLineFollower; //Change to sensorReflection
 clearLCDLine(0);
 displayLCDPos(0,0);
 displayNextLCDString("Light:");
 while(nLCDButtons != 2)
 {
 clearLCDLine(1);
 displayLCDPos(1,0);
 displayNextLCDNumber(SensorValue[sensorPort], 4);
 wait1Msec(100);
 }
 break;
 case 4:
 SensorType[sensorPort] = sensorLineFollower;
 clearLCDLine(0);
 displayLCDPos(0,0);
 displayNextLCDString("Line Tracker:");
 while(nLCDButtons != 2)
 {
 clearLCDLine(1);
 displayLCDPos(1,0);
 displayNextLCDNumber(SensorValue[sensorPort], 4);
 wait1Msec(100);
 }
 break;
 case 5:
 SensorType[sensorPort] = sensorPotentiometer;
 clearLCDLine(0);
 displayLCDPos(0,0);
 displayNextLCDString("Potentiometer:");
 while(nLCDButtons != 2)
 {
 clearLCDLine(1);
 displayLCDPos(1,0);
 displayNextLCDNumber(SensorValue[sensorPort], 4);
 wait1Msec(100);
 }
 break;
 case 6:
 SensorType[sensorPort] = sensorAccelerometer;
 clearLCDLine(0);
 displayLCDPos(0,0);
 displayNextLCDString("Accelerometer:");
 while(nLCDButtons != 2)
 {
 clearLCDLine(1);
 displayLCDPos(1,0);
 displayNextLCDNumber(SensorValue[sensorPort], 4);
 wait1Msec(100);
 }
 break;
 }
}
//----------------------------------------------------------------

//Creates the digital sensor to be displayed----------------------
void digitalSensorSetup(tSensors sensorPort)
{
 switch(sensorChoice){
 case 0:
 SensorType[sensorPort] = sensorTouch;
 clearLCDLine(0);
 displayLCDPos(0,0);
 displayNextLCDString("Touch:");
 while(nLCDButtons != 2)
 {
 clearLCDLine(1);
 displayLCDPos(1,0);
 displayNextLCDNumber(SensorValue[sensorPort], 1);
 wait1Msec(100);
 }
 break;
 case 1:
 SensorType[sensorPort] = sensorQuadEncoder;
 clearLCDLine(0);
 displayLCDPos(0,0);
 displayNextLCDString("Quad Encoder:");
 while(nLCDButtons != 2)
 {
 clearLCDLine(1);
 displayLCDPos(1,0);
 displayNextLCDNumber(SensorValue[sensorPort], 6);
 wait1Msec(100);
 }
 break;
 case 2:
 SensorType[sensorPort] = sensorSONAR_cm;
 clearLCDLine(0);
 displayLCDPos(0,0);
 displayNextLCDString("Ultrasonic (cm):");
 while(nLCDButtons != 2)
 {
 clearLCDLine(1);
 displayLCDPos(1,0);
 displayNextLCDNumber(SensorValue[sensorPort], 4);
 wait1Msec(100);
 }
 break;
 }
}
//----------------------------------------------------------------

Written by Jesse Flot

March 16th, 2011 at 11:48 am

Dancing VEX robot: Bear Bot [Team 4542]

with 2 comments

Thanks to magiccode from the forums for posting this!

Overview

Our robotics team made a semi-humanoid dancing VEX robot with a holonomic drive in place of legs. It has full range of motion in both arms and two planes of motion in its head. It can bend at the waist, and strafe or turn in any direction.

It dances. plays the piano and beats little kids up. He is an all around entertainer. We only had about a day to program him, so bear with us… pun intended”

Video


YouTube Direct Link 

Description

There were 3 “cool” things that were done with ROBOTC:

  1. The robot mimics the movements of a human arm which is holding the VexNet joystick or Vex accelerometer. This will not work in all directions if the joytick is being used because the joystick lacks a z-axis, but it will work in all directions if the accelerometer is being used.
  2. There were too many motors to be controlled by one cortex, so we linked two together by running a male to male pwm wire from the digital output port of one to the digital input port of the other.
  3. Programming was made easier by writing a function called moveServo(). The function would accept 3 parameters: the servo to move, the position to which it should move, and the amount of time it should take (does not take into account changes in battery power)

Code:

moveServo(tMotor servoName, int posToMove, int timeToTake);

How it works


YouTube Direct Link 

Written by Vu Nguyen

March 1st, 2011 at 10:18 am