The discussion of the Alien series of films and the props used in them is the aim, but if it's got Big Bugs and Big Guns, then they are welcome too!





Post new topic Reply to topic  [ 60 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject:
PostPosted: Sat Oct 03, 2020 5:17 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
OK, I added some more logic. I added a kill sequence after launching any sequence over a 20 second span. And I added a volume control routine. I also cleaned up the led and laser logic and separated out the sounds.

I did discover that mplayer has a 1-2 second delay on processing any given sound file. aplay seems to be quicker but you have to have PCM or float encoded wav files to use with it.

to invoke the killing of a playing song I used this line in the script:
os.system("pkill mpg123")
to invoke volume changes I used this line in the script:
os.system("amixer set HDMI -- -2000)
the number is basically figure representing the db level, -2000 is minus 20 db.

It was a fair bit of trial and error but those helped a lot in case I had to stop a file from playing in case it either, triggered someone, was inappropriate for a given situation, or silence was needed/required.

The LED's are going to be activated with elechawk rc switches. They seem to be the most simple hardware solution to provide power and light amperage needs for super bright led arrays. THey are not made state side that I can determine and have submitted a product suggestion to adafruit as I will lay odds they could sell one for 5 dollars and outdo everyone on the market period.

leds are as follows currently:
6 is the trilaser
15 is left cannon firelight array
4 is left cannon trilaser led light array
10 is right cannon light
11 is right cannon laser led.

btn a activates light sequences on left cannon. btn b activates light sequences on right cannon. btn Z activates lights on both cannons. btn c activates the tri laser array.

0 is left travel servo
1 is left tilt main servo
2 is left x tilt servo
3 is left y tilt servo
13 is right main tilt servo
14 is right x gyro servo
7 is right z gyro servo

I cleaned up unused servo numbers causing erratic performance with led and servos.

Servos and lights are all deactivated and placed to neutral start positions at script beginning.
it then asks to activate the wiimote.
status updates are then displayed to screen
hitting home button moves armatures to active postion and enables movement for x/y/z axis control units
hitting home again moves servos to start positions.
hitting plus and minus together exits script afte rmoving servos to start positions.
if battery is belowy 79 reading servos moved to start positions and wiimote vibrates. Any lower battery value causes responsiveness issues and quirky behavior I have observed if unit approaches a value of 70 out of a max sub 200 value.
Buttons A, B, C, Z control lights
joystick on nunchuck controls left armature
gyrosocope on 9dof board controls right armature.
all other buttons used to play sound effects.

Code:
#!/usr/bin/python
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#|R|a|s|p|b|e|r|r|y|P|i|-|S|p|y|.|c|o|.|u|k|
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#
# wii_remote_1.py
# Connect a Nintendo Wii Remote via Bluetooth
# and  read the button states in Python.
#
# Project URL :
# http://www.raspberrypi-spy.co.uk/?p=1101
#
# Author : Matt Hawkins
# Date   : 30/01/2013
# Updated 8/2020 by Gabriel Vos aka Knoxvilles_joker
# http://alienslegacy.com
# updates done to allow for sound and servo controls and read full feature set of nunchuk
# Please note if using notepad and not notepad++ you must check for excess carriage returns in linux with the nano, vim, or your other preferred editor
# Please note python is very picky about syntax and spaces edit at own risk

# Licensed under GPL/GNU licensing distribute as you see fit but please include header above.
# Not to be used for commercial gain or profit unless credit given to authors.

# -----------------------
# Import required Python libraries
# -----------------------
import cwiid
import time
import os
import subprocess
import board
from board import SCL, SDA
import busio
from adafruit_pca9685 import PCA9685
i2c_bus = busio.I2C(SCL, SDA)
pca = PCA9685(i2c_bus)
pca.frequency = 50
# standard servo declearations for controls
from adafruit_servokit import ServoKit
kit = ServoKit(channels=16)
# class adafruit_moter.servo.Servo(pwm.out, *, actuation_range=180, minPpulse=750, max_pluse=2250)

import adafruit_fxas21002c
i2c=busio.I2C(board.SCL, board.SDA)
sensor1=adafruit_fxas21002c.FXAS21002C(i2c)


# due to servo placement and positioning, you have to set the initial deployment angles at settings
# other than zero and ensure that time is given so proper travel can occur without causing undue binding issues.

time.sleep(0.1)
kit.servo[0].angle=160
#time.sleep(3)
kit.servo[1].angle=24
kit.servo[2].angle=140
# 0-2 are basically place holders for armature.
kit.servo[3].angle=180
#kit.servo[4].angle=0
#kit.servo[5].angle=90
#kit.servo[6].angle=0
kit.servo[7].angle=0
kit.servo[13].angle=0
kit.servo[14].angle=90
# these turn all the lights to an off state
kit.servo[6].angle=0
kit.servo[10].angle=0
kit.servo[11].angle=0
kit.servo[15].angle=0


# These are the options for the pwm portion of the servo bonnett
#set_pulse_widge_range(min_pulse, max_pulse)
# kit.servo[0].set_pulse_width_range(1000, 2000)
#pca.channels[15].duty_cycle = 0x7fff

button_delay = 0.1
# these are values for button depress bounces.  I use a counter to ensure accidental presses do not cause undue issues
# this also allows for gpio input if at some point there is a need to switch to RPi.GPIO button inputs with minimal change
# addressing for issues with debounce and system noise on button presses
# note that only ascii characters 0-128 are allowed.  Any special characters are not recognized for character counter names.
btn1cnt = 0
btn2cnt = 0
btnupcnt = 0
btnleftcnt = 0
btndowncnt = 0
btnrightcnt = 0
btnacnt = 0
btnbcnt = 0
btnccnt = 0
btnzcnt = 0
btnhomecnt = 0
btnminuscnt = 0
btnpluscnt = 0

# As a rule I place everything in /boot.  It is not neccessarily a recommend practice but makes later upgrades and midstream
# changes much easier to perform if there are major code updates.

# I may have to use the sub process command set to allow for multi tasking but that is at a later stage
# These are the files for sound playback over the 3.5mm audio output going over the 3.5mm jack from the hdmi port.
# wav files are played with aplay and mp3 files are played with mpg123 engaged using the os.system command subset
# playsound does not appear to play nice with python 3.7 and is not an option currently
#SFX
file1 = "/boot/minigun.wav"
file2 = "/boot/gameover.wav"
#themes
afam = "/boot/addamsfamily.mp3"
pred = "/boot/predator.mp3"
alienc = "/boot/alienscomplex.mp3"
combat = "/boot/combatdroppercussion.mp3"
liftoff = "/boot/liftoff.mp3"
lv426 = "/boot/lv426.mp3"
gb = "/boot/ghostbusters.mp3"
halloween = "/boot/halloweenteme.mp3"
filedown = "/boot/alienisolationintro.mp3"
laser = "/boot/laser.wav"
cannon = "/boot/cannon.wav"
# branches
army = "/boot/armyhymn.mp3"
af = "/boot/airforcesong.mp3"
usmc = "/boot/usmchymn.mp3"
navy = "/boot/navyhymn.mp3"
# sound tracks
b2 = "/boot/b2theme.mp3"
b3 = "/boot/b3introtheme.mp3"
everyrule = "/boot/everyrule.mp3"
jh = "/boot/jhsettingthewoodsonfire.mp3"
jumprope = "/boot/jumprope.mp3"
rammstein = "/boot/rammsteinhallelujah.mp3"
lithiumflower = "/boot/lithiumflower.mp3"
thriller = "/boot/thriller.mp3"
# misc sound effects found later in project
candy ="/boot/candy.wav"
anytime = "/boot/anytime.wav"
death = "/boot/death.wav"
demon = "/boot/demon.wav"
hell = "/boot/hell.wav"
jerry = "/boot/jerry.wav"
otherside = "/boot/otherside.wav"



print ('Press 1 + 2 on your Wii Remote now ...')
time.sleep(1)

# Connect to the Wii Remote. If it times out
# then quit.
# note that this is a clean way to quit script if stuff is not connected at startup.
try:
  wii=cwiid.Wiimote()
except RuntimeError:
  print ("Error opening wiimote connection")
  quit()

print ('Wii Remote connected...\n')
print ('Press some buttons!\n')
print ('Press PLUS and MINUS together to disconnect and quit.\n')
wii.led = 1
wii.rpt_mode = cwiid.RPT_BTN  | cwiid.RPT_ACC | cwiid.RPT_NUNCHUK

while True:
#  Do not turn this line on unless you like spam in your command line output if you do comment the same line above first though
#  wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC | cwiid.RPT_NUNCHUK
#  below are values pulled from the wm.state data array and stored to be used to drive various functions
#  you can comment out the status display to troubleshoot button pushes.  all buttons are accounted for in the script
  time.sleep(0.1) # pause required to get time for readings.
  battery = wii.state['battery']
  buttons = wii.state['buttons']
  # Wii Accelerometer readings are 0 - 255.  It is a true accelerommeter and it is meant to be used with the IR pointer for calibration in accurate use
  # Online documentation indicates that a light source can be used for referenc ein plcase of a light bar, but your mileage will vary.
  # this function is not used but is reported
  wacc= wii.state['acc']
  # I will be getting a wii motion device at some point and adding it but until then only the nunchuck accelerometer and joystick movements are used.
  nunbut = wii.state['nunchuk']
  nbut =nunbut['buttons']
  nacc =nunbut['acc']
  # Nunchuk stick range appears to be 226 - 26
  nstick= nunbut['stick']
  nstickx= int(((nstick[0]-26)/200)*180)
  nsticky= int(((nstick[1]-26)/200)*180)
  # Nunchuck range appears to be 250 - 26
  naccx  = int(((nacc[0]-20)/233)*180)
  naccy  = int(((nacc[1]-20)/233)*180)
  naccz  = int(((nacc[2]-20)/233)*180)
  time.sleep(button_delay)
# this is using the fxas21002c gyroscope as part of the setup that will mount to the head.  I may change this as I incorporate a QWIIC board.
#
  gyro_x, gyro_y, gyro_z=sensor1.gyroscope
  rightxa=(((int(gyro_x--256)/(256--256))*180))
  rightza=(((int(gyro_z--256)/(256--256))*180))
# the round() function drops off all additional decimal points.  Useful to provide clean number readouts and input
# note that on more complex numerical calculations it is vital to do rounding as the last step.  rounding errors
# create final calculation deviation and can skew result with sometimes noticable results.
  rightx = round(rightxa)
  rightz = round(rightza)
# These are disabled as the wiimote accelerometer has too odd a range of settings and is not a true tilt sensor
# It was meant to be used in conjuction with a ir ptr for calibration and pointing ability
# This is great for calibration based upon device input range is 0-255
# waccx  = int(((
 # waccy  = int(((
 # waccz  = int(((
  print(wii.state)
  print('wb nb bat joyxy, accxyz')
  print(buttons, nbut, battery, nstickx, nsticky, naccx, naccy, naccz)
  print("gx", rightx, "gz", rightz, gyro_y)

  time.sleep(0.1)
  # servo setup is as follows:
  # main track left is 0, 1 is tilt arm left. 2 is tilt arm left levelling servo, 3 is pan servo for left and right action
  # 5 is main tilt right servo, 6 is levelling servo right, 7 is right pan left right servo
  # 10 is pwm light for firing, 15 is head laser
  # I am still playing with pwm signaling with opto couplers with a full 5v laser setup.
  # due to some issues with coding we have to do an if else to allow for servo2 the second tilt servo to function properly. 
  if (btnhomecnt == 1):
    kit.servo[2].angle=nstickx
    kit.servo[3].angle=nsticky
    kit.servo[14].angle=rightx
    kit.servo[7].angle=rightz
# use naccx if you want to use nunchuk accelerometer settings
  else:
    kit.servo[2].angle = 140
    kit.servo[3].angle = 180
    kit.servo[14].angle = 90
   # kit.servo[5].angle = 90

  time.sleep(button_delay)
  #this was to determine that we need to loop y axis out of bound
  #kit.servo[3].angle = nsticky
  time.sleep(button_delay)
  # the midarm servo is being set to always maintain a level status regardless of arm tilt.  based on my calculations with a 1:1 gear ratio
 # kit.servo[2].angle = nsticky # implemented design indicates that the geared unit needs to be the x tilt mechanism the main armature is just a placement deal
  kit.servo[4].angle = naccx
  kit.servo[6].angle = naccz
  #kit.servo[5].angle = naccx
  # If Plus and Minus buttons pressed
  # together then rumble and quit.
  # This is a great way to exit code if you set it to run at startup and need console control back.
  # This failsafe is a great way to ensure if you have buggy code you have an opportunity to fix it
  # By default I will typically place this in the \boot directory.
  if (buttons - cwiid.BTN_PLUS - cwiid.BTN_MINUS == 0):
    print ('\nClosing connection ...')
    wii.rumble = 1
    time.sleep(1)
    kit.servo[0].angle = 160
    time.sleep(3)
    kit.servo[1].angle = 24
    time.sleep(2)
    kit.servo[2].angle = 140
    kit.servo[3].angle = 180
    kit.servo[4].angle = 0
    kit.servo[5].angle = 90
    kit.servo[6].angle = 0
    kit.servo[7].angle = 0
    kit.servo[13].angle = 0
    kit.servo[14].angle = 90

    time.sleep(4)
    wii.rumble = 0
    exit(wii)
  # this notifies you that the battery is low and prevents comm errors by ensuring you change the battery out.
  # This will constantly rumble until battery is replaced.
  if (battery <= 79):
    print ('please change battery now')
    wii.rumble = 1
    kit.servo[0].angle = 160
    time.sleep(3)
    kit.servo[1].angle = 24
    kit.servo[2].angle = 140
    kit.servo[3].angle = 180
    kit.servo[4].angle = 0
    kit.servo[5].angle = 90
    kit.servo[6].angle = 0
    kit.servo[7].angle = 0
    kit.servo[13].angle = 0
    kit.servo[14].angle = 90

    time.sleep(1)
    wii.rumble = 0
# The battery replace code is a physical reminder that battery is low.
# This is a failsafe to ensure that battery drop off is not severe.
# The value is 0-255 but I have seen it drop to 70s before comms are lost.
# The most I have seen it in is the upper 100s.  Mileage will vary based upon batteries in use
# Please bear in mind wiimote is only designed for standard AA batteries.  Do not cheat with fancier batteries
# The setup and maintenance is intended to be a lower cost setup.


  # Check if other buttons are pressed by
  # doing a bitwise AND of the buttons number
  # and the predefined constant for that button.
  # I am using a counter based setup for actions.
  # Theoretically this could lead to infinite number of actions after sequential number is reached
  # This is great if you are wanting a sequential set of sounds to play in sequence, or a start and reset sequence on a set servo or light
  # Please note that at the beginning for servos you want them all to reset to their neutral start positions.
  # This ensures if things crashed on the last go around you are not hyper extending or retracting servos beyond their active range
  # This lowers power consumption and esures minimal breakage issues

  if (buttons & cwiid.BTN_LEFT):
    print ('Left pressed')
    btnleftcnt = btnleftcnt +1
    print (btnleftcnt, "presses so far")
    time.sleep(button_delay)
  if (btnleftcnt == 2):
    subprocess.Popen(['mpg123', '-q', pred])
    print (btnleftcnt, "playing pred1")
    btnleftcnt = btnleftcnt +1
  if (btnleftcnt == 5):
    btnleftcnt = btnleftcnt +1
    os.system("pkill mpg123")
    print (btnleftcnt, "presses so far")
  if (btnleftcnt == 11):
    btnleftcnt = 0
    time.sleep(button_delay)

  if(buttons & cwiid.BTN_RIGHT):
    print ('Right pressed')
    btnrightcnt = btnrightcnt +1
    print (btnrightcnt, "presses so far")
    time.sleep(button_delay)
  if (btnrightcnt == 2):
    subprocess.Popen(['aplay', '-q', file2])
    btnrightcnt = btnrightcnt +1
    print (btnrightcnt, "playing file2")
    time.sleep(button_delay)
  if (btnrightcnt == 5):
    btnrightcnt = btnrightcnt +1
    os.system("pkill aplay")
  if (btnrightcnt == 8):
    subprocess.Popen(['mpg123', '-q', jumprope])
    btnrightcnt = btnrightcnt +1
    print (btnrightcnt, "playing jumprope")
    time.sleep(button_delay)
# jumprope is so short that a simple stop command should not be needed
# the os.system("pkill app") really is meant for longer file plays
  if (btnrightcnt == 11):
    subprocess.Popen(['mpg123', '-q', afam])
    btnrightcnt = btnrightcnt +1
    print (btnrightcnt, "playing addamsfamily")
    time.sleep(button_delay)
  if (btnrightcnt == 14):
    btnrightcnt = btnrightcnt +1
    os.system("pkill mpg123")
  if (btnrightcnt == 17):
    btnrightcnt = 0
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_UP):
    print ('Up pressed')
    btnupcnt = btnupcnt +1
    print (btnupcnt, "presses so far")
    time.sleep(button_delay)
  if (btnupcnt == 2):
    subprocess.Popen(['mpg123', '-q', filedown])
    btnupcnt = btnupcnt +1
    print (btnupcnt, "playing filedown")
    time.sleep(button_delay)
  if (btnupcnt == 5):
    btnupcnt = btnupcnt +1
    os.system("pkill mpg123")
  if (btnupcnt == 8):
    subprocess.Popen(['mpg123', '-q', alienc])
    btnupcnt = btnupcnt +1
    print (btnupcnt, "playing alienc")
    time.sleep(button_delay)
  if (btnupcnt == 11):
    btnupcnt = btnupcnt +1
    os.system("pkill mpg123")
  if (btnupcnt == 14):
    btnupcnt = btnupcnt +1
    subprocess.Popen(['mpg123', '-q', combat])
    print (btnupcnt, "playing combat")
    time.sleep(button_delay)
  if (btnupcnt == 17):
    btnupcnt = btnupcnt +1
    os.system("pkill mpg123")
  if (btnupcnt == 20):
    btnupcnt = btnupcnt +1
    subprocess.Popen(['mpg123', '-q', liftoff])
    time.sleep(button_delay)
    print (btnupcnt, "playing liftoff")
  if (btnupcnt == 23):
    btnupcnt = btnupcnt +1
    os.system("pkill mpg123")
  if (btnupcnt == 26):
    btnupcnt = btnupcnt +1
    subprocess.Popen(['mpg123', '-q', lv426])
    time.sleep(button_delay)
    print (btnupcnt, "playing lv426")
  if (btnupcnt == 29):
    btnupcnt = btnupcnt +1
    os.system("pkill mpg123")
  if (btnupcnt == 32):
    btnupcnt = 0
    time.sleep(button_delay)


  if (buttons & cwiid.BTN_DOWN):
    print ('Down pressed')
    btndowncnt = btndowncnt +1
    print (btndowncnt, "presses so far")
    time.sleep(button_delay)
  if (btndowncnt == 2):
    subprocess.Popen(['mpg123', '-q', af])
    time.sleep(button_delay)
    btndowncnt = btndowncnt +1
    print (btndowncnt, "playing af")
  if (btndowncnt == 5):
    btndowncnt = btndowncnt +1
    os.system("pkill mpg123")
  if (btndowncnt == 8):
    btndowncnt = btndowncnt +1
    subprocess.Popen(['mpg123', '-q', army])
    time.sleep(button_delay)
    print (btndowncnt, "playing army")
  if (btndowncnt == 11):
    btndowncnt = btndowncnt +1
    os.system("pkill mpg123")
  if (btndowncnt == 14):
    subprocess.Popen(['mpg123', '-q', navy])
    time.sleep(button_delay)
    btndowncnt = btndowncnt +1
    print (btndowncnt, "playing navy")
  if (btndowncnt == 17):
    btndowncnt = btndowncnt +1
    os.system("pkill mpg123")
  if (btndowncnt == 20):
    btndowncnt = btndowncnt +1
    subprocess.Popen(['mpg123', '-q', usmc])
    time.sleep(button_delay)
    print (btndowncnt, "playing usmc")
  if (btndowncnt == 23):
    btndowncnt = btndowncnt +1
    os.system("pkill mpg123")
  if (btndowncnt == 26):
    btndowncnt = 0
    time.sleep(button_delay)
    print (btndowncnt, "resetting count, restarting loop")

  if (buttons & cwiid.BTN_1):
    print ('Button 1 pressed')
    btn1cnt = btn1cnt +1;
    print(btn1cnt, "presses so far")
    time.sleep(button_delay)
  if (btn1cnt == 3):
    print (btn1cnt, "reached playing minigun snd");
#    os.system("aplay " + file1);
#   I am replacing the above with a subprocess that will allow for multitasking/sub process concurrency.
#   It makes for some interesting sound combinations...
#   It appears that concurrency limit is about 4.  This is the only way to play sounds and keep the script read loop running
#    Moving servos and having sound effects
#    For shorter sound effects I am not invoking a pkill command set.
    subprocess.Popen(['aplay', '-q', file1])
    btn1cnt = 0
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_2):
    print ('Button 2 pressed')
    btn2cnt = btn2cnt +1;
    print(btn2cnt, "presses so far");
    time.sleep(button_delay)
  if (btn2cnt == 2):
    print (btn2cnt, "reached playing gameover")
    subprocess.Popen(['aplay', '-q', file2])
    btn2cnt = btn2cnt +1
    time.sleep(button_delay)
