Static binding serial ports in ubuntu on Raspberry Pi - raspberry-pi

I am running a setup of 4 ESP32 which are connected to a PI through serial connections. Is there a way to statically bind all of the ESPs, so the port order after every boot doesn't matter?
It also has to be ID unspecific, since I'm running several similar setups and the code should fit all.
Also, in case of a replacement, I just want the system to know that there is the same device on the same port.
I'm sorry if I wrote it confusing, but generally, I want the ESPs to be replaceable, while the port describes the function of the device.
Thanks guys and happy coding

The only practical approach is ID based, sorry. USB devices are created in the same order they are initialized, so no guarantees whatsoever. If it helps, here's an udev rule which creates symlinks from the serial number of the Silabs USB-serial chip, e.g. /dev/EDK-d80d38b81e. Tested with DevKitC and LOLIN32 boards.
# udev rules for the Espressif ESP32-DevKitC and Wemos LOLIN32 dev boards to
# allocate symlinks with fixed names for each device using its serial number.
# CP2102N/CP2104N with idVendor=10c4, idProduct=ea60
#
# Instructions:
# 1. Copy udev rules and restart daemon:
# $ sudo ln -s "$PWD/70-cp210xn_ESP32-DevKitC.rules" /etc/udev/rules.d/ && sudo systemctl restart udev
# 2. Disconnect and connect the board to USB
# Espressif ESP32-DevKitC with CP2102N.
# Sample serial in chip is "7063b99e4b74ea11b6f52208cf25bb41" where only first
# 10 chars seem to be unique. We cut the serial down to those and create a
# symlink from the result, e.g. "/dev/EDK-7063b99e4b"
SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ATTRS{manufacturer}=="Silicon Labs", ATTRS{product}=="CP2102N USB to UART Bridge Controller", PROGRAM="/usr/bin/awk -- 'BEGIN { print substr(\"$attr{serial}\",1,10) }'" SYMLINK+="EDK-%c", GROUP="dialout", MODE="0660"
# Wemos LOLIN32 with CP2104N, sample serial in chip is "01DFA32C".
# We create a symlink "EDK-01DFA32C" (cropping to first 10 chars just in case).
SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", ATTRS{manufacturer}=="Silicon Labs", ATTRS{product}=="CP2104 USB to UART Bridge Controller", PROGRAM="/usr/bin/awk -- 'BEGIN { print substr(\"$attr{serial}\",1,10) }'" SYMLINK+="EDK-%c", GROUP="dialout", MODE="0660"

I had a similar issue, where I needed to statically bind physical USB ports to devices, in my case they are cheap serial/USB converters and they don't have a unique ID, so the only way to identify them was using physical port mapping.
I solved creating udev rules with aliases, like this:
SUBSYSTEM=="tty",KERNELS=="2-2:1.0",SYMLINK+="device1"
SUBSYSTEM=="tty",KERNELS=="2-3:1.0",SYMLINK+="device2"
Now I open the connection with the devices using the symlinks. In this way as long as you don't swap connectors, each device will always have the same symlink.

