How to select a particular USB port on raspberry pi 3B+ to program two arduino boards with arduino-mk? - linux

I have a python program on my Raspberry pi 3B+ witch updates an Arduino mega2560 and an Arduino Uno by using Arduino-mk through bash commands. Each Arduino has its own code folder with its code (.ino) and a Makefile which looks like:
ARDUINO_DIR = /usr/share/arduino
ARDUINO_PORT = /dev/ttyUSB0 (here is the problem)
USER_LIB_PATH = /home/pi/sketchbook/libraries
BOARD_TAG = mega2560 (Uno for the uno one)
include /usr/share/arduino/Arduino.mk
When I call the following command:
os.system("(cd ~/sketchbook/mega; make upload clean)")
with only the mega connected on the USB port everything works and the mega gets programed (same with Uno only). but when I try to get both done:
os.system("(cd ~/sketchbook/mega; make upload clean)")
os.system("(cd ~/sketchbook/uno; make upload clean)")
arduino-mk can't program the Uno (multiple timeouts).
At first the second line in Makefile was:
ARDUINO_PORT = /dev/ttyAMC0
but it was not working so I checked on the web and found that some Arduino copies worked better with:
ARDUINO_PORT = /dev/ttyUSB0
Then it worked but I couldn't get any result with ttyUSB1 up to ttyUSB3 (I hoped it would work like COM ports on windows).
I also noticed that if I keep testing with ttyUSB0 and try with each physical USB port and worked so ttyUSB0 refers to the four physical ports right?
Please how can I get one particular port name?
Or is there an other way to make Arduino-mk work?

Plug in one device at a time and look at the output of ls -l /dev/serial/by-id/, you should see a symlink to the actual device node, but uniquely named for your specific device.
You can then set ARDUINO_PORT=/dev/serial/by-id/unique_name in the respective makefiles.

Related

Configure Yocto image on CM4 to work with Official Raspberry Pi Display

I've got a Raspberry Pi CM4 (with eMMC) running an image built using Yocto. The CM4 is running on the official CMIO board.
I want to use the official Raspberry Pi 7" Display on this, using the DSI interface, but I have trouble getting it working. The display does not turn on at all. I need help configuring my image, or my yocto build correctly to allow me to use this display.
What worked:
It works as expected on a Raspberry Pi 4 Mode B. I can flash my Yocto-based image to an SD card and the device boots as expected with the display working
It works on the CM4 using the official Raspberry Pi OS image, but only after I do one of the following:
a. Add the dt-blob.bin file as described in the Compute Model Documentation
b. I add the following line to the config.txt file in the boot folder: dtoverlay=vc4-fkms-v3d
Issue:
When I flash my Yocto-based image to the Raspberry Pi, the screen does not work. The device boots up, and I can get an output through HDMI, but not through the DSI interface.
What I have tried
I've downloaded the dt-blob.bin file to both the /uboot/ and /boot/ folders on my device and rebooted, but it had no effect
I added the vc4-kms-dsi-7inch dtbo to the /uboot/overlays folder and added dtoverlay=vc4-fkms-v3dto config.txt in /uboot/ and it still didn't have any effect.
It feels like this is a device-tree related issue. And I imagine there is some difference in pin usage between the Raspberry Pi 4B and the CM4, which makes my image not work on the CM4.
One thing I did note, the image I'm using has dtoverlay=vc4-fkms-v3d in config.txt while the official image has dtoverlay=vc4-kms-v3d. I don't know if that makes a difference, but changing it on my image to fkms and rebooting didn't have any effect.
This is an extract from the local.conf file for my yocto build:
MACHINE ?= "raspberrypi4"
ENABLE_DWC2_HOST = "1"
RPI_USE_U_BOOT = "1"
MENDER_BOOT_PART_SIZE_MB = "40"
IMAGE_INSTALL_append = " kernel-image kernel-devicetree"
IMAGE_FSTYPES_remove += " rpi-sdimg"
MENDER_FEATURES_ENABLE_append = " mender-uboot mender-image-sd"
MENDER_FEATURES_DISABLE_append = " mender-grub mender-image-uefi"
MENDER_SERVER_URL = "https://hosted.mender.io"
MENDER_TENANT_TOKEN = [censored]
This build uses the meta-raspberrypi and meta-rpi64 layers.
Any help to understand the problem and get this display working would be appreciated.
Thanks!
I managed to solve this issue in the end.
The local.conf file had another conflicting MACHINE ?= "raspberrypi3-cm" command.
I removed this and created the image again.
Then, while still connected to the PC as a storage device, I added the dt-blob.bin file to the /boot/ drive.
I then booted up the CM4, and the display worked.
Next step would be to figure out how to implement that device tree overlay into the yocto build, but that's out of the scope of this question.

