I am currently working on a program that acts as a USB game controller but I am having trouble finding a way to simulate keypress and stick movement...
I am hoping to work with python but anything will work.
Have a look into pyvjoy, it allows you to simulate controllers when the emulator x360ce is installed.
Have a look at this rocket league bot framework where the code allows you to simulate input.
Example:
import pyvjoy
class PlayHelper:
def __init__(self, player_index):
self.device = pyvjoy.VJoyDevice(player_index + 1)
def update_controller(self, output):
self.device.data.wAxisX = output[0]
self.device.data.wAxisY = output[1]
self.device.data.wAxisZRot = output[2]
self.device.data.wAxisZ = output[3]
self.device.data.lButtons = (1 * output[4]) + (2 * output[5]) + (4 * output[6])
self.device.data.wAxisXRot = 16383
self.device.data.wAxisYRot = 16383
self.device.update() # Send data to vJoy device
Source: https://github.com/drssoccer55/RLBot
Related
I'm using picovoice (rhino speech-to-intent and pvrecorder) on my pi0.
Here's my code:
from pvrecorder import PvRecorder
import pvrhino
#my pico voice key
key='my_access_key' #removed the access key
#rhino instance
rhino = pvrhino.create(
access_key=key,
context_path='/home/aashvikt/Desktop/MiniMate/Contexts/Mini-Mate-Commands_en_raspberry-pi_v2_1_0.rhn'
)
#created a recorder
recorder = PvRecorder(device_index=-1,frame_length=512)
recorder.start()
def getNextAudioFrame():
return recorder.read()
while True:
audioFrame = getNextAudioFrame()
isFinalized = rhino.process(audioFrame)
if isFinalized:
inference = rhino.get_inference()
if inference.is_understood:
recorder.stop()
intent = inference.intent
slots = inference.slots
print(f"intent: {intent}\nslots: {slots}")
recorder.start()
else:
print('unrecognized')
rhino.delete()
Whenever I run this code, I get an error like
[WARN]- Overflow: Reader not reading fast enough
I'm using a usb microphone. What could the problem be?
My custom sensor dashboard requests new readings every second.
This worked well, until I hooked up 3 DS18B20 temperature sensors (1-wire protocol, so all on 1 pin), which each take 750ms to provide new data.
This is the class I currently use to read the temperature of each sensor:
# ds18b20.py
# written by Roger Woollett
import os
import glob
import time
class DS18B20:
# much of this code is lifted from Adafruit web site
# This class can be used to access one or more DS18B20 temperature sensors
# It uses OS supplied drivers and one wire support must be enabled
# To do this add the line
# dtoverlay=w1-gpio
# to the end of /boot/config.txt
#
# The DS18B20 has three pins, looking at the flat side with the pins pointing
# down pin 1 is on the left
# connect pin 1 to GPIO ground
# connect pin 2 to GPIO 4 *and* GPIO 3.3V via a 4k8 (4800 ohm) pullup resistor
# connect pin 3 to GPIO 3.3V
# You can connect more than one sensor to the same set of pins
# Only one pullup resistor is required
def __init__(self):
# Load required kernel modules
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
# Find file names for the sensor(s)
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')
self._num_devices = len(device_folder)
self._device_file = list()
i = 0
while i < self._num_devices:
self._device_file.append(device_folder[i] + '/w1_slave')
i += 1
def _read_temp(self, index):
# Issue one read to one sensor
# You should not call this directly
# First check if this index exists
if index >= len(self._device_file):
return False
f = open(self._device_file[index], 'r')
data = f.read()
f.close()
return data
def tempC(self, index=0):
# Call this to get the temperature in degrees C
# detected by a sensor
data = self._read_temp(index)
retries = 0
# Check for error
if data == False:
return None
while (not "YES" in data) and (retries > 0):
# Read failed so try again
time.sleep(0.1)
#print('Read Failed', retries)
data = self._read_temp(index)
retries -= 1
if (retries == 0) and (not "YES" in data):
return None
(discard, sep, reading) = data.partition(' t=')
if reading == 85000:
# 85ºC is the boot temperature of the sensor, so ignore that value
return None
temperature = float(reading) / 1000.0
return temperature
def device_count(self):
# Call this to see how many sensors have been detected
return self._num_devices
I already tried to return the previous temperature reading if the current one isn't finished yet, however this didn't reduce the time it took to read a sensor, so I guess the only way is to do things asynchronously.
I could reduce the precision to reduce the time it takes per reading, but ideally I would read all of the sensors simultaneously on separate threads.
How can I best implement this? Or are there other ways to improve the reading speed of multiple DS18B20 sensors?
Thanks for any insights!
You're facing some limitations introduced by the Linux kernel driver. If you were interacting with the OneWire protocol directly, you would only have a single 750ms read cycle for all three sensors, rather than (3 * 750ms). When speaking the 1-wire protocol directly, you can issue a single "convert temperature" command to all devices on the bus, as described here, and then read all the sensors.
The Linux driver explicitly doesn't support this mode of operation:
If none of the devices are parasite powered it would be possible to convert all the devices at the same time and then go back to read individual sensors. That isn’t currently supported. The driver also doesn’t support reduced precision (which would also reduce the conversion time) when reading values.
That means you're stuck with a 750ms per device read cycle. Your best option is probably placing the sensor reading code in a separate thread, e.g.:
import glob
import threading
import time
# Note that we're inheriting from threading.Thread here;
# see https://docs.python.org/3/library/threading.html
# for more information.
class DS18B20(threading.Thread):
default_base_dir = "/sys/bus/w1/devices/"
def __init__(self, base_dir=None):
super().__init__()
self._base_dir = base_dir if base_dir else self.default_base_dir
self.daemon = True
self.discover()
def discover(self):
device_folder = glob.glob(self._base_dir + "28*")
self._num_devices = len(device_folder)
self._device_file: list[str] = []
for i in range(self._num_devices):
self._device_file.append(device_folder[i] + "/w1_slave")
self._values: list[float | None] = [None] * self._num_devices
self._times: list[float] = [0.0] * self._num_devices
def run(self):
"""Thread entrypoint: read sensors in a loop.
Calling DS18B20.start() will cause this method to run in
a separate thread.
"""
while True:
for dev in range(self._num_devices):
self._read_temp(dev)
# Adjust this value as you see fit, noting that you will never
# read actual sensor values more often than 750ms * self._num_devices.
time.sleep(1)
def _read_temp(self, index):
for i in range(3):
with open(self._device_file[index], "r") as f:
data = f.read()
if "YES" not in data:
time.sleep(0.1)
continue
disacard, sep, reading = data.partition(" t=")
temp = float(reading) / 1000.0
self._values[index] = temp
self._times[index] = time.time()
break
else:
print(f"failed to read device {index}")
def tempC(self, index=0):
return self._values[index]
def device_count(self):
"""Return the number of discovered devices"""
return self._num_devices
Because this is a thread, you need to .start() it first, so your
code would look something like:
d = DS18B20()
d.start()
while True:
for i in range(d.device_count()):
print(f'dev {i}: {d.tempC(i)}')
time.sleep(0.5)
You can call the tempC method as often as you want, because it's
just return a value from the _values array. The actual update
frequency is controlled by the loop in the run method (and the
minimum cycle time imposed by the sensors).
I'm working on a project where I use a photoelectric sensor to detect a reflector attached to a motor axis. Every time the reflector reflects the light from the LED from the sensor it sends a pulse (voltage) to the raspberry pi (with a voltage divider). With some help I've come to the following code and I've noticed that the results that I'm getting are way too high. Anybody got any suggestions on how to improve it? I've seen other examples of RPM code online, but I wanted to learn it myself and the ones that I've found did not use the same method as me. Thanks in advance!
import time
from gpiozero import Button
sensor = Button(17)
i=1
timestampeven=0
timestamponeven=0
def pulsen():
global i
global timestampeven
global timestamponeven
if (i % 2) ==0:
timestampeven = time.time_ns()
i+=1
elif (i % 2) == 1:
timestamponeven = time.time_ns()
i+=1
periode = timestamponeven-timestampeven
frequentie = 1/(periode*10e09)
rpm = frequentie*60
print("rpm=" + str(rpm))
print("teller = " +str(i))
print("periode = " +str(periode))
print("frequentie = " +str(frequentie))
sensor.when_pressed = pulsen
while True:
pass
I use a template of a python script (running on Raspberry Pi) to send sensor data (i2c) via WiFi to my PC. The problem is, the values are not static. If I start the Web application, it reads the data from the sensor only once. So, if I check the values from my PC, I can see it sent the data correctly, but they won't change.
How can I modify the script to refresh the i2c_output value, without starting the script over and over again?
Here is what I have tried so far:
import web
import sys, os
import smbus
import math
#
# Lot of initialisation... forget that part
#
accel_xout = read_word_2c(0x3b)
accel_yout = read_word_2c(0x3d)
accel_zout = read_word_2c(0x3f)
afs_sel = read_word_2c(0x28)
LSB_afs_sel = 16384.0
accel_xout_sc = accel_xout / LSB_afs_sel
accel_yout_sc = accel_yout / LSB_afs_sel
accel_zout_sc = accel_zout / LSB_afs_sel
i2c_output = str(accel_xout_sc) + str(accel_yout_sc) + str(accel_zout_sc)
urls = ( '/','Index',
)
class Index:
def GET(self):
return i2c_output
if __name__=="__main__":
app=web.application(urls,globals())
app.run()
Move the code that retrieves the sensor data into a method and invoke that method each time the index is called.
def get_sensor_output():
#
# Lot of initialisation... forget that part
#
accel_xout = read_word_2c(0x3b)
accel_yout = read_word_2c(0x3d)
accel_zout = read_word_2c(0x3f)
afs_sel = read_word_2c(0x28)
LSB_afs_sel = 16384.0
accel_xout_sc = accel_xout / LSB_afs_sel
accel_yout_sc = accel_yout / LSB_afs_sel
accel_zout_sc = accel_zout / LSB_afs_sel
i2c_output = str(accel_xout_sc) + str(accel_yout_sc) + str(accel_zout_sc)
return i2c_output
class Index:
def GET(self):
return get_sensor_output()
Note: You may want to implement some sort of cache depending on how often this get method is called. currently each call will retrieve the sensor data, which may or may not be an expensive operation that will drain the battery on your pi
I would like to know in any way that i can run a function as a background process.
I have gone through reading threading but i am still unclear on how to implement it.
In my system , the scapy detection script run when i click on the Button.But then the system will be hang as the scapy function is running.
What i want to achieve is that when i click on the button that initiate the scapy detection script , i would like to be able to do other function in the same system.(general idea was to prevent the system from hang)
def startMonitor(self,event):
selectedInterface = self.interfaces_cblist.GetValue()
#selectInterfaceStr = str(selectedInterface)
if len(selectedInterface) == 0:
noInterfaceSelected = wx.MessageDialog(None,"Please select an interface","",wx.ICON_ERROR)
noInterfaceSelected.ShowModal()
else:
#confirmMonitor = wx.MessageDialog(None,"Monitoring Start on %s interface"%selectedInterface,"",wx.OK)
#confirmMonitor.ShowModal()
x = selectedInterface
thread.start_new_thread(self.camtableDetection(x))
def camtableDetection(self,a):
global interface
interface = str(a)
THRESH=(254/4)
START = 5
def monitorPackets(p):
if p.haslayer(IP):
hwSrc = p.getlayer(Ether).src
if hwSrc not in hwList:
hwList.append(hwSrc)
delta = datetime.datetime.now() - start
if((delta.seconds > START) and ((len(hwList)/delta.seconds) > THRESH)):
camAttackDetected = wx.MessageDialog(None,"Cam Attack Detected","",wx.ICON_ERROR)
camAttackDetected.ShowModal()
hwList = []
start = datetime.datetime.now()
sniff(iface=interface,prn=monitorPackets)