How to time interval between event in lua - lua

I am writing a simple script in lua. If the LED is on, it will increment the counter by 1. If the led is off for more than 1 seconds, it reset the counter.
So how exactly do we time event like that in lua ?
This is what i have and been testing multiple ways so far.
function ReadADC1()
local adc_voltage_value = 0
adc_voltage_value = tonumber(adc.readadc()) * 2 -- 0.10 --get dec number out of this -- need to know where package adc come from
--convert to voltage
adc_voltage_value = adc_voltage_value *0.000537109375 --get V
adc_voltage_value = math.floor(adc_voltage_value *1000 +0.5) --since number is base off resolution
--print (adc_voltage_value)
return adc_voltage_value
end
-- end of readADC1() TESTED
function interval()
local counter1 =0
ledValue = ReadADC1()
if (ledValue >= OnThreshHold) then
ledStatus = 1
t1=os.time()
else
ledStatus = 0
t2 = os.time()
end
--counter1 =0
for i=1,20 do
if (ledStatus == 1) then -- if led is off for more than 1 second, reset counter = 0
counter1 = counter1 + 1
elseif ((ledStatus ==0 and ((os.difftime(os.time(),t2)/100000) > 1000))) then -- increment counter when led is on
counter1 = 0
end
end
print (counter1)
end
I know for sure the logic for interval is wrong since os.time return a huge number (i assume it in psecond instead of second).
Any suggest or solution is welcome. I tried vmstarttimer and vmstoptimmer before this but not sure how it work.
EDIT:
function counter()
local ledValue = ReadADC1()
local t1 = os.clock()
while true do
local t2 = os.clock()
local dt = t2 - t1
t1 = t2
if ((ledValue < OnThreshHold) and (dt < 1)) then -- if led is off for less than 1 second
ledCounter = ledCounter + 1
elseif ((ledValue < OnThreshHold) and (dt > 1)) then-- if led is off for more than 1 second
ledCounter = 0;
else
ledCounter = ledCounter
end
print (ledCounter)
end
end
Ultimately, it will be return ledCounter instead of print counter since I will plug the value of counter to another function that will print a message correspond to the number of counter

You could use os.clock which returns your programs runtime since start in seconds.
Returns an approximation of the amount in seconds of CPU time used by the program.
Source
This function could be used in this way.
local t1 = os.clock() -- begin
local t2 = os.clock() -- end
local dt = t2 - t1 -- calulate delta time
-- or looped
local t1 = os.clock() -- begin
while true do
local t2 = os.clock() -- end
local dt = t2 - t1 -- calulate delta time
t1 = t2 -- reset t1
-- use dt ...
end
-- or wait for time elapsed
-- runs until 1 second passed
local t1 = os.clock()
while (os.clock() - t1) < 1 do
-- do stuff while dt is smaller than 1
-- could even reset timer (t1) to current to
-- repeat waiting
-- t1 = os.clock() | ...
end
-- logic for your example
function counter()
local time = os.clock()
local lastLedOn = false
local counter = 0
while true do
if os.clock() - time > 1.0 then
break
end
if getLedValue() == on then -- replace
time = os.clock()
if not lastLedOn then
lastLedOn = true
counter = counter + 1
-- print(counter) | or here if you want to print repeatedly
end
end
end
print(counter)
end -- was unable to test it

Related

Lua function returning error after false "if statement"

