The Aliens Legacy http://forum.alienslegacy.com/ |
|
Wiimote with nunchuk on linux via bluetooth (Xeno/Pred) http://forum.alienslegacy.com/viewtopic.php?f=3&t=18792 |
Page 1 of 3 |
Author: | knoxvilles_joker [ Sun May 31, 2020 1:30 am ] |
Post subject: | Wiimote with nunchuk on linux via bluetooth (Xeno/Pred) |
after having multiple issues with i2c addressing the nunchuk alone I decided to try using the wiimote with the nunchuk slaved to it going completely wireless side stepping the i2c bus issue. I have another option I will try on the raspberry pi that may help to address things and that post will get updated at that point. The short answer is I am getting a poor connection causing issues. Now down to business. The wiimote is a wonderful product as you have literally 24 possible button readings/states available to control any number of functions. The fact that it is wireless and only requires two AA batteries is especially good as the number one problem with any costume is too many wires getting in the way. Most of this stuff was initlally developed about ten years ago and has been rolled into most all mainstream Linux installs to date. Please note if you are running something other than Raspbian your commands may be slightly different. Also please note that as Linux advances, and it does so rapidly at a pace that it can boggle a mind when stuff works after a few months with fresh installs. Note in the thread or PM/email me if you are having issues with version info and we can troubleshoot through and try to document/figure out what is going on. First lets make sure we have the needed modules installed sudo apt-get install lswm wminput libcwiid1 sudo apt install bluez sudo apt-get install xwiimote Now the hardware address of the is obtained through the bluetoothctl command init just run bluetoothctl that opens console command and you need to run these commands agent on discoverable on scan on Output will be a list of devices. Hit the sync red button on the battery bay area of the wii mode to get it to broadcast its information for 20 seconds. Take note of the 16 character mac address. Make sure to note confuse the o with a zero as it is a hexadecimal address and things won't work with wrong characters list will list the avialble controllers and this is only relevant if you have a slaved controller. devices will show the available devices that the Bluetooth scan sees paired-devices shows which devices are paired. Once the device shows up reliably, noted by not having lights light up everyime you hit sync, you will need to set some settings for the device info mac_addr will show information on the device. This will have needed info if you are trying to manipulate some settings if you are using any sort of knock off or other device trust mac_addr sets the device as trusted pair mac_addr pairs it with the pi connect mac_addr connects the device. pairing and trust are consistant across reboots. sdptool is another nice utility as well but it is a little more tricky but can get you similar information on the devices sdptool browse will show a list of connected devices sdptool search --bdaddr mac_addr 0x0011 will show information on the wii nunchuck you get the mac_addr from running browse To verify that the nunchuk is connected you check here for hid_wiimote /sys/module Once you get that verified you can now run down to the xwii command set xwiishow list will show the connected device along with its uuid and identifier. note the number then run xwiishow # you will get a screen after a frew moments and it will list live raw data readings. On my hardware pieces I will have to add some additional settings to recognize additional button presses. Source sites for information: http://manpages.ubuntu.com/manpages/tru ... ote.7.html https://www.lifewire.com/use-nintendo-w ... es-2202065 https://www.instructables.com/id/Wiimot ... berry-Pi-/ http://manpages.ubuntu.com/manpages/tru ... ote.7.html https://dietpi.com/phpbb/viewtopic.php?t=2966 http://raspberrypi-aa.github.io/session4/venv.html http://wiiyourself.gl.tter.org/ https://sourceforge.net/projects/wiiuse/ https://automaticaddison.com/how-to-mak ... pberry-pi/ http://www.brianhensley.net/2012/08/wii ... esome.html https://www.raspberrypi-spy.co.uk/2013/ ... pberry-pi/ https://sudomod.com/forum/viewtopic.php?t=1607 https://www.cl.cam.ac.uk/projects/raspb ... t/wiimote/ https://stackoverflow.com/questions/567 ... -extension https://stackoverflow.com/questions/102 ... tion-issue https://github.com/wedesoft/cwiid https://github.com/abstrakraft/cwiid http://wiki.ros.org/cwiid https://github.com/dvdhrm/xwiimote/archive/master.zip https://github.com/dvdhrm/xwiimote-bind ... master.zip |
Author: | knoxvilles_joker [ Sun May 31, 2020 11:07 pm ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
OK, compiling the wiimote software from source seems to have helped things But, compiling dependencies need to be met with these installs: sudo apt-get install dh-autoreconf sudo apt install libudev-dev sudo apt-get install libncurses5-dev sudo apt-get install git build-essential swig3.0 python-dev nodejs-dev cmake libjson-c-dev sudo apt-get install swig These files need to be downloaded: wget https://github.com/dvdhrm/xwiimote/archive/master.zip mv master.zip xwiimote.zip then to install it: sudo sh autogen.sh sudo make sudo make install wget https://github.com/dvdhrm/xwiimote-bind ... master.zip mv master.zip xwiimote-bindings.zip then to install it: sudo sh autogen.sh sudo make sudo make install Compiling from source assures you have the latest build. It also fixes some issues you may have from out of date install repositories(old files) that your OS might have. |
Author: | knoxvilles_joker [ Fri Jun 05, 2020 9:53 pm ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
to set the nunchuck to auto connect at startup: sudo crontab -e 2 enter at bottom enter: @ reboot echo "connect 00:00:00:00:00:00" | bluetoothctl <-- 00:00:00:00:00:00 is the mac address of your wiimote. reboot and hit buttons 1 and 2 simultaneously on remote as pi is starting up. It will auto connect and will pause on hostname section at startup and then resume booting. Please note that if you change batteries or otherwise shut off remote a reboot of the pi will be required for reconnection in headless mode (no screen and keyboard used.) |
Author: | 88reaper88 [ Sat Jun 06, 2020 10:12 am ] |
Post subject: | |
What’s this got to do with Aliens? |
Author: | knoxvilles_joker [ Sun Jun 07, 2020 2:43 am ] |
Post subject: | Re: |
88reaper88 wrote: What’s this got to do with Aliens? This is an update to my control headend upgrades to my predator. Alternately I am doing this in generic enough a matter that you could use this to control a xenomorph. You could use it to play up to 24 different sounds. You could use this to remotely control a sentry gun setup. It could be used to control a robotic facehugger It could control a robot. To my knowledge this has not been documented and done to date. Plus I am having to work with the developer to see about getting some library updates done. The actual control boards being used are half the size of the current setup. Plus the way that I code things I try to make it very, very, very easy for newcomers and have no issues at all helping anyone at anytime if they are having issues with electronics or programming. The goal afterall is to make this community as welcoming as possible to anyone starting in the craft and trade of costuming. It was also a recent realization that by craft I am a very adept technical writer as that is something I have done at every single job I have ever had. Plus the spill over with creative energies has made me realize that I am also gifted with the ability to draft screen play and comedic skits. But the core question remains, how do I use my abilities and gifts to grow this group and make it the most awesome place on the internet? I had posed the question on having a separate section for predator or xenomorphs on the forums, but it really takes away from the main forum activity. The more you divide the more you split up the group into a separate shell that many never pay a mind to anywhere near as much. This is not getting posted on therpf. adafruit.com forums are down and have been going up and down as the international unrest continues and I would normally post this there additionally. |
Author: | knoxvilles_joker [ Sun Jun 14, 2020 11:13 am ] |
Post subject: | |
The CWIID library appears to be housed here: https://github.com/abstrakraft/cwiid http://wiki.ros.org/cwiid OK compiling from source: wget https://github.com/abstrakraft/cwiid/archive/master.zip mv master.zip cwiid.zip cd cwiid-master sudo apt-get install flex bison libbluetooth-dev gtk2.0-dev gtk2.0 gawk libgtk-3-dev sudo apt-get install build-essential zlib1g-dev pkg-config libglib2.0-dev binutils-dev libboost-all-dev autoconf libtool libssl-dev libpixman-1-dev libpython-dev python-pip python-capstone virtualenv python3-gi sudo libtoolize -f sudo aclocal -I usr/share/aclocal sudo automake -a -c sudo autoconf sudo ./configure sudo make sudo make install Doing a straight ./configure won't work you have to do autogen and then ./configure but then you get stuck on not finding gtk on check packages. Now the issue is this setup conflicts with xwiimote library as referenced above. I will again reach out to the author on this and see what options we have. |
Author: | knoxvilles_joker [ Sat Jun 20, 2020 8:47 am ] |
Post subject: | |
cwiid is compiled. I have reached out to the author on xwiimote to see what options we have as it keeps looking for a library file that is not there. The fix was in the bug reports and is resolved by: export LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH} source ~/.bashrc |
Author: | knoxvilles_joker [ Sat Aug 08, 2020 9:50 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
Got it working had to do this: bluetoothctl scan on pair bdaddr (where bdaddr is the Bluetooth address of the wiimote) compile cwiid and python3-wiimote from source here: https://github.com/azzra/python3-wiimote https://github.com/abstrakraft/cwiid copy 2.7 python modules to python3.7 as all the adafruit pieces are python3.7 only. https://talk.maemo.org/showthread.php?t=60178 This side showed the nomenclature to get me started: step down to python3 console with: sudo python3 import cwiid wm=cwiid.Wiimote() (hit sync button on bottom of remote) wm.state (shows current report state) report state is changed with: wm.rpt_mode = cwiid.RPT_BTN wm.led=# where # equals a decimal value 1 - 15 noted here: https://github.com/abstrakraft/cwiid/bl ... /command.c wm.rumble=# where # equals a uint8_t value noted here: https://github.com/abstrakraft/cwiid/bl ... /command.c Report options are as follows: RPT_STATUS minimal report RPT_NUNCHUK report on the nunchuk RPT_MOTIONPLUS report on the motionplus adapter RPT_IR report on the IR function, requires bar accessory to work RPT_EXT reports all readings on whatever connected device RPT_CLASSIC report on the classic controller RPT_BTN report on the wiimote controller RPT_BALANCE report on the balance controller RPT_ACC report on the wiimote accelerometer readings dir(cwiid) gives you all command options I am still going through the command options and identifying how I can avoid having to do placeholder arrays and processing things . I have posted an issues report on the developer GitHub documenting these requesting that they be added to the man pages (in layman's terms that is the funny user manual that is supposed to document everything.) |
Author: | knoxvilles_joker [ Mon Aug 10, 2020 3:12 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
OK, I can get ALL the readings to read into an array: wm.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC | cwiid.RPT_NUNCHUK {'rpt_mode' : 22, 'led' : 2, 'rumble' : 0, 'battery': 120, 'ext_type': 1, 'error': 0, 'buttons': 0, 'acc': (145, 128, 145), 'nunchuk': {'stick': (125, 129), 'acc': (171, 117, 132), 'buttons': 0}} The issue is that I have to rename ACC and BUTTONS to account for duplicate but discrete entries. |
Author: | knoxvilles_joker [ Mon Aug 17, 2020 3:41 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
OK, the way the reporting runs as seen here: wm.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC | cwiid.RPT_NUNCHUK {'rpt_mode' : 22, 'led' : 2, 'rumble' : 0, 'battery': 120, 'ext_type': 1, 'error': 0, 'buttons': 0, 'acc': (145, 128, 145), 'nunchuk': {'stick': (125, 129), 'acc': (171, 117, 132), 'buttons': 0}} This option set for reporting methodology will not work. You can use: wm.rpt_mode=cwiid.RPT_STATUS | cwiid.RPT_NUNCHUK or wm.rpt_mode=cwiid.RPT_STATUS | cwiid.RPT_ACC and not get duplicate array items. The core issue is that the wm.state is basically a print command for a dictionary array. The way that the python language works you can no slice sub dictionary elements without stepping things through more formatting. This is the quickest way to grab the wii nunchuk button states: wmbut=wm.state['nunchuk']; wbut=wmbut['buttons']; print(wbut) That will give the nunchuk button states as an integer value of 0, 1, 2, or 3. for acc settigs you will need to do this: wmbut=wm.state['nunchuk']; wacc=wmbut['acc']; print(wacc) This will give a value of (x, y, z) |
Author: | knoxvilles_joker [ Sat Aug 22, 2020 12:39 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
OK, because of the reporting methodology in use by libcwiid and python you have to extract the data, store it as variables and then use those as input for other commands. sudo python3 import cwiid wm=cwiid.Wiimote() wm.rpt_mode=cwiid.RPT_NUNCHUK nunbut=wm.state['nunchuk']; print(nunbut); wacc=nunut['acc']; print(wacc); naccx=wacc[0]; naccy=wacc[1]; naccz=wacc[2]; print(naccx, naccy, naccz); nstick=nunbut['stick']; nstickx=nstick[0]; nsticky=nstick[1]; print(nstickx, nsticky); nunbuttons=nunbut['buttons']; print(buttons); wm.state; and would yield the following output: (numbers will vary based upon wm.state data) {'stick': (124, 129), 'acc': (170, 121, 136), 'buttons': 0} 170, 121, 136) 170, 121, 136 (124, 129) 124, 129 0 |
Author: | knoxvilles_joker [ Sat Aug 22, 2020 3:52 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
the next key is to remap the accelerometer and stick values into values that the servos can use. There are two value options a pwm signal length (0ish to 2200ish), or an angular reading(0ish. There is not a clean way to do this built into the library. Nor is there a good remap or constrain function I could easily locate for the need. The basic remap formula is: new value = ((old value - old min)/(old max - old min))*(new max-new min) + new min The stick has a value range on the nunchuk of 28-220 and we are remapping to the typical servo range of 0-180 degrees. So the formula simplified is: new value = (( old value - 28)/(220-28))*(180 - 0) + 0 = ((old value - 28)/(192))* 180 so if our nunchuk value is a neutral 124 for the x access and has a value name of nstickx and we are going to name the new remapped value as nstickxr, we would have something like this: nstickr = ((nstickx -28)/(192))*180 (now in the next line lets substitute in the value of 124) nstickr = ((124-28)/192))*180 = ((96)/192))*180 = 0.5 * 180 = 90 = nstickr Now if you are not sure that you will always get a non integer value we will need to remap the number as an integer value. That is done with the int() function like so: nstickri = int(nstickr) but how can we simplify? nstickr= int(((nstickx-28)/192))*180) This works, but, can we simplify the equation and variables any more? Let us try to include the calculations into the readings we actually pull from the data array we are getting from the wiimote with minimal steps. for this case example lets pull the x axis reading on the nunchuk joystick nunbut=wm.state['nunchuk']; nstick=nunbut['stick']; print(nstick); nstickx=int(((nstick[0]-28)/192)*180); print(nstickx); that yields a result of (in neutral position): (124, 129) 90 Now the wiimote accelerometer is a little bit different as it has a max value of 255 (range 0-255.) The accelerometer in it is a true accelerometer in purpose and design and was intended to be used with the IR pointer and a light bar to track cursor movements. Not a good reader of movement, though I might play with a motion plus once I get one to see if I can get better acceleration readings with it. The wii nunchuk is a little bit different on its accelerometer readings as it is setup as more of a agyroscope position type sensor and as such is better at detecting yaw and pitch changes (x and z values.) the readings range on it seems to vary between 180 and 70 nunbut=wm.state['nunchuk']; nacc=nunbut['acc']; print(nstick); naccx=int(((nacc[0]-70)/110)*180); print(naccx); And this yields: (76, 104, 100) 9 And who thought that after highschool and college that they would no longer be doing polynomial math? |
Author: | knoxvilles_joker [ Sun Aug 23, 2020 5:28 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
Some conceptual notes. I may need to do a separate one on the math broken down. Attachment:
|
Author: | knoxvilles_joker [ Sun Aug 23, 2020 9:06 am ] |
Post subject: | |
OK, to ensure accidental button presses do not cause issues I added an incremental button press counter to the buttons I would be using for sounds. I followed the format that you would use for RPi.GPIO so that it would be a simple matter to later adapt using GPIO input pins into the code base. I took the button detection parts of the script for example button 2 and did this with it: at the top I declared all btncounters at a value of zero. I will also do this with all the servos and lights in case things get into a stale state if there is a battery or other power failures. import time import os btn2cnt = 0; file2 = "/boot/gameover.wav"; if (buttons & cwiid.BTN_2): print ('button 2 pressed'); btn2cnt = btn2cnt +1; print(btn2cnt, "presses so far"); time.sleep(button_delay) if (btn2cnt == 3): print ('btn2cnt reached playing gameover'); os.system("aplay " + file2); btn2cnt = 0; time.sleep(button_delay I directly call the audio file with aplay to play a wave file. I call directly to the files actual physical location and in so doing prevent issues where the script is in a different folder. On these sort of setups I prefer to keep things in the /boot directory as that way if something really hoses up I can simply reload things by loading the sdcard into a computer and reloading files. I use aplay for wav files and mpg123 for mp3 files. At each step a delay of 100ms is done to allow the pi to keep up. Now onto the board bonnet. I had to implement two variants of it. One for LED controls and the other for servo controls. They are able to run concurrently. 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 That sets up the board for duty ccycle implementation for the board. To call an led you call it like this: pca.channels[15].duty_cycle = 0x7fff That takes care of the light piece. I will have to play with an optocoupler to step up voltage on a super bright led array I have but that should be simple if I am understanding the wiring correctly now. To setup the servo control piece we do this: from adafruit_servokit import ServoKit kit = ServoKit(channels=16) to move a servo you call it like this: kit.servo[0].angle=180. the number in brackets is the channel number. The angle is an angle with a value of 0 to 180. Now after digging through the libraries and compositional files I found that I can run this report mode and pull EVERYTHING needed for our control setup. wii=cwiid.Wiimote() (this connects the wiimote and sets its instance as wii) (I have not tested it with two wii motes though...) wii.led = 1 (this turns on the second led to let you know that it is connected) wii.rpt_mode = cwiid.RPT_BTN | cwiid.RPT_ACC | cwiid.RPT_NUNCHUK now with that setup within the run loop you need to draw the data from wm.state. I do it this way: battery= wii.state['battery'] buttons = wii.state['buttons'] wacc = wii.state['acc'] nunbut = wii.state['nunchuk'] nbut = nunbut['buttons'] nacc = nunbut['acc'] nstick = nunbut['stick'] Now the nunchuk readings were output in wm.state as a nested dictionary. Due to the way that python is you can not slice or otherwise callout directly a subdictionary. You have to pull it out and then manipulate and pull data from that distinct array. The other quirk with python is there is not a good way to remap or constrain values so you have to do the calculations yourself. As I was going through calibrating things I found that the joystick values actually ranged 26-226 and had to adjust the formulas accordingly. nstickx = int(((nstick[0]-26)/200)*180) nsticky = int(((nstick[1]-26)/200)*180) naccx = int(((nacc[0]-70)/110)*180) naccy = int(((nacc[1]-70)/110)*180) naccz = int(((nacc[2]-70)/110)*180) the base formula for remapping is: new value = ((old value - old min)/ old max - old min) * (new max - new min) + new min Now all these calculations create a nice long decimal value but we need clean integers. No problem we use the int() function built into python. It drops the decimals for us and gives a nice clean number. Now that all of that is set it is an extremely straight forward matter to just plug in the readjusted values into the servo angular equestions like this: kit.servo[0].angle= nstickx The key to remember is to have a read of your active data stream so if it bombs out because something goes out of range you can re adjust things. You do that by doing this: print(wii.state) print('wb nb bat joyxy, accxyz') print(buttons, nbut, battery, nstickx, nsticky, naccx, naccy, naccz) This gives you the raw data, a key and the reformatted data. I am still formatting the python script but will have that available once I am happy with things. And I will try to copiously note the script so anyone could do whatever they want by tweaking the setup for themselves. But let me conclude with saying this is rather exciting as I got multiple pieces all working together for a nice working code piece and have things more or less fully documented. Adafruit servo board information and setup: https://learn.adafruit.com/16-channel-p ... cuitpython https://circuitpython.readthedocs.io/pr ... ervo.Servo https://circuitpython.readthedocs.io/pr ... t/api.html |
Author: | knoxvilles_joker [ Sun Aug 23, 2020 11:09 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
Draft one of script: 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 # ----------------------- # Import required Python libraries # ----------------------- import cwiid import time #import i2c import os #from board import SCL, SDA import board from board import SCL, SDA import busio #import adafruit_pca9685 from adafruit_pca9685 import PCA9685 i2c_bus = busio.I2C(SCL, SDA) pca = PCA9685(i2c_bus) pca.frequency = 50 #from adafruit_motor import servo #pca = PCA9685 # standard servo declearations for controls from adafruit_servokit import ServoKit #pca.frequency = 50 kit = ServoKit(channels=16) # class adafruit_moter.servo.Servo(pwm.out, *, actuation_range=180, minPpulse=750, max_pluse=2250) #import adafruit_moster.servo kit.servo[0].angle=170 time.sleep(0.1) kit.servo[0].angle=0 #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 btn1cnt = 0 btn2cnt = 0 btnupcnt = 0 btnleftcnt = 0 btndowncnt = 0 btnrightcnt = 0 btnacnt = 0 btnbcnt = 0 btnccnt = 0 btnzcnt = 0 btnhomecnt = 0 # 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 file1 = "/boot/minigun.wav" file2 = "/boot/gameover.wav" fileleft = "/boot/predator.mp3" filedown = "/boot/alien.wav" # canon and laser sounds #filec = #filez = #fileb = print ('Press 1 + 2 on your Wii Remote now ...') time.sleep(1) # Connect to the Wii Remote. If it times out # then quit. 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) battery = wii.state['battery'] buttons = wii.state['buttons'] wacc= wii.state['acc'] nunbut = wii.state['nunchuk'] nbut =nunbut['buttons'] nacc =nunbut['acc'] nstick= nunbut['stick'] nstickx= int(((nstick[0]-26)/200)*180) nsticky= int(((nstick[1]-26)/200)*180) naccx = int(((nacc[0]-70)/110)*180) naccy = int(((nacc[1]-70)/110)*180) naccz = int(((nacc[2]-70)/110)*180) # 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 # waccx = int((( # waccy = int((( # waccz = int((( print(wii.state) print('wb nb bat joyxy, accxyz') print(buttons, nbut, battery, nstickx, nsticky, naccx, naccy, naccz) time.sleep(0.1) kit.servo[1].angle = nstickx kit.servo[2].angle = nsticky # If Plus and Minus buttons pressed # together then rumble and quit. if (buttons - cwiid.BTN_PLUS - cwiid.BTN_MINUS == 0): print ('\nClosing connection ...') wii.rumble = 1 time.sleep(1) wii.rumble = 0 exit(wii) if (battery <= 79): print ('please change battery now') wii.rumble = 1 time.sleep(1) wii.rumble = 0 # Check if other buttons are pressed by # doing a bitwise AND of the buttons number # and the predefined constant for that button. if (buttons & cwiid.BTN_LEFT): print ('Left pressed') btnleftcnt = btnleftcnt +1 print (btnleftcnt, "presses so far") time.sleep(button_delay) if (btnleftcnt == 3): #os.system("aplay " + pred) 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 == 3): #os.system("aplay " + kill) 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 == 3): #os.system("aplay " + drum) 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 == 3): #os.system("aplay " + alien) btndowncnt = 0 time.sleep(button_delay) 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 ('btn cnt reached playing minigun snd'); #os.system("aplay " + 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 == 3): print ('btn2cnt reached playing gameover') #os.system("aplay " + file2) btn2cnt = 0; time.sleep(button_delay) 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 == 3): pca.channels[15].duty_cycle=0xffff time.sleep(button_delay) if (btnacnt == 5): pca.channels[15].duty_cycle=0x0000 btnacnt = 0 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'); #os.system("aplay " + fileb) btnbcnt = 0; 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 == 2): kit.servo[5].angle = 90 time.sleep(button_delay); if (btnhomecnt == 4): kit.servo[5].angle = 0 btnhomecnt = 0 time.sleep(4) if (buttons & cwiid.BTN_MINUS): print ('Minus Button pressed') time.sleep(button_delay) if (buttons & cwiid.BTN_PLUS): print ('Plus Button pressed') time.sleep(button_delay) 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): print ('fire left cannon, lights') pca.channels[14].duty_cycle=0xffff #os.system("aplay " + fire1) time.sleep(1) 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): print ('fire right cannon, lights') pca.channels[13].duty_cycle=0xffff #os.system("aplay " + fire1) btnzcnt = 0 time.sleep(button_delay) if (nbut - cwiid.NUNCHUK_BTN_Z - cwiid.NUNCHUK_BTN_C == 0): print ('nunchuk c plus z pressed') time.sleep(button_delay) |
Author: | knoxvilles_joker [ Sat Aug 29, 2020 3:17 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
I have dialed in the code. Parts orders are pending. It still burns me that some parts I can ONLY get out of china. Updated Code: 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 # ----------------------- # Import required Python libraries # ----------------------- import cwiid import time #import i2c import os #from board import SCL, SDA import board from board import SCL, SDA import busio #import adafruit_pca9685 from adafruit_pca9685 import PCA9685 i2c_bus = busio.I2C(SCL, SDA) pca = PCA9685(i2c_bus) pca.frequency = 50 #from adafruit_motor import servo #pca = PCA9685 # standard servo declearations for controls from adafruit_servokit import ServoKit #pca.frequency = 50 kit = ServoKit(channels=16) # class adafruit_moter.servo.Servo(pwm.out, *, actuation_range=180, minPpulse=750, max_pluse=2250) #import adafruit_moster.servo time.sleep(0.1) kit.servo[0].angle=25 kit.servo[1].angle=0 kit.servo[2].angle=0 kit.servo[3].angle=0 kit.servo[4].angle=0 kit.servo[5].angle=0 kit.servo[6].angle=0 kit.servo[7].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 # 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 file1 = "/boot/minigun.wav" file2 = "/boot/gameover.wav" fileleft = "/boot/predator.mp3" filedown = "/boot/alien.wav" # canon and laser sounds #filec = #filez = #fileb = print ('Press 1 + 2 on your Wii Remote now ...') time.sleep(1) # Connect to the Wii Remote. If it times out # then quit. 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) 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)/230)*180) naccy = int(((nacc[1]-20)/230)*180) naccz = int(((nacc[2]-20)/230)*180) time.sleep(button_delay) # 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 # waccx = int((( # waccy = int((( # waccz = int((( print(wii.state) print('wb nb bat joyxy, accxyz') print(buttons, nbut, battery, nstickx, nsticky, naccx, naccy, naccz) 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. kit.servo[3].angle = nstickx # time.sleep(button_delay) kit.servo[1].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 # the best way to acheive this is with a 180 -x = z factor. You will need to adjust this if gearing is different. kit.servo[2].angle = (180 - nsticky) kit.servo[4].angle = naccx # time.sleep(button_delay) kit.servo[6].angle = naccz time.sleep(button_delay) kit.servo[5].angle = (180 - naccz) # 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) wii.rumble = 0 exit(wii) if (battery <= 79): print ('please change battery now') wii.rumble = 1 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 == 3): #os.system("aplay " + pred) 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 == 3): #os.system("aplay " + kill) 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 == 3): #os.system("aplay " + drum) 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 == 3): #os.system("aplay " + alien) btndowncnt = 0 time.sleep(button_delay) 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 ('btn cnt reached playing minigun snd'); #os.system("aplay " + 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 == 3): print ('btn2cnt reached playing gameover') #os.system("aplay " + file2) btn2cnt = 0; time.sleep(button_delay) 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 == 3): pca.channels[15].duty_cycle=0xffff time.sleep(button_delay) if (btnacnt == 5): pca.channels[15].duty_cycle=0x0000 btnacnt = 0 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'); #os.system("aplay " + fileb) btnbcnt = 0; 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 == 2): kit.servo[0].angle = 150 time.sleep(button_delay); if (btnhomecnt == 4): kit.servo[0].angle = 30 btnhomecnt = 0 time.sleep(4) if (buttons & cwiid.BTN_MINUS): print ('Minus Button pressed') btnminuscnt = btnminuscnt +1; print(btn-cnt, "presses so far"); time.sleep(button_delay); if (btnminuscnt == 2): print ("resetting count"); btnminuscnt = 0 time.sleep(button_delay); if (buttons & cwiid.BTN_PLUS): print ('Plus Button pressed') time.sleep(button_delay) 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): print ('fire left cannon, lights') pca.channels[10].duty_cycle=0xffff #os.system("aplay " + fire1) time.sleep(1) 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): print ('fire right cannon, lights') pca.channels[13].duty_cycle=0xffff #os.system("aplay " + fire1) btnzcnt = 0 time.sleep(button_delay) if (nbut - cwiid.NUNCHUK_BTN_Z - cwiid.NUNCHUK_BTN_C == 0): print ('nunchuk c plus z pressed') time.sleep(button_delay) |
Author: | knoxvilles_joker [ Sat Aug 29, 2020 3:21 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
The code is super responsive. I am getting zero issues with things. I had to add a slight 200ms delay to allow for split servo movement. The armature servo I set as a self leveler by subtracting x axis reading from 180 and used that as the armature servo angle. I had to space out some of the movement to allow for things to catch up. |
Author: | knoxvilles_joker [ Sat Aug 29, 2020 11:07 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
40mm*40mm*20mm standard servo size 65mm * 47mm * 30mm large size servo There are nano, sub-micro, micro, slim-wing, mini, lowprofile, giant form factors as well. Standard servos typically have 25 or 26 tooth heads. torque = radius * Force * sine angle 1 ft-lb = 1.356Nm 1 ft-lb = 13.8254954376 kg-cm 1 ft-lb = 191.99999948048 oz-in 1 ft-lb = 12 in-lb 35kg-cm = 2.531554847923463 ft-lbs 60kg-cm = 4.339808310725937 ft-lbs 3304 oz-in = 17.20833337989622 ft-lbs Basically the weight is going to be somewhere in the ballpark of 460oz in o a 2kg load on the 226cm length of the armature. but the torque calculation is basically weight times length. https://www.robotshop.com/community/tut ... calculator https://www.societyofrobots.com/mechani ... mics.shtml So weight matters a lot. Plus you must factor in inertia with movement. Now the calculation for gravity at earth's surface is 9.8 m/s^2. Now an average gait is 1.4 meters per second and most are capable of 2.5 meters per second. So lets do some rounding say the gait is 2m/s and the gravity is constant. So if we account for worst case falls and stops you are looking at a multiplier of about 3 for your finished torque calculations for a worse case scenario. But that is so much extra we could probably swing just multiplying the torque calculation on your arm setup by a factor of 4. So 460oz-in need times 4 is 1840. Times 3 it is 1380 and times 2 920. Weight, structure, and servo costs are your main factors here. If you under value things and have a 20% chance of maybe causing an issue it might be worth it but that is a personal decision. Replacing a 40 dollar part every few months is much more budget friendly than buying a 200 dollar part and losing it or having it fail and you have no spares. So you got your torque calculations, now what? Now you need to protect the servo horns and hubs from being damaged. This is done either through a gearbox assembly or a servo block. You take the torque and have it rely on the framework of the assembly instead of the servo itself for core strength so all the servo does is movement. Done properly you are not going to have too much frictional drag and even then it is not enough to really be concerned with as that only comes into play in larger higher torque setups like vehicles and large robots. Bigger shops like Studio ADI and Stan Winston Studios machine their own custom parts. Many individuals either sculpt then cast their pieces or 3d print them. Additive printing techniques for metals is still too expensive to be doable for home every day use so the other option is to go to sites like servocity.com and just buy kits or parts and pieces to build your idea. Just do not expect to buy one set of parts and do not go in expecting to buy all the right parts the first time around. |
Author: | knoxvilles_joker [ Sun Sep 06, 2020 4:55 am ] |
Post subject: | |
I finally got the left canon assembly armature assembled and mounted on the test rig ahead of transplant to the actual backpack. I will have to build another pack from scratch and allow space for a channel of a linear actuator that I will have to integrate with the pi and allow control via a roboclaw control board. There are no really good 12v/5v control setups that are cheap that would play nicely with the pi. At this point I will need to finish the current build and see where else I am off on things. I am struggling to find or lay hands on reference photos and videos so accuracy will suffer as a result. 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 i2c import os #from board import SCL, SDA import board from board import SCL, SDA import busio #import adafruit_pca9685 from adafruit_pca9685 import PCA9685 i2c_bus = busio.I2C(SCL, SDA) pca = PCA9685(i2c_bus) pca.frequency = 50 #from adafruit_motor import servo #pca = PCA9685 # standard servo declearations for controls from adafruit_servokit import ServoKit #pca.frequency = 50 kit = ServoKit(channels=16) # class adafruit_moter.servo.Servo(pwm.out, *, actuation_range=180, minPpulse=750, max_pluse=2250) #import adafruit_moster.servo # 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=20 kit.servo[2].angle=180 # 0-2 are basically place holders for armature. kit.servo[3].angle=180 kit.servo[4].angle=0 kit.servo[5].angle=0 kit.servo[6].angle=0 kit.servo[7].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 # 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 file1 = "/boot/minigun.wav" file2 = "/boot/gameover.wav" fileleft = "/boot/predator.mp3" filedown = "/boot/alien.wav" # canon and laser sounds #filec = #filez = #fileb = print ('Press 1 + 2 on your Wii Remote now ...') time.sleep(1) # Connect to the Wii Remote. If it times out # then quit. 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) 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)/230)*180) naccy = int(((nacc[1]-20)/230)*180) naccz = int(((nacc[2]-20)/230)*180) time.sleep(button_delay) # 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 # waccx = int((( # waccy = int((( # waccz = int((( print(wii.state) print('wb nb bat joyxy, accxyz') print(buttons, nbut, battery, nstickx, nsticky, naccx, naccy, naccz) 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. kit.servo[2].angle = nstickx # time.sleep(button_delay) 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 # the best way to acheive this is with a 180 -x = z factor. You will need to adjust this if gearing is different. # kit.servo[2].angle = (nsticky/2) # angular calculations were proving problematic, switching to if else statement # if (0 < nsticky < 30): # kit.servo[2].angle = 0 # if (31 < nsticky <70): # kit.servo[2].angle = 45 # if (55 < nsticky < 65): # kit.servo[2].angle = 45 # if ( 66 < nsticky < 90): # kit.servo[2].angle = 90 # if (91 < nsticky < 130): # kit.servo[2].angle = 180 # if (nsticky > 131): # 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 # time.sleep(button_delay) kit.servo[6].angle = naccz time.sleep(button_delay) 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 = 20 time.sleep(2) kit.servo[2].angle = 180 kit.servo[3].angle = 180 kit.servo[4].angle = 0 kit.servo[5].angle = 0 kit.servo[6].angle = 0 kit.servo[7].angle = 0 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. if (battery <= 79): print ('please change battery now') wii.rumble = 1 kit.servo[0].angle = 160 time.sleep(3) kit.servo[1].angle = 20 kit.servo[2].angle = 180 kit.servo[3].angle = 180 kit.servo[4].angle = 0 kit.servo[5].angle = 0 kit.servo[6].angle = 0 kit.servo[7].angle = 0 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 == 3): #os.system("aplay " + pred) 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 == 3): #os.system("aplay " + kill) 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 == 3): #os.system("aplay " + drum) 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 == 3): #os.system("aplay " + alien) btndowncnt = 0 time.sleep(button_delay) 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 ('btn cnt reached playing minigun snd'); #os.system("aplay " + 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 == 3): print ('btn2cnt reached playing gameover') #os.system("aplay " + file2) btn2cnt = 0; time.sleep(button_delay) 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 == 3): pca.channels[15].duty_cycle=0xffff time.sleep(button_delay) if (btnacnt == 5): pca.channels[15].duty_cycle=0x0000 btnacnt = 0 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'); #os.system("aplay " + fileb) btnbcnt = 0; 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 == 2): # 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(3) kit.servo[1].angle = 20 # time.sleep(2) kit.servo[2].angle = 180 # kit.servo[3].angle = 180 # kit.servo[4].angle = 0 time.sleep(button_delay); if (btnhomecnt == 4): kit.servo[0].angle = 10 kit.servo[1].angle = 95 # time.sleep(4) #this is the operating position. Other arms will get added as I get the build out further along. btnhomecnt = 0 time.sleep(4) if (buttons & cwiid.BTN_MINUS): print ('Minus Button pressed') btnminuscnt = btnminuscnt +1; print(btn-cnt, "presses so far"); time.sleep(button_delay); if (btnminuscnt == 2): print ("resetting count"); btnminuscnt = 0 time.sleep(button_delay); if (buttons & cwiid.BTN_PLUS): print ('Plus Button pressed') time.sleep(button_delay) 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): print ('fire left cannon, lights') pca.channels[10].duty_cycle=0xffff #os.system("aplay " + fire1) time.sleep(1) 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): print ('fire right cannon, lights') pca.channels[13].duty_cycle=0xffff #os.system("aplay " + fire1) btnzcnt = 0 time.sleep(button_delay) if (nbut - cwiid.NUNCHUK_BTN_Z - cwiid.NUNCHUK_BTN_C == 0): print ('nunchuk c plus z pressed') time.sleep(button_delay) |
Author: | knoxvilles_joker [ Mon Sep 07, 2020 11:38 pm ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
quick video upload that I did: https://www.youtube.com/watch?v=vHM2tdNe_mE |
Author: | SulacoBoy [ Sat Sep 12, 2020 7:44 pm ] |
Post subject: | |
Pretty neat stuff! |
Author: | knoxvilles_joker [ Sat Sep 12, 2020 8:47 pm ] |
Post subject: | Re: |
Bacta Baby wrote: Pretty neat stuff! You are more than welcome to do it yourself. Contact me if there are questions or issues doing so. I specifically made the whole setup very modular and portable. It can literally do whatever you want it to. |
Author: | knoxvilles_joker [ Sun Sep 13, 2020 5:54 am ] |
Post subject: | |
OK, I did a few code hacks and I have sounds playing in the background. The concurrent limit appears to be about 4 sounds playing at once. This was accomplished by: import subprocess subprocess.Popen(['aplay', '-q', file1]) or subprocess.Popen(['mpg123', '-q', file2]) Aplay plays wav files. mpg123 plays mp3 files. I also integrated an RC on/off light module: https://www.amazon.com/Controlled-Recei ... WXBMY2HT0C It allowed me to power on the 5v LED array I had without issues but I had to switch from LED lighting controls using duty cycle to doing it via angle control for a clean set as the control range is off is below 1200 and on is above 1800 but cut off is over 2200. So I did: kit.servo[15].angle = 180 for on and kit.servo[15].angle = 40 for off. The elechawk unit appears to be a china made unit as I am not finding a factory but I am finding it all over wish, banggood, aliexpress. I am not finding a domestic equivalent outside of finding write ups on how to do the same with a servo guts hack. I am finding that a lot of the RC parts and such are ONLY made in China. This will change over time I suspect. |
Author: | knoxvilles_joker [ Sat Sep 26, 2020 6:52 am ] |
Post subject: | |
OK, I added a gyroscope that I finally got in. https://learn.adafruit.com/nxp-precisio ... cuitpython import adafruit_fxas21002c i2c= busio.I2C(board.SCL, board.SDA sensor1 = adafruit_fxas21002c.FXAS21002C(i2c) kit.servo[5].angle=90 while True: gyro_x, gyro_y, gyro_z = sensor1.gyroscope print(int(gyro_x)) print(int(gyro_z)) servox=(((int(gyro_x--256)/(256--256))*180)) print(servox) kit.servo[14].angle = servox servox=(((int(gyro_z--256)/(256--256))*180)) print(servoz) kit.servo[5].angle = servoz The above lines were added to the script and seem to provide decent head tracking. Remapping the values took a big of figuring as the range was -256 to +256. It was not clear in the manual documents for the chips, but that appears to be the actual range for the the gyroscope, and magnetometer readings. The accelerometer is a 16 bit value so I am thinking the value range on that is a bit higher, but acc values were outside of my scope of things and focus You can not map values or do servo movements within an if statement. Something to do with the values not being able to be seen outside of the conditional statement. I did try as that would have been so much easier. That this board is working and the nunchucky was not tells me that there is some sort of pullup voltage drop with the communications. Adafruit came out with an i2c booster board late last year so I am going to try it and see if that helps things. Adafruit also added their own version of the mpu-6050 with qwiic connectors and with a qwiic bonnet board things might be much more doable. The qwiic connection standard appears to be a new standard for the circuit python boards that requires no soldering. This makes prototyping infinitely safer with no soldering for our younger generations. I wonder if adafruit fixed the capacitor issues with the mpu-6050. They seem to have their own mpu-6050 library so it looks like they took ownership of the library and its related maintenance issues. Circuit python seems to be taking over so python seems to be coming back into dominance again until something replaces it temporarily. The bosch bno055 I would go with as it is a cleaner setup and a better board even with a steeper price, but the qwiic board is cheaper on that one as well. The 6050 is very tempting as it is only 7 bucks. Once the hat comes in I may do some more research on options with qwiic connections, though all the options for it are for sensors and a few display options, some which may work on a predator bomb gauntlet digit display. |
Author: | knoxvilles_joker [ Sat Sep 26, 2020 8:56 am ] |
Post subject: | Re: Wiimote with nunchuk on linux via bluetooth |
Updated code: 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 #from adafruit_motor import servo #pca = PCA9685 # standard servo declearations for controls from adafruit_servokit import ServoKit #pca.frequency = 50 kit = ServoKit(channels=16) # class adafruit_moter.servo.Servo(pwm.out, *, actuation_range=180, minPpulse=750, max_pluse=2250) #import adafruit_moster.servo # 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=0 kit.servo[6].angle=0 kit.servo[7].angle=0 kit.servo[13].angle=0 kit.servo[14].angle=90 # 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 # 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" 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) # 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) 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=nstickx # 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 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 = 0 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 = 0 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 == 3): subprocess.Popen(['mpg123', '-q', pred]) print (btnleftcnt, "playing pred1") 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): subprocess.Popen(['mpg123', '-q', jumprope]) btnrightcnt = btnrightcnt +1 print (btnrightcnt, "playing jumprope") time.sleep(button_delay) if (btnrightcnt == 8): subprocess.Popen(['mpg123', '-q', afam]) btnrightcnt = btnrightcnt +1 print (btnrightcnt, "playing addamsfamily") time.sleep(button_delay) if (btnrightcnt == 11): 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): subprocess.Popen(['mpg123', '-q', alienc]) btnupcnt = btnupcnt +1 print (btnupcnt, "playing alienc") time.sleep(button_delay) if (btnupcnt == 8): btnupcnt = btnupcnt +1 subprocess.Popen(['mpg123', '-q', combat]) print (btnupcnt, "playing combat") time.sleep(button_delay) if (btnupcnt == 11): btnupcnt = btnupcnt +1 subprocess.Popen(['mpg123', '-q', liftoff]) time.sleep(button_delay) print (btnupcnt, "playing liftoff") if (btnupcnt == 14): btnupcnt = btnupcnt +1 subprocess.Popen(['mpg123', '-q', lv426]) time.sleep(button_delay) print (btnupcnt, "playing lv426") if (btnupcnt == 17): 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 subprocess.Popen(['mpg123', '-q', army]) time.sleep(button_delay) print (btndowncnt, "playing army") if (btndowncnt == 8): subprocess.Popen(['mpg123', '-q', navy]) time.sleep(button_delay) btndowncnt = btndowncnt +1 print (btndowncnt, "playing navy") if (btndowncnt == 11): btndowncnt = btndowncnt +1 subprocess.Popen(['mpg123', '-q', usmc]) time.sleep(button_delay) print (btndowncnt, "playing usmc") if (btndowncnt == 14): 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 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 == 3): print (btn2cnt, "reached playing gameover") subprocess.Popen(['aplay', '-q', file2]) btn2cnt = 0; time.sleep(button_delay) 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 = 180 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 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[15].angle = 180 subprocess.Popen(['mplayer', cannon]) time.sleep(.1) kit.servo[15].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 # 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): subprocess.Popen(['mpg123', '-q', rammstein]) btnminuscnt = btnminuscnt +1 print (btnminuscnt, "playing rammstein") time.sleep(button_delay) if (btnminuscnt == 5): time.sleep(button_delay) subprocess.Popen(['mpg123', '-q', lithiumflower]) btnminuscnt = btnminuscnt +1 print (btnminuscnt, "playing lithiumflower") if (btnminuscnt == 8): subprocess.Popen(['mpg123', '-q', thriller]) btnminuscnt = btnminuscnt +1 print (btnminuscnt, "playing thriller") if (btnminuscnt == 11): print ("resetting count"); btnminuscnt = 0 time.sleep(button_delay); if (buttons & cwiid.BTN_PLUS): print ('Plus Button pressed') time.sleep(button_delay) 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): btnccnt = btnccnt +1 print (btnccnt, "playing gb") subprocess.Popen(['mpg123', '-q', gb]) if (btnccnt == 5): btnccnt = btnccnt +1 print (btnccnt, "playing halloween") subprocess.Popen(['mpg123', '-q', halloween]) if (btnccnt == 8): btnccnt = btnccnt +1 print (btnccnt, "playing jh") subprocess.Popen(['mpg123', '-q', jh]) if (btnccnt == 11): time.sleep(button_delay) if (btnccnt == 14): print ('fire left cannon, lights') kit.servo[10].angle = 110 subprocess.Popen(['mplayer', cannon]) time.sleep(1) kit.servo[10].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): btnzcnt = btnzcnt +1 print (btnzcnt, "playing b2") subprocess.Popen(['mpg123', '-q', b2]) if (btnzcnt == 5): btnzcnt = btnzcnt +1 print (btnzcnt, "playing b3") subprocess.Popen(['mpg123', '-q', b3]) if (btnzcnt == 8): btnzcnt = btnzcnt +1 print (btnzcnt, "playing everyrule") subprocess.Popen(['mpg123', '-q', everyrule]) if (btnzcnt == 11): print ('fire right cannon, lights') kit.servo[13].angle = 110 subprocess.Popen(['mplayer', cannon]) btnzcnt = 0 time.sleep(button_delay) time.sleep(1) kit.servo[13].angle = 40 if (nbut - cwiid.NUNCHUK_BTN_Z - cwiid.NUNCHUK_BTN_C == 0): print ('nunchuk c plus z pressed') time.sleep(button_delay) |
Page 1 of 3 | All times are UTC [ DST ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |