Ajuda para melhorar o meu código - Detecção de locomotivas sensores Hall Effect

Boas,

Com os meus limitados conhecimentos "bati numa parede" e preciso da vossa ajuda para avançar.

O código que vos trago faz tudo o que era inicialmente previsto. A ideia é implementar um sistema de localização de modelos de comboios e activar a sinalização e outros dispositivos como passagens de nível, etc...
Para já identifica o sensor que foi activado, liga e desliga as luzes em conformidade, identifica a direcção e faz o "loop" do último sensor para o primeiro e vice versa.
Tudo funciona correctamente com uma única locomotiva.

Mas isto era o que era pretendido... Depois de começar queremos sempre mais :slight_smile: e foi aqui que bati contra uma parede e não sei como avançar.

Precisava de dicas de como alterar o que está feito mas para mais que uma locomotiva em simultâneo.

A única solução que tenho (se é que se pode chamar solução é a seguinte. Como os comboios não saltam do 1º para o 5º sensor sem passar pelos 2, 3 e 4, pensei em avaliar se o segundo sensor que fosse activado estivesse fora do trajecto esperado então criar um segundo processo... Mas passar esta ideia para código tem-se revelado, no mínimo, difícil.

O código está dividido em 2 tabs. O primeiro tem as definições e a lógica pretendida.

/* Model Railroad - Hall Effect Position Sensores

  Identifica a posição e direcção de uma locomotiva e activa as luzes de aviso.
  Limitada a uma locomotiva

  Este Sketch detecta, através de sensores Hall Effect, a passagem de um comboio por um
  determinado ponto na linha e de seguida executa uma série de tarefas.

  Quando a locomotiva, com um íman colado no fundo, activa um sensor, o sketch
  faz o seguinte:

  - Identifica o sensor que foi activado;
  - Sabe qual a direcção que o comboio leva;
  - Liga os leds vermelhos e desliga os verdes, correspondentes aos blocos que estão em utilização
  - Liga os leds verdes e desliga os vermelhos, correspondentes aos blocos que deixaram de estar em utilização

  O pin 3 dos sensores está ligado ao arduino aos pins 14 a 18

  Esta versão só está a trabalhar com 5 sensores mas o procedimento é o mesmo até que se esgotem os pins disponiveis do arduino
*/

#define n_sensor 5 //Insira aqui o úmero de sensores com que vai operar no layout

int HallPin [n_sensor] = {18, 17, 16, 15, 14};     //Definir a que pinos estão ligados os sensores
int LedGreen [n_sensor] = {4, 5, 6, 7, 8};        //Definir a que pinos estão ligados os leds verdes
int LedRed [n_sensor] = {9, 10, 11, 12, 13};      //Definir a que pinos estão ligados os leds verdes

int i;

int HallPinStatus [n_sensor];                     //Variável que conterá o estado de cada um dos sensores após cada ciclo
int HallId[n_sensor];           //Identificação dos sensores para leitura "Humana"

int Position = 0;       //Variável que conterá o numero dos sensores que foram activados
int LastPosition = 0;   //Variável que conterá o numero dos sensores que foram activados anteriormente

int Direction = 0;      //Indica qual a direcção. Sentido ascendente (2) Sentido descendente (1)


void setup() {

  //Abrir a porta série
  Serial.begin(115200);

  //Definir pins e ligar leds verdes
  for (i = 0; i < n_sensor; i++) {
    pinMode (HallPin[i], INPUT);          // Definir os PINs dos sensores (14 a 18)
    pinMode (LedGreen[i], OUTPUT);        // Definir os PINs dos leds verdes (4 a 8)
    pinMode (LedRed[i], OUTPUT);          // Definir os PINs dos leds vermelhos (9 a 13)

    digitalWrite (LedGreen[i], HIGH);     // ligar os leds verdes - No arranque liga todos os LEDS em modo de linha livre até ao primeiro contacto com um sensor.
  }

  // Popular a variável com os numeros correctos
  for (i = 0; i < n_sensor; i++) {
    HallId[i] = i + 1;
  }
}


  void loop() {

    // Ler o estado dos sensores
    for (i = 0; i < n_sensor; i++) {
      HallPinStatus [i] = digitalRead(HallPin[i]);
      //SensorStatus(); //Se quiser visualizar o estado dos sensores em todos os ciclos apague "//" no inicio desta linha
    }

    //Determinar qual o sensor que foi activado e executar a respectiva função.
    for (i = 0; i < n_sensor; i++) {
      if (HallPinStatus[i] == LOW) {
        SensorExecute();
        Position = i + 1;
      }
    }

    //Estabelecer a direcção seguida
    if (Position < LastPosition) {
      Direction = 1;
    }
    else if (Position > LastPosition) {
      Direction = 2;
    }
    else {
      Direction = 0;
    }


    //Estabelecer e manter a ultima posição conhecida
    if (Position != LastPosition) {

      //Chamar a função que envia para o serial monitor o status das variáveis
      //O estado das variáveis. Só são enviados para o serial monitor quando existe uma alteração de posição
      DisplayStatus();

      //Redefinir as variáveis em função das novas alterações
      LastPosition = Position;

    }

    //Chamar a função que envia para o serial monitor o status das variáveis
    //StatusDisplay(); //Se quiser visualizar todos os ciclos no serial monitor apague "//" antes da função StatusDisplay

  }

e o segundo tab contem as funções. Criei este segundo para limpar um pouco o principal porque já estava a ficar perdido.

/* Model Railroad - Hall Effect Position Sensores

    Definição de funções especificas deste sketch
      - DisplayStatus() Função que envia para o serial monitor a situação das variáveis
      - SensorStatus() Função que envia para o serial monitor a condição dos sensores
      - SensorExecute() Função que executa as tarefas de cada um dos sensores

*/


// Função que envia para o serial monitor a situação das variáveis
void DisplayStatus() {


  Serial.println("");

  Serial.print(" - Actual Position: ");
  Serial.print(Position);

  Serial.print(" - Last Position: ");
  Serial.print(LastPosition);

  Serial.print(" - Direction: ");
  Serial.print(Direction);

  Serial.println("");
  Serial.println("");

}

//Função que envia para o serial monitor a condição dos sensores
void SensorStatus()
{
  Serial.print(" - Sensor ");
  Serial.print(HallId[i]);
  Serial.print(": ");
  Serial.println(HallPinStatus[i]);
}

//Função que executa as tarefas de cada um dos sensores
void SensorExecute()
{
  if (Position > 1 && Position <= n_sensor - 2) {
    //Desliga os LEDs verdes no bloco que foi accionado bem como do bloco seguinte

    digitalWrite(LedGreen[Position - 2], HIGH);
    digitalWrite(LedRed[Position - 2], LOW);

    digitalWrite(LedGreen[Position - 1], LOW);
    digitalWrite(LedRed[Position - 1], HIGH);

    digitalWrite(LedGreen[Position], LOW);
    digitalWrite(LedRed[Position], HIGH);

    digitalWrite(LedGreen[Position + 1], HIGH);
    digitalWrite(LedRed[Position + 1], LOW);



  }

  else if (Position == 1) {

    digitalWrite(LedGreen[n_sensor - 1], HIGH);
    digitalWrite(LedRed[n_sensor - 1], LOW);

    digitalWrite(LedGreen[Position - 1], LOW);
    digitalWrite(LedRed[Position - 1], HIGH);

    digitalWrite(LedGreen[Position], LOW);
    digitalWrite(LedRed[Position], HIGH);

    digitalWrite(LedGreen[Position + 1], HIGH);
    digitalWrite(LedRed[Position + 1], LOW);

  }

  else if (Position == n_sensor - 1 ) {

    digitalWrite(LedGreen[Position - 2], HIGH);
    digitalWrite(LedRed[Position - 2], LOW);

    digitalWrite(LedGreen[Position - 1], LOW);
    digitalWrite(LedRed[Position - 1], HIGH);

    digitalWrite(LedGreen[Position], LOW);
    digitalWrite(LedRed[Position], HIGH);

    digitalWrite(LedGreen[Position - n_sensor + 1], HIGH);
    digitalWrite(LedRed[Position - n_sensor + 1], LOW);

  }

  else if (Position == n_sensor ) {

    digitalWrite(LedGreen[Position - 2], HIGH);
    digitalWrite(LedRed[Position - 2], LOW);

    digitalWrite(LedGreen[Position - 1], LOW);
    digitalWrite(LedRed[Position - 1], HIGH);

    digitalWrite(LedGreen[Position], LOW);
    digitalWrite(LedRed[Position], HIGH);

    digitalWrite(LedGreen[Position - n_sensor ], LOW);
    digitalWrite(LedRed[Position - n_sensor ], HIGH);

    digitalWrite(LedGreen[Position - n_sensor + 1 ], HIGH);
    digitalWrite(LedRed[Position - n_sensor + 1 ], LOW);


  }

}

Qualquer ajuda é mais que bem vinda

Obrigado

Miguel

Coloca isto no post anterior... ainda estás a trabalhar no mesmo projecto e não faz sentido espalhar as dúvidas.