Snooker scoreboard with IR transmitter

ashawthing

New Member
I am trying to design and make an electronic snooker scoreboard with an IR hand-held transmitter. There will be the main scoreboard unit on the wall, each players score will be displayed on 2 sets of 3 seven segment displays. There will then be a small hand-held unit with a keypad. Each time a ball is potted the referee will press the number on the keypad corresponding to the appropriate points for the ball potted. There will also be a button to -1 from the count and reset both scores for a new game.

I have put this code together for the transmitter using a picaxe-14m

Code:
' Snooker score board IR remote

' output 1 - row 1
' output 2 - row 2
' output 3 - row 3
' output 4 - row 4

' input 0 - defines which player is scoring
' input 1 - column 1
' input 2 - column 2
' input 3 - column 3

symbol key_value = b0

polling:
	let key_value = 0
	let pins = %00000010
	gosub key_test
	
	let key_value = 3
	let pins = %00000100
	gosub key_test
	
	let key_value = 6
	let pins = %00001000
	gosub key_test
	
	let key_value = 9
	let pins = %00010000
	gosub key_test
	
	goto polling

' key_value will now be 0,3,6 or 9. Add 1,2 or 3 to this to get the correct key_value
' return if no key has been pressed

key_test:
	if pin1 = 1 then add1
	if pin2 = 1 then add2
	if pin3 = 1 then add3
	return

add1: let key_value = key_value + 1
add2:	let key_value = key_value + 2
add3:	let key_value = key_value + 3

' Now transmit the information using infraout

if pin0 = 0 then transmit_player1
goto transmit_player2

transmit_player1:
	for b1 = 1 to 10
	infraout 1,key_value
	pause 45
	next b1
	goto polling

transmit_player2:
	key_value = key_value + 12
	for b1 = 1 to 10
	infraout 1,key_value
	pause 45
	next b1
	goto polling
The code that figures out the keypad input has pretty much been taken from one of the examples on the programming editor.

I am interested on getting your thoughts on the code for sending the ir information. I plan on having a toggle switch setting input0 to 1/0, this determines which player is scoring and which score to increase the count of. I have just set the infraout data to key_value for player1 and key_value+12 for player2 (there are 12 possibilities for player1 so the first 12 infraout data values are taken).

There are no syntax errors from the programming editor but can anyone see anything that looks wrong. I am a relative novice so any advice is welcome
 

eclectic

Moderator
Looks a good start to your project.

To aid clarification,
could you post a proposed circuit/schematic?

CAD / Paint / ASCII / neat drawing are all OK.

e

Addit.
Diagram
 

Attachments

Last edited:

Chavaquiah

Senior Member
For a "relative novice", I'd say you've done pretty well. :)

There are, however, two small problems you will want to correct:

1) You gosub to key_test but don't always use return to... well, return. This will cause stack overflows soon enough (always use "return" when you go somewhere with "gosub"). Easy enough to correct. Instead of "goto polling" at each transmit_player block, issue a return.

2)
Code:
key_test:
	if pin1 = 1 then add1
	if pin2 = 1 then add2
	if pin3 = 1 then add3
	return

add1: let key_value = key_value + 1
add2:	let key_value = key_value + 2
add3:	let key_value = key_value + 3
Try to follow this on the simulator when pin1 is high. The program jumps to add1 (and that's fine) but then falls through add2 and add3. 6 will be added, instead of 1.

Maybe you could do something like this:
Code:
add1: let key_value = key_value + 1 : goto transmit_info
add2:	let key_value = key_value + 2 : goto transmit_info
add3:	let key_value = key_value + 3

' Now transmit the information using infraout

transmit_info:

if pin0 = 0 then transmit_player1
goto transmit_player2
 

ashawthing

New Member
For a "relative novice", I'd say you've done pretty well. :)

There are, however, two small problems you will want to correct:

1) You gosub to key_test but don't always use return to... well, return. This will cause stack overflows soon enough (always use "return" when you go somewhere with "gosub"). Easy enough to correct. Instead of "goto polling" at each transmit_player block, issue a return.

2)
Code:
key_test:
	if pin1 = 1 then add1
	if pin2 = 1 then add2
	if pin3 = 1 then add3
	return

