Variables data store and display

New to MIT App Inventor, I'm building an app to control a color sorting machine using Arduino Nano via Bluetooth. I have implemented start, stop, and restart buttons, along with displaying sorting numbers. Now, I aim to store sorting data with timestamps and display it on another screen as a table or chart. Any guidance on achieving this would be appreciated. Thanks!"

Can you please give me some instructions. So that I can achieve my aims.

Show how the data looks as it arrives, and the blocks you use to receive it.


Also post your sketch, so we can line it up with the app.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include "Adafruit_TCS34725.h"

Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

Servo wheelServo;
Servo chuteServo;

const int calibrating = 0;
const int wheelOverRun = 320;

const int startStopSwitch = 7;  // Pin for the start/stop switch
const int restartSwitch = 9;    // Pin for the restart switch
const int contactSwitch = 8;

int startStopState;
int restartState;
int switchState;
int arrayIndexToAimAt;

float redReading, greenReading, blueReading;

const int arrayRows = 6;
const int arrayColumns = 6;
int SAMPLES[arrayRows][arrayColumns] = {
  {83, 88, 59, "Red", 0, 0},      //red -0
  {73, 99, 62, "Green", 0, 40},   //green -1
  {84, 93, 53, "Yellow", 0, 80},  //yellow -2
  {70, 93, 67, "Blue", 0, 120},   //Blue -3
  {74, 94, 62, "Brown", 0, 150},  //Brown -4
  {82, 91, 57, "No Skittle", 0, 75}  //no skittle -5
};
const byte samplesCount = sizeof(SAMPLES) / sizeof(SAMPLES[0]);

LiquidCrystal_I2C lcd(0x27, 16, 2);

int totalSorts = 0;
int redSorts = 0;
int greenSorts = 0;
int yellowSorts = 0;
int blueSorts = 0;
int brownSorts = 0;

void setup() {
  pinMode(startStopSwitch, INPUT_PULLUP);
  pinMode(restartSwitch, INPUT_PULLUP);
  pinMode(contactSwitch, INPUT_PULLUP);

  Serial.begin(115200);
  wheelServo.attach(5);
  chuteServo.attach(6);

  if (tcs.begin()) {
    //Serial.println("Found sensor");
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1); // halt!
  }

  lcd.begin();
  lcd.backlight();
  printArray(SAMPLES);
}

void loop() {
  startStopState = digitalRead(startStopSwitch);
  restartState = digitalRead(restartSwitch);
   
    // Check for commands from the app via Bluetooth
   receivedCommand = 0;
  while (Serial.available() > 0) {
    char receivedCommand = Serial.read();
    handleBluetoothCommand(receivedCommand);
  }

  if (restartState == LOW || receivedCommand == 'R') {
    restartMachine();
  }

  if (startStopState == HIGH || receivedCommand == 'S') {
    switchState = digitalRead(contactSwitch);

    if (switchState == HIGH) {
      if (calibrating == 0) {
        clearScreen();
      }
      Serial.println();
      Serial.println("Yes - contact switch aligned. Taking a reading....");
      delay(wheelOverRun);
      wheelServo.write(95);
      readColour();
      if (calibrating == 0) {
        matchColour();
        updateCounts();
        updateLCD();
      }
      if (calibrating == 0) {
        printArray(SAMPLES);
      }
      arrayIndexToAimAt = findClosestSample();
      aimChute();
      if (calibrating == 1) {
        waitForUser();
      }
      delay(300);
    } else {
      Serial.println("Skittle moving wheel not aligned with contact switch yet - please gently rotate by hand unless a reading is produced shortly");
      wheelServo.write(126);
    }
  }
   if (receivedCommand == 'P') {
    // Add code to stop the machine
    stopSorting();
}
}

void readColour() {
  delay(70);
  tcs.getRGB(&redReading, &greenReading, &blueReading);
  Serial.println("Colour sensor currently reads:  ");
  Serial.print("R:"); Serial.print(int(redReading));
  Serial.print("\tG:"); Serial.print(int(greenReading));
  Serial.print("\tB:"); Serial.println(int(blueReading));
  Serial.println();
}

