Particle photon can't connect cloud after it run the function once

Hello,

I met a problem when I use particle photon. Each time when the photon run the “selectE()” function, it will disconnect the cloud. Once it disconnects the cloud, it can’t connect to the cloud anymore, even through I added some code like this"

  if (Particle.connected() == false) {
    Particle.connect();
  }

This is my code, I really hope someone can help me solve this issue.

// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_SSD1306.h"

// This #include statement was automatically added by the Particle IDE.
#include "Adafruit_GFX.h"


#define OLED_RESET D4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 0
#define DELTAY 1

int gsr = A3, pot = A2, motor = D3;
int gsrV, gsrT, potV; 

int led = D7;

String emotionV;

boolean flag = false;

unsigned long previousMillis = 0;
unsigned long interval = 5*60*1000;


void setup() {
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
    display.clearDisplay();
    
    pinMode(pot,INPUT);
    pinMode(gsr, INPUT);
    pinMode(motor, OUTPUT);
    pinMode(led,OUTPUT);
    
    display.setTextSize(2);           // from 1-9 sensible actually can be bigger but useless
    display.setTextColor(WHITE,BLACK); // 'inverted' text
    display.setCursor(0,30);       // 128,64 pixels
    display.clearDisplay();
    display.println("Hello");
    display.display();
    delay(3000);
    display.clearDisplay();
}

void selectE(){
    if (Particle.connected() == false) {
        Particle.connect();
    }
    Particle.publish("input section start","start");

    display.setTextColor(WHITE,BLACK);
    display.clearDisplay();
    for(int i=0; i<50; i++){
     //Particle.publish("potV", String(potV));
        potV = analogRead(pot);
        if(potV<=1820){
            //display.clearDisplay();
            if(potV<=455){
                display.fillCircle(3,5,3,WHITE);
                display.setTextSize(2);
                display.setCursor(8,0);
                display.println("Enjoyment");
                display.setTextSize(1);
                display.setCursor(60,20);
                display.println("Frustrated");
                display.setCursor(60,32);
                display.println("Relax");
                display.setCursor(60,45);
                display.println("Bored");
                display.setCursor(60,60);
                display.println("Nothing");
                emotionV = "Enjoyment";
            } else if(potV>455 && potV<=910){
                display.fillCircle(3,15,3,WHITE);
                display.setTextSize(1);
                display.setCursor(60,0);
                display.println("Enjoyment");
                display.setTextSize(2);
                display.setCursor(8,12);
                display.println("Frustrated");
                display.setTextSize(1);
                display.setCursor(60,30);
                display.println("Relax");
                display.setCursor(60,45);
                display.println("Bored");
                display.setCursor(60,60);
                display.println("Nothing");
                emotionV = "Frustrated";
            } else if(potV>910 && potV<=1365){
                display.fillCircle(3,30,3,WHITE);
                display.setTextSize(1);
                display.setCursor(60,0);
                display.println("Enjoyment");
                display.setCursor(60,15);
                display.println("Frustrated");
                display.setTextSize(2);
                display.setCursor(8,25);
                display.println("Relax");
                display.setTextSize(1);
                display.setCursor(60,45);
                display.println("Bored");
                display.setCursor(60,60);
                display.println("Nothing");
                emotionV = "Relax";
            } else if(potV>1365 && potV<=1820){
                display.fillCircle(3,45,3,WHITE);
                display.setTextSize(1);
                display.setCursor(60,0);
                display.println("Enjoyment");
                display.setCursor(60,13);
                display.println("Frustrated");
                display.setCursor(60,25);
                display.println("Relax");
                display.setTextSize(2);
                display.setCursor(8,40);
                display.println("Bored");
                display.setTextSize(1);
                display.setCursor(60,60);
                display.println("Nothing");
                emotionV = "Bored";
            }
            display.display();
        } else if(potV>1820 && potV<=3640){
            display.clearDisplay();
            if(potV>1820 && potV<=2275){
                display.fillCircle(3,5,3,WHITE);
                display.setTextSize(2);
                display.setCursor(8,0);
                display.println("Nothing");
                display.setTextSize(1);
                display.setCursor(60,20);
                display.println("Pride");
                display.setCursor(60,32);
                display.println("Anxiety");
                display.setCursor(60,45);
                display.println("Content");
                display.setCursor(60,60);
                display.println("Hopeless");
                emotionV = "Nothing";
            } else if(potV>2275 && potV<=2730){
                display.fillCircle(3,15,3,WHITE);
                display.setTextSize(1);
                display.setCursor(60,0);
                display.println("Nothing");
                display.setTextSize(2);
                display.setCursor(8,12);
                display.println("Pride");
                display.setTextSize(1);
                display.setCursor(60,30);
                display.println("Anxiety");
                display.setCursor(60,45);
                display.println("Content");
                display.setCursor(60,60);
                display.println("Hopeless");
                emotionV = "Pride";
                emotionN= 3;
            } else if(potV>2730 && potV<=3185){
                display.fillCircle(3,30,3,WHITE);
                display.setTextSize(1);
                display.setCursor(60,0);
                display.println("Nothing");
                display.setCursor(60,15);
                display.println("Pride");
                display.setTextSize(2);
                display.setCursor(8,25);
                display.println("Anxiety");
                display.setTextSize(1);
                display.setCursor(60,45);
                display.println("Content");
                display.setCursor(60,60);
                display.println("Hopeless");
                emotionV = "Anxiety";
            } else if(potV>3185 && potV<=3640){
                display.fillCircle(3,45,3,WHITE);
                display.setTextSize(1);
                display.setCursor(60,0);
                display.println("Nothing");
                display.setCursor(60,13);
                display.println("Pride");
                display.setCursor(60,25);
                display.println("Anxiety");
                display.setTextSize(2);
                display.setCursor(8,40);
                display.println("Content");
                display.setTextSize(1);
                display.setCursor(60,60);
                display.println("Hopeless");
                emotionV = "Content";
            }
            display.display();
        } else {
            display.clearDisplay();
            display.setTextSize(2);
            display.setCursor(8,0);
            display.println("Hopeless");
            display.fillCircle(3,5,3,WHITE);
            emotionV = "Hopeless";
            display.display();
        }
        delay(10);
    }
        display.clearDisplay();
        display.setCursor(20,20);
        display.setTextColor(BLACK,WHITE);
        display.println("end");
        display.display();
        Particle.publish("emotion", String(emotionV));
        Particle.publish("input section end", "end");

}

