Loop sound but check byte value and exit on certain value?

rs2845

Senior Member
Hi there,

Still working on my fire alarm system. Hit a wall with the core "Sound Alarms" function.

Basically I am wanting to activate a beeping sound every 200ms when the "Sound Alarms" hex value is received by my picaxe. I've successfully made a loop to repeat the buzzer sound but I am wanting the loop to also perform a SERIN and IF statement. Just after the buzzer beeps I need the picaxe to find out if the silence button has been pressed and if it has, go to "SilenceAlarms" (set in my program) but if not, it should continue with the beeping. I have provided all my code, but the section with the problem is "SoundAlarms"; and my issue is that with my attempts the buzzer beeps once and the program hangs until I touch my LCD, where it beeps again- I think it has something to do with my IF statement, never quite managed to use the ELSEIF or other syntax.

Code:
#picaxe 40x2
#com 3
setfreq em64

'Symbols
symbol buzzer = B.7
symbol zone1 = B.6
symbol zone2 = B.5
symbol zone3 = B.4
symbol zone4 = B.3
symbol zone5 = B.2
symbol zone6 = B.1
symbol zone7 = B.0
symbol zone8 = D.7
symbol zone9 = D.6
symbol zone10 = D.5
symbol zone11 = D.4
symbol zone12 = C.7
symbol zone13 = C.6
symbol zone14 = C.5
symbol zone15 = A.5'C.4
symbol zone16 = D.3


symbol fireLED = D.1
symbol powerLED = D.0
symbol faultLED = A.6
symbol testLED = C.2
symbol disablementLED = C.1
symbol sysfltLED = C.0

symbol lcdtx = D.2
symbol lcdrx = A.7

start0:'     Scans the LCD continuously and jumps to relevant section of menu in 'Start1'
serin A.7,N4800,($AA,$78),b17,b18',b19,b20,b21,b22,b23
debug

'****Display Test****
     IF b18= $16 THEN GOTO HighTestLED : IF B18 = $FD OR B18 = $FE THEN GOTO LowTestLED
     IF b18= $51 THEN GOTO StatusLEDTest
     IF b18= $52 THEN GOTO ZoneLEDTest
     IF b18= $54 THEN GOTO buzzertest
     IF b18= $55 THEN GOTO LCDTest


'****Critical Events****
     IF B18 = $06 OR B18 = $08 OR B18 = $60 THEN GOTO ActiveEvents
     IF B18 = $17 THEN GOTO SoundAlarms
     IF B18 = $19 THEN GOTO SilenceAlarms
     IF B18 = $1B THEN GOTO ResetSystem
     IF B18 = $11 THEN GOTO BuzzerCancel
goto start0


start1:
'Nothing goes in here yet!
goto start1 

SoundAlarms: 'Sound alarms on system 
     High FireLED ' defined at top of program B.7
     Do 'Start buzzer beeping
        sound B.7,(123,50)        
                pause 200
        serin A.7,N4800,($AA,$78),b17,b18 : IF B18 = $19 THEN GOTO SilenceAlarms : IF B18 <> $19 THEN EXIT
     Loop ' go back to start of loop

Goto SoundAlarms

SilenceAlarms:
     low FireLED
goto start0 '(start0 is a loop of the above used serin command)
For the system to go to the SilenceAlarms b18 = $19 and if not, continue the loop for the beeping.

What am I doing wrong? Sorry if this seems really dumb.
 

inglewoodpete

Senior Member
You are using a 40X2 for your project so it makes it much simpler to do many things at once.

I'd use background receive for the incoming serial data (hSerial commands) and a 100mS background timer with interrupts counting multiples of the 100mS ticks. The beeper can then be turned on and of without any killer "Pause" statements.

I'm not sure what you mean be "touch my LCD", though. Is it a touch screen or does it have on-board input button switches?
 

rs2845

Senior Member
Ah I was going to use HSerin but thought I'd make it simple to use normal serial in. Turns out that I should've used it!

When you say use an interrupt for the 100ms repetitions, how would I even implement this? I've never used hserial or interrupts before.

I know I'd have to change my hardware configuration for a hardware serial in line but in terms of software- I haven't a clue!

Ah yes it is a touchscreen LCD and upon pressing certain regions on my screen's menu, a specific hex command is returned (which I have predefined for each button)
 

Technical

Technical Support
Staff member
hserin is better, but you could also use a timeout on this line:


serin A.7,N4800,($AA,$78),b17,b18

At the moment it gets 'stuck' here until the next valid serin occurs. You can use a timeout to prevent this serin becoming a blocking command.
 

inglewoodpete

Senior Member
Sample Background Timer Program - 20X2, 28X2 or 40X2

The following program demonstrates how the background timer of X2 (or X1) PICAXE Models can be used to generate interrupts.

