Buenos días, estoy teniendo problemas con la implementación de un codigo. Realmente no es en arduino pero he visto que se puede hacer tambien aqui y no he querido dejar pasar la oportunidad de ver si alguien me puede dar una manita y asi tambien se queda implementado para Arduino.
Os pongo en situación.
Tengo 8 motores que han trabajado "x" horas cada uno. De comienzo 0-horas todos.
Ahora quiero realizar el codigo para que cuando yo solicite que arranque un motor cada 100 horas de trabajo tenga definida una secuencia de arranque donde siempre sea el primero el que menos horas lleve.
Mi problema reside en que esto no he tenido problemas siempre y cuando no tenga valores repetidos.
Os indico la secuencia que he realizado para resolver el problema.
1.) escaneo el numero de horas trabajas de cada motor.
2.) con el codigo de ordenación burbuja las ordeno en un array de menor a mayor numero de horas.
3.) activo una variable auxiliar para saber que ya he acabado la ordenación y por tanto puedo trabajar.
4.) pasadas un numero de horas determinadas y con la codicion de que todos los motores esten parados vuelvo a leer los datos de las horas y los ordeno para tener nuevamente otro orden de arranque.
Hasta aqui no tengo ningun problema. Tengo que decir que no lo tengo en arduino sino en SCL que es como C++ para simatic. pero es practicamente igual.
FUNCTION_BLOCK FB58
VAR_INPUT
MI_DB: BLOCK_DB;
Ordenar: BOOL;
Reset: BOOL;
Entrada00:BOOL;
Entrada01:Bool;
Entrada02:BOOL;
Entrada03:BOOL;
Entrada04:BOOL;
Entrada05:BOOL;
Entrada06:BOOL;
Entrada07:BOOL;
END_VAR
VAR_OUTPUT
Salida00:BOOL;
Salida01:BOOL;
Salida02:BOOL;
Salida03:BOOL;
Salida04:BOOL;
Salida05:BOOL;
Salida06:BOOL;
Salida07:BOOL;
END_VAR
VAR
//VARIABLE PARA RECOPILAR DATOS
HORAS_TRABAJO_MOTOR: ARRAY [0..7]OF INT;
HORAS_TRABAJO_MOTOR_ORD: ARRAY [0..7]OF INT;
Entrada: ARRAY [0..7]OF bool;
Salida: ARRAY [0..7]OF BOOL;
//SALIDA: ARRAY [0..7]OF BOOL;
i: INT := 0 ; // variable auxiliar
j: INT := 0 ; // variable auxiliar
aux00 : INT := 0; // variable axiliar
aux01 : INT := 0; // variable axiliar
aux02 : INT := 0; // variable axiliar
aux03 : INT := 0; // variable axiliar
aux04 : INT := 0; // variable axiliar
aux05 : INT := 0; // variable axiliar
aux06 : INT := 0; // variable axiliar
aux07 : INT := 0; // variable axiliar
aux08 : INT := 0; // variable axiliar
aux09 : INT := 0; // variable axiliar
aux10 : INT := 0; // variable axiliar
END_VAR
VAR_TEMP
END_VAR
BEGIN
IF (Salida[0] = 0) AND (Salida[1] = 0) AND (Salida[2] = 0) AND (Salida[3] = 0) AND (Salida[4] = 0) AND (Salida[5] = 0) AND (Salida[6] = 0) AND (Salida[7] = 0) THEN
aux05 := 1;
ELSE
aux05 := 0;
END_IF;
IF (RESET = 1) AND (aux05 = 1) THEN
aux02 := 0;
END_IF;
IF (Ordenar = 1) AND (aux02 = 0) AND (aux05 = 1) THEN
//RECOGER DATOS.
HORAS_TRABAJO_MOTOR[0] := WORD_TO_INT (MI_DB.DW[0]);
HORAS_TRABAJO_MOTOR[1] := WORD_TO_INT (MI_DB.DW[2]);
HORAS_TRABAJO_MOTOR[2] := WORD_TO_INT (MI_DB.DW[4]);
HORAS_TRABAJO_MOTOR[3] := WORD_TO_INT (MI_DB.DW[6]);
HORAS_TRABAJO_MOTOR[4] := WORD_TO_INT (MI_DB.DW[8]);
HORAS_TRABAJO_MOTOR[5] := WORD_TO_INT (MI_DB.DW[10]);
HORAS_TRABAJO_MOTOR[6] := WORD_TO_INT (MI_DB.DW[12]);
HORAS_TRABAJO_MOTOR[7] := WORD_TO_INT (MI_DB.DW[14]);
//COLOCARLOS EN LA VARIABLE QUE AUXILIAR PARA DESPUES ORDENARLOS
FOR i:=0 TO 7 DO
HORAS_TRABAJO_MOTOR_ORD[i] := HORAS_TRABAJO_MOTOR[i];
END_FOR;
//ORDENAR DATOS
FOR i:=0 TO 7 DO
FOR j:=i+1 TO 7 DO
IF HORAS_TRABAJO_MOTOR_ORD[j] < HORAS_TRABAJO_MOTOR_ORD[i] THEN
aux01 := HORAS_TRABAJO_MOTOR_ORD[j];
HORAS_TRABAJO_MOTOR_ORD[j]:=HORAS_TRABAJO_MOTOR_ORD[i];
HORAS_TRABAJO_MOTOR_ORD[i]:=aux01;
END_IF;
END_FOR;
// ORDENACION CONCLUIDA
END_FOR;
// ORDENACION CONCLUIDA
aux02:=1;
END_IF;
Apartir de aqui es donde tengo problemas.
5.) si recivo la entrada 0 busco leo el valor en HORAS_TRABAJO_MOTOR_ORD[0] y busco donde esta en HORAS_TRABAJO_MOTOR[] para conocer la posicion y asi poder saber que salida tengo que activar.
El problema va cuando tengo varios valores repetidos ya que en la que le corresponde lo activa pero abajo como el valor siguiente es igual lo desactivo.
os pongo el codigo que uso y asi podreis verlo mejor.
FOR aux03:=01 TO 8 BY 1 DO
IF (ENTRADA[aux03]=1) THEN
//miro si el siguiente valor en horas es igual
//BUSCO Y activo segmento original
aux06:=0;
FOR aux04:=0 TO 7 DO
IF (aux06=0) AND (HORAS_TRABAJO_MOTOR[aux04] = HORAS_TRABAJO_MOTOR_ORD[aux03]) THEN
Salida[aux04]:=1;
aux06:=1;
END_IF;
END_FOR;
aux06:=0;
ELSE
//BUSCO Y DESACTIVO. segmento original
aux07:=0;
FOR aux04:=0 TO 7 DO
IF (aux07=0) AND (HORAS_TRABAJO_MOTOR[aux04] = HORAS_TRABAJO_MOTOR_ORD[aux03] AND (Salida[aux04]=1)) THEN
Salida[aux04]:=0;
aux07:=1;
END_IF;
END_FOR;
aux07:=0;
END_IF;
END_FOR;
// ESCRIBIR SALIDA QUE CORRESPONDA
Salida00:=Salida[0];
Salida01:=Salida[1];
Salida02:=Salida[2];
Salida03:=Salida[3];
Salida04:=Salida[4];
Salida05:=Salida[5];
Salida06:=Salida[6];
Salida07:=Salida[7];
END_IF;
END_FUNCTION_BLOCK
He intentado diferentes cosas pero no han funcionado.
Por ejemplo una que he pensado es recorrer el array empezando en el valor siguiente de la ultima entrada es decir si la entrada es dos. empiezo a mirar para encontrar el igual apartir de la posicion 3 de HORAS_TRABAJO_MOTOR pero claro llego al 7 y al no dar la vuelta pierdo valores.
He intentado cambiar los valores donde miro una vez mirados y guardales por ejemplo un -1 para que asi abajo ya no lo encuentre y cuando la desactivo desde otro array le guardo otra vez el valor que tendria que tener. Pero tampoco me funciona.
Se que es un tostonazo de post pero he pensado que mejor aqui en uno de c++.Gracias a todos y espero alguna idea.
Saludos.