I wanna send data to a UART (motor controller) and when I test the software the UART stop to send in few seconds, I dont know why, but when I remove this part of the code:
enviado = sendDataUART(0x21,0,2); //Leemos la velocidad de motor 1 (izquierdo)
while(enviado == false)
{
enviado = sendDataUART(0x21,0,2);
}
enviado = sendDataUART(0x22,0,2); //Leemos la velocidad de motor 2 (derecho)
while(enviado == false)
{
enviado = sendDataUART(0x22,0,2);
}
enviado = sendDataUART(0x26,0,2); //Leemos la tensión
while(enviado == false)
{
enviado = sendDataUART(0x26,0,2);
}
it works fine. Could you tell me why? Thank you
Here is the complete code:
#include <MapleFreeRTOS.h>
#include <exti.h>
//***********************************
//PARAMETROS CONFIGURACIÓN PLATAFORMA
//***********************************
#define PULSOS_POR_VUELTA 360 //ticks de una vuelta completa para el eje de salida
#define DIAMETRO_RUEDA 0.09 //radio en m (100mm)
#define DISTANCIA_EJES 0.25 //Distancia entre ejes en m (200mm)
//***************************************
//CONFIGURAMOS LOS NOMBRES DE LOS PUERTOS
//***************************************
int ledPin = 13; // LED connected to digital pin 13
//*********************
//CREAMOS LAS VARIABLES
//*********************
//Calculo de posición y encoders
double x_actual = 0;
double y_actual = 0;
float teta_actual = 0;
int delta_ticksLeft = 0;
int delta_ticksRight = 0;
boolean reading_enc = false;
unsigned long encoder_izq_new = 0;//encoder izq = encoder 1 de la PCB
unsigned long encoder_der_new = 0;//encoder_der = encoder 2 de la PCB
unsigned long encoder_izq_old = 0;//encoder izq = encoder 1 de la PCB
unsigned long encoder_der_old = 0;//encoder_der = encoder 2 de la PCB
double x_enc = 0;
double y_enc = 0;
float teta_enc = 0;
double s_izq = 0;
double s_der = 0;
//lecturas de la MD25
int vel_izq = 0;
int vel_der = 0;
int volt_12v = 0;
int curr_izq = 0;
int curr_der = 0;
//otros
xQueueHandle xQueue_izq;
xQueueHandle xQueue_der;
xSemaphoreHandle xSemaphore_UART;
//********************
//DEFINIMOS LAS TAREAS
//********************
static void vTaskSerialUSB( void *pvParameters )
{
boolean enviado;
portTickType xLastWakeTimeSerialUSB;
const portTickType xFrequencySerialUSB = 1000; // Ejecutamos la tarea cada 1000ms
xLastWakeTimeSerialUSB = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time.
for(;;)
{
vTaskDelayUntil(&xLastWakeTimeSerialUSB, xFrequencySerialUSB);
SerialUSB.print("encoder izq: ");
SerialUSB.print(encoder_izq_new);
SerialUSB.print("\t");
SerialUSB.print("encoder der: ");
SerialUSB.print(encoder_der_new);
SerialUSB.print("\t");
SerialUSB.print("x_enc: ");
SerialUSB.print(x_enc);
SerialUSB.print("\t");
SerialUSB.print("y_enc: ");
SerialUSB.print(y_enc);
SerialUSB.print("\t");
SerialUSB.print("teta_enc: ");
SerialUSB.print(teta_enc);
SerialUSB.print("\n");
enviado = sendDataUART(0x21,0,2); //Leemos la velocidad de motor 1 (izquierdo)
while(enviado == false)
{
enviado = sendDataUART(0x21,0,2);
}
enviado = sendDataUART(0x22,0,2); //Leemos la velocidad de motor 2 (derecho)
while(enviado == false)
{
enviado = sendDataUART(0x22,0,2);
}
enviado = sendDataUART(0x26,0,2); //Leemos la tensión
while(enviado == false)
{
enviado = sendDataUART(0x26,0,2);
}
SerialUSB.print("vel izq: ");
SerialUSB.print(vel_izq);
SerialUSB.print("\t");
SerialUSB.print("ve der: ");
SerialUSB.print(vel_der);
SerialUSB.print("\t");
SerialUSB.print("volt 12v: ");
SerialUSB.print(volt_12v);
SerialUSB.print("\n");
//togglePin(ledPin);
}
}
static void vTaskPosCalc( void *pvParameters )
{
for(;;)
{
sendDataUART(0x32,0x08,3);
sendDataUART(0x31,0x08,3);
while(x_enc < 1.0)
{
digitalWrite(ledPin, HIGH);
}
sendDataUART(0x31,0xf8,3);
while(teta_enc<1.57)
{
digitalWrite(ledPin, HIGH);
}
sendDataUART(0x31,0x08,3);
while(y_enc < 1)
{
digitalWrite(ledPin, HIGH);
}
sendDataUART(0x31,0xf8,3);
while(abs(teta_enc)<3.10)
{
digitalWrite(ledPin, HIGH);
}
sendDataUART(0x31,0x08,3);
while(abs(x_enc) > 0.03)
{
digitalWrite(ledPin, HIGH);
}
sendDataUART(0x31,0xf8,3);
while(abs(teta_enc)>1.57)
{
digitalWrite(ledPin, HIGH);
}
sendDataUART(0x31,0x08,3);
while(abs(y_enc) > 0.03)
{
digitalWrite(ledPin, HIGH);
}
sendDataUART(0x31,0xf8,3);
while(abs(teta_enc)<0.03)
{
digitalWrite(ledPin, HIGH);
}
sendDataUART(0x32,0x00,3);
sendDataUART(0x31,0x00,3);
}
}
static void vTaskEncCount( void *pvParameters )
{
boolean enviado;
portTickType xLastWakeTimeEncCount;
const portTickType xFrequencyEncCount = 10; // Ejecutamos la tarea vTaskEncCount cada 10ms
xLastWakeTimeEncCount = xTaskGetTickCount(); // Initialise the xLastWakeTime variable with the current time.
for(;;)
{
vTaskDelayUntil(&xLastWakeTimeEncCount, xFrequencyEncCount);
enviado = sendDataUART(0x25,0,2); //Leemos la posición global de los encoders
while(enviado == false)
{
enviado = sendDataUART(0x25,0,2);
}
reading_enc = true;
xQueueReceive(xQueue_der, &encoder_der_new, 0);
xQueueReceive(xQueue_izq, &encoder_izq_new, 0);
odometer_thread();
}
}
//**********
//FUNCIONES
//**********
boolean sendDataUART(char command, char data, char numbytes)
{
xSemaphoreTake( xSemaphore_UART, ( portTickType ) 100 );
int numUnread=0;
int watchdog=0;
unsigned long time1;
unsigned long time2;
char buf[3];
buf[0] = 0x00;
buf[1] = command;
buf[2] = data;
Serial1.write(buf, numbytes);
if (command == 0x25) //LECTURA ENCODERS
{
time1 = millis();
do
{
numUnread = Serial1.available();
time2 = millis();
if(time2 > time1)
watchdog = time2-time1;
else
watchdog = 0xffffffff - time2 + time1;
}
while(numUnread < 8 || watchdog > 500);
if(watchdog > 500)
return false;
else
{
encoder_izq_old = encoder_izq_new; //guardo los viejos encoders en variables
encoder_der_old = encoder_der_new; //guardo los viejos encoders en variables
encoder_izq_new = 0;
encoder_der_new = 0;
for(int i = 0; i < 4; i++)
{
encoder_izq_new = encoder_izq_new + (Serial1.read() << (24-8*i));
}
for(int i = 0; i < 4; i++)
{
encoder_der_new = encoder_der_new + (Serial1.read() << (24-8*i));
}
xSemaphoreGive( xSemaphore_UART );
return true;
}
}
else if (command == 0x21 || command == 0x22 || command == 0x26 || command == 0x27 || command == 0x28)
{
time1 = millis();
do
{
numUnread = Serial1.available();
time2 = millis();
if(time2 > time1)
watchdog = time2-time1;
else
watchdog = 0xffffffff - time2 + time1;
}
while(numUnread < 1 || watchdog > 500);
if(watchdog > 500)
return false;
else
{
if(command == 0x21)
{
vel_izq = Serial1.read();
xSemaphoreGive( xSemaphore_UART );
return true;
}
else if(command == 0x22)
{
vel_der = Serial1.read();
xSemaphoreGive( xSemaphore_UART );
return true;
}
else if(command == 0x26)
{
volt_12v = Serial1.read();
xSemaphoreGive( xSemaphore_UART );
return true;
}
else if(command == 0x27)
{
curr_izq = Serial1.read();
xSemaphoreGive( xSemaphore_UART );
return true;
}
else if(command == 0x28)
{
curr_der = Serial1.read();
xSemaphoreGive( xSemaphore_UART );
return true;
}
}
}
xSemaphoreGive( xSemaphore_UART );
}
void initialize_odometry(double new_x, double new_y, float new_teta)
{
x_enc = new_x;
y_enc = new_y;
teta_enc = new_teta;
}
void odometer_thread()
{
int delta_enc_izq;
int delta_enc_der;
double expr1;
double cos_current;
double sin_current;
double right_minus_left;
double MUL_COUNT;
MUL_COUNT = PI * DIAMETRO_RUEDA / PULSOS_POR_VUELTA;
delta_enc_izq = encoder_izq_new - encoder_izq_old;
delta_enc_der = encoder_der_new - encoder_der_old;
s_izq = (double)delta_enc_izq * MUL_COUNT;
s_der = (double)delta_enc_der * MUL_COUNT;
cos_current = cos(teta_enc);
sin_current = sin(teta_enc);
if (s_izq == s_der)
{
/* Moving in a straight line */
x_enc = x_enc + s_izq * cos_current;
y_enc = y_enc + s_der * sin_current;
}
else
{
/* Moving in an arc */
expr1 = DISTANCIA_EJES * (s_der + s_izq) / 2.0 / (s_der - s_izq);
right_minus_left = s_der - s_izq;
x_enc = x_enc + expr1 * (sin(right_minus_left / DISTANCIA_EJES + teta_enc) - sin_current);
y_enc = y_enc - expr1 * (cos(right_minus_left / DISTANCIA_EJES + teta_enc) - cos_current);
/* Calculate new orientation */
teta_enc = teta_enc + right_minus_left / DISTANCIA_EJES;
/* Keep in the range -PI to +PI */
while(teta_enc > PI)
teta_enc = teta_enc - (2.0*PI);
while(teta_enc < -PI)
teta_enc = teta_enc + (2.0*PI);
}
}
// The setup() method runs once, when the sketch starts
void setup()
{
//configurar UART
Serial1.begin(38400);
// initialize the digital pin as an output:
pinMode(ledPin, OUTPUT);
delay(5000);
digitalWrite(ledPin, HIGH);
xQueue_izq = xQueueCreate( 2, sizeof(unsigned long) );
xQueue_der = xQueueCreate( 2, sizeof(unsigned long) );
vSemaphoreCreateBinary( xSemaphore_UART );
xTaskCreate(vTaskSerialUSB, (const signed char *)"SerialUSB", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
xTaskCreate(vTaskPosCalc, (const signed char *)"PosCalc", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
xTaskCreate(vTaskEncCount, (const signed char *)"EncCount", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 3, NULL);
sendDataUART(0x35,0,2); //Reseteo encoders
sendDataUART(0x34,0x01,3); //Configuro motores en modo
vTaskStartScheduler();
}
void loop()
{
// Insert background code here
}