Skip to content
monkeyserna edited this page May 10, 2014 · 36 revisions

La placa Arduino recibe por puerto USB un comando de 3 bytes de longitud, donde el primer byte indica el comando, y los dos restantes están destinados a parámetros. Estos parámetros, al ser de tipo byte, contemplan un rango numérico del 0 al 255.

Hay 16 comandos disponibles. Los 11 primeros están relacionados con el movimiento de los motores (comandos 0 al 10). El comando 11 está destinado al zumbador, el 12 al encendido y apagado de los leds, y los 4 últimos (13 al 16) realizan distintas lecturas de los sensores infrarrojos CNY70.

A continuación se detallan las funciones del código.

void setup()

Inicializa el código.

Abre la comunicación serie a 9600 baudios para poder realizar la comunicación por USB con la Raspberry Pi, y establece los modos de los pines de entrada y salida.

También establece la resolución de la escritura analógica a 10 bytes (esto significa que los valores que se pueden escribir con la función analogWrite(pin,value) van desde 0 hasta 1023). Por defecto, Arduino Due tiene una resolución de 12 bytes, aunque para mantener la compatibilidad con Arduino Mega, la placa GOShieldGR tiene una resolución de 10 bytes. La escritura analógica se emplea en el movimiento de los motores.

void loop()

Esta función espera a recibir un comando y mediante un switch llama a la función correspondiente.

Si hay 3 bytes disponibles en el buffer de la comunicación serie

void loop()
{
	//Receive a message (3 bytes)
	if (Serial.available() >= 3)
	{
		byte cmd = Serial.read();  //Command
		byte p1  = Serial.read();  //First parameter
		byte p2  = Serial.read();  //Second parameter
		
		switch (cmd)
		{
			//Command 0 -> Stop
			case 0:
			stopMotors();
			break;
			
			[... resto de comandos...]	
		}
	}
}

Los comandos disponibles son los siguientes:

  1. stopMotors(): Detiene el movimiento de los motores
  2. moveBalanced(speed,balance): Mueve los motores hacia adelante. El primer parámetro que recibe indica la velocidad, y el segundo el balance (0 se corresponde con un giro brusco a la izquierda, 123 avanza hazia adelante y 255 gira bruscamente a la derecha)
  3. setLeftSpeed(speed): Establece la velocidad del motor izquierdo.
  4. setRightSpeed(speed): Establece la velocidad del motor derecho.
  5. moveForward(speed): Establece la velocidad de ambos motores.
  6. turnLeft(speed): Establece la velocidad del motor izquierdo y detiene el derecho.
  7. turnRight(speed): Establece la velocidad del motor derecho y detiene el izquierdo.
  8. moveBackBalanced(speed,balance): Mueve los motores hacia atrás con velocidad y balance.
  9. moveBackBoth(speed): Establece la velocidad de movimiento hacia atrás de ambos motores.
  10. moveBackLeft(speed): Establece la velocidad de movimiento hacia atrás del motor izquierdo.
  11. moveBackRight(speed): Establece la velocidad de movimiento hacia atrás del motor derecho.
  12. beep(state): Establece el estado (encendido = 1, apagado = 0) del zumbador.
  13. led(numLed, state): Enciende (_state_ = 1) o apaga (_state_ = 0) el led _numLed_ (entre 0 y 13).
  14. sendFrontAndMiddle(): Lee todos los sensores infrarrojos y los envía los valores por USB.
  15. sendFront(): Lee los sensores frontales en binario (negro = 1, blanco = 0) y envía los valores por USB.
  16. sendMiddle(): Lee los sensores centrales en binario (negro = 1, blanco = 0) y envía los valores por USB.
  17. sendAnalogFront(): Lee los sensores frontales en analógico y envía los valores por USB.

Funciones de motores

A continuación se explican las funciones asociadas al movimiento de los motores. Cada motor tiene asociadas 2 señales para controlar su movimiento.

La explicación detallada del funcionamiento de los motores está disponible <<<en esta página>>>.

void stopMotors()

Esta función implementa el comando 0.