void loop() {
    display.clearDisplay();
    display.display();
    gsrV = analogRead(gsr);
    //Particle.publish("emotion_gsr", String(gsrV));
    delay(1000);
    gsrT = analogRead(gsr);
    int temp = abs(gsrV - gsrT);
    Particle.publish("temp",String(temp));
    if(abs(gsrV - gsrT)>30){
        flag = true;
    } else {
        flag = false;
    }
    
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis < interval){
        if(flag){
            analogWrite(motor,80);
            delay(1000);
            analogWrite(motor,0);
            delay(1000);
            selectE();
            flag = false;
            display.clearDisplay();
        } else {
            flag = false;
        }
    } 
    if(currentMillis - previousMillis >= interval){
        if(flag == false){
            analogWrite(motor,80);
            delay(1000);
            analogWrite(motor,0);
            delay(1000);
            selectE();
            display.clearDisplay();
            previousMillis = currentMillis;
        } else {
            previousMillis = currentMillis;
        }
    }
    
    //  Particle.publish("thingSpeakWrite_All", "{ \"1\": \"" + String(gsrV) + "\"," +
    //   "\"2\": \"" + String(emotionN) + "\"," +
    //   "\"k\": \"" + key + "\" }", 60, PRIVATE);
    
}

Hi,

Well having a read through your code, and pointing out I’m no expert… But for what its worth here are thoughts :slight_smile:

