Pond Controller with arduino and MIT App Inventer

Ok, so i am creating a pond Controller with an arduino nano as the main controller and an app, made on MIT app inventor 2, communicating over Bluetooth with the arduino. my Problem is that i have the phone app send over a list of all the data points every 100 milliseconds, and the arduino receives them just fine, with the RX led flashing, but it wont process the data or print out what it has gotten for a long time. Then is will suddenly print it all at once and go back to collecting it and doing nothing. I cant find any correlation with when it decides to print what it has received.

#include <EEPROM.h>
#include <Wire.h>
#include "StringSplitter.h"
#include "RTClib.h"
#define Port1 4
#define Port2 5
#define Port3 6
#define Port4 7
#define R 10
#define G 11
#define B 12
#define DeBug 8
StringSplitter *splitter;
String AsciiIN;
int Update;
int P1State;
int P2State;
int P3State;
int P4State;
RTC_DS1307 RTC;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  pinMode (DeBug, INPUT);
  pinMode (Port1, OUTPUT); //Sets Port 1-4 As Outputs
  pinMode (Port2, OUTPUT);
  pinMode (Port3, OUTPUT);
  pinMode (Port4, OUTPUT);
  pinMode (R, OUTPUT); //Sets RGB Pins As Outputs
  pinMode (G, OUTPUT);
  pinMode (B, OUTPUT);
  pinMode (13, OUTPUT);

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  Serial.println("Start Up Done");
}

void loop() {
  // put your main code here, to run repeatedly:
  DateTime now = RTC.now();
  if (Serial.available() > 0) {
    AsciiIN = Serial.readString();
    splitter = new StringSplitter(AsciiIN, ',', 5);  // new StringSplitter(string_to_split, delimiter, limit)
    String Refresh = splitter->getItemAtIndex(0);
    String P1 = splitter->getItemAtIndex(1);
    String P2 = splitter->getItemAtIndex(2);
    String P3 = splitter->getItemAtIndex(3);
    String P4 = splitter->getItemAtIndex(4);
    String RR = splitter->getItemAtIndex(5);
    String GG = splitter->getItemAtIndex(6);
    String BB = splitter->getItemAtIndex(7);
    Update == Refresh.toInt();
    Serial.println(AsciiIN);
    Serial.println(Up);
    Refresh = "";
    if (P1 == "On") {
      digitalWrite(Port1, HIGH);
      P1State = 1;
    }
    if (P1 == "OFF") {
      digitalWrite(Port1, LOW);
      P1State = 2;
    }
    if (P2 == "On") {
      digitalWrite(Port2, HIGH);
      P2State = 1;
    }
    if (P2 == "OFF") {
      digitalWrite(Port2, LOW);
      P1State = 2;
    }
    if (P3 == "On") {
      digitalWrite(Port3, HIGH);
      P2State = 1;
    }
    if (P3 == "OFF") {
      digitalWrite(Port3, LOW);
      P3State = 2;
    }
    if (P4 == "On") {
      digitalWrite(Port4, HIGH);
      P4State = 1;
    }
    if (P4 == "OFF") {
      digitalWrite(Port4, LOW);
      P4State = 2;
    }
  }
  if (Update == 1492) {
    digitalWrite(13, HIGH);
    Serial.print("P1");
    Serial.print(P1State);
    Serial.print(",");
    Serial.print("P2");
    Serial.print(P2State);
    Serial.print(",");
    Serial.print("P3");
    Serial.print(P3State);
    Serial.print(",");
    Serial.print("P4");
    Serial.print(P4State);
    Serial.print(",");
  }

  if (digitalRead(DeBug) == HIGH) {
    Serial.print("Ascii Translation-");
    Serial.println(AsciiIN);
    /*
        Serial.print("1Start-");
        Serial.println(Start1);
        Serial.print("1End-");
        Serial.println(End1);
        Serial.print("2Start-");
        Serial.println(Start2);
        Serial.print("2End-");
        Serial.println(End2);
        Serial.print("3Start-");
        Serial.println(Start3);
        Serial.print("3End-");
        Serial.println(End3);
        Serial.print("4Start-");
        Serial.println(Start4);
        Serial.print("4End-");
        Serial.println(End4);

        Serial.print(now.year(), DEC);
        Serial.print('/');
        Serial.print(now.month(), DEC);
        Serial.print('/');
        Serial.print(now.day(), DEC);
        Serial.print(' ');
        Serial.print(now.hour(), DEC);
        Serial.print(':');
        Serial.print(now.minute(), DEC);
        Serial.print(':');
        Serial.print(now.second(), DEC);
        Serial.println();
        delay(1000);
    */
  }
  AsciiIN = "";
  delay(100);
}

