---
title: "Choice! Check your fortune with tarot cards !"
url: "https://maker.wiznet.io/Alan/projects/choice%21-check-your-fortune-with-tarot-cards-%21/"
markdown_url: "https://maker.wiznet.io/Alan/projects/choice%21-check-your-fortune-with-tarot-cards-%21/md"
type: "WCC: WIZnet Created Content"
author: "Alan"
author_url: "https://maker.wiznet.io/Alan/"
published: "2023-07-07"
language: "en"
hardware: ["Raspberry Pi Pico", "WIZnet W5100S"]
likes: 2
views: 3989
comments: 1
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# Choice! Check your fortune with tarot cards !

> Choice! Check your fortune with tarot cards !

## Components

- **Raspberry Pi Pico** x 1 ([docs](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html))
- **WIZnet W5100S** x 1 ([docs](https://docs.wiznet.io/Product/Chip/Ethernet/W5100S))

## Article

### **Intro**

Hello! I made a fun project this time as well!

This project is very similar to the last one, but it's been upgraded a lot!

Check out the [previous project](https://www.hackster.io/alan43/wow-enjoy-the-current-weather-with-picasso-s-painting-1e01f4) for more information!

![Previous project](https://hackster.imgix.net/uploads/attachments/1605974/image_mXLBSFpUPv.png?auto=compress%2Cformat&w=740&h=555&fit=max)

Previous project

### **Hardware**

The configuration is very simple! All you need is a W5100S capable of Ethernet communication with Raspberry pico. I used the W5100S-PoE board that I developed. And just configure the switch circuit to press the SPI-enabled LCD and switch like last time, and that's it!

![](https://hackster.imgix.net/uploads/attachments/1605997/image_tXGp8Fdk0s.png?auto=compress%2Cformat&w=740&h=555&fit=max)

The pin setting is the same as the image above.

![](https://hackster.imgix.net/uploads/attachments/1605985/image_2YntaF3RTg.png?auto=compress%2Cformat&w=740&h=555&fit=max)

### **Ethernet Connectivity**

The first thing to do is to do is to connect Ethernet. You can easily connect the Pico board to Ethernet by entering the Git below.

[Getting Started](https://github.com/Wiznet/RP2040-HAT-CircuitPython/blob/master/Ethernet%20Example%20Getting%20Started%20%5BCircuitpython%5D.md)

![](https://hackster.imgix.net/uploads/attachments/1605999/image_wgBPGkBysX.png?auto=compress%2Cformat&w=740&h=555&fit=max)

You can configure the computer to be a server and the Pico to be a client.

### **Image transfer / Display**

![](https://hackster.imgix.net/uploads/attachments/1606002/image_n7lIvF04yO.png?auto=compress%2Cformat&w=740&h=555&fit=max)

```plaintext
while True:
    with open("back1234.bmp", "rb") as f:
        image_data = f.read()
    print(image_data)

    len_sent = f"LEN:{len(image_data)}".encode()
    print(f"length of sent data = {len_sent}")
    connectionSock.send(len_sent)
    time.sleep(1)
    connectionSock.send(image_data)
    time.sleep(1)
```

Pass the BMP image that has already been created over Ethernet. (Server)

![](https://hackster.imgix.net/uploads/attachments/1606008/image_h1JJtaHih7.png?auto=compress%2Cformat&w=740&h=555&fit=max)

```plaintext
while True:
    data = s.recv(MAXBUF)
    if not data:
        continue

    if len(data):
        print(len(data))
        if not len_buf:
            if b"LEN" in data:
                len_buf = int(data.decode().split(":")[1])
                print(f"length of buf = {len_buf}")
        else:
            buf += data
            if len(buf) >= len_buf:
                break

bmp_data = bytearray(buf)
with open("test.bmp", "wb") as f:
    f.write(bmp_data)
f.close()

group = displayio.Group()
display.show(group)

bitmap = displayio.OnDiskBitmap("/test.bmp")
tile_grid = displayio.TileGrid(bitmap, pixel_shader=bitmap.pixel_shader)
group.append(tile_grid)

os.remove("/test.bmp")
```

The client connects to the server and receives the image and displays it. (Client)

### **Select a card**

You can choose the card you want with four buttons.

```plaintext
while True:
    pressed = button1.value + button2.value * 2 + button3.value * 2 ** 2 + button4.value * 2 ** 3

    if pressed != 15:
        break

s.send(f"{15 - pressed}".encode())
```

In the Client, click the button for the desired card number. It calculates bits by bits and sends data to the server. When you click button 1, number 1 and 2 send 2, number 3 send 4, number 4 send 8.(Client)

```plaintext
while True:
    data = connectionSock.recv(2)
    if not data:
        continue
    data = data.decode()
    card_num: str = ''
    print(f"received={data}")
    if data == '1':
        card_num = 'first'
    elif data == '2':
        card_num = 'second'
    elif data == '4':
        card_num = 'third'
    elif data == '8':
        card_num = 'fourth'

    query = "4 random cards flipped on pamela colman smith rws tarot deck." \
            "I picked the {} card. Please explain what this card is like. Please explain within 3 sentences".format(card_num)
    print(query)
```

When the server receives the data, it converts the data into the desired characters. And make a string to deliver to GPT.(Server)

### **Chat GPT**

You can easily get a Chat GPT API Key from the site below.

[OpenAI Chat GPT API Key](https://platform.openai.com/overview)

![](https://hackster.imgix.net/uploads/attachments/1606001/8301411678979731073.jpg?auto=compress%2Cformat&w=740&h=555&fit=max)

```plaintext
def Chat_GPT(api_key, query):
    global answer

    openai.api_key = api_key

    model = "gpt-3.5-turbo"

    messages = [
        {
            "role": "system",
            "content": "You are the best tarotist."
        },
        {
            "role": "user",
            "content": query
        }
    ]

    response = openai.ChatCompletion.create(
        model=model,
        messages=messages
    )
    answer = response['choices'][0]['message']['content']
    print(answer)
```

I assigned the following role to Chat GPT and wrote a prompt accordingly.(Server)

```plaintext
query = "4 random cards flipped on pamela colman smith rws tarot deck." \
        "I picked the {} card. Please explain what this card is like. Please explain within 3 sentences".format(card_num)
print(query)
Chat_GPT(api_key, query)
```

The main code then combines the information about the click of a button received from the device into the prompt and forwards it to the GPT.(Server)

### **Dall-E-2**

DALL-E 2 is an image generation tool created by OpenAI.

```plaintext
def dall_e2(answer):
    global image_url
    global image_data
    response = openai.Image.create(
        prompt=answer,
        n=1,
        size="256x256",
    )
    image_url = response['data'][0]['url']
    urllib.request.urlretrieve(image_url, "test.bmp")

    im = Image.open("test.bmp")
    im_resized = im.resize((220, 220))

    im_resized = im_resized.convert('P', palette=Image.ADAPTIVE, colors=16)

    im_resized.save("test_resized.bmp", format="BMP")
    with open("test_resized.bmp", "rb") as f:
        image_data = f.read()
    print(image_data)
```

The code for DALL-E 2 is structured as follows. One thing to note here is the Image size section. Since I don't have separate memory, I will save the image in BMP format to the Pico board's Flash and display it later.

Anyway, when sending and receiving data, the image size cannot be larger than the size of SRAM because the data is stored in SRAM.

***In my experience, the program did not work properly when the image size exceeded 53k. I will upgrade this part in the future so that we can display even cooler images.***

```plaintext
Chat_GPT(api_key, query)
dall_e2(answer)
```

In the main code, we send the data received from GPT back to DALL-E 2 as follows.

![](https://hackster.imgix.net/uploads/attachments/1606011/image_eljUhGhdUP.png?auto=compress%2Cformat&w=740&h=555&fit=max)

The Dall-E2 creates an image from the prompt sent by the GPT.

### **Display**

![](https://hackster.imgix.net/uploads/attachments/1606012/image_6Lus2zXAHe.png?auto=compress%2Cformat&w=740&h=555&fit=max)

Send the data to the Client as you did in the process above to display the image created by the Dall-E2!

### **Card Description**

```plaintext
# Card Description
s.send(f"Card Description".encode())
```

After displaying the image, send the string Card Description to the server. (Client)

```plaintext
done = False
sent = False
while True:
    data = connectionSock.recv(100)
    if not data:
        continue
    print(f"received={data}")
    # if client sent OK all is done
    if data == b"OK":
        done = True
    if not sent:
        ret = connectionSock.send(answer.encode())
        sent = True
    # quit when client received my response
    if done:
        connectionSock.close()
        break
while True:
    data = connectionSock.recv(100)
    if not data:
        continue
    print(f"received={data}")
    # if client sent OK all is done
    if data == b"Reset":
        done = True
    break
```

When the server receives the "Card Description" message, it sends the description of the card it received through the Chat GPT to the client again

![](https://hackster.imgix.net/uploads/attachments/1606013/image_y5zxbuz5sh.png?auto=compress%2Cformat&w=740&h=555&fit=max)

The Client will display a description of the card.

### **Complete**

[Embedded media](https://www.youtube.com/embed/63N3rUuBgTM?rel=0)

It's a motion video! Every morning, I use this tarot card to predict my luck.It's amazing that AI can do these things now!

---

Source: https://maker.wiznet.io/Alan/projects/choice%21-check-your-fortune-with-tarot-cards-%21/
