Button States & triggers

HI, I’m wondering how often the triggers run or poll their condition states. I’m trying to make the button a “momentary” button rather than a switch. For example, I’m trying to use a cayenne trigger that switches one button off if a different button is pressed. I have the arduino sketch setup so that when button1 is pressed or HIGH, it activates a function that after a 500ms delay virtualwrites that same button, button1, back to LOW. The problem is that the trigger to alternate button2 based off button1 state isn’t working. Button2 never changes state. I’ve tried increasing the delay in the code but no luck.

Why don’t I just virtualwrite button 2 using code based off button1 you may wonder? Well I can’t get button2 to control the hardware then for some reason. Using virtualwrite to alternate button2 state works but it doesn’t actually switch the hardware state. Its like the button doesn’t send its updated value at all via that method. My other options is using a digitalwrite to the pin that button controls but then things really get out of sync…

Code below with prints disabled. Relays are Active LOW logic (seller error, got it free in the end at least).

Arduino Uno via ESP8266-01 setup

Any ideas or suggestions would be great.

//#define CAYENNE_DEBUG
//#define CAYENNE_PRINT mySerial

#include <CayenneESP8266Shield.h>
//#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SimpleTimer.h>


#define ONE_WIRE_BUS 10
//SoftwareSerial mySerial(2, 3); // RX, TX

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

SimpleTimer timer;

char token[] = "";
char ssid[] = "devices";
char password[] = "";


#define EspSerial Serial
ESP8266 wifi(EspSerial);

const int foodTrig = 9;
const int foodThrow = 8;
const int filterPin = 7;
const int currentPin = A0;

const unsigned long sampleTime = 100000UL;
const unsigned long numSamples = 500UL;
const unsigned long sampleInterval = sampleTime / numSamples;
const int adc_zero = 510;

int feedButton = LOW;
int filterButton;
int trigger;
int temp;
int feedingTimer;
int currentTimer;



void setup()
{
//	mySerial.begin(9600);
	delay(10);

	EspSerial.begin(9600);
	delay(10);

	sensors.begin();

	Cayenne.begin(token, wifi, ssid, password);

	feedingTimer = timer.setInterval(600000, feedingDone);
	currentTimer = timer.setInterval(5000, getCurrent);
	timer.disable(feedingTimer);

	

	pinMode(foodTrig, INPUT);
	pinMode(currentPin, INPUT);

	pinMode(foodThrow, OUTPUT);
	pinMode(filterPin, OUTPUT);

	Cayenne.syncAll();

}

void loop()
{
	Cayenne.run();
	timer.run();
//	mySerial.print(".");


	if (feedButton == 1)
		{
			timer.enable(feedingTimer);
			digitalWrite(foodThrow, HIGH);
			Cayenne.virtualWrite(V3, HIGH);
			Cayenne.virtualWrite(V5, LOW);
			//		digitalWrite(filterPin, HIGH);
			delay(500);

			trigger = digitalRead(foodTrig);
			while (trigger == HIGH)
				{
					trigger = digitalRead(foodTrig);
				}

			digitalWrite(foodThrow, LOW);
			Cayenne.virtualWrite(V1, LOW);
			feedButton = 0;
		}






	if (filterButton == 0)
		{
			digitalWrite(filterPin, LOW);
		}
	else
		{
			digitalWrite(filterPin, HIGH);
		}

}





void feedingDone()
{
	Cayenne.virtualWrite(V3, LOW);
	Cayenne.virtualWrite(V5, HIGH);
//	digitalWrite(filterPin, LOW);
	timer.disable(feedingTimer);
}


void getCurrent()
{
	unsigned long currentAcc = 0;
	unsigned int count = 0;
	unsigned long prevMicros = micros() - sampleInterval;
	while (count < numSamples)
		{
			if (micros() - prevMicros >= sampleInterval)
				{
					int adc_raw = analogRead(currentPin) - adc_zero;
					currentAcc += (unsigned long)(adc_raw * adc_raw);
					++count;
					prevMicros += sampleInterval;
				}
		}

	float rms = sqrt((float)currentAcc / (float)numSamples) * (75.7576 / 1024.0);
	Cayenne.virtualWrite(V4, rms);
	Cayenne.virtualWrite(V11, rms);
}


CAYENNE_OUT(V0)
{
	sensors.requestTemperatures();
	temp = sensors.getTempFByIndex(0);
	Cayenne.virtualWrite(V0, temp);
	Cayenne.virtualWrite(V10, temp);
}

CAYENNE_IN(V1)
{
	feedButton = getValue.asInt();
}

CAYENNE_IN(V5)
{
	filterButton = getValue.asInt();
}

I solved the problem. Just had to think about it more i guess.

1 Like

Awesome, can you share how you did it?

Well I changed the main function for feeding to just control the virtual pins and let cayenne do the actual triggering for the filter on and off using its triggers. Before I was trying to have cayenne pickup on the physical pin states which was giving me the sporadic behavior. Now, when “feedButton” is pressed, it changes the 2 state indicator and the cayenne trigger is based off thats state rather than “FeedButton” state which is being virtualwrited low after the function is called. It behaves like a momentary button now.

if (feedButton == 1)
{

		Cayenne.virtualWrite(V3, HIGH); // write indicator 2 state high

		timer.enable(feedingTimer);
		digitalWrite(foodThrow, HIGH);
		delay(1000);

		trigger = digitalRead(foodTrig);
		while (trigger == HIGH)
			{
				trigger = digitalRead(foodTrig);
			}
		digitalWrite(foodThrow, LOW);
		feedButton = 0;

// filterButton = 0;
Cayenne.virtualWrite(V1, LOW); //write feed button “off”
}
}

Also added a timer to run once after it is called in the above function for when they are done eating:

void feedingDone()
{
Cayenne.virtualWrite(V3, LOW); // write 2state low
// Cayenne.virtualWrite(V5, HIGH); //dont need
// filterButton = 1; //dont need
timer.disable(feedingTimer);
}

1 Like