NQC

NQC, Not Quite C, No Suficiente C, es un lenguaje de programación parecido al C, para programar el RCX de LEGO. Fue desarrollado por un ingeniero de Motorola llamado Dave Baum y es totalmente gratuito. Funciona desde la línea de comandos, esto significa que su funcionamiento es muy parecido al MS-DOS, aunques mucho más cómodo utilizarlo con el RCX Comand Center.

Programación del RCX mediante NQC 

En el libro de Dave Baum "Dave's Baum Definitive Guide To LEGO® MINDSTOMS" se puede encontrar toda la documentación necesaria para programar. Lo único que se necesita es un editor de texto, como puede ser el Bloc de Notas que acompaña a todas las versiones de Windows, y el compilador. Para aprender este lenguaje de programación existe la posibilidad de seguir el libro de Baum, o el preparado por Mark Overmars.

El RCX Comand Center es un entorno de programación que facilita la escritura de los programas, su depuración y su descarga al RCX. También dispone de una extensa ayuda sobre el NQC disponible en línea. Entre otros extras dispone de un teclado para facilitar la creación de código musical y de un joystick para enviar órdenes al robot desde el PC.

RCXCC 
Una vez iniciado el RCXCC, podemos ver que este programa es un simple editor de texto, con sus principales botones de abrir, guardar, imprimir, etc. Se conectará la torre de infrarrojos junto al RCX encendido y se pulsará OK.
Se observará una pantalla, donde aparecerá la tarea principal, main, que ejecutará el robot. Toda tarea está formada por diversas instrucciones que deberán ir entre llaves({}):
task main()
{
    instrucción 1;
    instrucción 2;
    ...
}
Las distintas instrucciones que podemos dar, serían:
 Iniciar la salida: OnFwd(OUT_A), donde A sería el motor que deseamos arrancar. Si el robot tiene varios motores, podemos arrancarlos a la vez poniendo: OnFwd(OUT_A+OUT_B...)
 Cambiar la velocidad del motor o motores: (OUT_A+OUT_B...3). La potencia varía entre los valores 0 y 7.
 Esperar un tiempo: Wait(xxx), donde xxx serán los "tics" o centésimas de segundo. Si fuera 500, el programa no hará nada durante 5 segundos.
 Regresar en sentido contrario: OnRev(OUT_A+OUT_B...). Si sólo mandamos la instrucción para un motor, el robot girará.
 Detener los motores:Off(OUT_A+OUT_B...)

Una vez realizado el programa, será necesario compilarlo, es decir, pasarlo al código que el robot pueda interpretar, y enviárselo, pulsando el botón. Si se ha cometido algún error, el programa lo notificará.

En NQC, también es posible definir constantes de precompilador:
#define TIEMPO_DE_AVANCE 300
#define TIEMPO_DE_RETROCESO 200
task main()
{
    On(OUT_A+OUT_B...);
    Wait(TIEMPO_DE_AVANCE);
    Rev(OUT_A+OUT_B...);
    Wait(TIEMPO_DE_RETROCESO);
    Off(OUT_A+OUT_B...);
}

Si queremos repetir alguna acción, utilizaríamos la instrucción repeat:

#define TIEMPO_DE_AVANCE 300
#define TIEMPO_DE_RETROCESO 200
task main()
{
    On(OUT_A+OUT_B...);
    repeat(2) 
    {
        Fwd(OUT_A+OUT_B...);
        Wait(TIEMPO_DE_AVANCE);
        Rev(OUT_A+OUT_B...);
        Wait(TIEMPO_DE_RETROCESO);
    } 
    Off(OUT_A+OUT_B...);
}

La acción se repetirá dos veces. Esto se define introduciendo entre paréntesis la cantidad de repeticiones que deseemos, tras el repeat.

También es posible introducir comentarios. Estos se escriben detrás de //. En el caso de que el comentario sea extenso, este irá entre /* comentario */.
Los comentarios permiten que el programa sea más fácil de entender por otros programadores.

Similar a C 

Al igual que en C, si necesitamos definir una variable, utilizaríamos int variable. Si queremos que el programa se ejecute sólo en ciertas ocasiones utilizaríamos if/else. Se pueden comparar valores de diferentes formas:

    ==  igual a        <=   menor o igual que     >=    mayor o igual que
    <   menor que      >    mayor que             !=    diferente de