add1: let key_value = key_value + 1
add2:	let key_value = key_value + 2
add3:	let key_value = key_value + 3
Try to follow this on the simulator when pin1 is high. The program jumps to add1 (and that's fine) but then falls through add2 and add3. 6 will be added, instead of 1.

Maybe you could do something like this:
Code:
add1: let key_value = key_value + 1 : goto transmit_info
add2:	let key_value = key_value + 2 : goto transmit_info
add3:	let key_value = key_value + 3

' Now transmit the information using infraout

transmit_info:

if pin0 = 0 then transmit_player1
goto transmit_player2
1). If I put return where would it go? I put goto polling because I didn't want to go back to the key_test routine.

2). Well spotted, thank you ;)
 

Chavaquiah

Senior Member
Return goes to the statement following the previous gosub...

You're probably thinking of the goto right before the start of key_test. That one is fine. The ones I meant are those following each transmit_playerX block:

Code:
transmit_player1:
	for b1 = 1 to 10
	infraout 1,key_value
	pause 45
	next b1
	return 'goto polling

transmit_player2:
	key_value = key_value + 12
	for b1 = 1 to 10
	infraout 1,key_value
	pause 45
	next b1
	return 'goto polling
 

ashawthing

New Member
Return goes to the statement following the previous gosub...

You're probably thinking of the goto right before the start of key_test. That one is fine. The ones I meant are those following each transmit_playerX block:

Code:
transmit_player1:
	for b1 = 1 to 10
	infraout 1,key_value
	pause 45
	next b1
	return 'goto polling

transmit_player2:
	key_value = key_value + 12
	for b1 = 1 to 10
	infraout 1,key_value
	pause 45
	next b1
	return 'goto polling
Ok just tryed it on the simulator, my understanding of it was wrong. Thanks

I'm now trying to figure out the best way to go about the reciever and counter. I think the simplest way is to use an 08M to recieve the IR signal and produce a series of clock pulses to 3 4026's. I cant find if you can count up and down with 3 coupled 4026's, I figure you cant?
 

eclectic

Moderator
Ok just tryed it on the simulator, my understanding of it was wrong. Thanks

I'm now trying to figure out the best way to go about the reciever and counter. I think the simplest way is to use an 08M to recieve the IR signal and produce a series of clock pulses to 3 4026's. I cant find if you can count up and down with 3 coupled 4026's, I figure you cant?
See Manual 3, page 22
"This system can be expanded to two digits by adding a second 4026B IC and a second
seven segment display, as shown in the diagram below. No changes to the code are
required, just give the variable b1 a value between 0 and 99 and the number will be
displayed on the two displays when sub-procedure ‘clock’ is called."

I did build a 3 x 7 segment
4026 circuit a couple of years ago.
It works, but
it took ages to make.
And, it's not very bright. :-(
(See the datasheet)
Never again!

