PDA

View Full Version : "Variable already an alias" - is there a way to avoid this?



CuriousOne
- 15th June 2020, 19:55
Say I want to have following code, when on specific condition, either of subroutines will be called.



'1ST DIGIT


DG1:
AX VAR PORTD.3:BX VAR PORTC.4:CX VAR PORTC.1:DX VAR PORTC.2: EX VAR PORTD.0
FX VAR PORTD.2: GX VAR PORTC.5
RETURN


'2ND DIGIT


DG2:
AX VAR PORTD.4: BX VAR PORTD.5:CX VAR PORTA.7: DX VAR PORTA.6
EX VAR PORTC.0:GX VAR PORTC.6: FX VAR PORTC.7
RETURN


(and so on, for 2 more digits)

But it won't compile, giving above mentioned error. I can of course avoid this, by introducing additional variables for each digit, like having AX, AX2, AX3, AX4, but this is just waste of memory, I wanted to do a shortcut, but as it seems, that does not works?

mpgmike
- 16th June 2020, 00:22
Try:
AX CON PORTD.3

HenrikOlsson
- 16th June 2020, 05:51
Variables, aliases and constants are allocated/defined/whatever at compiletime - not runtime. So when the compiler hits the DG2 subroutine it sees you want a variable/alias called AX but it can't do that for you since you allready have a variable/alias with that exact name - and since it's a compile time thing it can't re-define it at runtime.


I can of course avoid this, by introducing additional variables for each digit, like having AX, AX2, AX3, AX4, but this is just waste of memory,
No, not in this case since the names AX, AX2, AX3 etc are just aliases/pointers to already existing registers, namely PORTx.y and so on - so no wase of memory in this particular case.

You can have several aliases pointing to the same address but you can't have one alias pointing to different addresses - how's the compiler gonna know when to use which?

I suppose you could use an array containing the offset from, lets say PortA.0. The first element would be your AX, second element would be AX1 and so on. In each subroutine you then populate that array differently depending on "where" you want AX, AX1 etc to point.

CuriousOne
- 16th June 2020, 06:26
Yes I see.
Even this does not works:

IF X=1 then
Y var PORTA.0
else
Y var PORTA.1

So this is just compiler limitation, right?

For the arrays, can be port name in it?

CuriousOne
- 16th June 2020, 10:08
I have 4 piece of 7 segment led displays connected directly to MCU pins, via 220 ohm resistor, common anode going to Vdd. I wrote a routine, which allows to display any number (X) on any digit (Y). But it is taking about 2.7k of memory, mostly because I can not redefine variables on the fly. So my main goal was to shorten this code somehow.




SMART: 'DECODER ROUTINE
FOR X=0 TO 9
IF X=0 AND Y=1 THEN GOSUB N10 'displays specific digit for specific segment
IF X=1 AND Y=1 THEN GOSUB N11
IF X=2 AND Y=1 THEN GOSUB N12
IF X=3 AND Y=1 THEN GOSUB N13
IF X=4 AND Y=1 THEN GOSUB N14
IF X=5 AND Y=1 THEN GOSUB N15
IF X=6 AND Y=1 THEN GOSUB N16
IF X=7 AND Y=1 THEN GOSUB N17
IF X=8 AND Y=1 THEN GOSUB N18
IF X=9 AND Y=1 THEN GOSUB N19

IF X=0 AND Y=2 THEN GOSUB N20
IF X=1 AND Y=2 THEN GOSUB N21
IF X=2 AND Y=2 THEN GOSUB N22
IF X=3 AND Y=2 THEN GOSUB N23
IF X=4 AND Y=2 THEN GOSUB N24
IF X=5 AND Y=2 THEN GOSUB N25
IF X=6 AND Y=2 THEN GOSUB N26
IF X=7 AND Y=2 THEN GOSUB N27
IF X=8 AND Y=2 THEN GOSUB N28
IF X=9 AND Y=2 THEN GOSUB N29

IF X=0 AND Y=3 THEN GOSUB N30
IF X=1 AND Y=3 THEN GOSUB N31
IF X=2 AND Y=3 THEN GOSUB N32
IF X=3 AND Y=3 THEN GOSUB N33
IF X=4 AND Y=3 THEN GOSUB N34
IF X=5 AND Y=3 THEN GOSUB N35
IF X=6 AND Y=3 THEN GOSUB N36
IF X=7 AND Y=3 THEN GOSUB N37
IF X=8 AND Y=3 THEN GOSUB N38
IF X=9 AND Y=3 THEN GOSUB N39

IF X=0 AND Y=4 THEN GOSUB N40
IF X=1 AND Y=4 THEN GOSUB N41
IF X=2 AND Y=4 THEN GOSUB N42
IF X=3 AND Y=4 THEN GOSUB N43
IF X=4 AND Y=4 THEN GOSUB N44
IF X=5 AND Y=4 THEN GOSUB N45
IF X=6 AND Y=4 THEN GOSUB N46
IF X=7 AND Y=4 THEN GOSUB N47
IF X=8 AND Y=4 THEN GOSUB N48
IF X=9 AND Y=4 THEN GOSUB N49

PAUSE 300
NEXT
Y=Y+1
IF Y>4 THEN Y=1
GOTO SMART

N10: '0 at 1st digit
GOSUB CLAR1
LOW A1: LOW B1: LOW C1: LOW D1: LOW E1: LOW F1 '0
return

N11: '1 AT 1ST DIGIT
GOSUB CLAR1
low b1: low c1 '1
RETURN

N12:
GOSUB CLAR1
low A1: low B1: low g1: low e1: low d1 '2
RETURN

N13:
GOSUB CLAR1
low A1: LOW B1: LOW C1: LOW D1: LOW G1 '3
RETURN

N14:
GOSUB CLAR1
LOW F1: LOW B1: LOW G1: LOW C1 '4
RETURN

N15:
GOSUB CLAR1
LOW A1: LOW F1: LOW G1: LOW C1: LOW D1 '5
RETURN

N16:
GOSUB CLAR1
LOW F1: LOW A1: LOW G1: LOW E1: LOW D1: LOW C1 'C6
RETURN

N17:
GOSUB CLAR1
low A1: low B1: low C1 '7
RETURN

N18:
gosub CLAR1
low A1: low B1: low C1: low f1: low e1: low g1: low d1 '8
RETURN

N19:
gosub CLAR1
low A1: low B1: low C1: low f1: low g1: low d1 '9
RETURN

CLAR1: 'clear 1ST DIGIT
high A1: high B1: high C1: high d1: high e1: high f1: high g1
return

N20: '0 at 1st digit
GOSUB CLAR2
LOW A2: LOW B2: LOW C2: LOW D2: LOW E2: LOW F2 '0
return

N21: '1 AT 1ST DIGIT
GOSUB CLAR2
low b2: low c2 '1
RETURN

