Trying to understand what is happening to my object.

I have a project I have been doing to control some of the features of my pool. I have used the Syslog library to send syslog messages over UDP to my rsyslog server.

I am instantiating an PoolLight object and passing in an instance of Syslog. The problem I am seeing is each member function of PoolLight only sends one log message, even with multiple calls.

I haven't a clue what I have done wrong.

poolduino_wemos.ino. N.B. truncated after the object instantiations

#include <Homie.h>
#include <WiFiUdp.h>
#include <Syslog.h>

#define firmwareVersion "2.3.0"

#define LIGHT_RELAY_PIN 5 // D1
#define LIGHT_RELAY_PULSE_INTERVAL 250
#define FLOAT_SENSOR_PIN 4 // D2
#define FLOAT_LOW_LED 14 // D5
#define THERMISTOR_PIN A0

// A UDP instance to let us send and receive packets over UDP
WiFiUDP udpClient;
// Private Libraries
#include <PoolLight.h>

// Syslog server connection info
#define SYSLOG_SERVER "mediastore"
#define SYSLOG_PORT 514

// This device info
#define DEVICE_HOSTNAME "poolduino"
#define DEFAULT_APP_NAME "PoolMain"


Syslog logger(udpClient, SYSLOG_SERVER, SYSLOG_PORT, DEVICE_HOSTNAME, DEFAULT_APP_NAME, LOG_LOCAL0);

PoolLight poolLight(LIGHT_RELAY_PIN, LIGHT_RELAY_PULSE_INTERVAL, logger);

...

PoolLight.h

#ifndef PoolLight_h
#define PoolLight_h

#include <Syslog.h>

class PoolLight
{
  public:
    String current_color;
    PoolLight(int pin, int interval, Syslog const &logger);
    void set_light_color(String color);
    void set_light_state(bool state);
    bool get_light_state();
    void loop();
  private:
    Syslog _logger;
    bool _light_state;
    void _log();
    void _logf();
    int _pin;
    int _pulse_count;
    int _interval;
    long _PreviousMillis = 0;
    int _color_pulses(String color);
    bool _active_color_change();
    void _pulse_light();
};
#endif

PoolLight.cpp

#include <Arduino.h>
#include <PoolLight.h>
#include <Syslog.h>
#define APP_NAME "PoolLight"


PoolLight::PoolLight(int pin, int interval, Syslog const &logger) : _logger(logger) {
  current_color = "Blue";
  _pin = pin;
  _interval = interval;
  _pulse_count = 0;
  _logger.appName(APP_NAME);
  _logger.log(LOG_DEBUG, "Setting up light relay");
  pinMode(pin, OUTPUT);
  set_light_state(false);
}

void PoolLight::set_light_state(bool state) {
  if (state) {
    if (!_active_color_change()) {
      _logger.log(LOG_DEBUG, "Switching the light ON, and pin to High");
    }
    _light_state = true;
  } else {
    if (!_active_color_change()) {
      _logger.log(LOG_DEBUG, "Switching the light OFF, and pin to Low");
    }
    _light_state = false;
  }
  digitalWrite(_pin, _light_state);
}

int PoolLight::_color_pulses(String color) {
  _logger.logf(LOG_INFO, "Setting color to .%s.", color.c_str());
  _logger.log(LOG_INFO, "This line never gets sent");
  Serial.print("Setting color to ");
  Serial.println(color.c_str());
  if (color == "Blue") {
    _logger.log(LOG_DEBUG, "Color Blue returns 8");
    return 8;
  } else if (color == "Green"){
    _logger.log(LOG_DEBUG, "Color Green returns 9");
    return 9;
  } else if (color == "Red"){
    _logger.log(LOG_DEBUG, "Color Red returns 10");
    return 10;
  } else if (color == "White"){
    _logger.log(LOG_DEBUG, "Color White returns 11");
    return 11;
  } else if (color == "Magenta"){
    _logger.log(LOG_DEBUG, "Color White returns 12");
    return 12;
  }
  _logger.logf(LOG_DEBUG, "Nothing matched [%s].  Returning 0", color.c_str());
  Serial.println(color);

  return 0;
}

in the call to color_pulses only the first log line gets sent. And the logging call in the constructor does not send anything to the syslog server.

#include <PoolLight.h>
#include <PoolTemp.h>
#include <PoolWaterLevel.h>
#include <PoolSensors.h