Have a look at some of the OLED or
ready built display units.
(Unless you've got the patience of a Saint).

e
 

eclectic

Moderator
And I should have added:

There are lots more exotic alternatives,
involving Multiplexing / 595 / LED controllers ......

How serious is your project?
Or is it simply for fun / interest?

e
 

ashawthing

New Member
See Manual 3, page 22
"This system can be expanded to two digits by adding a second 4026B IC and a second
seven segment display, as shown in the diagram below. No changes to the code are
required, just give the variable b1 a value between 0 and 99 and the number will be
displayed on the two displays when sub-procedure ‘clock’ is called."

I did build a 3 x 7 segment
4026 circuit a couple of years ago.
It works, but
it took ages to make.
And, it's not very bright. :-(
(See the datasheet)
Never again!

Have a look at some of the OLED or
ready built display units.
(Unless you've got the patience of a Saint).

e
Ah, that could be what I have been looking for :) . I'll try and figure out if I can use 1 picaxe to recieve the infrain2 and drive 2 of these circuits. Also I think I will make a large 7 segment display from LED's and drive it with transistors
 

ashawthing

New Member
And I should have added:

There are lots more exotic alternatives,
involving Multiplexing / 595 / LED controllers ......

How serious is your project?
Or is it simply for fun / interest?

e
The project is just for fun but it would be nice to solve the problem in a more elegant way if there is one. Do you know where I can find out about these more involved solutions?
 

ashawthing

New Member
Just had a look at some of the possiblities using shift registers etc. I think the code is a little beyond at this stage but thanks for bringing it to my attention. Maybe I can look into that for a future project
 

Chavaquiah

Senior Member
I cant find if you can count up and down with 3 coupled 4026's, I figure you cant?
Indeed, you can't. Not down. If the display is showing "35" and you need to show "34", you have to reset it to zero and then count up again 34 times.

Not as bad as it sounds. Most of times scores go up and the Picaxe can resend the necessary pulses fast enough.

I agree with ecletic that manually wiring 2 x 3 digits becomes quite tedious (unless we design our own PCB). But, for a "public" display, 7-segment LEDs have their advantages.
 

ashawthing

New Member
Ok, I have decided to use an 08M to recieve to IR information. This will then drive 2 sets of 3 4026's and 7 segs.

The code for the 08M is as follows

Code:
' Snooker scoreboard reciever and counter
' PICAXE 08M

symbol player1_score = b0		' Define variables amd assign values
symbol player2_score = b1
symbol counter = b2

player1_score = 0
player2_score = 0
counter = 0

checkIR:
	infrain2						' Check the IR sensor for information
	if infra <= 12 then gosub player1_count		
	if infra > 12 then gosub player2_count
	return
	
player1_count:						
	if infra = 1 then count1
	if infra = 2 then count2
	if infra = 3 then count3
	if infra = 4 then count4
	if infra = 5 then count5
	if infra = 6 then count6
	if infra = 7 then count7
	if infra = 8 then count8
	if infra = 9 then count9
	if infra = 10 then gosub downcount1
	if infra = 12 then gosub reset_scores
	
	player1_score = player1_score + counter	' Calculates the players new score
	
	pulsout 1,10				' Resets the counter to 0
	for b3 = 1 to player1_score		' then counts back to the new score
	pulsout 0,10
	next b3
	return
	
player2_count:						
	infra = infra - 12			' Subtract 12 to find actual value of count
	if infra = 1 then count1		' as 12 was added prior to sending over IR
	if infra = 2 then count2
	if infra = 3 then count3
	if infra = 4 then count4
	if infra = 5 then count5
	if infra = 6 then count6
	if infra = 7 then count7
	if infra = 8 then count8
	if infra = 9 then count9
	if infra = 10 then gosub downcount1
	if infra = 12 then gosub reset_scores
			
	player2_score = player2_score + counter	
	
	pulsout 3,10	
	for b3 = 1 to player2_score
	pulsout 2,10
	next b3
	return

reset_scores:
	pulsout 1,10				' Resets both players score on display to 0
	pulsout 3,10
	player1_score = 0
	player2_score = 0
	return

downcount1:
	player1_score = player1_score - 1	' Subtracts 1 from player1 score
	pulsout 1,10
	for b3 = 1 to player1_score
	pulsout 0,10
	next b3
	return

downcount2:
	player2_score = player2_score - 1	' Subtracts 1 from player2 score
	pulsout 3,10
	for b3 = 1 to player2_score
	pulsout 2,10
	next b3
	return

count1: counter = 1
	return
count2: counter = 2
	return
count3: counter = 3
	return
count4: counter = 4
	return
count5: counter = 5
	return
count6: counter = 6
	return
count7: counter = 7
	return
count8: counter = 8
	return
count9: counter = 9
	return
Are there any obvious problems there? The help is much appreciated
 

Chavaquiah

Senior Member
You'll have to revise i/o usage as the 08M does not have output 3. Actually, in3 will be used for the IR receiver.

And now you went from too few returns to too many. :D

For instance, at the very start:
Code:
checkIR:
	infrain2						' Check the IR sensor for information
	if infra <= 12 then gosub player1_count		
	if infra > 12 then gosub player2_count
	return
Return to where?

You would also have to change...

if infra = 2 then count2

... to...

if infra = x then gosub countx

... because you then end the countx subroutines with return.

Also, consider replacing all those "if infra = x then gosub countx" with
Code:
if infra < 10 then
   counter = counter + infra
else
   ...
endif
 

eclectic

Moderator
Three points at the moment.

1. The 4026 output is very low.
http://www.rev-ed.co.uk/docs/4026B.pdf
for the complicated details.

2. I can see some complications
and also see some possible improvements to your code.
However, I'm too tired at the moment, to reply coherently. :)

I'm sure that you'll get intelligent answers soon

On-Gosub Inputs / outputs .................

3. How important is this project?
As in real snooker hall / just for fun .......
Would it be easier to go up-market, and get
a more powerful 18M2 / 20X2 / 28X2 / 40X2?
(Coupled with the appropriate project board).

Lots more outputs and a lot more processing power.

e

addit. I told you! :))
Chavaquiah posted an intelligent answer while I was typing. :))
 
Last edited:
Top