Skip to content

Commit 8fee524

Browse files
authored
Merge pull request #106 from openUC2/mergemaster
Mergemaster
2 parents 93da3cf + 80296c1 commit 8fee524

5 files changed

Lines changed: 87 additions & 453 deletions

File tree

.DS_Store

0 Bytes
Binary file not shown.

README.md

Lines changed: 80 additions & 234 deletions
Original file line numberDiff line numberDiff line change
@@ -1,274 +1,120 @@
1-
2-
<p align="left">
3-
<a href="#logo" name="logo"><img src="https://raw.githubusercontent.com/bionanoimaging/UC2-GIT/master/IMAGES/UC2_logo_text.png" width="400"></a>
4-
</p>
5-
6-
# UC2 REST API
7-
8-
This is the playground to start development of using UC2 modules using the HTTP REST API.
9-
10-
## ESP32
11-
12-
This folder contains all the code for handling actuators and sensors through HTTP requests.
13-
Please use the release versio of the Arduino code and flash it on your ESP32 wemos D1 R32. You can find the [RELEASE here](https://github.com/openUC2/UC2-REST/releases/tag/ESP32_WEMOS_D1_R32)
14-
15-
## PYTHON
16-
17-
We provide a simple [ESP32Client.py](./PYTHON/ESP32Client.py) that can be used to control the ESP32 microcontroler. We have a Jupyter-notebook based tutorial that can help you through the process.
18-
19-
In order to run it, clone this repository/download it and do:
20-
```
21-
conda activate $YOURENVIRONMENT$
22-
cd PYTHON
23-
jupyter notebook
24-
pip install numpy requests python-opencv
25-
pip install socket tempfile pyserial
26-
```
27-
28-
The tutorial can be found [here](./PYTHON/UC2_REST_Tutorial_v0.ipynb).
29-
30-
You can also install it using `PIP`:
31-
32-
```
33-
!pip install UC2-REST==0.1.0rc0
34-
```
35-
36-
37-
### General Usage
38-
39-
```py
40-
from ESP32Client import ESP32Client
41-
ESP32 = ESP32Client(serialport="unknown")
42-
43-
# move and measure
44-
print("Current position: "+ str(ESP32.get_position(axis=1)))
45-
ESP32.move_x(steps=1000, speed=1000, is_blocking=True, is_absolute=True, is_enabled=True)
46-
47-
# set a funny pattern
48-
import numpy as np
49-
50-
Nx=8
51-
Ny=8
52-
led_pattern = np.abs(np.int8(np.random.randn(3,Nx*Ny)*255))
53-
ESP32.send_LEDMatrix_array(led_pattern, timeout=1)
54-
```
55-
56-
## Hardware
57-
58-
It is the easiest to use the ESP32 WEMOS D1 R32 (Arduino compatible) board in combination with the CNC shield v3:
59-
60-
<p align="center">
61-
<a href="#logo" name="logo"><img src="./IMAGES/CNCShieldV3.jpeg" width="400"></a>
62-
</p>
63-
641
<p align="center">
65-
<a href="#logo" name="logo"><img src="./IMAGES/ESP32_D1_R32.jpeg"width="400"></a>
2+
<img src="https://raw.githubusercontent.com/bionanoimaging/UC2-GIT/master/IMAGES/UC2_logo_text.png" width="320" alt="UC2 logo">
663
</p>
674

5+
# UC2‑Python Client
686

69-
## Tutorials
70-
71-
We provide two tutorials that help you installing the software:
72-
73-
<p align="left">
74-
<a href="https://youtu.be/9doTdo5SW2E" name="logo"><img src="./IMAGES/YouTubeUC2RestSetup.png" width="600"></a>
75-
</p>
76-
77-
78-
as well as connecting the hardware:
79-
80-
<p align="left">
81-
<a href="https://youtu.be/v8Xx2iVbDck" name="logo"><img src="./IMAGES/YouTubeRestWire.png" width="600"></a>
82-
</p>
7+
Python interface to the **UC2 REST** micro‑controller firmware — control motors, lasers, LED matrices, galvos and more over USB‑Serial or Wi‑Fi from any Python environment.
838

9+
## Highlights
8410

85-
# Installation
11+
- **Plug‑and‑play connection** via USB (`/dev/ttyUSB*`, `COM*`) or TCP (`host`, `port`).
12+
- **Rich device model**: every hardware block is a Python object with high‑level helpers (e.g. `motor.move_x`, `led.setPattern`, `laser.set_laser`).
13+
- **Asynchronous & blocking modes** for precise timing or maximum throughput.
14+
- **Callback hooks** to react to hardware feedback in real time.
15+
- **Runs everywhere**: desktop Python, headless Raspberry Pi, or in‑browser with PyScript.
16+
- **LGPL‑3.0‑or‑later** license – use it in academic and commercial projects.
8617

87-
***IMPORTANT: USE THE ESP-IDF version 1.0.6 - >=2.0 has issues with the PS3 controller!***
88-
89-
### Install Arduino IDE
90-
91-
- Download the Arduino IDE 1.8.1 from [here](https://www.arduino.cc/en/software/OldSoftwareReleases)
92-
- Install it
93-
94-
### Install Serial driver
95-
96-
In case you use a chinese derivate Arduino or an ESP32 board, you most likely need to install the ***CH340*** serial driver. Please have a look [here](https://learn.sparkfun.com/tutorials/how-to-install-ch340-drivers/all)
97-
98-
### Get the right Boards
99-
100-
If you want an ESP32 board, please add the following sources to the preferences (Boards). More information can be found [here](https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/)
101-
102-
```
103-
https://dl.espressif.com/dl/package_esp32_index.json, http://arduino.esp8266.com/stable/package_esp8266com_index.json
104-
```
105-
106-
### Install the required libraries
107-
108-
109-
***BEST PRACTICE:*** Clone the following repository and copy the libraries inside the Arduino library folder: [https://github.com/beniroquai/BenesArduinoLibraries](https://github.com/beniroquai/BenesArduinoLibraries)
110-
111-
*Alternatively:*
112-
113-
Go to Tools -> Manage Libraries and add the following libraries (More information [here](https://arduinogetstarted.com/faq/how-to-install-library-on-arduino-ide):
18+
## Installation
11419

20+
```bash
21+
pip install uc2rest # latest release
22+
# or for the bleeding‑edge version
23+
pip install git+https://github.com/openUC2/UC2-REST.git#subdirectory=PYTHON
11524
```
116-
ArduinoJson (Benoit Blanchon)
117-
StepperDriver (by Laurentiu Badea)
118-
Adafruit NeoMatrix (Adafruit) and its dependency
119-
```
120-
121-
122-
123-
### PS3/PS4 controller
12425

125-
This code enables a rudimentary integration of the PS3/PS4 controller. For this you need to know/modify the controller's MAC address.
26+
Dependencies (`requests`, `numpy`, `pyserial`) are resolved automatically.
12627

127-
Add the corresponding libraries from here:
128-
- [PS3 controller](https://github.com/jvpernis/esp32-ps3) from the Arduino library manager
129-
- [PS4 controller (modified)](https://github.com/beniroquai/PS4-esp32/)
28+
## Quick start
13029

131-
Please follow the tutorial [here](https://github.com/aed3/PS4-esp32/edit/master/README.md) (similar for PS3)
30+
```python
31+
import uc2rest
13232

133-
#### Installation
134-
The instructions on how to do this are base off what can be found [here](https://github.com/jvpernis/esp32-ps3/issues/3#issuecomment-517141523)
135-
1. You can add the ESP32 boards to your Arduino IDE by adding them to the Boards Manager:
136-
1. Open `File -> Preferences`
137-
1. Paste the following URL in the `Additional Boards Manager URLs` field:
138-
`https://dl.espressif.com/dl/package_esp32_index.json`
139-
1. Open the Boards Manager with `Tools -> Board: "xxx" -> Boards Manager`
140-
1. Look for `esp32` (probably the last one in the list), and click `install`
141-
1. Select the ESP32 board you have with `Tools -> Board: "xxx"` under the section `ESP32 Arduino`
142-
1. To install this library into your Arduino IDE:
143-
1. Click on the "Code" button in the top right of this page
144-
1. Select "Download Zip" (It's always a good idea to look through the code on this page first to make sure you know what you're downloading)
145-
1. In the Arduino IDE, navigate to `Sketch -> Include Library -> Add .ZIP Library`, then select the file you just downloaded
33+
# USB example
34+
esp = uc2rest.UC2Client(serialport="/dev/ttyUSB0") # Linux / Mac OS
35+
# esp = uc2rest.UC2Client(serialport="COM3") # Windows
36+
# Wi‑Fi example
37+
# esp = uc2rest.UC2Client(host="192.168.4.1", port=31950)
14638

147-
### Pairing the PS4 Controller:
39+
# LED matrix: switch all pixels on at half intensity
40+
esp.led.setAll(True, intensity=128)
14841

149-
When a PS4 controller is 'paired' to a PS4 console, it just means that it has stored the console's Bluetooth MAC address, which is the only device the controller will connect to. Usually, this pairing happens when you connect the controller to the PS4 console using a USB cable, and press the PS button. This initiates writing the console's MAC address to the controller.
150-
151-
Therefore, if you want to connect your PS4 controller to the ESP32, you either need to figure out what the Bluetooth MAC address of your PS4 console is and set the ESP32's address to it, or change the MAC address stored in the PS4 controller.
152-
153-
Whichever path you choose, you might want a tool to read and/or write the currently paired MAC address from the PS4 controller. You can try using [sixaxispairer](https://github.com/user-none/sixaxispairer) for this purpose.
154-
155-
If you opted to change the ESP32's MAC address, you'll need to include the ip address in the ```PS4.begin()``` function during within the ```setup()``` Arduino function like below where ```1a:2b:3c:01:01:01``` is the MAC address (**note that MAC address must be unicast**):
42+
# Move X axis by 1 mm (1000 steps @ 1 kHz)
43+
esp.motor.move_x(steps=1000, speed=1000, is_blocking=True)
15644

45+
# Turn green laser to full power
46+
esp.laser.set_laser(channel="G", value=255)
15747
```
158-
void setup()
159-
{
160-
PS4.begin("1a:2b:3c:01:01:01");
161-
Serial.println("Ready.");
162-
}
163-
```
164-
16548

49+
## Supported modules (automatically attached to `UC2Client`) citeturn1file12
16650

51+
| Object | Purpose | Example method(s) |
52+
|-----------------|---------------------------------------|--------------------------------------|
53+
| `motor` | X/Y/Z/θ stages | `move_x / move_xy`, `setup_motor` |
54+
| `led` | 8×8 RGB LED matrix | `setPattern`, `send_LEDMatrix_rings` |
55+
| `laser` | 3‑channel RGB or IR lasers | `set_laser`, `set_servo` |
56+
| `galvo` | Analogue DAC & 2‑axis scanner | `set_dac`, `set_scanner_pattern` |
57+
| `gripper` | Micro‑gripper (servo) | `open`, `close` |
58+
| `home` | End‑stop homing routines | `home_x`, `home_z` |
59+
| `rotator` | Filter wheel or Dove prism | `move`, `set_speed` |
60+
| `objective` | Piezo objective positioner | `move_z`, `calibrate` |
61+
| `temperature` | NTC digital temperature sensor | `get_temperature` |
62+
| `analog` | Arbitrary analogue outputs | `set_voltage` |
63+
| `digitalout` | GPIO (TTL) outputs | `set_pin`, `pulse` |
64+
| `wifi` | ESP32 network helpers | `scan`, `connect` |
65+
| `message` | Generic key‑value messaging/trigger | `register_callback`, `trigger_message` |
16766

168-
### Compile and Upload Arduino Firmware
169-
170-
- Download this repository following this [link](https://github.com/openUC2/UC2-REST/archive/refs/heads/master.zip)
171-
- Go to the folder that contains the file `main.ino` in [.ESP32/main](https://github.com/openUC2/UC2-REST/tree/master/ESP32/main)
172-
- Select the board you want to install it to (e.g. Arduino or ESP32 from the Boardmanager)
173-
- *Optional* adapt some settings (e.g. adding modules, selecting the communication channel like Wifi / Serial) by commenting/outcommenting the following lines (you can find it under the tab
174-
*REST_API_JSON_Serial_Wifi_motor_PS3_v0* )
175-
67+
## Design philosophy
17668

69+
UC2 REST splits interaction into three JSON endpoints per device:
17770

17871
```
179-
// CASES:
180-
// 1 Arduino -> Serial only
181-
// 2 ESP32 -> Serial only
182-
// 3 ESP32 -> Wifi only
183-
// 4 ESP32 -> Wifi + Serial ?
184-
185-
// load configuration
186-
#define ARDUINO_SERIAL
187-
//#define ESP32_SERIAL
188-
//#define ESP32_WIFI
189-
//#define ESP32_SERIAL_WIFI
190-
191-
....
192-
193-
194-
// load modules
195-
# ifdef IS_ESP32
196-
#define IS_DAC // ESP32-only
197-
#define IS_PS3 // ESP32-only
198-
#define IS_ANALOGOUT// ESP32-only
199-
#endif
200-
#define IS_LASER
201-
#define IS_MOTOR
202-
72+
/*_act → perform an action (e.g. move)
73+
/*_set → configure a device (e.g. speed)
74+
/*_get → query state (e.g. position)
20375
```
204-
- *Optional*: Adapt some pin settings in thhe file `pindef.h`
205-
- Now select the port of your arduino device. go to `tools`-> `Ports` and select the one that looks like your arduino/esp32
206-
- Now upload the code (hit the right-arrow on the left hand side)
207-
- Compiling can take a moment
208-
20976

210-
### Test the code using the Arduino Serial
77+
The Python client wraps those endpoints so you rarely deal with raw JSON.
21178

212-
- Open the Arduino Serial (more information [here](https://starthardware.org/arduino-serial-print/)
213-
- Set the Baudrate to `115200` and enter some `Json` commands to manipulate the actuators
214-
- Identify the Board: `{"task": "/state_get"}`
215-
- Turn on the laser: `{"task": "/laser_act", "LASERid":1, "LASERval":2}`
216-
- Move the motor: `{"task": "/motor_act", "axis":1, "speed":1000, "position":1000, "isabsolute":1, "isblocking":1}`
217-
- Operate the analog out: `{"task": "/analogout_act", "analogoutid": 1, "analogoutval":1000}`
218-
- Operate the dac (e.g. lightsheet): `{"task": "/dac_act", "dac_channel": 19, "frequency":1, "offset":0, "amplitude":0, "clk_div": 10000}`
21979

80+
## Running in a browser (PyScript)
22081

221-
### Test the code using the Python interface
222-
223-
- Open a terminal in the folder where you downloaded this repository
224-
- Navigate to the folder [PYTHON](https://github.com/openUC2/UC2-REST/tree/master/PYTHON)
225-
- Install the following dependencies via `pip`:
226-
```pip install requests python-opencv```
227-
- Open the file [TEST_ESP32RestSerialAPI.py](https://github.com/openUC2/UC2-REST/blob/master/PYTHON/TEST_ESP32RestSerialAPI.py)
228-
- Adapt the `serialport`:
229-
```
230-
serialport = "/dev/cu.SLAB_USBtoUART"
231-
serialport = "/dev/cu.SLAB_USBtoUART"
232-
serialport = "/dev/cu.wchusbserial1430"
233-
serialport = "COM3"
82+
```html
83+
<py-config>
84+
packages = ["uc2rest"]
85+
</py-config>
86+
<py-script>
87+
from uc2rest import UC2Client
88+
esp = UC2Client(SerialManager=pyserial_manager) # see docs
89+
esp.led.setAll(True)
90+
</py-script>
23491
```
235-
- Execute script in Python and check result
236-
- In case of an error, file an Issue here
237-
238-
239-
## UC2 and ImSwitch
24092

241-
The device adapter in [PYTHON/ESP32RestSerialAPI.py](PYTHON/ESP32RestSerialAPI.py) is integrated into the open-source control and visualization software ImSwitch. A customized fork for UC2 can be found [here](https://github.com/beniroquai/ImSwitch/tree/master/imswitch/).
93+
## Documentation & examples
24294

243-
In order to get it working, please follow the steps in the dedicated [README](https://github.com/beniroquai/ImSwitch/tree/master/imswitch/)
95+
* Jupyter notebook tutorial: `PYTHON/UC2_REST_Tutorial_v0.ipynb`
96+
* Example scripts: `examples/` directory (motor scan, laser modulation, timelapse)
97+
* Firmware sources and hardware guides: <https://github.com/openUC2>
24498

245-
## API defintion
99+
## Troubleshooting
246100

247-
This will come soon.
248-
In principle, every actuator/sensor should have three comonents:
101+
| Symptom | Fix |
102+
|------------------------------|-----|
103+
| `serial.serialutil.SerialException` | Check port name and permissions (`sudo adduser $USER dialout`) |
104+
| No JSON response / timeout | Increase `timeout` argument; verify baud rate matches firmware |
249105

250-
- `*_act` => *action* -> do something
251-
- `*_set` => *set* -> set parameters
252-
- `*_get` => *get* -> get parameters
106+
## Contributing
253107

254-
### Available hardware
108+
1. Fork the repo and create a feature branch.
109+
2. Follow the `pre‑commit` checks (`black`, `isort`, `flake8`).
110+
3. Create pull requests against `develop`.
255111

256-
- Stepper Motor (e.g. 2Wire)
257-
- Analog Out (e.g. PWM)
258-
- DAC (e.g. function generator for Galvos)
259-
- Laser (e.g. TTL)
260-
- State (e.g. information from the board)
112+
Please open issues for bugs or feature requests.
261113

262-
### Accessing the Swagger UI
263-
264-
This is an experimental feature. You can access the REST API from the Swagger UI in your browser by opening the browser and connect to the ESP32 presumingly both are in the same network.
265-
266-
<p align="center">
267-
<a href="#logo" name="logo"><img src="./IMAGES/Swagger1.png"></a>
268-
</p>
114+
## License
269115

116+
MIT — see `LICENSE` for details.
270117

271-
## TODO's
118+
---
272119

273-
- create pip package
274-
- add testing files
120+
Made with 💚 by the OpenUC2 community.

uc2rest/camera.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
from PIL import Image
1+
try:
2+
from PIL import Image
3+
IS_IMAGE = True
4+
except ImportError:
5+
IS_IMAGE = False
26
import base64
37
import io
48
import numpy as np

0 commit comments

Comments
 (0)