Reset USB Devices on RaspberryPi Ubuntu

Hey everyone,

I ran into a small issue today on my RaspberryPi. Occasionally, when restarting scripts that utilised usb devices (lidar, arduino) the usb connections were locking up. This meant that when I tried to restart the scripts I wasn’t able to reconnect.

My initial solution was to simply restart the Pi each time it occurred. Unfortunately, this became pretty tedious when testing required a lot of relaunching.

In order to get around having to restart each time I used usbreset in a small script attached to my launch files. This allowed me to ensure that all usb devices were ready to go.

for id in $(lsusb | grep -oP 'ID \S+' | awk '{print $2}'); do
    echo "Resetting device $id"
    sudo usbreset "$id"
    sleep 1  # Add a small delay between resets
done

Note that you can also simply paste this into your shell. This was done on a RaspberryPi that has been imaged with Ubuntu, but I expect it will work on Raspbian as well.

Automatically Shutdown a RaspberryPi when the Network is not Reachable

Hi everyone,

I’ve had a bit of an issue recently with my RaspberryPi disconnecting when I’m flooding the network with camera images. Unfortunately I’m using a dodgy TP-Link WiFi range extender and it doesn’t handle the load well at all.

The issue with this is that it means I cannot connect to the RaspberryPi to safely shut it down. I can switch off the power but this risks corrupting the SD card. In order to get around this I added a script to automatically shutdown when the Pi cannot reach my server for 30 seconds (with help from Co-Pilot!).

target_ip="192.168.0.1"  # Replace with your target IP address
ping_timeout=30           # Timeout in seconds
while true; do
    if ping -c 1 -W $ping_timeout $target_ip >/dev/null; then
        echo "Target IP is reachable."
    else
        echo "Target IP is not reachable. Initiating shutdown..."
        sudo shutdown -h now  # Change to "poweroff" if "shutdown" is not available
    fi
    sleep 1
done

To use the script:

  • 1. Open a text editor and paste the script into a new file.
  • 2. Replace the target_ip variable with the IP address you want to monitor.
  • 3. Save the file with a .sh extension (e.g., shutdown_script.sh).
  • 4. Open a terminal and navigate to the directory where you saved the script.
  • 5. Make the script executable by running the following command: chmod +x shutdown_script.sh.
  • 6. Run the script using the following command: ./shutdown_script.sh.

The script will continuously ping the target IP address every second. If the target IP becomes unreachable for 30 seconds, it will shutdown the pi. You might need to run the script with root privileges (sudo) to execute the shutdown command successfully.

To test it I pointed the script at a VM on my main computer and then paused the VM.

chris@robot1:~/robot_ws/src/my_bot$ sudo ./auto_shutdown.sh
[sudo] password for chris: 
Target IP is reachable.
...
Target IP is reachable.
Target IP is reachable.
Target IP is not reachable. Initiating shutdown...

I then tried pinging the Pi from my main computer to confirm it had shutdown:

Chris@Chriss-Mini-8 Journal % ping 192.168.0.123
PING 192.168.0.123 (192.168.0.123): 56 data bytes
ping: sendto: Host is down
ping: sendto: Host is down

Wheel Going in the Wrong Direction – RVIZ2 and FoxGlove

Hi everyone,

I hope you’re having a good break! I’m currently following this tutorial and messing around with a diffdrive robot. After making a few changes I noticed that my simulations were playing up. Strangely, the robot itself was still working perfectly fine.

The problem I was having was that even though my robot was driving forward the simulations seemed to think that the left wheel was going backwards. Initially I suspected this was an issue with my robot’s definition but even when returning to a known working state the issue persisted.

Eventually, I realised that this meant it had to be a hardware issue. I am using an Arduino and two L298N motor controllers for the motors that run my wheels. The arduino then publishes my encoding counts over serial.

To debug this setup, I used miniterm to communicate with the arduino and view the serial output. To get this going I had to track down which serial port had the arduino connected:

ubuntu@ubuntu:~/robot_ws$ lsusb
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 006: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter

Alternatively, ls /dev/ttyUSB* would also work. I also needed the baud rate which is set to 57600. This allowed me to connect, move the motors forward and also see the encoding counts:

ubuntu@ubuntu:~/robot_ws$ miniterm -e /dev/ttyUSB0 57600
--- Miniterm on /dev/ttyUSB0 57600,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
e
0 0
o 255 255
OK
e
-5531 5572
e
-8120 8222
e
-8120 8222

The issue became obvious with the left wheel outputting a negative value. The fix for this was pretty simple. Reversing the pins outputting the encoding count for the left wheel reverses the counter. Re-running the miniterm test showed both wheels with a positive count:

