# MEMENTO Wireless Remote with TouchOSC

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/127/190/medium800/camera_memrem_beauty02.jpg?1706053393)

A wireless remote control can be very helpful for certain types of photography -- maybe you want to take a group photo and actually be in the photo this time! Or perhaps you're shooting stop motion animation and need to avoid bumping the camera out of position.

Thanks to the WiFi built into the MEMENTO ESP32-S2 chip, you can trigger any camera function you like with wireless commands sent with an iOS or Android app using the **OSC** protocol.

![](https://cdn-learn.adafruit.com/assets/assets/000/127/191/medium800/camera_memrem_beauty03.jpg?1706053403)

Info: 

## Parts
### MEMENTO - Python Programmable DIY Camera - Bare Board

[MEMENTO - Python Programmable DIY Camera - Bare Board](https://www.adafruit.com/product/5420)
Make memories, or just a cool camera-based project,&nbsp;with **Adafruit's MEMENTO Camera Board**. It's a development board with everything you need to create programmable camera and vision projects: with a camera module, TFT preview screen, buttons, SD card slot and...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5420)
[Related Guides to the Product](https://learn.adafruit.com/products/5420/guides)
![Video of a DIY camera on a lazy susan.](https://cdn-shop.adafruit.com/product-videos/640x480/5420-05.jpg)

### Lithium Ion Polymer Battery with Short Cable - 3.7V 420mAh

[Lithium Ion Polymer Battery with Short Cable - 3.7V 420mAh](https://www.adafruit.com/product/4236)
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This battery has a capacity of 420mAh for a total of about 1.55 Wh. If you need a larger (or smaller!) battery, <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4236)
[Related Guides to the Product](https://learn.adafruit.com/products/4236/guides)
![Lithium Ion Polymer Battery 3.7v 420mAh with JST 2-PH connector and short cable](https://cdn-shop.adafruit.com/640x480/4236-04.jpg)

### 256MB Micro SD Memory Card

[256MB Micro SD Memory Card](https://www.adafruit.com/product/5251)
Add storage in a jiffy using this **256MB microSD card**. Preformatted to FAT32, so it works out of the packaging with our projects. Works great with any device in the Adafruit shop that uses microSD cards. Ideal for use with Feathers, data loggers, or small Linux SBCs (not good...

In Stock
[Buy Now](https://www.adafruit.com/product/5251)
[Related Guides to the Product](https://learn.adafruit.com/products/5251/guides)
![Angled shot of Small microSD card 256mb](https://cdn-shop.adafruit.com/640x480/5251-00.jpg)

Warning: 

### USB Type A to Type C Cable - approx 1 meter / 3 ft long

[USB Type A to Type C Cable - approx 1 meter / 3 ft long](https://www.adafruit.com/product/4474)
As technology changes and adapts, so does Adafruit. This&nbsp;&nbsp; **USB Type A to Type C** cable will help you with the transition to USB C, even if you're still totin' around a USB Type A hub, computer or laptop.

USB C is the latest industry-standard connector for...

In Stock
[Buy Now](https://www.adafruit.com/product/4474)
[Related Guides to the Product](https://learn.adafruit.com/products/4474/guides)
![Angled shot of a coiled black, USB-C to USB-A cable.](https://cdn-shop.adafruit.com/640x480/4474-02.jpg)

## TouchOSC

This project uses TouchOSC by Hexler Limited, available [here](https://hexler.net/touchosc#get). As of this time, TouchOSC is $12.99 in the Apple App Store for iOS and in the Google Play store for Android.

The layout can be edited (or even created from scratch) on the mobile app, but the desktop version for Mac, Windows, or Linux makes it a lot easier. The desktop license costs $25.50 at this time.

Since OSC is a free, open standard, you could adapt the code very easily to use other OSC apps of your choosing.

![camera_oscdesk.jpg](https://cdn-learn.adafruit.com/assets/assets/000/127/193/medium640/camera_oscdesk.jpg?1706054420)

## Mobile Device

You can use nearly any iOS or Android device with WiFi to run TouchOSC.

### Optional:
### Adafruit MEMENTO Camera Enclosure & Hardware Kit

[Adafruit MEMENTO Camera Enclosure & Hardware Kit](https://www.adafruit.com/product/5843)
Once you've picked up your **MEMENTO Camera** and you're ready to take it out into the world, here is a chic and minimalist enclosure that will look great on the runways of Paris or the street photography of New York City! These front and back plates have been...

In Stock
[Buy Now](https://www.adafruit.com/product/5843)
[Related Guides to the Product](https://learn.adafruit.com/products/5843/guides)
![Overhead shot of two square-shaped PCB boards for a DIY camera above eight black plastic screws and four black plastic hex nuts with 3pin to 3pin JST PH cable and adhesive sticker.](https://cdn-shop.adafruit.com/640x480/5843-05.jpg)

### JST PH 2mm 3-pin Plug-Plug Cable - 100mm long

[JST PH 2mm 3-pin Plug-Plug Cable - 100mm long](https://www.adafruit.com/product/4336)
This cable is a little over 100mm / 4" long&nbsp;and fitted with JST-PH 3-pin connectors on either end.&nbsp;

We dig the solid and compact nature of these connectors and the latch that keeps the cable from coming apart easily. We're carrying these to <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4336)
[Related Guides to the Product](https://learn.adafruit.com/products/4336/guides)
![Angled shot of JST PH 3-pin Plug-Plug Cable - 100mm long.](https://cdn-shop.adafruit.com/640x480/4336-01.jpg)

# MEMENTO Wireless Remote with TouchOSC

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

Warning: Make sure you use CircuitPython 9.0.0 final or later. CircuitPython 9.0.0-beta.1 and earlier have a bug that can corrupt the fileystem.

```auto
import storage
storage.erase_filesystem()
```

Your board will reboot after running this.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_esp32s3_camera/)
Warning: As of CircuitPython 9, you'll need to create a folder called "sd" on your CIRCUITPY drive to mount the microSD card, if it's not already there.

[Follow these steps to create the /sd directory](https://learn.adafruit.com/adafruit-memento-camera-board/circuitpython-memento-starter-projects)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_most_boards_CircuitPython_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/102/129/medium640/install_circuitpython_on_most_boards_CircuitPython_downloaded.jpg?1620922559)

![](https://cdn-learn.adafruit.com/assets/assets/000/126/734/medium800/adafruit_products_resetNeo.jpg?1702908010)

Plug your board into your computer, using a known-good data-sync cable, directly, or via an adapter if needed.

Double-click the **reset** button (highlighted in red above), and you will see the **RGB status LED(s)** turn green (highlighted in green above). If you see red, try another port, or if you're using an adapter or hub, try without the hub, or different adapter or hub.

For this board, tap reset and wait for the LED to turn purple, and as soon as it turns purple, tap reset again. The second tap needs to happen while the LED is still purple.

If you do not see the LED turning purple, you will need to reinstall the UF2 bootloader. See the **Factory Reset** page in this guide for details.

If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **CAMERABOOT**. Drag the **adafruit-circuitpython-adafruit\_esp32s3\_camera-etc.uf2** file to **CAMERABOOT**.

![adafruit_products_cameraboot.png](https://cdn-learn.adafruit.com/assets/assets/000/126/740/medium640/adafruit_products_cameraboot.png?1702932896)

The **BOOT** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it!

![install_circuitpython_on_most_boards_CIRCUITPY.jpg](https://cdn-learn.adafruit.com/assets/assets/000/102/130/medium640/install_circuitpython_on_most_boards_CIRCUITPY.jpg?1620923145)

# MEMENTO Wireless Remote with TouchOSC

## Create Your settings.toml File

CircuitPython works with WiFi-capable boards to enable you to make projects that have network connectivity. This means working with various passwords and API keys. As of [CircuitPython 8](https://circuitpython.org/downloads), there is support for a **settings.toml** file. This is a file that is stored on your **CIRCUITPY** drive, that contains all of your secret network information, such as your SSID, SSID password and any API keys for IoT services. It is designed to separate your sensitive information from your **code.py** file so you are able to share your code without sharing your credentials.

CircuitPython previously used a **secrets.py** file for this purpose. The **settings.toml** file is quite similar.

Warning: Your **settings.toml** file should be stored in the main directory of your **CIRCUITPY** drive. It should not be in a folder.

## CircuitPython **settings.toml** File

This section will provide a couple of examples of what your **settings.toml** file should look like, specifically for CircuitPython WiFi projects in general.

The most minimal **settings.toml** file must contain your WiFi SSID and password, as that is the minimum required to connect to WiFi. Copy this example, paste it into your **settings.toml** , and update:

- `your_wifi_ssid`
- `your_wifi_password`

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
```

Many CircuitPython network-connected projects on the Adafruit Learn System involve using Adafruit IO. For these projects, you must _also_ include your Adafruit IO username and key. Copy the following example, paste it into your settings.toml file, and update:

- `your_wifi_ssid`
- `your_wifi_password`
- `your_aio_username`
- `your_aio_key`

```auto
CIRCUITPY_WIFI_SSID = "your_wifi_ssid"
CIRCUITPY_WIFI_PASSWORD = "your_wifi_password"
ADAFRUIT_AIO_USERNAME = "your_aio_username"
ADAFRUIT_AIO_KEY = "your_aio_key"
```

Some projects use different variable names for the entries in the **settings.toml** file. For example, a project might use `ADAFRUIT_AIO_ID` in the place of `ADAFRUIT_AIO_USERNAME`. **If you run into connectivity issues, one of the first things to check is that the names in the settings.toml file match the names in the code.**

Warning: Not every project uses the same variable name for each entry in the **settings.toml** file! Always verify it matches the code.

## **settings.toml** File Tips
Here is an example **settings.toml** file.

```auto
# Comments are supported
CIRCUITPY_WIFI_SSID = "guest wifi"
CIRCUITPY_WIFI_PASSWORD = "guessable"
CIRCUITPY_WEB_API_PORT = 80
CIRCUITPY_WEB_API_PASSWORD = "passw0rd"
test_variable = "this is a test"
thumbs_up = "\U0001f44d"
```

In a **settings.toml** file, it's important to keep these factors in mind:

- Strings are wrapped in double quotes; ex: `"your-string-here"`
- Integers are _ **not** _ quoted and may be written in decimal with optional sign (`+1`, `-1`, `1000`) or hexadecimal (`0xabcd`).
  - Floats (decimal numbers), octal (`0o567`) and binary (`0b11011`) are not supported.

- Use `\u` escapes for weird characters, `\x` and `\ooo` escapes are not available in **.toml** files
  - Example: `\U0001f44d` for 👍 (thumbs up emoji) and `\u20ac` for € (EUR sign)

- Unicode emoji, and non-ASCII characters, stand for themselves as long as you're careful to save in "UTF-8 without BOM" format

&nbsp;

&nbsp;

When your&nbsp; **settings.toml&nbsp;** file is ready, you can save it in your text editor with the **.toml** &nbsp;extension.

![adafruit_products_dotToml.jpg](https://cdn-learn.adafruit.com/assets/assets/000/117/071/medium640/adafruit_products_dotToml.jpg?1671034293)

## Accessing Your **settings.toml** Information in **code.py**
In your **code.py** file, you'll need to `import` the `os` library to access the **settings.toml** file. Your settings are accessed with the `os.getenv()` function. You'll pass your settings entry to the function to import it into the **code.py** file.

```python
import os

print(os.getenv("test_variable"))
```

![](https://cdn-learn.adafruit.com/assets/assets/000/117/072/medium800/adafruit_products_tomlOutput.jpg?1671034496)

In the upcoming CircuitPython WiFi examples, you'll see how the **settings.toml&nbsp;** file is used for connecting to your SSID and accessing your API keys.

# MEMENTO Wireless Remote with TouchOSC

## Code the Wireless Remote Camera

## Text Editor

Adafruit recommends using the&nbsp; **Mu** &nbsp;editor for editing your CircuitPython code. You can get more info in&nbsp;[this guide](https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor).

Alternatively, you can use any text editor that saves simple text files.

## Download the Project Bundle

Your project will use a specific set of CircuitPython libraries, and the&nbsp; **code.py** &nbsp;file. To get everything you need, click on the&nbsp; **Download Project Bundle** &nbsp;button below, and uncompress the .zip file.

Connect your computer to the board via a known good USB power+data cable. A new flash drive should show up as&nbsp; **CIRCUITPY**.

Drag the contents of the uncompressed bundle directory onto your board&nbsp; **CIRCUITPY** &nbsp;drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/MEMENTO/Wireless_Remote/code.py

## How It Works

The code boots up, connects to your WiFi, launches the camera app, and then waits for interactions from either the hardware buttons on the MEMENTO itself, or the equivalent software commands sent from your mobile device in the OSC messages.

### Libraries

First, the libraries are imported. For more info on the OSC integration, check out Todbot's [microosc library](https://github.com/todbot/CircuitPython_MicroOSC/tree/main).

```auto
import time
import os
import bitmaptools
import displayio
import gifio
import ulab.numpy as np
import adafruit_pycamera
import wifi
import socketpool
import microosc
```

### Wireless Setup

Next, the `UDP_Host` and `UDP_Port` are set for the OSC server, and the WiFi access point credentials are set.

```auto
UDP_HOST = ""
UDP_PORT = 8000
ssid = os.getenv("CIRCUITPY_WIFI_SSID")
password = os.getenv("CIRCUITPY_WIFI_PASSWORD")
print("connecting to WiFi", ssid)
wifi.radio.connect(ssid, password)
print("my ip address:", wifi.radio.ipv4_address)
socket_pool = socketpool.SocketPool(wifi.radio)
```

### PyCamera Initialization

The camera is set up as well as the autofocus.

```auto
pycam = adafruit_pycamera.PyCamera()
pycam.autofocus_init()
```

### Camera Functions

- `snap_jpeg()`: Captures a JPEG image
- `snap_gboy()`: Captures a frame for a Game Boy-style effect (GIF)
- `snap_gif()`: Records a GIF animation
- `snap_stop()`: Captures a frame, displays a ghost/onion skin of the previous frame for use in stop motion animation

```auto
def snap_jpeg():
    pycam.tone(600, 0.1)
    try:
        pycam.display_message("Snap!", color=0x0000FF)
        pycam.capture_jpeg()
        pycam.live_preview_mode()
    # pylint: disable=unused-variable
    except TypeError as e:
        pycam.display_message("Failed", color=0xFF0000)
        time.sleep(0.5)
        pycam.live_preview_mode()
    except RuntimeError as e:
        pycam.display_message("Error\nNo SD Card", color=0xFF0000)
        time.sleep(0.5)

def snap_gboy():
    pycam.tone(600, 0.1)
    try:
        f = pycam.open_next_image("gif")
        pycam.display_message("Snap!", color=0x00ff44)
    # pylint: disable=unused-variable
    except RuntimeError as e:
        pycam.display_message("Error\nNo SD Card", color=0xFF0000)
        time.sleep(0.5)

    with gifio.GifWriter(
        f,
        pycam.camera.width,
        pycam.camera.height,
        displayio.Colorspace.RGB565_SWAPPED,
        dither=True,
    ) as g:
        g.add_frame(last_frame, 1)

def snap_gif():
    pycam.tone(600, 0.1)
    try:
        f = pycam.open_next_image("gif")
    # pylint: disable=unused-variable
    except RuntimeError as e:
        pycam.display_message("Error\nNo SD Card", color=0xFF0000)
        time.sleep(0.5)
    i = 0
    ft = []
    pycam._mode_label.text = "RECORDING"  # pylint: disable=protected-access

    pycam.display.refresh()
    with gifio.GifWriter(
        f,
        pycam.camera.width,
        pycam.camera.height,
        displayio.Colorspace.RGB565_SWAPPED,
        dither=True,
    ) as g:
        t00 = t0 = time.monotonic()
        while (i &lt; 15) or not pycam.shutter_button.value:
            i += 1
            _gifframe = pycam.continuous_capture()
            g.add_frame(_gifframe, 0.12)
            pycam.blit(_gifframe)
            t1 = time.monotonic()
            ft.append(1 / (t1 - t0))
            print(end=".")
            t0 = t1
    pycam._mode_label.text = "GIF"  # pylint: disable=protected-access
    print(f"\nfinal size {f.tell()} for {i} frames")
    print(f"average framerate {i/(t1-t00)}fps")
    print(f"best {max(ft)} worst {min(ft)} std. deviation {np.std(ft)}")
    f.close()
    pycam.display.refresh()
    pycam.tone(1200, 0.15)

def snap_stop():
    pycam.tone(600, 0.1)
    pycam.capture_into_bitmap(last_frame)
    pycam.stop_motion_frame += 1
    try:
        pycam.display_message("Snap!", color=0x0000FF)
        pycam.capture_jpeg()
    # pylint: disable=unused-variable
    except TypeError as e:
        pycam.display_message("Failed", color=0xFF0000)
        time.sleep(0.5)
    except RuntimeError as e:
        pycam.display_message("Error\nNo SD Card", color=0xFF0000)
        time.sleep(0.5)
    pycam.live_preview_mode()
```

### OSC Message Handlers

When different OSC messages are dispatched, the message handler functions are triggered.&nbsp;

- `fader_handler(msg)`: Handles fader messages (float values) and adjusts the LED level based on the fader value.
- `radio_handler(msg)`: Handles radio button messages for adjusting mode, resolution, LED color, and effects.
- `button_handler(msg)`: Handles button messages (press/release) for setting focus and snapping the shutter

### OSC Messages

The OSC messages contain path addresses and element names as well as values. For example: `/1/button2 [1.0]` is **page1** , **button2** with a value of **1.0&nbsp;** which the `button_handler()` interprets as the **focus** button being pressed.

While `/2/radio4 [5]` is **page2** , **radio button 3** &nbsp; with a value of **5**. This means the **blue** LED value has been selected.

When the LED brightness fader is adjusted, the message will look like this: `/2/fader1 [0.629] `

```auto
def fader_handler(msg):  # faders
    """Used to handle 'fader' OscMsgs, printing it as a '*' text progress bar
    :param OscMsg msg: message with one required float32 value
    """
    osc_addr = msg.addr.split('/')  # chop up the address into parts
    # page_num = osc_addr[1]
    fader_num = int(osc_addr[2].replace('fader', ''))  # get the number only
    if fader_num == 1:  # led level
        led_val = int(msg.args[0] * 5)
        pycam.led_level = led_val

mode_texts = ("JPEG", "GIF", "GBOY", "STOP")

def radio_handler(msg):  # Radio buttons
    osc_addr = msg.addr.split('/')  # chop up the address into parts
    print(osc_addr)
    page_num = osc_addr[1]
    print("page_num:", page_num)
    rad_num = int(osc_addr[2].replace('radio', ''))  # get the number only
    print("rad_num:", rad_num)
    if rad_num == 1:  # MODE
        print("switched mode to", mode_texts[msg.args[0]])
        pycam.mode = msg.args[0]
    if rad_num == 2:  # resolution
        print("switched resolution")
        pycam.resolution = msg.args[0]
    if rad_num == 3:  # LED color
        print("set color")
        pycam.led_color = msg.args[0]
    if rad_num == 4:  # effects
        print("switched effect")
        pycam.effect = msg.args[0]

def button_handler(msg):  # buttons
    addr = msg.addr
    button_num = int(addr.replace('/1/button',''))
    if msg.args[0] == 1.0:
        print(button_num, "is ON")
        if button_num == 1:
            pycam.tone(1200, 0.05)
            pycam.tone(1600, 0.05)
            if pycam.mode_text == "JPEG":
                snap_jpeg()
            if pycam.mode_text == "GBOY":
                snap_gboy()
            if pycam.mode_text == "GIF":
                snap_gif()
            if pycam.mode_text == "STOP":
                snap_stop()

        if button_num == 2:  # focus
            pycam.tone(1800, 0.05)
            print("FOCUS")
            print(pycam.autofocus_status)
            pycam.autofocus()
            print(pycam.autofocus_status)
            pycam.tone(1400, 0.05)

    else:
        print(button_num, "is off")
```

### Dispatch Map

The `dispatch_map` is a dictionary that maps the incoming OSC messages to their handler functions. You can get as granular as you like here, for example, dispatching messages from particular pages to their own functions.

```auto
dispatch_map = {
    "/": lambda msg: print("msg:", msg.addr, msg.args),  # prints all messages
    "/1/fader": fader_handler,
    "/2/fader": fader_handler,
    "/1/toggle": toggle_handler,
    "/1/button": button_handler,
    "/1/radio": radio_handler,
    "/2/radio": radio_handler
}
```

### OSC Server&nbsp;

The OSC server is set up to receive messages using UDP.

`osc_server = microosc.OSCServer(socket_pool, UDP_HOST, UDP_PORT, dispatch_map)`

## Main Loop

The main loop the code continuously polls the OSC server for incoming messages, which are then used by the `dispatch_map`.

Additionally, all of the hardware buttons on the MEMENTO are used to snap the shutter, autofocus on long hold, and adjust the settings. These are the same as in the original PyCamera library example code, but some of the code has been moved into functions that both the buttons and the OSC messages can use.

```auto
osc_server.poll()  # check for incoming OSC messages

    if pycam.mode_text == "STOP" and pycam.stop_motion_frame != 0:
        # alpha blend
        new_frame = pycam.continuous_capture()
        bitmaptools.alphablend(
            onionskin, last_frame, new_frame, displayio.Colorspace.RGB565_SWAPPED
        )
        pycam.blit(onionskin)
    elif pycam.mode_text == "GBOY":
        bitmaptools.dither(
            last_frame, pycam.continuous_capture(), displayio.Colorspace.RGB565_SWAPPED
        )
        pycam.blit(last_frame)
    else:
        pycam.blit(pycam.continuous_capture())

    pycam.keys_debounce()

    if pycam.shutter.long_press:
        print("FOCUS")
        print(pycam.autofocus_status)
        pycam.autofocus()
        print(pycam.autofocus_status)

    if pycam.shutter.short_count:
        print("Shutter released")
        if pycam.mode_text == "STOP":
            snap_stop()

        if pycam.mode_text == "GBOY":
            snap_gboy()

        if pycam.mode_text == "GIF":
            snap_gif()

        if pycam.mode_text == "JPEG":
            snap_jpeg()

    if pycam.card_detect.fell:
        print("SD card removed")
        pycam.unmount_sd_card()
        pycam.display.refresh()
    if pycam.card_detect.rose:
        print("SD card inserted")
        pycam.display_message("Mounting\nSD Card", color=0xFFFFFF)
        for _ in range(3):
            try:
                print("Mounting card")
                pycam.mount_sd_card()
                print("Success!")
                break
            except OSError as e:
                print("Retrying!", e)
                time.sleep(0.5)
        else:
            pycam.display_message("SD Card\nFailed!", color=0xFF0000)
            time.sleep(0.5)
        pycam.display.refresh()

    if pycam.up.fell:
        print("UP")
        key = settings[curr_setting]
        if key:
            setattr(pycam, key, getattr(pycam, key) + 1)
    if pycam.down.fell:
        print("DN")
        key = settings[curr_setting]
        if key:
            setattr(pycam, key, getattr(pycam, key) - 1)
    if pycam.left.fell:
        print("LF")
        curr_setting = (curr_setting + 1) % len(settings)
        print(settings[curr_setting])
        pycam.select_setting(settings[curr_setting])
    if pycam.right.fell:
        print("RT")
        curr_setting = (curr_setting - 1 + len(settings)) % len(settings)
        print(settings[curr_setting])
        pycam.select_setting(settings[curr_setting])
    if pycam.select.fell:
        print("SEL")
    if pycam.ok.fell:
        print("OK")
```

# MEMENTO Wireless Remote with TouchOSC

## TouchOSC Setup & Use

Download and Install TouchOSC from either the [Apple App Store](https://apps.apple.com/us/app/touchosc/id1569996730) for iOS or [Google Play store](https://play.google.com/store/apps/details?id=net.hexler.lex) for Android.

Warning: 

https://www.youtube.com/live/4_E0T3JaWgs?feature=shared&t=2267

## MEMENTO Layout

Download the TouchOSC layout file linked in the button below and uncompress it. You can then transfer it to your phone or tablet -- for example, on iOS an iCloud shared folder can be used.

![](https://cdn-learn.adafruit.com/assets/assets/000/127/167/medium800/camera_memrem1.jpg?1705971924)

![](https://cdn-learn.adafruit.com/assets/assets/000/127/166/medium800/camera_memrem2.jpg?1705981600)

[MEMENTO_remote_03.tosc.zip](https://cdn-learn.adafruit.com/assets/assets/000/127/164/original/MEMENTO_remote_03.tosc.zip?1705955621)
### Open Document

In TouchOSC, tap the E **ditor Panel** icon.

Then, scroll the toolbar to reveal the **Open Document** icon.

![camera_memrem_scrn01.jpg](https://cdn-learn.adafruit.com/assets/assets/000/127/196/medium640/camera_memrem_scrn01.jpg?1706065623)

Tap it and browse for the **MEMENTO\_remote** file.

Tap the **Import** button, this will open the layout into the TouchOSC editor.

A Comment popup will open, tap **OK**.

![camera_memrem_scrn02.jpg](https://cdn-learn.adafruit.com/assets/assets/000/127/197/medium640/camera_memrem_scrn02.jpg?1706065675)

You can now close the **Editor**  **Panel** by tapping the icon shown.

### Connections

Tap the link icon to open the **Connections** page, this is where we'll establish UDP settings for the MEMENTO's server.

![camera_memrem_scrn03.jpg](https://cdn-learn.adafruit.com/assets/assets/000/127/198/medium640/camera_memrem_scrn03.jpg?1706065774)

### IP Address

When you reset or power on the MEMENTO, look for the IP address listed at the bottom of the screen. This screen will pause for ten seconds so you can write down that IP address. This is the address you'll use on the next step in TouchOSC to fill in the Host settings.

![camera_IPScreen.jpg](https://cdn-learn.adafruit.com/assets/assets/000/127/208/medium640/camera_IPScreen.jpg?1706120745)

Warning: 

Tap the **OSC** button.

Check the box for **Connection 1** , select **UDP** from the dropdown menu, and then fill in the **Host** address of your MEMENTO (this is printed in the REPL serial output when the MEMENTO first connects to your WiFi access point). In my case it is `192.168.1.57` but this will most likely be different for you depending on your network.

Fill in the **Send Port** address as `8000`. Then, tap **Done&nbsp;** to return to the editor.

![camera_memrem_scrn04.jpg](https://cdn-learn.adafruit.com/assets/assets/000/127/199/medium640/camera_memrem_scrn04.jpg?1706065922)

### Control Surface View

Scroll the top toolbar until you see the triangle "play" button. This launches the Control Surface view, which is the interaction mode of TouchOSC.

Press the **big red button** to snap the shutter on the camera -- remotely! This will send the OSC message over WiFi to tell the MEMENTO to take a picture (or start recording a GIF).

You can now also tap the **focus** button to have the camera focus on the center frame subject.

Tap any of the mode buttons at the bottom of the screen to pick among **JPEG, GIF, Gameboy,** and **Stop motion** modes.

The MEMENTO remote layout has two pages, which are selected with the tabs named **remote** and **settings**. Tap the **settings** tab now.

![camera_memrem_scrn05.jpg](https://cdn-learn.adafruit.com/assets/assets/000/127/200/medium640/camera_memrem_scrn05.jpg?1706066147)

![](https://cdn-learn.adafruit.com/assets/assets/000/127/203/medium800/camera_memrem_beauty.jpg?1706066873)

### Settings

The resolution page is broken into three columns.

In the **Resolution** column you can pick any of the available pixel resolutions.

In the **LEDs** column you can pick **NeoPixel**  **colors** and adjust the **brightness** with the fader.

In the **Effects** column you can pick among any of the available **effects**.

To get back to the snapshot screen, tap the **remote** tab.

Any time you want to leave Control Surface view and return to the editor, tap the circle in the upper right corner of the screen.

![camera_memrem_scrn06.jpg](https://cdn-learn.adafruit.com/assets/assets/000/127/201/medium640/camera_memrem_scrn06.jpg?1706066430)

![](https://cdn-learn.adafruit.com/assets/assets/000/127/202/medium800/camera_memrem_beauty03.jpg?1706066846)


## Featured Products

### MEMENTO - Python Programmable DIY Camera - Bare Board

[MEMENTO - Python Programmable DIY Camera - Bare Board](https://www.adafruit.com/product/5420)
Make memories, or just a cool camera-based project,&nbsp;with **Adafruit's MEMENTO Camera Board**. It's a development board with everything you need to create programmable camera and vision projects: with a camera module, TFT preview screen, buttons, SD card slot and...

Out of Stock
[Buy Now](https://www.adafruit.com/product/5420)
[Related Guides to the Product](https://learn.adafruit.com/products/5420/guides)
### Adafruit MEMENTO Camera Enclosure & Hardware Kit

[Adafruit MEMENTO Camera Enclosure & Hardware Kit](https://www.adafruit.com/product/5843)
Once you've picked up your **MEMENTO Camera** and you're ready to take it out into the world, here is a chic and minimalist enclosure that will look great on the runways of Paris or the street photography of New York City! These front and back plates have been...

In Stock
[Buy Now](https://www.adafruit.com/product/5843)
[Related Guides to the Product](https://learn.adafruit.com/products/5843/guides)
### Lithium Ion Polymer Battery with Short Cable - 3.7V 420mAh

[Lithium Ion Polymer Battery with Short Cable - 3.7V 420mAh](https://www.adafruit.com/product/4236)
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This battery has a capacity of 420mAh for a total of about 1.55 Wh. If you need a larger (or smaller!) battery, <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4236)
[Related Guides to the Product](https://learn.adafruit.com/products/4236/guides)
### 256MB Micro SD Memory Card

[256MB Micro SD Memory Card](https://www.adafruit.com/product/5251)
Add storage in a jiffy using this **256MB microSD card**. Preformatted to FAT32, so it works out of the packaging with our projects. Works great with any device in the Adafruit shop that uses microSD cards. Ideal for use with Feathers, data loggers, or small Linux SBCs (not good...

In Stock
[Buy Now](https://www.adafruit.com/product/5251)
[Related Guides to the Product](https://learn.adafruit.com/products/5251/guides)
### JST PH 2mm 3-pin Plug-Plug Cable - 100mm long

[JST PH 2mm 3-pin Plug-Plug Cable - 100mm long](https://www.adafruit.com/product/4336)
This cable is a little over 100mm / 4" long&nbsp;and fitted with JST-PH 3-pin connectors on either end.&nbsp;

We dig the solid and compact nature of these connectors and the latch that keeps the cable from coming apart easily. We're carrying these to <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4336)
[Related Guides to the Product](https://learn.adafruit.com/products/4336/guides)
### MEMENTO LED Ring Front Plate with 8 RGBW NeoPixels

[MEMENTO LED Ring Front Plate with 8 RGBW NeoPixels](https://www.adafruit.com/product/5854)
This product is just the LED ring add-on board for the MEMENTO camera kit pack.

Out of Stock
[Buy Now](https://www.adafruit.com/product/5854)
[Related Guides to the Product](https://learn.adafruit.com/products/5854/guides)
### USB Type A to Type C Cable - approx 1 meter / 3 ft long

[USB Type A to Type C Cable - approx 1 meter / 3 ft long](https://www.adafruit.com/product/4474)
As technology changes and adapts, so does Adafruit. This&nbsp;&nbsp; **USB Type A to Type C** cable will help you with the transition to USB C, even if you're still totin' around a USB Type A hub, computer or laptop.

USB C is the latest industry-standard connector for...

In Stock
[Buy Now](https://www.adafruit.com/product/4474)
[Related Guides to the Product](https://learn.adafruit.com/products/4474/guides)

## Related Guides

- [Adafruit MEMENTO Camera Board](https://learn.adafruit.com/adafruit-memento-camera-board.md)
- [Face Tracking Robot with MEMENTO](https://learn.adafruit.com/face-tracking-robot-with-memento.md)
- [IoT Bird Feeder with Camera](https://learn.adafruit.com/iot-window-bird-feeder-with-camera.md)
- [OpenAI Image Descriptors with MEMENTO](https://learn.adafruit.com/openai-image-descriptors-with-memento.md)
- [DIY IoT Doorbell Camera with MEMENTO](https://learn.adafruit.com/diy-iot-doorbell-camera-with-memento.md)
- [Memento Photo Capture with itsaSNAP](https://learn.adafruit.com/memento-photo-capture-with-itsasnap.md)
- [Set up Web Workflow on the Adafruit MEMENTO](https://learn.adafruit.com/set-up-web-workflow-on-the-adafruit-memento.md)
- [MEMENTO Focus Stacking](https://learn.adafruit.com/memento-focus-stacking.md)
- [AdaBox 021](https://learn.adafruit.com/adabox021.md)
- [3D Printed Camera Case for MEMENTO](https://learn.adafruit.com/memento-3d-case.md)
- [Facial Detection and Recognition with MEMENTO](https://learn.adafruit.com/facial-detection-and-recognition-with-memento.md)
- [Remote Shutter Button for MEMENTO](https://learn.adafruit.com/memento-shutter.md)
- [Bluetooth Controlled NeoPixel Lightbox](https://learn.adafruit.com/bluetooth-neopixel-lightbox.md)
- [How to register your drone in the US](https://learn.adafruit.com/how-to-register-your-drone-in-the-usa.md)
- [Adafruit PMSA003I Air Quality Breakout](https://learn.adafruit.com/pmsa003i.md)
