NXC Cheat Sheet

About the NXC Cheat Sheet

NXC - or "Not Exactly C" is a C like language for programming the Lego Mindstorms NXT brick. This cheat sheet demonstrates some of the basic features of the language that will be useful for coding the Club Engineer Lego printer, and a Robocup Rescue robot.

Contents

Chaining procedures
Initialize sensor
Rotate motor fixed duration
Rotate motor until touch sensor is triggered
Print encoded line segment (eg "    xxxx    xxxx    xxxx")
Calibrate light sensor
Forward, then stop on line
Test the ultrasonic sensor read time
Run parallel tasks
Execute some code for a defined time
Wait for a NXT button press
Save data to a file
Read data from a file

Chaining Procedures

void DrawBorder()
{
RectOut(0, 0, 999, 999);
RectOut(2, 2, 999-4, 999-4);
}

void FlashTextOnce(const string ATextToFlash, const AFlashTime)
{
TextOut(x, y, ATextToFlash);
Wait(AFlashTime);
TextOut(x, y, " ");
Wait(AFlashTime);
}

void FlashText(const string ATextToFlash, const int AFlashCount, const int AFlashTime)
{
DrawBorder();
repeat (AFlashCount)
{
FlashTextOnce(ATextToFlash, AFlashTime);
}
}

task main()

{
FlashText("Hello World", 3, 500);
}

Initialize Sensors

#define CLightSensor IN_3
task main()
{
SetSensorTouch(IN_1);
SetSensorLight(CLightSensor);
...
}

Rotate motor a fixed duration

void MoveForward()
{
RotateMotor(OUT_A, 20, -20);
}

Rotate motor until a touch sensor is triggered

void ResetScanHead()
{
OnFwd(OUT_B, 20);
while (!SensorBoolean(IN_1))
{
wait(50);
}
Off(OUT_B);
}

task main()
{
SetSensorTouch(IN_1);
ResetScanHead();
}

Print Encoded Line Segment (eg, "    xxxx    xxxx    xxxx")

void PrintEncodedLineSegment(const string ALine)
{
  int i = 1;
  int LSkip = 0;
  int LLineLen;
  string LThisChr = " ";
  string LLastChr = " ";

  LLineLen = strlen(ALine);
  for (i; i<= LLineLen; i++)
  {
    LThisChr = SubStr(ALine, i, 1);
    
    if (LThisChr == LLastChr)
      {LSkip++;}
    else
    {
      if (LLastChr == " ")
        {PenUp();}
      else
        {PenDown();}
      LLastChr = LThisChr;
      AdvancePrinterHead(LSkip);
      LSkip = 1;
    }
  }
  PenUp();
  ResetPrinterHead();
  AdvancePaper(1);
}

Calibrate light sensor

task main()
{
  SetSensorLight(IN_1, true);
  while (true)
  {
    ClearScreen();
    NumOut(10, 10, SensorValue(IN_1));
    Wait(100);
  }
}

Forward then stop on line

task main()
{
  SetSensorLight(IN_1, true);
  OnFwd(OUT_AC, 50);
  while (SensorValue(IN_1) > 50)
  {
    Wait(50);
  }
  Off(OUT_AC);
}

Test Ultrasonic Sensor Read Time

#define CRepeat 100

task main()
{
  unsigned int LStart;
  unsigned int LEnd;
  
  SetSensorLight(IN_1);
  SetSensorUltrasonic(IN_2);
  
  // Time how long to read the light sensor
  LStart = CurrentTick();
  repeat(CRepeat)
  {
    SensorValue(IN_1);
  }
  LEnd = CurrentTick();
  TextOut(10, LCD_LINE3, "Light:");
  NumOut(80, LCD_LINE3, (LEnd - LStart) / CRepeat);

  // Time how long to read the US Sensor
  LStart = CurrentTick();
  repeat (CRepeat)
  {
    SensorUS(IN_2);
  }
  LEnd = CurrentTick();
  TextOut(10, LCD_LINE5, "Untrasonic:");
  NumOut(80, LCD_LINE5, (LEnd - LStart) / CRepeat);
  Wait(3000);
  
}