N22:
GOSUB CLAR2
low A2: low B2: low g2: low e2: low d2 '2
RETURN

N23:
GOSUB CLAR2
low A2: LOW B2: LOW C2: LOW D2: LOW G2 '3
RETURN

N24:
GOSUB CLAR2
LOW F2: LOW B2: LOW G2: LOW C2 '4
RETURN

N25:
GOSUB CLAR2
LOW A2: LOW F2: LOW G2: LOW C2: LOW D2 '5
RETURN

N26:
GOSUB CLAR2
LOW F2: LOW A2: LOW G2: LOW E2: LOW D2: LOW C2 'C6
RETURN

N27:
GOSUB CLAR2
low A2: low B2: low C2 '7
RETURN

N28:
gosub CLAR2
low A2: low B2: low C2: low f2: low e2: low g2: low d2 '8
RETURN

N29:
gosub CLAR2
low A2: low B2: low C2: low f2: low g2: low d2 '9
RETURN

CLAR2: 'clear 1ST DIGIT
high A2: high B2: high C2: high d2: high e2: high f2: high g2
return

N30: '0 at 1st digit
GOSUB CLAR3
LOW A3: LOW B3: LOW C3: LOW D3: LOW E3: LOW F3 '0
return

N31: '1 AT 1ST DIGIT
GOSUB CLAR3
low b3: low c3 '1
RETURN

N32:
GOSUB CLAR3
low A3: low B3: low g3: low e3: low d3 '2
RETURN

N33:
GOSUB CLAR3
low A3: LOW B3: LOW C3: LOW D3: LOW G3 '3
RETURN

N34:
GOSUB CLAR3
LOW F3: LOW B3: LOW G3: LOW C3 '4
RETURN

N35:
GOSUB CLAR3
LOW A3: LOW F3: LOW G3: LOW C3: LOW D3 '5
RETURN

N36:
GOSUB CLAR3
LOW F3: LOW A3: LOW G3: LOW E3: LOW D3: LOW C3 'C6
RETURN

N37:
GOSUB CLAR3
low A3: low B3: low C3 '7
RETURN

N38:
gosub CLAR3
low A3: low B3: low C3: low f3: low e3: low g3: low d3 '8
RETURN

N39:
gosub CLAR3
low A3: low B3: low C3: low f3: low g3: low d3 '9
RETURN

CLAR3: 'clear 1ST DIGIT
high A3: high B3: high C3: high d3: high e3: high f3: high g3
return

N40: '0 at 1st digit
GOSUB CLAR4
LOW A4: LOW B4: LOW C4: LOW D4: LOW E4: LOW F4 '0
return

N41: '1 AT 1ST DIGIT
GOSUB CLAR4
low b4: low c4 '1
RETURN

N42:
GOSUB CLAR4
low A4: low B4: low g4: low e4: low d4 '2
RETURN

N43:
GOSUB CLAR4
low A4: LOW B4: LOW C4: LOW D4: LOW G4 '3
RETURN

N44:
GOSUB CLAR4
LOW F4: LOW B4: LOW G4: LOW C4 '4
RETURN

N45:
GOSUB CLAR4
LOW A4: LOW F4: LOW G4: LOW C4: LOW D4 '5
RETURN

N46:
GOSUB CLAR4
LOW F4: LOW A4: LOW G4: LOW E4: LOW D4: LOW C4 'C6
RETURN

N47:
GOSUB CLAR4
low A4: low B4: low C4 '7
RETURN

N48:
gosub CLAR4
low A4: low B4: low C4: low F4: low E4: low G4: low D4 '8
RETURN

N49:
gosub CLAR4
low A4: low B4: low C4: low F4: low G4: low D4 '9
RETURN

CLAR4: 'clear 1ST DIGIT
high A4: high B4: high C4: high D4: high E4: high F4: high G4
return

HenrikOlsson
- 16th June 2020, 11:25
Yes I see.
Even this does not works:


IF X=1 then
Y var PORTA.0
else
Y var PORTA.1


You have to understand that the "code" Y VAR PORTA.0 isn't something that is actually being executed on the PIC itself. It's simply a way to inform the compiler that you, in your code, want bit 0 of PortA to be "named" Y. And since it IS something that the compiler handles when it converts your program from PBP into ASM (which is then assembled by the assembler) it can not later be changed by the running program.


So this is just compiler limitation, right?
You can call it a limitation if you like but it's just the way it works.


For the arrays, can be port name in it?
No. But you can do this:

idx VAR BYTE
idx = 9
PortA.0[idx] = 1

Here, idx acts as an offset from PortA.0
If you look at the datasheet for the PIC you'll find that the Port registers are consecutive in the memory map so by counting 9 bits from bit 0 of PortA.0 you'll end up PortB.1.

So with this method you can use an Array to hold your seven offsets and redifine those offsets at will, something like this (untested and uncompiled, treat it accordingly):

X VAR BYTE[7] ' Array to hold the bit offset from PortA.0
idx VAR BYTE ' Temporary variable needed to actually use the indexing

Main:

GOSUB DG1
idx = X[2] ' Since X[2] contains the value 17, so will idx
PortA.0[idx] = 1 ' Write to "PortA.17" which in real life will be PortC.1

GOSUB DG2
idx = X[2] ' Now that we've changed the values in the X-Array, X[2] contains the value 18 and so will idx
PortA.0[idx] = 1 ' Write to PortC.2

END

DG1:
X[0] = 27 ' AX VAR PORTD.3
X[1] = 20 ' BX VAR PORTC.4
X[2] = 17 'CX VAR PORTC.1
X[3] = 18 'DX VAR PORTC.2
X[4] = 24 'EX VAR PORTD.0
X[5] = 26 'FX VAR PORTD.2
X[6] = 21 'GX VAR PORTC.5
RETURN

DG2:
X[0] = 28 ' AX VAR PORTD.4
X[1] = 21 ' BX VAR PORTC.5
X[2] = 18 'CX VAR PORTC.2
X[3] = 19 'DX VAR PORTC.3
X[4] = 25 'EX VAR PORTD.1
X[5] = 27 'FX VAR PORTD.3
X[6] = 22 'GX VAR PORTC.6
RETURN

CuriousOne
- 16th June 2020, 15:17
Well, we have been also told that PBP can't do string variables and this is chip limitation, but there are some other compilers, which can do variables on PICs. So I believe, this "on the fly" port redefine is exactly this particular compiler issue, not general hardware or software limitation.

Thanks for the array code, will read it later.

richard
- 17th June 2020, 06:04
So I believe, this "on the fly" port redefine is exactly this particular compiler issue, not general hardware or software limitation.
the ability to alter a defined constant at runtime would be make a total mockery of sound programming fundamentals .
changing a constants definition is not a thing .
runtime allocation of resources is not done that way in any programming language, pbp3 is not particularly adept at it but with a bit of imagination there are workarounds. the sort of output pin manipulation via port alias indexing can do what you desire (as henrik has stated ) .

