CanOpen communication (Python) 1 Slave and CAN-USB adapter - python

I am currently trying to implement simple communication between an I/O module as a CanOpen slave and my computer(Python script). The I/O module is connected to my computer with a PEAK USB-CAN adapter.
My goal would be to read or write the inputs/outputs. Is this even possible with the hardware, since I don't have a real "master" from that point of view?
Unfortunately I don't know what else I have to do to be able to communicate correctly with my I/O module.
import canopen
import time
network = canopen.Network()
network.connect(bustype='pcan', channel='PCAN_USBBUS1', bitrate=500000)
#add node and DCF File
IO_module = network.add_node(1, 'path to my DIO.DCF')
network.add_node(IO_module)
IO_module.nmt.state = 'RESET COMMUNICATION' # 000h 82 01
print(IO_module.nmt.state)
time.sleep(5)
IO_module.nmt.state = 'OPERATIONAL'
print(IO_module.nmt.state)
for node_id in network:
print(network[node_id])
IO_module.load_configuration()
i see some kind of communication in my console with timeout errors
INITIALISING
OPERATIONAL
<canopen.node.remote.RemoteNode object at 0x000002A023493A30>
Transfer aborted by client with code 0x05040000
No SDO response received
Transfer aborted by client with code 0x05040000
No SDO response received
Any advices ?
I can't get any further with the documentation alone
https://canopen.readthedocs.io/en/latest/
thank you

The good news is, you probably have all the required hardware. You are doing the "master" part from Python, that's fine. (The CAN bus isn't really master/slave, just broadcast. CANopen can be master/slave sometimes, but it's still all broadcast messages among equals on the same bus.)
You haven't provided information about your device, but I would start checking at a lower level.
Do you even have the CAN-Bus wired up correctly, and if so, what did you do to verify it? (Most common mistake: CAN-Bus not terminated with two 120ohm resistors. Though you usually can get away with just one instead of two.) And have you verified that you are using the correct baud rate?
The library docu example suggests to wait for the heartbeat with node.nmt.wait_for_heartbeat(). Why are you using a sleep instead? If there is no heartbeat, you don't need to continue. (Unless the device docu says that it doesn't implement NMT heartbeat - would be unusual.)
I certainly wouldn't try to go ahead with SDOs if you cannot confirm a NMT heartbeat. Also, some devices don't implement SDOs but only PDOs.
Try sniffing the CAN bus at a lower level (e.g. not PDOs/SDOs but just print the raw messages received - from Python, or with a separate application - e.g. candump on Linux.) Try getting statistics of the CAN "network" interface (on Linux, e.g. ifconfig). If everything is okay, the adapter should be in state "ERROR-ACTIVE", and you should see the frame counter increase for frames you've sent via Python.

Related

How to get data directly from XBee iolines

Hi I have XBee RF mode S2C which does not have internal storage to run micropython. So I need to get data from KY-001 sensor connected its iolines. With python library I didnt get anything just get_adc_value(ioline) function which seems doesnt do anything. I need to check sensor in local device for now .After I gonna use same solve to remote devices (I only use Python XBee library). Or exactly can I use Xbee iolines directly to get data from sensor without external MCU?
I don't think you'll be able to interface to this 1-Wire sensor, it's intended for a microprocessor that can handle timing requirements and uses a tristate I/O line (IIRC).
You should be looking at temperature sensors with an analog voltage output (like this TMP36) that you can tie to one of the analog inputs of the XBee, and then read that input with a remote ATIS for a single sample or ATIR for periodic sampling.

Python/Scapy Performance on embedded device using Wi-Fi

I am using Scapy to capture Wi-Fi client request frames. I am only interested in the MAC and requested SSID address of the clients. I do something like the following.
sniff(iface="mon0", prn=Handler)
def Handler(pkt):
if pkt.hasLayer(Dot11):
if pkt.type == 0 and pkt.subtype == 4:
print pkt.addr2 + " " + pkt.info
My issue is that I am doing this on a embedded device with limited processing power. When I run my script, my processor utilization rises to nearly 100%. I assume this is because of the sheer volume of frames that Scapy is sniffing and passing to my Python code. I also assume that if I could employ the right filter in my sniff command, I could eliminate many of the frames that are not being used and thus reduce the processor load.
Is there a filter statement that could be used to do this?
With Scapy it is possible to sniff with an BPF Filter applied to the capture. This will filter out packets at a much lower level then your Handler function is doing, and should significantly improve performance.
There is a simple example in the Scapy documentation.
# Could also add a subtype to this.
sniff(iface="mon0", prn=Handler, filter="type mgt")
Filter pieced together from here specifically.
Unfortunately I can't test this right now, but this information should provide you with a stepping stone to your ultimate solution, or someone else to post exactly what you need. I believe you will also need to set the interface to monitor mode.
You may also find this question of interest - Accessing 802.11 Wireless Management Frames from Python.
Scapy is extremely slow due to the way it decodes the data. You may
Use a BPF-filter on the input to only get the frames you are looking for before handing them to scapy. See this module for example. The module uses libpcap to get the data from the air or from a file first and passes it through a dynamically updated BPF-filter to keep unwanted traffic out
Write your own parser for wifi in c (which is not too hard, given the limited amount of information you need, there are things like prismhead though)
Use tshark from wireshark as a subprocess and collect data from there
I highly recommend the third approach although wiresharek comes with a >120mb library that your embedded device might not be able to handle.