# gameover is a super short clip comparatively so no pkill is needed
  if (btn2cnt == 5):
    print (btn2cnt, "presses so far")
    subprocess.Popen(['mpg123', '-q', rammstein])
    btn2cnt = btn2cnt +1
    print ("playing rammstein")
  if (btn2cnt == 8):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 11):
    print(btn2cnt, "presses so far")
    subprocess.Popen(['mpg123', '-q', lithiumflower])
    btn2cnt = btn2cnt +1
    print ("playing lithium flower")
  if (btn2cnt == 14):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 17):
    btn2cnt = btn2cnt +1
    print (btn2cnt, "presses so far")
    subprocess.Popen(['mpg123', '-q', thriller])
    print ("playing thriller")
  if (btn2cnt == 20):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 23):
    btn2cnt = btn2cnt +1
    print (btn2cnt, "presses so far")
    subprocess.Popen(['mpg123', '-q', gb])
    print ("playing ghostbusters instrumental")
  if (btn2cnt == 26):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 29):
    btn2cnt = btn2cnt +1
    print (btn2cnt, "presses so far")
    subprocess.Popen(['mpg123', '-q', halloween])
    print ("playing halloween instrumental them")
  if (btn2cnt == 32):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 35):
    print (btn2cnt, "presses so far")
    btn2cnt = btn2cnt +1
    subprocess.Popen(['mpg123', '-q', jh])
    print ("playing setting wodds on fire with joker and harley")
  if (btn2cnt == 38):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 41):
    btn2cnt = btn2cnt +1
    subprocess.Popen(['mpg123', '-q', b2])
    print ("playing borderlands2 theme song")
  if (btn2cnt == 44):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 47):
    btn2cnt = btn2cnt +1
    subprocess.Popen(['mpg123', '-q', b3])
    print ("playing borderlands3 themesong")
  if (btn2cnt == 50):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 53):
    btn2cnt = btn2cnt +1
    subprocess.Popen(['mpg123', '-q', everyrule])
    print ("playing everyone wants to rule the world")
  if (btn2cnt == 56):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 59):
    btn2cnt = 0
    print ("resetting count")


  if (buttons & cwiid.BTN_A):
    print ('Button A pressed engaging disengaging laser')
    btnacnt = btnacnt +1
    print(btnacnt, "presses so far")
    time.sleep(button_delay)
  if (btnacnt == 2):
    subprocess.Popen(['mplayer', laser])
    kit.servo[15].angle = 110
    kit.servo[4].angle = 110
    time.sleep(button_delay)
    btnacnt = btnacnt +1
    print (btnacnt, "playing and lighting laser")
  if (btnacnt == 5):
    subprocess.Popen(['mplayer', laser])
    kit.servo[15].angle = 40
    kit.servo[4].angle = 40
    btnacnt = btnacnt +1
    print (btnacnt, "playing laser and powering down")
  if (btnacnt == 8):
    btnacnt = 0
    print (btnacnt, "resetting count restarting a loop")
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_B):
    print ('Button B pressed')
    btnbcnt = btnbcnt +1;
    print(btnbcnt, "presses so far");
    time.sleep(button_delay)
  if (btnbcnt == 3):
    print('btnbcnt reached playing laser sound');
    kit.servo[11].angle = 110
    time.sleep(1)
    kit.servo[10].angle = 110
    subprocess.Popen(['mplayer', cannon])
    time.sleep(.5)
    kit.servo[10].angle = 40
    time.sleep(.2)
    kit.servo[11].angle = 40
    btnbcnt = 0;
    print (btnbcnt, "playing cannon sound and lighting up")
    time.sleep(button_delay);

  if (buttons & cwiid.BTN_HOME):
    print ('Home Button pressed')
    btnhomecnt = btnhomecnt +1;
    print(btnhomecnt, "presses so far");
    time.sleep(button_delay)
  if (btnhomecnt == 0):
    # Initial starting point.  This ensures no movements until you are ready and accounts for accidental presses as you fumble with things suiting up and powering stuff on.
    kit.servo[0].angle = 160
