program frozen?

pleiser

Senior Member
As mentioned previously I am working on a PICAXE laptop,it occasionaly spontaniously freezes at various point in the program (program requests 2 keys from picaxe 28X2 i2c slave keyboard monitor (similar to setup with diy laptop here), saves to alfat (via i2c) and displays info from alfat (always !00 (command sucessful) and goes to menu). at a random point the program appears to stop (according to both OLED and toggling debug LED the relevant parts of the program are:
Code:
'picaxe laptop demo program slot 0
#picaxe 28x2
#slot 0
'i2c constants
symbol alfat=%10100100
symbol keyboard=%01010100
'system variables
symbol screenlevel=bit0
symbol loopcount=b11
'keyboard variables
symbol keycheck = b4
symbol keyraw =b5
symbol keyascii = b6
symbol keynum = b7
'wordedit variables
symbol cursorrow = b8
symbol cursorcol = b9
symbol cursorpos = b10
'game variables
'symbol guesscount = b11
'symbol hitcount = b0
'symbol gamerandom = b12
'symbol gamerandom2 =b13
'symbol gamerandom3 =b14
'symbol gamerandom4 =b15
'symbol gamerandom5 =b16
'symbol gamerandom6 =b17
'symbol gamerandom7 =b18
'symbol gamerandom8 =b19


hi2csetup i2cmaster,alfat,i2cfast,i2cbyte
'pause 200
hi2cout ("I M:",lf)
setup:

hi2cin (b12)
if b12=255 then setup2
if b12 <> "!" then setup
hi2cin (b12,b12,b12)

hi2cout ("I M:",lf)
setup2:

pause 530
serout C.1, N2400, (254,1)'clear display
pause 40
serout C.1, N2400, (254,128)


'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
menu:
main:
serout C.1,N2400, (254,128)
serout C.1, N2400, (254,1)
pause 30
serout C.1,N2400, ("1 Utilities")
serout C.1,N2400,(254,192,"2 Tests")

serout C.1,N2400,(254,148,"3 SD card")
'serout C.1,N2400,(254,148,"3 games")
serout C.1,N2400, (254,212,"4 other")
'serout C.1,N2400,(254,212,"4 calculator")

gosub getakey
branch keynum, (menu,utilitymenu, testmenu,gamemenu,othermenu)

goto menu
'....

gamemenu:   'sd card menu
'run 1
serout C.1,N2400, (254,128)
serout C.1, N2400, (254,1)
serout C.1, N2400, ("1 read sdcard")
serout C.1, N2400, (254,192,"2 reader number")
serout C.1, N2400, (254,148,"3 add to visitor log")
serout C.1, N2400, (254,212,"4 view visitor log")
'serout C.1,N2400, ("no games, press esc")
'serout C.1,N2400,(254,192,"- subtraction")
'serout C.1,N2400,(254,148,"* multiplication")
'serout C.1,N2400,(254,212,"/ division")
gosub getakey
branch keynum, (menu,sdreadsetup,sdtestsetup,visitorlogappend)

if keyraw =118 or keyraw=108 then menu
goto gamemenu
visitorlogappend:
serout C.1, N2400,(254,1)
pause 30
do
	pause 100
loop until pinC.0=0
hi2cout [alfat],("O 1A>M:",92,"visitor log.txt",lf)
hi2cin (b12,b12,b12,b12)
serout C.1, N2400, (254,128,"initials?")
gosub getakey
serout C.1, N2400,(254,148,keyascii,".")
b13=keyascii
gosub getakey
serout C.1, N2400,(keyascii,".")
do
pause 100
loop until pinC.0=0
hi2cout ("W 1>5",lf)
pause 10
for loopcount=0 to 19
hi2cin (b12)
serout C.1, N2400, (b12)
inc cursorrow
gosub position
next loopcount
pause 1000
hi2cout (b13,".",keyascii,". ")

serout C.1,N2400, (254,192)
pause 1000
hi2cout ("C 1",lf)
pause 100
hi2cout ("C 1",lf)
for loopcount=0 to 19
hi2cin (b12)
serout C.1, N2400, (b12)
next loopcount
serout C.1, N2400, ("complete")


pause 1000
toggle b.7
goto menu

'...
getakey:                         'key detecting subroutine
	'hi2csetup i2cmaster,%01010100,i2cfast,i2cbyte  'setup i2c master with keyboard slave
	hi2cin [keyboard],0,(keycheck,keyraw,keyascii,keynum)
	'sertxd(#b23,",",#b24,cr,lf)
	if keycheck<> 1 then 
		keyraw = 0
		goto getakey						'if b0 != 1, then set received byte to 0
	else
		'sertxd ("got a key")
		hi2cout 0,(0)
	endif					'reset keyboard status byte
	if keynum=11 then powersaversetup

hi2csetup i2cmaster, alfat, i2cfast, i2cbyte
	return
The keyboard leds flash even after the freeze, so I dont think the keyboard monitering chip is the problem, so what is the error in my code??


~thanks, Patrick
p.s. for completeness here is the keyboard moniter code:
Code:
#picaxe 28x2
symbol keyraw=b0
symbol keycheck=b1
symbol keyascii=b2
symbol keynum=b3
symbol powerstate=b4
EEPROM $00,("?9?5312C?A864?'?")	' Function keys
EEPROM $10,("?????Q1???ZSAW2?")	' Main keyboard keys
EEPROM $20,("?CXDE43?? VFTR5?")
EEPROM $30,("?NBHGY6???MJU78?")
EEPROM $40,("?,KIO09??./L;P-?")
EEPROM $50,("??'?[=????",181,"]?#?") '"??'?[=?????]???")
EEPROM $60,("?",218,"????",127,"??1?",127,"7???")	' Numeric keypad keys
EEPROM $70,("0.",180,"5",126,179,"??B+3-*9??")	
startup:
'setfreq m8
put 0,0
hi2csetup i2cslave,%01010100
pause 500
'kbled %10000101			'disable LED blinking (enable capslock and scroll lock, disable numlock)

main:
	pause 300
	'sertxd("getting key ")
	kbin b0			'grab one character
	'sertxd("got key ")
	'sertxd(#b0)
	'sertxd(cr)
	get 0,b1
	if b1=1 then main		'if status=ready, discard character

	put 1,b0			'if status <> ready, store character
	read b0,b2                    'read eeprom for ascii
	put 2,b2
	select case b0     'numbers or significant commands
	case 69
		b3=0
	case 22
		b3=1
	case 30
		b3=2
	case 38
		b3=3
	case 37
		b3=4
	case 46
		b3=5
	case 54
		b3=6
	case 61
		b3=7
	case 6
		b3=8
	case 70
		b3=9
	'case 63                    'sleep button
	'	powerstate=1
	'	b3=11                'sleep command on master
	'case 94                       'wake up button
	'	high A.3
	'	powerstate=0
	'	b3=12
	'	pause 500
	'	low A.3
	else
		b3=10
	endselect
	put 3,b3
	put 0,1			'update status=ready
	pause 400
	'debug
	goto main
 

inglewoodpete

Senior Member
Tips on debugging

I have downloaded your main code and had a look at it in my PE.

Structured as it is, I find your code quite hard to follow. I could, of course, but I have other things I want to do. Mapping out a flow diagram for someone else is not what I want to do with my time.

Once a program gets to the level of complexity of yours, the best I can do is offer some tips on how to make the program easier for you and others to read. If it easier to read, it is usually easier to debug. You are already doing some of what I have to suggest, so please don't take what I suggest as criticism.

  • Use indentation but reduce the size of the <tabs>. I use <tabs> of 3 spaces. Where you use labels, indent the code under it. That makes the labels stand out more.
  • Indent looping structures: Do and Loop, For and Next are easier to read and understand if the code between the 'pairs' of commands are indented too. Looping structures are the usual places for programs to appear to 'freeze'.
  • Avoid the use of 'GoTo' statements. It is far easier to read code that uses more looping structures, block If-Then-Else structures and Select Case structures.
  • Use more comments. It helps others understand what the program is doing. And it will help you when you want to add more features in 3 months time.
  • Use more subroutines. Subroutines have 2 purposes. (1.) Allow 1 piece of code to be used from 2 or more places in a program. And (2.) Allow functional blocks of code to be moved out of your main loop. I note that you are doing this already:).
When debugging, use the SerTxd command. I can see that you have been using the SerTxd already:). When your program appears to freeze, it it probably just 'stuck' in a loop somewhere with a combination of register values that you did not anticipate. Temporarily insert SerTxd commands where ever you think your program could be getting stuck. I use commands like 'SerTxd("#")', 'SerTxd("@")', 'SerTxd("$")', 'SerTxd("%")' around my programs in these situations to see where the holdups are. Once I know the problem area, I replace the SerTxd with something like 'SerTxd(#b3, " ") to show what is (or is not) happening in a particular register.

