/*
  Forum: https://forum.arduino.cc/t/i-do-not-read-analog-input-with-millis-function/1310084
  Wokwi: https://wokwi.com/projects/411467196421173249

  Original Version see here  Wokwi: https://wokwi.com/projects/411465414534821889

*/

/************************************************************************
    Random numbers from 1 to 3

   v 10.2   25 October 2024
   
   
 ************************************************************************/

#define WOKWI

#include <Adafruit_GFX.h>

#include <SPI.h>
#include <Wire.h>

#ifdef WOKWI

#define TFT_CS   10
#define TFT_DC   8
#include "Adafruit_ILI9341.h"
Adafruit_ILI9341 display = Adafruit_ILI9341(TFT_CS, TFT_DC);


#else

#include <Adafruit_SSD1331.h>
#define sclk 13
#define mosi 11
#define cs   10
#define rst  9
#define dc   8
Adafruit_SSD1331 display = Adafruit_SSD1331(cs, dc, rst);

#endif


// +++++++++++++ color definition +++++++++
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF

// +++++++++++++ functions ++++++++++++++++
void soglieDato();
void storingData();
void allarme();
void azzera();
void leggeDato();
void fine();

// +++++++++++++ global variables ++++++++
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 3000;  // displays in seconds
byte uno = 0;   // byte HIGH
byte due = 0;   // byte LOW
unsigned long seed;
const byte analogPin = A3;
bool uscito1 = false;
bool uscito2 = false;
bool uscito3 = false;
int dimTesto = 7;
int valore = 0;   // data readout port ADC A3
int dato = 0;     // random number extracted
int giocata = 0;  // variable for repeat outputs
int maxGiocata = 13;
int maxDato = 3;
const int massimo = 94;  // maximum value for array 
int myArray[100]; // array to momentarily insert value
int indirizzoAr = 0; // Array cell address
int indirizzoEE = 0; // EEPROM cell address

void setup() {
  Wire.begin();
  display.begin();
  display.fillScreen(GREEN);
  display.setCursor(5, 20); //column, row
  display.setTextColor(WHITE);
  display.setTextSize(2);
  display.print("ver10.2");
  display.setCursor(25, 50); //column, row
  display.setTextSize(1);
  display.print("23 ott 24");
  delay(3000);
  Serial.begin(9600);
  //soglieDato(); // calculates and displays + or - thresholds
  startMillis = millis();
  //count = 0;
  unsigned long seed = analogRead(A0);
  for (int i = 1; i <= 3; ++i) {
    delay(50);
    seed += analogRead(A0) * 1024 * i;
    }
  randomSeed(seed);
}



void loop() {
  dato = random(1, 4);
  //Serial.println(dato);

  switch (dato) {
    case 1:
      if (uscito1 == false) {
        display.fillScreen(BLACK);
        display.setCursor(30, 5); //column, row
        display.setTextColor(CYAN);
        display.setTextSize(dimTesto);
        display.print("1");
        // save data in the first free cell
        myArray[indirizzoAr] = dato;  // random number extracted
        Serial.print("dato  ");
        Serial.println(myArray[indirizzoAr]);
        indirizzoAr++;  // increase cell Array address
        leggeDato();   // goes read ADC input
      }
      uscito1 = true; 
      break;

    case 2:
      if (uscito2 == false) {
        display.fillScreen(BLACK);
        display.setCursor(30, 5); //column, row
        display.setTextColor(CYAN);
        display.setTextSize(dimTesto);
        display.print("2");
       // save data in the first free cell
        myArray[indirizzoAr] = dato;  // random number extracted
        Serial.print("dato  ");
        Serial.println(myArray[indirizzoAr]);
        indirizzoAr++;  // increase cell Array address
        leggeDato();   // goes read ADC input
      }
      uscito2 = true;
      break;

    case 3:
      dato = 3;
      if (uscito3 == false) {
        display.fillScreen(BLACK);
        display.setCursor(30, 0); //column, row
        display.setTextColor(CYAN);
        display.setTextSize(dimTesto);
        display.print("X"); // 3
        // save data in the first free cell
        myArray[indirizzoAr] = dato;  // random number extracted
        Serial.print("dato  ");
        Serial.println(myArray[indirizzoAr]);
        indirizzoAr++;  // increase cell Array address
        leggeDato();   // goes read ADC input 
      }
      uscito3 = true;
      break;
  }
  // did the three numbers (1,2,3) come out ?
  if (uscito1 == true && uscito2 == true && uscito3 == true) {  
    azzera();
    }
  if (giocata >= maxGiocata) { 
      fine();
  }
}


/********************************************************
                  Functions
 ********************************************************/
void leggeDato() {
  startMillis = millis();
  while ((millis() - startMillis) <= period){ //true until the end of the period
      valore = analogRead(analogPin); // ADC fattening value law
      Serial.println(valore);
      myArray[indirizzoAr] = valore;  // saves in the Array cell
      delay(100);
      indirizzoAr++;  // increments cell address Array
    }
}
    
void azzera(){  
    uscito1 = false;  // reset for new reading
    uscito2 = false;  // reset for new reading
    uscito3 = false;  // reset for new reading
    giocata = ++giocata;
    display.fillScreen(BLACK);
    display.setCursor(40, 25); //column, row
    display.setTextColor(YELLOW);
    display.setTextSize(5);
    myArray[indirizzoAr] = giocata; // save play in Array
    delay(100);
    indirizzoAr++;  // increment cell address Array
    giocata = giocata++;  // increase play
    storingData();  // reads Array and saves data, values, play to EEPROM
    Serial.print("Giocata ");
    Serial.println(giocata);
    indirizzoAr = 0;  // saving in the Array restarts from cell 0
}

void storingData(){ // reads cells Array and saves data, values, play to EEPROM
  for(indirizzoAr = 0; indirizzoAr < massimo; indirizzoAr++){
    int x = myArray[indirizzoAr]; // reads Array cell and writes to variable X
    //due = x;      // compute the 8 bits LOW
    //uno= x >> 8;  // compute the 8 bits HIGH
    //uno = ((x >> 8) & 0xFF);
    //due = (x & 0xFF);
    uno = highByte(x);
    due = lowByte(x);
    Wire.beginTransmission(0x50);
    Wire.write(highByte(indirizzoEE));
    Wire.write(lowByte(indirizzoEE));
    Wire.write(byte(uno));
    Wire.endTransmission();
    delay(10);
    indirizzoEE++;  
    Wire.beginTransmission(0x50);
    Wire.write(highByte(indirizzoEE));
    Wire.write(lowByte(indirizzoEE));
    Wire.write(byte(due));
    Wire.endTransmission();
    delay(10);
    indirizzoEE++;
    }
}

void fine(){ 
    display.fillScreen(RED);
    display.setCursor(15, 20); //column, row
    display.setTextColor(WHITE);
    display.setTextSize(3);
    display.print("End");
    Serial.print("indirizzoEE ");
    Serial.println(indirizzoEE);
    while (1);
}