Unfortunately, the Raspberry Pi (don't know about linux in general) is reassigning the USB ports after each boot or when connecting/disconnecting devices. So the serial port numbers change more or less randomly. You need some other way of identifying which device is which. Probably the best method is to use unused pins for identifying the device and query the device id from the host at startup, so you know which ESP32 is connected on which port.

Related

Will an I2C device get detected when it is connected to Raspberry Pi when there is no Driver and dts related to it?

I'm in confusion that will an I2C device get detected in raspberry pi even when there
are no device drivers and DTS files related to it.
Will it show up when we use this command
ls /dev/i2c-*
and are we able to detect its address when I try to probe using
i2cdetect -y bus_number
In short:
... when there are no device drivers and DTS files related to it.
Will it show up when we use this command
ls /dev/i2c-*
No. This command will list available I2C buses, not devices.
and are we able to detect its address when I try to probe using
i2cdetect -y bus_number
Maybe. In most cases yes.
A bit more elaborated:
Depending of what kind of I2C device it is, and what you want to do with it, you might still be able to communicate with it.
driver - best case
If you have relevant device tree change to describe this I2C device (on what bus it is located, its address, extra signals if needed - like interrupt pin, etc) and associated driver is present (built-in or as a module, check *_defconfig options in Linux kernel source) - driver should probe device during either boot or manual module loading.
Why best case? If you have a driver you don't have to think about protocols and programming, and, as an example, reading a value from ADC device might be as simple as:
root#pi:~# cat /sys/bus/iio/devices/iio:device0/in_voltage0_raw
291
i2ctools
Another approach would be to use i2cget/i2cset tools from i2ctools package. No device tree changes needed. With these tools you can talk with any unclaimed I2C device on any enabled I2C bus in device tree.
You'll need to implement communication with I2C device by your own. From security and stability perspective - IMO this is the worst case to go, but is good for hardware debugging and, in some cases, initial bring-up.
Example is here.
Note regarding i2cdetect - this command tries to detect devices on particular bus, but gives no warranty. As per man i2cdetect:
As there is no standard I2C detection command, i2cdetect uses arbitrary SMBus commands (namely SMBus quick write and SMBus receive byte) to probe for devices.

No internet through GSM connection, possible interface issue

I have a problem with getting GSM connection to work.
Currently used:
Advantech UNO-2272G device
Ubuntu 18.04
NetworkManager/nmcli package
The card works when put in a mobile phone.
*Note: following screenshots are made over SSH and remotely, as the device is currently plugged in ethernet until this issue is resolved.
This is current state of "nmcli" command:
nmcli print
The system connection for GSM is called "radi". My guess is that somehow the interface of that connection is trying to work with the other interface (underlined in red), which in turn is trying to get its DNS conf from router (to which it currently is connected with ethernet, but nothing changes if device is plugged out from router and NetworkManager and network is restarted, it still tries to get to router for its DNS).
This is current state of "ip addr" command:
ip addr
This is current state of /etc/network/interfaces file:
interfaces
This is current state of /etc/NetworkManager/system-connections/radi file:
systemconnection
So, the question is, what am I missing here? Is it the interface issue as written above, or something else entirely?
Disclaimer: I am not that proficient in the stuff presented here, most if not all of it was configured following guidelines on the internet.
Hey I'm not expert in this but I do have a different cellular modem connected to a linux system (RPI) and working with NetworkManager (and ModemManager). My modem was connected by a serial UART port (ttyACM0) so that seems similar to what you have done.
When I configured my cellular connection profile in NM I had to setup the ppp section of the connection profile on top of the gsm part. I also went into my ppp options (on the host) and configured those to match a chat script that came from my modem manufacturer. WHen NetworkManager runs a ppp interface it expects the ppp options for the pppd (daemon) to be configured properly.
Here is the ppp section of my NetworkManager cellular connection settings file. Most are defaults and in my case I only added the baud rate for my modem (since it was connected to a UART).
ppp.noauth: yes
ppp.refuse-eap: no
ppp.refuse-pap: no
ppp.refuse-chap: no
ppp.refuse-mschap: no
ppp.refuse-mschapv2: no
ppp.nobsdcomp: no
ppp.nodeflate: no
ppp.no-vj-comp: no
ppp.require-mppe: no
ppp.require-mppe-128: no
ppp.mppe-stateful: no
ppp.crtscts: no
ppp.baud: 115200
ppp.mru: 0
ppp.mtu: auto
ppp.lcp-echo-failure: 0
ppp.lcp-echo-interval: 0
If this is not helpful then have a look at this thread on NM and routing. In their case eth0 was a local network interface and eth1 was their cellular interface
Now to save you 10 hours of troubleshooting - note that the route
metric is independent of the DNS priority! So if you still have
connectivity issues, make sure it's not a DNS resolution issue (eg.
your DHCP server is providing a dummy resolution service). If it is,
then increase the ipv4.dns-priority of your eth0 connection to make it
lower priority, and/or make sure the ipv4.dns-search of your eth1 is
set to "~" to make it the go-to option.

How to setup Xbee without X-CTU(official tool)

I try to make two raspberry pi communicate (text) with each other via XBee S2 module. Instead of using XBee shield, I connected XBee and pi with dupont lines(PIN: 3.3V, Tx, Rx, Ground).
Under pi, install minicom and
minicom -b 9600 -D /dev/ttyAMA0
I could enter XBee command mode, where I got reply 'OK' when I type some commands. My test architecture is shown below.
(C)PI-XBee (R)XBee-PI
I set same PANID and destination address as source address of each other. However, I cannot get the message from each other in minicom.
Did I miss something? Or I did need to setup with X-CTU.
Did you exit command mode before sending data (I think the command is ATCN, or just let command mode time out)? Are the modules joined to the same network? Check AI (association indicator, should be zero), SC (scan channels, identical on both modules), CH (channel) and OI (operating PAN ID). The read-only CH and OI should be the same on both modules if they're on the same network. Use ATNR to reset the network on the coordinator, and then on the router to force it to rejoin the network. Be sure to use ATWR to write your settings if you want them to stick after power cycling.
Edit: Turns out both modules had Router firmware installed, so they were both trying to join a network. The S2B has different firmware files for Coordinator and Router/End Device node types. The S2C has a single firmware and uses the setting of ATCE to select coordinator (1) or router/end device (0) operation.

