General area when it fits no where else

Moderator: Mmiscool

User avatar
By ardhuru
#49100 Hi,

I have a program in which there are 3 things to be done;

1) Keep flashing an LED independently
2) Send a UDP reply ("open" / "closed") depending on the state of a pin and
3) Receive a character over UDP and send the same back as an acknowledgement to the sender.

The attached code starts of working fine, but a few characters later (random, no pattern noticed) the ESP does not ping back the received characters. At this point, the switch reading the pin is still working, and transmitting back the pin status, whenever it changes. The LED is also flashing as it should be.

Its only the UDP characters that are not being received (accepted) by the ESP.

I have tested this with Ciccio's UDP debugger as well as an Android UDP sender/receiver.

Code: Select allrelay = 0 'Relay on gpio.0
led = 2 'Led on gpio.2
switch = 3 'Door switch on gpio.3
io(po,relay,0)

pwd = read.val("myfile")
udpbegin 5001

interrupt 3, [shutter]

timer 1500, [blipLED]

[begin]

udpbranch [udpreceived]
wait

[udpreceived]
let msg = udpread()
UDPREPLY msg   'Acknowledge BACK to sender
delay 100           'for keypad beeps
goto [begin]

return
end

[blipLED]
io(po,led,1)
delay 1
io(po,led,0)
wait

[shutter]
if io(laststat,3) == 1 then UDPREPLY "open" else UDPREPLY "closed"
wait


I'm sure I'm doing a number of wrong things here, but cant really figure out what.

Any help would be highly appreciated, folks!

Regards.
User avatar
By Electroguard
#49101 Remember what I said before, don't repeat the code for 'interrupty' things ... so move the udpbranch [udpreceived] line up above your [begin] branch that you keep returning to (or replace the [udpreceived] goto [begin] with a wait).
This will prevent your branch on udp interrupt 'udpbranch [udpreceived]' from keep being re-assigned after every received udp msg. If you are going to repeatedly return to [begin] after udp interrupts you might as well be consistent and return there to wait from the other interrupt branches as well.

Code: Select allrelay = 0 'Relay on gpio.0
led = 2 'Led on gpio.2
switch = 3 'Door switch on gpio.3
io(po,relay,0)
pwd = read.val("myfile")
udpbegin 5001
udpbranch [udpreceived]
interrupt 3, [shutter]
timer 1500, [blipLED]
'end of one-off definitions

[begin]
' just a quiet place to return to and wait for interrupts!
wait

[udpreceived]
let msg = udpread()
UDPREPLY msg   'Acknowledge BACK to sender
delay 100           'for keypad beeps
goto [begin]

[blipLED]
io(po,led,1)
delay 1 ' (blink and you miss it!)
io(po,led,0)
goto [begin]

[shutter]
if io(laststat,3) == 1 then UDPREPLY "open" else UDPREPLY "closed"
goto [begin]
User avatar
By ardhuru
#49111 Okay, I get the idea now (I think!).

I tried your edited version, and the flashing and switch polling works flawlessly.

BUT, only the first cycle of UDP receive works? Doesnt seem to receive anything after that.
User avatar
By Electroguard
#49139 I had only edited your script, not tried it - you had no return from udp interrupt.
The help text below explains that you need to initially define your udp interrupt branch (in much the same way as you do for timer or interrupt) rather than repeatedly call it.
In the case of udp, on receipt of a udp msg it will branch to the specified pre-defined branch, but then looks for a 'return' command to return back to where it was interrupted from.
I've added the required return instruction into your [udpreceived] branch. I've also changed your udpreply msg slightly so that you can see it is now working ok.

UdpBranch:
Define a branch label defining the place where the program will continue as soon as an UDP message is received. As soon as the return command is found, the program will continue from the interrupted point.

Example:
Udpbegin 4567
udpbranch [udp.received]
wait

[udp.received]
let rec = udpread()
let rem = udpremote()
Serialprint “Message received “ & rec & “ from “ & rem
udpreply “OK”
return



Code: Select alllet relay = 0 'Relay on gpio.0
let led = 2 'Led on gpio.2
let switch = 3 'Door switch on gpio.3
io(po,relay,0)
'pwd = read.val("myfile")
udpbegin 5001
udpbranch [udpreceived]
interrupt 3, [shutter]
timer 1500, [blipLED]

[begin]
' just a quiet place to return to and wait for interrupts!
wait

[udpreceived]
let msg = udpread()
UDPREPLY "Received=" & msg   'Acknowledge BACK to sender
delay 100           'for keypad beeps
return

[blipLED]
io(po,led,1)
delay 1 ' (blink and you miss it!)
io(po,led,0)
goto [begin]

[shutter]
if io(laststat,3) == 1 then UDPREPLY "open" else UDPREPLY "closed"
goto [begin]


It might help to understand the udp logic and program flow if you remember that the udpbranch is branching on interrupt when a udp msg is received, and interrupts work by pushing the currently interrupted program pointer onto a stack in memory so that it can remember where to return to after the interrupt has been serviced, after which it pulls the saved address back from the stack and returns to it... but if for some reason you don't keep balancing out the interrupt pushes with corresponding pulls but branch off somewhere else instead of 'returning', then you will just keep interrupting your interrupts and pushing ever more addresses until you eventually run out of stack space and the program crashes.