HW Requirements

Wio-link board

WiFi connected PC/Laptop + Router

Software tools

Anaconda (Py3.4+, ampy, esptools), Visual Studio, PuTTY, httplib header, Any text editor, Chrome browser on PC

Demonstration of BrainStem Customised WebGL game

https://www.gpupowered.org/brainstem/game.html

Introduction

The chrome browser ships with a simple jumper game that can be controlled with a single key (space bar). But, it needs to be played on the laptop keyboard that takes away the freedom and fun. What can be done in the days of the lockdown ?

The Wio-link bare board has a single CONFIG button on it. 

 → A great pairing to create a game, to be played free of the laptop or internet !

Note — The steps below will destroy the shipped firmware on wiolink board.

Design

The system consists of 3 parts:

  1. The Wio-link acting as a WiFi-remote, running micropython (code below)
  2. The Server running on the Laptop, connected with wio on local network, running a server either Python or C++ (code below)
  3. The Chrome Browser on the Laptop, running chrome:\\dino

Programming the Wio-link (as Controller)

Without the connector, the board has just 2 buttons - RESET, and CONFIG. Left with no choice than to choose the CONFIG button.
For the USB serial port to come up install the serial driver, referred in the notes in references below.
Finding the GPIO config for the CONFIG button took a while. It took just some more extra time to figure out it was pulled high, looking at the Schematic PDF on the Wiolink site.
The rest was easy to figure out.

The board is programmed to send data in JSON via the micropython json library.


Micropython code (for Wiolink as Station)

https://gist.github.com/prabindh/f8bac87189949e877f97a26666d062ab

import network
import urequests
import ujson
import machine
import time

def do_post(url, data):

    headers = {'Content-Type': 'application/json'}

    r = urequests.post(url, data=data, headers=headers)
    #print(r)
    results = r.json()
    #print(results)
    
def do_connect_as_ap(ap_ssid, ap_pwd):
    ap = network.WLAN(network.AP_IF)
    ap.active(True)
    sta_if = network.WLAN(network.STA_IF)
    sta_if.active(False)
    ap.config(essid=ap_ssid, password=ap_pwd)

    while ap.active() == False:
      pass
    print('network config:', ap.ifconfig())
       
def do_connect_as_station(sta_ssid, sta_pwd):
    ap = network.WLAN(network.AP_IF)
    ap.active(False)

    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect(sta_ssid, sta_pwd)
        while not sta_if.isconnected():
            pass
    print('network config:', sta_if.ifconfig())


### Main config parameters
kelvi_host_ip = "http://10.41.2.37:8000/"
WHICH_PIN = 0 ## GPIO 0 - config button in wiolink
key_val = 0
self_id = 100 # Some unique id for this station
ap_ssid = "MicroPython-abba"
ap_pwd = "abba"
sta_ssid = ""
sta_pwd = ""

# Connect to target host
do_connect_as_station(sta_ssid, sta_pwd);

data = {}
data["station-id"] = str(self_id)
data["counter"] = 0

# DEMO - Loop for 50 presses at this time
press_count = 0
while press_count < 50:
    time.sleep_ms(50)
    key_val = machine.Pin(WHICH_PIN).value()

    if int(key_val) == 0: # default pulled high
        press_count = press_count + 1
        
        data["value"] = int(1)
        data["counter"] = press_count
        json_data = ujson.dumps(data)
        # POST to target host
        try:
            do_post(kelvi_host_ip, json_data)
        except:
            print('Error posting')


Programming the PC (as Server)

Python sample code

C++ server code (alternative to Python)

https://gist.github.com/prabindh/9dee285a38c4b708811f1fce7a36eca5Operation

// Prabindh Sundareson 2020
// Age of the lockdown

#include "pch.h" // include #include "httplib.h" in this file
#include <iostream>

static httplib::Server svr;

void pressSpace()
{
    INPUT ip;
    ip.type = INPUT_KEYBOARD;
    ip.ki.time = 0;
    ip.ki.dwFlags = 0;
    ip.ki.wScan = 0; 
    
    ip.ki.wVk = VK_SPACE;

    ip.ki.dwExtraInfo = 0;
    SendInput(1, &ip, sizeof(INPUT));

    // Release...
Read more »