Table of Contents

Arduino goes TPS

For my Lighthouse model ( that I have sold in the meantime) I needed a circuit that flashes the light every 5 seconds 3x. Since the analog solution is not straightforward, I have dug out an ATTiny24 (I just had one available) from my hardware collection, switched on my AVR studio and just quickly wrote the controller software. A quick solution..

At various model exhibitions, I was asked again and again how to replicate it. Of course you can, if you … And of course, other flash sequences should be selectable. And preferably controlled by remote control, selectable including other lamps … I am surprised that among the model DIYlers the MCU knowledge is rather scarce. That's a pity.

I recently came across Burkhard Kainka’s TPS (http://www.elektronik-labor.de/Lernpakete/TPS/TPS0.html). This was just the right solution for many needs in model making. It is easy to program. Actually reduced to the bare minimum. The only thing the TPS lacks is the connection to a remote control. And also, the possibility to control one (or 2) servos the TPS does not have. Not yet, I thought to myself.

And so I started: Since I am very familiar with the Atmel processor range and also have a lot of experience with the Arduino system, it was only a small step to move the TPS functionality on to the Arduino. In addition, the Arduino is very widespread.

At first, I thought I could easily adapt the existing TPS variant written in BASCOM, but unfortunately that was not so easy. So, I've reprogrammed the entire controller functionality from scatch and also added a few command extensions for the model design people. Here I present the resulting version free of charge and for general use. If you find a bug / mistake, then just write an email, so I can correct it. I have not been able to test all possible paths yet and will try to remove the bugs as soon as possible.

And something more regarding this Arduino implementation. It can run on 2 different MCU's: On the one hand, on the Arduino itself, then even with the possibility to be programmed directly from my emulator. The 2nd variant is based on an ATtiny84. Unfortunately, this software can then only be programmed using a “standard” ISP programmer. And the TPS commands are then programmed directly as with the HOLTEK version - only via the buttons and LEDs – no PC connection. This possibility exists of course in the Arduino version as well, a good solution if you have to modify something quickly on-site close to the water with your model boats.

Features

In addition to Burkhard’s TPS, this version has the following additional features:

Push value onto stack and Pop from stack – read data and take the value off the stack.

The PWM signals are generated at 500Hz, the servo signals are PPM coded. (50Hz repetition frequency; and the shortest pulse is 1ms long, the longest pulse 2ms, middle position is at 1,5ms.) With the arduino variant you are able to produce some sound. The output is shared with the PWM 2 output. For selecting the pitch, you have to set the A register to a value between 36 (low C2) and 109 (C8) as in the midi specification.

Programming the Arduino_TPS is the same as the TPS variants. (But see the enhanced programming modes, too)

New since 0.10 is the serial programming mode, where you can upload a program via a serial connection. For this the INtelHEX format is used for uploading. You can generate this format by using my SPS Assembler.

Limitations

A mixed operation of servo and PWM (for example, PWM.1 and Servo.2) is unfortunately not possible because the two influence each other. So, either servo output or PWM output. The sound output is also affected by this, since the sound is on the Servo 2 (PWM 2) output.

Hardware connections

Here you find the input and output connections for the TPS and their equivalents on the arduino board:

TPS Connection Arduino Pins
Din1..4 D0..D3
Dout1..4 D4..D7
PWM1,2 D9,10
ADC1,2 A1,2
SW_PRG D8
SW_SEL D11

the additional inputs and outputs for the TPS variant:

TPS Connection Arduino Pins
RC1,2 D18, D19 (A4, A5)
Servo1,2 D9, D10
Tone D10

Just a little image:

Instruction Set

The areas shaded in yellow are the extensions of my Arduino_TPS and ATTiny84 version. In squared bracket you will find the mnemonic for the SPS assembler.

  0 1 2 3 4 5 6 7
  n.n. Port
[DOUT]
Delay
[WAIT]
Jump back relative
[RJMP]
A=#
[LDA]
=A A= A=Ausdruck
0 NOP [NOP] aus 1ms 0 0 A<->B [SWAP]    
1   1 2ms 1 1 B=A [MOV] A=B [MOV] A=A + 1 [INC]
2   2 5ms 2 2 C=A [MOV] A=C [MOV] A=A - 1 [DEC]
3   3 10ms 3 3 D=A [MOV] A=D [MOV] A=A + B [ADD]
4   4 20ms 4 4 Dout=A [STA] Din [LDA] A=A - B [SUB]
5   5 50ms 5 5 Dout.1=A.1 [STA] Din.1 [LDA] A=A * B [MUL]
6   6 100ms 6 6 Dout.2=A.1 [STA] Din.2 [LDA] A=A / B [DIV]
7   7 200ms 7 7 Dout.3=A.1 [STA] Din.3 [LDA] A=A and B [AND]
8   8 500ms 8 8 Dout.4=A.1 [STA] Din.4 [LDA] A=A or B [OR]
9   9 1s 9 9 PWM.1=A [STA] ADC.1 [LDA] A=A xor B [XOR]
a   10 2s 10 10 PWM.2=A [STA] ADC.2 [LDA] A= not A [NOT]
b   11 5s 11 11 Servo.1=A [STA] RCin.1 [LDA] A= A % B (Rest) [MOD]
c   12 10s 12 12 Servo.2=A [STA] RCin.2 [LDA] A= A + 16 * B [BYTE]
d   13 20s 13 13 E=A [MOV] A=E [MOV] A= B - A[BSUBA]
e   14 30s 14 14 F=A [MOV] A=F [MOV]  
f   15 60s 15 15 Push A [PUSH] Pop A [POP]  
Additional Features of the Arduino_TPS version:

  8 9 a b c d e f
  Page [PAGE] Jump absolut (#+16*page)
[JMP]
C* C>0: C=C-1;
Jump # + (16*page)
[LOOPC]
D* D>0:D=D-1;
Jump # + (16*page)
[LOOPC]
Skip if Call # + (16*Page)
[Call]
Callsub/Ret Byte Befehle
0 0 0 0 0 A==0 [SKIP0] 0 ret [RTR] A=ADC.1 [BLDA]
1 1 1 1 1 A>B [AGTB] 1 Call 1 [CASB] A=ADC.2 [BLDA]
2 2 2 2 2 A<B [ALTB] 2 2 [CASB] A=RCin.1 [BLDA]
3 3 3 3 3 A==B [AEQB] 3 3 [CASB] A=RCin.2 [BLDA]
4 4 4 4 4 Din.1==1 [DEQ1 1] 4 4 [CASB] PWM.1=A [BSTA]
5 5 5 5 5 Din.2==1 [DEQ1 2] 5 5 [CASB] PWM.2=A [BSTA]
6 6 6 6 6 Din.3==1 [DEQ1 3] 6 6 [CASB] Servo.1=A [BSTA]
7 7 7 7 7 Din.4==1 [DEQ1 4] 7   Servo.2=A [BSTA]
8 8 8 8 8 Din.1==0 [DEQ0 1] 8 Def 1 [DFSB] Tone=A [TONE]
9 9 9 9 9 Din.2==0 [DEQ0 2] 9 2 [DFSB]  
a 10 10 10 10 Din.3==0 [DEQ0 3] 10 3 [DFSB]  
b 11 11 11 11 Din.4==0 [DEQ0 4] 11 4 [DFSB]  
c 12 12 12 12 S_PRG==0 [PRG0] 12 5 [DFSB]  
d 13 13 13 13 S_SEL==0 [SEL0] 13 6 [DFSB] int. LED on
e 14 14 14 14 S_PRG==1 [PRG1] 14   int. LED off
f 15 15 15 15 S_SEL==1 [SEL1] 15 restart [REST] PrgEnd [PEND]
Aditional Features in this Arduino_TPS version:

And now please have fun with the Arduino_TPS.
Oh, and as always: everything without any warranty …
And here the picture of a small test setup:

InField programming

One of the most used features of the TPS is the possibility to program the unit only with the 3 buttons and the 4 LEDs. So you don't need any other programming hard- or software. A printed command chard or one on your mobil phone would be very helpful.
Please be aware the external hardware must maybe unconnected before programming, because of some unpredictable results.
Four me, the original programming mode was a bit to clumsy, so i decide to reprogram it. The new one has a nicer interface, as you now always know where you are.
The process for every programming step is always the same and has 3 steps.

  1. showing the actual address
  2. programming the command (uppper nibble of the command/data value, this is the column of the programming table.)
  3. programming the data (lower nibble of the command/data value, which is the row of the table)

The programming starts always at address 0, for programming always the PRG button and for selecting value always the SEL button is used. As in the original programming sequenz, you can step thru the program using only the PRG button.

Starting the programming with keeping PRG pushed after Reset. As a result, all LEDs will shortly blink now, indicating that you are in Programming Mode. Please release now the PRG Button. Than the programming loop will start.

If you are ready with programming or you want to cancel the programming simply press the reset button.

Start programming, press RESET and PRG, than release RESET. hold PRG until all LEDs light up.

LEDs Comment next Step
1111 wait until PRG is released release PRG
*0001 indicator for low nibble of address do nothing, delay of 1/4 second
xxxx low nibble of address, if address is 0x00 than nothing is shown do nothing, delay of 1/2 second
0010 indicator for high nibble of address do nothing, delay of 1/4 second
xxxx high nibble of address, if address is 0x00 than nothing is shown do nothing, delay of 1/2 second
0100 indicator for command do nothing, delay of 1/4 second
xxxx showing the actual command with SEL you can change the value of the command (column in programming table), with PRG you go to the next step
1000 indicator for data do nothing, delay of 1/4 second
xxxx showing the actual data with SEL you can change the value of the data (row in programming table), with PRG you save the actual value of command (all LEDs will blink once) and data into the memory, and go to the next address (goto *)

Download

here you can download the actual released version of the Arduino_TPS: | last Release als ZIP

The sourc codes of this is hosted on github: Arduino_TPS Source

Earlier versions are available on my Gogs server Arduino SPS Source