device tree, change fixed link ethernet phy speed runtime

I'm working with a custom IMX8 board with a phy that is not supported by the Linux kernel (it's a clause 45 automotive oabr transceiver).
The phy is actually working, and its mdio bus and digital IO's are controlled with an userspace application.
To acheive this i had to bind it in the device tree with the fixed-link property as below.
...
port#0 {
reg = <0x00>;
label = "oabr";
phy-mode = "rgmii";
fixed-link {
speed = <1000>;
full-duplex;
pause;
asym-pause;
};
};
...
Now... the question is, i would like to change the speed of the phy from 1000 to 100, i'm able to do it if configure the phy AND change the device tree, but this implies a reboot of the device to load a new dts file.
Is there a way to get it working runtime?
Thanks a lot,
Marco
In order to add or load a device tree blob in runtime, the only way is to use Linux overlay.
But the problem is that NXP does not support it in its linux-imx kernel , you can see their post about it here.
If you don't make the change permanently to your main device tree file used for the image, I can advise you of doing this:
Create another dts (Ex: new-phy.dts) that includes the main dts and add your override node there
Add the new dtb name to your ${MACHINE}.conf KERNEL_DEVICETREE variable:
KERNEL_DEVICETREE += "freescale/new-phy.dtb"
Now you need to choose it once you boot from u-boot CLI, like:
u-boot> setenv fdt_file new-phy.dtb
u-boot> saveenv
u-boot> boot
Or, you can set it in your u-boot/configs/${MACHINE}_defconfig:
CONFIG_DEFAULT_FDT_FILE="new-phy.dtb"
Otherwise, you can try to add the overlay support for the kernel you are using.
Toradex has SOMs and EVKs based on IMX8M and they are working with overlays, you can take a look here and try to understand what they did to support it.

PyUSB Barcode Scanner without Button by Honeywell

I have a Honeywell N5600 that I'm trying to use, but I don't get it to scan anything.
The device is recognized as /dev/hidraw1, but as it does not have any button to press, I cannot trigger the scan and thus, when I try to read from it, it just waits forever.
I started creating a python program, that seems to be able to communicate with it (different return values):
VENDOR_LEGO = 0x0c2e
PRODUCT_EV3 = 0x0967
device = usb.core.find(idVendor=VENDOR_LEGO, idProduct=PRODUCT_EV3)
device.detach_kernel_driver(0)
#"TRGMOD8." would - when scanned (which I cannot do, at this point) - activate a permanent scanning mode
device.ctrl_transfer(0x21, 0x9, wValue=0x200, wIndex=0x00, data_or_wLength='TRGMOD8.')
#8 is returned
device.ctrl_transfer(0x21, 0x9, wValue=0x200, wIndex=0x00, data_or_wLength='PAPSPC.')
#7 is returned
Unluckily the link given in this post is not reachable anymore. It seems like it would have solved my problem.
How can I activate the scanning?
The document on Honeywell N5600 is as follows.
N5600 OEM 2D Imager Data Sheet
N56XX Decoded Engine User's Guide
You need a Windows PC that can connect to the Internet, but there is a tool called EZConfig-Scanning that configures and maintains the scanner.
EZConfig Device Management Data Sheet
Perhaps the recognition device /dev/hidraw1 is probably because the scanner is set to USB HID Bar Code Scanner mode.
If you change the setting to USB Keyboard(PC/Mac), it is always readable and the barcode you read will be notified as keyboard input.
By changing the setting to USB Serial, reading start/stop can be controlled by SerialPort command transmission. The barcode read is notified by receiving data from SerialPort.

Persistant name in usb device which open several connections || connect USB to specific port [duplicate]

