Running Particle.function to turn something on with other logic

This may belong in cloud, but its my first post so excuse me if I'm wrong. I'm new to coding so I'm learning.

I have some software with a digital IR switch controlling a solenoid. Powered through a mosfet. I've managed to get this to function properly in my loop structure. However, I was trying my hand at getting the solenoid to turn "on" and "off" using the Console.particle.io (over the internet). I used code similar to the LED example on the website.

By itself, with no other logic, I am able to successfully do this. And by it self without particle.function code my logic reads the state of the IR switch and activates the solenoid However, with my other logic in my loop structure and the particle.funtion code when I try to activate the solenoid on the console, it only momentarily activates. I assume this is because my other logic (IR switch) is telling the solenoid to be off.

So my question is generally how do I make both these function work. Also, why doesn't the logic for the particle.funtion belong in my loop as shown in the LED example?

I tried including a boolean (= false while toggle "on") and a while loop in my loop() but I don't know enough about coding to properly make it work. This was an attempt to "turn off my loop" if the net was calling.

I think this would be much easier to solve if you shared your code, then we could explain how to restructure what you have to fix the problem.

But to answer one of your questions: The reason a Particle.function takes a callback function instead of your handling it from your regular loop code, is cloud functions are necessarily asynchronous; they're intended to be handled when the cloud requests it, not when you decide to handle it from loop. However, as long as you are only triggering an operation and not needing a result to be returned, one common model is to only set a global variable flag in your Particle.function, then you can handle it from your regular loop code so you don't have to duplicate the code in two places.

/* 
 * Project Digital IR switch activates LED
 * Author: Aaron
 * Date: 06/25/24
 * Pololu 5cm IR switch on D0 turns LED 
 */


// Include Particle Device OS APIs
#include "Particle.h"

// Let Device OS manage the connection to the Particle Cloud
SYSTEM_MODE(AUTOMATIC);

// Run the application and system concurrently in separate threads
SYSTEM_THREAD(ENABLED);

// Show system, cloud connectivity, and application logs over USB
// View logs with CLI using 'particle serial monitor --follow'
SerialLogHandler logHandler(LOG_LEVEL_INFO);

int ledPin = A5;
int led2Pin = D1;
int potPin = A2;
int irPin = D0;
int Sol = D2;
int potValue;
int pinValue;
int irValue;
int irPinValue;
bool running; 

unsigned long previousTimeLEDPWM = 0;
unsigned long LEDPWMDelay = 200;
unsigned long previousTimePot = 0;
unsigned long PotDelay = 100;
unsigned long previousTimeir = 0;
unsigned long irDelay = 200; 

int toggle(String command){
    if (command=="on"){
      digitalWrite(Sol, HIGH);
      return 1;
      bool running = false;
    }
    else if (command=="off"){
      digitalWrite(Sol, LOW);
      return 0;
      bool running = true;
    }
    else {
      return -1;
      bool running = true;
    }
  }

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(Sol, OUTPUT);
  pinMode(potPin, INPUT);
  pinMode(irPin, INPUT);
  
  Particle.function("Solenoid",toggle);



}


void loop(){
    unsigned long timeNow = millis();
    //Read pot value and write LED PWM
  if(timeNow - previousTimePot > PotDelay){
    potValue = analogRead(potPin);

    pinValue = ((255.0 / 4095.0)*potValue);
    analogWrite(led2Pin, pinValue);

    previousTimePot += PotDelay;}


  

  //Read IR Digitial input and write LED digital output
    if(timeNow - previousTimeir > irDelay){
     while(running){
         int irRead = digitalRead(irPin);
            if(irRead == HIGH){
             digitalWrite(ledPin, LOW);
             digitalWrite(Sol, LOW);
            }
        }}
    else(digitalWrite(ledPin, HIGH), digitalWrite(Sol, HIGH));

    
    previousTimeir += irDelay;
    
    }