Puede ser invocada desde Raspberry Pi mediante el mensaje: [0,0,0] (bytes).

No recibe parámetros.

Realiza lo siguiente:

Realiza un frenado por bloqueo estableciendo las 4 señales de los motores al valor máximo.

Este freno es el más rápido, aunque también el más agresivo. Para realizar un frenado gradual (también llamado frenado por descarga o frenado al aire) se puede emplear la función moveForward(0), que se corresponde con la señal [4,0,0].

El código es el siguiente:

void stopMotors()
{
	analogWrite(O_Bin1,MAX_ANALOG_RESOLUTION);
	digitalWrite(O_Bin2,HIGH);
	analogWrite(O_Ain1,MAX_ANALOG_RESOLUTION);
	digitalWrite(O_Ain2,HIGH);
}

El código es el siguiente:

void setForwardSpeedRight(int speed)

Función interna, es invocada desde otras funciones, nunca directamente desde la Raspberry ya que primero el valor debe ser escalado desde [0,255] a [0,KMAXSPEED]

Recibe un valor entre 0 y KMAXSPEED. Esta constante es la velocidad máxima de los motores, que por defecto es 400, y como máximo puede ser 1023, que es la resolución de la escritura analógica. Poner los motores a máxima velocidad no es recomendable ya se pueden dañar. La velocidad máxima recomendada es de 750, aunque esto hace la conducción del robot complicada.

Establece la primera señal del motor derecho a la velocidad indicada, y la segunda a nivel bajo. Si la velocidad está fuera del rango permitido, establece la misma al valor máximo o mínimo según corresponda.

void setForwardSpeedRight(int speed)
{
	//Check if numbers are out of range
	if      (speed < 0)         speed = 0;
	else if (speed > KMAXSPEED) speed = KMAXSPEED;

	//Set motor speed
	analogWrite(O_Ain1,speed);
	digitalWrite(O_Ain2,LOW);
}

void setForwardSpeedLeft(int speed)

Función interna, es invocada desde otras funciones, nunca directamente desde la Raspberry ya que primero el valor debe ser escalado desde [0,255] a [0,KMAXSPEED]

Recibe un valor entre 0 y KMAXSPEED. Esta constante es la velocidad máxima de los motores, que por defecto es 400, y como máximo puede ser 1023, que es la resolución de la escritura analógica. Poner los motores a máxima velocidad no es recomendable ya se pueden dañar. La velocidad máxima recomendada es de 750, aunque esto hace la conducción del robot complicada.

Establece la primera señal del motor izquierdo a la velocidad indicada, y la segunda a nivel bajo. Si la velocidad está fuera del rango permitido, establece la misma al valor máximo o mínimo según corresponda.

void setForwardSpeedLeft(int speed)
{
	//Check if numbers are out of range
	if      (speed < 0)         speed = 0;
	else if (speed > KMAXSPEED) speed = KMAXSPEED;

	//Set motor speed
	analogWrite(O_Bin1,speed);
	digitalWrite(O_Bin2,LOW);
}

setMotors(int left, int right)

Función interna, es invocada desde otras funciones, nunca directamente desde la Raspberry ya que primero el valor debe ser escalado desde [0,255] a [0,KMAXSPEED]

Recibe los parámetros:

  1. int left Velocidad del motor izquierdo entre [0,KMAXSPEED]
  2. int right Velocidad del motor dercho entre [0,KMAXSPEED]

Establece la velocidad de los motores haciendo uso de las funciones auxiliares setForwardSpeedRight(left) y setForwardSpeedLeft(right)

void setMotors(int left, int right)
{
	setForwardSpeedRight(left);
	setForwardSpeedLeft(right);
}

void turnLeft(byte speed)

Esta función implementa el comando 5.

Puede ser invocada desde Raspberry Pi mediante el comando: [5,<speed>,0] (bytes)

Recibe el parámetro:

  1. byte speed: Velocidad en el rango [0,255] a la que se establece el motor izquierdo.

