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.
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.
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.
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:
The areas highlighted in yellow are the extensions of my ATTiny_TPS and the Arduino_TPS version. The corresponding mnemonics of the SPS assembler are in square brackets.
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] | A=A SHR 1 [SHR] ab V 11 |
|
f | 15 | 60s | 15 | 15 | Push A [PUSH] | Pop A [POP] | A=A SHL 1 [SHL] ab V 11 |
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] |
Additional features in the Arduino_TPS version:
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.
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 *) |
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