while pbp3 has no str type vars it can deal with and create null terminated c-type strings easily, with a little practice and a little skills
strings can be manipulated in any way necessary with little fuss.


i would just say one more thing multiplexing ffs

CuriousOne
- 17th June 2020, 18:48
Why pin definition should be constant?

OK say compiler substitutes say code "LD, B(3)" which say means making PORTB.3 high each time I'm making HIGH BUZ because previously I had defined BUZ var PORTB.3

Now let's say, I want to do dynamic port re-mapping and at one moment BUZ is PORTB.3 and at another moment it is PORTB.4. What compiler should do? During the compile time, instead of replacing all references of BUZ with "LD,B(3)", it just places statement "LD,B(X)", where is X an address say in eeprom or ram, from which, during runtime, the number of port to be made high is being read. And when I need to force this statement to make say PORTB.4 high, I'll write 4 into that address, instead of 3.

I'm asking of something unusual and not previously done?

Ioannis
- 17th June 2020, 20:52
I really do not understand why you may need this.

At design time, you decide what you will connect on which ports. Then you proceed to writing the program.

At this stage you have lines that will be defining what your circuit will do, at compile time, and what decisions your code will do at run time. Your electric connection cannot change dynamically!

It just doesn't make sense, to me at least, why move around a LED or Buzzer, or Button from port to port at run time...

Ioannis

CuriousOne
- 17th June 2020, 21:00
Simple.

To make code shorter.

I've posted an example above. Yes it works but I have 40 subroutines and 40 IF THEN's in it. In case of redefinable port<>variable, it would be reduced 4 times.

Ioannis
- 17th June 2020, 21:28
I am sure there are other ways...

Ioannis

richard
- 18th June 2020, 00:43
you can lead a horse to water but ....

any pin can be addressed with PORTA.0[offset]

CuriousOne
- 18th June 2020, 05:03
So say

FOR A=1 to 20
HIGH PORTA+A
NEXT

will work?

richard
- 18th June 2020, 05:56
So say

FOR A=1 to 20
HIGH PORTA+A
NEXT

will work?

do you think that looks even close ?




FOR A=0 to 20
PORTA.0[A]=1
NEXT

assuming the 18 [chip dependent] pins in that range are set as digital output

HenrikOlsson
- 18th June 2020, 06:02
I don't mean to be rude or to offend anyone but do you actually read and/or try any of the solutions you are provided with - for free - here or is the purpose of your post simply to vent your ideas on how you EXPECT expect everytning to work and then continue doing it "your way"?

Several times now you've been shown the correct syntax to access any pin using an offset and it's (for example, using PortA.0 as the "base address") PortA.0[offset] and yet you ask if PORTA+A will work, I'm sorry but I don't get it. And to be perfectly clear, no, PORTA+A will not do what you want.

So in your example:

FOR A=1 to 20
HIGH PORTA.0[A]
NEXT
I would not use HIGH though but instead PORTA.0[A] = 1 since that will produce smaller and faster code and it will work provided TRIS are cleared for the pins in question.

/Henrik.

CuriousOne
- 19th June 2020, 06:11
Well you're the pros, for me a lot of these strange brackets and other syntax things are quite hard to understand, because I've learned BASIC on ZX Spectrum, almost 35 years ago :) So I'm asking to clarify.

So back to this:


FOR A=1 to 32
PORTA.0[A]=1
NEXT
Will make all ports of PORTA/PORTB/PORTC/PORTD high in sequence, right? (All TRIS and other yada-yada are already set).

richard
- 19th June 2020, 06:25
if it does not work post code and schematic of your attempt, its a simple test

HenrikOlsson
- 19th June 2020, 07:11
FOR A=1 to 32
PORTA.0[A]=1
NEXT
Will make all ports of PORTA/PORTB/PORTC/PORTD high in sequence, right? (All TRIS and other yada-yada are already set).
Since you start your offset value (the FOR loop) at 1 it the first bit to be set will be "one away" from PortA.0, in other words PortA.1 and then contiune 32 bits "up from there", so you will write to the first bit of the register comming after PortD - that can ruin your day.

But, as Richard says, TRY IT for crying out loud :-) Investigate how it works, does it do what you expect, change something and see if you get the expected result and if not think about WHY.

CuriousOne
- 19th June 2020, 08:22
Well my circuit is already built, software written and it works fine, just it takes about 7.3k memory, so I'd like to slim it down. If anyone want to build a LED clock, with directly driven segments, using PIC16F887 and DS3231, here's the working code (it needs some cleanup, unused labels and variables should be removed, but it works just fine as it is). I also can upload gerber files of PCB. I'm planning to add some extra features to existing hardware, like user digit style selection (US/EU/JP) and temperature measurement via DS18B20, but all this later.




#CONFIG
cfg1 = _INTRC_OSC_NOCLKOUT ; INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
cfg1&= _WDT_ON ; WDT enabled
cfg1&= _PWRTE_OFF ; PWRT disabled
cfg1&= _MCLRE_OFF ; RE3/MCLR pin function is digital input, MCLR internally tied to VDD
cfg1&= _CP_OFF ; Program memory code protection is disabled
cfg1&= _CPD_OFF ; Data memory code protection is disabled
cfg1&= _BOR_OFF ; BOR disabled
cfg1&= _IESO_ON ; Internal/External Switchover mode is enabled
cfg1&= _FCMEN_ON ; Fail-Safe Clock Monitor is enabled
cfg1&= _LVP_OFF ; RB3 pin has digital I/O, HV on MCLR must be used for programming
cfg1&= _DEBUG_OFF ; In-Circuit Debugger disabled, RB6/ICSPCLK and RB7/ICSPDAT are general purpose I/O pins
__CONFIG _CONFIG1, cfg1


cfg2 = _BOR40V ; Brown-out Reset set to 4.0V
cfg2&= _WRT_OFF ; Write protection off
__CONFIG _CONFIG2, cfg2


#ENDCONFIG


'nixie led clock electronics direct drive


'include "modedefs.bas"


OSCCON=%01110101 'SET INTOSC TO 8MHZ
ANSEL=%00000000
ANSELH=%00000000 'disable ADC


TRISC=%00000000 'set PORTC as output all
TRISD=%00000000 'set PORTD as output all
TRISB=%00000000 'set PORTB as output all
TRISA=%00000001 'set PORTA 0 as input, others as output
TRISE=%00000000
'OPTION_REG=%100000000 'disable portb pullups



DEFINE OSC 8 'OSC SPEED
'turn off all digits


PORTA=0: PORTB=0: PORTC=0: PORTD=0 : PORTE=0