Detecting serial port settings

From time to time I suddenly have a need to connect to a device's console via its serial port. The problem is, I never remember what port settings (baud rate, data bits, stop bits, etc...) to use with each particular device, and documentation never seems to be lying around when it's really needed.
I wrote a Python script, which uses a simple brute-force method (i.e. iterates over all possible settings, sends some test input and displays the response for a human to decide if it makes sense ), but:
it takes a long time to complete
does not always work (perhaps port reset/timeout issues)
just does not seem like a proper way to do this :)
So the question is: does anyone know of a procedure to auto-detect what port settings the remote device is using?
Although part 1 is no direct answer to your question:
There are devices, which just have a autodetection (called Auto-bauding) method included, that means: Send a character using your current settings (9k6, 115k2, ..) to the device and chances are high that the device will answer with your (!) settings. I've seen this on HP switches.
Second approach: try to re-order the connection possibilities. E.g. chances are high that the other end uses 9k6 with no hardware handshake, but less that it uses 38k4 with software Xon/Xoff.
If you break down your tries into just a few, the "brute force" method will be much more efficient.

Linux libnetfilter_queue delayed packet problem

I have to filter and modify network traffic using Linux kernel libnetfilter_queue (precisely the python binding) and dpkt, and i'm trying to implement delayed packet forward.
Normal filtering works really well, but if i try to delay packets with function like this
def setVerdict(pkt, nf_payload):
nf_payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(pkt), len(pkt))
t = threading.Timer(10, setVerdict, [pkt, nf_payload])
t.start()
It crashs throwing no exception (surely is a low level crash). Can i implement delay using directly libnetfilter like this or I must copy pkt, drop it and send the copy using standard socket.socket.send()?
Thank you
Sorry for the late reply, but I needed to do something like this, although slightly more complicated. I used the C-version of the library and I copied packets to a buffer inside my program, and then issued a DROP verdict. After a timeout relating to your delay, I reinject the packet using a raw socket. This works fine, and seems quite efficient.
I think the reason for your crash was due to the fact that you didnt issue a verdict fast enough.
I can't answer your question, but why not use the "netem" traffic-queue module on the outgoing interface to delay the packet?
It is possible to configure tc queues to apply different policies to packets which are "marked" in some way; the normal way to mark such packets is with a netfilter module (e.g. iptables or nfqueue).

Fast Bluetooth Name Lookup

I'm experiencing problems in fast detecting nearby bluetooth devices' names (human names, not BTADDR)
I found a very interesting Python-based project here [http://code.google.com/p/python-bluetooth-scanner/] but the issue basically is that, while looking for BTADDR and RSSI is fast, detecting the "human" name of the device takes longer (even if they say it should work in the code)
I know I can look up for names with:
the simple "hcitool scan" console command, which is slow
the bluetooth.lookup_name(address) method of module PyBlueZ
as written in the project, reported below
-
sock = bluetooth.bluez._gethcisock(device)
timeoutms = int(timeout * 1000)
try:
name = bluetooth._bluetooth.hci_read_remote_name( sock, address, timeoutms )
except bluetooth._bt.error, e:
print e
logger.debug("Lookup Failed")
name = None
sock.close()
return name
A brief insight: the system uses 2 dongles to detect nearby BT devices, if I make them looking up for names, they spend more time hence remaining locked, when a new device is discovered, devices are still locked in looking for the previous one's name and the whole software hangs.
I'm running Ubuntu 10.10 in a VirtualBox in WindowsXP environment and a couple BT 2.1 dongles.
Apart from creating a list of "unnamed" devices to look for as soon as my dongles are done with the previous ones. Do you know any way I could do that faster?
Finding a remote device's friendly name is generally a two-step process. First, you perform an inquiry scan "discovering" nearby device that are discoverable. Second, you need to connect to
the remote device and "ask" it for its friendly name. Part of the delay comes from the fact that these two steps are often not performed in an interleaved manner (i.e., a device is discovered and then the name is queried). Oftentimes, you run an inquiry scan until completion (which takes a while) and then you ask specific devices for their friendly names. (To interleave the discovery and name lookup, you would start the discovery, wait until you "discover" a new device, cancel the discovery, query for the name, then restart the discovery. Repeat until no new devices are found. Some stacks do this for you automatically. Some don't.)
If both devices support Extended Inquiry Response (added in the Bluetooth 2.1 specification), the friendly name is returned as part of the discovery process. This speeds things up considerably, but it needs to be supported further down in the stack.

Categories