Possibility to run pyjoulescope in 32 bit Python

Hello!
Our Joulescopes work great out of the box with GUI app and in 64-bit Python.
Question is - it is possible to make pyjoulescope work with 32 bit Python? What is ‘the blocking’ factor here? Cython implementation of some features? DLLs?
I am asking, because we were looking into integrating Joulescope into our Python test environment, and some of packages we are currently using work only with 32 bit Python (DLLs).

Even ‘hacks’ are most welcome :slight_smile:

Best regards,
Piotr

2 Likes

Hi Piotr (@reggy) and welcome to the forum! I presume that you are running on Windows, since Linux and macOS long ago made mixed 32/64 bit support difficult if not impossible. When you say 32-bit Python, what Windows are you running? Here is the matrix:

  1. 32-bit python on 32-bit windows ? may work, but completely unsupported
  2. 64-bit python on 32-bit windows :x:
  3. 32-bit python on 64-bit windows ? may work, but completely unsupported
  4. 64-bit python on 64-bit windows :grinning:

I did a quick test to see how bad (3) is. The pyjoulescope stuff is in good shape:

D:\repos\Jetperch\pyjoulescope>python -V -V
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 19:29:22) [MSC v.1916 32 bit (Intel)]

D:\repos\Jetperch\pyjoulescope>python setup.py build_ext --inplace
Compiling joulescope/stream_buffer.pyx because it changed.
Compiling joulescope/pattern_buffer.pyx because it changed.
[1/2] Cythonizing joulescope/pattern_buffer.pyx
[2/2] Cythonizing joulescope/stream_buffer.pyx
running build_ext
building 'joulescope.stream_buffer' extension
creating build
creating build\temp.win32-3.7
creating build\temp.win32-3.7\Release
creating build\temp.win32-3.7\Release\joulescope
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\bin\HostX86\x86\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -ID:\bin\Python37-32\lib\site-packages\numpy\core\include -ID:\bin\Python37-32\lib\site-packages\numpy\core\include -ID:\bin\Python37-32\include -ID:\bin\Python37-32\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\cppwinrt" /Tcjoulescope/stream_buffer.c /Fobuild\temp.win32-3.7\Release\joulescope/stream_buffer.obj
stream_buffer.c
d:\bin\python37-32\lib\site-packages\numpy\core\include\numpy\npy_1_7_deprecated_api.h(14) : Warning Msg: Using deprecated NumPy API, disable it with #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
joulescope/stream_buffer.c(5185): warning C4244: '=': conversion from 'uint64_t' to 'Py_ssize_t', possible loss of data
creating D:\repos\Jetperch\pyjoulescope\build\lib.win32-3.7
creating D:\repos\Jetperch\pyjoulescope\build\lib.win32-3.7\joulescope
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\bin\HostX86\x86\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:D:\bin\Python37-32\libs /LIBPATH:D:\bin\Python37-32\PCbuild\win32 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\ATLMFC\lib\x86" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\lib\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17134.0\ucrt\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17134.0\um\x86" /EXPORT:PyInit_stream_buffer build\temp.win32-3.7\Release\joulescope/stream_buffer.obj /OUT:build\lib.win32-3.7\joulescope\stream_buffer.cp37-win32.pyd /IMPLIB:build\temp.win32-3.7\Release\joulescope\stream_buffer.cp37-win32.lib
   Creating library build\temp.win32-3.7\Release\joulescope\stream_buffer.cp37-win32.lib and object build\temp.win32-3.7\Release\joulescope\stream_buffer.cp37-win32.exp