'PIN CONFIG
FEXI VAR PORTA.0


'BUZZER




low portA
low portb
low portc
low portd
low porte


'1 digit
A1 VAR PORTD.3: B1 VAR PORTC.4: C1 VAR PORTC.1: D1 VAR PORTC.2: E1 VAR PORTD.0
F1 VAR PORTD.2: G1 VAR PORTC.5:
'2
A2 VAR PORTD.4: B2 VAR PORTD.5: C2 VAR PORTA.7: D2 VAR PORTA.6: E2 VAR PORTC.0
G2 VAR PORTC.6: F2 VAR PORTC.7
'3
A3 VAR PORTB.2: B3 VAR PORTB.5: C3 VAR PORTA.5: D3 VAR PORTE.0: E3 VAR PORTE.1
F3 VAR PORTB.1: G3 VAR PORTB.0:
'4
A4 VAR PORTD.7: B4 VAR PORTD.6: C4 VAR PORTA.1: D4 VAR PORTA.2: E4 VAR PORTA.3
F4 VAR PORTB.3: G4 var PORTB.4


DOT VAR PORTE.2
'BUT VAR PORTA.0
BUZ var PORTB.7


SDA VAR PORTD.1
SCL VAR PORTC.3
'PORTA.4 UNUSED
'dot




'my time variables


RTCYear Var Byte: RTCMonth Var Byte: RTCDate Var Byte: RTCDay Var Byte: RTCHour Var Byte
RTCMin Var Byte: RTCSec Var Byte: RTCCtrl Var Byte




saatebi var word 'hours
cutebi var word 'minutes
clebi var word 'years
tve var word 'months
dge var word 'days
DRO var byte 'temp time holder
cvladi var word
cvlileba var byte 'detect time change variable
dlycnt var word 'delay counter for keyboard debouncing.
menuitem var byte 'selected menu item number
ticker var word 'counter for loop waiting
alhr var word 'alarm hours
almin var word 'alarm minutes
alwk var byte 'alarm on/off weekends on/off
HR24 var byte 'HR24 mode
tcr var byte ' time corrector variable
rmd var byte ' refresh mode selection
ROLL VAR BYTE 'ROLL ENABLE/DISABLE
trigfix var byte 'corrector reset variable
X VAR WORD ' TEMP VARIABLE refresh time
Y var word 'dot display delay
Z var word 'temp variable 3
Z1 var word 'temp 4
Z2 var word 'temp 5
Z3 var word 'temp 6
T1 VAR WORD 'VARIABLES FOR TIME DIGITS
T2 VAR WORD 'from left to right
T3 VAR WORD
T4 VAR WORD


'______________initial variable values
trigfix=1
cvladi=0
ticker=0
dlycnt=0
menuitem=0
TCR=30
X=1
y=1
Z=1 'high dot


FOR Y=1 TO 3
GOSUB CLEANER
X=350
LOW E4: LOW D4: LOW C4: LOW B4: LOW A4 'A AT 4
PAUSE X
GOSUB CLAR4
LOW E3: LOW D3: LOW C3: LOW B3: LOW A3 'A AT 3
LOW A4: LOW B4: LOW F4: LOW E4: LOW D4 'L AT 4
PAUSE X
GOSUB CLAR4: GOSUB CLAR3
LOW A4: LOW B4: LOW C4: LOW D4 'E AT 4
LOW A3: LOW B3: LOW F3: LOW E3: LOW D3 'L AT 3
LOW E2: LOW D2: LOW C2: LOW B2: LOW A2 'A AT 2
PAUSE X
GOSUB CLAR4: GOSUB CLAR3: GOSUB CLAR2
LOW E1: LOW D1: LOW C1: LOW B1: LOW A1 'A AT 1
LOW A2: LOW B2: LOW F2: LOW E2: LOW D2 'L AT 2
LOW A3: LOW B3: LOW C3: LOW D3 'E AT 3
LOW B4: LOW G4: LOW C4: LOW D4 'Q AT 4
PAUSE X
GOSUB CLEANER
LOW A1: LOW B1: LOW F1: LOW E1: LOW D1 'L AT 1
LOW A2: LOW B2: LOW C2: LOW D2 'E AT 2
LOW B3: LOW G3: LOW C3: LOW D3 'Q AT 3
LOW F4: LOW E4: LOW D4: LOW C4 'S AT 4
PAUSE X
GOSUB CLEANER
LOW A1: LOW B1: LOW C1: LOW D1 'E AT 1
LOW B2: LOW G2: LOW C2: LOW D2 'Q AT 2
LOW F3: LOW E3: LOW D3: LOW C3 'S AT 3
LOW E4: LOW F4: LOW A4: LOW B4: LOW C4 'I AT 4
PAUSE X
GOSUB CLEANER
LOW B1: LOW G1: LOW C1: LOW D1 'Q AT 1
LOW F2: LOW E2: LOW D2: LOW C2 'S AT 2
LOW E3: LOW F3: LOW A3: LOW B3: LOW C3 'I AT 3
GOSUB CLAR4
PAUSE X
GOSUB CLEANER
LOW F1: LOW E1: LOW D1: LOW C1 'S AT 1
LOW E2: LOW F2: LOW A2: LOW B2: LOW C2 'I AT 2
GOSUB CLAR3
PAUSE X


GOSUB CLEANER
LOW E1: LOW F1: LOW A1: LOW B1: LOW C1 'I AT 1
GOSUB CLAR2
PAUSE X
GOSUB CLEANER
PAUSE X
NEXT
PAUSE 1000


GOSUB EREAD ' read eeprom values
gosub ZEROPLAY ' show zeros
for Z=1 to 4000
pause 1
if fexi=0 then gosub longbibi: goto setuploop
next
goto demoscene


setuploop: 'configuration
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1


endif




if ticker>1500 and fexi=0 then gasvla 'if long pressed, then exit and (or) go to selector item
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap
ticker=0
dlycnt=0
pause 1
menuitem=menuitem+1 'this is incremental variable, substitute another next time you need it
if menuitem>14 then menuitem=0
t1=menuitem dig 1: t2=menuitem dig 0: gosub display ' display current item
gosub bibi
endif
goto setuploop


gasvla:
ticker=0:dlycnt=0 'RESET COUNTER VARIABLES
gosub bibi 'beep


'read RTC values into system variables
gosub gettime 'READ TIMES
gosub timedecode 'CONVERT TO DEC
GOSUB EREAD 'READ EEPROM
IF alhr=255 THEN alhr=0 'RESET alarm hours VARIABLE FOR FIRST RUN
IF almin=255 THEN almin=0 'RESET alarm hours VARIABLE FOR FIRST RUN
IF HR24=255 THEN HR24=0 'RESET HR24 VARIABLE FOR FIRST RUN
IF alwk=255 THEN alwk=0 'RESET week alarm VARIABLE FOR FIRST RUN
if tcr=255 then tcr=30 'reset time corrector to default
if rmd=255 then rmd=0 'set refresh value to default
IF ROLL=255 THEN ROLL=0 'SET ROLL MODE INITIAL
gosub yeardecode
clebi=T3*10+T4
gosub monthdaydecode
tve=T1*10+T2 ' get month
dge=T3*10+T4 'get day


