Harvey71 / emdr

Firmware and controller app for DIY EMDR equipment (lightbar, buzzers and headphones)
MIT License
26 stars 9 forks source link

Issue with Lightbar connecting to Controller #3

Closed Nigel214 closed 1 year ago

Nigel214 commented 2 years ago

Howdy,

I've created the lightbar and have tested that it works by running some of the WS2812 examples in Arduino Sketch.

First question has to do with the lightbar.ino code. Should the first line in the file do anything? I was getting an error so I remarked it out. This line: @@ -0,0 +1, 55 @@

I've made sure the NUMLED is correct and the Port is correct (24). I compile the lightbar software and upload to the Teensy LC and everything looks good, but when I run the controller software it is not seeing the lightbar USB. My Teensy LC is running as Serial USB on Com8, and I am running the controller in Windows 10. I've made sure I have the correct versions of PYUSB, PYGAME, and Thorpy.

Any help would be greatly appreciated!

Awesome project!

Harvey71 commented 2 years ago

Please ignore the @@ line - I do not know where it comes from and I will delete it in the next release.

Regarding USB: Have you installed libusb as well? For Windows you can download a DLL here: https://github.com/libusb/libusb/releases/download/v1.0.26/libusb-1.0.26-binaries.7z.

When connecting the lightbar, do you hear the Windows "connect sound" and does a "USB Serial" device appear in the Windows Device Manager under "USB Devices"?

Can you run this simple python script and post the output?

import usb
for dev in usb.core.find(find_all=True):
    print(dev)
ooktown commented 1 year ago

Greetings! I'm having a similar problem.

I have a Raspberry Pi 4B with 4GB, and I'm using a Teensy 3.2 to control the Lightbar. I have separately debugged the Teensy 3.2 to work with the LED strip (I installed some test programs to verify that I could control all 60 LEDs), and also verified that the Teensy responded properly on the serial monitor with "EMDR Lightbar" and passed the test() to light up two LEDs. (Side note: I used the level shifters you recommended, and I was able to drive all 60 LEDs simultaneously using an external power supply.)

I've also gotten the interface running and can hear the ping-pong sound when I use the audio option.

However, the lightbar is not recognized, and I can't use the visual bi-lateral stimulation. Before I try making the buzzer, I want to debug the lightbar.

Here is the output when I ran the python script in your last comment:

DEVICE ID 1d6b:0003 on Bus 002 Address 001 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x300 USB 3.0
 bDeviceClass           :    0x9 Hub
 bDeviceSubClass        :    0x0
 bDeviceProtocol        :    0x3
 bMaxPacketSize0        :    0x9 (9 bytes)
 idVendor               : 0x1d6b
 idProduct              : 0x0003
 bcdDevice              :  0x601 Device 6.01
 iManufacturer          :    0x3 Error Accessing String
 iProduct               :    0x2 Error Accessing String
 iSerialNumber          :    0x1 Error Accessing String
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 0 mA ====================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x1f (31 bytes)
   bNumInterfaces       :    0x1
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0 
   bmAttributes         :   0xe0 Self Powered, Remote Wakeup
   bMaxPower            :    0x0 (0 mA)
    INTERFACE 0: Hub =======================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x1
     bInterfaceClass    :    0x9 Hub
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
      ENDPOINT 0x81: Interrupt IN ==========================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x81 IN
       bmAttributes     :    0x3 Interrupt
       wMaxPacketSize   :    0x4 (4 bytes)
       bInterval        :    0xc
DEVICE ID 16c0:0483 on Bus 001 Address 003 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x110 USB 1.1
 bDeviceClass           :    0x2 Communications Device
 bDeviceSubClass        :    0x0
 bDeviceProtocol        :    0x0
 bMaxPacketSize0        :   0x40 (64 bytes)
 idVendor               : 0x16c0
 idProduct              : 0x0483
 bcdDevice              :  0x275 Device 2.75
 iManufacturer          :    0x1 Error Accessing String
 iProduct               :    0x2 Error Accessing String
 iSerialNumber          :    0x3 Error Accessing String
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 100 mA ==================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x43 (67 bytes)
   bNumInterfaces       :    0x2
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0 
   bmAttributes         :   0xc0 Self Powered
   bMaxPower            :   0x32 (100 mA)
    INTERFACE 0: CDC Communication =========================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x1
     bInterfaceClass    :    0x2 CDC Communication
     bInterfaceSubClass :    0x2
     bInterfaceProtocol :    0x1
     iInterface         :    0x0 
      ENDPOINT 0x82: Interrupt IN ==========================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x82 IN
       bmAttributes     :    0x3 Interrupt
       wMaxPacketSize   :   0x10 (16 bytes)
       bInterval        :   0x40
    INTERFACE 1: CDC Data ==================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x1
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x2
     bInterfaceClass    :    0xa CDC Data
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
      ENDPOINT 0x3: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x3 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
      ENDPOINT 0x84: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x84 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