Generating code
Finished generating code
building 'joulescope.pattern_buffer' extension
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\bin\HostX86\x86\cl.exe /c /nologo /Ox /W3 /GL /DNDEBUG /MD -ID:\bin\Python37-32\lib\site-packages\numpy\core\include -ID:\bin\Python37-32\lib\site-packages\numpy\core\include -ID:\bin\Python37-32\include -ID:\bin\Python37-32\include "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\ATLMFC\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\include" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\include\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\shared" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\um" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\winrt" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.17134.0\cppwinrt" /Tcjoulescope/pattern_buffer.c /Fobuild\temp.win32-3.7\Release\joulescope/pattern_buffer.obj
pattern_buffer.c
d:\bin\python37-32\lib\site-packages\numpy\core\include\numpy\npy_1_7_deprecated_api.h(14) : Warning Msg: Using deprecated NumPy API, disable it with #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
joulescope/pattern_buffer.c(3286): warning C4090: '=': different 'const' qualifiers
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\bin\HostX86\x86\link.exe /nologo /INCREMENTAL:NO /LTCG /DLL /MANIFEST:EMBED,ID=2 /MANIFESTUAC:NO /LIBPATH:D:\bin\Python37-32\libs /LIBPATH:D:\bin\Python37-32\PCbuild\win32 "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\ATLMFC\lib\x86" "/LIBPATH:C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.15.26726\lib\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17134.0\ucrt\x86" "/LIBPATH:C:\Program Files (x86)\Windows Kits\10\lib\10.0.17134.0\um\x86" /EXPORT:PyInit_pattern_buffer build\temp.win32-3.7\Release\joulescope/pattern_buffer.obj /OUT:build\lib.win32-3.7\joulescope\pattern_buffer.cp37-win32.pyd /IMPLIB:build\temp.win32-3.7\Release\joulescope\pattern_buffer.cp37-win32.lib
   Creating library build\temp.win32-3.7\Release\joulescope\pattern_buffer.cp37-win32.lib and object build\temp.win32-3.7\Release\joulescope\pattern_buffer.cp37-win32.exp
Generating code
Finished generating code
copying build\lib.win32-3.7\joulescope\stream_buffer.cp37-win32.pyd -> joulescope
copying build\lib.win32-3.7\joulescope\pattern_buffer.cp37-win32.pyd -> joulescope

Note that they cython compilation only has the one conversion error. Inspecting the C says that’s from stream_buffer.pyx line 365, which is fine. Let’s try the unit tests without a Joulescope connected:

D:\repos\Jetperch\pyjoulescope>python -m unittest
.Invalid signing key
..Invalid format: missing signature start tag
.Invalid signing key
....Invalid signing key
.Invalid signing key
................................sssss.......pkt_index mismatch: expected 1, received 3
{'sample_id': 252, 'header_error': 0, 'pkt_index_error': 1, 'pattern_error': 0}
.........................js_stream_buffer_get stop <= start
..........process: stream_buffer is behind: 0 + 252 < 504
.process: stream_buffer is behind: 0 + 254 < 504
.............sample_id < 0: -2, -1
..
----------------------------------------------------------------------
Ran 104 tests in 9.618s

OK (skipped=5)

Good so far! Now let’s install it:

python setup.py bdist_wheel
pip install dist\joulescope-0.6.5-cp37-cp37m-win32.whl

And try python:

D:\repos\Jetperch\pyjoulescope>python
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 19:29:22) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import joulescope
>>> joulescope.scan()
[]

Good so far. Let’s connect a Joulescope:

>>> joulescope.scan()
[]

I confirm that the joulescope is connected, but not found. If I try the same in my normal 64-bit python, I see:

D:\>python
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import joulescope
>>> joulescope.scan()
[<joulescope.driver.Device object at 0x0000022BDB3106A0>]

Well, this narrows down the first issue to just joulescope.usb.winusb.setupapi.py. This module uses ctypes to access the standard Windows SetupDi functions.

I suspect the ctypes structure definitions and/or function prototypes are not correct for 32-bit or intermixed 32-bit python / 64-bit windows. The structure definitions and function prototypes in joulescope.usb.winusb.kernel32.py will also need to change in the same way.

Is this enough to enable you to dig further?

Thanks for warm welcome to the forum!
Yes, my configuration is #3.

Thanks for narrowing down the issue. I will try to dig there.

Hi again!
I did short investigation today and difference is in results from device_interface_guid_to_paths.
When I took path returned by it from 64 bit python (in my case it was: \\?\usb#vid_16d0&pid_0e88#000250#{576d606f-f3de-4e4e-8a87-065b9fd21eb0} ) and hard-coded it into pyjoulescope at expected path in scan from usb.winusb.device.py, then after building with 32 bit Python I was able to scan and communicate with my Joulescope.
Now I just need to figure out how to generate this path - I will probably use pypiwin32 module.

1 Like

Well that’s interesting. Is that while loop in setupapi.py detecting any devices? If not, then problem is likely with SetupDiEnumDeviceInterfaces or its arguments. Otherwise, the problem is likely with SetupDiGetDeviceInterfaceDetail, its arguments, or wstring_at. I don’t recommend manually generating that path.

Great to hear that hard coding it works though! That means that once we get discover working, we should be good to go! It says that the winusb.device code is good. We may be closer than I expected.