OK....
Trying to set up multiple instances of MyMessage in order to sort the messages in a simple, extensible loop. There is the full code:
/*
*/
//
//#include <avr/pgmspace.h>
#include <MySensor.h>
#include <SPI.h>
//
#define NUMBER_OF_VALVES 8 // Change this to set your valve count.
#define RESET_TIME 5000 // Change this (in milliseconds) for the time you need your valves to hydraulically change state
#define RADIO_ID AUTO
//
typedef enum {
ALL_ZONES_OFF, SINGLE_ZONE_OPERATION, RUN_ALL_ZONES}
SprinklerStates;
//
SprinklerStates state = ALL_ZONES_OFF;
SprinklerStates lastState;
//
int valveTime [NUMBER_OF_VALVES + 1];
int valveSoloTime [NUMBER_OF_VALVES + 1];
int valveIntID [17] = { 0b1111111111111111, 0b1111111111111110, 0b1111111111111101, 0b1111111111111011, 0b1111111111110111, 0b1111111111101111, 0b1111111111011111, 0b1111111110111111, 0b1111111101111111, 0b1111111011111111, 0b1111110111111111, 0b1111101111111111, 0b1111011111111111, 0b1110111111111111, 0b1101111111111111, 0b1011111111111111, 0b0111111111111111};// this array is good up to sixteen valve positions, even if you select less.
int valveNumber;
unsigned long startMillis;
//
unsigned long oneHour = 3600000UL;
unsigned long hourTimer;
//
//Setup Shift Register
//
int latchPin = 8;
int clockPin = 4;
int dataPin = 7;
int pin = 3;//
int ledPin = 5; // LED status blinks fast while changing a valve; steady during valve open or initialization; and slow blink when in stand-by
boolean buttonPushed = false;
//
MySensor gw;
//
void (*msg1valve[ NUMBER_OF_VALVES + 1 ] )();
void (*var1valve[ NUMBER_OF_VALVES + 1 ] )();
void (*var2valve[ NUMBER_OF_VALVES + 1 ] )();
//
void setup()
{
/*
for (int i = 0; i <= NUMBER_OF_VALVES; i++)
{
msg1valve[i] = new MyMessage (i,V_LIGHT);
var1valve[i] = new MyMessage (i,V_VAR1);
var2valve[i] = new MyMessage (i,V_VAR2);
}*/
Serial.begin(115200);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(pin, OUTPUT);
pinMode(ledPin, OUTPUT);
attachInterrupt(1, PushButton, CHANGE);
digitalWrite (ledPin, HIGH);
//
gw.begin(getVariables, RADIO_ID, false); // Does not create a Radio repeating node
delay(3000);
gw.sendSketchInfo("NewSprinkler", "2.0");
delay(3000);
for (int i = 0; i <= NUMBER_OF_VALVES; i++)
{
gw.present(i, S_LIGHT);
delay(3000);
}
Serial.println(F("Sensor Presentation Complete"));
//
updateRelays(valveIntID[0]);
Serial.println(F("All Valves OFF"));
/*
for (int i = 0; i <= NUMBER_OF_VALVES + 1; i++)
{
//Set all valves off
}
*/
//getTimesVera();
hourTimer = millis();
digitalWrite (ledPin, LOW);//ready
Serial.println(F("READY"));
}
//
void loop()
{
gw.process();
//
if (buttonPushed)
{
if (state != RUN_ALL_ZONES);
{
state = RUN_ALL_ZONES;
valveNumber = 1;
startMillis = millis();
Serial.println(F("Button Pressed!!!"));
Serial.println(F("Manually directed cycling through all valves"));
Serial.print(F("state = "));
Serial.println(state);
}
buttonPushed = false;
}
if (state == ALL_ZONES_OFF)
{
slowToggleLED ();
if (lastState != state)
{
updateRelays(valveIntID[0]);
}
}
//
if (state == RUN_ALL_ZONES)
{
fastToggleLed();
unsigned long nowMillis = millis();
if (nowMillis - startMillis < RESET_TIME)
{
updateRelays(valveIntID[0]);
}
else if (nowMillis - startMillis < (valveTime[valveNumber] * 60000UL))
{
digitalWrite (ledPin, HIGH);
updateRelays(valveIntID [valveNumber]);
}
else
{
updateRelays(valveIntID[0]);
startMillis = millis();
valveNumber++;
if (valveNumber > NUMBER_OF_VALVES)
{
state = ALL_ZONES_OFF;
digitalWrite (ledPin, LOW);
Serial.print(F("State = "));
Serial.println(state);
}
}
}
//
if (state == SINGLE_ZONE_OPERATION)// Run single valve
{
fastToggleLed();
unsigned long nowMillis = millis();
if (nowMillis - startMillis < RESET_TIME)
{
updateRelays(valveIntID[0]);
}
else if (nowMillis - startMillis < (valveSoloTime [valveNumber] * 60000UL))
{
digitalWrite (ledPin, HIGH);
updateRelays(valveIntID [valveNumber]);
}
else if (nowMillis - startMillis > (valveSoloTime [valveNumber] * 60000UL))
{
updateRelays(valveIntID[0]);
state = ALL_ZONES_OFF;
digitalWrite (ledPin, LOW);
Serial.print(F("State = "));
Serial.println(state);
}
}
lastState = state;
}
//
void updateRelays(int value)
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, highByte(value));
shiftOut(dataPin, clockPin, MSBFIRST, lowByte(value));
digitalWrite(latchPin, HIGH);
}
//
void PushButton(){ //interrupt with debounce
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 200)
{
Serial.println(F("interrupt"));
buttonPushed = true;
}
last_interrupt_time = interrupt_time;
}
//
void fastToggleLed()
{
static unsigned long fastLedTimer;
if (millis() - fastLedTimer >= 100UL)
{
digitalWrite(ledPin, !digitalRead(ledPin));
fastLedTimer = millis ();
}
}
//
void slowToggleLED ()
{
static unsigned long slowLedTimer;
if (millis() - slowLedTimer >= 1250UL)
{
digitalWrite(ledPin, !digitalRead(ledPin));
slowLedTimer = millis ();
}
}
//
void getVariables(const MyMessage &message)
{
if (message.isAck())
{
Serial.println("This is an ack from gateway");
}
for (int i = 1; i<= NUMBER_OF_VALVES; i++)
{
if (message.sensor == i)
{
if (message.type == V_VAR1)
{
//get single duration
}
if (message.type == V_VAR2)
{
//get cycle duration
}
}
}
}
Stripped down only for the purpose of creating the function pointer:
#include <MySensor.h>
#include <SPI.h>
//
#define NUMBER_OF_VALVES 8 // Change this to set your valve count.
//
int valveTime [NUMBER_OF_VALVES + 1];
//
MySensor gw;
//
void (*msg1valve[ NUMBER_OF_VALVES + 1 ] )();
void (*var1valve[ NUMBER_OF_VALVES + 1 ] )();
void (*var2valve[ NUMBER_OF_VALVES + 1 ] )();
//
void setup()
{
for (int i = 0; i <= NUMBER_OF_VALVES; i++)
{
msg1valve[i] = new MyMessage (i,V_LIGHT);
var1valve[i] = new MyMessage (i,V_VAR1);
var2valve[i] = new MyMessage (i,V_VAR2);
}
}
void loop()
{
}
The last function of the entire sketch will be used to sort all of the incoming messages
You won't be able to compile it without the MySensors libraries... but I have the MyMessages.h and MyMessages.cpp attached here:
MyMessage.cpp (4.48 KB)
MyMessage.h (7.24 KB)