Situation:
I want to save the record of a data which is a value of the sensor in the certain file.
Code is..
--Header file
require("TIMER")
require("IPBOX")
require("ANALOG_IN")
require("LOG")
function OnExit()
print("Exit code...do something")
end
function main()
timer = "Timer"
local analogsensor_1 = "AIR_1"
local analogsensor_2 = "AIR_2"
local timestr = os.data("%Y-%m-%d %H:%M:%S")
-- open the file for writing binary data
local filehandle = io.open("collection_of_data.txt", "a")
while true do
valueOfSensor_1 = ANALOG_IN.readAnalogIn(analogsensor_1);
valueOfSensor_2 = ANALOG_IN.readAnalogIn(analogsensor_2);
if (valueOfSensor_1 > 0 and valueOfSensor_2 > 0) then
-- save values of sensors
filehandle:write(timestr, " -The Value of the Sensors: ", tostring(valueOfSensor_1), tostring(valueOfSensor_2)"\n");
-- save values using rolling log appender:
LOG.log_event( ScenarioLoggerDevicenameInDeviceList, " -The Value of the Sensors: ", tostring(valueOfSensor_1), tostring(valueOfSensor_2), "any other string you wish to add", "etc", "etc")
LOG.log_event( ScenarioLoggerDevicenameInDeviceList, " -The Value of the Sensors: ", tostring(valueOfSensor_1))
print("Hello3"..valueOfSensor_1)
end
TIMER.sleep(timer,500)
end
-- close the file
filehandle:close()
end
print("start main")
main()
In this line:
filehandle:write(timestr, " -The Value of the Sensors: ", tostring(valueOfSensor_1), tostring(valueOfSensor_2)"\n");
I get an error:
"attemp to index global 'filehandle' (a nil value)"
How can I fix it?
io.open returns nil if it cannot open the file. This can be due to "file not found", "permissions denied" and maybe other reasons. To figure out the problem, io.open has a second return value, which lets you inspect the error (in fact, it even returns a third value, which is an error-code integer - but its meaning is system dependent).
Change:
local filehandle = io.open("collection_of_data.txt", "a")
to
local filehandle, message = io.open("collection_of_data.txt", "a")
if not filehandle then
print(message)
end
You can also use the following Lua idiom:
local filehandle = assert(io.open("collection_of_data.txt", "a"))
This will do the same. If the first argument to assert is nil, then the second argument (the second return value of io.open will be printed. If the first argument is not nil, it will simply be returned.
Related
I have this problem in a Lua class. Here is the code of my class:
local Temp = {}
function Temp:new(tmp)
local self = {temp = -273.15}
if tmp > self.temp then
self.temp = tmp
end
local setC = function(usrTmp)
if usrTmp < -273.15 then
self.temp = -273.15
else
self.temp = usrTmp
end
end
local getC = function()
return self.temp
end
local getF = function()
return self.temp * 1.8 + 32
end
local getK = function()
return self.temp + 273.15
end
return {
setC = setC,
getC = getC,
getF = getF,
getK = getK
}
end
return Temp
And here is my main method:
temp = require "tempClass"
io.write("Please enter the initial temperature: ")
usrTemp = io.read("*n")
myTemp = temp:new(usrTemp)
print("The current temperature in Celsius is: ".. myTemp:getC())
print("The current temperature in Fahrenheit is: " .. myTemp:getF())
print("The current temperature in Kelvin is: " .. myTemp:getK())
io.write("Please enter new temperature: ")
changeTemp = io.read("*n")
myTemp:setC(changeTemp)
print("The current temperature in Celsius is: " .. myTemp:getC())
print("The current temperature in Fahrenheit is: " .. myTemp:getF())
print("The current temperature in Kelvin is: " .. myTemp:getK())
io.write("Please enter new temperature: ")
My problem is the if usrTmp < -273.15 then line in the setC function. I'm getting this error message:
lua: ./tempClass.lua:10: attempt to compare table with number
stack traceback:
./tempClass.lua:10: in function 'setC'
[string "<eval>"]:14: in main chunk
I know, however, that usrTmp is a number. If I call type on the variable before the function, I get type number. In the function, the type is table. Why is usrTmp a table in the function? How can I fix this? Thanks!
You need to be explicit about the self parameter when defining functions that shall be used with it. The function setC should have an additional such parameter:
local setC = function(self, usrTmp)
-- as before...
end
Recall that these two invocations are identical:
myTemp:setC(changeTemp)
myTemp.setC(myTemp, changeTemp)
That should explain the actual error message your received.
In addition, you need to turn Table.new into an ordinary (not self-parameter-enhanced) function. It's not connected to an instance yet, it is supposed to return one. And finally, the state variable temp must be included in the table that Table.new returns:
function Temp.new(tmp)
-- ^ note the dot instead of the colon
-- function body as before, but all functions now need the self parameter, e.g.:
local getC = function(self)
return self.temp
end
return {
temp = self.temp,
setC = setC,
getC = getC,
getF = getF,
getK = getK
}
end
i'm new in progamming and starting with few basics tips. So my problem is: i'm trying to run a code that ask user a name and print it on screen, its run ok. So i'm trying to do something special now adding to code a part that ask the user how many times the name will be printed on screen, but when i do that it start a infinite loop and won't stop until i close the progam.
Here its the code
function metodoDois()
print("Write a name: ")
name = io.read();
print("Write how many times that it will be printed on screen: ")
quantidade = io.read()
k = 0;
while name do
k = k+1;
io.write("\n", name, " ", k)
if k == quantidade then
name = not name;
end
end
end
metodoDois()
Usually, to repeat a computation a known number of times, it is used a for loop. So, if you do not have specific reasons to use a while loop, you could go with:
function metodoDois()
print("Write a name:")
local name = io.read()
print("Write how many times that it will be printed on screen:")
local quantidade = io.read()
for k = 1, quantidade do
io.write("\n", name, " ", k)
end
end
metodoDois()
This way, you avoid explicitly creating the control variable k and to perform a test at each iteration in order to asses when to end it. In fact, the control variable k in the for-loopis automatically updated at each iteration, letting the loop end when such variable gets its final value.
Moreover, k is local to the for-loop (i.e., it doesn't exist before or after it), making the code more readable and less error prone (see: Local Variables and Blocks in the Lua Reference.)
The problem is your "quantidade" variable is being read as a string, while your "k" variable is a number. Numbers and strings are not alike, so, for example, 1 isn't the same as "1".
To fix this, simply convert the reading stored in the "quantidade" variable to a number first using the tonumber() function, by changing quantidade = io.read() to quantidade = tonumber(io.read()) like so:
function metodoDois()
print("Write a name: ")
name = io.read();
print("Write how many times that it will be printed on screen: ")
quantidade = tonumber(io.read())
k = 0;
while name do
k = k+1;
io.write("\n", name, " ", k)
if k == quantidade then
name = not name;
end
end
end
metodoDois()
Also, this is just a nitpick, but that code seems a bit un-optimized! I'd recommend using something more like this:
function metodoDois()
print("Write a name: ")
local name = io.read();
print("Write how many times that it will be printed on screen: ")
local quantidade = tonumber(io.read())
for k = 1, quantidade do
io.write(name.." "..k.."\n")
end
end
metodoDois()
I have a lua table which I used to share values between files. But I am getting confused in the following case
utility.lua file
M = {}
M.host_url = '192.168.0.1'
function M.myFunc()
print(M.host_url )
end
return M
in my main.lua
utility = require('utility')
utility.myFunc() -- this gives me 'a nil value' error
I get an error (nil value) for the host_url?
In M.myFunc doing only print action that function nothing will be return.in your utility file returning whole array see he below code that will clear your doudt.
In main.lua
utility = require('util')
value = utility.host_url
print(value)
I'm getting a very strange error, when trying to compare 2 integer variables using LUA on Corona SDK.
Basically this is what i have
**jAnswer** -- is a variable set via jSON, the value can only be 0 or 1.
local function checkAnswer(answer)
if (answer == jAnswer ) then
print("Correct Answer")
print("Answer is = "..answer.." jAnswer = "..jAnswer)
else
print("Wrong Answer")
print("Answer is = "..answer.." jAnswer = "..jAnswer)
end
end
checkAnswer(1) -- Calling the Function Here
Heres the problem, even if a get a output like "Answer is = 1, jAnswer = 1", i still get the "Wrong Answer".
Basically, the jAnswer, was being seen as a String, so i just needed to convert the string to number, using a global class on lua named tonumber()
jAnswer = tonumber(jAnswer, 10) -- Convert using the decimal base
Thanks!
I have a program which checks for conditions some variable field, like
if(tostring(field) == '0') then {do something}
if(tostring(field) == '1') then {do something}
if(tostring(field) == '2') then {do something}
But, i think lua is interpreting '0' and '1' as TRUE/FALSE values and not checking the corresponding if conditions properly. The condition executes properly for field == '2' condition.
How can i overcome this case? How can i make it work for check conditions '0' and '1'?
Thank You in advance!
In case you are wondering why i tagged wireshark, the if check condition is checking for a field in pcap file.
My lua code for reference is as follows:
#!/usr/bin/lua
do
local pkts = 0
local stat = {}
local file = io.open("luawrite","w")
local function init_listener()
local tap = Listener.new("wlan")
local src_addr = Field.new("wlan.sa")
local type = Field.new("wlan.fc.type")
local sub_type = Field.new("wlan.fc.subtype")
local frame_length = Field.new("frame.len")
local data_rate = Field.new("wlan.data_rate")
function tap.reset()
pkts = 0;
end
function tap.packet(pinfo, tvb)
local client = src_addr()
local stype = sub_type()
local ty = type()
local ts = tostring(pinfo.rel_ts)
local fl = frame_length()
rate = data_rate()
if(tostring(ty) == '0') then
file:write(tostring(ts), "\t", tostring(fl), "\t", tostring(rate), "\n")
end
end
end
init_listener()
end
The condition i am referring to 7th line from last line. If i give the condition tostring(ty) == '2', it works properly.
From the manual:
The condition expression of a control structure can return any value.
Both false and nil are considered false. All values different from nil
and false are considered true (in particular, the number 0 and the
empty string are also true).
Both the number 0 and the empty string evaluate to true, so it's definitely not mistaking the string "0" for false. I might avoid redefining type. Also, I think frame_type returns a number so you can get rid of the tostring() in the condition.
do
local pkts = 0
local stat = {}
local file = io.open("luawrite","w")
local function init_listener()
local tap = Listener.new("wlan")
local src_addr = Field.new("wlan.sa")
-- Changed function from type to frame_type
local frame_type = Field.new("wlan.fc.type")
local sub_type = Field.new("wlan.fc.subtype")
local frame_length = Field.new("frame.len")
local data_rate = Field.new("wlan.data_rate")
function tap.reset()
pkts = 0;
end
function tap.packet(pinfo, tvb)
local client = src_addr()
local stype = sub_type()
local ty = frame_type()
local ts = tostring(pinfo.rel_ts)
local fl = frame_length()
rate = data_rate()
-- skip the tostring
if ty == 0 then
file:write(tostring(ts), "\t", tostring(fl), "\t", tostring(rate), "\n")
end
end
end
init_listener()
end
If all else fails, try writing a line regardless of the frame type and write the frame type with it:
function tap.packet(pinfo, tvb)
local client = src_addr()
local stype = sub_type()
local ty = frame_type()
local ts = tostring(pinfo.rel_ts)
local fl = frame_length()
rate = data_rate()
file:write(tostring(ty), "\t", tostring(ts), "\t", tostring(rate), "\n")
end
Then you can see which frame types you're receiving.
As Corbin said, it's definitely not interpreting "0" and "1" as TRUE/FALSE. Wireshark runs the stock Lua interpreter, and Lua only considers nil and the boolean value of false as false values. Of course you're not really checking if they're false values, you're doing a string comparison of the string-ified value of the "wlan.fc.type" field value to the string "0" or the string "1" or whatever. The actual value you get for the "wlan.fc.type" field is a number, so as Corbin said there's no need to convert it to a string and string-compare it to a string of "0" or whatever... just compare them as numbers.
Regardless, stringifying both of them should have worked too (just been less efficient), so the odds are there simply isn't an 802.11 packet with a wlan.fc.type of 0 in your capture. A wlan.fc.type of 0 is a management frame, a 1 is a control frame, and a 2 is a data frame. So the odds are you're only capturing 802.11 data packets, which is why your comparison of the string-ified wlan.fc.type to the string "2" succeeds.
One way to find out is to open your capture file in wireshark, and put in a display filter for "wlan.fc.type == 0" and see if any packets are shown. If not, then you don't have any management packets.