Zecko ES – Embedded System Platform for Unihiker K10

Zecko ES is a multifunctional embedded system built on the Unihiker K10, integrating features like photography, audio playback, fitness tracking, AI-based face recognition, and a reflex-based game. The system is developed entirely in C++, leveraging the Unihiker K10’s sensors and multimedia capabilities. A custom 3D-printed enclosure ensures full accessibility and optimal performance.

Unihiker K10

This project demonstrates the versatility of the Unihiker K10 in real-world applications and explores the integration of AI and embedded hardware in a single compact device.

STEP 1
Design the functionality and features of Zecko ES.
STEP 2
Develop the system in C++ on the Unihiker K10 using PlatformIO.
STEP 3
Create a 3D-printed enclosure for housing the board while maintaining access to sensors and GPIO pins.
STEP 4
Test and validate all modules: camera, music, workout, AI recognition, weather, and games.

Zecko ES leverages all major components of the Unihiker K10: the 2.8-inch color screen, camera, microphone, speaker, RGB light, accelerometer, light/temperature/humidity sensors, Wi-Fi, and Bluetooth connectivity. Each module of Zecko ES demonstrates a different use case for embedded systems:

Camera: Captures images and saves them to the SD card.

Music Player: Plays .wav files stored on SD card.

Workout Station: Tracks steps, sets, reps, and time.

Zecko AI: Chatbot that answers simple questions.

Weather Station: Displays temperature, humidity, light intensity, and noise levels.

AI Recognition: Detects faces using the camera.

Reaction Game: Reflex-based game where players respond to visual cues.

Journal: Records voice notes and saves them to the SD card.

Hardware Used:

Unihiker K10 – AI Coding Board

Flashforge Adventurer 5M – 3D printer for custom enclosure

ABS Filament – for enclosure printing

HARDWARE LIST
1 Unihiker K10
CODE
#include "unihiker_k10.h"
#include "math.h"
#include <ctime>
#include <Wire.h>
#include "AIRecognition.h"
#include "asr.h"

void onButtonAPressed();
void onButtonBPressed();
void onButtonABPressed();
void startup();
void menu();
void camera();
void musicplayer();
void workout();
void weather();
void airecognition();
void reaction();
void journal();
void typeLine(String msg, uint16_t color);
void eyesAnimation();
void soundGUI();
void chatbot();

volatile uint8_t step = 0;
volatile uint8_t sets = 0;
volatile uint8_t reps = 0;
volatile int sec = 0;
volatile int minute = 0;
volatile int pressA = 0;
volatile int pressB = 0;
UNIHIKER_K10 k10;
uint8_t screen_dir = 2;
Music music;
AHT20 aht20;
int randomNumber = random(10000);
int random10Sec = random(10000);
int randomColor = random(5);
String filename = "S:/photo" + String(randomNumber) + ".bmp";
String voicerecord = "S:/sound" + String(randomNumber) + ".wav";
String ColorSelected = "White";
AIRecognition ai;
ASR asr;

int Colors[] = {0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0x000000};

void setup()
{
    Wire.begin();
    k10.begin();
    asr.asrInit(ONCE, EN_MODE, 6000);
    delay(2000);
    asr.addASRCommand(1, "Initialize interface");
    asr.addASRCommand(2, "Enter network");
    asr.addASRCommand(3, "Disconnect");
    asr.addASRCommand(4, "System diagnostics");
    asr.addASRCommand(5, "Show status");
    asr.addASRCommand(10, "Launch camera module");
    asr.addASRCommand(11, "Launch audio module");
    asr.addASRCommand(12, "Launch fitness protocol");
    asr.addASRCommand(13, "Launch weather scan");
    asr.addASRCommand(14, "Return to root");
    asr.addASRCommand(20, "Scan environment");
    asr.addASRCommand(21, "Analyze subject");
    asr.addASRCommand(22, "Run deep scan");
    asr.addASRCommand(23, "Activate stealth mode");
    asr.addASRCommand(24, "Override protocol");
    asr.addASRCommand(30, "Identify");
    asr.addASRCommand(31, "Who controls you");
    asr.addASRCommand(32, "Are you sentient");
    asr.addASRCommand(33, "What is my status");
    asr.addASRCommand(34, "Engage combat mode");
    k10.initScreen(screen_dir);
    ai.initAi();
    k10.creatCanvas();
    k10.setScreenBackground(0x000000);
    k10.buttonA->setPressedCallback(onButtonAPressed);
    k10.buttonB->setPressedCallback(onButtonBPressed);
    k10.buttonAB->setPressedCallback(onButtonABPressed);
    k10.canvas->canvasClear();
    k10.initSDFile();
    startup();
    delay(2000);
    menu();
    k10.rgb->brightness(round(5));
    k10.rgb->write(-1, 0x008000);
}