void matchColour() {
  int colourDistance;

  for (byte i = 0; i < samplesCount; i++) {
    colourDistance = getColourVariance(redReading, greenReading, blueReading, SAMPLES[i][0], SAMPLES[i][1], SAMPLES[i][2], SAMPLES[i][3]);
    SAMPLES[i][4] = colourDistance;
  }
}

int getColourVariance(int redSensor, int greenSensor, int blueSensor, int redSample, int greenSample, int blueSample, char *colour) {
  Serial.print("Checking the skittle against the ");
  Serial.print(colour);
  Serial.println(" sample.");
  int redDifference;
  redDifference = compareValues(redSensor, redSample, "Red ");
  int greenDifference;
  greenDifference = compareValues(greenSensor, greenSample, "Green ");
  int blueDifference;
  blueDifference = compareValues(blueSensor, blueSample, "Blue ");
  Serial.print("Total variance between the measured colour and sample for the ");
  Serial.print(colour);
  Serial.print(" item in the array = ");
  int totalDifference;
  totalDifference = redDifference + greenDifference + blueDifference;
  Serial.println(totalDifference);
  Serial.println();
  return totalDifference;
}

int compareValues(int sensorColour, int sampleColour, char *colour) {
  int difference;
  Serial.print("Comparing Colours:");
  Serial.print(colour);
  Serial.print(int(sensorColour));
  Serial.print(" was measured compared with ");
  Serial.print(int(sampleColour));
  Serial.print(" which has a difference of = ");
  difference = sensorColour - sampleColour;
  if (difference < 0) {
    difference = difference * (-1);
  }
  Serial.println(int(difference));
  return difference;
}

void printArray(const int a[][ arrayColumns ]) {
  for (int i = 0; i < arrayRows; ++i) {
    for (int j = 0; j < arrayColumns; ++j ) {
      Serial.print(a[i][j]);
      Serial.print(", ");
    }
    Serial.println();
  }
  Serial.println();
}

int findClosestSample() {
  int index = 0;

  for (int i = 0; i < arrayRows; i++) {
    if (SAMPLES[i][4] < SAMPLES[index][4]) {
      index = i;
    }
  }
  Serial.print("The closest sample in the array to the colour just sensed is the array row number ");
  Serial.println(index);
  return index;
}

void aimChute() {
  chuteServo.write(SAMPLES[arrayIndexToAimAt][5]);
}

void clearScreen() {
  for (int i = 0; i <= 80; i++) {
    Serial.println();
  }
}

void waitForUser() {
  Serial.println();
  Serial.println("-----========   Waiting for a single character to be sent before proceeding     ======------");
  while (Serial.available() == 0) {
    delay(1);
  }
  Serial.read();
  Serial.read();
  Serial.read();
}

void updateCounts() {
  if (arrayIndexToAimAt != 5) {
    totalSorts++;
  }

  if (arrayIndexToAimAt == 0) {
    redSorts++;
  } else if (arrayIndexToAimAt == 1) {
    greenSorts++;
  } else if (arrayIndexToAimAt == 2) {
    yellowSorts++;
  } else if (arrayIndexToAimAt == 3) {
    blueSorts++;
  } else if (arrayIndexToAimAt == 4) {
    brownSorts++;
  }
}

void updateLCD() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("T:");
  lcd.print(totalSorts);
  lcd.print("  R:");
  lcd.print(redSorts);
  lcd.print("  G:");
  lcd.print(greenSorts);

  lcd.setCursor(0, 1);
  lcd.print("Y:");
  lcd.print(yellowSorts);
  lcd.print("  B:");
  lcd.print(blueSorts);
  lcd.print("  Br:");
  lcd.print(brownSorts);
}
void stopSorting() {
  // Add code to stop the machine

  // Set servos to a neutral position
  wheelServo.write(95);  // Adjust the value based on your servo's neutral position
  // Additional code for stopping or shutting down the machine
  Serial.println("Stopping the machine...");

  // Perform any other necessary actions or cleanup here
}
void restartMachine() {
  totalSorts = 0;
  redSorts = 0;
  greenSorts = 0;
  yellowSorts = 0;
  blueSorts = 0;
  brownSorts = 0;

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Machine Restarted");
  delay(2000);
}

