I have a Fluke Endurance pyrometer (and a pretty flimsy user guide) which has output via an ethernet cable which I'm then connecting to my computer via a USB3.0 to Gigabit ethernet adaptor (windows control panel tells me it's working). According to the guide, communication should be possible via RS485 and profinet. But it's unclear to me if both are possible through the same cable.
My initial plan was to try to use snap7 to try profinet communication, but when I try:
import snap7
plc = snap7.client.Client()
plc.connect("192.168.42.132",0,1)
I get
snap7.snap7exceptions.Snap7Exception: b' TCP : Unreachable peer'
I can ping the device at that IP address.
So my questions are:
any ideas why I can ping, but snap7 seems to have problems connecting?
if I can't get profinet communication to work, any chance I can get RS485 communication somehow through the ethernet cable? Everything I looked up on that talks about having hardware that does the conversion, so I'm assuming it's more than just looking for the right signal format on the right wires. I can't find anything in the manual that turns on/off one form of communication, and it looks like from the menu they are both active, if that's possible.
Better yet, if anyone has communicated with this device in python, any suggestions would be greatly appreciated!
Thanks,
Matthew
Update:
In case anyone else has a similar problem, I solved this by using socket and ASCII commands like this:
import socket
pyrometerIP = "192.168.42.132"
pyrometerPORT = 6363
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(3) # 3 second timeout on commands
s.connect((pyrometerIP, pyrometerPORT))
MESSAGE=bytes('U=C\r', 'ascii')
s.send(MESSAGE)
There are couple of reasons why, some of the reason are listed below:
The rack and slot available to over TIA portal.
You cannot reach the PLC on that IP
You do not have the two DLL file for snap7 module which can be found on https://sourceforge.net/projects/snap7/files/1.4.2/
Related
I am trying to send IPv6 UDP packets to all of the nodes on the local network segment, in python, over Windows.
I have several network interfaces in my computer, and I want to know how to specify the network interface for sending the packets.
I have tried sending the packets to the multicast address ff02::1, using socket.sendto (without binding), but the packets are sent in the wrong network interface.
Any idea how can I specify the network adapter? (I read about BINDTODEVICE, but it won't work on windows, and some methods using bind to broadcast IP address classes, but only for IPv4).
Thanks!
According the answer to this question- multicasting with ff12::1 sometimes works better than multicasting with ff02::1.
I tried it and it worked- the packets were sent through the Ethernet network interface (as I wanted), and not in the WiFi as they were before.
However, I don't know why is it working, and I couldn't find any reference for it in the IPv6 RFC or anywhere else in the internet.
Explanations will be welcomed :)
I didn't really like the previous solution, so I kept looking for others.
The first option that worked for me is to bind the sender socket to the specific network interface address. The network interfaces addresses can be found using netifaces module, and I used this helpful answer to specify the Ethernet address.
Another option that might work is the IPV6_MULTICAST_IF option-
#x is the relevant interface index
sock.setsockopt(socket.IPPROTO_IPV6,socket.IPV6_MULTICAST_IF,x)
In Windows, python 2.7, one should add the line
socket.IPPROTO_IPV6=41
before this code (since the relevant enum is not well defined).
Additional information can be found here (Windows) or here (Linux).
Although it seems like a simpler solution, I didn't completely managed to make it work, and not sure what is the proper way to find the right interface index (on Windows, Linux has several options).
This is a problem with your system configuration. The operating system needs to be configured with the proper IPv6 routes to ensure the packets go out on the correct interface. It is not up to the application to decide, similar to how it is not the application's job to assign an IP address to the network interface - it's all the responsibility of the OS.
Here is an answer that explains how this is done under Linux. Feel free to add a comment with a link for how it's done on Windows if anyone knows.
My goal is to have remote control of a device on a WLAN. This device has software that enables me to configure this wireless network (IP, mask, gateway, dns). I can successfully connect this device, and my computer to a common network. Since both machines share the same network, I made the assumption that I would be able to open up a socket between them. Knowing the IP and port of the device that I am attempting to control remotely I used the following code, only to receive a timeout:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('192.168.xxx.xxx', XXXX))
(I am using python 2.7 on mac OS 10.11.6)
The network that I am connected to is on a different subnet that the IP that I assigned to my device. I also tried this having an IP on the same subnet as my network. There could be a number of things keeping me from opening a socket. That's not really what I'm after. The heart of my question is whether or not I can use python's 'socket' module to connect to a device wirelessly.
Yes you can.
So you get a timeout when you try to connect to a wireless device. There are several steps you can take in order to troubleshoot this.
Make sure your device has a program running that is listening to the port you want to connect to. Identify if the device can answer ICMP packets in general and can be pinged in particular. Try to ping the device. If ping succeeds, it means that basic connectivity is established and the problem is somewhere higher in the OSI stack.
- I can ping the device - great, it means that the problem is somewhere in TCP or Application Layer of the TCP/IP stack. Make sure the computer, the device, and intermediate networking equipment allow for TCP connections to the particular host and port. Then proceed to your application and the device software. Add some code to the question, post the stack trace you get or ask another one on SO.
- I can't ping the device - great. There's no connectivity between the devices and you're to identify the reason.
I) Draw a network diagram. How many intermediate network devices are placed in between the computer and the device? What are they, routers, switches? (Just in case, home grade wifi modem is a router.) Get an idea of how IP datagrams should travel across the net.
II) You said that the device can be used to configure an IP network. At least for troubleshooting purposes I would ignore this option and rely on a static IP or your router's DHCP server. Using an existing DHCP will ensure there's no IP misconfigurations.
III) Review routing tables of all the devices you have. Do they have an appropriate default gateway? Does a router knows how to pass the packets to the device. You're probably in trouble if the computer and the device are in the same subnet but attached to different network interfaces. Split the network in two subnets if needed and set up static routes between them on the router.
You can also use wireshark to see if data you send leaves the computer or is dropped right there by some nasty firewall.
There's a lot of caveats in getting a LAN working. You may want to ask questions on networking.stackexchange if these simple steps doesn't help you or if you have major troubles following them. Or just leave a comment here, I'd be happy to help.
If this is a stupid question, please don't mind me. But I spent some time trying to find the answer but I couldn't get anything solid. Maybe this is a hardware question, but I figured I'd try here first.
Does Serial Communication only work one to one? The reason this came up is because I had an arduino board listening for communication on its serial port. I had a python script feed bytes to the port as well. However, whenever I opened up the arduino's serial monitor, the connection with the python script failed. The serial monitor also connects to the serial port for communication for its little text input field.
So what's the deal? Does serial communication only work between a single client and a single server? Is there a way to get multiple clients writing to the server? I appreciate your suggestions.
Multiple clients (e.g. Arduinos) communicating with one server (e.g. a desktop computer) is commonly done with the serial variant:
RS-485
This is a simple method widely used in industrial settings where you want to have many devices connected to one computer via one serial port. This type of arrangement is also called multi-drop, because one cable strings around a building with Tees that tap in and drop lines to each device.
The hardware for this is widely available. You can buy USB serial adapters that provide the hardware interface for a computer. Programmatically the port looks just like an RS232 port. For the Arduino you would just add a transceiver chip. A sea of serial transceivers exists, e.g.
Example computer USB adapter with 485 interface
Sample RS485 transceiver chip from Element14
All the devices hang on the same bus listening at the same time. A simple communication protocol used is just add a device address before every command. For example:
001SETLIGHT1 <- tells Arduino "001" to turn on the light
013SETLIGHT0 <- tells "013" to turn off the light
Any device hanging on the cable ignores commands that do not start with their address. When a device responds, it prepends its address.
001SETLIGHT1DONE <- response from device "001" that the command has been received and executed
The address in the response lets the receiving party know which device was talking.
Well, your question can be quite wide, so I'm going to layer my answer:
On the hardware side, the same pair of wires can work be shared with many devices. It is mostly a question of electronics (maintaining the signal in the good voltage range), and not having all devices writing to the serial port at the same time (or you'll get wreckage).
On the software side, on the host, yes you can share the same serial connection to a device with multiple processes. But that's not straight forward. I'll assume you're using an unix (macos or linux):
in unix, everything is a file, your serial connection is one too: /dev/ttyACM0 on linux, for example.
When you have a process opening that file, it will block it (using ioctl, iirc) so no other process can mess with that file too.
Then, you can input and output to that file using the process that opened it, that's all.
But hopefully, it is still possible to share the connection between processes. One of them would simply be to use the tee command, that will be able to get input from one process, and give it back output, and copy the output to another process. You can also do it from within python, by duplicating the file descriptor.
To easily output stuff that can be redirected the unix way (using pipes), you can use socat: http://www.dest-unreach.org/socat/
here's an usage example:
socat -,raw,echo=0,escape=0x0f /dev/ttyACM0,raw,echo=0,crnl
you may want to tweak it for your needs.
Edit:
I forgot about RS-485, which 'jdr5ca' was smart enough to recommend. My explanation below is restricted to RS-232, the more "garden variety" serial port. As 'jdr5ca' points out, RS-485 is a much better alternative for the described problem.
Original:
To expand on zmo's answer a bit, it is possible to share serial at the hardware level, and it has been done before, but it is rarely done in practice.
Likewise, at the software driver level, it is again theoretically possible to share, but you run into similar problems as the hardware level, i.e. how to "share" the link to prevent collisions, etc.
A "typical" setup would be two serial (hardware) devices attached to each other 1:1. Each would run a single software process that would manage sending/receiving data on the link.
If it is desired to share the serial link amongst multiple processes (on either side), the software process that manages the link would also need to manage passing the received data to each reading process (keeping track of which data each process had read) and also arbitrate which sending process gets access to the link during "writes".
If there are multiple read/write processes on each end of the link, the handshaking/coordination of all this gets deep as some sort of meta-signaling arrangement may be needed to coordinate the comms between the process on each end.
Either a real mess or a fun challenge, depending on your needs and how you view such things.
I am working on a multi threaded server application for processing serial/USB ports.
The issue is that if a cable gets unplugged, pyserial keeps reporting that the port is open and available. When reading I only receive Empty exceptions (due to read timeout).
How do I find out that a port has been disconnected so that I can handle this case?
Edit: OS is Ubuntu 12.04
Edit 2: Clarification - I am connecting to serial port devices via Serial to USB connector, thus the device being disconnected is an USB device.
A Serial port has no real concept of "cable connected" or not connected.
Depending on the equipment you are using you could try to poll the DSR or CTS lines, and decide there is no device connected when those stay low over a certain time.
From wikipedia:
DTR and DSR are usually on all the time and, per the RS-232 standard
and its successors, are used to signal from each end that the other
equipment is actually present and powered-up
So if you've got a conforming device, the DSR line could be the thing you need.
Edit:
As you seem to use an USB2Serial converter, you can try to check whether the device node still exists - you don't need to try to open it.
so os.path.exists(devNode) could suffice.
I am trying to read UDP packages sent by an FPGA with my computer. They are sent
to port 21844 and to the IP 192.168.1.2 (which is my computer's IP). I can see the package in wireshark, they have no errors. When I run however this little python script, then only a very very small fraction of all packages are received by it, also depending if wireshark is running or not.
import socket
import sys
HOST, PORT = "192.168.1.2", 21844
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((HOST,PORT))
received ,address= sock.recvfrom(2048)
print address
I use windows 7 with Norton Internet Security, where I allow all traffic in the firewall for the FPGA IP and also for python. The same program on a Windows XP computer does not receive anything either...
Thanks for any help!
The TCP/IP stack of your OS doesn't hold those packets for you for eternity. Your script looks like something that very much depends on when it is run. Try to recvfrom in a loop, and run the script in the background. Then, start sending packets from your FPGA.
For extra convenience, explore the SocketServer module from Python's stdlib.
Ok, I found the problem: The UDP checksum in the FPGA was computed wrongly. Wireshark shows every package, but by default it does not check if the checksum is correct. When I set the checksum to 0x0000, then the packages arrive in python! Thanks for your help again!