You are checking that you are connected to the cloud in your display function. Seems a bit odd to me. Not knowing your whole project, all I can suggest is that not a good idea.

Also if your not connected, you are calling for a connection. But your not waiting for the connection to establish. I’m not sure if the call for a connection is a blocking procedure. But if its not, your not giving the code time to connect.

Those are my thoughts.

Liam

I concur with @VideoLiam.

  1. You use Particle.connect() but do not wait for the connection. And it is possible that you call it again successively while establishing the connection. If you call Particle.connect() while a connection is establishing, you may just as well kill the partial connection and try to re-establish… which puts you into an endless loop of trying to connect.

  2. You make multiple Particle.publish() calls and you may be are violating the 1 publish per second rule (or 4 publishes per second with a 4 second cool down.) You should manage the publish times better or use a publish manager such as PublishQueueAsyncRK.

  3. You make multiple delays(). If you delay for more than 10 seconds (which I don’t think you are) the cloud connection will not be serviced and will disconnect. Perhaps modeling your code more like a Finite State Machine (FSM) would better manage the states and what is currently processing. Go after the first two points before this one.

2 Likes

To clarify some things, with default SYSTEM_MODE(AUTOMATIC) in absence of SYSTEM_THREAD(ENABLED) and without actively disconnecting from cloud the user application will almost immediately stop running and the system will purely focus on reestablishing the cloud connection.
Hence Particle.connect() nor a Particle.connected() check are required - nor does one need to wait for the connect call to return as it won’t.

But all of the above suggestions are considered good practice and hence should be applied whenever possible.
However that won’t be the reason for the issue.

I’d put my money on @ninjatill’s #3 and add the question: “What are these 50 repetitions for?”

    for(int i=0; i<50; i++){
      // i is never used in here so everything is 
      // done exactly the same but 50 times????
    }

(the analogRead() should better be done between calls of that function than in a tight loop)

Also the whole display printing logic could do with a good overhaul to reduce repetition of code even more.

A starting point for the overhaul might be to replace these range checks with something like this

  int category = map(analogRead(pot), 0, 4095, 1, 9); // each category ~455 steps
  switch (category) {
    case 1:
      // distinct stuff for that case stored in variables
      break;
    case 2:
      // distinct stuff for that case stored in variables
      break;
    case 3:
    case 4:
    case 5: 
      // a wider ranged category
      // distinct stuff for that case stored in variables
      break;
    case 6:
      // distinct stuff for that case stored in variables
      break;
    default:
      // whatever else
      break;   
  }
  // do the common stuff and use the variables from above
3 Likes
    for(int i=0; i<50; i++){
      // i is never used in here so everything is 
      // done exactly the same but 50 times????
    }

Since I use a potentiometer to select different options in a menu, and after the potentiometer stops on an option last for 30 seconds, it will automatically confirm the option.
20181218135422
I don’t know how to write this function in a smart way:joy:

I tried with the following code, however, it always cause cloud disconnect.

  unsigned long previousMillis = 0;
   unsigned long currentMillis = millis();
unsigned long interValue = 30000;
 while(currentMillis - previousMillis < interValue){
   // do something
}
previousMillis = currentMillis;

Call Particle.process() inside of that while().

But the idea is to get rid of that while() completely and rather measure the time the current options has been selected.

So together with my previous suggestion, you could do

const uint32_t SELECT_TIME = 30000; // time before a selection gets activated 

void loop() {
  static uint32_t msCat = 0;        // how long was the current category already selected?
  static int prevCat = -1;          // which category had been selected last

  int category = map(analogRead(pot), 0, 4095, 1, 9); // each category ~455 steps

  if (category == prevCat) {
    if (millis() - msCat > SELECT_TIME) {
      // mark as selected and do stuff
    }
  }
  else {
    // update display according to new selection
    prevCat = category;
    msCat = millis();
  } 
}

This way there is no need for the for() or while() loops inside loop() and it will reduce flicker on the display too.

1 Like