#    time.sleep(4)
    kit.servo[1].angle = 24
    kit.servo[3].angle = 180
    kit.servo[2].angle = 140
    kit.servo[13].angle = 0
    kit.servo[14].angle = 90
    kit.servo[5].angle = 90
#   tilt angle control is done through an if or else statement at beginning of script to constrain movement in down position
    time.sleep(button_delay);
  if (btnhomecnt == 1):
    kit.servo[0].angle = 10
    kit.servo[1].angle = 95
    kit.servo[13].angle = 51
    #this is the operating position.  Other arms will get added as I get the build out further along.
#   I had to add a separate failsafe check to reset btnhome count to prevent erraneous readings for the angle of the cannon on the y axis.
  if (btnhomecnt == 2):
  #  time.sleep(4)
    btnhomecnt = 0

  if (buttons & cwiid.BTN_MINUS):
    print ('Minus Button pressed')
    btnminuscnt = btnminuscnt +1;
    print(btnminuscnt, "presses so far");
    time.sleep(button_delay);
  if (btnminuscnt == 2):
    os.system("amixer set HDMI -- 400")
    btnminuscnt = btnminuscnt +1
  if (btnminuscnt == 5):
    time.sleep(button_delay)
    btnminuscnt = btnminuscnt +1
    os.system("amixer set HDMI -- 200")
  if (btnminuscnt == 8):
    btnminuscnt = btnminuscnt +1
    os.system("amixer set HDMI -- 0")
  if (btnminuscnt == 11):
    btnminuscnt = btnminuscnt +1
    os.system("amixer set HDMI -- -2000")
  if (btnminuscnt == 14):
    btnminuscnt = btnminuscnt +1
    os.system("amixer set HDMI -- -4000")
  if (btnminuscnt == 17):
    btnminuscnt = btnminuscnt +1
    os.system("amixer set HDMI -- -10200")
  if (btnminuscnt == 20):
    print ("resetting count");
    btnminuscnt = 0
    time.sleep(button_delay);

  if (buttons & cwiid.BTN_PLUS):
    print ('Plus Button pressed')
    btnpluscnt = btnpluscnt +1
    print (btnpluscnt, "presses so far")
    time.sleep(button_delay)
  if (btnpluscnt == 2):
    btnpluscnt = btnpluscnt +1
    print (btnpluscnt, "presses so far")
    subprocess.Popen(['mplayer', anytime])
  if (btnpluscnt == 5):
    btnpluscnt = btnpluscnt +1
    subprocess.Popen(['mplayer', demon])
  if (btnpluscnt == 8):
    btnpluscnt = btnpluscnt +1
    print (btnpluscnt, "presses so far")
    subprocess.Popen(['mplayer', candy])
  if (btnpluscnt == 11):
    btnpluscnt = btnpluscnt +1
    print (btnpluscnt, "presses so far")
    subprocess.Popen(['mplayer', hell])
  if (btnpluscnt == 14):
    btnpluscnt = btnpluscnt +1
    print (btnpluscnt, "presses so far")
    subprocess.Popen(['mplayer', death])
  if (btnpluscnt == 17):
    btnpluscnt = btnpluscnt +1
    subprocess.Popen(['mplayer', jerry])
    print (btnpluscnt, "presses so far")
  if (btnpluscnt == 20):
    btnpluscnt = btnpluscnt +1
    subprocess.Popen(['mplayer', otherside])
    print (btnpluscnt, "presses so far")
  if (btnpluscnt == 23):
    btnpluscnt = 0
    print ("resetting count and resetting loop")



  if (nbut & cwiid.NUNCHUK_BTN_C):
    print ('nunchuk c pressed')
    btnccnt = btnccnt +1;
    print (btnccnt, "presses so far")
    time.sleep(button_delay)
  if (btnccnt == 2):
    kit.servo[6].angle = 110
    subprocess.Popen(['mplayer', laser])
    time.sleep(.2)
    btnccnt = btnccnt +1
  if (btnccnt == 5):
    print ('fire left cannon, lights')
    subprocess.Popen(['mplayer', laser])
    time.sleep(1)
    kit.servo[6].angle = 40
    btnccnt = 0

  if (nbut & cwiid.NUNCHUK_BTN_Z):
    btnzcnt = btnzcnt +1
    print (btnzcnt, "presses so far")
    print ('nunchuk z pressed')
    time.sleep(button_delay)
  if (btnzcnt == 2):
  #  kit.servo[6].angle = 110
    subprocess.Popen(['mplayer', laser])
    time.sleep(.3)
    btnzcnt = btnzcnt +1
  if (btnzcnt == 5):
    btnzcnt = btnzcnt +1
    kit.servo[4].angle= 110
    kit.servo[11].angle= 110
  if (btnzcnt == 8):
    btnzcnt = btnzcnt +1
    kit.servo[15].angle=110
    kit.servo[10].angle=110
    subprocess.Popen(['mplayer', cannon])
    time.sleep(.5)
    kit.servo[15].angle=40
    kit.servo[10].angle=40
  if (btnzcnt == 11):
    btnzcnt = btnzcnt +1
  if (btnzcnt == 14):
    print ('fire right cannon, lights')
    kit.servo[4].angle = 40
    kit.servo[11].angle = 40
    subprocess.Popen(['mplayer', laser])
    btnzcnt = 0
    time.sleep(button_delay)
    time.sleep(1)
   # kit.servo[6].angle = 40

  if (nbut - cwiid.NUNCHUK_BTN_Z - cwiid.NUNCHUK_BTN_C == 0):
    print ('nunchuk c plus z pressed')
    time.sleep(button_delay)

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Oct 03, 2020 5:19 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
Current line count is somewhere in the 720ish range. I researched adding a voice recording and playback function but the feature is not something the pi would support without adding another hat and converter and would tax the performance of the unit which would land me back into the same situation as the Arduino unit which I am trying to avoid.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re: Wiimote with nunchuk on linux via bluetooth
PostPosted: Thu Oct 15, 2020 1:21 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
OK, I am looking at using an OLED or TFT bonnet (sits on top of pi via pins.) to display recalculated readings. Part of the issue is that I do not want to over load the I2C (40 plus year technology invented by Motorola if memory serves) bus as I already have a Gyroscope plugged in on that so I would go with a TFT SPI bonnet to separate out the separate communication lines built-in to the pi.