if menuitem=0 then DEMOSCENE
if menuitem=1 then YSET 'year set
IF MENUITEM=2 THEN MSET 'month set
IF MENUITEM=3 THEN DSET 'date set
IF MENUITEM=4 THEN HSET 'hour set
IF MENUITEM=5 THEN TSET 'minute set
IF MENUITEM=6 THEN HRMD '12/24 hour set
IF MENUITEM=7 THEN AHRS 'alarm hours
IF MENUITEM=8 THEN AMIN 'alarm minutes
IF MENUITEM=9 THEN ASET 'alarm/snooze enabled/disabled
'if menuitem=10 then RSET 'roll enable/disable
if menuitem=10 then RMOD 'refresh mode selection
if menuitem=11 then TCOR 'enter time corrector value
if menuitem=12 then FACHO 'go to segment looper
if menuitem=13 then DAYSET 'set day of the week
if menuitem=14 then DBGR 'debug mode


pause 200


goto setuploop




DEMOSCENE: 'main code loop
gosub gettime
gosub timedecode
'if Z3=30 then 'enable dot 30 seconds
'high dot
'pause 1
'low dot
'endif
if HR24=1 then gosub corrector 'adjust time to 24hr format
if cvlileba=1 then
'high dot
trigfix=1 'reset trigger alarm
low buz 'silence the alarm
pause 1
'low dot
gosub segtest 'if time changed, then let's animate display
endif


't3= z dig 1
't4=z dig 0
gosub display
FOR Y=1 TO 500
PAUSE 1
HIGH dot 'blink the separator dots
IF FEXI=0 THEN GOSUB TDM
NEXT Y
FOR Y=1 TO 500
PAUSE 1
low dot 'blink the separator dots
IF FEXI=0 THEN GOSUB TDM
NEXT Y






' alarm subroutine
if alwk=1 and saatebi=alhr and cutebi=almin and trigfix=1 then 'alarm all weekdays
high buz
endif


if alwk=2 and saatebi=alhr and cutebi=almin and trigfix=1 and RTCDAY<6 then 'alarm on workdays
'T1=0:T2=0
'T3=ALHR DIG 1: T4=ALHR DIG 0: GOSUB DISPLAY


'T1=0:T4=RTCDAY
'GOSUB DISPLAY
'PAUSE 2000
high buz


endif


GOTO DEMOSCENE


TDM: 'display year, month, date
trigfix=0
low buz 'turn of buzzer if enabled
GOSUB YEARDECODE
gosub meko
GOSUB DISPLAY
'LOW DOT
PAUSE 2000 'adjust these "2000" values for desired delay between displayed info change
GOSUB MONTHDAYDECODE
gosub meko
GOSUB DISPLAY
'HIGH DOT
PAUSE 2000
'LOW DOT
if alwk<>0 then 'if alarm is enabled, show it's value
gosub meko
t1=alhr dig 1: t2=alhr dig 0: t3=almin dig 1: t4=almin dig 0: gosub display: pause 2000 'display alarm
gosub meko
endif
RETURN


' Subroutine to write time to RTC
settime:
'rtcsec=0 ' this is necessary to make clock tick
I2CWrite SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
Return

' Subroutine to read time from RTC
gettime:
I2CRead SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]

if DRO<>rtcmin then 'check for time changes, so display only is refreshed when time is changed
cvlileba=1
else
cvlileba=0
endif

DRO=rtcmin

Return


timedecode: 'decode time from RTC into values suitable for nixie digit illumination
t1=rtchour >> 4
t2=rtchour // 16
t3=rtcMin >> 4
T4=rtcMin // 16
Z1=RTCSEC >> 4
Z2=RTCseC // 16

saatebi=t1*10+t2 'read hours
cutebi=T3*10+T4 ' read minutes
z3=Z1*10+Z2 'READ SECONDS
IF SAATEBI=23 AND CUTEBI=58 AND Z3=30 and tcr<>30 THEN
GOSUB CHIPFIX 'RESET MIDNIGHT CHIP
endif


return


yeardecode:
t1=2
t2=0
T3=rtcyear >> 4
T4=rtcyear // 16
return


monthdaydecode:
t1=rtcmonth >> 4
t2=rtcmonth // 16
T3=rtcdate >> 4
T4=rtcdate // 16
return






SEGTEST: 'refresh all segments with cool animation
IF RMD=0 THEN KEKO
IF RMD=1 THEN ZEKO
IF RMD=2 THEN MEKO


KEKO: 'ANOTHER ROLL MODE
return


zeko:


return

meko:


RETURN


DISPLAY: 'DECODE VALUES AND DISPLAY THEM
x=t1: Y=1: GOSUB DECODER
x=t2: Y=2: GOSUB DECODER
x=t3: Y=3: GOSUB DECODER
X=t4: Y=4: GOSUB DECODER


pause 10


'ended
return


:FACHO 'test all segments


corrector: 'adjust for 12 hour display
IF T1=1 AND T2=3 THEN T2=1:T1=0
IF T1=1 AND T2=4 THEN T2=2:T1=0
IF T1=1 AND T2=5 THEN T2=3:T1=0
IF T1=1 AND T2=6 THEN T2=4:T1=0
IF T1=1 AND T2=7 THEN T2=5:T1=0
IF T1=1 AND T2=8 THEN T2=6:T1=0
IF T1=1 AND T2=9 THEN T2=7:T1=0
IF T1=2 AND T2=0 THEN T2=8:T1=0
IF T1=2 AND T2=1 THEN T2=9:T1=0
IF T1=2 AND T2=2 THEN T2=0:T1=1
IF T1=2 AND T2=3 THEN T2=1:T1=1
return


'EEPROM READ AND WRITE
EREAD:
READ 1, HR24 'READ 12/24 HOUR MODE VARIABLE
READ 2, ALWK 'READ ALARM ENABLE/DISABLE AND WEEK
READ 3, ALHR 'READ ALARM HOURS
READ 4, ALMIN 'READ ALARM MINUTES
read 5, HR24 'HR24 value
read 6, tcr ' time corrector value
read 7, rmd 'refresh mode
READ 8, ROLL 'ROLL MODE
RETURN


