The world's easiest controls
programming language

We believe SPLat’s programming language is the easiest in the world for embedded OEM control applications. SPLat’s language was originally devised, and has evolved over time, with embedded machine control as its main driver.

The example below shows off just a few of the language features that make SPLat so easy for control programming. Compared to C, Basic and other general purpose computer languages, SPLat focusses on those language elements that are important for programing controls, which is very different to general computing. SPLat lets you express the concepts of logic, sequence and time quickly and easily. Compared to ladder, SPLat lets you tell the controller what to do, rather than what to be (in ladder you emulate a circuit made up of relays, timers etc, so in reality you are designing a circuit that will solve the problem rather than simply solving the problem directly).

… You compare, you decide!

In the two side-by-side windows below you can compare the same program written in several languages that are used for programming controls. Just click on the language names to select.

What the program doesIs this comparison honest?What about my favourite language?

Click a key word below to show the code

Start:
    
LaunchTask      FirstIn
    LaunchTask      PushOnPushOff
    LaunchTask      LongShort
    RunTasksForever

** First button pressed (Sale of the Century) **
FirstIn:
    YieldTask
    GoIfInOn 4,      FirstIn_Got_4
    
    GoIfInOn        7, FirstIn_Got_7
    GoTo            FirstIn

FirstIn_Got_4:
    On            4
    Pause           100
    
Off            4
    GoTo            FirstIn_WaitBothOff

FirstIn_Got_7:
    On              7
    Pause           100
    Off             7

FirstIn_WaitBothOff:
    WaitOff        4
    GoIfInOn        7, FirstIn_WaitBothOff
    GoTo            FirstIn

** Push ON/Push OFF button **
PushOnPushOff:
    WaitOnK           5
    On              5
    WaitOnK         5
    Off             5
    GoTo            PushOnPushOff

** Short pulse = ON, Long pulse = OFF **
LongShort:
    WaitOnK         6
    WaitOffT        6,100
    GoIfT           LongShort_1
    Off             6
    GoTo            LongShort

LongShort_1:
    On              6
    GoTo            LongShort
//SPLatOS C
void main(void)
{
   SPLAT_vInitialise();
   THREAD_vIgnite();
   mFOREVER
   {
   }
}

//** First button pressed (Sale of the Century) **
void APP_vMsgGameShow( APPtbMSG bMsg, uint8 bData )
{
   switch( bMsg )
   {
   case APPkeMSG_Timer_GameShowLight:
      DIGITAL_vClrLed1();
      DIGITAL_vClrLed4();
      break;

   default:
      if( !TIMER_oIsRunning( APPkeMSG_Timer_GameShowLight ) && bData == DIGITALkeS_Pressed )
      {
         DIGITAL_vWrite( bMsg == APPkeMSG_IP_BtnLeft ? DIGITALkeOP_Led1 : DIGITALkeOP_Led4, TRUE );
         TIMER_vStart( APPkeMSG_Timer_GameShowLight, 1000, FALSE );
      }
      break;
   }
}

//** Push ON/ Push OFF button **
void APP_vMsgPushy( APPtbMSG bMsg, uint8 bData )
{
   if( bData == DIGITALkeS_Pressed )
      DIGITAL_vToggle( DIGITALkeOP_Led2 );
}

//** Short pulse = ON, Long pulse = OFF **
void APP_vMsgShorty( APPtbMSG bMsg, uint8 bData )
{
   if( bData == DIGITALkeS_Released )
      DIGITAL_vSetLed3();

   else if( bData == DIGITALkeS_Held )
      DIGITAL_vClrLed3();
}

Statement list.
* First button pressed (Sale of the Century) *
LD      0004
ANB     0507
LD      0504
AND     1004
ORL
OUT     0504
LD      0007
ANB     0504
LD      0507
AND     1004
ORL
OUT     0507
LD      0004
OR      0007
LD      1004
ANB     T002
ORL
OUT     1004
LD      0504
OR      0507
TMR     002    #00040
LDB     T002
AND     0507
OUT     1010
LDB     T002
AND     0504
OUT     1009