Parallel Tasks

Requires the enhanced NXC firmware from here. Use Tools | Download firmware in the BricxCC to install.

#define CRepeat 100

int GSensorUSValue;

task CEReadSensorUS()
{
  while (true)
  {
   GSensorUSValue = SensorUS(IN_2);
   Wait(20);
  }
}

task main()
{

  SetSensorLight(IN_1);
  SetSensorUltrasonic(IN_2);

  start CEReadSensorUS;

  while (true)
  {
    ClearLine(LCD_LINE5);
    NumOut(10, LCD_LINE5, GSensorUSValue);
    Wait(100);
  }

}

Execute some code for a defined time

This fragment shows how to execute some code for a limited time.

#define CTaskTime 3000

task main()
{
  unsigned long LStart;
  unsigned long LNow;
  
  LStart = CurrentTick();
  LNow = LStart;
  while ((LNow - LStart) <= CTaskTime)
  {
    ClearLine(LCD_LINE5);
    NumOut(10, LCD_LINE5, (LNow - LStart));
    Wait(100);
    LNow = CurrentTick();
  }
}

Wait for a NXT button press

This code shows how to wait for a NXT button to be pressed.

void WaitForCenterButton()
{
  while (!ButtonPressed(BTNCENTER, true))
    Wait(50);
}

task main()
{
  TextOut(0, LCD_LINE4, "   Press the");
  TextOut(0, LCD_LINE5, "  button"); 
  TextOut(0, LCD_LINE6, " to continue..."); 
  WaitForCenterButton(); 
  ClearScreen(); 
  TextOut(0, LCD_LINE5, " The
"); TextOut(0, LCD_LINE6, " was pressed."); Wait(5000); }

Save data to a file

This code shows how to save data to a file. In the BricxCC, use "Tools | NXT Explorer" to view the file and edit it's contents.

void WriteToFile(
  const string AValue1,
  const string AValue2,
  const string AValue3)
{

  byte         LFileHandle;
  unsigned int LReturnCode;

  // Try to create a new file
  LReturnCode = CreateFile(CDataFileName, 1024, LFileHandle);

  // If it already exists, delete it and try to create it again
  if (LReturnCode == LDR_FILEEXISTS)
  {
    DeleteFile(CDataFileName);
    LReturnCode = CreateFile(CDataFileName, 1024, LFileHandle);
  }

  // If the file could not be opened, abort the program
  AbortIfFileError(LReturnCode);

  WriteLn(LFileHandle, AValue1);
  WriteLn(LFileHandle, AValue2);
  WriteLn(LFileHandle, AValue3);

  CloseFile(LFileHandle);

}

Read from file

This code shows how to read data from a file. In the BricxCC, use "Tools | NXT Explorer" to view the file and edit it's contents.

#define CDataFileName "data.txt"

void AbortIfFileError(unsigned int AReturnCode)
{
  if (AReturnCode != LDR_SUCCESS)
  {
     TextOut(10, LCD_LINE5, "Read error: " + NumToStr(AReturnCode));
     Wait(5000);
     abort();
  }
}

void ReadFromFile(
  string &AValue1,
  string &AValue2,
  string &AValue3)
{
  byte         LFileHandle;
  unsigned int LFileSize;
  unsigned int LReturnCode;

  // Try to create a new file
  LReturnCode = OpenFileRead(CDataFileName, LFileSize, LFileHandle);

  // If the file could not be opened, abort the program
  AbortIfFileError(LReturnCode);

  ReadLnString(LFileHandle, AValue1);
  ReadLnString(LFileHandle, AValue2);
  ReadLnString(LFileHandle, AValue3);

  CloseFile(LFileHandle);

}

task main()
{
  string LValue1 = "";
  string LValue2 = "";
  string LValue3 = "";
    
  ReadFromFile(
    LValue1,
    LValue2,
    LValue3);
    
  TextOut(10, LCD_LINE3, LValue1);
  TextOut(10, LCD_LINE4, LValue2);
  TextOut(10, LCD_LINE5, LValue3);
  Wait(5000);

}

Toggle menu