Si deseamos que la acción se realice siempre que la condición sea verdadera, utilizaremos do

Sensores 

Podemos hacer que el robot reaccione si ocurre algo, gracias a los sensores que se le pueden conectar a este.
 Dependiendo de donde se lo conectemos se denominará de una forma u otra, SENSOR_1, SENSOR_2,....SENSOR_X.
 Dependiendo del tipo de sensor que vayamos a utilizar: SENSOR_TOUCH, SENSOR_LIGHT, SENSOR_ROTATION, SENSOR_TEMPERATURE...
Un ejemplo de programa para un sensor de contacto podría ser el siguiente:
task main()
{
    SetSensor(SENSOR_2,SENSOR_TOUCH);
    OnFwd(OUT_A+OUT_B...);
    until (SENSOR_1 == 1);
    Off(OUT_A+OUT_B...);
}

El sensor de luz mide la cantidad de luz que hay en una determinada dirección. Esto es posible, debido a que el sensor emite luz, y es capaz de distinguir la intensidad reflejada en el objeto al que está apuntando. Este tipo de sensor es muy utilizado cuando se desea que el robot siga solo una determinada dirección.

Tareas 

Un programa en NQC consta como máximo de diez tareas. Como ya se mencionó, la tarea principal main, y otras secundarías que se ejecutarán con la orden start y se detendrán con la orden stop. Si se deseas iniciar de nuevo la tarea, ésta empezará desde le principio, no desde que se detuvo.

La tarea main, define los sensores, si los hubiera, e inicia las demás tareas. A continuación la tarea main finaliza y se realizan la demás tareas. Hay que tener en cuenta que las tareas se inician de manera simultánea. Esto puede dar lugar a resultados inesperados si no se programa de forma correcta.

Subrutinas 

En ocasiones es necesario usar una parte del código en varias partes del programa. Para ello se utilizan las subrutinas. Sólo habría que asignarle un nombre tras la palabra sub, y escribirlo cuando se necesite. Un programa soporta hasta ocho subrutinas.

Se deberán tomar las siguientes precauciones:

 Una subrutina no puede ser llamada desde otra subrutina.
 Una subrutina puede ser llamada desde distintas tareas, pero si no se está seguro de lo que se hace, es conveniente no hacerlo, ya que puede dar lugar a errores, al estar ejecutándose en varias tareas.
 No usar expresiones complicadas, para denominar a las subrutinas.

Funciones 

Cuando las subrutinas son demasiado cortas, es conveniente utilizar funciones en su lugar. Estas se copian en el sitio donde se quieren utilizar. Consumen más memoria, pero son ilimitadas y no se producen errores al utilizar expresiones complicadas.

Al igual que en otros lenguajes de programación, como en C, se utiliza la palabra void, para definir las funciones.

Las funciones además tienen otra ventaja frente a las subrutinas, que es la posibilidad de tener argumentos, que puedan ser utilizados para dar valores a ciertas variables de la función.

Macros 

Las macros son muy útiles para definir pequeños fragmentos de código que han de ser utilizados en diferentes lugares. Esto convierte el código en más compacto y legible. Además pueden tener parámetros.

Música 

El RCX tiene incorporado un altavoz que produce sonidos, e incluso pequeñas melodías. Esto se utiliza cuando el robot hace alguna acción en particular, o bien mientras este se mueve.
Los sonidos se pueden generar con la orden playsound (). Entre los paréntesis se introduce uno de los siguientes sonidos:

    0     Clik de tecla.
    1     Pitido.
    2     Barrido de frecuencia decreciente.
    3     Barrido de frecuencia creciente.
    4     Buhhh sonido de error.
    5     Barrido rápido de crecimiento.

Referencias 
NQC para distintos sistemas operativos:
 NQC IDE para DOS
 NQC IDE para BeOS 
 NQC IDE para OS X
 NQC IDE para Windows
 NQC IDE para Linux
 NQC para Ubuntu
Enlaces externos:
 NQC tutorial por Mark Overmars
 NQC tutorial por Matt Miller

Lenguajes de programación
Software robótico