EWRITE:
WRITE 1, HR24 'READ 12/24 HOUR MODE VARIABLE
WRITE 2, ALWK 'READ ALARM ENABLE/DISABLE AND WEEK
WRITE 3, ALHR 'READ ALARM HOURS
WRITE 4, ALMIN 'READ ALARM MINUTES
write 5, HR24 'HR24 value
write 6, tcr ' time corrector value
write 7, rmd 'refresh mode
WRITE 8, ROLL 'ROLL MODE
RETURN


BIBI: 'MAKE DA NOIZE
high buz
pause 100
low buz
RETURN


LONGBIBI: 'exit confirmation with long beep and variables reset
ticker=0: dlycnt=0: menuitem=0 'reset variables again
high buz
PAUSE 400
low buz
return




'_setup subroutines_______________________________________ _____________________
'


YSET: 'SET THE YEAR
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
gosub LONGBIBI
gosub ZEROPLAY 'reset display
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap
ticker=0
dlycnt=0
clebi=clebi+1
if clebi>59 then clebi=20
rtcyear=clebi DIG 1
rtcyear=rtcyear<<4
rtcyear=rtcyear+clebi DIG 0
gosub settime
'lcdout $fe,$c0, " Year: ", #clebi," " 'debug just for case
T1=0:t2=1:t3=clebi dig 1: t4=clebi dig 0: gosub display
pause 1
gosub bibi
endif
goto yset

MSET: 'SET THE MONTH
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
gosub ZEROPLAY 'reset display
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap
ticker=0
dlycnt=0
tve=tve+1
if tve>12 then tve=1
rtcmonth=tve DIG 1
rtcmonth=rtcmonth<<4
rtcmonth=rtcmonth+tve DIG 0
gosub settime
'lcdout $fe,$c0, " Month: ", #tve," " 'debug just for case
T1=0:t2=2:t3=tve dig 1: t4=tve dig 0: gosub display
pause 1
gosub bibi
endif
goto MSET


DSET: 'SET THE DATE
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
gosub ZEROPLAY
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap
ticker=0
dlycnt=0
dge=dge+1
if dge>31 then dge=1
rtcdate=dge DIG 1
rtcdate=rtcdate<<4
rtcdate=rtcdate+dge DIG 0
gosub settime
'lcdout $fe,$c0, " Day: ", #dge," " 'debug just for case
T1=0:t2=3:t3=dge dig 1: t4=dge dig 0: gosub display
pause 1
gosub bibi
endif
goto DSET


HSET: 'SET THE HOURs
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
gosub zeroplay
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap
ticker=0
dlycnt=0
saatebi=saatebi+1
if saatebi>23 then saatebi=0
rtchour=saatebi DIG 1
rtchour=rtchour<<4
rtchour=rtchour+saatebi DIG 0
gosub settime
T1=0:t2=4:t3=saatebi dig 1: t4=saatebi dig 0: gosub display
pause 1
gosub bibi
endif
goto HSET




TSET: 'SET THE minutes
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
gosub zeroplay
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap
ticker=0
dlycnt=0
cutebi=cutebi+1
if cutebi>59 then cutebi=0
rtcmin=cutebi DIG 1
rtcmin=rtcmin<<4
rtcmin=rtcmin+cutebi DIG 0
gosub settime
T1=0:t2=5:t3=cutebi dig 1: t4=cutebi dig 0: gosub display
pause 1
gosub bibi
endif
GOTO TSET


AHRS: 'SET THE ALARM HOURS


if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
GOSUB EWRITE 'WRITE VARIABLES TO EEPROM
gosub zeroplay
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap


ticker=0
dlycnt=0
alhr=alhr+1
if alhr>23 then alhr=0
T1=0:t2=7:t3=alhr dig 1: t4=alhr dig 0: gosub display
pause 1
gosub bibi
endif
goto AHRS


AMIN: 'SET THE ALARM MINUTES


if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
GOSUB EWRITE 'WRITE VARIABLES TO EEPROM
gosub zeroplay
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap


ticker=0
dlycnt=0
almin=almin+1
if almin>59 then almin=0
T1=0:t2=8:t3=almin dig 1: t4=almin dig 0: gosub display
pause 1
gosub bibi
endif
goto AMIN


ASET: 'ENABLE/DISABLE ALARM/SNOOZE 'SET ALARM ON WEEKENDS
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
GOSUB EWRITE 'WRITE VARIABLES TO EEPROM
gosub zeroplay
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap


ticker=0
dlycnt=0
alwk=alwk+1
if alwk>2 then alwk=0
T1=0:t2=9:t3=alwk dig 1: t4=alwk dig 0: gosub display
pause 1
gosub bibi
endif
goto ASET




HRMD: 'HR24 MODE/12-24 HOURS
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
GOSUB EWRITE 'WRITE VARIABLES TO EEPROM
gosub zeroplay
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap


ticker=0
dlycnt=0
HR24=HR24+1
if HR24>1 then HR24=0
T1=0:t2=6:t3=0: t4=HR24 dig 0: gosub display
pause 1
gosub bibi
endif
GOTO HRMD


RMOD: 'REFRESH MODE SELECTION
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
GOSUB EWRITE 'WRITE VARIABLES TO EEPROM
gosub zeroplay
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap


ticker=0
dlycnt=0
RMD=RMD+1
if RMD>2 then RMD=0
T1=1:t2=0:t3=0: t4=RMD dig 0: gosub display
pause 1
gosub bibi
endif
GOTO RMOD


RSET: 'ROLL SET
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
GOSUB EWRITE 'WRITE VARIABLES TO EEPROM
gosub zeroplay
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap


ticker=0
dlycnt=0
ROLL=ROLL+1
if ROLL>1 then ROLL=0
T1=1:t2=0:t3=0: t4=ROLL dig 0: gosub display
pause 1
gosub bibi
endif
GOTO RSET


TCOR: 'TIME CORRECTOR SET
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
GOSUB EWRITE 'WRITE VARIABLES TO EEPROM
gosub zeroplay
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap


ticker=0
dlycnt=0
TCR=TCR+1
if TCR>45 then TCR=15
T1=1:t2=2:t3=TCR DIG 1: t4=TCR dig 0: gosub display
pause 1
gosub bibi
endif
GOTO TCOR








ZEROPLAY: 'clear the display and set to 00s
T1=0: t2=0: t3=0: t4=0
gosub display
return


CHIPFIX: 'SUBROUTINE FOR FIXING DS3231 ISSUES
if tcr<>30 then
rtcsec=z3 DIG 1
rtcsec=rtcsec << 4 'convert time to RTC format
rtcsec=rtcsec+z3 DIG 0
GOSUB SETTIME
'high buz
'pause 1000
'low buz
endif
RETURN


DAYSET: 'set day of week
if fexi=0 then
dlycnt=dlycnt+1 'increase debounce variable while button is pressed
ticker=ticker+1
pause 1
endif


