Help with a thingspeak - arduino nodemcu 8266 program

Hello , So This is a follow up from another thread since it went more into programmin on thingspeak I have created a thread more focused on this ...

My goal is :

I have a proximity sensor HC-SR501 and a nodemcu 8266 , what I want to do is to send data there so that I can recognize when there is activity presence ... so I need at least one variable signalling the activity everytime, this should be ok with the high state I guess... I have a led popping up everytime this happens going low when activity is over, which is controlled by the second variable motionstate.
I wanted to add a third variable for spawning an activity inside another program , I want this asctivity to be launched at the first time there is sensor activity , and I want it to last for about a minute or two after this time the activity in this other program needs to disappear and so needs the arduino get a signal from that program with a write function to set the third variable spawn to 0 ... once this is done if a new activity is detected there is again a spawn set to 1 and so on , but for all the time that I do not receive a signal from the external program the spwan should remain one and not be updated or at least not send me continuously spwans to the external program .
Is this the right way to program it ? Or is better another way ? I am not sure if I am doing this well ...

Here is the preliminary code :

#include "ThingSpeak.h"                                 // Include ThingSpeak Library
#include <ESP8266WiFi.h>  

//Replace  wifi credentials here

 Analytics Cloud platform.
const char* ssid     = "*******************";
const char* password = "*******************";
unsigned long myChannelNumber  = *******************; //change  channel number here
const char *server = "api.thingspeak.com"; //Initializing Server.
const char * apiKey = "*******************";        // Enter your ThingSpeak API Key


int LED = 12 ;                // Choose the pin for the LED (Pin D6, GPIO 13) 
int sensor = 13;              // Choose the input pin for motion sensor (Pin D7, GPIO 14)                            // Choose the input pin for motion sensor (Pin D6, GPIO 12)
int motionState = 0;           //  start, assuming no motion detected
int val = 0;                  // Variable for reading the pin status
int spawn = 0; // Variable to spawn 

unsigned long currentMillis = millis();
unsigned long previousMillis = 0;
unsigned long resetMillis = 0;
const long interval = 90000;   // Time delay interval (90 seconds) to prevent false triggers when setting up device 
                                                       
int status = WL_IDLE_STATUS;

WiFiClient  client;
// Program written in setup will run only once for connecting to Wi-Fi network.
      
void setup() {
  
  WiFi.begin(ssid, password); // Start //WiFi connection
  
  ThingSpeak.begin(client);  // Start ThingSpeak connection
  Serial.begin(115200); // Serial Baud Rate
  delay(500);
  pinMode(sensor,INPUT); // declare sensor as input
  pinMode (LED,OUTPUT); // Declares LED As output
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid); 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("."); 
    }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("Netmask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Gateway: ");
  Serial.println(WiFi.gatewayIP());
  Serial.println("Motion Sensor presence");
  ThingSpeak.setField( (unsigned int) 1, (int) val ) ;          // store field 1   
  ThingSpeak.setField( (unsigned int) 2, (int) spawn ) ;        // store field 2
  ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                                 
 

}

void loop (){
//********************* Read motion sensor and upload to ThingSpeak ***************************** 
 currentMillis = millis();                                                 // Set the currentMillis equal to the millis function

val = digitalRead(sensor);    

long state = digitalRead (sensor); 
            if (val == HIGH)    {
              if ((motionState == 0) && (currentMillis >= interval))
                {                                                        
                  digitalWrite(LED, HIGH);                                         // Turn LED ON
                  Serial.println("Motion detected!");                                 // Motion Detected                                                       
                  motionState = 1;  
                  ThingSpeak.setField( (unsigned int) 1, (int) val ) ;          // store field 1   
                 // ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;  // store field 2
                  ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                  Serial.println("Data Sent to ThingSpeak!");  
                  delay(500);                  
                }
              } 
              else 
              {
                digitalWrite(LED, LOW);                                            // Turn LED OFF
                if (motionState == 1)
                {                                                                     // Motion stopped                                                      
                  Serial.println("Motion ended!");                                                                          
                  motionState = 0; 
                  ThingSpeak.setField( (unsigned int) 1, (int) val ) ;          // store field 1   
                  //ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;  // store field 2
                  ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                  Serial.println("Data Sent to ThingSpeak!");  
                  delay(500);  
                               
                }
              }    
             
 if (currentMillis - previousMillis >= 10000)                             // Update Serial Monitor every ten seconds (10000 milliseonds)
 {                                                                        // as to how long the program has been running
 Serial.print("Program running for ");
 Serial.print((currentMillis/1000)/60);
 Serial.println(" Minutes"); 
 previousMillis = currentMillis;
 yield();                                                                 // Yield to prevent the WDT from crashing the NodeMCU
 }
 
if ((val == HIGH) && (spawn==0) && (currentMillis - previousMillis >= interval) )        
                {                                                                                     
                 spawn = 1;
                 ThingSpeak.setField( (unsigned int) 2, (int) spawn ) ;  // store field 2
                 ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                 Serial.println("Data Sent to ThingSpeak!");  
                 delay(interval);   
                 yield();                                           
                }
}  