and my MIT Inventor App. Any help is appreciated, Please and thank you. Edit- "The forum will not allow me to add my .aia app file so if you know of any way I can share that please post."

Where does "Up" come from?

BTW if you need to attach a file that Arduino won't 'allow', copy the contents to a .txt file.

I apologise, I cleaned up my code before I posted and I guess I missed one. It should have said "update" not "up", I have fixed it in the first post. I can't post the text thats in an .aia file because in both notepad, and wordpad it comes in a corrupted mess.

Never 'fix it' in the original post. It makes the audit trail (thread) useless as nobody can track changes. Post new code. No shame in making mistakes otherwise you wouldn't be here.

Pins and ports are very different things on the Arduino. Do NOT name pins PortX.

OK so i changed the names of Port1,2,3,4 to Output1,2,3,4
and here is the updated sketch

#include <EEPROM.h>
#include <Wire.h>
#include "StringSplitter.h"
#include "RTClib.h"
#define Output1 4
#define Output2 5
#define Output3 6
#define Output4 7
#define R 10
#define G 11
#define B 12
#define DeBug 8
StringSplitter *splitter;
String AsciiIN;
int Update;
int P1State;
int P2State;
int P3State;
int P4State;
RTC_DS1307 RTC;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  pinMode (DeBug, INPUT);
  pinMode (Output1, OUTPUT); //Sets Port 1-4 As Outputs
  pinMode (Output2, OUTPUT);
  pinMode (Output3, OUTPUT);
  pinMode (Output4, OUTPUT);
  pinMode (R, OUTPUT); //Sets RGB Pins As Outputs
  pinMode (G, OUTPUT);
  pinMode (B, OUTPUT);
  pinMode (13, OUTPUT);

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  Serial.println("Start Up Done");
}

void loop() {
  // put your main code here, to run repeatedly:
  DateTime now = RTC.now();
  if (Serial.available() > 0) {
    AsciiIN = Serial.readString();
    splitter = new StringSplitter(AsciiIN, ',', 7);  // new StringSplitter(string_to_split, delimiter, limit)
    String Refresh = splitter->getItemAtIndex(0);
    String P1 = splitter->getItemAtIndex(1);
    String P2 = splitter->getItemAtIndex(2);
    String P3 = splitter->getItemAtIndex(3);
    String P4 = splitter->getItemAtIndex(4);
    String RR = splitter->getItemAtIndex(5);
    String GG = splitter->getItemAtIndex(6);
    String BB = splitter->getItemAtIndex(7);
    Update == Refresh.toInt();
    Serial.println(AsciiIN);
    Serial.println(Up);
    Refresh = "";
    if (P1 == "On") {
      digitalWrite(Output1, HIGH);
      P1State = 1;
    }
    if (P1 == "OFF") {
      digitalWrite(Output1, LOW);
      P1State = 2;
    }
    if (P2 == "On") {
      digitalWrite(Output2, HIGH);
      P2State = 1;
    }
    if (P2 == "OFF") {
      digitalWrite(Output2, LOW);
      P1State = 2;
    }
    if (P3 == "On") {
      digitalWrite(Output3, HIGH);
      P2State = 1;
    }
    if (P3 == "OFF") {
      digitalWrite(Output3, LOW);
      P3State = 2;
    }
    if (P4 == "On") {
      digitalWrite(Output4, HIGH);
      P4State = 1;
    }
    if (P4 == "OFF") {
      digitalWrite(Output4, LOW);
      P4State = 2;
    }
  }
  if (Update == 1492) { //1492 is an arbitrary value i use to signal that if conditional. 
    digitalWrite(13, HIGH);
    Serial.print("P1");
    Serial.print(P1State);
    Serial.print(",");
    Serial.print("P2");
    Serial.print(P2State);
    Serial.print(",");
    Serial.print("P3");
    Serial.print(P3State);
    Serial.print(",");
    Serial.print("P4");
    Serial.print(P4State);
    Serial.print(",");
  }

  if (digitalRead(DeBug) == HIGH) {
    Serial.print("Ascii Translation-");
    Serial.println(AsciiIN);
    /*
        Serial.print("1Start-");
        Serial.println(Start1);
        Serial.print("1End-");
        Serial.println(End1);
        Serial.print("2Start-");
        Serial.println(Start2);
        Serial.print("2End-");
        Serial.println(End2);
        Serial.print("3Start-");
        Serial.println(Start3);
        Serial.print("3End-");
        Serial.println(End3);
        Serial.print("4Start-");
        Serial.println(Start4);
        Serial.print("4End-");
        Serial.println(End4);

        Serial.print(now.year(), DEC);
        Serial.print('/');
        Serial.print(now.month(), DEC);
        Serial.print('/');
        Serial.print(now.day(), DEC);
        Serial.print(' ');
        Serial.print(now.hour(), DEC);
        Serial.print(':');
        Serial.print(now.minute(), DEC);
        Serial.print(':');
        Serial.print(now.second(), DEC);
        Serial.println();
        delay(1000);
    */
  }
  AsciiIN = "";
  delay(100);
}

I put my MIT app inventor app in the zip attached below.

PondController.zip (180 KB)

    AsciiIN = Serial.readString();

That is the poorest way possible to read serial data. That function reads until there is no more data in the buffer and the WAITS for more data. The time that it waits is adjustable, but there are far batter ways to know when to stop reading.

Find Robin2's "Serial Input Basics - Updated" thread and read it front to back, top to bottom.

You would be talking about Serial Input Basics - updated - Introductory Tutorials - Arduino Forum With Example 3 being the best option for this application Correct.

MR-Turtle:
You would be talking about Serial Input Basics - updated - Introductory Tutorials - Arduino Forum With Example 3 being the best option for this application Correct.

Example 3 is a good option. Whether or not it is the best option is for you to decide.

Ok, so i have spent some time implementing Robin2's example 3 code into my existing code. But now it just completely freezes after receiving a few lines generally about 1 or 2 lines before it stops responding.

#include <EEPROM.h>
#include <Wire.h>
#include "StringSplitter.h"
#include "RTClib.h"
#define Output1 4
#define Output2 5
#define Output3 6
#define Output4 7
#define R 10
#define G 11
#define B 12
#define DeBug 8
StringSplitter *splitter;
String AsciiIN;
int Update;
int P1State = 1;
int P2State = 1;
int P3State = 2;
int P4State = 2;
const byte numChars = 32;
char receivedChars[numChars];
boolean newData = false;
RTC_DS1307 RTC;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  pinMode (DeBug, INPUT);
  pinMode (Output1, OUTPUT); //Sets Port 1-4 As Outputs
  pinMode (Output2, OUTPUT);
  pinMode (Output3, OUTPUT);
  pinMode (Output4, OUTPUT);
  pinMode (R, OUTPUT); //Sets RGB Pins As Outputs
  pinMode (G, OUTPUT);
  pinMode (B, OUTPUT);
  pinMode (13, OUTPUT);

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  Serial.println("Start Up Done");
}

void loop() {
  // put your main code here, to run repeatedly:
  DateTime now = RTC.now();
  recvWithStartEndMarkers();
  showNewData();
    Serial.print(P1State);
    Serial.print(",");
    Serial.print(P2State);
    Serial.print(",");
    Serial.print(P3State);
    Serial.print(",");
    Serial.println(P4State);
    /*
    Serial.print(1);
    Serial.print(",");
    Serial.print(1);
    Serial.print(",");
    Serial.print(2);
    Serial.print(",");
    Serial.println(2);
*/
  delay(100);
}
void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
    AsciiIN = receivedChars;
    splitter = new StringSplitter(receivedChars, ',', 7);  // new StringSplitter(string_to_split, delimiter, limit)
    String Refresh = splitter->getItemAtIndex(7);
    String P1 = splitter->getItemAtIndex(0);
    String P2 = splitter->getItemAtIndex(1);
    String P3 = splitter->getItemAtIndex(2);
    String P4 = splitter->getItemAtIndex(3);
    String RR = splitter->getItemAtIndex(4);
    String GG = splitter->getItemAtIndex(5);
    String BB = splitter->getItemAtIndex(6);
    Update == Refresh.toInt();
    //Serial.println(AsciiIN);
    //Serial.println(Update);
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

And my MIT app if you need it-

PondControler.zip (181 KB)

I Did find my problem for any one else that stumbles onto this thread, my problem was Heap Memory Fragmentation Caused by the arduino string class. i was splitting up my main inputs into strings at it was to many. So i used Robin2's Serial input basics Serial Input Basics - updated - Introductory Tutorials - Arduino Forum and example number 5 it fixed my problem hopefully it fixes yours.