The problem when you have a bunch of items on an I2C bus or any serial based bus or communications design, you have to add delays for polling and processing and that can slow an entire script down. Something I wish to avoid this time around.

Fortunately now there is this nice thing called QWIIC/QT connectors that allow you to easily plug in I2C devices.

A lot of this stuff is becoming easier over time as folks are trying to allow kids to tip toe into things instead of requiring engineering level education self taught or otherwise to try and figure things out.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Oct 25, 2020 3:32 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
OK, I think I uncovered a core hardware issue with the bno088 i2c board. I am trying an mpu-6050 board as they are the cheapest boards on the market and also have a qwiic connector. I am just hoping the board updates done by adafruit fix some of the quirkiness I was having with that board with Arduino based setup. From what I am finding on the qwiic/qt/stemma connectors, they have pullup resistors built-in which solves some issues with things.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re: Wiimote with nunchuk on linux via bluetooth
PostPosted: Sun Oct 25, 2020 5:47 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
knoxvilles_joker wrote:
OK, I am looking at using an OLED or TFT bonnet (sits on top of pi via pins.) to display recalculated readings. Part of the issue is that I do not want to over load the I2C (40 plus year technology invented by Motorola if memory serves) bus as I already have a Gyroscope plugged in on that so I would go with a TFT SPI bonnet to separate out the separate communication lines built-in to the pi.

The problem when you have a bunch of items on an I2C bus or any serial based bus or communications design, you have to add delays for polling and processing and that can slow an entire script down. Something I wish to avoid this time around.

Fortunately now there is this nice thing called QWIIC/QT connectors that allow you to easily plug in I2C devices.

A lot of this stuff is becoming easier over time as folks are trying to allow kids to tip toe into things instead of requiring engineering level education self taught or otherwise to try and figure things out.


Correction I2C was invented by phillips in the early 80s and is now under the name NXP. SMBUS was a derived from the protocol and actually used in PCI standards for communications and in motherboards today as well for some of the slower communications protocols.

I got the minipitft to work with the qwiic arcade button to display status updates.

Not I have to sort through some update performance issues but, yay, more research.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Nov 28, 2020 5:21 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
OK, the screen idea was not a good idea. As I like to mash up genres. I thought using espeak which was created in the early 90s for the RISC_OS.

The screen was adding a 6 second delay on writes and there was no way to sub thread python code within python code AND pass variables to a function in a sub-thread. I am not sure if that will ever be addressed at some point but there might be something obscure out there that does the trick but super obscure functions are asking for trouble from a programming stand point.

The qwiic/QT STEMMA connectors are wonderful features. no soldering and you can use straight i2c communications. I will use an arcade button to engage the script after boot in headless (no display) mode. And the mpu-6050 seems to be working great for pan/tilt functionality on the gyroscope it has built-in. The connection standard is built with our younger inventors and programmers in mind so they can safely learn before it is safe for them to solder and make reliable solder joints.

The closest I could come to Joshua was with this command string:
espeak --stdout -a200 -g13 -k01 -p1 - s160 -ven-sc "Shall we play aa game" | aplay

apparently some recent pi updates broke the audio and alsa/alsamixer components. Just go through the errors to find out the components that are broken in the most recent updates. The Pi 4 has required some updates and it has made things fun for the pi zero w users to an extent.

I start the script with that line and then have it say press red button now when it is trying to connect.

The motor board does stack and it does appear to work with the servo board. The only issue with stepper motors is that the buggers get hot to a point that it will cause issues with 3d printed stuff.

I am waiting on the linear motion component assembly before I proceed much further.

But on that note the motor control board and the roboclaw unit which I may end up having to use, have two outputs. So I could run a stepper motor for the blade assembly.

The issue with the adafruit motor board is that there is no way to have it go run a set amount without using a for I in 200 loop. The roboclaw board has a much more refined control mechanism on it.

The backpack will require a complete redesign and redo to descretely house the linear motion rail. As the goal on this project is off the shelf stuff I will not be able to house it in the main body like they did on the AVPR pack. The nice thing is once the linear motion setup is built-in the look will be much, much closer to the actual movie setup once I add the metal wraps to hide the mechanical pieces.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re: Wiimote with nunchuk on linux via bluetooth
PostPosted: Mon Nov 30, 2020 3:30 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
I got the linear motion setup. I installed the stepper motor and motion was slower than I would have liked and torque is a bit of a concern. I got a message in to servo city to see if I have any other options.

The movement does appear to have sufficient torque and may work as designed.

Movement is about 16 rotations. So to do full movement in 16 seconds rpm rating would have to be 60rpm. 8 seconds if 120rpm. 4 seconds if 240rpm. The trade off is torque with higher rpm ratings and with high torque units you are looking at 7amps at 12 volts dc. This puts me in a pickle with power supply and battery life.

The dewalt units I am hoping to use only supply 12vdc at 2amps.

before my substantial upgrades I was getting about 2-3 hours on a fully charged 5 amp hour 20v max dewalt battery. Now I could switch to a 12ah or 9ah dewalt battery but then I am looking at 200 per battery versus 60 or a set of 2 or 3 depending upon sources.

I was looking at getting a dewalt battery operated mower. Those use a 60v battery but the weight is substantially more. That is the other issue I am trying to minimize weight concerns as well.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Dec 06, 2020 9:06 pm 

Service Number: A05/TQ2.0.32141E1
Country: United States
I ran into an issue with the qwiic button causing an intermittent coms error with the motor shield. I may have to switch over to a regular gpio button but this is not a big deal breaker, more of a pain.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re: Wiimote with nunchuk on linux via bluetooth
PostPosted: Sat Dec 19, 2020 4:49 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
OK at this point I am looking at using a GPIO button setup off of the pi on pins 39 and 40 (ground and GPIO pin 21) to kick off the script and restart it as needed.

Now there are currently two ways to do this on Linux:
Systemd
init.d

init.d is in the process of getting phased out with systemd. init.d scripts can be easier to use as there can be a fair amount of sophistication you need to write into scripts.

How to start them and make them persistant in the background waiting for an interrupt. How to restart them. How to poll the running script and make sure it is operating before really killing the script to restart it.

The other kicker is to prevent false button presses which is used through a debounce mechanism. The newer versions of RPi.GPIO on the raspberry pi have a debounce function built-in. Previously it was a fair bit of programming to account for system noise creating false indications of a button press.

Now writing stuff with future proofing in mind that will still work 5 or 10 years from now is a real gamble. Will init.d still be around in another decade? Will something come about that is even better than systemd?

I have even run into cases where updated raspberry pi OS updates break things. Like the ability to use flash on the raspberry pi 4. Flash and internet explorer are basically discontinued products at this point, but, too many products are written to only function with them and would literally have to be rebuilt from the ground up to function with the new setups and vendors are in a catch-22, redo for the new hotness, wait a bit to see if things settle, or just go ahead and spend the money and be compliant with various agency regulations and avoid potential fines, or just do the extra paperwork to avoid fines and look at potentially paying fines. Government in some cases will tell companies, no you can not just pay the fine, you will fix it or have your product or facility removed from the market immediately.

I have also run into cases where if you wait a few months something on the internet is no longer there for any number of reasons.

I have also run into other cases where a simple product update breaks core functionality of something you are trying to use. This is a lot of what I have been fighting with as technological advancement forces rapid changes in everything.

I have concluded that espeak will be the best way to know where you are at in the script initialization process as I can fork or split the command to run in the background and not impact script performance.
I thought start the scrip with, Shall we play a game, followed by press the red button to initiate wiimote connection process. Then once connected announce launching in...

The best way I have figured to initiate the script is as a service via a button press. At startup first and then as a button is pressed. The key is to ensure that there is a cleanup mechanism to kill any hung processes also running in the background.

Update:
After more digging it appears that Systemd is in fact the official replacement for init.d. Developers do not all like system as it does not work nicely programmatically with older things. Adoption is slow and not without its hold outs.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re: Wiimote with nunchuk on linux via bluetooth
PostPosted: Sat Dec 19, 2020 9:54 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
Ok after some digging and work I have the gpio script initial draft done I think and the SystemD setup. The GPIO setup has a debounce feature, a tone indicator for button presses and detents to account for accidental presses

SystemD setup would be here: /lib/system/system/predator.service
and would contain this:
[Unit]
Description=My Script Service
After=multi-user.target
[Service]
Type=idle
ExecStart=/usr/bin/python3 /home/pi/myscript.py
ExecStop=/killall myscript.py wii_remote_1.py
[Install]
WantedBy=multi-user.target

Code:
import psutil
from subprocess import Popen
import time
from soundplayer import SoundPlayer
import os
import subprocess
import RPi.GPIO as GPIO 
GPIO.setmode(GPIO.BCM)   
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)   
GPIO.add_event_detect(21, GPIO.FALLING, bouncetime=2000) 
btn21cnt = 0
btn21run = 0
while True:
  for process in psutil.process_iter():
    if process.cmdline() == ['python3', 'wii_remote_final1.py']:
      btn21run = 1     
  else:
    print('Process not found: starting it.')
    btn21run = 0
  time.sleep(1)
  if GPIO.event_detected(21):
    btn21cnt = btn21cnt +1
    SoundPlayer.playTone(900, 0.3, True, dev) # 900 Hz
    print(btn21cnt, "presses so far") 
    time.sleep(0.1)
  if (btn21cnt == 3):
      if (btn21run == 1):
        print(btn21cnt, "threshold reached, stopping script")
        os.system("killall -9 wii_remote_final1.py")
        btn21cnt = btn21cnt +1
      elif(btn21run == 0):
        print("script not running")
        btn21cnt = btn21cnt +1
  if (btn21cnt == 6):
    if (btn21run == 0):
      print(btn21cnt, "threshold reached, starting script")
