Requirement for ledPin

Is there some fundamental requirement that a ledPin or at least one pin be declared in a photon? That might sound weird but as I was cleaning up some code I removed my declaration for ledPin and pinMode which caused the photon to just blink red constantly. Despite the fact that I do NOT call setting of the pin anywhere in my code. It was just there from experimenting earlier. I was at my wits end so I put everything back in and one by one cut code out. If I cut out my pinMode and ledPin declarations it reds on me again.

No there is no such requirement.
But when you say you see red blinks it would be helpful to tell us about what kind of blink this is (e.g. SOS + x slow blinks).
Also what pin did you use and how did you have the LED wired?

If we could have a look at the code we might be able to see what’s up.

2 Likes

Ya for sure I can provide more info. I’ll try to reproduce the red blinking but it resets the device. Blinks red and device seems to reboot as it blinks green then reconnects.

To answer your question, I don’t have an LED even connected. It’s just a simple power meter using semonlib and mqtt. I wonder if maybe something in those libraries requires the LED and I have to declare it my code?

It’s pretty hacky code and I wouldn’t waste too much of your time on this but I thought it a very interesting issue. So in here getting rid of ledPin and pinMode blows the whole thing up. I’m using 1.5.2 as fw 2.0 refuses to run for some reason, I assume something in the libraries creates issues.


#include "MQTT.h"

#define MQTT_USER "mqtt"
#define MQTT_PASSWORD "xxxx"
#define MQTT_CLIENTID "sump_nw"

void callback(char *topic, byte *payload, unsigned int length);

byte server[] = {192, 168, 101, 195};

MQTT client(server, 1883, callback);

// recieve message
void callback(char *topic, byte *payload, unsigned int length)
{

  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  delay(100);
}

// Energy monitoring
EnergyMonitor emon1; // Create an instance

double Irms = 0;
double Prms = 0;
double prevPrms = 0;
char msg[20];
int prevMillis = 0;
int runCount = 0;
int ledPin = D2; // Onboard blue LED
// setup() runs once, when the device is first turned on.
void setup()
{
  Serial.begin(9600);
  Serial.println("Hello there!");

  // Put initialization like pinMode and begin functions here.

  client.connect("sparkclient", MQTT_USER, MQTT_PASSWORD);
  // Set pin mode to output
  pinMode(ledPin, OUTPUT);
  // publish/sub
  if (client.isConnected()) {
    client.publish("outTopic/message", "hello world");
    client.subscribe("inTopic/message");
  }

  Particle.variable("Arms", Irms);
  Particle.variable("Prms", Prms);
  emon1.current(0, 15);
}

// loop() runs over and over again, as quickly as it can execute.
void loop()
{
  // The core of your code will likely live here.
  Irms = emon1.calcIrms(1480); // Calculate Irms only
  Prms = Irms * 120;

  if (!(client.isConnected()) and (millis() - prevMillis) > 15000)
  {
    client.connect("sparkclient", MQTT_USER, MQTT_PASSWORD);
    prevMillis = millis();
  }

  if (client.isConnected() and (abs(Prms - prevPrms) > 10 or (millis() - prevMillis) > 15000))
  {
    
    if ((Prms - prevPrms) > 100) runCount++;
    //Publish to MQTT
    if (client.isConnected()) client.loop();
    sprintf(msg, "{\"power\": %f}", Prms);
    client.publish("sump/sump_nw_va", msg);

    sprintf(msg, "{\"runCount\": %d}", runCount);
    client.publish("sump/sump_nw_runs", msg);

    prevMillis = millis();
    delay(100);
  }

  prevPrms = Prms;
  
}

Hi, I’m not 100% sure but your issue can be with int prevMillisas you try to store some value from miliis(); but it return unsigned long int is a little too small to store the values form millis.
Here is some information from Ardurino reference I’m asumming will be the same for Particle

One thing I’d definitely suggest: Replace sprintf() with snprintf() to ensure you’ll never overshoot the limit of your msg buffer.
And while at it, limit the number of decimal places for your floating point variables

  sprintf(msg, sizeof(msg), "{\"power\": %.3f}", Prms);

I don’t qhow what your emon1.calcIrms() may do, but one reason for panic crashes could be a div/0 exception.
Another - but unlikely - thing could be a race condition where adding the pinMode() may just allow those extra clock cycles to prevent a crash.
This may not have anything to do with pinMode() itself, but just the timing of things.

If you can post a video of the crash it might offer some extra insight about possible causes.

BTW, I’d put the Particle.variable() statements at the top of setup - at least before your MQTT stuff.
And remove that delay(100) from the MQTT callback.

BTW²: You don’t trust your MQTT connection, do you? :wink:

However, client.loop() wants to be called as often as possible, so I wouldn’t have it inside the timed condition but rather flip that round

e.g.

  if (client.isConnected()) {
    client.loop();
    if (abs(Prms - prevPrms) > 10 || (millis() - prevMillis) > 15000) {
      ...
    }
  }
  else  if((millis() - prevMillis) > 15000) {
    client.connect("sparkclient", MQTT_USER, MQTT_PASSWORD);
    prevMillis = millis();
  }

Yup, I agree with @dreamER, you should use uint32_t for millis() and calculations with it - although using the “wrong” types shouldn’t cause a crash, they all (int, unsigned int, long, unsigned long, int32_t, uint32_t) are 32 bit on these devices.
It won’t be a length issue, but may result in “miscalculia” due to the mixing of signed and unsigned types.

1 Like

thanks @ScruffR for clarifying this :slight_smile: I learned something again today :).
@doubleopinter I checked semonlib.cpp which I found on Web IDE and looks for me that the first par in emon1.current(0, 15); in your setup routine can’t be 0 as this should be one of analog Pin.
here is some reference:

semonlib_1

Hey, thanks for the response. The code has been running just fine with 0 as pin 1 for quite some time.

Well thank you very much for all of that :slight_smile: Really interesting read. I do trust my MQTT connection but the other day I had a power outage and my NAS, where the broker is running, takes a long while to boot up. The photon started up and I guess timed out waiting for it, then never tried to reconnect at a later time.

Curious about the race condition, let me think about that and see if there’s something there. I’ll test it later tongiht

I agree with @dreamER again, it may work but I cannot imagine how that would render any correct readings :confused:
Pin 0 is D0 which is not capable to perform analogRead() action.

Huh. Ok I’ll change it and give it a whirl.

I changed the pin to “A0” and now I can confirm for you that yes it is an SOS red flash haha. A0 didn’t help but it also didn’t break it so I’ll leave it in.

Can you tell how many slow blinks follow the first SOS signal?
There are different errors assigned to each number
https://docs.particle.io/tutorials/device-os/led/photon/#red-flash-sos