Any Sugestions?

I don't think that, at the moment, your problems are related to Thingspeak but more about the logic of the application. You have anyway said that at least a basic communication with Thingspeak now works.

So that it is clear what you are trying to do, you should try to draw a timeline showing the state of the variables on the vertical access and time on the horizontal axis. It appears anyway that the variables are boolean having only states 0 and 1. Start your timeline a minute before the PIR is triggered and finish it a few minutes after any activity has stopped. Annotate it with relevant actions your program should take.

The timeline would look a bit like a logic analyser trace. This is just an example.

Sorry I am not expert on this, but what do you mean in specific that I should do ? How I draw this timeline?

Ok to make some debugging I added a counter ...

#include "ThingSpeak.h"                                 // Include ThingSpeak Library
#include <ESP8266WiFi.h>  

//Replace  wifi credentials here

//String apiKey = "*****************";     //  Enter your Write API key from ThingSpeak IoT Analytics Cloud platform.
const char* ssid     = "*****************";
const char* password = "*****************";
unsigned long myChannelNumber  = *****************; //change  channel number here
const char *server = "api.thingspeak.com"; //Initializing Server.
const char * apiKey = "*****************";        // Enter your ThingSpeak API Key

int LED2 = 14 ;                // Choose the pin for the LED (Pin D5, GPIO 14) 
int LED = 12 ;                // Choose the pin for the LED (Pin D6, GPIO 13) 
int sensor = 13;              // Choose the input pin for motion sensor (Pin D7, GPIO 14)                            // Choose the input pin for motion sensor (Pin D6, GPIO 12)
int motionState = 0;           //  start, assuming no motion detected
int val = 0;                  // Variable for reading the pin status
int spawn = 0; // Variable to spawn 
// Variables will change: contaore
int SensorPushCounter = 0;   // counter for the number of sensor activities
int SensorState = 0;         // current state of the sensor
int lastSensorState = 0;     // previous state of the sensor

unsigned long currentMillis = millis();
unsigned long previousMillis = 0;
unsigned long resetMillis = 0;
const long interval = 90000;   // Time delay interval (90 seconds) to prevent false triggers when setting up device 
                                                       
int status = WL_IDLE_STATUS;

WiFiClient  client;
// Program written in setup will run only once for connecting to Wi-Fi network.
      
void setup() {
  
  WiFi.begin(ssid, password); // Start //WiFi connection
  
  ThingSpeak.begin(client);  // Start ThingSpeak connection
  Serial.begin(115200); // Serial Baud Rate
  delay(500);
  pinMode(sensor,INPUT); // declare sensor as input
  pinMode (LED,OUTPUT); // Declares LED As output
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid); 
  while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print("."); 
    }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("Netmask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Gateway: ");
  Serial.println(WiFi.gatewayIP());
  Serial.println("Motion Sensor presence");
  ThingSpeak.setField( (unsigned int) 1, (int) val ) ;                 // store field 1   
  ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;        // store field 2
  ThingSpeak.setField( (unsigned int) 3, (int) spawn ) ;             // store field 3
  ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                                 
 

}

