Back to Parent

#include <Adafruit_Thermal.h>
#include <Arduino_APDS9960.h>

#include <project_2_rme_inferencing.h>
#include "edge-impulse-sdk/classifier/ei_classifier_types.h"

//IMAGE BITMAPS
#include "symbol1.h"
#include "symbol2.h"
#include "symbol3.h"
#include "symbol4.h"
#include "symbol5.h"
#include "symbol6.h"
#include "symbol7.h"
#include "symbol8.h"

#define BAUDRATE  9600

/**************************************************************************
  This is a library for several Adafruit displays based on ST77* drivers.

  The 1.47" TFT breakout
    ----> https://www.adafruit.com/product/5393

  Check out the links above for our tutorials and wiring diagrams.
  These displays use SPI to communicate, 4 or 5 pins are required to
  interface (RST is optional).

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 **************************************************************************/

#include <Adafruit_GFX.h>    // Core graphics library
#include <SPI.h>

// EDGE IMPULSE VARS
const char* model_name = "model";
ei_impulse_result_t result;


Adafruit_Thermal printer(&Serial1);

float p = 3.1415926;


const int nSensors = 15;
const int nSensorsPerMux = 8;

int sensorVals[15];

//Mux control pins
int s0 = D12;
int s1 = D11;
int s2 = D10;

int t0 = D9;
int t1 = D8;
int t2 = D7;

//Mux in "Z" pin
const int comPin1 = A0;
const int comPin2 = A1;

int total = 0;
int avg;
float avg_sensor_val = 0.0;
int line_length_band = 0; // For determining what kind of text prompt to write to user
float max_thresh = 80; // For checking if hand too far away

bool beginPrint = false;
bool isPrinting = false;

String goodSymbols[3] = {
  "symbol1",
  "symbol2",
  "symbol3"
};  

String neutralSymbols[3] = {
  "symbol6",
  "symbol7",
  "symbol8"
};

String badSymbols[2] = {
  "symbol4",
  "symbol5"
};

String prediction;


/////////////// SETUP FUNCTION /////////////
void setup(void) {
  //SENSORS
  pinMode(s0, OUTPUT); 
  pinMode(s1, OUTPUT); 
  pinMode(s2, OUTPUT); 

  pinMode(t0, OUTPUT); 
  pinMode(t1, OUTPUT); 
  pinMode(t2, OUTPUT); 

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  
  digitalWrite(t0, LOW);
  digitalWrite(t1, LOW);
  digitalWrite(t2, LOW);
  
  //THERMAL PRINTER
  Serial.begin(9600);
  Serial1.begin(9600);
  printer.begin(); 

  Serial.println(F("Initialized"));
  run_classifier_init();
  delay(2000);
  
}

int test_get_data(int offset, int length, float* out_ptr) {
  // sanity check
  float training_short[]  = {100., 121., 153., 139., 175., 144., 164., 144.,  96., 116., 137., 127., 143., 128., 137.};
  float training_medium[] = {103., 122., 169., 146., 191., 160., 172., 150., 121., 128., 145., 136., 151., 145., 148.};
  float training_long[]   = {86.,  99., 146., 121., 179., 136., 165., 128., 139., 132., 157., 287., 164., 113., 754.};

  avg_sensor_val = 0.0;
  for (int i = 0; i < nSensors; i++) {
    out_ptr[i] = float(sensorVals[i]); // / 1024.0 * 100 + 100);
    avg_sensor_val += float(sensorVals[i]);
  }
  // Serial.println("\n");  
  avg_sensor_val /= nSensors;
  // Update line lnegth band
  line_length_band = max(1, min(ceil(avg_sensor_val / (1024.0 / 4) * 3), 3)) - 1;
  return 0;
}