DEVICE ID 2109:3431 on Bus 001 Address 002 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x210 USB 2.1
 bDeviceClass           :    0x9 Hub
 bDeviceSubClass        :    0x0
 bDeviceProtocol        :    0x1
 bMaxPacketSize0        :   0x40 (64 bytes)
 idVendor               : 0x2109
 idProduct              : 0x3431
 bcdDevice              :  0x421 Device 4.21
 iManufacturer          :    0x0 
 iProduct               :    0x1 Error Accessing String
 iSerialNumber          :    0x0 
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 100 mA ==================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x19 (25 bytes)
   bNumInterfaces       :    0x1
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0 
   bmAttributes         :   0xe0 Self Powered, Remote Wakeup
   bMaxPower            :   0x32 (100 mA)
    INTERFACE 0: Hub =======================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x1
     bInterfaceClass    :    0x9 Hub
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
      ENDPOINT 0x81: Interrupt IN ==========================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x81 IN
       bmAttributes     :    0x3 Interrupt
       wMaxPacketSize   :    0x1 (1 bytes)
       bInterval        :    0xc
DEVICE ID 1d6b:0002 on Bus 001 Address 001 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x200 USB 2.0
 bDeviceClass           :    0x9 Hub
 bDeviceSubClass        :    0x0
 bDeviceProtocol        :    0x1
 bMaxPacketSize0        :   0x40 (64 bytes)
 idVendor               : 0x1d6b
 idProduct              : 0x0002
 bcdDevice              :  0x601 Device 6.01
 iManufacturer          :    0x3 Error Accessing String
 iProduct               :    0x2 Error Accessing String
 iSerialNumber          :    0x1 Error Accessing String
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 0 mA ====================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x19 (25 bytes)
   bNumInterfaces       :    0x1
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0 
   bmAttributes         :   0xe0 Self Powered, Remote Wakeup
   bMaxPower            :    0x0 (0 mA)
    INTERFACE 0: Hub =======================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x1
     bInterfaceClass    :    0x9 Hub
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
      ENDPOINT 0x81: Interrupt IN ==========================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x81 IN
       bmAttributes     :    0x3 Interrupt
       wMaxPacketSize   :    0x4 (4 bytes)
       bInterval        :    0xc

Sorry for all that output! I wasn't sure what was relevant.

I'm thinking I might need to update the VendorID and/or the device hex code. Any help would be appreciated! I think I am REALLY CLOSE to getting this to work! I would appreciate any help you can send my way.

ooktown commented 1 year ago

More output that might be helpful:

pi@emdr-controller:~ $ sudo python3 devices.py 
pygame 2.0.3 (SDL 2.0.14, Python 3.9.2)
Hello from the pygame community. https://www.pygame.org/contribute.html
error: XDG_RUNTIME_DIR not set in the environment.
The path /dev/dri/ cannot be opened or is not available
The path /dev/dri/ cannot be opened or is not available

pi@emdr-controller:~ $ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 16c0:0483 Van Ooijen Technische Informatica Teensyduino Serial
Bus 001 Device 002: ID 2109:3431 VIA Labs, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Harvey71 commented 1 year ago

Hey, ooktown.

Vendor Id (0x16c0) looks good to me. I have some questions for you:

ooktown commented 1 year ago

Greetings! Thanks for the quick response. To answer your question(s):

Harvey71 commented 1 year ago

Okay, so the lightbar seems to work properly. Then it must be an issue with the controller. Could you please run this simple Python script an give me the outputs?

import usb
devs = usb.core.find(find_all=True, idVendor=0x16c0)
dev=next(devs)
print(dev)
dev.write(0x03, 'i\n')
id_arr = dev.read(0x84, size_or_buffer=64, timeout=100)
id_str = ''.join(chr(x) for x in id_arr).strip()
print(id_str)
dev.finalize()

If this works fine and prints out "EMDR Lightbar", then please delete line 50-52 from devices.py and try the controller again.

ooktown commented 1 year ago

Ok! It looks like there are errors when I run they Python script. Here are the results:

pi@emdr-controller:~ $ sudo python3
Python 3.9.2 (default, Mar 12 2021, 04:06:34) 
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import usb
>>> devs = usb.core.find(find_all=True, idVendor=0x16c0)
>>> dev=next(devs)
>>> print(dev)
DEVICE ID 16c0:0483 on Bus 001 Address 003 =================
 bLength                :   0x12 (18 bytes)
 bDescriptorType        :    0x1 Device
 bcdUSB                 :  0x110 USB 1.1
 bDeviceClass           :    0x2 Communications Device
 bDeviceSubClass        :    0x0
 bDeviceProtocol        :    0x0
 bMaxPacketSize0        :   0x40 (64 bytes)
 idVendor               : 0x16c0
 idProduct              : 0x0483
 bcdDevice              :  0x275 Device 2.75
 iManufacturer          :    0x1 Teensyduino
 iProduct               :    0x2 USB Serial
 iSerialNumber          :    0x3 5713550
 bNumConfigurations     :    0x1
  CONFIGURATION 1: 100 mA ==================================
   bLength              :    0x9 (9 bytes)
   bDescriptorType      :    0x2 Configuration
   wTotalLength         :   0x43 (67 bytes)
   bNumInterfaces       :    0x2
   bConfigurationValue  :    0x1
   iConfiguration       :    0x0 
   bmAttributes         :   0xc0 Self Powered
   bMaxPower            :   0x32 (100 mA)
    INTERFACE 0: CDC Communication =========================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x0
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x1
     bInterfaceClass    :    0x2 CDC Communication
     bInterfaceSubClass :    0x2
     bInterfaceProtocol :    0x1
     iInterface         :    0x0 
      ENDPOINT 0x82: Interrupt IN ==========================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x82 IN
       bmAttributes     :    0x3 Interrupt
       wMaxPacketSize   :   0x10 (16 bytes)
       bInterval        :   0x40
    INTERFACE 1: CDC Data ==================================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x1
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x2
     bInterfaceClass    :    0xa CDC Data
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x0 
      ENDPOINT 0x3: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x3 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
      ENDPOINT 0x84: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x84 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :   0x40 (64 bytes)
       bInterval        :    0x0