Stick with it. With persistance, you will find the problem.
 

nick12ab

Senior Member
I've found that using background i2c slave mode at the same time as some other communications protocol ('hardware' or otherwise) that the PICAXE can freeze up and that the only way to avoid this is to bit-bang the interface with pauses and high/lows (for output) or let bitx = pinx (for input).
 

pleiser

Senior Member
@nick12ab I don't think the slave/keyboard monitor is frozen (at least not completely), because the keyboard's LEDs still blink after freezing.
@buzby I will try that when I get home (my mom decided we would go skiing today,we just left). Would that cause a problem mid program, after it had been operating for a while (not always at the same point)?

~Patrick
 

inglewoodpete

Senior Member
I will try that when I get home (my mom decided we would go skiing today,we just left). Would that cause a problem mid program, after it had been operating for a while (not always at the same point)?
It is very unlikely that you will get an i2c lockup in a PICAXE configured as a slave, especially if it has successfully booted up. Having said that, there could be problems if your i2c bus badly wired (eg dry joints).

I hope you enjoyed your skiing. The closest ski-able snow to where I live is about 3,000 km (2,000 mi) away.

Grown-ups often have no idea of kids priorities;). -Peter, father of 2 teenagers.
 

pleiser

Senior Member
Code:
#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#0#0#0#255#255#255#255#255#255#255#255@#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255!#0#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#25512222222222222222222233333333333333333333#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255@#0#0#0#0#0#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255!#0#0#0#0#0#0
@inglewoodpete: Yes, I did enjoy skiing :D, it is ~1.5 hours away, not too far :). Above is the result of a sertxd with below code (relevant parts)
Code:
visitorlogappend:
serout C.1, N2400,(254,1)
pause 30
do
	pause 100
loop until pinC.0=0
hi2cout [alfat],("O 1A>M:",92,"visitor log.txt",lf)
hi2cin (b12,b12,b12,b12)
serout C.1, N2400, (254,128,"initials?")
[U][B]sertxd("@")[/B]
gosub getakey
serout C.1, N2400,(254,148,keyascii,".")
[B]sertxd ("!")[/B]
b13=keyascii
gosub getakey
serout C.1, N2400,(keyascii,".")[/U]
do
pause 100
[B]sertxd("1")[/B]
loop until pinC.0=0
hi2cout ("W 1>5",lf)
pause 10
for loopcount=0 to 19
hi2cin (b12)
serout C.1, N2400, (b12)
inc cursorrow
gosub position
[B]sertxd ("2")[/B]
next loopcount
pause 1000
hi2cout (b13,".",keyascii,". ")

serout C.1,N2400, (254,192)
pause 1000
hi2cout ("C 1",lf)
pause 100
hi2cout ("C 1",lf)
for loopcount=0 to 19
hi2cin (b12)
serout C.1, N2400, (b12)
[B]sertxd("3")[/B]
next loopcount
serout C.1, N2400, ("complete")


pause 1000
'toggle b.7
goto menu
'....
getakey:                         'key detecting subroutine
	'hi2csetup i2cmaster,%01010100,i2cfast,i2cbyte  'setup i2c master with keyboard slave
	hi2cin [keyboard],0,(keycheck,keyraw,keyascii,keynum)
	'sertxd(#b23,",",#b24,cr,lf)
	if keycheck<> 1 then 
		keyraw = 0
		[B]sertxd ("#",#keycheck)[/B]
		pause 100
		goto getakey						'if keycheck != 1, then set received byte to 0
	else
		'sertxd ("got a key")
		hi2cout 0,(0)
	endif					'reset keyboard status byte
'	if keynum=11 then powersaversetup

hi2csetup i2cmaster, alfat, i2cfast, i2cbyte
	return
as you can see the slave returned 255 for the check value most of the time (presumably while waiting for the keyboard) then 0 a few times (presumably before updating the status marker) then it continued to the main code and went through those loops, when the sertxd stopped (i did not stop/ turn off the picaxe) there were no i2c reads, failed or otherwise, eliminating the keyboard as the problem. also it always freezes in the area of code underlined (based on output to display) any other ideas of the solution or next step?
 

inglewoodpete

Senior Member
With very few comments in your code, it is very difficult for others to guess what you expect to happen.

I suggest that you slow the i2c signalling down while debugging. Once you have everything debugged, then you can try speeding the bus up again. The bus must run at the speed of the slowest slave: otherwise the slowest slave can get confused at any time and mess the bus up. If you are running the 28X2 at its default speed (8MHz), then use i2cSlow_8. With the 28X2 still running at 8MHz, you can also try using i2cSlow_16, which will run the bus at half the slow speed. If there are i2c signalling problems, this usually sorts them out.

Are you saying that the logging output stops 'dead' at the end of the logging you posted: #255#255!#0#0#0#0#0#0 ?
 

inglewoodpete

Senior Member
First, try slowing the i2c bus down and see what happens.

Also, add in more "SerTxd" commands where you (or I) think something is happening:

Code:
getakey:                         'key detecting subroutine
	'hi2csetup i2cmaster,%01010100,i2cfast,i2cbyte  'setup i2c master with keyboard slave
	hi2cin [keyboard],0,(keycheck,keyraw,keyascii,keynum)
	'sertxd(#b23,",",#b24,cr,lf)
	if keycheck <> 1 then 
		keyraw = 0
		sertxd ("#",#keycheck)
		pause 100
		goto getakey						'if keycheck != 1, then set received byte to 0
	Else
		'sertxd ("got a key")
		SerTxd("+")
		hi2cout 0,(0)
	endif					'reset keyboard status byte
	'	if keynum=11 then powersaversetup
	
	SerTxd("$")
	hi2csetup i2cmaster, alfat, i2cfast, i2cbyte
	SerTxd("-")
	return
 

pleiser

Senior Member
when adding the sertxd and a pause 100 (preventing the sertxd from flooding the terminal) I couldn't get the program to freeze after (according to the sd card) ~130 trials :) I tried removing the sertxdand it still worked, so it looks like I have solved the problem and will be leaving the pause 100 command in the program. :) :D
 
Top