/////////////// LOOP FUNCTION /////////////
void loop() {
  readMux(sensorVals);
  printSensorVals(sensorVals);

  delay(200);
  

  // Edge impulse inference
  ei::signal_t signal;
  signal.total_length = nSensors;
  signal.get_data = &test_get_data;

  //ei_impulse_result_t result;
  int err = run_classifier(&signal, &result, false); // False to not print debug info
  if (err != EI_IMPULSE_OK) {
    Serial.println("Classification failed");
  } else { // Print edge impulse results

    //NO READING
    Serial.println(avg_sensor_val);
    if (avg_sensor_val < max_thresh) {
      Serial.println("Hand is too far away; please move closer to sensors.");
      beginPrint = false;
      
    //PRINT FORTUNE
    } else {
      //Serial.print("Inference result: ");
      const char* fortune = result.classification[line_length_band].label;
      
      Serial.println(fortune);
      
      if (!isPrinting){      //if there is no ongoing print, then start new print
        if (fortune == "short"){
          prediction = "bad";
        } else if (fortune == "medium"){
          prediction = "ambiguous";
        } else if (fortune == "long"){
          prediction = "good";
        }
        Serial.println(String("ASK_OPENAI")+String(" ") + prediction);
        delay(20000);
        String imgPrint = chooseImage(fortune);
        isPrinting = true;
        Serial.println("Chosen Image");
        
        printImage(imgPrint);
        
        //isPrinting = false;
        printer.justify('L');
        printer.println();
        
        if( Serial.available() ){ //print fortune generated by openAI
          String incoming = Serial.readString();
          Serial.println("RECEIVED DATA =>");
          Serial.println(incoming);//display same r
          printer.setSize('S'); //small text size
          printReceivedText( incoming );
        }
      }
    }
  }
}


//change it to thermal print
void printReceivedText( String text ){

  printer.setFont('B');
  printer.println(text);

}


//////////SENSOR/////////////////
void readMux( int sensorVals[]) {
  int controlPin1[] = {s0, s1, s2};
  int controlPin2[] = {t0, t1, t2};

  int muxChannel[8][3]={
    {0,0,0}, //channel 0
    {1,0,0}, //channel 1
    {0,1,0}, //channel 2
    {1,1,0}, //channel 3
    {0,0,1}, //channel 4
    {1,0,1}, //channel 5
    {0,1,1}, //channel 6
    {1,1,1}, //channel 7
  };

  //loop through every pin
  for (int j = 0; j < nSensorsPerMux; j++){
    //loop through the 3 sig
    for(int i = 0; i < 3; i ++){
      digitalWrite(controlPin1[i], muxChannel[j][i]);
      digitalWrite(controlPin2[i], muxChannel[j][i]);
    }
    //read the value at the Z pin
    int val1 = analogRead(comPin1);
    int val2 = analogRead(comPin2);

    //populate array
    sensorVals[j] = val1;
    total += val1;
    if (j != nSensorsPerMux -1){
      sensorVals[j + nSensorsPerMux] = val2;
      total += val2;
    }
  }
}

void printSensorVals(int sensorVals[]){
  for (int i = 0; i < nSensors; i++){
    Serial.print(sensorVals[i]); Serial.print(", ");
  }
  Serial.println("\n");
}

//////////PRINTER/////////////////
//algorithm to choose image to print

String chooseImage(const char* fortune){
  String img;
  if (fortune == "long"){
    //choose a symbol from 'good' symbols
    long imgN = random(0, 3);
    img = goodSymbols[imgN];
    Serial.print("long symbol"); Serial.println(imgN);
  } else if (fortune == "medium"){
    //choose a symbol from 'neutral' symbols
    long imgN = random(0, 2);
    img = neutralSymbols[imgN];
    Serial.print("medium symbol"); Serial.println(imgN);
  } else {
    //choose a symbol from 'bad' symbols
    long imgN = random(0, 3);
    img = badSymbols[imgN];
    Serial.print("short symbol"); Serial.println(imgN);
  }
  return img;
}




void printImage(String img){
  Serial.print("sending img "+img);
  printer.justify('C');
  printer.boldOn();
  printer.println("PALMISTRY LOVE FORTUNE");
  printer.boldOff();
  if (img == "symbol1"){
    printer.printBitmap(256, 256, heart1);
  } else if (img == "symbol2") {
    printer.printBitmap(256, 256, heart2);
  } else if (img == "symbol3") {
    printer.printBitmap(256, 256, heart);
  } else if (img == "symbol4") {
    printer.printBitmap(256, 256, knot1);
  } else if (img == "symbol5") {
    printer.printBitmap(256, 256, knot);
  } else if (img == "symbol6") {
    printer.printBitmap(256, 256, arrow1);
  } else if (img == "symbol7") {
    printer.printBitmap(256, 256, arrow2);
  } else if (img == "symbol8") {
    printer.printBitmap(256, 256, neutral);
  }
}
Click to Expand

Content Rating

Is this a good/useful/informative piece of content to include in the project? Have your say!

0