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 ... cuitpythonhttps://circuitpython.readthedocs.io/pr ... ervo.Servohttps://circuitpython.readthedocs.io/pr ... t/api.html