I have a function to move a point over to different positions. I have a positions table containing all the Xs and Ys of each position, a position counter (posCounter) do keep track of where the point is and a maxPos, which is pretty much the lenght of the table positions.
In this code snippet, everything after if posCounter <= maxPos then shouldn't run if the posCounter variable is greater than 3, but I still get an error for exceeding the table's limit.
local maxPos = 3
local posCounter = 1
local function movePointToNext( event )
if posCounter <= maxPos then
posCounter = posCounter + 1
transition.to( pointOnMap, { x = positions[posCounter].x, y = positions[posCounter].y } )
end
end
if posCounter <= maxPos then
posCounter = posCounter + 1
What happens if posCounter == maxPos? Your if executes, then you increment it, so it is too big (equal to maxPos + 1), and then you try to index with it, thus giving you an error.
You either want to change your if to stop at posCounter == maxPos - 1, so that after incrementing it still is correct; or you want to move your increment after indexing with it (depending on what is the intended behaviour of your code).
option 1
local maxPos = 3
local posCounter = 1
local function movePointToNext( event )
if posCounter < maxPos then
posCounter = posCounter + 1
transition.to( pointOnMap, {
x = positions[posCounter].x,
y = positions[posCounter].y } )
end
end
option 2
local maxPos = 3
local posCounter = 1
local function movePointToNext( event )
if posCounter <= maxPos then
transition.to( pointOnMap, {
x = positions[posCounter].x,
y = positions[posCounter].y } )
posCounter = posCounter + 1
end
end

How to run code whenever a value reaches a multiple of 50 in lua

Pretty simple, dont really have any code to give but just as an example:
local n = 0
local clock = os.clock
function sleep(n)
local t0 = clock()
while clock() - t0 <= n do end
end
while True do
sleep(1)
n = n + 1
(code to run when 'n' is a multiple of 50)
print("n is a multiple of 50")
end
Pretty simple, Any help appreciated!
not to wait for a long time, I took a small values:
local function sleep (a)
local sec = tonumber(os.clock() + a)
while os.clock() < sec do
end
end
local n = 0
while true do -- true~=True
sleep(1)
n = n + 1
print(n)
if n%5==0 then
print(n," - n is a multiple of 5")
end
if n>=10 then break end
end
and more: you need to wait for the result, when the script finishes working, such a feature of the Lua interpreter.

Rate limiting with lua

We have implemented redis based rate limiting for our web service which has been taken from here. I am duplicating the relevant code here.
local limits = cjson.decode(ARGV[1])
local now = tonumber(ARGV[2])
local weight = tonumber(ARGV[3] or '1')
local longest_duration = limits[1][1] or 0
local saved_keys = {}
-- handle cleanup and limit checks
for i, limit in ipairs(limits) do
local duration = limit[1]
longest_duration = math.max(longest_duration, duration)
local precision = limit[3] or duration
precision = math.min(precision, duration)
local blocks = math.ceil(duration / precision)
local saved = {}
table.insert(saved_keys, saved)
saved.block_id = math.floor(now / precision)
saved.trim_before = saved.block_id - blocks + 1
saved.count_key = duration .. ':' .. precision .. ':'
saved.ts_key = saved.count_key .. 'o'
for j, key in ipairs(KEYS) do
local old_ts = redis.call('HGET', key, saved.ts_key)
old_ts = old_ts and tonumber(old_ts) or saved.trim_before
if old_ts > now then
-- don't write in the past
return 1
end
-- discover what needs to be cleaned up
local decr = 0
local dele = {}
local trim = math.min(saved.trim_before, old_ts + blocks)
for old_block = old_ts, trim - 1 do
local bkey = saved.count_key .. old_block
local bcount = redis.call('HGET', key, bkey)
if bcount then
decr = decr + tonumber(bcount)
table.insert(dele, bkey)
end
end
-- handle cleanup
local cur
if #dele > 0 then
redis.call('HDEL', key, unpack(dele))
cur = redis.call('HINCRBY', key, saved.count_key, -decr)
else
cur = redis.call('HGET', key, saved.count_key)
end
-- check our limits
if tonumber(cur or '0') + weight > limit[2] then
return 1
end
end
end
I am trying to figure out the meaning of the comment -- don't write in the past
I don't see how a case would be possible where old_ts is greater than now
I have put logs all over the lua code but without any success.
At maximum old_ts can be equal to saved.trim_before which in turn can be equal to now if precision is 1 and blocks is 1. But not greater .
It would be helpful if someone has insights on it.
If you look at the gist provided in the article
https://gist.github.com/josiahcarlson/80584b49da41549a7d5c
There is comment which asks
In over_limit_sliding_window_lua_, should
if old_ts > now then
at here be
if old_ts > saved.block_id then
And I agree to this, the old_ts is supposed to have the bucket and when the bucket jumps to the next slot, that is when old_ts will be greater then than the block_id

How to have currentMilis and previousMillis like arduino in Lua script

I am writing an extremely simple script in Lua using simcom GPU.
It will count how many times a led flashing and return a string correspond to counter number. So far i have using os.clock() to do the job but the result is not as I expected.
function counter()
local t1 = os.clock()
while (ReadADC1() > 98) do
local t2 = os.clock()
local dt = t2 - t1
t1 = t2
local ledValue = ReadADC1()
if ((ledValue >= OnThreshHold) and (dt < 1)) then -- if led is on for less than 1 second
ledCounter = ledCounter + 1
--vmsleep(100)
elseif ((ReadADC1() < OnThreshHold) and (dt > 2.3)) then-- if led is off for more than 2 second
ledCounter = 0;
--vmsleep(100)
else
ledCounter = ledCounter
end
--print (ledValue,"\r\n")
end
print(ledCounter,"\r\n")
--return ledCounter
end
For this case, if i use this counter() function, it only work if the value from ReadADC() is input for short time then stop. It wont work if adc read continuously flow of data.
In arduino, the solution is extremely easy since you can use currentmillis and previousMillis to determine time pass between flashes. So in lua, do we have anything similar ?

Table value doesn't change

I have a 2 dim array and all it's cells filled with zeros.
What i'm trying to do is to take some randomly chosen cells and fill it with 4 or 5
but what i get is either empty gird with all value equal to zero or i get just one value that has changed to 4 or 5 and that's my code below:
local grid = {}
for i=1,10 do
grid[i] = {}
for j=1,10 do
grid[i][j] = 0
end
end
local empty={}
for i=1,10 do
for j=1,10 do
if grid[i][j]==0 then
table.insert(empty,i ..'-'.. j)
end
end
end
local fp=math.floor(table.maxn(empty)/3)
local fx,fy
for i=1,fp do
math.randomseed(os.time())
math.random(0,1)
local fo=math.random(0,1)
math.random(table.maxn(empty))
local temp= empty[math.random(table.maxn(empty))]
local dashindex=string.find(temp,'-')
fx=tonumber(string.sub(temp,1,dashindex-1))
fy=tonumber(string.sub(temp,dashindex+1,string.len(temp)))
if fo==0 then
grid[fx][fy]=4
elseif fo==1 then
grid[fx][fy]=5
end
end
for i=1,10 do
for j=1,10 do
print(grid[i][j])
end
print('\n')
end
I'm not sure what the for i=1,fp loop is doing with temp and fo, for example the seed should only be set once, and also, the return value on line after local fo is ignored, seems very messy. But based on your post, if you really just want to randomly select N cells from your 2D array and set those to either 4 or 5 (randomly), this should work:
-- maybe N = fp
local N = 5
math.randomseed(os.time())
local i = 1
repeat
fx = math.random(1, 10)
fy = math.random(1, 10)
if grid[fx][fy] == 0 then
grid[fx][fy] = math.random(4,5)
i = i + 1
end
until i > N
Note however that the closer N is to number of items in array (100 in your example), the longer it will take for the loop to complete. If this is a concern, then for large N values, you could do the opposite: initialize each cell to 4 or 5 randomly, and then randomly set size - N of them to 0.
math.randomseed(os.time())
local rows = 10
local columns = 10
local grid = {}
if N > rows*columns/2 then
for i=1,rows do
grid[i] = {}
for j=1,columns do
grid[i][j] = math.random(4,5)
end
end
local i = 1
repeat
fx = math.random(1, 10)
fy = math.random(1, 10)
if grid[fx][fy] ~= 0 then
grid[fx][fy] = 0
i = i + 1
end
until i > N
else
for i=1,rows do
grid[i] = {}
for j=1,columns do
grid[i][j] = 0
end
end
local i = 1
repeat
fx = math.random(1, 10)
fy = math.random(1, 10)
if grid[fx][fy] == 0 then
grid[fx][fy] = math.random(4,5)
i = i + 1
end
until i > N
end

Resources