Running Snap! Project locally on raspberry pi with gpio

Pretty sure you can use a python web server, because you can make it listen to requests, and then you can control the pins directly in python. I think that might be the best solution right now.

This sounds like a great project. I'm not sure whether it would be suitable for emulating PLC programming, but we're currently using a Raspberry Pi Model 4b running Snap! communicating with a Raspberry Pi Pico microcontroller running MicroBlocks (https://microblocks.fun/). @jmaloney developed a library of Snap! blocks (Micro:Bridge) that enables Snap! to control physical objects using the Pico microcontroller. The Pico is only about five dollars and about the size of a stick of gum, so it works very well for our applications. This can all be run locally if necessary.

If this sounds like something that would be useful for your application, let us know and we can provide more details.

Thanks @glenbull , I think I may have been reading about the early days of your project.

This could definitely work to control i/o but I was hoping to run the snap! Pages on the pi so it can be a stand alone unit. The students program will be in an actual PLC hooked up to this pi through some interface relays etc. with either a mouse or touch screen to click buttons on the simulator. Beats building a bunch of pump systems or conveyor systems for them to hook up to.

Scratch3 offline has gpio functions now so I could use that I suppose, I was hoping to take advantage of the larger stage size in snap! But I’m not yet experienced with http and general web stuff. Good time to learn! :+1:

For us, Snap! is like Scratch on steroids. Both are good, but have different intended audiences and purposes. Snap! is very extensible, and we have gotten a lot of support from the Snap! community in developing extensions.

We would love to hear more as your project develops and will look forward to following its progress.

Scratch3 may be a viable route but my experience of it is it really needs a Pi4 with at least 2GB of RAM (I tried it on a 4GB one)

What I/O requirements do you envisage for your project? Are you just controlling relays or are you wanting to receive data as well?

I’m wanting to receive gpio inputs as well but in a pinch or to get started I toyed with the idea of just sending key presses from a python script, since my first simulation is running on ‘when key pressed’ blocks for testing purposes.

The trick was definitely getting gpio out to work.
I have set up a little web server using flask in python (not my own work) and that is working ok to control gpio from a web page, so I will now look at modifying it for my purposes. Just reading up on http to see what all the headers and data back and forth are.

Pi 4s are as rare as hens teeth at the moment.
Sorry if I drop off, I’m in Australia and we are about 10 hours ahead of UK. Let me know if you want me to send you the winning Loto numbers…. Is that how it works?

Soooo…

I’ve got a little web server up and running and controlling the gpio pin11.

I’ve just set it to receive http://pi ip address:port/11on or /11off and I can control it from chrome browser locally and over LAN. :sweat_smile:

The problem I have is when I try to put this in the url block minus http:// i get some gibberish and a 400 error http wrong version. I’m running offline snap!. My server reports v1.1 when it replies correctly to chrome. Is this obvious to anybody? Is http/1.1 still suitable? Cheers

Can you enable browser dev tools and see if any clues in the console log?

Are you running Snap! directly from a local folder or are you running a local webserver to serve files from your local folder?

Can you upload your webserver code (either here or elsewhere) and I'll try it out at my end?

I will try dev tools.

At this point I am running snap! offline from a folder on windows10 laptop on same network as pi. This python script that my Mate ChatGPT helped me write uses the built in webserver functionality of python 3 rather than the flask approach I started with. It actually did a really good job except for a few indexing errors that I had to debug.

import RPi.GPIO as GPIO
from http.server import BaseHTTPRequestHandler, HTTPServer

GPIO.setmode(GPIO.BOARD)
GPIO.setup([11, 12, 13, 15, 16, 18], GPIO.OUT)
#GPIO.setup(11, GPIO.OUT)

class RequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        path = self.path[1:]  # Remove leading '/'
        #print(str(path[:2]))
        if  len(path) < 4:
            print('length issue')
            self.send_error(404)
            return
        elif not path[:-3].isdigit():
            print('digit issue ' + str(path[:-3]))
            self.send_error(404)
            return
        elif int(path[:2]) not in [11, 12, 13, 15, 16, 18]:
            self.send_error(404)
            return
        pin = int(path[:2])
        print(pin)
        state = path[2:4] == "on"
        print (path[2:4])
        print(state)

        GPIO.output(pin, state)

        self.send_response(200)
        self.send_header("Content-type", "text/plain")
        self.end_headers()
        self.wfile.write(b"GPIO state set")

if __name__ == '__main__':
    server_address = ('', 8000)
    httpd = HTTPServer(server_address, RequestHandler)
    print('Server started')
    httpd.serve_forever()

I think I will change this in future to just recieve 8 bits to represent the outputs so I can update all outputs with one GET.

thanks @cymplecy looks like the url block is sending a https: request and I am set up for http: only?

Does anyone know an easy way to make snap! just send http? I really won't need encryption for local control.

This may shade some lights...

It's a good job @dardoro has a better memory than me :slight_smile:

Thanks @dardoro . I’ll try Firefox and see if the result is any better.

I won’t get a chance to do it tonight but maybe in the morning.

I'm having a play to see if using MQTT via websockets can bypass the issue.

Are you planning on running snap locally on the Pi eventually or are you going to stick to running it from a PC?

Hi @cymplecy ,

Don’t worry about it, it’s working!

So to clarify I can send url commands in both chrome and Firefox.

I had read somewhere that url block adds http:// to the start of whatever is entered. It seems as though this may be incorrect or perhaps I was reading about someone’s custom block. But by typing the whole url http://192.168.x.x:8000/11on or /11off it works with that web server script. Sorry for my noob late night brain not trying that straight away.

I’m thinking I will modify this server script to accept 8 binary values to represent 8 outputs in one go in order to save traffic and hopefully keep response speed usable.

For inputs I’ll aim to generate key presses to represent gpio inputs while data is being regularly received? (Watchdog) and stop once output traffic stops. It’s pretty rough but should stop the key presses entering text in other programs once the page is closed. Accepting ideas on a better way but my python and web skills are still beginner.
Wait! Could the server just respond to every command with the values of inputs? :face_with_monocle:

This is the first simulation I have done for an industrial roller door if you want
to have a look.
Roller Door Simulator

Looks very nice :slight_smile:

Hi All,

So Outputs are all working great. I'm sending 8 bits representing the values and iterating over them to set output pins.

Does anyone know what returned info should show up in the URL Blocks reporting bubble?
The documentation says it is the content of a web page but mine is always blank.
I was returning 200 and plain text 'gpio pins set'. I changed to send HTML Title and body which shows in browser but nothing in reporting bubble.
Thanks for everyones help to get this far.

Don't worry, I sorted it out, as mentioned elsewhere in the forum it was the CORS Issue (Cross-Origin Resource Sharing)
I will post the working server script once Inputs are working.

why is this flagged???