Python for Keithley - python

I hooked up the Keithley 2701 DMM, installed the software and set the IPs right. I can access and control the instrument via the internet explorer webpage and the Keithley communicator. When I try to use python, it detects the instrument
i.e. a=visa.instrument("COM1") doesn't give an error.
I can write to the instrument as well:
a.write("*RST")
a.write("DISP:ENAB ON/OFF")
a.write("DISP:TEXT:STAT ON/OFF")
etc all don't give any error but no change is seen on the instrument screen.
However when I try to read back, a.ask("*IDN?") etc give me an error
saying timeout expired before operation completed.
I tried redefining as:
a=visa.instrument("COM1",timeout=None)
a=visa.instrument("TCPIP::<the IP adress>::1354::SOCKET")
and a few other possible combinations but I'm getting the same error.
Please do help.

The issue with communicating to the 2701 might be an invalid termination character. By default the termination character has the value CR+LF which is “\r\n”.
The python code to set the termination character is:
theInstrument = visa.instrument(“TCPIP::<IPaddress>::1394::SOCKET”, term_chars = “\n”)
or
theInstrument = visa.instrument(“TCPIP::<IPaddress>::1394::SOCKET”)
theInstrument.term_chars = “\n”
I hope this helps,

Related

Telnet using Python

hi I am new to python and I am trying to telenet to my host connected via Host-only adapter :
My command are
import telnetlib
import time
def call_func():
time1 = 2
connect = telnetlib.Telnet('192.168.1.100',23,3)
connect.write('show version'.encode('ascii'))
time.sleep(time1)
print (connect.read_very_eager().decode('ascii'))
connect.close()
call_func()
However I am not able to read the full output of the show version command. Can someone explain why I am not able to do so?
Output got:
'R1>show version'
You can read about all read_ methods in telnetlib documentation and compare their outputs. It states there, that only read_until() will give you text "until a given byte string". All of the other ones will return only "all data until EOF", "everything that can be without blocking in I/O", "readily available data." etc.
That said, you should use read_until() to be sure you get a full string returned. This in the only method that waits for telnet to return the whole text.
Additional explanation can be found here in a similar question.

Python, serial - changing baudrate, strange behaviour

I am having troubles with changing baudrate while the port is running. All the communication is run at 100k baud, but I also need to send some data at 10k baud. I've read I should use setBaudrate method, so I tried this:
ser = serial.Serial(2, baudrate=BAUD, timeout=TIMEOUT)
def reset(string):
if string:
ser.flushInput() #erase input and output buffers
ser.flushOutput()
ser.setBaudrate(RESET_BAUD) #change baudrate to 10k
ser.write(string)
ser.setBaudrate(BAUD) #go back to 100k
The problem is, it doesn't work right. I don't know what is wrong here, but the string just isn't received properly. But here is interesting part - if I remove the last line (going back to 100k) and run this function from the shell, everything is fine. Then I can just run the last command directly in shell, not inside function.
My question is what exactly happens here and how to avoid it? All I need is a function to send a string with different baudrate and then return to the original baudrate...
You need to wait long enough for the string to be sent before resetting the BAUD rate - otherwise it changes while some of it is still in the serial port (hardware) buffer.
Add time.sleep(0.01*len(string)) before the last line.
BTW try not to use reserved words like string as variable names as it can cause problems.
My guess is that the baud rate is being changed before the data is actually sent. A good bet is to force the data to be sent before trying to change the baud rate.
According to the docs, this is done by calling Serial.flush() (not flushInput() or flushOutput(), as these just discard the buffer contents).

How do I log text and a variable in the same line in Python?

