PDA

View Full Version : Timer Event in Serial Response



dsmes
March 19th, 2007, 06:28 PM
I want to record the phone numbers being dialed out and have a serial device that tells me what touch-tones it hears being dialed. I am using the serial.Classes.Simple2:New device driver and in the ReceiveResponse function I gather the tones in a table like this:
local _, _, tone = string.find(self.data, "B1 Tone=([%d%*#])")
print("==+++++ Tone is "..tone)
self.Phone.Tone.now = os.time()
------ No new tones for 3 seconds means a new set of tones is being received
if self.Phone.Tone.now - self.Phone.Tone.previous > 3 then
self.Phone.Tone.Dialed[self.Phone.Tone.DialCount] = {}
local item = self.Phone.Tone.Dialed[self.Phone.Tone.DialCount]
item.time = os.date('*t')
item.ToneCount = 1
item.Tones = {}
item.Tones[item.ToneCount] = tone
item.ToneCount = item.ToneCount + 1
else -- Tones being received are part of same phone number being dialed
local item = self.Phone.Tone.Dialed[self.Phone.Tone.DialCount]
item.Tones[item.ToneCount] = tone
item.ToneCount = item.ToneCount + 1
end
self.Phone.Tone.previous = self.Phone.Tone.now
if t then
t:Destroy()
t = nil
end
t = gir.CreateTimer("", "self:ToneDone(self.data)", "", false)
t:Arm(5000) -- 5 secondsWhat I'm trying to do in the last few lines is call a "finish up" function when tones stop being received. Here's the problem- The function called within the CreateTimer throws this error when called:
Timer (pcall): [string "Timer/OnTrigger"]:1: attempt to index global `self' (a nil value)
For reference, here is ToneDone function within the serial driver:
ToneDone = function(self, data)
local item = self.Phone.Tone.Dialed[self.Phone.Tone.DialCount]
item.Number = table.concat(item.Tones)
self.Phone.Tone.DialCount = self.Phone.Tone.DialCount + 1
t:Destroy()
t = nil
end,I'm obviously doing something wrong within the timer. Any ideas? Alternatively, is there a better way to accomplish what I'm after?

Rob H
March 20th, 2007, 01:31 AM
The problem is that you're passing a string to CreateTimer - try


local data = self.data
t = gir.CreateTimer("", function() self:ToneDone(data) end, "", false)

dsmes
March 20th, 2007, 03:03 AM
Thanks Rob! Works great!

Question- Why is it proper to pass a string in this example (from Girder help)?
t = gir.CreateTimer("", "print('now!')", "", true)

Rob H
March 20th, 2007, 05:28 AM
It's fine there because timer functions run in a global context. In your original example however there is no global variable called self.