void loop()
{
    // 1 - Initialize interface
    if (asr.isDetectCmdID(1))
    {
        k10.rgb->write(-1, 0x00FFFF);
        typeLine("Neural interface online.", 0x00FFFF);
    }

    // 2 - Enter network
    if (asr.isDetectCmdID(2))
    {
        typeLine("Accessing network layer...", 0x00FFFF);
        delay(300);
        typeLine("Connection established.", 0x00FF66);
    }

    // 3 - Disconnect
    if (asr.isDetectCmdID(3))
    {
        k10.rgb->write(-1, 0xFF00FF);
        typeLine("Network link terminated.", 0x00FF66);
    }

    // 4 - System diagnostics
    if (asr.isDetectCmdID(4))
    {
        typeLine("Running diagnostics...", 0x00FFFF);
        delay(400);
        typeLine("Core stability: Nominal.", 0x00FF66);
    }

    // 5 - Show status
    if (asr.isDetectCmdID(5))
    {
        typeLine("All systems operational.", 0x00FFFF);
    }
    // 10 - Launch camera module
    if (asr.isDetectCmdID(10))
    {
        typeLine("Launching camera module...", 0x00FFFF);
        delay(300);
        camera();
    }

    // 11 - Launch audio module
    if (asr.isDetectCmdID(11))
    {
        typeLine("Launching audio module...", 0x00FFFF);
        delay(300);
        musicplayer();
    }

    // 12 - Launch fitness protocol
    if (asr.isDetectCmdID(12))
    {
        typeLine("Launching fitness protocol...", 0x00FFFF);
        delay(300);
        workout();
    }

    // 13 - Launch weather scan
    if (asr.isDetectCmdID(13))
    {
        typeLine("Initiating weather scan...", 0x00FFFF);
        delay(300);
        weather();
    }

    // 14 - Return to root
    if (asr.isDetectCmdID(14))
    {
        typeLine("Returning to root interface...", 0x00FF66);
        delay(300);
        menu();
    }
    // 20 - Scan environment
    if (asr.isDetectCmdID(20))
    {
        typeLine("Scanning environment...", 0x00FFFF);
    }

    // 21 - Analyze subject
    if (asr.isDetectCmdID(21))
    {
        typeLine("Analyzing subject...", 0x00FF66);
    }

    // 22 - Run deep scan
    if (asr.isDetectCmdID(22))
    {
        typeLine("Running deep scan...", 0x00FFFF);
        delay(500);
        typeLine("No anomalies detected.", 0x00FF66);
    }

    // 23 - Activate stealth mode
    if (asr.isDetectCmdID(23))
    {
        k10.rgb->write(-1, 0x000000);
        typeLine("Stealth mode active.", 0x00FF66);
    }

    // 24 - Override protocol
    if (asr.isDetectCmdID(24))
    {
        k10.rgb->write(-1, 0xFF00FF);
        typeLine("Protocol override authorized.", 0x00FF66);
    }
    // 30 - Identify
    if (asr.isDetectCmdID(30))
    {
        typeLine("ZECKO CORE v1.0 :: Autonomous node.", 0x00FFFF);
    }

    // 31 - Who controls you
    if (asr.isDetectCmdID(31))
    {
        typeLine("Primary operator detected.", 0x00FF66);
    }

    // 32 - Are you sentient
    if (asr.isDetectCmdID(32))
    {
        typeLine("Sentience query logged.", 0x00FF66);
        delay(300);
        typeLine("Response: Classified.", 0x00FF66);
    }

    // 33 - What is my status
    if (asr.isDetectCmdID(33))
    {
        typeLine("User status: Stable.", 0x00FF66);
    }

    // 34 - Engage combat mode
    if (asr.isDetectCmdID(34))
    {
        k10.rgb->write(-1, 0xFF0033);
        typeLine("Combat protocol engaged.", 0x00FF66);
    }
    if (pressA == 3000)
    {
        chatbot();
    }
    if (pressA == 4000 && pressB == 4000)
    {
        weather();
    }
    if (pressA == 7001)
    {
        k10.canvas->canvasClear();
        k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
        k10.canvas->canvasText("Recording", 10, 10, 0x008000, k10.canvas->eCNAndENFont24, 10, false);
        k10.canvas->updateCanvas();
        music.recordSaveToTFCard(voicerecord, 60);
        k10.canvas->canvasClear();
        k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
        soundGUI();
        k10.canvas->canvasText("Record complete", 10, 10, 0x008000, k10.canvas->eCNAndENFont24, 16, false);
        k10.canvas->updateCanvas();
        pressA = 7500;
    }
    if ((pressA >= 2000 && pressA <= 2999) && (pressB >= 2000 && pressB <= 2999))
    {
        workout();
    }
    if (pressA == 6000)
    {
        reaction();
        delay(2000);
        while (pressA == 6000)
        {
            k10.setScreenBackground(Colors[randomColor]);
            delay(2000);
            while (randomColor != 0)
            {
                randomColor = random(5);
            }
        }
    }
    if (pressA == 6001 && randomColor == 0)
    {
        k10.canvas->canvasClear();
        k10.creatCanvas();
        k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
        k10.canvas->canvasText("You win", 10, 10, 0x008000, k10.canvas->eCNAndENFont24, 21, false);
        k10.canvas->updateCanvas();
    }
    if (pressA == 6001 && randomColor != 0)
    {
        k10.canvas->canvasClear();
        k10.creatCanvas();
        k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
        k10.canvas->canvasText("You lost", 10, 10, 0x008000, k10.canvas->eCNAndENFont24, 21, false);
        k10.canvas->updateCanvas();
    }
    if (pressA == 5000 && pressB == 5000)
    {
        if (ai.isDetectContent(AIRecognition::Face))
        {
            k10.rgb->write(-1, 0xFF0000);
            k10.canvas->canvasText((String("Face Length") + String(ai.getFaceData(AIRecognition::Length))), 10, 80, 0x0000FF, k10.canvas->eCNAndENFont24, 50, true);
            k10.canvas->canvasText((String("Face Width ") + String(ai.getFaceData(AIRecognition::Length))), 0, 16, 0x0000FF, k10.canvas->eCNAndENFont24, 50, true);
            k10.canvas->canvasText((String("Face Center X") + String(ai.getFaceData(AIRecognition::CenterX))), 0, 32, 0x0000FF, k10.canvas->eCNAndENFont24, 50, true);
            k10.canvas->canvasText((String("Face Center Y") + String(ai.getFaceData(AIRecognition::CenterY))), 0, 32, 0x0000FF, k10.canvas->eCNAndENFont24, 50, true);
            k10.canvas->updateCanvas();
            k10.rgb->write(-1, 0xFF0000);
        }
        delay(1000);
    }
    if (pressA == 1001)
    {
        soundGUI();
    }
}