#      subprocess.Popen(['python3 /boot/wii_remote_final1.py'])
      subproces.call(['python3', '/boot/wii_remote_final1.py'])
      btn21cnt = 0
    elif (btn21run == 1):
      btn21cnt = 0

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re: Wiimote with nunchuk on linux via bluetooth
PostPosted: Wed Dec 23, 2020 8:52 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
OK, I got the gpio input to work.

This is the main service code:
Code:
import time
import os
import subprocess
import RPi.GPIO as GPIO 
GPIO.setmode(GPIO.BCM)   
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)   
GPIO.add_event_detect(21, GPIO.FALLING, bouncetime=1500) 
btn21cnt = 0
while True:
  if GPIO.event_detected(21):
    btn21cnt = btn21cnt +1
    subprocess.Popen(['play', '-n', '-c1', 'synth', '0.5', 'sine', '1000'])
    print(btn21cnt, "presses so far") 
    time.sleep(0.1)
  if (btn21cnt == 3):
    print(btn21cnt, "threshold reached, stopping script")
    subprocess.Popen(['pkill', '-9', 'script.py'])
    btn21cnt = btn21cnt +1
  if (btn21cnt == 6):
    print(btn21cnt, "threshold reached, starting script")
    subproces.Popen(['python3', '/boot/script.py'])
    btn21cnt = 0
    time.sleep(0.1)


This is just a simple service with audible queues I wrote to troubleshoot.
Code:
import time
import subprocess
import os
btncnt = 0
while True:
  subprocess.Popen(['play', '-n', '-c1', 'synth', '0.5', 'sine', '1000'])
  btncnt = btncnt +1
  print(btncnt, "iterations so far")
  time.sleep(0.1)
  if (btncnt == 20):
    btncnt = 0
    print("resetting btncnt")[code][/code]

This is the systemD service at /lib/sytemd/system/gpio.service:
[code]
[Unit]
Description=GPIO service nag
After=multi-user.target

[Service]
Type=idle
ExecStart=/usr/bin/python3 /boot/gpio.py
ExecStop=/pkill /boot/gpio.py

[Install]
WantedBy=multi-user.target

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re: Wiimote with nunchuk on linux via bluetooth
PostPosted: Mon Mar 08, 2021 4:33 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
I got version 2 code base to work for a travel limit switch assembly. I was fighting on this for a long while.

I had to move the jumper wires to make the switches work as designed. to my knowledge this python3 based gpio setup with the pi has not been done or accomplished as of yet.

Code:
#!/usr/bin/python

import cwiid
import RPi.GPIO as GPIO
import sys
from time import *
import subprocess
import board
#import pygame
import keyboard
from gpiozero import Button

from adafruit_motorkit import MotorKit
from adafruit_motor import stepper
kit1 = MotorKit()
# this is for stepper motors
from board import SCL, SDA
import busio
from adafruit_pca9685 import PCA9685
i2c_bus = busio.I2C(SCL, SDA)
pca = PCA9685(i2c_bus)
pca.frequency = 50
# standard servo declearations for controls
from adafruit_servokit import ServoKit
kit = ServoKit(channels=16)
#pygame.init()

# These defs are function definitions and are function calls
def add_print12(channel):
        print("BCM 12 hit")
        kit1.stepper1.release()
        for i in range (200):
          kit1.stepper1.onestep(direction=stepper.BACKWARD, style=stepper.DOUBLE)
def add_print13(channel):
        print("BCM 13 hit")
        kit1.stepper1.release()
        for i in range (200):
          kit1.stepper1.onestep(direction=stepper.FORWARD, style=stepper.DOUBLE)
def add_print27(channel):
        print("BCM 27 hit")
        for i in range (200):
          kit1.stepper2.onestep(direction=stepper.BACKWARD, style=stepper.DOUBLE)
def add_print5(channel):
        print("BCM 5 hit")
        for i in range (200):
          kit1.stepper2.onestep(direction=stepper.FORWARD, style=stepper.DOUBLE)


button12 = Button(12)
button13 = Button(13)
button27 = Button(27)
button5 = Button(5)







while True:
#  GPIO.setmode(GPIO.BCM);
 # GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_UP);
#  GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP);
 # GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP);
 # GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP);

#while True:
# GPIO add event callback.  Callbacks are a fancy way to run a custom command set on detection of an event
#  if not 'event' in locals():
#    event =
#  GPIO.add_event_detect(12, GPIO.FALLING, callback=add_print12, bouncetime=500)
  if button12.is_pressed:
    print("button12 pressed")
    for i in range (200):
      kit1.stepper1.onestep(direction=stepper.BACKWARD, style=stepper.DOUBLE)
#    event =
#  GPIO.add_event_detect(13, GPIO.FALLING, callback=add_print13, bouncetime=500)
  if button13.is_pressed:
    print("button13 pressed")
    for i in range (200):
      kit1.stepper1.onestep(direction=stepper.FORWARD, style=stepper.DOUBLE)
 # for event in pygame.event.get():
  #  if event.type == pygame.KEYDOWN:
   #   if event.key == pygame.K_f:
  if keyboard.is_pressed('f'):
    print("f is pressed")
    for i in range (200):
      kit1.stepper1.onestep(direction=stepper.BACKWARD, style=stepper.DOUBLE)
 # for event in pygame.event.get():
  #  if event.type == pygame.KEYDOWN:
   #   if event.key == pygame.K_b:
  if keyboard.is_pressed('b'):
    print("b is pressed")
    for i in range (200):
      kit1.stepper1.onestep(direction=stepper.FORWARD, style=stepper.DOUBLE)
#  else:
  sleep(0.2)
#  GPIO.cleanup()



_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re: Wiimote with nunchuk on linux via bluetooth
PostPosted: Sat Apr 10, 2021 4:39 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
OK this will be the final code I will be using for the metrothamcon event:

Code:
#!/usr/bin/python
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#|R|a|s|p|b|e|r|r|y|P|i|-|S|p|y|.|c|o|.|u|k|
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#
# wii_remote_1.py
# Connect a Nintendo Wii Remote via Bluetooth
# and  read the button states in Python.
#
# Project URL :
# http://www.raspberrypi-spy.co.uk/?p=1101
#
# Author : Matt Hawkins
# Date   : 30/01/2013
# Updated 8/2020 by Gabriel Vos aka Knoxvilles_joker
# http://alienslegacy.com
# updates done to allow for sound and servo controls and read full feature set of nunchuk
# Please note if using notepad and not notepad++ you must check for excess carriage returns in linux with the nano, vim, or your other preferred editor
# Please note python is very picky about syntax and spaces edit at own risk

# Licensed under GPL/GNU licensing distribute as you see fit but please include header above.
# Not to be used for commercial gain or profit unless credit given to authors.

# -----------------------
# Import required Python libraries
# -----------------------
import cwiid
import time
import os
import subprocess
import board
from board import SCL, SDA
import busio
from adafruit_pca9685 import PCA9685
i2c_bus = busio.I2C(SCL, SDA)
pca = PCA9685(i2c_bus)
pca.frequency = 50
# standard servo declearations for controls
from adafruit_servokit import ServoKit
kit = ServoKit(channels=16)
# class adafruit_moter.servo.Servo(pwm.out, *, actuation_range=180, minPpulse=750, max_pluse=2250)

#import adafruit_fxas21002c
#i2c=busio.I2C(board.SCL, board.SDA)
#sensor1=adafruit_fxas21002c.FXAS21002C(i2c)
import adafruit_mpu6050
i2c = busio.I2C(board.SCL, board.SDA)
sensor1 = adafruit_mpu6050.MPU6050(i2c)
#was mpu = but used old value to easily change code

# due to servo placement and positioning, you have to set the initial deployment angles at settings
# other than zero and ensure that time is given so proper travel can occur without causing undue binding issues.

time.sleep(0.1)
kit.servo[0].angle=160
#time.sleep(3)
kit.servo[1].angle=24
kit.servo[2].angle=140
# 0-2 are basically place holders for armature.
kit.servo[3].angle=180
#kit.servo[4].angle=0
#kit.servo[5].angle=90
#kit.servo[6].angle=0
kit.servo[7].angle=0
kit.servo[13].angle=0
kit.servo[14].angle=90
# these turn all the lights to an off state
kit.servo[6].angle=0
kit.servo[10].angle=0
kit.servo[11].angle=0
kit.servo[15].angle=0


# These are the options for the pwm portion of the servo bonnett
#set_pulse_widge_range(min_pulse, max_pulse)
# kit.servo[0].set_pulse_width_range(1000, 2000)
#pca.channels[15].duty_cycle = 0x7fff

button_delay = 0.1
# these are values for button depress bounces.  I use a counter to ensure accidental presses do not cause undue issues
# this also allows for gpio input if at some point there is a need to switch to RPi.GPIO button inputs with minimal change
# addressing for issues with debounce and system noise on button presses
# note that only ascii characters 0-128 are allowed.  Any special characters are not recognized for character counter names.
btn1cnt = 0
btn2cnt = 0
btnupcnt = 0
btnleftcnt = 0
btndowncnt = 0
btnrightcnt = 0
btnacnt = 0
btnbcnt = 0
btnccnt = 0
btnzcnt = 0
btnhomecnt = 0
btnminuscnt = 0
btnpluscnt = 0

# As a rule I place everything in /boot.  It is not neccessarily a recommend practice but makes later upgrades and midstream
# changes much easier to perform if there are major code updates.

# I may have to use the sub process command set to allow for multi tasking but that is at a later stage
# These are the files for sound playback over the 3.5mm audio output going over the 3.5mm jack from the hdmi port.
# wav files are played with aplay and mp3 files are played with mpg123 engaged using the os.system command subset
# playsound does not appear to play nice with python 3.7 and is not an option currently
#SFX
file1 = "/boot/minigun.wav"
file2 = "/boot/gameover.wav"
#themes
afam = "/boot/addamsfamily.mp3"
pred = "/boot/predator.mp3"
alienc = "/boot/alienscomplex.mp3"
combat = "/boot/combatdroppercussion.mp3"
liftoff = "/boot/liftoff.mp3"
lv426 = "/boot/lv426.mp3"
gb = "/boot/ghostbusters.mp3"
halloween = "/boot/halloweenteme.mp3"
filedown = "/boot/alienisolationintro.mp3"
laser = "/boot/laser.wav"
cannon = "/boot/cannon.wav"
# branches
army = "/boot/armyhymn.mp3"
af = "/boot/airforcesong.mp3"
usmc = "/boot/usmchymn.mp3"
navy = "/boot/navyhymn.mp3"
# sound tracks
b2 = "/boot/b2theme.mp3"
b3 = "/boot/b3introtheme.mp3"
everyrule = "/boot/everyrule.mp3"
jh = "/boot/jhsettingthewoodsonfire.mp3"
jumprope = "/boot/jumprope.mp3"
rammstein = "/boot/rammsteinhallelujah.mp3"
lithiumflower = "/boot/lithiumflower.mp3"
thriller = "/boot/thriller.mp3"
# misc sound effects found later in project
candy ="/boot/candy.wav"
anytime = "/boot/anytime.wav"
death = "/boot/death.wav"
demon = "/boot/demon.wav"
hell = "/boot/hell.wav"
jerry = "/boot/jerry.wav"
otherside = "/boot/otherside.wav"