if ticker>1500 and fexi=0 then
GOSUB gettime 'read time variables
RTCDAY=X 'write to RTCDAY
gosub settime 'write it
gosub zeroplay
gosub LONGBIBI
goto setuploop 'if long pressed, then exit and (or) go to selector item
endif
if fexi=1 and dlycnt>100 then 'if short pressed, then do the rap


ticker=0
dlycnt=0
RTCDay=RTCDay+1
if RTCDay>7 then RTCDay=1
T1=1:t2=3:t3=0: t4=RTCDAY: gosub display
pause 1
gosub bibi
X=RTCDAY
endif
goto DAYSET




DBGR: 'debug info display
T1=0: T2=0: t3=0: T4=TRIGFIX
GOSUB DISPLAY
PAUSE 2000
gosub gettime 'read time
gosub yeardecode 'convert to decimal
T1=0: t2=1
gosub display 'year
pause 2000


GOSUB MONTHDAYDECODE
GOSUB DISPLAY 'month/day
pause 2000
gosub timedecode 'time
gosub display
pause 2000
t1=1: t2=1: t3=0:t4=rtcday 'day
gosub display
pause 2000
t1=2: t2=2: t3=rtcsec dig 1:t4=rtcsec dig 0 'seconds
gosub display
pause 2000
gosub eread
T1=0:t2=0: t3=0: t4= hr24 'time format var
gosub display
pause 2000
T1=0:t2=0: t3=0: t4= alwk 'alarm mode
gosub display
pause 2000
T1=0:t2=0: t3=alhr dig 1: t4= alhr dig 0 'alarm hours
gosub display
pause 2000
T1=0:t2=0: t3=almin dig 1: t4= almin dig 0 'alarm minutes
gosub display
pause 2000
T1=0:t2=0: t3=tcr dig 1: t4= tcr dig 0 'corrector value
gosub display
pause 2000
T1=0:t2=0: t3=rmd dig 1: t4= rmd dig 0 'refresh mode
gosub display
pause 2000
T1=0:t2=0: t3=roll dig 1: t4= roll dig 0 'roll value
gosub display
pause 2000
gosub longbibi
goto setuploop
DECODER: 'DECODER ROUTINE


IF X=0 AND Y=1 THEN GOSUB N10 'displays specific digit for specific segment
IF X=1 AND Y=1 THEN GOSUB N11
IF X=2 AND Y=1 THEN GOSUB N12
IF X=3 AND Y=1 THEN GOSUB N13
IF X=4 AND Y=1 THEN GOSUB N14
IF X=5 AND Y=1 THEN GOSUB N15
IF X=6 AND Y=1 THEN GOSUB N16
IF X=7 AND Y=1 THEN GOSUB N17
IF X=8 AND Y=1 THEN GOSUB N18
IF X=9 AND Y=1 THEN GOSUB N19


IF X=0 AND Y=2 THEN GOSUB N20
IF X=1 AND Y=2 THEN GOSUB N21
IF X=2 AND Y=2 THEN GOSUB N22
IF X=3 AND Y=2 THEN GOSUB N23
IF X=4 AND Y=2 THEN GOSUB N24
IF X=5 AND Y=2 THEN GOSUB N25
IF X=6 AND Y=2 THEN GOSUB N26
IF X=7 AND Y=2 THEN GOSUB N27
IF X=8 AND Y=2 THEN GOSUB N28
IF X=9 AND Y=2 THEN GOSUB N29


IF X=0 AND Y=3 THEN GOSUB N30
IF X=1 AND Y=3 THEN GOSUB N31
IF X=2 AND Y=3 THEN GOSUB N32
IF X=3 AND Y=3 THEN GOSUB N33
IF X=4 AND Y=3 THEN GOSUB N34
IF X=5 AND Y=3 THEN GOSUB N35
IF X=6 AND Y=3 THEN GOSUB N36
IF X=7 AND Y=3 THEN GOSUB N37
IF X=8 AND Y=3 THEN GOSUB N38
IF X=9 AND Y=3 THEN GOSUB N39


IF X=0 AND Y=4 THEN GOSUB N40
IF X=1 AND Y=4 THEN GOSUB N41
IF X=2 AND Y=4 THEN GOSUB N42
IF X=3 AND Y=4 THEN GOSUB N43
IF X=4 AND Y=4 THEN GOSUB N44
IF X=5 AND Y=4 THEN GOSUB N45
IF X=6 AND Y=4 THEN GOSUB N46
IF X=7 AND Y=4 THEN GOSUB N47
IF X=8 AND Y=4 THEN GOSUB N48
IF X=9 AND Y=4 THEN GOSUB N49
RETURN


N10: '0 at 1st digit
GOSUB CLAR1
LOW A1: LOW B1: LOW C1: LOW D1: LOW E1: LOW F1 '0
return


N11: '1 AT 1ST DIGIT
GOSUB CLAR1
low b1: low c1 '1
RETURN


N12:
GOSUB CLAR1
low A1: low B1: low g1: low e1: low d1 '2
RETURN


N13:
GOSUB CLAR1
low A1: LOW B1: LOW C1: LOW D1: LOW G1 '3
RETURN


N14:
GOSUB CLAR1
LOW F1: LOW B1: LOW G1: LOW C1 '4
RETURN


N15:
GOSUB CLAR1
LOW A1: LOW F1: LOW G1: LOW C1: LOW D1 '5
RETURN


N16:
GOSUB CLAR1
LOW F1: LOW A1: LOW G1: LOW E1: LOW D1: LOW C1 'C6
RETURN


N17:
GOSUB CLAR1
low A1: low B1: low C1 '7
RETURN


N18:
gosub CLAR1
low A1: low B1: low C1: low f1: low e1: low g1: low d1 '8
RETURN


N19:
gosub CLAR1
low A1: low B1: low C1: low f1: low g1: low d1 '9
RETURN


CLAR1: 'clear 1ST DIGIT
high A1: high B1: high C1: high d1: high e1: high f1: high g1
return


N20: '0 at 1st digit
GOSUB CLAR2
LOW A2: LOW B2: LOW C2: LOW D2: LOW E2: LOW F2 '0
return


N21: '1 AT 1ST DIGIT
GOSUB CLAR2
low b2: low c2 '1
RETURN


N22:
GOSUB CLAR2
low A2: low B2: low g2: low e2: low d2 '2
RETURN


N23:
GOSUB CLAR2
low A2: LOW B2: LOW C2: LOW D2: LOW G2 '3
RETURN


N24:
GOSUB CLAR2
LOW F2: LOW B2: LOW G2: LOW C2 '4
RETURN


N25:
GOSUB CLAR2
LOW A2: LOW F2: LOW G2: LOW C2: LOW D2 '5
RETURN


N26:
GOSUB CLAR2
LOW F2: LOW A2: LOW G2: LOW E2: LOW D2: LOW C2 'C6
RETURN