Most people around here throw a fit if you don't post ALL of your code. And, if its too much to post, you need to pare this down to a simple case that shows the error. Make up a small stripped down version that contains the error. Then you will probably get a lot more action on this post. Or you will have found your error while doing that.

Good luck!

-jim lee

Gotcha. I will pare down the posted code to what I believe are the salient bits.

Ok to circle back on this. There was actually nothing wrong with my code. Turns out UDP messages on an ESP8266 get dropped if they happen too close together. on the order of 2 ns. So in my code where I had back to back logging messages, the second one consistently failed to send.

As an aside, in an effort to be a better forum citizen, I am reading up on how to post better.

Thanks.

jtimon:
As an aside, in an effort to be a better forum citizen, I am reading up on how to post better.

+1 Karma for this !

I am new to Arduino. I tried to make a simple code. first run countdown goes well, after completion and will try again countdown does not work. is there something wrong ?

#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int runTimer = 1;
int runFor = 5; // time in seconds
int data = 0;

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

byte rowPins[ROWS] = { A0,A1,A2,A3 };
byte colPins[COLS] = { 5,4,3,2 };
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

int relay = 8;

int led = 13;

void setup()

{
pinMode(led, OUTPUT);

pinMode(relay, OUTPUT);

lcd.begin(16,2);

}

void loop()
{

char key = keypad.getKey();

if (key == '*')

// PERINTAH TOMBOL BINTANG
{
digitalWrite(relay, HIGH);
digitalWrite(led, LOW);
lcd.print("*");
delay(500);
lcd.clear();
}

// SELESAI PERINTAH TOMBOL BINTANG
if (key == '#')

// PERINTAH TOMBOL PAGAR
{
digitalWrite(relay, LOW);
digitalWrite(led, HIGH);
lcd.print("#");
delay(500);
lcd.clear();
}
// SELESAI PERINTAH TOMBOL PAGAR

if (key == 'A')

// PERINTAH TOMBOL A

{

if(runTimer == 1){
digitalWrite(relay,LOW); // relay is OFF during countdown
/* *change to HIGH if you want the relay to be ON while countdowning /
lcd.clear();
lcd.print("TIMER=");
//Start timer
timer();
} else {
digitalWrite(relay,HIGH); // relay is ON when time expired
/
*change to LOW if you want the relay to be OFF when the time expired */
}
runTimer = 0;
lcd.noDisplay();
delay(250);
for(int duration = 0; duration < 100; duration ++){

delayMicroseconds(500);

delayMicroseconds(500);
}
lcd.display();
delay(250);

}
// SELESAI PERINTAH TOMBOL A
}

void panggil() {

if(runTimer == 1){
digitalWrite(relay,LOW); // relay is OFF during countdown
/* *change to HIGH if you want the relay to be ON while countdowning /
lcd.clear();
lcd.print("TIMER=");
//Start timer
timer();
} else {
digitalWrite(relay,HIGH); // relay is ON when time expired
/
*change to LOW if you want the relay to be OFF when the time expired */
}
runTimer = 0;
lcd.noDisplay();
delay(250);
for(int duration = 0; duration < 100; duration ++){

delayMicroseconds(500);

delayMicroseconds(500);
}
lcd.display();
delay(250);

}

void timer() {
for(int timer = runFor;timer > 0; --timer){
if(timer >= 10) {
lcd.setCursor(6,0);
} else {
lcd.setCursor(6,0);
lcd.print("0");
lcd.setCursor(7,0);
}
lcd.print(timer);
lcd.print(" SECOND!");
delay(1000);
}
lcd.setCursor(0,0);
lcd.clear();
lcd.print(" TIMER ALERT!");
delay(1000);
lcd.clear();
digitalWrite(relay,HIGH); // relay is ON when time expired

}

  _logger.logf(LOG_INFO, "Setting color to .%s.", color.c_str());
  _logger.log(LOG_INFO, "This line never gets sent");

Hmm:

  _logger.log(LOG_INFO, "Let's log a line");
  _logger.logf(LOG_INFO, "If you see the previous line and also this line but not the next, then you have a buffer overrun issue in logf() .%s.", color.c_str());
  _logger.log(LOG_INFO, "If you only saw the fist line and not that second line, I'm thinking maybe network latency?");

herohsu:
I am new to Arduino. I tried to make a simple code....

Don’t hijack threads and read the forum rules on how to post correctly