Situation :
There are two sensors and I want to save the data of values of each sensor in the certain file..But it's not working. I am working on linux system and the file is still empty.
What's wrong with my code? any suggestion please?
my code is:
--Header file
require("TIMER")
require("TIMESTAMP")
require("ANALOG_IN")
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");
end
TIMER.sleep(timer,500)
end
-- close the file
filehandle:close()
end
print("start main")
main()
I do not know what this libs realy do.
But this code is incorrect;
1) you do not close while statement.
if in real code you close it before filehandle:close() then try call filehandle:flush()
2) you forgot comma:
filehandle:write(timestr, " -The Value of the Sensors: ", tostring(valueOfSensor_1), tostring(valueOfSensor_2)"\n")
(it should seay something like attemt call a number value).
3) try print out valueOfSensor_1 and valueOfSensor_2 values. May be there no data.
Beside the typos pointed out by #moteus, shouldn't this:
if (valueOfSensor_1 and valueOfSensor_2 > 0) then
be like this?
if (valueOfSensor_1 > 0 and valueOfSensor_2 > 0) then
Edit, in response to your comment to another answer:
still error..it says "attempt to call field 'data' (a nil value)
I can't be sure without the stack trace, but, most likely, something bad happens in the ANALOG_IN library code. You may not be using it properly.
try to turn this:
valueOfSensor_1 = ANALOG_IN.readAnalogIn(analogsensor_1);
valueOfSensor_2 = ANALOG_IN.readAnalogIn(analogsensor_2);
into this:
success, valueOfSensor_1 = pcall(ANALOG_IN.readAnalogIn, analogsensor_1);
if not success then
print("Warning: error reading the value of sensor 1:\n"..valueOfSensor_1)
valueOfSensor_1 = 0
end
success, valueOfSensor_2 = pcall(ANALOG_IN.readAnalogIn, analogsensor_2);
if not success then
print("Warning: error reading the value of sensor 2:\n"..valueOfSensor_2)
valueOfSensor_2 = 0
end
If the failure in ANALOG_IN is not systematic, it will work around it. If the call fails systematically, you'll get a huge warning log, and an empty collection_of_data.txt.
Please note that ANALOG_IN is not a standard Lua library. You should check its documentation , and pay attention to the details of its usage.
Related
I'm new to DXL programming language in IBM DOORS. However, I think I have managed to do many interesting things: create Modules, create Objects, create Links, delete Objects etc.
However, I have a very specific problem regarding "null" Modules. I've just written null between "" because the modules exist and they are referenced with a correct name.
When doing this:
Module m1 = edit("1. MY_MODULE", false)
save(m1)
close(m1)
An error like this appears:
enter image description here
You could not understand what does that mean as it is spanish. Basically states this: "Module null parameter in the first position of the argument." That means that the "m1" is null, as the parameter for save() method is null.
The point is that it is an error which appears only sometimes. It seems that the Module is null as it has been previously opened and DOORS does not close properly.
Is there any way, any method...whatever to avoid this error?
I assume that the script cannot find the module when another folder is active.
Try
Module m1 = edit ("/myproject/myfolder/mysubfolder/1. MY_MODULE", false)
There might be many reasons that the module can't be opened in edit mode. For example: User do not have write access OR Module is being used by other user, etc.
However, you can get around the error with the below code snippet:
Module m = edit('My_module', false)
if(!null m) {
//execute program
...
}
else {
//do something
}
I hope this helps.
How does your script work? do you open the same module again and again and sometimes get the error or do you open lots of modules and for some of them it works and for others it doesn't? In the latter case, perhaps you misspelled the path. You could add some sanity checks like
string fullPathToMod = "/myproject/myfolder.."
Item i = item fullPathToMod;
if null i then error "there is no item called " fullPathToMod
if "Module" != type i then error "there is an item, but it's not a module, it's a " type i
This is how the Code is structured:
void checkModule(string folderPath, string mName, Skip list, int listSize, int listLastIndex, string headers[], string heading[], string headerKey, bool uniqueKey, string combinedKey[]){
if (module mName){
Folder f = folder(folderPath)
current = f
Module m = edit(folderPath""mName, false)
current = m
Object o = first(m) // error sometimes: Se ha pasado un parametro Module null en una posiciĆ³n de argumento 1
if (o == null){
loadModule(m, list, listSize, listLastIndex, headers, heading)
} else {
updateModule(m, mName, list, listSize, listLastIndex, heading, headerKey, headers, uniqueKey, combinedKey)
save(m)
close(m)
}
if (lastError() != ""){
print "Error: " lastError() "\n"
}
} else {
print "No module " mName ".\n"
}
}
Exactly it breaks in line:
current = m
But as said, only sometimes, not always.
BTW, I'm executing this script via Batch, via Java code. One curious thing is that if I close DOORS, and execute the script it does execute correctly. It is as if it needs to be closed in order to edit modules correctly.
I pressume current can be used more than once with different types of Items. I guess it should not be wrong, but it breaks saying (more or less):
Null value passed to DXL commmand (current Module).
Obviously, it means that m is null, but I cannot see any reason for that.
I'm writing an LPeg-based parser. How can I make it so a parsing error returns nil, errmsg?
I know I can use error(), but as far as I know that creates a normal error, not nil, errmsg.
The code is pretty long, but the relevant part is this:
local eof = lpeg.P(-1)
local nl = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n" + eof -- \r for winblows compat
local nlnoeof = (lpeg.P "\r")^-1 * lpeg.P "\n" + lpeg.P "\\n"
local ws = lpeg.S(" \t")
local inlineComment = lpeg.P("`") * (1 - (lpeg.S("`") + nl * nl)) ^ 0 * lpeg.P("`")
local wsc = ws + inlineComment -- comments count as whitespace
local backslashEscaped
= lpeg.P("\\ ") / " " -- escaped spaces
+ lpeg.P("\\\\") / "\\" -- escaped escape character
+ lpeg.P("\\#") / "#"
+ lpeg.P("\\>") / ">"
+ lpeg.P("\\`") / "`"
+ lpeg.P("\\n") -- \\n newlines count as backslash escaped
+ lpeg.P("\\") * lpeg.P(function(_, i)
error("Unknown backslash escape at position " .. i) -- this error() is what I wanna get rid of.
end)
local Line = lpeg.C((wsc + (backslashEscaped + 1 - nl))^0) / function(x) return x end * nl * lpeg.Cp()
I want Line:match(...) to return nil, errmsg when there's an invalid escape.
LPeg itself doesn't provide specific functions to help you with error reporting. A quick fix to your problem would be to make a protected call (pcall) to match like this:
local function parse(text)
local ok, result = pcall(function () return Line:match(text) end)
if ok then
return result
else
-- `result` will contain the error thrown. If it is a string
-- Lua will add additional information to it (filename and line number).
-- If you do not want this, throw a table instead like `{ msg = "error" }`
-- and access the message using `result.msg`
return nil, result
end
end
However, this will also catch any other error, which you probably don't want. A better solution would be to use LPegLabel instead. LPegLabel is an extension of LPeg that adds support for labeled failures. Just replace require"lpeg" with require"lpeglabel" and then use lpeg.T(L) to throw labels where L is an integer from 1-255 (0 is used for regular PEG failures).
local unknown_escape = 1
local backslashEscaped = ... + lpeg.P("\\") * lpeg.T(unknown_escape)
Now Line:match(...) will return nil, label, suffix if there is a label thrown (suffix is the remaining unprocessed input, which you can use to compute for the error position via its length). With this, you can print out the appropriate error message based on the label. For more complex grammars, you would probably want a more systematic way of mapping the error labels and messages. Please check the documentation found in the readme of the LPegLabel repository to see examples of how one may do so.
LPegLabel also allows you to catch the labels in the grammar by the way (via labeled choice); this is useful for implementing things like error recovery. For more information on labeled failures and examples, please check the documentation.
I don't quite have an answer but I'm narrowing it down. Somehow I'm mixing/confusing types, I believe, between what is provided by commands like 'os.path' and type str().
As I've made the assignment of the logfile(s) globally, even though I can print it in the function, when the variable is used in fout = open(... it's actually a null that's being referenced, i.e. open() doesn't like/can't use the type it finds.
The error:
UnboundLocalError: local variable 'fout' referenced before assignment
I am simply writing a log of dot files (left on USB drives by OSX) for deletion, but the try/except is now falling over. First the original version.
working code:
logFile = "/Users/dee/Desktop/dotFile_names.txt"
try:
fout = open(logFile, 'w')
for line in dotFile_names:
fout.write(line)
except IOError as e:
print ("Error : %s not found." % fout)
finally:
fout.close()
Attempting better practice, I sought to put the log file specs and path as variables so they can be modified if need be - I hope to make it cross platform workable. these variables are at the head of the program, i.e. not in main(), but I pass them in and print() statements have shown me they are successfully being referenced. i.e. I get this printed:
/Users/dee/Desktop/dotFile_names.txt
Despite this the error I get is:
UnboundLocalError: local variable 'fout' referenced before assignment -
error points at the "fout.close()" line
Error producing code
logFilespec = "dotFile_names.txt"
fullLogFileSpec = []
userDesktop = os.path.join(os.path.expanduser('~'), 'Desktop')
fullLogFilespec = os.path.join(userDesktop, logFilespec)
try:
print "opening " + fullLogFilespec
fout = open(fullLogFileSpec, 'w')
for line in dotFile_names:
print "..", # are we executing this line..?
fout.write(line)
except IOError as e:
print ("Error : %s not found." % fout)
finally:
print "\nclosing " + fullLogFilespec
fout.close()
I've found that if I modify this line by converting to a string
fout = open(fullLogFileSpec, 'w')
fout = open(str(fullLogFileSpec), 'w')
the error goes away, BUT NO file is created on the Desktop!
At the very least I guess that I am passing something unrecognisable to fout = open() but it is not being caught by the except. Then when I pass something that does seem to allow fout =open() to work it seems to be a ghost?
So I figure I am lost between a String and whatever kind of reference/pointer os.path.expanduser() gives me.
I'm sure it's insanely simple. Before adding the str() code I also checked all indentation, removing them all and adding back using the editor indent hotkeys, just in case that was affecting things somehow.
OK, it looks like I was wearing my dumb glasses, I think declaring
fullLogFileSpec = []
as a list instead of a string was my error.
Similar as it is, having re-written it without that list declaration this code is working fine:
logfile_directory = os.path.join(os.path.expanduser('~'),'Desktop')
log_bf_file_spec = 'ItemsFoundByFolder_' + Deez_1.current_datetime() + '.txt'
log_by_folder = os.path.join(logfile_directory, log_bf_file_spec)
the function later calls, with no error:
fout_by_folder = open(log_by_folder, 'w')
function saveScore()
local path = system.pathForFile("scoredata001.txt", system.DocumentsDirectory)
local file = io.open(path, "w")
if file then
local score=get_score() --The get_score() returns the value of current score which is saved in 'score'.
local newScore = compareScore()
local contents = tostring( newScore )
file:write( contents )
io.close( file )
return true
else
print("Error: could not write Score")
return false
end
end
function loadScore()
local path = system.pathForFile("scoredata001.txt", system.DocumentsDirectory)
local contents = ""
local file = io.open( path, "r" )
if file then
local contents = file:read( "*a" )
local score = tonumber(contents);
io.close( file )
return score
end
print("Could not read scores from scoredata.txt")
return nil
end
function return_highScore()
local highscore=loadScore()
if highscore==nil then
highscore=0
end
return highscore
end
function compareScore()
local highscore=return_highScore()
if highscore then
local currscore=get_score()
if highscore==0 then
return highscore
elseif currscore>highscore then
return currscore
end
end
return true
end
function disp_permScore()
local display_score=return_highScore()
text_display2= display.newText("GAME OVER!\n BEST: " ..display_score, 0, 0, "Helvetica", 80)
text_display2.x = centerX
text_display2.y = centerY
text_display2.alpha=1
function gameOver()
mainScreen()
saveScore()
disp_permScore()
end
(This is with refernce to previous question Permission issues in lua )
Basically I'm trying to build a game in lua (This is my first ever game)
But, I'm unable to save highscore to file. If it gets saved, then I'm unable to retrieve them. (In short, I always some or the other error/problem in executing the code.
Please have a look at the code above. I want to display both high score and current score. Current score is being displayed perfect. This is something I tried yesterday night. But now, the high score is not being saved in file. (i.e. the best always displays 0) Also, the cmd says "unable to read scores form scoredata.txt) I'm unable to find where I went wrong.
Please help with this?
Please tell where do I go wrong?
Also, if possible, provide (or edit) the correct code please?
There seems to be a problem on this line
if highscore==0
then
return highscore
Meaning you check if the highscore is 0 and if it is then you return it instead of the actual higher score.
Also, I don't know if your code was just pasting error, but without indenting your code it becomes really hard to read. Try and look again I indentet it and now the error becomes really easy to spot.
Humbling expierence here and I think this one will make a fool of me, but...I'm trying to convert an ancient cash register program to .net. Conquered everything else, but I can't pop open the cash register. Its connected to COM1, you are supposed to send a "trigger" text down COM1 that will cause the register to open.
Here is the .net code.
MsgBox("Opening Drawer")
Dim port As System.IO.Ports.SerialPort
port = New System.IO.Ports.SerialPort("Com1")
port.PortName = "COM1"
port.BaudRate = 9600
port.Parity = IO.Ports.Parity.None
port.DataBits = 8
port.StopBits = IO.Ports.StopBits.One
'port.Handshake = IO.Ports.Handshake.RequestToSend
port.RtsEnable = True
'port.DtrEnable = True
port.Open()
If port.IsOpen Then
'MsgBox("Attempt 1")
port.Write("####################")
MsgBox("Signal Sent: " & Chr(65))
Else
MsgBox("Port is not open")
End If
port.Close()
MsgBox("Pop, durn it!")
I get msgboxes "Signal Sent", "Done Pop Drawer"
Dang thing, just won't pop. It's an MS-Cash Drawer (EP125KC). Definitely connected to COM1, definitely has power. Chr(65) is the old code used to pop drawer and it works:
Open drawerComPort For Output Access Write As #1
Print #1, Chr$(65); "A";
Close #1
NOTE: The above code worked successfully. The root problem was caused by a reveresed power cord (negative was on the wrong side).
Thanks for all the help guys!
You've set your handshake to None but the cash drawer probably has its own idea. Also set DtrEnable to True. Chr(65) is the ASCII code for an "A", your VB code suggests the real command is "AA".
The manual documents that the cash drawer auto-tunes its baudrate. It recommends sending at least 20 # characters. And that the real command is Ctrl+G (Chr(7)). The "AA" command might have worked previously due to a baudrate mismatch. Perhaps.
If I remember my very rusty BASIC.
Print #1, Chr$(65); "A";
means print to port1 the character 65 followed by the string "A", Now the character 65 is 'A', so this looks to me like you should be sending "AA" to port1
port.Write("AA");
or alternately,
port.Write(new byte[]{65,'A'}, 0, 2);
It might be sending Unicode 65, which would be 0065, which would not end well.
Just a thought, can you try sending a raw int?
I dont use .net, but is the port buffered? do you need to send a flush/fflush()?
Are you sure you're supposed to send out this code? I would have always thought that the code is prefixed by ESC i.e. 0x1b hexadecimal...for cash drawers...
"\x1bA"
Interesting that double 'A' is used...oh well... :)
Edit: After thinking about this I realized there is another way of doing it, read on...
I have modified your original BASIC code with a bit of bullet-proofing...save it to opendrawer.bas
Sub OpenDrawer()
drawerComPort = "COM1"
Open drawerComPort For Output Access Write As #1
REM ADDED ERROR HANDLING
ON ERROR GOTO ErrHandler
Print #1, Chr$(65); "A";
Close #1
print "Drawer Ok"
OpenDrawer_Exit:
On Error Goto 0
Exit Sub
ErrHandler:
print "Oops, Write Failed"
Goto OpenDrawer_Exit
End Sub
REM The Main....
OpenDrawer
Download the old QB4.5 MS-Quick Basic compiler, and compile that to an executable, into opendrawer.exe, the QB4.5 can be found here. Now, the onus is on you to make this bulletproof, i.e. what happens if writing to COM1 fails, issue a message like in the example BASIC code I modified
Then you can use the System.Diagnostics.Process to shell out using a hidden window
public class TestDrawer
{
private StringBuilder sbRedirectedOutput = new StringBuilder();
public string OutputData
{
get { return this.sbRedirectedOutput.ToString(); }
}
public void Run()
{
System.Diagnostics.ProcessStartInfo ps = new System.Diagnostics.ProcessStartInfo();
ps.FileName = "opendrawer";
ps.ErrorDialog = false;
ps.CreateNoWindow = true;
ps.UseShellExecute = false;
ps.RedirectStandardOutput = true;
ps.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
{
proc.StartInfo = ps;
proc.Exited += new EventHandler(proc_Exited);
proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(proc_OutputDataReceived);
proc.Start();
proc.WaitForExit();
proc.BeginOutputReadLine();
while (!proc.HasExited) ;
}
}
void proc_Exited(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("proc_Exited: Process Ended");
if (this.sbRedirectedOutput.ToString().IndexOf("Oops, write failed") > -1){
MessageBox.Show(this, "Error in opening Cash Drawer");
}
if (this.sbRedirectedOutput.ToString().IndexOf("Drawer Ok") > -1){
MessageBox.Show(this, "Drawer Ok");
}
}
void proc_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
{
if (e.Data != null) this.sbRedirectedOutput.Append(e.Data + Environment.NewLine);
//System.Diagnostics.Debug.WriteLine("proc_OutputDataReceived: Data: " + e.Data);
}
The process shells out to a hidden window and all output is redirected and handled in the event handler...that should do the trick. Notice, how the redirected output goes into the sbRedirectedOutput (a StringBuilder instance). In the proc_ProcExited event handler, it checks the sbRedirectedOutput for the message 'Oops Write failed' which would be issued from the QB4.5 program.
Be aware, that you may need to include the QB4.5's run-time library in the same directory...not 100% sure...it's being years...
What do you think?
Hope this helps,
Best regards,
Tom.