N27:
GOSUB CLAR2
low A2: low B2: low C2 '7
RETURN


N28:
gosub CLAR2
low A2: low B2: low C2: low f2: low e2: low g2: low d2 '8
RETURN


N29:
gosub CLAR2
low A2: low B2: low C2: low f2: low g2: low d2 '9
RETURN


CLAR2: 'clear 1ST DIGIT
high A2: high B2: high C2: high d2: high e2: high f2: high g2
return


N30: '0 at 1st digit
GOSUB CLAR3
LOW A3: LOW B3: LOW C3: LOW D3: LOW E3: LOW F3 '0
return


N31: '1 AT 1ST DIGIT
GOSUB CLAR3
low b3: low c3 '1
RETURN


N32:
GOSUB CLAR3
low A3: low B3: low g3: low e3: low d3 '2
RETURN


N33:
GOSUB CLAR3
low A3: LOW B3: LOW C3: LOW D3: LOW G3 '3
RETURN


N34:
GOSUB CLAR3
LOW F3: LOW B3: LOW G3: LOW C3 '4
RETURN


N35:
GOSUB CLAR3
LOW A3: LOW F3: LOW G3: LOW C3: LOW D3 '5
RETURN


N36:
GOSUB CLAR3
LOW F3: LOW A3: LOW G3: LOW E3: LOW D3: LOW C3 'C6
RETURN


N37:
GOSUB CLAR3
low A3: low B3: low C3 '7
RETURN


N38:
gosub CLAR3
low A3: low B3: low C3: low f3: low e3: low g3: low d3 '8
RETURN


N39:
gosub CLAR3
low A3: low B3: low C3: low f3: low g3: low d3 '9
RETURN


CLAR3: 'clear 1ST DIGIT
high A3: high B3: high C3: high d3: high e3: high f3: high g3
return


N40: '0 at 1st digit
GOSUB CLAR4
LOW A4: LOW B4: LOW C4: LOW D4: LOW E4: LOW F4 '0
return


N41: '1 AT 1ST DIGIT
GOSUB CLAR4
low b4: low c4 '1
RETURN


N42:
GOSUB CLAR4
low A4: low B4: low g4: low e4: low d4 '2
RETURN


N43:
GOSUB CLAR4
low A4: LOW B4: LOW C4: LOW D4: LOW G4 '3
RETURN


N44:
GOSUB CLAR4
LOW F4: LOW B4: LOW G4: LOW C4 '4
RETURN


N45:
GOSUB CLAR4
LOW A4: LOW F4: LOW G4: LOW C4: LOW D4 '5
RETURN


N46:
GOSUB CLAR4
LOW F4: LOW A4: LOW G4: LOW E4: LOW D4: LOW C4 'C6
RETURN


N47:
GOSUB CLAR4
low A4: low B4: low C4 '7
RETURN


N48:
gosub CLAR4
low A4: low B4: low C4: low F4: low E4: low G4: low D4 '8
RETURN


N49:
gosub CLAR4
low A4: low B4: low C4: low F4: low G4: low D4 '9
RETURN


CLAR4: 'clear 1ST DIGIT
high A4: high B4: high C4: high D4: high E4: high F4: high G4
return


CLEANER: 'clear all
high a1: high b1: high c1: high d1: high e1: high f1: high g1
high a2: high b2: high c2: high d2: high e2: high f2: high g2
high a3: high b3: high c3: high d3: high e3: high f3: high g3
high a4: high b4: high c4: high d4: high e4: high f4: high g4
RETURN



As I understand, this sequential access is good, but I can't use it with my PCB, need to design a new one...
8886
8885

richard
- 19th June 2020, 10:11
As I understand, this sequential access is good, but I can't use it with my PCB, need to design a new one..

nonsense, you can map it to any configuration

CuriousOne
- 19th June 2020, 14:57
https://youtu.be/EoPaM2Jru24

Here version with HPWM controlled color setting mode :)

CuriousOne
- 19th June 2020, 22:28
And by adding properly synced multiplexing, even nicer effects can be obtained. Too bad they do not make RGB 7 segment displays in manageable size or price....

8887

As you can see, greens are less bright than reds, this is due fact, that there are two leds in series for each color and each segment, so driving them from 5V makes green look less brighter. To achieve same level of brightness of green as red has, it needs about 5.8V, which is way too high and most likely will burn my MCU, so I'm avoiding that at all costs.

astanapane
- 19th August 2020, 16:13
And by adding properly synced multiplexing, even nicer effects can be obtained. Too bad they do not make RGB 7 segment displays in manageable size or price....

8887

As you can see, greens are less bright than reds, this is due fact, that there are two leds in series for each color and each segment, so driving them from 5V makes green look less brighter. To achieve same level of brightness of green as red has, it needs about 5.8V, which is way too high and most likely will burn my MCU, so I'm avoiding that at all costs.

very nice work. thanks for sharing. I'm not going to use your code but definately it will help me understand some things.

CuriousOne
- 20th August 2020, 05:48
I've added external drivers to circuitry, so voltage now not an issue, so brightness also can be increased :)

CuriousOne
- 10th June 2022, 10:29
Bringing up an old thread...

I have CD4514 connected with it's ABCD inputs to upper 4 bits of PORT.D (PORTD4-7)
I have variable that changes values between 0 and 16. Name is A
How Can I directly write this variable to these upper bits?

PORTD.0[4+A]=A seems not to be working...

pedja089
- 10th June 2022, 23:16
Try
PORTD.4=A.0
PORTD.5=A.1
PORTD.6=A.2
PORTD.7=A.3
Another way
PORTD=A>>4

CuriousOne
- 12th June 2022, 06:26
Thanks, that works!

peterdeco1
- 16th June 2022, 18:04
We aren't looking for fencing on an electronics forum.

mpgmike
- 16th June 2022, 18:16
We aren't looking for fencing on an electronics forum.

He made one other seemingly useless post with his fence company link embedded. I deleted this one. Maybe I should have deleted the other one. At least in the other one his fence link looked like a signature. Had I seen this one first, I would have just got rid of him.

Ioannis
- 16th June 2022, 18:39
In the past was not in the annoying side of spams. Checked the previous posts and cannot decide to kick him/her out... We'll keep our eye on..

Ioannis

CuriousOne
- 16th June 2022, 22:37
By the way, is there a way to arraywrite to predefined area of array?

arraywrite topline, ["mose"]

writes to 0 to 3 positions of array, but say I want to write this text from 4 to 7 positions, how should I?
I can add something like arraywrite topline, [1,2,3,4,"mose"], but this will delete previous content of previous array members, and I want to avoid this. Any way?

Ioannis
- 18th June 2022, 22:22
SKIP 4 as a modifier maybe?

Ioannis