Descripción de la función:

  • Escala el valor recibido en el parámetro speed de [0,255] a [0,KMAXSPEED] y establece la velocidad del motor izquierdo. Además, establece a 0 la velocidad del motor derecho, esto garantiza que (en caso de proporcionar una velocidad de giro suficiente) se realice el giro.

Código fuente:

void turnLeft(byte speed)
{
	int speedMapped = map(speed,0,255,0,KMAXSPEED);
	setForwardSpeedRight(0);
	setForwardSpeedLeft(speedMapped);
}

void turnRight(byte speed)

Esta función implementa el comando 6.

Puede ser invocada desde Raspberry Pi mediante el comando: [6,<speed>,0] (bytes)

Recibe el parámetro:

  1. byte speed: Velocidad en el rango [0,255] a la que se establece el motor derecho.

Descripción de la función:

  • Escala el valor recibido en el parámetro speed de [0,255] a [0,KMAXSPEED] y establece la velocidad del motor derecho. Además, establece a 0 la velocidad del motor izquierdo, esto garantiza que (en caso de proporcionar una velocidad de giro suficiente) se realice el giro.

Código fuente:

void turnRight(byte speed)
{
	int speedMapped = map(speed,0,255,0,KMAXSPEED);
	setForwardSpeedRight(speedMapped);
	setForwardSpeedLeft(0);
}

void setLeftSpeed(byte speed)

void setLeftSpeed(byte speed)
{
	int speedMapped = map(speed,0,255,0,KMAXSPEED);
	setForwardSpeedLeft(speedMapped);
}

void setRightSpeed(byte speed)

void setRightSpeed(byte speed)
{
	int speedMapped = map(speed,0,255,0,KMAXSPEED);
	setForwardSpeedRight(speedMapped);
}

void moveBalanced(byte speed, byte balance)

void moveBalanced(byte speed, byte balance)
{
	//Sets speed between 0 and KMAXSPEED
	int speedMapped = map(speed,0,255,0,KSTRAIGHTSPEED);

	//Sets balance between -KTURNSPEED and KTURNSPEED
	int balanceMapped = map(balance,0,255,-KTURNSPEED,KTURNSPEED);

	//Sets speed of left and right motors
	int left = speedMapped - balanceMapped;
	int right = speedMapped + balanceMapped;

	setMotors(left,right);
}

void moveForward(byte speed)

void moveForward(byte speed)
{
	//Sets speed between 0 and KMAXSPEED
	int speedMapped = map(speed,0,255,0,KMAXSPEED);

	setMotors(speedMapped,speedMapped);
}


Otros comandos

void led(byte num,bool state)

Controla el estado de los leds. Esta función puede ser invocada por comunicación USB con el comando 12, y recibe 2 parámetros. El primero, entre 0 y 13 se corresponde con el número de led. El segundo indica el estado (1 es encendido, y 0 apagado).

La placa GoShield-GR lleva incorporados 14 leds, 12 de ellos en las posiciones de los sensores frontales, y otros 2 en el centro. Por tanto, para establecer su estado (encendido o apagado), se envía como primer parámetro un valor numérico entre 0 y 13, donde 0 es el led situado más a la izquierda, 11 el que está más a la derecha, y 13 y 14 los dos leds adicionales situados en el centro.

Esta función comprueba el rango de los leds, entre o y 13. Si el valor es mayor, encenderá el led número 13, correspondiente al led secundario central situado ligeramente a la derecha.

Por otra parte, recibe como segundo parámetro un booleano que indica el estado del led. Si un valor es distinto de 0, se considera true y se encenderá el led. En caso de recibir un 0, el estado del led será apagado.

void led(byte num,bool state)
{
	if		(num < 0)			num = 0;
	else if (num >= NUMLEDS)	num = NUMLEDS-1;
	
	digitalWrite(LEDS[num],state);
}

void beep(bool status)

Establece el estado del zumbador, o claxon. 0 equivale a apagado, y cualquier otro valor (entre 1 y 255) establece el zumbador a activo.

void beep(bool status)
{
	digitalWrite(O_BUZZER,status);
}