I don't see any code in the sketch that talks to the Bluetooth stream.

There is a Serial stream with lots of English text, suitable for a console display, an LCD display stream presumably to feed a small attachment, but no stream for Bluetooth.

And you say you have working control from the app?

sorry for the mistake. here is the code. and i face another problem during control. i connected the app with blutooth module but when i click on any butoons. it shows Error 515.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
#include "Adafruit_TCS34725.h"

Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

Servo wheelServo;
Servo chuteServo;

const int calibrating = 0;
const int wheelOverRun = 320;

const int startStopSwitch = 7;
const int restartSwitch = 9;
const int contactSwitch = 8;

int startStopState;
int restartState;
int switchState;
int arrayIndexToAimAt;

float redReading, greenReading, blueReading;

const int arrayRows = 6;
const int arrayColumns = 6;
int SAMPLES[arrayRows][arrayColumns] = {
  {83, 88, 59, "Red", 0, 0},      //red -0
  {73, 99, 62, "Green", 0, 40},   //green -1
  {84, 93, 53, "Yellow", 0, 80},  //yellow -2
  {70, 93, 67, "Blue", 0, 120},   //Blue -3
  {74, 94, 62, "Brown", 0, 150},  //Brown -4
  {82, 91, 57, "No Skittle", 0, 75}  //no skittle -5
};
const byte samplesCount = sizeof(SAMPLES) / sizeof(SAMPLES[0]);

LiquidCrystal_I2C lcd(0x27, 16, 2);

int totalSorts = 0;
int redSorts = 0;
int greenSorts = 0;
int yellowSorts = 0;
int blueSorts = 0;
int brownSorts = 0;

void setup() {
  pinMode(startStopSwitch, INPUT_PULLUP);
  pinMode(restartSwitch, INPUT_PULLUP);
  pinMode(contactSwitch, INPUT_PULLUP);

  Serial.begin(115200);
  wheelServo.attach(5);
  chuteServo.attach(6);

  if (tcs.begin()) {
    //Serial.println("Found sensor");
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1); // halt!
  }

  lcd.begin();
  lcd.backlight();
  printArray(SAMPLES);
}

void loop() {
  startStopState = digitalRead(startStopSwitch);
  restartState = digitalRead(restartSwitch);

  // Check for commands from the app via Bluetooth
  while (Serial.available() > 0) {
    char receivedCommand = Serial.read();
    handleBluetoothCommand(receivedCommand);
  }

  if (restartState == LOW) {
    restartMachine();
  }

  if (startStopState == HIGH) {
    switchState = digitalRead(contactSwitch);

    if (switchState == HIGH) {
      if (calibrating == 0) {
        clearScreen();
      }
      Serial.println();
      Serial.println("Yes - contact switch aligned. Taking a reading....");
      delay(wheelOverRun);
      wheelServo.write(95);
      readColour();
      if (calibrating == 0) {
        matchColour();
        updateCounts();
        updateLCD();
      }
      if (calibrating == 0) {
        printArray(SAMPLES);
      }
      arrayIndexToAimAt = findClosestSample();
      aimChute();
      if (calibrating == 1) {
        waitForUser();
      }
      delay(300);
    } else {
      Serial.println("Skittle moving wheel not aligned with contact switch yet - please gently rotate by hand unless a reading is produced shortly");
      wheelServo.write(126);
    }
  }

  if (Serial.available() > 0) {
    char receivedCommand = Serial.read();
    handleBluetoothCommand(receivedCommand);
  }
}

void handleBluetoothCommand(char command) {
  switch (command) {
    case 'R':
      restartMachine();
      break;
    case 'S':
      stopSorting();
      break;
    default:
      break;
  }
}

void readColour() {
  delay(70);
  tcs.getRGB(&redReading, &greenReading, &blueReading);
  Serial.println("Colour sensor currently reads:  ");
  Serial.print("R:"); Serial.print(int(redReading));
  Serial.print("\tG:"); Serial.print(int(greenReading));
  Serial.print("\tB:"); Serial.println(int(blueReading));
  Serial.println();
}