;****** Push on/ Push off function ***
LD      0005
ANB     1006
AND     0512
OUT     1005
LD      0005
ANB     1006
OR      0512
ANB     1005
OUT     0512
LD      0005
OUT     1006
LD      0512
OUT     0505

;** Short pulse = ON, Long pulse = OFF **
LDB     0000
ANB     1008
AND     1001
OUT     1007
LDB     0000
OUT     1008
LD      0000
OUT     1001
LD      1007
ANB     T000
SET     1003
LD      1007
AND     T000
RES     1003
LD      0000
TMR     000    #00030
LD      1003
OUT     0500
END
ENDH
//Dynamic C™
main()
{
   char SwitchStateA;
   char SwitchStateB;
   char LastStateA;
   char LastStateB;
   char LampState;
   char Running;
   char Changed;
   char FlashCount;

   char LastStateSL;
   char SwitchStateSL;
   char LampStateSL;
   unsigned long LastPressSL;
   unsigned long DiffSL;

   char LastStateT;
   char SwitchStateT;
   char LampStateT;

   brdInit();

   LastStateA=1;
   LastStateB=1;
   Running=0;

   LastStateSL=1;
   LampStateSL=0;

   LastStateT=1;
   LampStateT=0;

   while(1)
   {
   ////////////////Sale of the Century
   costate
   {
      SwitchStateA=digIn(1);
      SwitchStateB=digIn(2);
      if( Running==0 )
      {
         Changed=0;
         if( SwitchStateA==0 && SwitchStateA!=LastStateA && SwitchStateB==1 )
         {
            Running=1;
            Changed=1;
         }

         if( SwitchStateB==0 && SwitchStateB!=LastStateB && SwitchStateA==1 )
         {
            Running=2;
            Changed=1;
         }

         if( Changed==1 )
         {
            LampState=1;
            FlashCount=0;
            digOut( Running,1 );
         }
      }
      LastStateA=SwitchStateA;
      LastStateB=SwitchStateB;
   }

   costate
   {
      waitfor(DelayMs(500));
      if( Running > 0 )
      {
         if( FlashCount++ < 4 )
         {
            LampState=LampState==0 ? 1 : 0;
            digOut(Running,LampState );
         }
         else
         {
            digOut(Running,0);
            Running=0;
         }
      }
   }

   /////////////Push ON-Push OFF button
   costate
   {
      SwitchStateT=digIn(3);
      if( SwitchStateT==0 && SwitchStateT!=LastStateT )
      {
         LampStateT=LampStateT==1 ? 0 : 1;
         digOut( 3, LampStateT );
      }
      LastStateT=SwitchStateT;
   }

   /////////// Short pulse = ON, Long pulse = OFF
   costate
   {
      SwitchStateSL=digIn(0);
      if( SwitchStateSL!=LastStateSL )
      {
         if( SwitchStateSL==0 )
            LastPressSL=MS_TIMER;
         else
         {
            DiffSL=labs( MS_TIMER-LastPressSL );
            if( DiffSL >= 1000 )
               LampStateSL=0;
            else
               LampStateSL=1;
            digOut(0,LampStateSL);
         }
      }
      LastStateSL=SwitchStateSL;
   }

}
Trio Basic™
*** Prog Sale_Century: Run on Process 0
WHILE 1=1
   WAIT UNTIL IN(8,9)=0
   WAIT UNTIL IN(8,9)<>0

   IF IN(8,9)=1 THEN
      GOSUB set_10
   ELSEIF IN(8,9)=2 THEN
      GOSUB set_11
   ENDIF
WEND

set_10:
   OP(10,1):WA(1000):OP(10,0)
RETURN

set_11:
   OP(11,1):WA(1000):OP(11,0)
RETURN

**** Prog Push_on_off: Run on Process 1
WHILE 1=1
   IF IN(12,13)=1 AND allow_switch=1 THEN
      OP(13,1)
      allow_switch=0
   ENDIF

   IF IN(12,13)=3 AND allow_switch=1 THEN
      OP(13,0)
      allow_switch=0
   ENDIF

   IF IN(12)=0 THEN allow_switch=1
WEND

*** Prog Pulse_control: Run on Process 2
timing=0
WHILE 1=1
   IF IN(14)=ON AND timing=0 THEN GOSUB start_timing
   IF IN(14)=OFF AND timing=1 THEN GOSUB output_decision
WEND

start_timing:
   t2=TICKS
   timing=1
RETURN

output_decision:
   IF t2-TICKS<=500 THEN OP(15,1)
   IF t2-TICKS>500 THEN OP(15,0)
   timing=0
RETURN

Click a key word below to show the code

Start:
    
LaunchTask      FirstIn
    LaunchTask      PushOnPushOff
    LaunchTask      LongShort
    RunTasksForever

** First button pressed (Sale of the Century) **
FirstIn:
    YieldTask
    GoIfInOn 4,      FirstIn_Got_4
    
    GoIfInOn        7, FirstIn_Got_7
    GoTo            FirstIn

FirstIn_Got_4:
    On            4
    Pause           100
    
Off            4
    GoTo            FirstIn_WaitBothOff

FirstIn_Got_7:
    On              7
    Pause           100
    Off             7

FirstIn_WaitBothOff:
    WaitOff        4
    GoIfInOn        7, FirstIn_WaitBothOff
    GoTo            FirstIn

** Push ON/Push OFF button **
PushOnPushOff:
    WaitOnK           5
    On              5
    WaitOnK         5
    Off             5
    GoTo            PushOnPushOff

** Short pulse = ON, Long pulse = OFF **
LongShort:
    WaitOnK         6
    WaitOffT        6,100
    GoIfT           LongShort_1
    Off             6
    GoTo            LongShort

LongShort_1:
    On              6
    GoTo            LongShort
//SPLatOS C
void main(void)
{
   SPLAT_vInitialise();
   THREAD_vIgnite();
   mFOREVER
   {
   }
}

//** First button pressed (Sale of the Century) **
void APP_vMsgGameShow( APPtbMSG bMsg, uint8 bData )
{
   switch( bMsg )
   {
   case APPkeMSG_Timer_GameShowLight:
      DIGITAL_vClrLed1();
      DIGITAL_vClrLed4();
      break;

   default:
      if( !TIMER_oIsRunning( APPkeMSG_Timer_GameShowLight ) && bData == DIGITALkeS_Pressed )
      {
         DIGITAL_vWrite( bMsg == APPkeMSG_IP_BtnLeft ? DIGITALkeOP_Led1 : DIGITALkeOP_Led4, TRUE );
         TIMER_vStart( APPkeMSG_Timer_GameShowLight, 1000, FALSE );
      }
      break;
   }
}

//** Push ON/ Push OFF button **
void APP_vMsgPushy( APPtbMSG bMsg, uint8 bData )
{
   if( bData == DIGITALkeS_Pressed )
      DIGITAL_vToggle( DIGITALkeOP_Led2 );
}

//** Short pulse = ON, Long pulse = OFF **
void APP_vMsgShorty( APPtbMSG bMsg, uint8 bData )
{
   if( bData == DIGITALkeS_Released )
      DIGITAL_vSetLed3();

   else if( bData == DIGITALkeS_Held )
      DIGITAL_vClrLed3();
}

Statement list.
* First button pressed (Sale of the Century) *
LD      0004
ANB     0507
LD      0504
AND     1004
ORL
OUT     0504
LD      0007
ANB     0504
LD      0507
AND     1004
ORL
OUT     0507
LD      0004
OR      0007
LD      1004
ANB     T002
ORL
OUT     1004
LD      0504
OR      0507
TMR     002    #00040
LDB     T002
AND     0507
OUT     1010
LDB     T002
AND     0504
OUT     1009

;****** Push on/ Push off function ***
LD      0005
ANB     1006
AND     0512
OUT     1005
LD      0005
ANB     1006
OR      0512
ANB     1005
OUT     0512
LD      0005
OUT     1006
LD      0512
OUT     0505

;** Short pulse = ON, Long pulse = OFF **
LDB     0000
ANB     1008
AND     1001
OUT     1007
LDB     0000
OUT     1008
LD      0000
OUT     1001
LD      1007
ANB     T000
SET     1003
LD      1007
AND     T000
RES     1003
LD      0000
TMR     000    #00030
LD      1003
OUT     0500
END
ENDH
//Dynamic C™
main()
{
   char SwitchStateA;
   char SwitchStateB;
   char LastStateA;
   char LastStateB;
   char LampState;
   char Running;
   char Changed;
   char FlashCount;

   char LastStateSL;
   char SwitchStateSL;
   char LampStateSL;
   unsigned long LastPressSL;
   unsigned long DiffSL;

   char LastStateT;
   char SwitchStateT;
   char LampStateT;

   brdInit();

   LastStateA=1;
   LastStateB=1;
   Running=0;

   LastStateSL=1;
   LampStateSL=0;

   LastStateT=1;
   LampStateT=0;

   while(1)
   {
   ////////////////Sale of the Century
   costate
   {
      SwitchStateA=digIn(1);
      SwitchStateB=digIn(2);
      if( Running==0 )
      {
         Changed=0;
         if( SwitchStateA==0 && SwitchStateA!=LastStateA && SwitchStateB==1 )
         {
            Running=1;
            Changed=1;
         }

         if( SwitchStateB==0 && SwitchStateB!=LastStateB && SwitchStateA==1 )
         {
            Running=2;
            Changed=1;
         }

         if( Changed==1 )
         {
            LampState=1;
            FlashCount=0;
            digOut( Running,1 );
         }
      }
      LastStateA=SwitchStateA;
      LastStateB=SwitchStateB;
   }

   costate
   {
      waitfor(DelayMs(500));
      if( Running > 0 )
      {
         if( FlashCount++ < 4 )
         {
            LampState=LampState==0 ? 1 : 0;
            digOut(Running,LampState );
         }
         else
         {
            digOut(Running,0);
            Running=0;
         }
      }
   }

   /////////////Push ON-Push OFF button
   costate
   {
      SwitchStateT=digIn(3);
      if( SwitchStateT==0 && SwitchStateT!=LastStateT )
      {
         LampStateT=LampStateT==1 ? 0 : 1;
         digOut( 3, LampStateT );
      }
      LastStateT=SwitchStateT;
   }

   /////////// Short pulse = ON, Long pulse = OFF
   costate
   {
      SwitchStateSL=digIn(0);
      if( SwitchStateSL!=LastStateSL )
      {
         if( SwitchStateSL==0 )
            LastPressSL=MS_TIMER;
         else
         {
            DiffSL=labs( MS_TIMER-LastPressSL );
            if( DiffSL >= 1000 )
               LampStateSL=0;
            else
               LampStateSL=1;
            digOut(0,LampStateSL);
         }
      }
      LastStateSL=SwitchStateSL;
   }

}
Trio Basic™
*** Prog Sale_Century: Run on Process 0
WHILE 1=1
   WAIT UNTIL IN(8,9)=0
   WAIT UNTIL IN(8,9)<>0

   IF IN(8,9)=1 THEN
      GOSUB set_10
   ELSEIF IN(8,9)=2 THEN
      GOSUB set_11
   ENDIF
WEND

set_10:
   OP(10,1):WA(1000):OP(10,0)
RETURN

set_11:
   OP(11,1):WA(1000):OP(11,0)
RETURN

**** Prog Push_on_off: Run on Process 1
WHILE 1=1
   IF IN(12,13)=1 AND allow_switch=1 THEN
      OP(13,1)
      allow_switch=0
   ENDIF

   IF IN(12,13)=3 AND allow_switch=1 THEN
      OP(13,0)
      allow_switch=0
   ENDIF

   IF IN(12)=0 THEN allow_switch=1
WEND

*** Prog Pulse_control: Run on Process 2
timing=0
WHILE 1=1
   IF IN(14)=ON AND timing=0 THEN GOSUB start_timing
   IF IN(14)=OFF AND timing=1 THEN GOSUB output_decision
WEND

start_timing:
   t2=TICKS
   timing=1
RETURN

output_decision:
   IF t2-TICKS<=500 THEN OP(15,1)
   IF t2-TICKS>500 THEN OP(15,0)
   timing=0
RETURN