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 does | Is this comparison honest? | What about my favourite language?
Click a key word below to show the code
-
SPLat
-
SPLatOS C
-
Ladder
-
Statement list
-
Dynamic C
-
Basic
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
-
SPLat
-
SPLatOS C
-
Ladder
-
Statement list
-
Dynamic C
-
Basic
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