Hardware components | ||||||
![]() |
| × | 1 | |||
| × | 1 | ||||
![]() |
| × | 1 | |||
Software apps and online services | ||||||
![]() |
| |||||
![]() |
| |||||
Hand tools and fabrication machines | ||||||
![]() |
|
This project is made by my daughter Sashrika and I am sharing on her behalf.
She made this cute 3D printed box stuffed with Wio terminal and NeoPixel ring. She wanted to give a tech gadget to her mother on this year Mother's day and came up with this idea. She can share pictures and messages to the box from anywhere around the world. When the box receives any picture, the ring turns pink and buzz to notify her mother.
Watch the demo video below.
from PIL import Image
import array
import os
from github import Github
from paho.mqtt import client as mqtt_client
import random
import time
g = Github("Your_github_personal_token")
repo = g.get_user().get_repo("your_public_repo")
broker_address="broker.hivemq.com"
client_id = f'python-mqtt-{random.randint(0, 1000)}'
port = 1883
topic = "your_topic"
fname = input("Enter the filename to upload")
generate_file = "%s.bmp" %(time.strftime("%Y%m%d-%H%M%S"))
print(generate_file)
def rgb332(r, g, b):
r = r >> 5
g = g >> 5
b = b >> 6
c = r << 5 | g << 2 | b
return [c]
def convert(filename):
#converted_filename = "%s.bmp" %(filename)
converted_filename = generate_file
#size = [320,240]
size = [288,216]
Image.open(filename).resize(size=size).save(converted_filename)
im = Image.open(converted_filename)
width, height = im.size
v = [rgb332(r, g, b) for (r, g, b) in im.getdata()]
b = bytearray()
b.append(width & 0xff)
b.append(width >> 8)
b.append(height & 0xff)
b.append(height >> 8)
for pair in v:
for i in pair:
b.append(i)
f = open(converted_filename, "wb")
f.write(b)
f.close()
print("done!")
def upload():
with open(generate_file, 'rb') as file:
content = file.read()
r = repo.create_file("assets/%s" %(generate_file), "committing files", content, branch="main")
print(r)
published = False
def postMqtt(message):
global published
def on_connect(client, userdata, flags, rc):
global published
if rc == 0:
print("Connected to MQTT Broker!")
client.publish(topic, message)
print("published")
time.sleep(1)
published = True
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
client.on_connect = on_connect
client.connect(broker_address, port)
client.loop_start()
while not published:
time.sleep(1)
print(".")
def cleanRepo():
contents = repo.get_contents("assets")
print(contents)
for file in contents:
content = repo.get_contents(file.path)
repo.delete_file(content.path, "remove", branch="main")
if __name__ == "__main__":
convert(fname)
upload()
postMqtt(generate_file)
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIN D0 // On Trinket or Gemma, suggest changing this to 1
// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 12 // Popular NeoPixel ring size
// #include <rpcWiFi.h>
// #include <WiFiClientSecure.h>
// #include <HTTPClient.h>
#include <rpcWiFiClientSecure.h>
#include <PubSubClient.h>
const char *ssid = "WIFI_SSID";
const char *password = "WIFI_PASSWORD";
const char *ID = "Wio-Terminal-Client"; // Name of our device, must be unique
const char *TOPIC = "your_topic"; // Topic to subcribe to
const char *mqttserver = "broker.hivemq.com"; // Server URL
WiFiClientSecure client;
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
#include "TFT_eSPI.h"
#include "Seeed_FS.h" //Including SD card library
#include "RawImage.h" //Including image processing library
TFT_eSPI tft;
File myFile;
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
uint8_t brightness = 50;
void setup() {
//Initialise SD card
Serial.begin(115200);
pinMode(WIO_KEY_A, INPUT_PULLUP);
pinMode(WIO_5S_PRESS, INPUT_PULLUP);
pinMode(WIO_5S_UP, INPUT_PULLUP);
pinMode(WIO_5S_DOWN, INPUT_PULLUP);
pinMode(WIO_BUZZER, OUTPUT);
pixels.begin();
pixels.setBrightness(brightness);
setRingColor(255, 208, 0);
while (!SD.begin(SDCARD_SS_PIN, SDCARD_SPI)) {
Serial.println("Card Mount Failed");
return;
}
Serial.println("SD card mounted");
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
Serial.println("No SD card attached");
return;
}
Serial.println("SD card attached");
tft.begin();
tft.setRotation(3);
int dotCounter = 0;
while (WiFi.status() != WL_CONNECTED)
{
if(dotCounter%10 == 0){
tft.fillScreen(TFT_BLACK);
tft.setCursor(100,110);
}
tft.print(".");
dotCounter ++;
WiFi.begin(ssid, password);
}
tft.fillScreen(TFT_BLACK);
tft.setCursor(100,110);
tft.print("IP:");
tft.print(WiFi.localIP());
delay(1000);
delay(1000);
drawImage<uint8_t>("bg.bmp", 0, 0); //Display this 8-bit image in sd card from (0, 0)
mqttClient.setServer(mqttserver, 1883);
mqttClient.setCallback(callback);
setRingColor(255, 255, 255);
}
String url = "web.bmp";
void loop() {
if(digitalRead(WIO_5S_PRESS) == LOW){
setRingColor(255,255,255);
}
if(digitalRead(WIO_5S_UP) == LOW){
if(brightness < 250){
brightness = brightness + 25;
pixels.setBrightness(brightness);
setRingColor(255, 255, 255);
Serial.println(brightness);
}
}
if(digitalRead(WIO_5S_DOWN) == LOW){
if(brightness > 25){
brightness = brightness - 25;
pixels.setBrightness(brightness);
setRingColor(255, 255, 255);
Serial.println(brightness);
}
}
if (digitalRead(WIO_KEY_A) == LOW) {
Serial.println("A Key pressed");
//buzz();
//rainbow(10);
Serial.println("End of rainbow");
downloadImage("bg.bmp");
}
if (!mqttClient.connected()) {
reconnect();
}
mqttClient.loop();
}
void downloadImage(String filename){
if(&client) {
Serial.printf("RTL8720 Firmware Version: %s\n", rpc_system_version());
char* server = "raw.githubusercontent.com"; // Server URL
if (!client.connect(server, 443))
Serial.println("Connection failed!");
else {
Serial.println("Connected to server!");
client.println("GET your_github_url_path/"+ filename +" HTTP/1.1");
client.println("Host: "+ String(server));
client.println("User-Agent: wio");
client.println("Connection: close");
client.println();
long len = -1;
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
while (client.connected()) {
//Serial.print(".");
String line = client.readStringUntil('\n');
//Serial.println(line);
if (line.startsWith("Content-Length:")) {
len = line.substring(15).toInt();
}
if (line == "\r") {
Serial.println("headers received");
break;
}
}
Serial.printf("Content-Length = %d \n", len);
if(SD.exists("web.bmp")){
SD.remove("web.bmp");
Serial.println("removed old file");
}
File myFile = SD.open("web.bmp", FILE_WRITE); //Writing Mode
if (myFile) {
uint8_t buff[128];
while (client.connected() && (len > 0 || len == -1)) {
//while ((len > 0 || len == -1)) {
size_t size = client.available();
Serial.printf("size %i\n", size);
if (size>0) {
int c = client.readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
//int c = client.readBytes(buff, ((size > 128) ? 128 : size));
myFile.write(buff, c);
if (len > 0) {
len -= c;
}
}else {
break;
}
//delay(1);
// Serial.printf("bytes left %i\n", len);
}
myFile.flush();
Serial.printf("Written file size = %d\n", myFile.size());
myFile.close();
Serial.println("file closed.");
tft.fillScreen(TFT_ORANGE);
delay(1000);
drawImage<uint8_t>("web.bmp", 16, 12);
}else{
Serial.println("error opening file");
}
client.stop();
Serial.println("stopping client");
}
}else{
Serial.println("Unable to create client");
}
}
void buzz() {
analogWrite(WIO_BUZZER, 128);
delay(1000);
analogWrite(WIO_BUZZER, 0);
delay(1000);
}
void blink(){
pixels.clear();
for(int i=0; i<NUMPIXELS; i++) { // For each pixel...
// pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
// Here we're using a moderately bright green color:
pixels.setPixelColor(i, pixels.Color(0, 150, 0));
pixels.show(); // Send the updated pixel colors to the hardware.
delay(200); // Pause before next pass through loop
}
delay(1000);
pixels.clear();
pixels.show();
}
void setRingColor(uint8_t r, uint8_t g, uint8_t b){
pixels.clear();
for(int i=0; i<NUMPIXELS; i++) { // For each pixel...
pixels.setPixelColor(i, pixels.Color(r, g, b));
pixels.show(); // Send the updated pixel colors to the hardware.
delay(200); // Pause before next pass through loop
}
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
//url = String((char*)payload);
char message[length];
for (int i=0;i<length;i++) {
//Serial.print((char)payload[i]);
message[i] = (char)payload[i];
}
Serial.println(String(message));
downloadImage(String(message));
setRingColor(238, 0, 255);
buzz();
}
void reconnect() {
// Loop until we're reconnected
while (!mqttClient.connected())
{
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (mqttClient.connect(ID)) {
Serial.println("connected to MQTT");
// Once connected, publish an announcement...
//mqttClient.publish(TOPIC, "{\"message\": \"Wio Terminal is connected!\"}");
mqttClient.subscribe(TOPIC);
}
else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void rainbow(int wait) {
// Hue of first pixel runs 5 complete loops through the color wheel.
// Color wheel has a range of 65536 but it's OK if we roll over, so
// just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
// means we'll make 5*65536/256 = 1280 passes through this outer loop:
for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
for(int i=0; i<pixels.numPixels(); i++) { // For each pixel in strip...
// Offset pixel hue by an amount to make one full revolution of the
// color wheel (range of 65536) along the length of the strip
// (strip.numPixels() steps):
int pixelHue = firstPixelHue + (i * 65536L / pixels.numPixels());
// strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
// optionally add saturation and value (brightness) (each 0 to 255).
// Here we're using just the single-argument hue variant. The result
// is passed through strip.gamma32() to provide 'truer' colors
// before assigning to each pixel:
pixels.setPixelColor(i, pixels.gamma32(pixels.ColorHSV(pixelHue)));
}
pixels.show(); // Update strip with new contents
delay(wait); // Pause for a moment
}
pixels.clear();
pixels.show();
}
4 projects • 32 followers
I am a 9th grade student, passionate about technology.
34 projects • 184 followers
Hacker and Maker driven by passion. Ambassador at Edge Impulse and Balena. Follow me on Twitter @_mithundas
Comments
Please log in or sign up to comment.