void matchColour() {
  int colourDistance;

  for (byte i = 0; i < samplesCount; i++) {
    colourDistance = getColourVariance(redReading, greenReading, blueReading, SAMPLES[i][0], SAMPLES[i][1], SAMPLES[i][2], SAMPLES[i][3]);
    SAMPLES[i][4] = colourDistance;
  }
}

int getColourVariance(int redSensor, int greenSensor, int blueSensor, int redSample, int greenSample, int blueSample, char *colour) {
  Serial.print("Checking the skittle against the ");
  Serial.print(colour);
  Serial.println(" sample.");
  int redDifference;
  redDifference = compareValues(redSensor, redSample, "Red ");
  int greenDifference;
  greenDifference = compareValues(greenSensor, greenSample, "Green ");
  int blueDifference;
  blueDifference = compareValues(blueSensor, blueSample, "Blue ");
  Serial.print("Total variance between the measured colour and sample for the ");
  Serial.print(colour);
  Serial.print(" item in the array = ");
  int totalDifference;
  totalDifference = redDifference + greenDifference + blueDifference;
  Serial.println(totalDifference);
  Serial.println();
  return totalDifference;
}

int compareValues(int sensorColour, int sampleColour, char *colour) {
  int difference;
  Serial.print("Comparing Colours:");
  Serial.print(colour);
  Serial.print(int(sensorColour));
  Serial.print(" was measured compared with ");
  Serial.print(int(sampleColour));
  Serial.print(" which has a difference of = ");
  difference = sensorColour - sampleColour;
  if (difference < 0) {
    difference = difference * (-1);
  }
  Serial.println(int(difference));
  return difference;
}

void printArray(const int a[][ arrayColumns ]) {
  for (int i = 0; i < arrayRows; ++i)
{
    for (int j = 0; j < arrayColumns; ++j ) {
      Serial.print(a[i][j]);
      Serial.print(", ");
    }
    Serial.println();
  }
  Serial.println();
}

int findClosestSample() {
  int index = 0;

  for (int i = 0; i < arrayRows; i++) {
    if (SAMPLES[i][4] < SAMPLES[index][4]) {
      index = i;
    }
  }
  Serial.print("The closest sample in the array to the colour just sensed is the array row number ");
  Serial.println(index);
  return index;
}

void aimChute() {
  chuteServo.write(SAMPLES[arrayIndexToAimAt][5]);
}

void clearScreen() {
  for (int i = 0; i <= 80; i++) {
    Serial.println();
  }
}

void waitForUser() {
  Serial.println();
  Serial.println("-----========   Waiting for a single character to be sent before proceeding     ======------");
  while (Serial.available() == 0) {
    delay(1);
  }
  Serial.read();
  Serial.read();
  Serial.read();
}

void updateCounts() {
  if (arrayIndexToAimAt != 5) {
    totalSorts++;
  }

  if (arrayIndexToAimAt == 0) {
    redSorts++;
  } else if (arrayIndexToAimAt == 1) {
    greenSorts++;
  } else if (arrayIndexToAimAt == 2) {
    yellowSorts++;
  } else if (arrayIndexToAimAt == 3) {
    blueSorts++;
  } else if (arrayIndexToAimAt == 4) {
    brownSorts++;
  }
}

void updateLCD() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("T:");
  lcd.print(totalSorts);
  lcd.print("  R:");
  lcd.print(redSorts);
  lcd.print("  G:");
  lcd.print(greenSorts);

  lcd.setCursor(0, 1);
  lcd.print("Y:");
  lcd.print(yellowSorts);
  lcd.print("  B:");
  lcd.print(blueSorts);
  lcd.print("  Br:");
  lcd.print(brownSorts);
}

void stopSorting() {
  // Add code to stop the machine

  // Set servos to a neutral position
  wheelServo.write(95);  // Adjust the value based on your servo's neutral position
  // Additional code for stopping or shutting down the machine
  Serial.println("Stopping the machine...");

  // Perform any other necessary actions or cleanup here
}

void restartMachine() {
  totalSorts = 0;
  redSorts = 0;
  greenSorts = 0;
  yellowSorts = 0;
  blueSorts = 0;
  brownSorts = 0;

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Machine Restarted");
  delay(2000);
}



For the 515 error, check for connection before sending data.

The order of AND clauses is left to right.