Menu

LEGO Train Sensor Solution

Anobium
2 days ago
2 days ago
  • Anobium

    Anobium - 2 days ago

    Multiple Hall Switch Monitor for GCBASIC

    Overview

    This is a Multiple Hall Switch Monitor for the train track teaching solution I am building. This can support 14 hall sensors. I am using seven at the moment. The map below shows the placement of the hall sensors. The logic for the placement will become obvious when I post more later.


    Main Train Track Map

                    -------------------------------------------O-----------------------------------   
                =                                                                                    = 
              =                                                                                         = 
            =                                                                                             = 
          =                                                                                                 = 
         =                                                                                                   = 
        =                                                                                                     = 
       =                                                                                                       = 
      =                                                                                                        = 
      =                                                                                                        = 
      =                                                                                                        = 
       =                                                                                                       = 
       O                                                                                                       O 
        =                                                                                                     = 
         =                        ----O--------------------------------------O------                        = 
          =                     =                                                      =                    = 
            =                 =                                                         =                 = 
               =            =                                                             =             = 
                  --------------O-----------------------------------------------------O---------------   
    

    Legend

    • = : Parallel track lines (main rail path)
    • - : Horizontal rail Parallel track lines
    • O : Sensors
    • Blank spaces: Open areas or spacing for layout clarity

    Overview

    This program monitors hall effect switches connected to an LGT8F328P microcontroller. It uses pin change interrupts with simple debounce logic to detect state changes and report them over UART.

    • Channels 0–5: A0–A5 (PC0–PC5) via PCINT1
    • Channel 6: D2 (PD2) via PCINT2
    • Channel 7: D3 (PD3) via PCINT2
    • Active‑low inputs with internal pull‑ups enabled
    • Interrupt‑driven with 10ms debounce inside ISRs
    • Sends packets: 0xFF + channel (0–7) + state twice for redundancy
    • Startup message + initial states sent automatically
    • LED on PB5 (digital pin 13) pulses for 10ms on any change

    Target: LGT8F328P @ 32 MHz
    Compiler: GCBASIC


    UART Configuration

    #DEFINE USART_BAUD_RATE 9600
    #DEFINE USART_TX_BLOCKING
    #DEFINE USART_DELAY 10 us
    

    Chip and Compiler Settings

    #chip LGT8F328P, 32
    #option Explicit
    

    Pin Constants

    #define LED_PIN PORTB.5
    

    Variables

    Dim OldHallState As Byte
    Dim ChangeFlags As Byte
    Dim channel As Byte
    Dim mask As Byte
    Dim state As Byte
    

    Subroutine: SendPacket

    Sub SendPacket(pSensor As Byte, pState As Byte)
        HserSend 255
        HserSend pSensor
        HserSend pState
        HserSend 255
        HserSend pSensor
        HserSend pState
    End Sub
    

    Subroutine: InitPins

    Sub InitPins
        Dir PORTC In
        PORTC = 0B00111111      ' Pull-ups on PC0-PC5 only
    
        Dir PD2 In
        Dir PD3 In
        PORTD.2 = 1
        PORTD.3 = 1
    
        Dir LED_PIN Out
        Set LED_PIN Off
    
        OldHallState = PINC And 0B00111111
        If PIND.2 = 1 Then OldHallState = OldHallState Or 0B01000000
        If PIND.3 = 1 Then OldHallState = OldHallState Or 0B10000000
    
        For channel = 0 To 7
            mask = FnLSL(1, channel)
            Dim pin_low As Bit
            If channel < 6 Then
                pin_low = ((PINC And mask) = 0)
            Else If channel = 6 Then
                pin_low = (PIND.2 = 0)
            Else
                pin_low = (PIND.3 = 0)
            End If
            state = 0
            If pin_low = 1 Then state = 1
            SendPacket channel, state
        Next
    End Sub
    

    Interrupt Service Routines

    ISR for PORTC (Channels 0–5)

    Sub ISR_PortC
        Wait 10 ms
        Dim current As Byte
        current = PINC And 0B00111111
        Dim changed As Byte
        changed = current Xor (OldHallState And 0B00111111)
        If changed <> 0 Then
            ChangeFlags = ChangeFlags Or changed
            OldHallState = (OldHallState And 0B11000000) Or current
        End If
    End Sub
    

    ISR for PORTD (Channels 6–7)

    Sub ISR_PortD
        Wait 10 ms
        Dim current_mapped As Byte
        current_mapped = 0
        If PIND.2 = 1 Then current_mapped = current_mapped Or 0B01000000
        If PIND.3 = 1 Then current_mapped = current_mapped Or 0B10000000
        Dim changed As Byte
        changed = current_mapped Xor (OldHallState And 0B11000000)
        If changed <> 0 Then
            ChangeFlags = ChangeFlags Or changed
            OldHallState = (OldHallState And 0B00111111) Or current_mapped
        End If
    End Sub
    

    Main Program

    InitPins
    
    PCICR.1 = 1
    PCMSK1 = 0B00111111
    
    PCICR.2 = 1
    PCMSK2 = 0B00001100   ' PD2 and PD3
    
    On Interrupt PinChange1 Call ISR_PortC
    On Interrupt PinChange2 Call ISR_PortD
    
    INTON
    
    Do
        If ChangeFlags <> 0 Then
            For channel = 0 To 7
                mask = FnLSL(1, channel)
                If (ChangeFlags And mask) <> 0 Then
                    Dim pin_low As Bit
                    If channel < 6 Then
                        pin_low = ((PINC And mask) = 0)
                    Else If channel = 6 Then
                        pin_low = (PIND.2 = 0)
                    Else
                        pin_low = (PIND.3 = 0)
                    End If
                    state = 0
                    If pin_low = 1 Then state = 1
                    SendPacket channel, state
                    ChangeFlags = ChangeFlags And Not mask
                End If
            Next
            PulseOut LED_PIN, 10 ms
        End If
    Loop
    
    End
    
     
    👍
    1
  • Anobium

    Anobium - 2 days ago

    Below is the PC application shows the real time sensor state: the sensors show the position of the train as it passes over the sensor. The position controls points and other functional parts of the overall solution.

    There are other track sections but the are not monitored.

     

    Last edit: Anobium 2 days ago

Log in to post a comment.