#subprocess.Popen(['espeak', '--stdout', '-a200', '-g13', '-k01', '-p1', '-s160', '-ven-sc', "Shall we play aa game"], stdout=PIPE)
#subprocess.Popen(['aplay'])
print ('Press 1 + 2 on your Wii Remote now ...')
time.sleep(1)

# Connect to the Wii Remote. If it times out
# then quit.
# note that this is a clean way to quit script if stuff is not connected at startup.
p1 = subprocess.Popen(['espeak', '-a200', '--stdout', '-g13', '-k01', '-p1', "Hit Red Button nnow"], stdout=subprocess.PIPE)
subprocess.Popen(['aplay'], stdin=p1.stdout, stdout=subprocess.PIPE)
try:
  wii=cwiid.Wiimote()
except RuntimeError:
  print ("Error opening wiimote connection")
  quit()

print ('Wii Remote connected...\n')
print ('Press some buttons!\n')
print ('Press PLUS and MINUS together to disconnect and quit.\n')
wii.led = 1
wii.rpt_mode = cwiid.RPT_BTN  | cwiid.RPT_ACC | cwiid.RPT_NUNCHUK

while True:
#  Do not turn this line on unless you like spam in your command line output if you do comment the same line above first though
#  wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC | cwiid.RPT_NUNCHUK
#  below are values pulled from the wm.state data array and stored to be used to drive various functions
#  you can comment out the status display to troubleshoot button pushes.  all buttons are accounted for in the script
  time.sleep(0.1) # pause required to get time for readings.
  battery = wii.state['battery']
  buttons = wii.state['buttons']
  # Wii Accelerometer readings are 0 - 255.  It is a true accelerommeter and it is meant to be used with the IR pointer for calibration in accurate use
  # Online documentation indicates that a light source can be used for referenc ein plcase of a light bar, but your mileage will vary.
  # this function is not used but is reported
  wacc= wii.state['acc']
  # I will be getting a wii motion device at some point and adding it but until then only the nunchuck accelerometer and joystick movements are used.
  nunbut = wii.state['nunchuk']
  nbut =nunbut['buttons']
  nacc =nunbut['acc']
  # Nunchuk stick range appears to be 226 - 26
  nstick= nunbut['stick']
  nstickx= int(((nstick[0]-26)/200)*180)
  nsticky= int(((nstick[1]-26)/200)*180)
  # Nunchuck range appears to be 250 - 26
  naccx  = int(((nacc[0]-20)/233)*180)
  naccy  = int(((nacc[1]-20)/233)*180)
  naccz  = int(((nacc[2]-20)/233)*180)
  time.sleep(button_delay)
# this is using the fxas21002c gyroscope as part of the setup that will mount to the head.  I may change this as I incorporate a QWIIC board.
#
  gyro_x, gyro_y, gyro_z=sensor1.gyro
  rightxa=(((int(gyro_x--256)/(256--256))*180))
  rightza=(((int(gyro_z--256)/(256--256))*180))
# the round() function drops off all additional decimal points.  Useful to provide clean number readouts and input
# note that on more complex numerical calculations it is vital to do rounding as the last step.  rounding errors
# create final calculation deviation and can skew result with sometimes noticable results.
  rightx = round(rightxa)
  rightz = round(rightza)
# These are disabled as the wiimote accelerometer has too odd a range of settings and is not a true tilt sensor
# It was meant to be used in conjuction with a ir ptr for calibration and pointing ability
# This is great for calibration based upon device input range is 0-255
# waccx  = int(((
 # waccy  = int(((
 # waccz  = int(((
  print(wii.state)
  print('wb nb bat joyxy, accxyz')
  print(buttons, nbut, battery, nstickx, nsticky, naccx, naccy, naccz)
  print("gx", rightx, "gz", rightz, gyro_y)

  time.sleep(0.1)
  # servo setup is as follows:
  # main track left is 0, 1 is tilt arm left. 2 is tilt arm left levelling servo, 3 is pan servo for left and right action
  # 5 is main tilt right servo, 6 is levelling servo right, 7 is right pan left right servo
  # 10 is pwm light for firing, 15 is head laser
  # I am still playing with pwm signaling with opto couplers with a full 5v laser setup.
  # due to some issues with coding we have to do an if else to allow for servo2 the second tilt servo to function properly. 
  if (btnhomecnt == 1):
    kit.servo[2].angle=nstickx
    kit.servo[3].angle=nsticky
    kit.servo[14].angle=rightx
    kit.servo[7].angle=rightz
# use naccx if you want to use nunchuk accelerometer settings
  else:
    kit.servo[2].angle = 140
    kit.servo[3].angle = 180
    kit.servo[14].angle = 90
   # kit.servo[5].angle = 90

  time.sleep(button_delay)
  #this was to determine that we need to loop y axis out of bound
  #kit.servo[3].angle = nsticky
  time.sleep(button_delay)
  # the midarm servo is being set to always maintain a level status regardless of arm tilt.  based on my calculations with a 1:1 gear ratio
 # kit.servo[2].angle = nsticky # implemented design indicates that the geared unit needs to be the x tilt mechanism the main armature is just a placement deal
  kit.servo[4].angle = naccx
  kit.servo[6].angle = naccz
  #kit.servo[5].angle = naccx
  # If Plus and Minus buttons pressed
  # together then rumble and quit.
  # This is a great way to exit code if you set it to run at startup and need console control back.
  # This failsafe is a great way to ensure if you have buggy code you have an opportunity to fix it
  # By default I will typically place this in the \boot directory.
  if (buttons - cwiid.BTN_PLUS - cwiid.BTN_MINUS == 0):
    print ('\nClosing connection ...')
    wii.rumble = 1
    time.sleep(1)
    kit.servo[0].angle = 160
    time.sleep(3)
    kit.servo[1].angle = 24
    time.sleep(2)
    kit.servo[2].angle = 140
    kit.servo[3].angle = 180
    kit.servo[4].angle = 0
    kit.servo[5].angle = 90
    kit.servo[6].angle = 0
    kit.servo[7].angle = 0
    kit.servo[13].angle = 0
    kit.servo[14].angle = 90

    time.sleep(4)
    wii.rumble = 0
    exit(wii)
  # this notifies you that the battery is low and prevents comm errors by ensuring you change the battery out.
  # This will constantly rumble until battery is replaced.
  if (battery <= 79):
    print ('please change battery now')
    wii.rumble = 1
    kit.servo[0].angle = 160
    time.sleep(3)
    kit.servo[1].angle = 24
    kit.servo[2].angle = 140
    kit.servo[3].angle = 180
    kit.servo[4].angle = 0
    kit.servo[5].angle = 90
    kit.servo[6].angle = 0
    kit.servo[7].angle = 0
    kit.servo[13].angle = 0
    kit.servo[14].angle = 90

    time.sleep(1)
    wii.rumble = 0
# The battery replace code is a physical reminder that battery is low.
# This is a failsafe to ensure that battery drop off is not severe.
# The value is 0-255 but I have seen it drop to 70s before comms are lost.
# The most I have seen it in is the upper 100s.  Mileage will vary based upon batteries in use
# Please bear in mind wiimote is only designed for standard AA batteries.  Do not cheat with fancier batteries
# The setup and maintenance is intended to be a lower cost setup.


  # Check if other buttons are pressed by
  # doing a bitwise AND of the buttons number
  # and the predefined constant for that button.
  # I am using a counter based setup for actions.
  # Theoretically this could lead to infinite number of actions after sequential number is reached
  # This is great if you are wanting a sequential set of sounds to play in sequence, or a start and reset sequence on a set servo or light
  # Please note that at the beginning for servos you want them all to reset to their neutral start positions.
  # This ensures if things crashed on the last go around you are not hyper extending or retracting servos beyond their active range
  # This lowers power consumption and esures minimal breakage issues

  if (buttons & cwiid.BTN_LEFT):
    print ('Left pressed')
    btnleftcnt = btnleftcnt +1
    print (btnleftcnt, "presses so far")
    time.sleep(button_delay)
  if (btnleftcnt == 2):
    subprocess.Popen(['mpg123', '-q', pred])
    print (btnleftcnt, "playing pred1")
    btnleftcnt = btnleftcnt +1
  if (btnleftcnt == 5):
    btnleftcnt = btnleftcnt +1
    os.system("pkill mpg123")
    print (btnleftcnt, "presses so far")
  if (btnleftcnt == 11):
    btnleftcnt = 0
    time.sleep(button_delay)

  if(buttons & cwiid.BTN_RIGHT):
    print ('Right pressed')
    btnrightcnt = btnrightcnt +1
    print (btnrightcnt, "presses so far")
    time.sleep(button_delay)
  if (btnrightcnt == 2):
    subprocess.Popen(['aplay', '-q', file2])
    btnrightcnt = btnrightcnt +1
    print (btnrightcnt, "playing file2")
    time.sleep(button_delay)
  if (btnrightcnt == 5):
    btnrightcnt = btnrightcnt +1
    os.system("pkill aplay")
  if (btnrightcnt == 8):
    subprocess.Popen(['mpg123', '-q', jumprope])
    btnrightcnt = btnrightcnt +1
    print (btnrightcnt, "playing jumprope")
    time.sleep(button_delay)