void loop (){
//********************* Read motion sensor and upload to ThingSpeak ***************************** 
 currentMillis = millis();                                                 // Set the currentMillis equal to the millis function

val = digitalRead(sensor);      
SensorState = digitalRead(sensor);
long state = digitalRead (sensor); 
            if (val == HIGH)    
            {
              if ((motionState == 0) && (currentMillis >= interval) )
                { digitalWrite(LED, HIGH);                                         // Turn LED ON
                  Serial.println("Motion detected!");                                 // Motion Detected                                                       
                  motionState = 1;                                        
                  ThingSpeak.setField( (unsigned int) 1, (int) val ) ;          // store field 1   
                  ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;  // store field 2
                  ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                  Serial.println("Data Sent to ThingSpeak!");  
                  delay(500);                  
                }
              }   
              else 
              {
                digitalWrite(LED, LOW);                                            // Turn LED OFF
                if (motionState == 1)
                {                                                                     // Motion stopped                                                      
                  Serial.println("Motion ended!");                                                                          
                  motionState = 0; 
                  ThingSpeak.setField( (unsigned int) 1, (int) val ) ;          // store field 1   
                  ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;  // store field 2
                  ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                  Serial.println("Data Sent to ThingSpeak!");  
                  delay(500);  
                               
                }
              }    
             
 if   (currentMillis - previousMillis >= 10000)                // Update Serial Monitor every ten seconds (10000 milliseonds)
 {                                                              // as to how long the program has been running
 Serial.print("Program running for ");
 Serial.print((currentMillis/1000)/60);
 Serial.println(" Minutes"); 
 previousMillis = currentMillis;
 yield();                                                                 // Yield to prevent the WDT from crashing the NodeMCU
 }
if ((SensorState != lastSensorState) && (currentMillis >= interval)){
    // if the Sensor state has changed, increment the counter
    if (SensorState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      SensorPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(SensorPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastSensorState = SensorState;


  // turns on the LED every ten sensor activities by checking the modulo of the
  // counter. the modulo function gives you the remainder of the
  // division of two numbers:
  if (SensorPushCounter % 10 == 0) {
    digitalWrite(LED2, HIGH);                                            // Turn LED OFF
               
  } else {
    digitalWrite(LED2, LOW); ;
  }

} 

I also added a new LED to check when on and off its been counted 10 activities, but ... doesn't work , I do never see the LED getting on state , why ?
nvm I forgot to add declaration of LED2 as output!

Ok here is my new code, it almoust works but for some reason it seems a little buggy and the spawn variable seems passed sometimes, and some other times doesn't ... when I have the blue light on which means there is a spawn , the spawn variable in teamspeak remains to 0 , why that?

#include "ThingSpeak.h"                                 // Include ThingSpeak Library
#include <ESP8266WiFi.h>  

//Replace  wifi credentials here

//String apiKey = "****************";     //  Enter your Write API key from ThingSpeak IoT Analytics Cloud platform.
const char* ssid     = "****************";
const char* password = "****************";
unsigned long myChannelNumber  = ****************; //change  channel number here
const char *server = "api.thingspeak.com"; //Initializing Server.
const char * apiKey = "****************";        // Enter your ThingSpeak API Key

int LED2 = 15 ;                // Choose the pin for the LED (Pin D5, GPIO 14) 
int LED = 12 ;                // Choose the pin for the LED (Pin D6, GPIO 13) 
int sensor = 13;              // Choose the input pin for motion sensor (Pin D7, GPIO 14)                            // Choose the input pin for motion sensor (Pin D6, GPIO 12)
int motionState = 0;           //  start, assuming no motion detected
int val = 0;                  // Variable for reading the pin status
int spawn = 0; // Variable to spawn 
// Variables will change: contaore
int SensorPushCounter = 0;   // counter for the number of sensor activities
int SpawnCounter = 0;   // counter for the number of sensor activities 
int SensorState = 0;         // current state of the sensor
int lastSensorState = 0;     // previous state of the sensor

unsigned long currentMillis = millis();
unsigned long timer = 0 ;
unsigned long spawnttime =0 ;
unsigned long previousMillis = 0;
unsigned long resetMillis = 0;
const long interval = 9000;   // Time delay interval (90 seconds) to prevent false triggers when setting up device 
                                                       
int status = WL_IDLE_STATUS;

WiFiClient  client;
// Program written in setup will run only once for connecting to Wi-Fi network.
      
void setup() {
  
  WiFi.begin(ssid, password); // Start //WiFi connection
  
  ThingSpeak.begin(client);  // Start ThingSpeak connection
  Serial.begin(115200); // Serial Baud Rate
  delay(500);
  pinMode(sensor,INPUT); // declare sensor as input
  pinMode (LED,OUTPUT); // Declares LED As output
  pinMode (LED2,OUTPUT); // Declares LED As output
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid); 
  while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  Serial.print("."); 
    }

  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("Netmask: ");
  Serial.println(WiFi.subnetMask());
  Serial.print("Gateway: ");
  Serial.println(WiFi.gatewayIP());
  Serial.println("Motion Sensor presence");
  ThingSpeak.setField( (unsigned int) 1, (int) val ) ;                 // store field 1   
  ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;        // store field 2
  ThingSpeak.setField( (unsigned int) 3, (int) spawn ) ;             // store field 3
  ThingSpeak.setField( (unsigned int) 4, (int) SensorPushCounter ) ;  // store field 4
  ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                                 
 

}

void loop (){
//********************* Read motion sensor and upload to ThingSpeak ***************************** 
 currentMillis = millis();                                                 // Set the currentMillis equal to the millis function

val = digitalRead(sensor);      
SensorState = digitalRead(sensor);
long state = digitalRead (sensor); 
            if (val == HIGH)    
            {
              if ((motionState == 0) && (currentMillis >= interval) )
                { digitalWrite(LED, HIGH);                                      // Turn LED ON
                  Serial.println("Motion detected!");                                 // Motion Detected                                                       
                  motionState = 1;  
                  ThingSpeak.setField( (unsigned int) 1, (int) val ) ;                 // store field 1   
                  ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;        // store field 2
                  ThingSpeak.setField( (unsigned int) 3, (int) spawn ) ;             // store field 3
                  ThingSpeak.setField( (unsigned int) 4, (int) SensorPushCounter ) ;  // store field 4
                  ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                  Serial.println("Data Sent to ThingSpeak!");  
                                  delay(500);                  
                }
              }   
              else 
              {
                digitalWrite(LED, LOW);                                         // Turn LED OFF
                if (motionState == 1)
                {                                                                     // Motion stopped                                                      
                  Serial.println("Motion ended!");                                                                          
                  motionState = 0; 
                  ThingSpeak.setField( (unsigned int) 1, (int) val ) ;                 // store field 1   
                  ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;        // store field 2
                  ThingSpeak.setField( (unsigned int) 3, (int) spawn ) ;             // store field 3
                  ThingSpeak.setField( (unsigned int) 4, (int) SensorPushCounter ) ;  // store field 4
                  ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                  Serial.println("Data Sent to ThingSpeak!");   
                  delay(500);  
                               
                }
              }    
             
 if   (currentMillis - previousMillis >= 10000)                // Update Serial Monitor every ten seconds (10000 milliseonds)
 {                                                              // as to how long the program has been running
 Serial.print("Program running for ");
 Serial.print((currentMillis/1000)/60);
 Serial.println(" Minutes"); 
 previousMillis = currentMillis;
 yield();                                                                 // Yield to prevent the WDT from crashing the NodeMCU
 }
if ((SensorState != lastSensorState) && (currentMillis >= interval))
{
    // if the Sensor state has changed, increment the counter
    if (SensorState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      SensorPushCounter++;
      SpawnCounter++;
      Serial.println("on");
      Serial.print("numero di passaggi davanti il sensore: ");
      Serial.println(SensorPushCounter);
      Serial.print("numero di passaggi davanti il sensore dopo la generazione del personaggio : ");
      Serial.println(SpawnCounter-1);
                          // turns on the LED every ten sensor activities by checking the modulo of the
                          // counter. the modulo function gives you the remainder of the
                          // division of two numbers:
                          //if ((SensorPushCounter % 10 == 0)) {
                          // digitalWrite(LED2, HIGH);    
                          //Serial.println("blue on");
                          //delay(500);   
                           
                          if  (SpawnCounter == 1)
                          { 
                          spawn = 1; // spawns character at counter == 1
                          digitalWrite(LED2, HIGH);
                          Serial.println("generato un personaggio");
                          spawnttime = (((millis())/1000)/60);
                          
                          Serial.print ("tempo di generazione : "); Serial.println(spawnttime); Serial.println(" minuti");
                          ThingSpeak.setField( (unsigned int) 1, (int) val ) ;                 // store field 1   
                          ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;        // store field 2
                          ThingSpeak.setField( (unsigned int) 3, (int) spawn ) ;             // store field 3
                          ThingSpeak.setField( (unsigned int) 4, (int) SensorPushCounter ) ;  // store field 4
                          ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                          Serial.println("Data Sent to ThingSpeak!");  
                  
                         }
                           else if ((spawn = 1) &&((timer-spawnttime)>=2))  // despawns if time difference superior to 2 minute ...
                           {  
                           timer = (((millis())/1000)/60);
                           Serial.print("timer : ");   Serial.print(timer); Serial.println(" minuti"); 
                           Serial.print("spawnttime :");  Serial.print(spawnttime); Serial.println(" minuti"); 
                           Serial.print("differenza timer :");  Serial.print(timer-spawnttime);   Serial.println(" minuti"); 
                           Serial.println("cancellato il personaggio");
                           SpawnCounter =0 ;  Serial.println("reset timer");
                           spawn = 0;
                           Serial.println("blue off"); digitalWrite(LED2, LOW); 
                           ThingSpeak.setField( (unsigned int) 1, (int) val ) ;                 // store field 1   
                           ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;        // store field 2
                           ThingSpeak.setField( (unsigned int) 3, (int) spawn ) ;             // store field 3
                           ThingSpeak.setField( (unsigned int) 4, (int) SensorPushCounter ) ;  // store field 4
                           ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                           Serial.println("Data Sent to ThingSpeak!");  
                           }
                         else if ((SensorPushCounter >= 29)) // Resets counter after 30  
                          { 
                          SensorPushCounter =0 ;  
                          Serial.println("reset counter");
                          ThingSpeak.setField( (unsigned int) 1, (int) val ) ;                 // store field 1   
                          ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;        // store field 2
                          ThingSpeak.setField( (unsigned int) 3, (int) spawn ) ;             // store field 3
                          ThingSpeak.setField( (unsigned int) 4, (int) SensorPushCounter ) ;  // store field 4
                          ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
                          Serial.println("Data Sent to ThingSpeak!");  
                         }
                           else 
                          {                            
                           timer = (((millis())/1000)/60); 
                           Serial.print("tempo corrente : "); Serial.print (timer); Serial.println("minuti"); 
                           Serial.print("tempo spawn : ");  Serial.print (spawnttime);Serial.println("minuti"); 
                           Serial.print("tempo trascorso dallo spawn : "); Serial.print (timer-spawnttime);  Serial.println("minuti"); 
                             delay(500);
                            spawn = 0;
                          }
    } 
    else
    {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
  ThingSpeak.setField( (unsigned int) 1, (int) val ) ;                 // store field 1   
  ThingSpeak.setField( (unsigned int) 2, (int) motionState ) ;        // store field 2
  ThingSpeak.setField( (unsigned int) 3, (int) spawn ) ;             // store field 3
  ThingSpeak.setField( (unsigned int) 4, (int) SensorPushCounter ) ;  // store field 4
  ThingSpeak.writeFields(myChannelNumber, apiKey);   // write all fields to the channel and reset stored fields
 
    }
    // Delay a little bit to avoid bouncing
    delay(500);
  }
  // save the current state as the last state, for next time through the loop
  lastSensorState = SensorState;


  

} 

basically the thingspeak stat don't match the serial monitor ones.

This could be because thingspeak is rejecting some transactions.

Your logic is getting very hard to follow, but this (or the comment) is not correct and the interval between transactions to thingspeak has to be greater than 15 seconds (15'000ms).

Yes I managed to make it work , the interval I reduced to be able to quickly test before waiting several minutes , but I am putting it back to 90000 , at least 90 seconds .