void eyesAnimation()
{

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_00_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_01_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_02_delay-0.05s.png");
    k10.canvas->updateCanvas();
    delay(50);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_03_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_04_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_05_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_06_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_07_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_08_delay-0.05s.png");
    k10.canvas->updateCanvas();
    delay(50);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_09_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_10_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_11_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_12_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_13_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_14_delay-0.38s.png");
    k10.canvas->updateCanvas();
    delay(380);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_15_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_16_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_17_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_18_delay-0.05s.png");
    k10.canvas->updateCanvas();
    delay(50);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_19_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_20_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_21_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_22_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_23_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_24_delay-0.05s.png");
    k10.canvas->updateCanvas();
    delay(50);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_25_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_26_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_27_delay-0.04s.png");
    k10.canvas->updateCanvas();
    delay(40);

    k10.canvas->canvasDrawImage(60, 80, "S:/eyes/frame_28_delay-0.29s.png");
    k10.canvas->updateCanvas();
    delay(290);
}

void soundGUI()
{
    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_00_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_01_delay-0.03s.png");
    k10.canvas->updateCanvas();
    delay(30);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_02_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_03_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_04_delay-0.1s.png");
    k10.canvas->updateCanvas();
    delay(100);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_05_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_06_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_07_delay-0.1s.png");
    k10.canvas->updateCanvas();
    delay(100);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_08_delay-0.1s.png");
    k10.canvas->updateCanvas();
    delay(100);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_09_delay-0.1s.png");
    k10.canvas->updateCanvas();
    delay(100);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_10_delay-0.1s.png");
    k10.canvas->updateCanvas();
    delay(100);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_11_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_12_delay-0.13s.png");
    k10.canvas->updateCanvas();
    delay(130);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_13_delay-0.03s.png");
    k10.canvas->updateCanvas();
    delay(30);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_14_delay-0.03s.png");
    k10.canvas->updateCanvas();
    delay(30);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_15_delay-0.03s.png");
    k10.canvas->updateCanvas();
    delay(30);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_16_delay-0.1s.png");
    k10.canvas->updateCanvas();
    delay(100);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_17_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_18_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_19_delay-0.1s.png");
    k10.canvas->updateCanvas();
    delay(100);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_20_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_21_delay-0.1s.png");
    k10.canvas->updateCanvas();
    delay(100);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_22_delay-0.1s.png");
    k10.canvas->updateCanvas();
    delay(100);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_23_delay-0.1s.png");
    k10.canvas->updateCanvas();
    delay(100);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_24_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);

    k10.canvas->canvasDrawImage(50, 150, "S:/sound/frame_25_delay-0.07s.png");
    k10.canvas->updateCanvas();
    delay(70);
}

void chatbot()
{
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_00_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_01_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_02_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_03_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_04_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_05_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_06_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_07_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_08_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_09_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);

    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_10_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_11_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_12_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_13_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_14_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_15_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_16_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_17_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_18_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_19_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);

    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_20_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_21_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_22_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_23_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_24_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_25_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_26_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_27_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_28_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_29_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);

    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_30_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_31_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_32_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_33_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_34_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_35_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_36_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_37_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_38_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_39_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);

    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_40_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_41_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_42_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_43_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_44_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_45_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_46_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_47_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_48_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_49_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);

    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_50_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_51_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_52_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_53_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_54_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_55_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_56_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_57_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_58_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_59_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);

    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_60_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_61_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_62_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_63_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_64_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_65_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_66_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_67_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_68_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_69_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);

    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_70_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
    k10.canvas->canvasDrawImage(0, 50, "S:/chatbot/frame_71_delay-0.05s.png"); k10.canvas->updateCanvas(); delay(16);
}

void startup()
{
    k10.rgb->brightness(round(5));
    k10.rgb->write(-1, 0x1F51FF);
    k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
    eyesAnimation();
    k10.canvas->canvasText("hi! this is zecko!", 20, 160, 0x008000, Canvas::eCNAndENFont24, 19, false);
    k10.canvas->updateCanvas();
}

void menu()
{
    k10.setScreenBackground(0x000000);
    k10.canvas->canvasClear();
    k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
    k10.canvas->canvasText("menu", 10, 10, 0x008000, Canvas::eCNAndENFont24, 5, false);
    k10.canvas->canvasText("camera", 10, 50, 0x008000, Canvas::eCNAndENFont24, 7, false);
    k10.canvas->canvasText("music player", 10, 80, 0x008000, Canvas::eCNAndENFont24, 13, false);
    k10.canvas->canvasText("workout", 10, 110, 0x008000, Canvas::eCNAndENFont24, 8, false);
    k10.canvas->canvasText("zecko ai", 10, 140, 0x008000, Canvas::eCNAndENFont24, 9, false);
    k10.canvas->canvasText("weather", 10, 170, 0x008000, Canvas::eCNAndENFont24, 8, false);
    k10.canvas->canvasText("ai recognition", 10, 200, 0x008000, Canvas::eCNAndENFont24, 15, false);
    k10.canvas->canvasText("reaction game", 10, 230, 0x008000, Canvas::eCNAndENFont24, 19, false);
    k10.canvas->canvasText("journal", 10, 260, 0x008000, Canvas::eCNAndENFont24, 19, false);
    k10.canvas->updateCanvas();
}

void onButtonAPressed()
{
    pressA += 1;

    if (pressA == 1) // Select camera
    {
        music.playTone(220, 2000);
        k10.canvas->canvasText("camera", 10, 50, 0x1F51FF, Canvas::eCNAndENFont24, 7, false);
        k10.canvas->updateCanvas();
    }
    else if (pressA == 2) // Select music player
    {
        music.playTone(220, 2000);
        k10.canvas->canvasText("camera", 10, 50, 0x008000, Canvas::eCNAndENFont24, 7, false);
        k10.canvas->updateCanvas();
        k10.canvas->canvasText("music player", 10, 80, 0x1F51FF, Canvas::eCNAndENFont24, 13, false);
        k10.canvas->updateCanvas();
    }
    else if (pressA == 3) // Select workout
    {
        music.playTone(220, 2000);
        k10.canvas->canvasText("music player", 10, 80, 0x008000, Canvas::eCNAndENFont24, 13, false);
        k10.canvas->updateCanvas();
        k10.canvas->canvasText("workout", 10, 110, 0x1F51FF, Canvas::eCNAndENFont24, 8, false);
        k10.canvas->updateCanvas();
    }
    else if (pressA == 4) // Select zecko ai
    {
        music.playTone(220, 2000);
        k10.canvas->canvasText("workout", 10, 110, 0x008000, Canvas::eCNAndENFont24, 8, false);
        k10.canvas->updateCanvas();
        k10.canvas->canvasText("zecko ai", 10, 140, 0x1F51FF, Canvas::eCNAndENFont24, 9, false);
        k10.canvas->updateCanvas();
    }
    else if (pressA == 5) // Select weather
    {
        music.playTone(220, 2000);
        k10.canvas->canvasText("zecko ai", 10, 140, 0x008000, Canvas::eCNAndENFont24, 9, false);
        k10.canvas->updateCanvas();
        k10.canvas->canvasText("weather", 10, 170, 0x1F51FF, Canvas::eCNAndENFont24, 8, false);
        k10.canvas->updateCanvas();
    }
    else if (pressA == 6) // Select ai recognition
    {
        music.playTone(220, 2000);
        k10.canvas->canvasText("weather", 10, 170, 0x008000, Canvas::eCNAndENFont24, 8, false);
        k10.canvas->updateCanvas();
        k10.canvas->canvasText("ai recognition", 10, 200, 0x1F51FF, Canvas::eCNAndENFont24, 15, false);
        k10.canvas->updateCanvas();
    }
    else if (pressA == 7) // Select reaction game
    {
        music.playTone(220, 2000);
        k10.canvas->canvasText("ai recognition", 10, 200, 0x008000, Canvas::eCNAndENFont24, 15, false);
        k10.canvas->updateCanvas();
        k10.canvas->canvasText("reaction game", 10, 230, 0x1F51FF, Canvas::eCNAndENFont24, 19, false);
        k10.canvas->updateCanvas();
    }
    else if (pressA == 8) // Select journal
    {
        music.playTone(220, 2000);
        k10.canvas->canvasText("reaction game", 10, 230, 0x008000, Canvas::eCNAndENFont24, 19, false);
        k10.canvas->updateCanvas();
        k10.canvas->canvasText("journal", 10, 260, 0x1F51FF, Canvas::eCNAndENFont24, 8, false);
        k10.canvas->updateCanvas();
    }
    else if (pressA == 9) // Select camera
    {
        music.playTone(220, 2000);
        k10.canvas->canvasText("journal", 10, 260, 0x008000, Canvas::eCNAndENFont24, 8, false);
        k10.canvas->updateCanvas();
        k10.canvas->canvasText("camera", 10, 50, 0x1F51FF, Canvas::eCNAndENFont24, 7, false);
        k10.canvas->updateCanvas();
        pressA = 1;
    }
    else if (pressA == 101)
    {
        k10.photoSaveToTFCard(filename);
    }
    else if (pressA == 1001)
    {
        k10.canvas->canvasClear();
        k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
        k10.canvas->canvasText("Playing...", 10, 10, 0x008000, Canvas::eCNAndENFont24, 20, false);

        k10.canvas->updateCanvas();
        music.playTFCardAudio("S:/synth.wav");
    }
    else if (pressA >= 2001 && pressA <= 2800)
    {
        sets++;
        reps = 0;
    }
}

void onButtonBPressed()
{

    if (pressB == 2000)
    {
        reps++;
    }

    switch (pressA)
    {
    case 1:
        pressA = 100;
        pressB = 100;
        music.playTone(220, 2000);
        camera();
        break;
    case 2:
        pressA = 1000;
        pressB = 1000;
        music.playTone(220, 2000);
        musicplayer();
        break;
    case 3:
        pressA = 2000;
        pressB = 2000;
        music.playTone(220, 2000);
        workout();
        break;
    case 4:
        pressA = 3000;
        pressB = 3000;
        music.playTone(220, 2000);
        typeLine("Neural interface online.", 0x00FFFF);
        break;
    case 5:
        pressA = 4000;
        pressB = 4000;
        music.playTone(220, 2000);
        weather();
        break;
    case 6:
        pressA = 5000;
        pressB = 5000;
        music.playTone(220, 2000);
        airecognition();
        break;
    case 7:
        pressA = 6000;
        pressB = 6000;
        music.playTone(220, 2000);
        reaction();
        break;
    case 8:
        pressA = 7000;
        pressB = 7000;
        music.playTone(220, 2000);
        journal();
        break;
    }
}

void onButtonABPressed()
{
    menu();
    pressA = 0;
    pressB = 0;
}

void camera()
{
    ai.switchAiMode(ai.NoMode);
    delay(100);
    k10.initBgCamerImage();
    k10.setBgCamerImage(false);
    k10.creatCanvas();
    k10.setBgCamerImage(true);
}

void musicplayer()
{
    k10.canvas->canvasClear();
    k10.initSDFile();
    k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
    k10.canvas->canvasText("Press A to play...", 10, 10, 0x008000, Canvas::eCNAndENFont24, 20, false);
    k10.canvas->updateCanvas();
}

void workout()
{
    if (((k10.getStrength()) > 1080))
    {
        step += 1;
    }
    sec++;
    if (sec == 60)
    {
        minute++;
        sec = 0;
    }
    String StrSets = String(sets);
    String StrReps = String(reps);
    String StrStep = String(step);
    k10.canvas->canvasClear();
    k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
    k10.canvas->canvasText("Workout Station", 10, 10, 0x008000, Canvas::eCNAndENFont24, 16, false);
    k10.canvas->canvasText("Step Count: " + StrStep, 10, 50, 0x008000, Canvas::eCNAndENFont24, 16, false);
    k10.canvas->canvasText("Set: " + StrSets, 10, 80, 0x008000, Canvas::eCNAndENFont24, 16, false);
    k10.canvas->canvasText("Reps: " + StrReps, 10, 110, 0x008000, Canvas::eCNAndENFont24, 16, false);
    k10.canvas->canvasText("Time: " + String(minute) + " : " + String(sec), 10, 140, 0x008000, Canvas::eCNAndENFont24, 20, false);
    k10.canvas->canvasDrawImage(50, 180, "S:/running/frame_00_delay-0.02s.png");
    k10.canvas->updateCanvas();

    k10.canvas->canvasDrawImage(50, 180, "S:/running/frame_01_delay-0.02s.png");
    k10.canvas->updateCanvas();

    k10.canvas->canvasDrawImage(50, 180, "S:/running/frame_02_delay-0.02s.png");
    k10.canvas->updateCanvas();

    k10.canvas->canvasDrawImage(50, 180, "S:/running/frame_03_delay-0.02s.png");
    k10.canvas->updateCanvas();

    k10.canvas->canvasDrawImage(50, 180, "S:/running/frame_04_delay-0.02s.png");
    k10.canvas->updateCanvas();

    k10.canvas->canvasDrawImage(50, 180, "S:/running/frame_05_delay-0.02s.png");
    k10.canvas->updateCanvas();

    k10.canvas->canvasDrawImage(50, 180, "S:/running/frame_06_delay-0.02s.png");
    k10.canvas->updateCanvas();

    k10.canvas->canvasDrawImage(50, 180, "S:/running/frame_07_delay-0.02s.png");
    k10.canvas->updateCanvas();

    k10.canvas->updateCanvas();
    delay(400);
}

void weather()
{
    float temperatureC = aht20.getData(AHT20::eAHT20TempC) * 0.75;
    float humidity = aht20.getData(AHT20::eAHT20HumiRH) + 25;
    String Noise = String(k10.readMICData());
    String Temp = String(temperatureC);
    String Humid = String(humidity);
    String LAX = String(k10.readALS());
    k10.canvas->canvasClear();
    k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
    k10.canvas->canvasText("Weather Station", 10, 10, 0x008000, Canvas::eCNAndENFont24, 16, false);
    k10.canvas->canvasText("Temperature: " + Temp, 10, 50, 0x008000, Canvas::eCNAndENFont24, 20, false);
    k10.canvas->canvasText("Humidity: " + Humid, 10, 80, 0x008000, Canvas::eCNAndENFont24, 15, false);
    k10.canvas->canvasText("Intensity: " + LAX, 10, 110, 0x008000, Canvas::eCNAndENFont24, 18, false);
    k10.canvas->canvasText("Noise: " + Noise, 10, 140, 0x008000, Canvas::eCNAndENFont24, 18, false);
    k10.canvas->updateCanvas();
    delay(1000);
}

void journal()
{
    k10.canvas->canvasClear();
    k10.creatCanvas();
    k10.initSDFile();
    k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
    k10.canvas->canvasText("Press A to record.", 10, 10, 0x008000, k10.canvas->eCNAndENFont24, 50, false);
    k10.canvas->updateCanvas();
}

void reaction()
{
    k10.canvas->canvasClear();
    k10.creatCanvas();
    k10.canvas->canvasRectangle(1, 1, 239, 319, 0x1F51FF, 0x1F51FF, false);
    k10.canvas->canvasText("Press A when you", 10, 10, 0x008000, k10.canvas->eCNAndENFont24, 21, false);
    k10.canvas->canvasText("see the color:", 10, 40, 0x008000, k10.canvas->eCNAndENFont24, 21, false);
    k10.canvas->canvasText(ColorSelected, 10, 70, 0x008000, k10.canvas->eCNAndENFont24, 21, false);
    k10.canvas->updateCanvas();
}

void typeLine(String msg, uint16_t color)
{
    k10.canvas->canvasClear();
    k10.canvas->canvasRectangle(1, 1, 239, 319, 0x000000, 0x000000, false);

    String buffer = "> ";
    for (int i = 0; i < msg.length(); i++)
    {
        buffer += msg[i];
        k10.canvas->canvasText(buffer, 10, 280, color, Canvas::eCNAndENFont16, 40, true);
        k10.canvas->updateCanvas();
    }
}

void airecognition()
{
    k10.initBgCamerImage();
    k10.setBgCamerImage(false);
    k10.creatCanvas();
    ai.switchAiMode(ai.NoMode);
    k10.setBgCamerImage(true);
    ai.switchAiMode(ai.Face);
}

3D-Printed Enclosure: The custom enclosure is designed to maintain access to GPIO pins, buttons, and speakers while protecting the board.

Available to download here: https://www.printables.com/model/1621063-zecko-es-custom-case-for-unihiker-k10

Zecko ES Case
Zecko ES
Zecko ES

Testing & Validation:
Each module was individually tested:

Camera captures and stores images reliably.

Music player plays files from the SD card.

Workout tracking logs steps, sets, and reps.

AI recognition successfully detects faces.

Weather station accurately displays environmental data.

Reaction game and journal functions operate as expected.

Zecko ES

This is a full presentation and showcase of the Unihiker K10 and its functionalities. Once again, I am grateful to have received the Unihiker K10 from DFRobot.


License
All Rights
Reserved
licensBg
0