Close

Complete!!

A project log for WoW ! Enjoy the current weather with Picasso's pai

It's a fun project to get the weather in real time with Picasso's interesting paintings!

alanAlan 04/20/2023 at 15:040 Comments

Hello everyone! I would like to share an interesting project that I've been working on!

This is almost everything I saw in the thumbnail. I will briefly explain the project.

My current project is very similar to the one I created before. Therefore, please refer to my previous project for more detailed information.

Chat GPT API + Youtube Comment + Weather

Here's a simple flowchart! I only changed the LCD configuration from my previous project. I will bring some parts that I used in my previous project, such as web crawling and Chat GPT, albeit in a simplified manner.

Web Crawling

First of all, it's weather information, and I want to read it in a fun way as the weather caster tells me, not just weather information. So I decided to read it using the GPT API. GPT does not currently support real-time data services. So I decided to read it on Naver as WebCrawling.It started implementing in a Python environment that is relatively light and easy to implement.

from bs4 import BeautifulSoup
def getweather() :
    html = requests.get('http://search.naver.com/search.naver?query=수내+날씨')
    soup = BeautifulSoup(html.text, 'html.parser')
    global weather
    weather = ''

    address = "Bundang Sunae"
    weather += address + '*'

    weather_data = soup.find('div', {'class': 'weather_info'})

    # Current Temperature
    temperature = (str(weather_data.find('div', {'class': 'temperature_text'}).text.strip()[5:])[:-1])
    weather += temperature + '*'

    # Weather Status
    weatherStatus = weather_data.find('span', {'class': 'weather before_slash'}).text

    if weatherStatus == '맑음':
        weatherPrint = 'Sunny'
    elif '흐림':
        weatherPrint = 'Cloud'

    weather += weatherPrint

 WebCrawling can be done simply with a package called BeautifulSoup.

<Screen that appears when searching for weather in the water on the Naver site>

Let me deal with Crawling briefly.

In the script, temperature was read from temperature_text.

And weather was read in the span class of weather before_slash.

I want to read it in English, but I couldn't find it, so I just hardcoded it...And when you run this, it will look like the following.

It outputs temperature and weather like this.

Chat GPT

I will convert it to Chat GPT and get the data.Chat GPT 3.5 API was officially released recently, making it easy to implement.Chat GPT requires API Key just like YouTube.

def Chat_GPT(api_key, query):
    global answer

    openai.api_key = api_key

    model = "gpt-3.5-turbo"

    messages = [
        {
            "role": "system",
            "content": "You are a very creative and interesting writer."
        },
        {
            "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.

query = "The current weather is very {} with {} degrees. Create a creative story in this situation. No more than two sentences.".format(weather,temperature)
print(query)

Chat_GPT(api_key,query)

And in the main code, I send the information obtained from web crawling to GPT by inputting it into the prompt.

Dall-E-2

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

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.

Chat_GPT(api_key,query)
answer = "Picasso's painting of the story. '{}'".format(answer)
print(answer)
dall_e2(answer)

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

W5100S Ethernet

Now we need to send the received data to the Pico board via Ethernet.

WIZnet/RP2040-HAT-CircuitPython

The library using the Wiznet Ethernet Chip on the RP2040, Pico's MCU, is located at the link above.This library allows you to simply attach W5100S to Pico.

NEXT

Alright, we have finished coding on the server side. Now we need to code on the client side, which is the W5100S-EVB-Pico.

First of all, I worked in the CircuitPython environment. Therefore, RP2040 needs to be set up for the CircuitPython environment.

Circuitpython Raspberry pi Pico

You can easily set up the RP2040 for CircuitPython environment by downloading the UF2 file from the official website and putting it into a folder.

And you can see the program execution process through the serial terminal.

Client W5100S Ethernet

Now it's time for the Ethernet code on the client side.

##SPI0
SPI0_SCK = board.GP18
SPI0_TX = board.GP19
SPI0_RX = board.GP16
SPI0_CSn = board.GP17

##reset
W5x00_RSTn = board.GP20

Make sure to set the pins according to the situation.

print("Wiznet5k Loopback Test (DHCP)")
# Setup your network configuration below
# random MAC, later should change this value on your vendor ID
MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05)
IP_ADDRESS = (192, 168, 0, 50)
SUBNET_MASK = (255, 255, 255, 0)
GATEWAY_ADDRESS = (192, 168, 0, 1)
DNS_SERVER = (8, 8, 8, 8)
led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT
ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT

Make sure to configure the settings according to your own IP address.

# Initialize ethernet interface without DHCP
eth = WIZNET5K(spi_bus, cs, is_dhcp=False, mac=MY_MAC, debug=False)
# Set network configuration
eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)

Configure the settings such as whether to use DHCP or not correctly.

Anyway, all the detailed instructions are available on the WIZnet Git that I shared earlier, so you can follow them.

QVGA ILI9341 2.2 TFT SPI 240x320

I referred to the ILI9341 section in the Git I shared earlier. It is explained in detail and is easy to follow, so you can easily implement it.

CircuitPython-ILI9341-Examples

It's educ8s' Git, and since there was no information about the license, you used it. If there are any issues, you can take it down immediately.

Saving the data in BMP format and displaying it on the LCD.

bmp_data = bytearray(buf)
with open ("test.bmp", "wb") as f:
f.write(bmp_data)
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)

Now all that's left is to display the data received from the server on the LCD!

Congratulations, you've completed the project!

Complete!!

Complete!!

That's great! I set this awesome image to change every hour.

I can imagine how cool it would be to apply this device at exhibitions or galleries.Of course, you should put the LCD in a frame to make it bigger and more majestic!

Great! Feel free to share a video of the project in action to show how it works!

Sounds great! I look forward to hearing about your next project!

Discussions