This question already has an answer here:
Change default names for USB virtual serial ports in Linux
(1 answer)
Closed 5 years ago.
I am trying to add a persistent name to a USB device connection to be able to connect to it by writing /dev/multitech instead of /devttyACMx. I have been able to do so with other devices by adding an udev rule, for example:
SUBSYSTEM=="tty", ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="0021",ATTRS{serial}=="356136967675473", SYMLINK+="multitech"
The problem is that this device open 6 connections, from ttyACM0 to ttyACM5 (if nothing else connected) but to use it you have to use the ttyACM0 (meaning the first connection) but if you write:
$ ls -l /dev/multitech
you may get whatever connection it has open, maybe ttyACM0 or maybe ttyACM3... the thing is that this is useless for me, since it sometimes works and sometimes it does not. Is there anything I can do about this?
Thanks a lot!!
normally each connection the device establishes has its own interface or alternate setting in USB tree structure. in udev rules you can use several other attributes (all you can display using udevadm info --attribute-walk http://www.beyondlogic.org/usbnutshell/usb5.shtml#InterfaceDescriptors )
run an attribute walk with udevadm info --attribute-walk + /sys/class/... or /dev/... path for your device to see the identifiers of the several usb interfaces it has in its usb structure and try to include them in the udev rule, i.e. using the following attributes:
ATTRS{bAlternateSetting}=="..."
ATTRS{bInterfaceClass}=="..."
ATTRS{bInterfaceNumber}=="..."
ATTRS{bInterfaceProtocol}=="..."
ATTRS{bInterfaceSubClass}=="..."
try to assign a specific /dev/ttyACMx for any interface the device has in its usb structure and try to assign the top-level interface in the usb structure to /dev/ttyACM0 ...
http://weininger.net/how-to-write-udev-rules-for-usb-devices.html
Change default names for USB virtual serial ports in Linux
This post was the solution to my troubles, instead of using the /devttyACMx
y changed to used the names in /dev/serial/by-id/
up until now it has worked fine, if it stops doing it I will post it

Automate Bluetooth Pairing/Trusting in Bluez5

I've been working on making my RPi 2 function like a car bluetooth receiver and all is well, except I have no idea how I could automate the pairing of bluetooth devices in Bluez5. In the past I would've used the bluetooth agent and a simple script, but that seems to have gone out the window with the move from 4 -> 5. The nature of the setup means I have no kb/mouse on the RPi once its in the car, so it needs to be a fully automated setup where anyone can scan for the RPi, and if the probably hard-coded PIN is correct, the trusting of the device needs to be automatically done, no cli input.
I've searched all over the web but everyone seems to say that using bluetoothctl works for them, but in this particular setup where I'd like to be able to have friends pair their own phones, having to trust devices with the RPi out of the car isn't ideal.
I'm not sure why you say using a simple script is not possible with bluez5. I think you can do it. Below is one example how.
Download the bluez5 source and edit test/simple-agent. Comment out the lines of code as shown below:
def RequestAuthorization(self, device):
print("RequestAuthorization (%s)" % (device))
#auth = ask("Authorize? (yes/no): ")
#if (auth == "yes"):
return
#raise Rejected("Pairing rejected")
What that does it remove the prompt for authorisation and always accepts the pairing request.
Can now start the simple-agent with the NoInputNoOutput capability so that it uses simple pairing and will go through the above code path:
./simple-agent -c NoInputNoOutput
After that you should be able to pair with the RPi without any user prompt or PIN.
Note that this is just one example of what you can do. If say you wanted to have a hard coded PIN instead of simple pairing then edit the appropriate section of the same simple-agent code to do that. I'll leave that as an exercise for you.
I already had bluez-5.43 installed. This is how to automate the pairing process on a raspberry pi.
(1) First test a line like this out to make sure bluetooth agent works:
bluez-5.43/test/simple-agent -c NoInputNoOutput
(2) To automate pairing, put this code into a shell file (I named mine pairbot.sh):
if [ "$(id -un)" != "pi" ]; then
exec sudo -u pi $0 "$#"
fi
export XAUTHORITY=/home/pi/.Xauthority
export DISPLAY=:0
lxterminal --command="/bin/bash -c '/home/pi/bluez-5.43/test/simple-agent -c NoInputNoOutput &; read'"
(3) Go to crontab:
sudo cronetab -e
(4) At the bottom add:
#reboot sleep 20 && /home/pi/pairbot.sh > /home/pi/blelog.txt 2>&1
(5) Reboot and test if it works.
My recommendation for others facing the same issue would be to look into your bluez folder (or if you don't have one install the latest version of bluez) and search for the folder that says "test" for "simple agent" to locate the file path. From here, you should be able to construct the command line shown above (1). Hopefully it will work for you too.

Resources