Disable usb power protection on Linux (raspbian)

I'm playing arround with a Raspberry pi zero but it has some issues powering my WIFI dongle.
Nov 21 21:42:49 raspberrypi kernel: [ 456.466068] usb 1-1.1: rejected 1 configuration due to insufficient available bus power
It works, but it requires some manual labour to to turn it on:
echo 1 > /sys/bus/usb/devices/1-1.1/bConfigurationValue
In my case, this enables the device and then all is well. However, I need to repeat this step after each boot (tried init script, no luck yet).
My question is how to solve this problem. Preferably i'd just like to disable the power check (if possible) and just have the kernel configure the device.
Is this possibe/is there a better solution?
I had a similar problem (my router sometimes acted weird and my Pi didn't reconnect) and I use a script that checks every minute if the Pi has a wifi connection, if not it "reboots the wifi". (Got it from this tutorial http://alexba.in/blog/2015/01/14/automatically-reconnecting-wifi-on-a-raspberrypi/)
#!/bin/bash
# The IP for the server you wish to ping (8.8.8.8 is a public Google DNS server)
SERVER=8.8.8.8
# Only send two pings, sending output to /dev/null
ping -c2 ${SERVER} > /dev/null
# If the return code from ping ($?) is not 0 (meaning there was an error)
if [ $? != 0 ]
then
# Restart the wireless interface
ifdown --force wlan0
ifup wlan0
fi
Although it probably is not the most elegant solution you could just follow this tutorial and replace
ifdown --force wlan0
ifup wlan0
with this I guess:
echo 1 > /sys/bus/usb/devices/1-1.1/bConfigurationValue
But since you say that you say that you just need to run this script on boot and it works until you power the Pi back off again making a simple python script like
import os
os.system("echo 1 > /sys/bus/usb/devices/1-1.1/bConfigurationValue")
and making sure it starts on boot by adding this line in the /etc/rc.local file just above the exit 0 in that file:
sudo python /path/to/the/python/script/this_script.py
This should do the trick although I'm pretty sure the Pi has a good reason disabling your Wifi dongle (I'm pretty sure you could 'burn out' your Pi by using to much current if there was no protection). What Wifi dongle are you using and what are your powering you Pi with? I'm sorry for my not so clear answer, I'm just starting to get into the Pi but I hope I was at least of some help.

Passive WiFi detection system using WiFi router

As part of my project requirement I want to make a system which will detect all the WiFi devices in my router range either its connected or not, I did some research on it then I found something like wireshark ,kismate etc I just tried the wireshark by making my Mac machine's WiFi as an adhoc network and its all fine I am able to list all the WiFi devices in wireshark, now I want to make a real-time system based on a real WiFi router I don't know how I will configure my router using my PC and how I will monitor the router from my PC , one more thing if I am using this wireshark how I will use this data for my requirement. If any one worked with similar scenarios please help me..thanks in advance
To do that you will need more than the usual API that you have on commercial WiFi routers (by that I mean a full SSH access). I would:
flash my router with OpenWRT (you can search for your router on this page for detailed instructions)
Install the aircrack-ng suite on the flashed router with
opkg update
opkg install aircrack-ng
Put my WiFi card in monitor mode and run the airodump service:
airmon-ng start wlan0 #Put your NIC in monitor mode
airodump-ng mon0 #Sniff surrounding packets
You don't necessarily have to install aircrack-ng, you can just put your card in monitor mode using command line (look at the documentation for your WiFi driver) and then run tcpdump (command line equivalent to wireshark) but aircrack works very well and has a nice format.
Also, I should warn you that you can brick your router by flashing it. I never had such a problem when flashing router mentioned on the OpenWRT wiki and there are (most of the times) ways to restore a bricked router depending on the brand but I am not responsible if you break it ;)