ubuntu@ubuntu:~/robot_ws$ miniterm -e /dev/ttyUSB0 57600
--- Miniterm on /dev/ttyUSB0 57600,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
e
0 0
o 255 255
OK
e
8146 8211

RaspberryPi Camera not detected – Ubuntu 20.04.5 LTS

Hi everyone,

I ran into a bit of an issue with a RaspberryPi 4 running Ubuntu 20.04.5 this morning. Running vcgencmd get_camera should have returned supported=1 detected=1 but instead I was getting supported=0 detected=0.

This was a bit of a hard one to track down with Google but I eventually came across a stackoverflow post suggesting the following:

  • Run sudo nano /boot/firmware/config.txt
  • Add start_x=1 at the end
  • Reboot

Check out this post for more info: https://askubuntu.com/a/1244259/770194.

If you’re using a new camera you may also run into this error:

mmal: Cannot read camera info, keeping the defaults for OV5647
mmal: mmal_vc_component_create: failed to create component 'vc.ril.camera' (1:ENOMEM)
mmal: mmal_component_create_core: could not create component 'vc.ril.camera' (1)
mmal: Failed to create camera component
mmal: main: Failed to create camera component
mmal: Only 76M of gpu_mem is configured. Try running "sudo raspi-config" and ensure that "memory_split" has a value of 128 or greater

The fix for this one is to simply append another line to /boot/firmware/config.txt. All you’ll need is gpu_mem=128.

Another issue you might run into is VHCI initialization failed. Generally, that just means you need to add your current user to the video group.

# Check your current user's groups.
groups

# Add your user to the video group.
sudo usermod -aG video <username>

Once you’ve added the group, rebooting should be enough to get past that error.

Change i2c address of ina219

Hi everyone,

I wanted to use ina219 with pca9685 but they shared the same i2c address 0x4:
download0.

Luckily, there’s a fairly easy fix for this. All we need to do is solder two pins together. We’re going to bridge a0 and this will change our address to 0x41.

In order to check these run sudo i2cdetect -y 1 pm the raspberry pi:
download

After soldering it becomes:
download

You can solder a combination of pins for different addresses:
None = 0x40 (default)
A0 = 0x41
A1 = 0x44 (the one I’ve soldered to get 44)
A0 + A1 = 0x45

A4988 Stepper motor RaspberryPi

We’re using a 42shd0034-20B Geetech stepping motor taken from a 3d printer:
download

We’ll be driving it with an A4988 stepper motor controller. You can pick up five packs of these for less than $2 online – definitely worth having a few extras around:
download

The datasheet is available here: https://www.pololu.com/file/download/A4988.pdf?file_id=0J450

The following diagram illustrates what we’ll be doing:
download

Once everything is connected it’ll end up looking something like this:
download

To start, connect your stepping and direction pins. I’ve used GPIO16 for stepping and GPIO21 for direction:
download

Each time GPIO16 is set to HIGH it will make the stepper motor take one step. When the direction pin is HIGH the stepper motor will go clockwise, when it’s LOW, anti-clockwise.

If you’re not using the sleep functionality, connect the RESET and SLP pins together and then wire them directly to 3.3v:
download

Using a separate power source wire 12v to the GND and VMOT pins. You should also place a capacitor across these pins as close to the board as possible. Generally the longest leg is positive. You’ll also need to connect the external GND to the Raspberry Pi’s GND:
download

Connect the four pins of the stepper motor:
download

Connect the A4988 to 3.3v and common GND:
download

The code is pretty straight forward but I’ve provided a class below to help you get started:


# System imports
import RPi.GPIO as GPIO
from time import sleep

class StepperHandler():

__CLOCKWISE = 1
__ANTI_CLOCKWISE = 0

def __init__(self, stepPin, directionPin, delay=0.208, stepsPerRevolution=200):

# Configure instance
self.CLOCKWISE = self.__CLOCKWISE
self.ANTI_CLOCKWISE = self.__ANTI_CLOCKWISE
self.StepPin = stepPin
self.DirectionPin = directionPin
self.Delay = delay
self.RevolutionSteps = stepsPerRevolution
self.CurrentDirection = self.CLOCKWISE
self.CurrentStep = 0

# Setup gpio pins
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(self.StepPin, GPIO.OUT)
GPIO.setup(self.DirectionPin, GPIO.OUT)

def Step(self, stepsToTake, direction = __CLOCKWISE):

print("Step Pin: " + str(self.StepPin) + " Direction Pin: " + str(self.DirectionPin) + " Delay: " + str(self.Delay))
print("Taking " + str(stepsToTake) + " steps.")

# Set the direction
GPIO.output(self.DirectionPin, direction)

# Take requested number of steps
for x in range(stepsToTake):
print("Step " + str(x))
GPIO.output(self.StepPin, GPIO.HIGH)
self.CurrentStep += 1
sleep(self.Delay)
GPIO.output(self.StepPin, GPIO.LOW)
sleep(self.Delay)

# Define pins
STEP_PIN = 16
DIRECTION_PIN = 21

# Create a new instance of our stepper class (note if you're just starting out with this you're probably better off using a delay of ~0.1)
stepperHandler = StepperHandler(STEP_PIN, DIRECTION_PIN, 0.0025)

# Go forwards once
stepperHandler.Step(200)

# Go backwards once
stepperHandler.Step(200, stepperHandler.ANTI_CLOCKWISE)

Update Wireless Info on Raspberry Pi

Hi everyone,

Just a quick post on how to configure wireless info on a raspberry pi. To start with, open the config file:

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

You can then add any number of connections to the file with varying priorities:

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=AU

network={
        ssid="Mobile Network"
        psk="YOUR_PASSWORD"
        key_mgmt=WPA-PSK
        priority=2
}

network={
        ssid="Home Network"
        psk="YOUR_PASSWORD"
        key_mgmt=WPA-PSK
        priority=10
}

Then save the file. Your raspberry pi will now connect to the network with the highest priority first (home network), when that’s not available it will use the network with the lower priority (mobile network).

The official doco is actually pretty good for this use case if you need more info: https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md

Using INA219 (GY-219) with the Raspberry Pi

Hi everyone,

I’ve just setup an INA219B Voltage/Current sensor on my RaspberryPi. Just thought I’d link the tutorials and libraries I used – there’s a lot of really useful info out there.

Install the following library via git: https://github.com/chrisb2/pi_ina219
sudo pip3 install pi-ina219

Follow this tutorial: https://www.rototron.info/raspberry-pi-ina219-tutorial/

Misc Notes

  • Common ground is required
  • Vin – and Vin+ are attached to +, neither goes to ground

Custom Sensor Address
na = INA219(SHUNT_OHMS, MAX_EXPECTED_AMPS, address=0x41)

Can be configured via the following:

https://www.rototron.info/raspberry-pi-ina219-tutorial/
https://www.rototron.info/raspberry-pi-ina219-tutorial/

Enable Low Power Between Reads
ina.configure(ina.RANGE_16V)
while True:
print "Voltage : %.3f V" % ina.voltage()
ina.sleep()
time.sleep(60)
ina.wake()

If you’re getting the following error:

OSError: [Errno 121] Remote I/O error

Run the following command:

i2cdetect -y 1

And check to ensure that your device is showing up on 40. If it’s a different number you’ll just need to update the address in your code e.g. (0x40, 0x41, etc.)

Mini-360 DC-DC Buck Converter – Incorrect Voltage 10v Instead of 5v

Hi everyone,

I’ve been playing around with a few DC-DC buck converters similar to these ones: https://www.amazon.com.au/UEB-Power-Converter-Module-Supply/dp/B078CXHWXC/ref=sr_1_fkmr1_1?ie=UTF8&qid=1519030369&sr=8-1-fkmr1&keywords=mini+360+buck+converter

I had expected 5v output from my 12v supply but when I hooked it up to a multimeter I found I was getting just over 10v. This would fry pretty much everything in my circuit so I was pretty worried.

After a bit of research, I came across a thread on eevblog that mentioned a screw for adjustment. Looking closely you can see that there is a small screw on the side of the chip. Turning this quarter of a rotation anti-clockwise put mine at exactly 5.04 volts.

A few other small tips:

  • The thread seems to indicate that some models require a lot more turning (up to 30 seconds for one poster).
  • I had to push down fairly hard to get it to actually turn the part underneath instead of just the metal cover

Hopefully this helps someone else out!

Eevblog: https://www.eevblog.com/forum/beginners/dc-dc-buck-converter-step-down-module-lm2596-power-supply/

Thanks,
Chris

Duinotech Hall Effect Sensor with RaspberryPi

Hi everyone,

This is just a quick post to cover how the Duinotech hall effect sensor module (XC-4434) can be hooked up to a RaspberryPi.

Sample Code

The code below will output a zero when the sensor is activated by a magnet, otherwise a zero.


import time
import datetime
import RPi.GPIO as GPIO

# Define constants
BUCKET_HALL_EFFECT_SIG_PIN = 14

# Setup GPIO pins
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(BUCKET_HALL_EFFECT_SIG_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Important

while True:
print(str(GPIO.input(BUCKET_HALL_EFFECT_SIG_PIN))
time.sleep(0.5)

Wiring

Example

When near a magnetic field the light on the sensor will turn on. If you’re using the sample code above, a zero will be shown when close to a magnet, otherwise a 1.

Misc

Purchased from: https://www.jaycar.com.au/arduino-compatible-hall-effect-sensor-module/p/XC4434

Spec Sheet: Z7275