Little BMO wannabe robot featuring 4 buttons and a unicorn hat from Pimodoro (RGB fancy neopixel stuff) on an esp8266 running micropython.
Last active
January 20, 2018 22:54
-
-
Save murilopolese/af06c26092db129f8bd8ea08575dc6bb to your computer and use it in GitHub Desktop.
BeeMu
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from machine import Pin, Timer | |
from neopixel import NeoPixel | |
from time import sleep | |
from urandom import getrandbits as randbits | |
import math | |
pin = Pin(12, Pin.OUT) | |
np = NeoPixel(pin, 64) | |
LED = [ | |
[63, 48, 47, 32, 31, 16, 15, 0], | |
[62, 49, 46, 33, 30, 17, 14, 1], | |
[61, 50, 45, 34, 29, 18, 13, 2], | |
[60, 51, 44, 35, 28, 19, 12, 3], | |
[59, 52, 43, 36, 27, 20, 11, 4], | |
[58, 53, 42, 37, 26, 21, 10, 5], | |
[57, 54, 41, 38, 25, 22, 9, 6], | |
[56, 55, 40, 39, 24, 23, 8, 7] | |
] | |
whiteButton = Pin(14, Pin.IN) | |
redButton = Pin(4, Pin.IN) | |
greenButton = Pin(5, Pin.IN) | |
blueButton = Pin(16, Pin.IN) | |
buttonHandler = False | |
whitePressed = False | |
redPressed = False | |
greenPressed = False | |
bluePressed = False | |
def random(n): | |
return randbits(10) % n | |
def setPixel(x, y, color): | |
np[LED[y][x]] = color | |
def render(self): | |
np.write() | |
def clear(color=(0,0,0)): | |
for y in range(0, 8): | |
for x in range(0, 8): | |
setPixel(x, y, color) | |
def onEvent(event, value=0): | |
return value | |
def whiteCheck(): | |
global whitePressed | |
global onEvent | |
if not whitePressed and whiteButton.value() == 1: | |
onEvent('whitePressed', 1) | |
whitePressed = (whiteButton.value() == 1) | |
whiteTimer = Timer(-1) | |
whiteTimer.init(period=100, mode=Timer.PERIODIC, callback=lambda t:whiteCheck()) | |
def redCheck(): | |
global redPressed | |
global onEvent | |
if not redPressed and redButton.value() == 1: | |
onEvent('redPressed', 1) | |
redPressed = (redButton.value() == 1) | |
redTimer = Timer(-1) | |
redTimer.init(period=100, mode=Timer.PERIODIC, callback=lambda t:redCheck()) | |
def greenCheck(): | |
global greenPressed | |
global onEvent | |
if not greenPressed and greenButton.value() == 1: | |
onEvent('greenPressed', 1) | |
greenPressed = (greenButton.value() == 1) | |
greenTimer = Timer(-1) | |
greenTimer.init(period=100, mode=Timer.PERIODIC, callback=lambda t:greenCheck()) | |
def blueCheck(): | |
global bluePressed | |
global onEvent | |
if not bluePressed and blueButton.value() == 1: | |
onEvent('bluePressed', 1) | |
bluePressed = (blueButton.value() == 1) | |
blueTimer = Timer(-1) | |
blueTimer.init(period=100, mode=Timer.PERIODIC, callback=lambda t:blueCheck()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Boot | |
print('Booted') | |
import network | |
import webrepl | |
sta_if = network.WLAN(network.STA_IF) | |
ap_if = network.WLAN(network.AP_IF) | |
if sta_if.active() and !sta_if.isconnected(): | |
sta_if.active(False) | |
ap_if.active(True) | |
ap_if.config(essid='( ^ . ^)/', authmode=network.AUTH_WPA_WPA2_PSK, password="bananabanana") | |
else: | |
webrepl.start() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Game(object): | |
def __init__(self, state, infinite_board = True): | |
self.state = state | |
self.width = state.width | |
self.height = state.height | |
self.infinite_board = infinite_board | |
def step(self, count = 1): | |
for generation in range(count): | |
new_board = [[False] * self.width for row in range(self.height)] | |
for y, row in enumerate(self.state.board): | |
for x, cell in enumerate(row): | |
neighbours = self.neighbours(x, y) | |
previous_state = self.state.board[y][x] | |
should_live = neighbours == 3 or (neighbours == 2 and previous_state == True) | |
new_board[y][x] = should_live | |
self.state.board = new_board | |
def neighbours(self, x, y): | |
count = 0 | |
for hor in [-1, 0, 1]: | |
for ver in [-1, 0, 1]: | |
if not hor == ver == 0 and (self.infinite_board == True or (0 <= x + hor < self.width and 0 <= y + ver < self.height)): | |
count += self.state.board[(y + ver) % self.height][(x + hor) % self.width] | |
return count | |
# def display(self): | |
# return self.state.display() | |
class State(object): | |
def __init__(self, positions, x, y, width, height): | |
active_cells = [] | |
for y, row in enumerate(positions.split('\n')): | |
for x, cell in enumerate(row.strip()): | |
if cell == 'o': | |
active_cells.append((x,y)) | |
board = [[False] * width for row in range(height)] | |
for cell in active_cells: | |
board[cell[1] + y][cell[0] + x] = True | |
self.board = board | |
self.width = width | |
self.height = height | |
# def display(self): | |
# | |
# output = '' | |
# | |
# for y, row in enumerate(self.board): | |
# for x, cell in enumerate(row): | |
# if self.board[y][x]: | |
# output += ' o' | |
# else: | |
# output += ' .' | |
# output += '\n' | |
# | |
# return output | |
glider = """oo. | |
o.o | |
o..""" | |
my_game = Game(State(glider, x = 3, y = 5, width = 8, height = 8)) | |
step = 0 | |
while True: | |
step = step + 1 | |
my_game.step(step) | |
for y, row in enumerate(my_game.state.board): | |
for x, value in enumerate(row): | |
if value: | |
setPixel(x, y, (0, 70, 70)) | |
else: | |
setPixel(x, y, (0, 0, 0)) | |
np.write() | |
sleep(0.05) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Arduino.h> | |
#include <ESP8266WiFi.h> | |
#include <ESP8266WiFiMulti.h> | |
#include <WebSocketsServer.h> | |
#include <ESP8266WebServer.h> | |
#include <DNSServer.h> | |
#include <Hash.h> | |
#include "editor.h" | |
#include <Adafruit_NeoPixel.h> | |
#define PIN 12 | |
#define NUMPIXELS 64 | |
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800); | |
#define USE_SERIAL Serial | |
const byte DNS_PORT = 53; | |
DNSServer dnsServer; | |
ESP8266WebServer server = ESP8266WebServer(80); | |
WebSocketsServer webSocket = WebSocketsServer(81); | |
IPAddress apIP(192, 168, 4, 1); | |
IPAddress netMsk(255, 255, 255, 0); | |
const char *ssid = "BeeMu"; | |
const char *password = "satan666"; | |
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { | |
switch(type) { | |
case WStype_DISCONNECTED: | |
USE_SERIAL.printf("[%u] Disconnected!\n", num); | |
break; | |
case WStype_CONNECTED: { | |
IPAddress ip = webSocket.remoteIP(num); | |
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); | |
// send message to client | |
webSocket.sendTXT(num, "Connected"); | |
} | |
break; | |
case WStype_TEXT: | |
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); | |
String str((char*)payload); | |
parse_instructions(str); | |
break; | |
} | |
} | |
int selectedPixel = 0; | |
int redValue = 0; | |
int blueValue = 0; | |
int greenValue = 0; | |
void parse_instructions(String str) | |
{ | |
int delimiter_pos = str.indexOf(" "); | |
String command = str.substring(0, delimiter_pos); // command | |
String params = str.substring(delimiter_pos+1); // parameter | |
if(command.equals("selectPixel")) { | |
selectedPixel = params.toInt(); | |
} | |
if(command.equals("setRed")) { | |
redValue = params.toInt(); | |
} | |
if(command.equals("setBlue")) { | |
blueValue = params.toInt(); | |
} | |
if(command.equals("setGreen")) { | |
greenValue = params.toInt(); | |
} | |
if(command.equals("writePixel")) { | |
pixels.setPixelColor(selectedPixel, pixels.Color(redValue,greenValue,blueValue)); | |
} | |
if(command.equals("showPixels")) { | |
pixels.show(); | |
} | |
} | |
void handleRoot() { | |
server.send(200, "text/html", editor); | |
} | |
void setup() { | |
USE_SERIAL.begin(115200); | |
USE_SERIAL.println(); | |
USE_SERIAL.print("Setting soft-AP configuration: "); | |
USE_SERIAL.println(WiFi.softAPConfig(apIP, apIP, netMsk) ? "Ready" : "Failed!"); | |
USE_SERIAL.print("Setting soft-AP"); | |
USE_SERIAL.print(":"); | |
USE_SERIAL.println(WiFi.softAP(ssid, password) ? "Ready" : "Failed!"); | |
delay(500); | |
USE_SERIAL.print("AP IP address: "); | |
USE_SERIAL.println(WiFi.softAPIP()); | |
dnsServer.setErrorReplyCode(DNSReplyCode::NoError); | |
dnsServer.start(DNS_PORT, "*", apIP); | |
USE_SERIAL.print("DNS Server started"); | |
webSocket.begin(); | |
webSocket.onEvent(webSocketEvent); | |
USE_SERIAL.println("WebSocket server started"); | |
server.on("/", handleRoot); | |
server.onNotFound(handleRoot); | |
server.begin(); | |
USE_SERIAL.println("HTTP server started"); | |
pixels.begin(); | |
USE_SERIAL.println("Pixels started"); | |
} | |
void loop() { | |
dnsServer.processNextRequest(); | |
webSocket.loop(); | |
server.handleClient(); | |
delay(20); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
white = (30, 30, 30) | |
black = (0, 0, 0) | |
batLength = 3 | |
batPos = 2 | |
ballX = 3 | |
ballY = 3 | |
ballVx = 1 | |
ballVy = 1 | |
btnPressed = False | |
t = 0 | |
def drawBat(color): | |
for i in range(0, batLength): | |
setPixel(0, batPos+i, color) | |
def drawBall(color): | |
setPixel(ballX, ballY, color) | |
clear() | |
render() | |
while True: | |
drawBat(black) | |
drawBall(black) | |
if btnPressed != True: | |
if whitePressed == True and batPos > 0: | |
batPos = batPos - 1 | |
btnPressed = True | |
if bluePressed == True and batPos < (8 - batLength): | |
batPos = batPos + 1 | |
btnPressed = True | |
else: | |
if whitePressed == False and bluePressed == False: | |
btnPressed = False | |
if ballX == 7: | |
ballVx = ballVx * -1 | |
if ballX == 0: | |
print('game over') | |
break | |
if ballX == 1 and ballY <= batPos+batLength and ballY >= batPos: | |
ballVx = ballVx * -1 | |
if ballY == 7 or ballY == 0: | |
ballVy = ballVy * -1 | |
if t % 5 == 0: | |
ballX = ballX + ballVx | |
ballY = ballY + ballVy | |
drawBat(white) | |
drawBall(white) | |
render() | |
t = t + 1 | |
sleep(0.1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment