Can the Arduino Giga tell your future?

Pretend for a moment you’ve been captured by a motley band of rebel physicists bent on building a time machine.

You’ve been locked in an electronics shop and told you can’t come out until you have a working prototype built.

This is going to be a problem, you have a dentist appointment at 3:15pm, and if you miss it, rescheduling those is a nightmare. That gives you 45 minutes to build a working time machine prototype.

Instead of building a time machine, you’ll build something to distract them, while you sneak out to your dentist appointment.

You’ll build a Probabilistic Time State Engine…basically, it’s a magic 8-ball, but instead of an 8-ball, you’ll use the 3d printed cat…

Arduino Code

You’ll need a ChatGPT API key to make this work. It’s pretty easy to set up a developer account with OpenAI and get your key, here’s how.

The ChatGPT library “ChatGPTuino” used in this example is here. It is still very much under development.

#include "Arduino_BMI270_BMM150.h"
#include "Arduino_H7_Video.h"
#include "lvgl.h"
#include "lv_conf.h"
#include <ChatGPTuino.h>
#include <WiFi.h>
#include "credentials.h"  // Network name, password, and private API key

Arduino_H7_Video Display(800, 480, GigaDisplayShield); /* Arduino_H7_Video Display(1024, 768, USBCVideo); */
BoschSensorClass imu(Wire1);

const int TOKENS = 100;  // How lengthy a response you want, every token is about 3/4 a word
const int NUM_MESSAGES = 20;

ChatGPTuino chat{ TOKENS, NUM_MESSAGES };  // Will store and send your most recent messages (up to NUM_MESSAGES)
const char *model = "gpt-4o";              // OpenAI Model being used

const int fadeAmount = 5;

static lv_style_t style_main;
static lv_style_t style_shadow;
lv_obj_t *shadow_label;
lv_obj_t *main_label;

volatile int text_opacity = 255;

enum States {
  FORTUNE_DISPLAYED,
  GET_FORTUNE,
  REVEAL_FORTUNE
} state = FORTUNE_DISPLAYED;

void setup() {

  Serial.begin(115200);
  Display.begin();
  imu.begin();

  //Set Background Black
  lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0x000000), LV_PART_MAIN);

  // Make a label
  /*Create a style for the shadow*/
  lv_style_init(&style_shadow);
  lv_style_set_text_opa(&style_shadow, LV_OPA_30);
  lv_style_set_text_color(&style_shadow, lv_color_hex(0xef7422));
  lv_style_set_text_font(&style_shadow, &lv_font_montserrat_48);

  lv_style_init(&style_main);
  lv_style_set_text_color(&style_main, lv_color_white());
  lv_style_set_text_font(&style_main, &lv_font_montserrat_48);

  /*Create a label for the shadow first (it's in the background)*/
  shadow_label = lv_label_create(lv_screen_active());
  lv_obj_add_style(shadow_label, &style_shadow, 0);

  /*Create the main label*/
  main_label = lv_label_create(lv_screen_active());
  lv_obj_add_style(main_label, &style_main, 0);

  // WiFi Setup
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // Initialize messages array
  chat.init(key, model);

  // Add user message to messages array
  chat.putMessage(userMessage, strlen(userMessage));
  // Add system message to messages array
  chat.putMessage(systemMessage, strlen(systemMessage), Sys);

  lv_label_set_text(main_label, "Shake me for possibilities");

  /*Set the same text for the shadow label*/
  lv_label_set_text(shadow_label, lv_label_get_text(main_label));

  /*Position the main label*/
  lv_obj_align(main_label, LV_ALIGN_CENTER, 0, 0);

  /*Shift the second label down and to the right by 2 pixel*/
  lv_obj_align_to(shadow_label, main_label, LV_ALIGN_TOP_LEFT, 6, 6);

  // Print response
  Serial.println(chat.getLastMessageContent());
}

uint8_t rotation = 0;

void loop() {

  lv_timer_handler();

  float x, y, z;
  static int count = 0;

  if (imu.accelerationAvailable() && (state == FORTUNE_DISPLAYED)) {
    imu.readAcceleration(x, y, z);

    if (z < 0.8 && z > -0.8) {

      text_opacity = text_opacity - fadeAmount;

      if (text_opacity <= 0) {
        text_opacity = 0;
        chat.putMessage(userMessage, strlen(userMessage));
        state = GET_FORTUNE;
      }

      lv_style_set_text_opa(&style_shadow, text_opacity);
      lv_style_set_text_opa(&style_main, text_opacity);
      lv_obj_align_to(shadow_label, main_label, LV_ALIGN_TOP_LEFT, 6, 6);
      lv_obj_report_style_change(NULL);

      Serial.print("text_opacity = ");
      Serial.println(text_opacity);
    }
  }

  if (state == GET_FORTUNE) {
    // Send message array and receive response
    chat.getResponse();

    Serial.println(chat.getLastMessageContent());
    lv_label_set_text(main_label, chat.getLastMessageContent());

    /*Set the same text for the shadow label*/
    lv_label_set_text(shadow_label, lv_label_get_text(main_label));
    lv_obj_align_to(shadow_label, main_label, LV_ALIGN_TOP_LEFT, 6, 6);

    text_opacity = 255;
    lv_style_set_text_opa(&style_shadow, text_opacity);
    lv_style_set_text_opa(&style_main, text_opacity);
    lv_obj_report_style_change(NULL);

    state = FORTUNE_DISPLAYED;
  }

}

credentials.h file:

#ifndef Secret_h
#define Secret_h

/* Keep all these private */
const char* ssid = "UnderGroundLayer";  // Change to your WiFi Network name
const char* password = "MWaHaHaHa7#!";  // Change to your WiFi password
const char* key = "";                   // Your private API Key see https://bit.ly/OpenAI-Dev to get setup

const char *userMessage = "Give me a new fortune.";  // User message to ChatGPT
const char *systemMessage =
  "You are a magic 8 ball simulator with a twist.  You are funny and snarky, and almost always predict doom or amazing glory. "
  "Your target audience is physicists. "
  "You have been loaded onto an embedded device with a small LCD screen. "
  "You must respond in 20 words or less. Less is fine. "
  "you need to include newline characters so that the text does not flow over the screen. "
  "Do not use special characters like umlauts, or apsotrophes either. "
  "For example: "
  "You are in\n "
  "Luck \n "
  "thoretically";

#endif

AppLab Bricks open in background with actual brick

Arduino AppLab Bricks → Marketing Garbage or New Powerful Interface?

Arduino Ventuno single board computer - top side

New Ventuno Q Dual Brain Single Board Computer

AppLab Pip Install

How to Add Python Packages in Arduino AppLab (No pip install needed)

Arduino Power Section Schematic

Kit-on-a-Shield Schematic Review

Just how random is the ESP32 random number generator?

Just how random is the ESP32 random number generator?

Leave a Comment