I am relativly new to coding with Python.
I recently set up a gps logging device with a raspberry pi and I want to make my log file look cleaner.
My current code for logging is:
logging.info('Altitude:')
logging.info(gpsd.fix.altitude)
It logs:
INFO:root:Altitude:
INFO:root:80
What I want to see in the log is:
Altitude: 80
I tried to do this with my limited knowledge with python, but it only resulted in failure.
Thanks!
Also, any other tips for cleaning up the log file?
If altitude is a decimal then
logging.info('Altitude: %d' % gpsd.fix.altitude)
will do it, there are several other ways to achieve the same thing though as I'm sure others can present!
In Python >=3.6 you can do this :
logging.info(f"Altitude: {gpsd.fix.altitude}")
By adding the "f" at the beginning of the string the value between brackets will be interpreted as a variable and will be replaced by its value.
logging.info('{}:{}'.format("Altitude", gpsd.fix.altitude)
You can use format method. Have a look at the examples to understand format better.
Example:
print '{}:{}'.format("Altitude", 80)
Output
Altitude:80
Try:
logging.info('Altitude:%s' % gpsd.fix.altitude)

extracting ip address from raw_input

I have compiled a script in python 2.6.5, The script is simply to automate my most used functions for nmap and log the output to a txt file on the desktop.
I haven't written this all myself as i am still only learning python. I found an update script for updating backtrack and used that as a template for indentation and commands and modified it and added some of my own stuff to give me what i needed.
The problem i'm having is with this block
def nmap_target():
try: ip = raw_input(" [>] Enter ip to scan: ")
except KeyboardInterrupt:
print "\n [>] Exiting!\n"
sleep(1)
sys.exit()
print " [>] Attempting targeted scan.\n"
#print ip
if subprocess.Popen("nmap ip >> //root/Desktop/Target.txt && tail /root/Desktop/Target.txt",shell=True).wait() == 0:
print "\n"
print " [>] Targeted scan completed successfully!\n"
menu_main()
else:
print "\n"
print " [>] Nmap scan failed.\n"
The idea behind it is that it asks the user to input an ip address into raw_input() and call it ip, I'm trying to then pass it to nmap using subprocess.Popen("nmap ip as can be seen above.
The problem is its just writing nmap ip rather than printing the ip address and then returning errors, It even tries to scan out of my network, every time i test it i make sure the internet cable is unplugged from my router, This causes a bug with my internet test though, so if you try running the code bellow you may need to hash out the internet_check() option in the menu_main() section if you have your internet unplugged from the router
I have spent 4 days on this now and its driving me mad, At first i thought i needed to convert the number to floating point so i tried that and still the same, I've tried all sorts of things and spent hours trawling the internet looking for an answer to no avail.
I am now convinced its not the command i'm trying that is to blame i think it is the exit statement, I have tried putting "print ip" right after the line where it says "print " [>] Attempting targeted scan.\n" and sure enough the ip address that was entered is displayed on the screen, That proved to me that raw_input() is working. As soon as i move it anywhere bellow that it fails, This suggests to me that it must be either a problem with the exit statement or maybe indentation, I'm not sure though.
I have also tried hashing out the keyboard interrupt as well as the couple of lines bellow, i tried moving the try: and if statements around and even tried other commands instead but it just wont work aaaarrrrrgggghhhhhh
Would i be right in thinking that the ip is being entered into raw_input() and then the file ip that was created that holds the ip address is being destroyed before i can pass it to subprocess.Popen("nmap ip.
Like i mentioned i didn't write this script from scratch and this is my first project like this so i've got a lot to learn, I've been all through the python man pages and looked through all sorts of tutorials but just can't figure this out.
Any help will be much appreciated
i will post the full script if anyone is interested,just as soon as i can figure out how to post code properly
You need to seperate the variable from the string! Try this :D
if subprocess.Popen('nmap '+ip+' >> //root/Desktop/Target.txt && tail /root/Desktop/Target.txt',shell=True).wait() == 0:
Hope it helps!
EDIT - If for some reason python takes the raw input as an integer, convert it to string like so:
if subprocess.Popen('nmap '+str(ip)+' >> //root/Desktop/Target.txt && tail /root/Desktop/Target.txt',shell=True).wait() == 0:
Python doesn't like to concatenate str and int types, or so it tells when my script fails :P I am pretty sure your ip variable will be str type though so the first example should work.
Cheers!
You need to format the string properly or the string ip won't be interpreted at all, i.e. it won't get replaced wth the actual IP. Try something like:
cmd = "nmap ${0} >> [....] root/Desktop/Target.txt".format(ip)
if subprocess.Popen(cmd):
You could also use the % operator:
cmd = "nmap %s >> [....] root/Desktop/Target.txt" % ip

PyODBC Cursor.fetchall() causes python to crash (segfault)

I am using Python 2.7 on Windows XP.
I have a simple python script on a schedule that uses pyodbc to grab data from an AR database which has worked perfectly until today. I get a segfault once the cursor reaches a particular row. I have similar code in C++ which has no problem retrieving the results, so I figure this is an issue with pyodbc. Either way, I'd like to "catch" this error. I've tried to use the subprocess module, but it doesn't seem to work since once the script hits a segfault it just hangs on the "python.exe has encountered a problem and needs to close." message. I guess I could set some arbitrary time frame for it to complete in and, if it doesn't, force close the process, but that seems kind of lame.
I have reported the issue here as well - http://code.google.com/p/pyodbc/issues/detail?id=278
#paulsm4 - I have answered your questions below, thanks!
Q: You're on Windows/XP (32-bit, I imagine), Python 2.7, and BMC
Remedy AR. Correct?
A: Yes, it fails on Win XP 32 bit and Win Server 2008 R2 64 bit.
Q: Is there any chance you (or perhaps your client, if they purchased
Remedy AR) can open a support call with BMC?
A: Probably not...
Q: Can you isolate which column causes the segfault? "What's
different" when the segfault occurs?
A: Just this particular row...but I have now isolated the issue with your suggestions below. I used a loop to fetch each field until a segfault occurred.
cursor.columns(table="mytable")
result = cursor.fetchall()
columns = [x[3] for x in result]
for x in columns:
print x
cursor.execute("""select "{0}"
from "mytable"
where id = 'abc123'""".format(x))
cursor.fetchall()
Once I identified the column that causes the segfault I tried a query for all columns EXCEPT that one and sure enough it worked no problem.
The column's data type was CHAR(1024). I used C++ to grab the data and noticed that the column for that row had the most characters in it out of any other row...1023! Thinking that maybe there is a buffer in the C code for PyODBC that is getting written to beyond its boundaries.
2) Enable ODBC tracing: http://support.microsoft.com/kb/274551
3) Post back the results (including the log trace of the failure)
Ok, I have created a pastebin with the results of the ODBC trace - http://pastebin.com/6gt95rB8. To protect the innocent, I have masked some string values.
Looks like it may have been due to data truncation.
Does this give us enough info as to how to fix the issue? I'm thinking it's a bug within PyODBC since using the C ODBC API directly works fine.
Update
So I compiled PyODBC for debugging and I got an interesting message -
Run-Time Check Failure #2 - Stack around the variable 'tempBuffer' was corrupted.
While I don't currently understand it, the call stack is as follows -
pyodbc.pyd!GetDataString(Cursor * cur=0x00e47100, int iCol=0) Line 410 + 0xf bytes C++
pyodbc.pyd!GetData(Cursor * cur=0x00e47100, int iCol=0) Line 697 + 0xd bytes C++
pyodbc.pyd!Cursor_fetch(Cursor * cur=0x00e47100) Line 1032 + 0xd bytes C++
pyodbc.pyd!Cursor_fetchlist(Cursor * cur=0x00e47100, int max=-1) Line 1063 + 0x9 bytes C++
pyodbc.pyd!Cursor_fetchall(_object * self=0x00e47100, _object * args=0x00000000) Line 1142 + 0xb bytes C++
Resolved!
Problem was solved by ensuring that the buffer had enough space.
In getdata.cpp on line 330
char tempBuffer[1024];
Was changed to
char tempBuffer[1025];
Compiled and replaced the old pyodbc.pyd file in site-packages and we're all good!
Thanks for your help!
Q: You're on Windows/XP (32-bit, I imagine), Python 2.7, and BMC Remedy AR. Correct?
Q: Is there any chance you (or perhaps your client, if they purchased Remedy AR) can open a support call with BMC?
Q: Can you isolate which column causes the segfault? "What's different" when the segfault occurs?
Please do the following:
1) Try different "select a,b,c" statements using Python/ODBC to see if you can reproduce the problem (independent of your program) and isolate a specific column (or, ideally, a specific column and row!)
2) Enable ODBC tracing:
http://support.microsoft.com/kb/274551
3) Post back the results (including the log trace of the failure)
4) If that doesn't work - and if you can't get BMC Technical Support involved - then Plan B might be to debug at the ODBC library level:
How to debug C extensions for Python on Windows
Q: What C/C++ compiler would work best for you?
for any one else who might get this error, check the data type format returned. in my case, it was a datetime column. used select convert(varchar, getdate(), 20) from xxx, or any convert formats to get your desired result.

Categories