>>> dev.write(0x03, 'i\n')
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/usb/_interop.py", line 92, in as_array
    return array.array('B', data)
TypeError: cannot use a str to initialize an array with typecode 'B'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/dist-packages/usb/core.py", line 947, in write
    _interop.as_array(data),
  File "/usr/local/lib/python3.9/dist-packages/usb/_interop.py", line 97, in as_array
    a.fromstring(data) # deprecated since 3.2
AttributeError: 'array.array' object has no attribute 'fromstring'
>>> id_arr = dev.read(0x84, size_or_buffer=64, timeout=100)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/dist-packages/usb/core.py", line 983, in read
    ret = fn(
  File "/usr/local/lib/python3.9/dist-packages/usb/backend/libusb1.py", line 828, in bulk_read
    return self.__read(self.lib.libusb_bulk_transfer,
  File "/usr/local/lib/python3.9/dist-packages/usb/backend/libusb1.py", line 936, in __read
    _check(retval)
  File "/usr/local/lib/python3.9/dist-packages/usb/backend/libusb1.py", line 595, in _check
    raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 110] Operation timed out
>>> id_str = ''.join(chr(x) for x in id_arr).strip()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'id_arr' is not defined
>>> print(id_str)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'id_str' is not defined
>>> dev.finalize()
>>> 
>>> 
Harvey71 commented 1 year ago

After some research: unfortunately, pyUSB 1.0.2 is incompatible with Python 3.9. Please either degrade Python to 3.8 or update pyUSB to latest version. You can do the latter by: pip install --upgrade pyusb. Also it would be a good idea to exchange the first line of the requirements.txt file with pyusb==1.2.1. If you give me positive feedback, I will commit this change to the repo, so that further users will not have the same troubles...

ooktown commented 1 year ago

Thank you SO MUCH for your help and diligent research! I will try this out later today or tomorrow and comment back either way on the results.

ooktown commented 1 year ago

Here's my update:

Based on the results, and the difficulty of managing multiple versions of Python ond PyUSB, my next step will be to:

Let me know what you think of my plan.

ooktown commented 1 year ago

I could not get Python 3.8 to run with the required modules (pyUSB, pygame, thorpy, pysdl2-dll) because the default dependency for many of these modules was to download the latest version of Python.

I attempted to work around this by downloading and installing pygame and thorpy, for example, but I wasn't able to get them to load in the Python script when running Python 3.8.

So, now I'm going to go back trying to learn Python and re-factor the code to use the latest version of pyUSB, pygame, thorpy, etc. Lots to learn!

Harvey71 commented 1 year ago

I strongly recommend that you stick with your 3.9 Python version and upgrade pyUSB. In the meantime, I have bumped my Python version to 3.9.16 on MacOS and the lightbar is reliably detected. I have committed some changes to the controller source - maybe that will help. If you still have this problem, could you please run the script I gave you 3 days ago again? If you have updated pyUSB you should get a different error now.

ooktown commented 1 year ago

I got the Lightbar working! AWESOME. Thank you so much for your help and updating the code/configuration files!

I had to slightly modify the PiBakery recipe, and I also ran these command manually. Here's the recipe I ended up using to make the Lightbar work on a Raspberry Pi 4 4GB:

until (curl https://github.com -o /dev/null); do sleep 1; done

sudo apt-get install libusb-1.0-0-dev
sudo apt install python3-sdl2
git clone https://github.com/Harvey71/emdr
cp emdr/controller/* ~ -r
sudo pip3 install -r requirements.txt
mkdir -p ~/.config/lxsession/LXDE-pi
echo sudo python3 main.py fullscreen touchscreen>~/.config/lxsession/LXDE-pi/autostart
sudo chmod 755 *.py
sudo rm -rf LCD-show
git clone https://github.com/goodtft/LCD-show.git
chmod -R 755 LCD-show
cd LCD-show&&sudo ./LCD35-show 180

And when the Pi rebooted, the Lightbar was recognized, and I could start the LED sequence.