The interrupts can be counted to make a simple timer that, in this case, flashes an LED "in the background" and does not interfere directly with the main loop's operation. Of course, the interrupt periodically steals a small amount of time from the main program. In most situations, this is unnoticable.

The main benefit for this style of timer is that it can be started and then forgotten. If you replace the LED with a beeper, you would get a continuous stream of beeps. You may want to use another bit of the Timer Status byte rTimerStatus to enable and disable the beeper without stopping and starting the timer itself.

Code:
' Demonstration program to use background interrupts to create a (background) 100mS clock
' A simple counter is added with an On/Off Flag to allow differing On and Off Periods
' Program and timer assumes that the default 8MHz processor clock speed is used.
' The output pin for oLED can be redefined to suit other hardware arrangements
' LED On and Off periods can be changed by altering the definitions of cOnCount & cOffCount
' Written by inglewoodpete  01-Jan-2013 Tested on the AXE401 PICAXE28X2 Shield
'
#PICAXE 28X2
#No_Table                        'No need to download table of EEPROM Data in this demonstration
'
' **** Hardware Definitions
'
Symbol oLED0            = C.3    'Output pin with LED/Resistor combination (Also called S.13 on the shield)
'
' **** Register definitions
'
Symbol bTimerStatus     = b0     'b0 can be used for other purposes: Timer Status is preserved in RAM
Symbol b100mSCount      = b55    'Ticks at background timer rate up to 1 second, then is reset
'
' **** Timer status/control bits - All bits of b0
Symbol tTimerPointer    = bit7   'Either On_timer or Off_timer
'
' **** Standard Definitions
'
Symbol False            = 0
Symbol True             = 1
'
' **** Timer Constants
'
Symbol cOffTimer        = 0           'Flag bit value
Symbol cOnTimer         = 1           'Flag bit value
'
Symbol cOnCount         = 2           '2 * 100mS = 200mS On period
Symbol cOffCount        = 5           '5 * 100mS = 500mS Off period
'
Symbol mskBGTimer       = %10000000   'When only the timer is used here
Symbol flgBGTimer       = %10000000   'When only the timer is used here
Symbol tmrIntOn1stTick  = 65535       'Interrupt to be caused by roll over on first major tick
Symbol tmr100mS_8       = 62411       '100mS @ 8MHz = 65536 - (Treq * 1,000,000 / Clk / 256)
'
' **** RAM Allocation - Note that bytes 0 to 55 are used for byte registers b0 to b55 *****
'
Symbol rSaveRegsForInt  = 56   '57&58 Store for 2 byte registers when using Interrupt routine.
Symbol rTimerStatus     = 57   'Contains bit flags for software timers: tTimerMode; tTimerPointer
'
' **** Initialisation ***********************************************************
'
Init: 'The following code starts the background timer which then runs continuously
      TOFlag = False
      Timer = tmrIntOn1stTick                    'Interrupt after 1 tick
      SetTimer tmr100mS_8                        'Expires after 100 milliseconds
      SetIntFlags flgBGTimer, mskBGTimer         'Set timer 0 to interrupt
'
' **** Main Loop ****************************************************************
'
      Do
         'Add your own code here to run in the foreground
      Loop
'
' **** Interrupt Handler ********************************************************
'
Interrupt:If TOFlag = True then
            ' Only the timers are handled here
            Poke rSaveRegsForInt, b0            'b0 Preserve variables
            '                                     - whatever happened to be in the registers at the time
            Peek rTimerStatus, bTimerStatus     'Fetch the timer status byte
            If b100mSCount = 0 Then             '100 milliseconds have passed
               If tTimerPointer = cOffTimer Then'Off time expired: turn relay on
                  tTimerPointer = cOnTimer      'Swap to other timer
                  b100mSCount = cOnCount        'Initialise 'on' period
                  High oLED0                    'Turn LED 0 On
               Else                             'On time expired: turn relay off
                  tTimerPointer = cOffTimer     'Swap to other timer
                  b100mSCount = cOffCount       'Initialise 'on' period
                  Low oLED0                     'Turn LED 0 On
               EndIf
               Poke rTimerStatus, bTimerStatus
            EndIf 
            Dec b100mSCount
            Poke rTimerStatus, bTimerStatus     'b0 Preserve the timer bits
            '
            Timer = tmrIntOn1stTick             'Reset the timer
            SetIntFlags flgBGTimer, mskBGTimer  'Set timer 0 to interrupt
            TOFlag = False                      'Clear the flag
            '
            Peek rSaveRegsForInt, b0            'Restore variables
         Else
            SerTxd("o")                         'Interrupt other than a timer interrupt
         EndIf
         Return
'
' *******************************************************************************
 
Top