The main issue is that when you say bool running = inside of your toggle() function, you're making new running variables inside of that function that are different from the one you declare outside of the function. So if you delete the bool and just say running = that should allow you to change the global running from that function.
Other small things - do you really want running to be set to true when an invalid cloud function input is received? Also, do you want to have the cloud function call digitalWrite()? You may want to just set running to a value and let your loop handle the rest. Not sure if that was just sanity checking and not what you were intending to use once you got it figured out.

what you're saying about the bool makes complete sense. However, I am still unable to get it to enter the mart of my code in my loop while running = true. Please see the updated code

 * Project Digital IR switch activates LED
 * Author: Aaron
 * Date: 06/25/24
 * Pololu 5cm IR switch on D0 turns LED 
 */


// Include Particle Device OS APIs
#include "Particle.h"

// Let Device OS manage the connection to the Particle Cloud
SYSTEM_MODE(AUTOMATIC);

// Run the application and system concurrently in separate threads
SYSTEM_THREAD(ENABLED);

// Show system, cloud connectivity, and application logs over USB
// View logs with CLI using 'particle serial monitor --follow'
SerialLogHandler logHandler(LOG_LEVEL_INFO);

int ledPin = A5;
int led2Pin = D1;
int potPin = A2;
int irPin = D0;
int Sol = D2;
int potValue;
int pinValue;
int irValue;
int irPinValue;
bool running; 

unsigned long previousTimeLEDPWM = 0;
unsigned long LEDPWMDelay = 200;
unsigned long previousTimePot = 0;
unsigned long PotDelay = 100;
unsigned long previousTimeir = 0;
unsigned long irDelay = 200; 

int toggle(String command){
    if (command=="on"){
      digitalWrite(Sol, HIGH);
      digitalWrite(ledPin, HIGH);
      return 1;
      running = false;
    }
    else if (command=="off"){
      digitalWrite(Sol, LOW);
      digitalWrite(ledPin, LOW);
      return 0;
      running = true;
    }
    else {
      return -1;
      running = true;
    }
  }

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(Sol, OUTPUT);
  pinMode(potPin, INPUT);
  pinMode(irPin, INPUT);
  
  Particle.function("Solenoid",toggle);
  digitalWrite(ledPin, LOW);
  digitalWrite(Sol, LOW);


}


void loop(){
    unsigned long timeNow = millis();
    //Read pot value and write LED PWM
  if(timeNow - previousTimePot > PotDelay){
    potValue = analogRead(potPin);

    pinValue = ((255.0 / 4095.0)*potValue);
    analogWrite(led2Pin, pinValue);

    previousTimePot += PotDelay;}


  

  //Read IR Digitial input and write LED digital output
    while(running){
      if(timeNow - previousTimeir > irDelay){
         int irRead = digitalRead(irPin);
            if(irRead == HIGH){
             digitalWrite(ledPin, LOW);
             digitalWrite(Sol, LOW);
            }
            else(digitalWrite(ledPin, HIGH),digitalWrite(ledPin, HIGH));
            }
        previousTimeir += irDelay;} 
     }

You have the return statement before setting the running variable. The return statement returns from the function immediately, and doesn't execute any code after it, so the variable is never set.

1 Like

is the return statement even needed?

You need at least one return statement. I'd put one at the bottom of the function and always return 0.

I was not able to get the code to work. However, I'm not sure something isn't wrong with my device. It seemed that my ledPin would come on but no solenoid. Now something happened and I have no led status lights. Will make a new post in hardware

I've tried holding mode and hitting reset but there is no status lights on my photon 2

How was the solenoid connected? In most cases, you need a flyback diode, and probably a MOSFET or similar transistor, and sometimes a relay, or you will permanently damage your Photon 2 as it is not designed to drive that large of a load.

I had a flyback diode and a MOSFET IRLB8721. I also had a 10k pull down resistor to ground on the gate. While plugged in, it seems to be making a buzzing noise. If I power the 5v and ground directly a small led by the USB port flashes (near letters CHG). This also briefly flashes when the usb is plugged in.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.