# jumprope is so short that a simple stop command should not be needed
# the os.system("pkill app") really is meant for longer file plays
  if (btnrightcnt == 11):
    subprocess.Popen(['mpg123', '-q', afam])
    btnrightcnt = btnrightcnt +1
    print (btnrightcnt, "playing addamsfamily")
    time.sleep(button_delay)
  if (btnrightcnt == 14):
    btnrightcnt = btnrightcnt +1
    os.system("pkill mpg123")
  if (btnrightcnt == 17):
    btnrightcnt = 0
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_UP):
    print ('Up pressed')
    btnupcnt = btnupcnt +1
    print (btnupcnt, "presses so far")
    time.sleep(button_delay)
  if (btnupcnt == 2):
    subprocess.Popen(['mpg123', '-q', filedown])
    btnupcnt = btnupcnt +1
    print (btnupcnt, "playing filedown")
    time.sleep(button_delay)
  if (btnupcnt == 5):
    btnupcnt = btnupcnt +1
    os.system("pkill mpg123")
  if (btnupcnt == 8):
    subprocess.Popen(['mpg123', '-q', alienc])
    btnupcnt = btnupcnt +1
    print (btnupcnt, "playing alienc")
    time.sleep(button_delay)
  if (btnupcnt == 11):
    btnupcnt = btnupcnt +1
    os.system("pkill mpg123")
  if (btnupcnt == 14):
    btnupcnt = btnupcnt +1
    subprocess.Popen(['mpg123', '-q', combat])
    print (btnupcnt, "playing combat")
    time.sleep(button_delay)
  if (btnupcnt == 17):
    btnupcnt = btnupcnt +1
    os.system("pkill mpg123")
  if (btnupcnt == 20):
    btnupcnt = btnupcnt +1
    subprocess.Popen(['mpg123', '-q', liftoff])
    time.sleep(button_delay)
    print (btnupcnt, "playing liftoff")
  if (btnupcnt == 23):
    btnupcnt = btnupcnt +1
    os.system("pkill mpg123")
  if (btnupcnt == 26):
    btnupcnt = btnupcnt +1
    subprocess.Popen(['mpg123', '-q', lv426])
    time.sleep(button_delay)
    print (btnupcnt, "playing lv426")
  if (btnupcnt == 29):
    btnupcnt = btnupcnt +1
    os.system("pkill mpg123")
  if (btnupcnt == 32):
    btnupcnt = 0
    time.sleep(button_delay)


  if (buttons & cwiid.BTN_DOWN):
    print ('Down pressed')
    btndowncnt = btndowncnt +1
    print (btndowncnt, "presses so far")
    time.sleep(button_delay)
  if (btndowncnt == 2):
    subprocess.Popen(['mpg123', '-q', af])
    time.sleep(button_delay)
    btndowncnt = btndowncnt +1
    print (btndowncnt, "playing af")
  if (btndowncnt == 5):
    btndowncnt = btndowncnt +1
    os.system("pkill mpg123")
  if (btndowncnt == 8):
    btndowncnt = btndowncnt +1
    subprocess.Popen(['mpg123', '-q', army])
    time.sleep(button_delay)
    print (btndowncnt, "playing army")
  if (btndowncnt == 11):
    btndowncnt = btndowncnt +1
    os.system("pkill mpg123")
  if (btndowncnt == 14):
    subprocess.Popen(['mpg123', '-q', navy])
    time.sleep(button_delay)
    btndowncnt = btndowncnt +1
    print (btndowncnt, "playing navy")
  if (btndowncnt == 17):
    btndowncnt = btndowncnt +1
    os.system("pkill mpg123")
  if (btndowncnt == 20):
    btndowncnt = btndowncnt +1
    subprocess.Popen(['mpg123', '-q', usmc])
    time.sleep(button_delay)
    print (btndowncnt, "playing usmc")
  if (btndowncnt == 23):
    btndowncnt = btndowncnt +1
    os.system("pkill mpg123")
  if (btndowncnt == 26):
    btndowncnt = 0
    time.sleep(button_delay)
    print (btndowncnt, "resetting count, restarting loop")

  if (buttons & cwiid.BTN_1):
    print ('Button 1 pressed')
    btn1cnt = btn1cnt +1;
    print(btn1cnt, "presses so far")
    time.sleep(button_delay)
  if (btn1cnt == 3):
    print (btn1cnt, "reached playing minigun snd");
#    os.system("aplay " + file1);
#   I am replacing the above with a subprocess that will allow for multitasking/sub process concurrency.
#   It makes for some interesting sound combinations...
#   It appears that concurrency limit is about 4.  This is the only way to play sounds and keep the script read loop running
#    Moving servos and having sound effects
#    For shorter sound effects I am not invoking a pkill command set.
    subprocess.Popen(['aplay', '-q', file1])
    btn1cnt = 0
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_2):
    print ('Button 2 pressed')
    btn2cnt = btn2cnt +1;
    print(btn2cnt, "presses so far");
    time.sleep(button_delay)
  if (btn2cnt == 2):
    print (btn2cnt, "reached playing gameover")
    subprocess.Popen(['aplay', '-q', file2])
    btn2cnt = btn2cnt +1
    time.sleep(button_delay)
# gameover is a super short clip comparatively so no pkill is needed
  if (btn2cnt == 5):
    print (btn2cnt, "presses so far")
    subprocess.Popen(['mpg123', '-q', rammstein])
    btn2cnt = btn2cnt +1
    print ("playing rammstein")
  if (btn2cnt == 8):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 11):
    print(btn2cnt, "presses so far")
    subprocess.Popen(['mpg123', '-q', lithiumflower])
    btn2cnt = btn2cnt +1
    print ("playing lithium flower")
  if (btn2cnt == 14):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 17):
    btn2cnt = btn2cnt +1
    print (btn2cnt, "presses so far")
    subprocess.Popen(['mpg123', '-q', thriller])
    print ("playing thriller")
  if (btn2cnt == 20):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 23):
    btn2cnt = btn2cnt +1
    print (btn2cnt, "presses so far")
    subprocess.Popen(['mpg123', '-q', gb])
    print ("playing ghostbusters instrumental")
  if (btn2cnt == 26):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 29):
    btn2cnt = btn2cnt +1
    print (btn2cnt, "presses so far")
    subprocess.Popen(['mpg123', '-q', halloween])
    print ("playing halloween instrumental them")
  if (btn2cnt == 32):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 35):
    print (btn2cnt, "presses so far")
    btn2cnt = btn2cnt +1
    subprocess.Popen(['mpg123', '-q', jh])
    print ("playing setting wodds on fire with joker and harley")
  if (btn2cnt == 38):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 41):
    btn2cnt = btn2cnt +1
    subprocess.Popen(['mpg123', '-q', b2])
    print ("playing borderlands2 theme song")
  if (btn2cnt == 44):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 47):
    btn2cnt = btn2cnt +1
    subprocess.Popen(['mpg123', '-q', b3])
    print ("playing borderlands3 themesong")
  if (btn2cnt == 50):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 53):
    btn2cnt = btn2cnt +1
    subprocess.Popen(['mpg123', '-q', everyrule])
    print ("playing everyone wants to rule the world")
  if (btn2cnt == 56):
    btn2cnt = btn2cnt +1
    os.system("pkill mpg123")
  if (btn2cnt == 59):
    btn2cnt = 0
    print ("resetting count")


  if (buttons & cwiid.BTN_A):
    print ('Button A pressed engaging disengaging laser')
    btnacnt = btnacnt +1
    print(btnacnt, "presses so far")
    time.sleep(button_delay)
  if (btnacnt == 2):
    subprocess.Popen(['mplayer', laser])
    kit.servo[15].angle = 110
    kit.servo[4].angle = 110
    time.sleep(button_delay)
    btnacnt = btnacnt +1
    print (btnacnt, "playing and lighting laser")
  if (btnacnt == 5):
    subprocess.Popen(['mplayer', laser])
    kit.servo[15].angle = 40
    kit.servo[4].angle = 40
    btnacnt = btnacnt +1
    print (btnacnt, "playing laser and powering down")
  if (btnacnt == 8):
    btnacnt = 0
    print (btnacnt, "resetting count restarting a loop")
    time.sleep(button_delay)

  if (buttons & cwiid.BTN_B):
    print ('Button B pressed')
    btnbcnt = btnbcnt +1;
    print(btnbcnt, "presses so far");
    time.sleep(button_delay)
  if (btnbcnt == 3):
    print('btnbcnt reached playing laser sound');
    kit.servo[11].angle = 110
    time.sleep(1)
    kit.servo[10].angle = 110
    subprocess.Popen(['mplayer', cannon])
    time.sleep(.5)
    kit.servo[10].angle = 40
    time.sleep(.2)
    kit.servo[11].angle = 40
    btnbcnt = 0;
    print (btnbcnt, "playing cannon sound and lighting up")
    time.sleep(button_delay);

  if (buttons & cwiid.BTN_HOME):
    print ('Home Button pressed')
    btnhomecnt = btnhomecnt +1;
    print(btnhomecnt, "presses so far");
    time.sleep(button_delay)
  if (btnhomecnt == 0):
    # Initial starting point.  This ensures no movements until you are ready and accounts for accidental presses as you fumble with things suiting up and powering stuff on.
    kit.servo[0].angle = 160
#    time.sleep(4)
    kit.servo[1].angle = 24
    kit.servo[3].angle = 180
    kit.servo[2].angle = 140
    kit.servo[13].angle = 0
    kit.servo[14].angle = 90
    kit.servo[5].angle = 90
#   tilt angle control is done through an if or else statement at beginning of script to constrain movement in down position
    time.sleep(button_delay);
  if (btnhomecnt == 1):
    kit.servo[0].angle = 10
    kit.servo[1].angle = 95
    kit.servo[13].angle = 51
    #this is the operating position.  Other arms will get added as I get the build out further along.
