Codigo para activacion de menor a mayor. Con repetidos.

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.

Bienvenido al foro Arduino Lurdab.
Yo creo que tu error parte de suponer algo que no corresponde siquiera presentarlo en este foro.
Si lo vas a hacer en Arduino, lo planteas en arduino. Veo las similitudes pero forma parte de las normas del foro restringirse al ambiente arduino y su programación.
Mucha gente no podra siquiera entender lo que planteas mas alla que esta perfectamente claro para mi.
A fin de que surja la solución para Arduino que prometes, te invito a que modifiques el Titulo agregando [OFF TOPIC] por ahora para poder continuar con la idea.
Hasta aca como moderador.

Ahora va mi respuesta.
Porque solo llevas horas? Porque no llevas minutos tmb y asi la posiblidad de que dos motores lleven igual cantidad de minutos será menor. Eso restringiría tus problemas pero si se diera el caso de dos motores con igual cantidad de minutos repetirías el problema.
Entonces agregas a segundos y bue... si se cumple que ambos tienen misma cantidad ya te ganaste la loteria.

Se me ocurre llevar una segunda tabla ademas de las horas, min o segundos sea el contador que decidas llevar en la que si se diera el caso de dos motores o mas con tiempos iguales, estableces una secuencia de uso que no se repita. Algo como una lista de prioridad que va cambiando cuando tomas la decisión de accionar tal motor.

supongamos que decides usar minutos y tres motores fortuitamente tienen 23456 minutos al momento de que esten todos parados.
Bueno, he aqui tu dilema. Como decides pues, simple, arranca el 1ro pero entonces lo pones en una prioridad mas baja para la siguiente decisión de manera que si se produce otra situación en al que este motor este igualado con otro, simplemente no será el primero en ser accionado, sino el último.

A ver que te parece mis sugerencias.

Primero disculparme, tenia una cuenta antigua y al no poder usarla por fallo en las contraseñas he creado esta, Por eso no me presente. Lo siento. Apartir de aqui ya no vuelvo a cometer este fallo.

Respecto al sistema, mi problema de hacerlo con prioridad esque no se muy bien como plantearlo.

Cuando busco el valor supongamos que:

Desordenado es estos 2 3 4 5 6 1 2
ya ordenados es esto 1 2 2 3 4 5 6

la entrada 1 activa la salida 6

la entrada 2 activa la salida 0

pero como la entrada 3 que tambien busca un dos esta a "0" y encuentra el dos primero resetea la salida 0

con prioridades no se como implementar el codigo para hacerle que busque el primer dos para la entrada 2 y el segundo 2 para la entrada 3, En otras palabras no se como hacer para diferenciarlos.

Con hora, min y segundos ya lo pense pero justo cuando inicio la instalacion todos tienen 0 h, 0 min, 0seg, por tanto tengo este mismo problema pero en lugar de con dos entras con las 8.

Se que el codigo no esta en arduino pero era necesario para que se viera mi problema y saber si alguien ha implementado este problema en arduino.

surbyte mil gracias, con tus indicaciones y una ducha fria ya se como plantearlo.

añadiendo decimales, para cada numero si no esta respetido sera x.0 si esta respetido sera x.0, x.1,.....

asi ya no tengo repetidos y puedo hacerlo sin problemas.

Mil gracias si esto funciona bien tratare de implementarlo en arduino para que lo tenga todo el mundo.

Desordenado es estos 2.0 3.0 4.0 5.0 6.0 1.0 2.0

ya ordenados es esto 1.0 2.0 2.1 3.0 4.0 5.0 6.0

Saludos