#   I had to add a separate failsafe check to reset btnhome count to prevent erraneous readings for the angle of the cannon on the y axis.
  if (btnhomecnt == 2):
  #  time.sleep(4)
    btnhomecnt = 0

  if (buttons & cwiid.BTN_MINUS):
    print ('Minus Button pressed')
    btnminuscnt = btnminuscnt +1;
    print(btnminuscnt, "presses so far");
    time.sleep(button_delay);
  if (btnminuscnt == 2):
    os.system("amixer set HDMI -- 400")
    btnminuscnt = btnminuscnt +1
  if (btnminuscnt == 5):
    time.sleep(button_delay)
    btnminuscnt = btnminuscnt +1
    os.system("amixer set HDMI -- 200")
  if (btnminuscnt == 8):
    btnminuscnt = btnminuscnt +1
    os.system("amixer set HDMI -- 0")
  if (btnminuscnt == 11):
    btnminuscnt = btnminuscnt +1
    os.system("amixer set HDMI -- -2000")
  if (btnminuscnt == 14):
    btnminuscnt = btnminuscnt +1
    os.system("amixer set HDMI -- -4000")
  if (btnminuscnt == 17):
    btnminuscnt = btnminuscnt +1
    os.system("amixer set HDMI -- -10200")
  if (btnminuscnt == 20):
    print ("resetting count");
    btnminuscnt = 0
    time.sleep(button_delay);

  if (buttons & cwiid.BTN_PLUS):
    print ('Plus Button pressed')
    btnpluscnt = btnpluscnt +1
    print (btnpluscnt, "presses so far")
    time.sleep(button_delay)
  if (btnpluscnt == 2):
    btnpluscnt = btnpluscnt +1
    print (btnpluscnt, "presses so far")
    subprocess.Popen(['mplayer', anytime])
  if (btnpluscnt == 5):
    btnpluscnt = btnpluscnt +1
    subprocess.Popen(['mplayer', demon])
  if (btnpluscnt == 8):
    btnpluscnt = btnpluscnt +1
    print (btnpluscnt, "presses so far")
    subprocess.Popen(['mplayer', candy])
  if (btnpluscnt == 11):
    btnpluscnt = btnpluscnt +1
    print (btnpluscnt, "presses so far")
    subprocess.Popen(['mplayer', hell])
  if (btnpluscnt == 14):
    btnpluscnt = btnpluscnt +1
    print (btnpluscnt, "presses so far")
    subprocess.Popen(['mplayer', death])
  if (btnpluscnt == 17):
    btnpluscnt = btnpluscnt +1
    subprocess.Popen(['mplayer', jerry])
    print (btnpluscnt, "presses so far")
  if (btnpluscnt == 20):
    btnpluscnt = btnpluscnt +1
    subprocess.Popen(['mplayer', otherside])
    print (btnpluscnt, "presses so far")
  if (btnpluscnt == 23):
    btnpluscnt = 0
    print ("resetting count and resetting loop")



  if (nbut & cwiid.NUNCHUK_BTN_C):
    print ('nunchuk c pressed')
    btnccnt = btnccnt +1;
    print (btnccnt, "presses so far")
    time.sleep(button_delay)
  if (btnccnt == 2):
    kit.servo[6].angle = 110
    subprocess.Popen(['mplayer', laser])
    time.sleep(.2)
    btnccnt = btnccnt +1
  if (btnccnt == 5):
    print ('fire left cannon, lights')
    subprocess.Popen(['mplayer', laser])
    time.sleep(1)
    kit.servo[6].angle = 40
    btnccnt = 0

  if (nbut & cwiid.NUNCHUK_BTN_Z):
    btnzcnt = btnzcnt +1
    print (btnzcnt, "presses so far")
    print ('nunchuk z pressed')
    time.sleep(button_delay)
  if (btnzcnt == 2):
  #  kit.servo[6].angle = 110
    subprocess.Popen(['mplayer', laser])
    time.sleep(.3)
    btnzcnt = btnzcnt +1
  if (btnzcnt == 5):
    btnzcnt = btnzcnt +1
    kit.servo[4].angle= 110
    kit.servo[11].angle= 110
  if (btnzcnt == 8):
    btnzcnt = btnzcnt +1
    kit.servo[15].angle=110
    kit.servo[10].angle=110
    subprocess.Popen(['mplayer', cannon])
    time.sleep(.5)
    kit.servo[15].angle=40
    kit.servo[10].angle=40
  if (btnzcnt == 11):
    btnzcnt = btnzcnt +1
  if (btnzcnt == 14):
    print ('fire right cannon, lights')
    kit.servo[4].angle = 40
    kit.servo[11].angle = 40
    subprocess.Popen(['mplayer', laser])
    btnzcnt = 0
    time.sleep(button_delay)
    time.sleep(1)
   # kit.servo[6].angle = 40

  if (nbut - cwiid.NUNCHUK_BTN_Z - cwiid.NUNCHUK_BTN_C == 0):
    print ('nunchuk c plus z pressed')
    time.sleep(button_delay)

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Apr 10, 2021 4:45 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
For some reason soundplayer would not initialize in python or associate for whatever reason. I added sox but play does do tones which I went with a simple tone to indicate button presses. I added an espeak for the main run script to queue when to hit the red button on the back. I added this to /etc/rc.local as sudo python3 /boot/bootcode.py &

Code:
#/usr/bin/python
import psutil
from subprocess import Popen
import time
import os
import subprocess
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(21, GPIO.FALLING, bouncetime=2000)
btn21cnt = 0
btn21run = 0
while True:
  for process in psutil.process_iter():
    if process.cmdline() == ['python3', 'wii_remote_final2.py']:
      btn21run = 1
#    else:
 #     print('Process not found: starting it.')
  #    btn21run = 0
  if GPIO.event_detected(21):
    btn21cnt = btn21cnt + 1
    subprocess.Popen(['play', '-n', '-c1', 'synth', '0.25', 'sine', '1000'])
    print(btn21cnt, "presses so far")
    time.sleep(0.1)
  if (btn21cnt == 3):
    print(btn21cnt, "threshold reached stopping script")
    os.system("killall -9 wii_remote_final2.py")
    btn21cnt - btn21cnt + 1
  if (btn21cnt == 6):
    print(btn21cnt, "threshold reached starting script")
    subprocess.run(['python3', '/boot/wii_remote_final2.py'])
    btn21cnt = 0


_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat May 22, 2021 7:12 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
OK, looks like I may have found a replacement for the pimoroni on/off shim.

https://www.adafruit.com/product/5038

witty pi3 mini bonnet.

The bonnet form factor would allow for maybe condensing the stack a little bit more...

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re:
PostPosted: Sun Jun 13, 2021 7:08 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
knoxvilles_joker wrote:
OK, looks like I may have found a replacement for the pimoroni on/off shim.

https://www.adafruit.com/product/5038

witty pi3 mini bonnet.

The bonnet form factor would allow for maybe condensing the stack a little bit more...


I had to remove the pimoroni scripts and then things worked. I did discover though that the wittypi shares the same address as the mpu6050. I had to switch to another cheap gyroscope and that is enroute.

integration test so far has been ok. I had some weird troubleshooting issues trying to get the limit test script working properly.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Jun 20, 2021 8:38 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
I made some progress on the new prototype setup. Wiring things up for full on ethernet quick disconnects is proving to make transport a much easier affair.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Jul 05, 2021 3:57 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
The ethernet screw terminal adapters are working rather well. The new sensor works but the -5 to 5 range does up the sensitivity. I will have to get a new stepper motor as I think one I am using has a winding or draw issue of some sort.

I have discovered that the stepper motor board will cause a pause on the script as the linear motion command is executing. Not too different from current setup but it does cause an inconvenient pause as things are engaging or disengaging.

The board setup is definitely a lot more streamlined now.

I have found some options to wire in the gpio buttons a bit better. There are screw terminal shields out there now.
https://store.ncd.io/

Apparently the pi is getting super popular and is starting to overtake some of the Arduino things for functionality.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Jul 10, 2021 7:59 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
wiimote integrates but for some reason the remap had to be re-adjusted for a max range of 255-0 on the analog stick.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 08, 2021 1:05 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
Ok recent wear test at fanboy showcased that I need to up the amperage on the power supply and get a beefier capacitor.

I will have to bench the setup again to run down the issue on the right cannon arm.

https://forums.adafruit.com/viewtopic.p ... 72#p897172

I have asked adafruit what is the max power I can run through the servo board as well.

So far the suit it looks like a good AVP demolisher.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re: Wiimote with nunchuk on linux via bluetooth (Xeno/Pred)
PostPosted: Mon Nov 08, 2021 1:05 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
Attachment:
IMG_3468.JPG
IMG_3468.JPG [ 1.73 MiB | Viewed 3303 times ]
here is a pic

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Nov 29, 2021 12:04 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
Still trying to sort power distribution. I will need to split the servo power between two power connections. The pca9685 board supports a max of 8amps and I just need another to take the rest of the load.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Dec 04, 2021 8:25 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
rev robotics power injection unit seemed to do the trick.
https://www.revrobotics.com/rev-11-1144/

Once I used a 14AWG cable and adapted it to a dc barrell connector power issues all seemed to disappear.

It does appear that xt60 connectors may be better suited for the higher amperage draws, but, the battery packs I am using use barrel connectors.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject: Re:
PostPosted: Wed Dec 15, 2021 5:32 pm 

Service Number: A05/TQ2.0.32141E1
Country: United States
knoxvilles_joker wrote:
rev robotics power injection unit seemed to do the trick.
https://www.revrobotics.com/rev-11-1144/

Once I used a 14AWG cable and adapted it to a dc barrell connector power issues all seemed to disappear.

It does appear that xt60 connectors may be better suited for the higher amperage draws, but, the battery packs I am using use barrel connectors.


OK, some more digging. servo cables are typically 22awg. some are 20awg and some folks are switching to 18awg.

I will need to get some servo power monitors as I think some of my cables either have an intermittent connection or are getting overloaded due to physics limitations of the wire gauges used.

So I could buy some 20awg cables and see if that helps.

Premade cables are best as the machine made cables are more standard in quality and connectivity. Manually making cables requires a matching crimper and die for less errors on cable creation. 18awg are becoming more of a commonality but are made by the makers and not in a factory setting as of yet.

Ironically troubleshooting wiring harness on this and on vehicles is not too terribly different.

My prior idea on using an ethernet harness setup, may actually stop some of the issues as I could add a separate power connector to power servos. Soldering the wires together as they are added to the screw terminal connectors also ensures a better solid connection. Plus that sort of setup lessens insertion loss with few connectors being used.

The key though I think is to only use name brand wire extension cables.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun May 15, 2022 7:52 am 

Service Number: A05/TQ2.0.32141E1
Country: United States
According to adafruit with the shorter runs voltage drop is not as much of a concern.

Now it appears that the rev robotics servo module is incompatible with the pca9685 servo board. Something with signals and dc-dc power conversion causing some bleed through.

Just on prior calculations I will need to split the board out power wise. So I am stuck with a bus or a power module of some sort.

_________________
The impossible takes a while longer and goes over budget too...


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 60 posts ]  Go to page Previous  1, 2, 3  Next



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron