Port active in feeding/water change mode

Post Reply
bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Port active in feeding/water change mode

Post by bubbles »

Hi everyone,

Think I might have found a bug in the recent library updates. Noticed that one of my tunze pumps kept running when activating either feeding or water change mode. Code is unchanged and worked prior update. Also verified that the socket is live by swapping the 2 tunze cords on the relay box (i.e. it's not something specified to the pump)

Have included my code for review just in case it's me doing something silly.

Any thoughts?

Code: Select all

#include <ReefAngel_Features.h>
#include <Globals.h>
#include <RA_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <InternalEEPROM.h>
#include <RA_NokiaLCD.h>
#include <RA_ATO.h>
#include <RA_Joystick.h>
#include <LED.h>
#include <RA_TempSensor.h>
#include <Relay.h>
#include <RA_PWM.h>
#include <Timer.h>
#include <Memory.h>
#include <ReefAngel.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>

//*** Define only one mode ***
//#define TUNZE_MODE_SINE // sine wave, no pulse
#define TUNZE_MODE_LONG // no sine wave, long pulse
//#define TUNZE_MODE_SHORT // no sine wave, short pulse
//#define TUNZE_MODE_LONGSINE // sine wave, long pulse
//#define TUNZE_MODE_SHORTSINE // sine wave, short pulse

#define TUNZE_SINE_SEC 10
#define TUNZE_SINE_SYNC false

#define TUNZE_LONGPULSE_SEC 10
#define TUNZE_LONGPULSE_SYNC false

#define TUNZE_SHORTPULSE_MS 500
#define TUNZE_SHORTPULSE_SYNC false

char* TUNZE_LABEL = "Sine Wave - No Pulse";

byte PORT_TUNZE_1 = Port1;
byte PORT_TUNZE_1_BIT = Port1Bit;

byte PORT_TUNZE_2 = Port2;
byte PORT_TUNZE_2_BIT = Port2Bit;

byte PORT_HEATER = Port3;
byte PORT_HEATER_BIT = Port3Bit;

byte PORT_ATO = Port4;
byte PORT_ATO_BIT = Port4Bit;

byte PORT_RETURN = Port5;
byte PORT_RETURN_BIT = Port5Bit;

byte PORT_LED = Port6;
byte PORT_LED_BIT = Port6Bit;

byte PORT_SKIMMER = Port7;
byte PORT_SKIMMER_BIT = Port7Bit;

byte PORT_SALINITY = Port8;
byte PORT_SALINITY_BIT = Port8Bit;

byte TP_DISPLAY = T1_PROBE;
byte TP_SUMP = T2_PROBE;

/*
runTunzes
 */
void runTunzes(byte minSpeed, byte maxSpeed) {

#ifdef TUNZE_MODE_SINE
  ReefAngel.PWM.SetDaylight(SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, true));
  ReefAngel.PWM.SetActinic(SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, TUNZE_SINE_SYNC));
#endif

#ifdef TUNZE_MODE_LONG
  ReefAngel.PWM.SetDaylight(LongPulseMode(minSpeed, maxSpeed, TUNZE_LONGPULSE_SEC, true));
  ReefAngel.PWM.SetActinic(LongPulseMode(minSpeed, maxSpeed, TUNZE_LONGPULSE_SEC, TUNZE_LONGPULSE_SYNC));
#endif

#ifdef TUNZE_MODE_SHORT
  ReefAngel.PWM.SetDaylight(ShortPulseMode(minSpeed, maxSpeed, TUNZE_SHORTPULSE_MS, true));
  ReefAngel.PWM.SetActinic(ShortPulseMode(minSpeed, maxSpeed, TUNZE_SHORTPULSE_MS, TUNZE_SHORTPULSE_SYNC));
#endif

#ifdef TUNZE_MODE_LONGSINE
  ReefAngel.PWM.SetDaylight(LongPulseMode(minSpeed, SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, true), TUNZE_LONGPULSE_SEC, true));
  ReefAngel.PWM.SetActinic(LongPulseMode(minSpeed, SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, TUNZE_SINE_SYNC), TUNZE_LONGPULSE_SEC, TUNZE_LONGPULSE_SYNC));
#endif

#ifdef TUNZE_MODE_SHORTSINE
  ReefAngel.PWM.SetDaylight(ShortPulseMode(minSpeed, SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, true), TUNZE_SHORTPULSE_MS, true));
  ReefAngel.PWM.SetActinic(ShortPulseMode(minSpeed, SineMode(minSpeed, maxSpeed, TUNZE_SINE_SEC, TUNZE_SINE_SYNC), TUNZE_SHORTPULSE_MS, TUNZE_SHORTPULSE_SYNC));
#endif

}

/*
DrawCustomMain
 */
void DrawCustomMain() {

  ReefAngel.LCD.DrawDate(6, 2);

  char text[7];
  byte y = 10;
  byte middle = 66;  

  y = drawSeperator(y);

  byte x = 1;
  int tempColor = ReefAngel.Relay.Status(PORT_HEATER) ? COLOR_NAVY : COLOR_GREEN;
  
  // Temp Display + pH
  ReefAngel.LCD.DrawText(tempColor, COLOR_WHITE, x + 1, y, "Display");
  ReefAngel.LCD.DrawText(PHColor, DefaultBGColor, x + middle, y, "pH");
  y += 8;
  
  ConvertNumToString(text, ReefAngel.Params.Temp[TP_DISPLAY], 10);                   
  ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, tempColor, x, y, text);
  ConvertNumToString(text, ReefAngel.Params.PH, 100);                       
  ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, PHColor, x + middle, y, text);
  y += 17;
  
  //y = drawSeperator(y);

  // Temp Sump + Salinity
  ReefAngel.LCD.DrawText(tempColor, COLOR_WHITE, x + 1, y, "Sump");
  ReefAngel.LCD.DrawText(PHColor, DefaultBGColor, x + middle, y, "Salinity");
  y += 8;
  
  ConvertNumToString(text, ReefAngel.Params.Temp[TP_SUMP], 10);                       
  ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, tempColor, x, y, text);
  ConvertNumToString(text, ReefAngel.Params.Salinity, 10);                       
  ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, PHColor, x + middle, y, text);
  y += 17;

  y = drawSeperator(y);
  
  /*
  byte val = now() % 60;
  y += 17;
  ConvertNumToString(text, val, 1);                       
  ReefAngel.LCD.DrawHugeNumbers(COLOR_WHITE, PHColor, x, y, text);
  */

  // TUNZE
  y = drawTunzeBar(2, y, 126, false);
  //drawTunzeBar(26, y, 102, false);

  y = drawSeperator(y);

  // Relay
  byte relay = ReefAngel.Relay.RelayData;
  relay &= ReefAngel.Relay.RelayMaskOff;
  relay |= ReefAngel.Relay.RelayMaskOn;
  drawOutletBox(13, y, relay);
  //ReefAngel.LCD.DrawCircleOutletBox(60, y + 5, relay, false);
  y += 14;

  y = drawSeperator(y);
  
  // ATO
  x = 2;
  byte radius = 5;
  ReefAngel.LCD.FillCircle(x + radius, y + radius, radius, ReefAngel.LowATO.IsActive() ? COLOR_GREEN : COLOR_RED);
  ReefAngel.LCD.FillCircle(x + 2 + 3 * radius, y + radius, radius, ReefAngel.HighATO.IsActive() ? COLOR_GREEN : COLOR_RED);
  
  // Check for ATO
  y = 50;
  y = drawWarning(40, y, ATO_Exceed_Flag, "ATO");
  y = drawWarning(5, y, Overheat_Exceed_Flag, "Overheat");
}

/*
drawWarning
*/
byte drawWarning(byte x, byte y, int location, char* message) {
  if (InternalMemory.read(location)) {
    byte txtColor = now() % 2 == 0 ? COLOR_RED : COLOR_WHITE;
    byte bgColor = now() % 2 == 0 ? COLOR_WHITE : COLOR_RED;
    ReefAngel.LCD.DrawHugeText(txtColor, bgColor, x, y, message);
    y += 16;
  }
  
  return y;
}

/*
drawOutletBox
*/
byte drawOutletBox(byte x, byte y, byte relayData) {
  ReefAngel.LCD.Clear(OutletBorderColor, x, y, x + 104, y);
  ReefAngel.LCD.Clear(OutletBorderColor, x, y + 12, x + 104, y + 12);

  for (byte a = 0; a < 8; a++) {
    byte bcolor = OutletOffBGColor;
    byte fcolor = OutletOffFGColor;
    char temp[] = "  ";
    
    if ((relayData&(1 << a)) == 1 << a) {
      bcolor = OutletOnBGColor;
      fcolor = OutletOnFGColor;
    }
        
    ReefAngel.LCD.Clear(bcolor, x + (a * 13), y + 1, x + 13 + (a * 13), y + 11);
    itoa(a + 1, temp, 10);
    ReefAngel.LCD.DrawText(fcolor, bcolor, x + 4 + (a * 13),y + 3,temp);
  }
  
  return y;
}

/*
Draw the seperator
 */
byte SEPERATOR = 0;

byte drawSeperator(byte y) {
  ReefAngel.LCD.Clear(COLOR_BLACK, 1, y, 129, y + SEPERATOR);
  return y += SEPERATOR + 2;
}

/*
Draw the tunze bar
 */
byte drawTunzeBar(byte x, byte y, byte delta, boolean showLabel) {
  byte bgColor = COLOR_GREEN;
  byte barColor = COLOR_RED;
  byte txtColor = COLOR_WHITE;

  if (showLabel) {
    ReefAngel.LCD.DrawText(COLOR_BLACK, DefaultBGColor, x, y, TUNZE_LABEL);
    y += 9;
  }

  ReefAngel.LCD.Clear(bgColor, x, y, x + delta, y + 18);

  float tunze1 = ReefAngel.PWM.GetDaylightValue();
  float tunze2 = ReefAngel.PWM.GetActinicValue();

  x++;
  y++;
  delta -= 2;

  ReefAngel.LCD.Clear(barColor, x, y, x + (tunze1 / 100) * delta, y + 7);
  char text[7];
  ConvertNumToString(text, tunze1, 1); 
  ReefAngel.LCD.DrawText(txtColor, barColor, x, y, text);

  y += 9;
  ReefAngel.LCD.Clear(barColor, x, y, x + (tunze2 / 100) * delta, y + 7);
  ConvertNumToString(text, tunze2, 1); 
  ReefAngel.LCD.DrawText(txtColor, barColor, x, y, text);

  return y += 10;
}

/*
DrawCustomGraph
 */
void DrawCustomGraph() {
}

/*
Setup
 */
void setup() {
  ReefAngel.Init();
  ReefAngel.AddWifi();
  ReefAngel.AddStandardMenu();
  ReefAngel.AddDateTimeMenu();  

  ReefAngel.FeedingModePorts = PORT_ATO_BIT | PORT_SKIMMER_BIT | PORT_RETURN_BIT | PORT_TUNZE_1_BIT | PORT_TUNZE_2_BIT;
  ReefAngel.WaterChangePorts = PORT_ATO_BIT | PORT_SKIMMER_BIT | PORT_RETURN_BIT | PORT_TUNZE_1_BIT | PORT_TUNZE_2_BIT;
  ReefAngel.LightsOnPorts = PORT_LED_BIT;
  
  // Temperature related settings
  ReefAngel.SetTemperatureUnit(Celsius);
  ReefAngel.OverheatProbe = TP_SUMP;
  ReefAngel.OverheatShutoffPorts = PORT_HEATER_BIT;

  // Relay states
  ReefAngel.Relay.On(PORT_TUNZE_1);
  ReefAngel.Relay.On(PORT_TUNZE_2);
  ReefAngel.Relay.On(PORT_SKIMMER);
  ReefAngel.Relay.On(PORT_RETURN);
  ReefAngel.Relay.On(PORT_LED);
  ReefAngel.Relay.On(PORT_SALINITY);
}

/*
Loop
 */
void loop() {
  //ReefAngel.LCD.DrawLargeText(COLOR_STEELBLUE, COLOR_WHITE, 28, 121, "JVR Reef");
  ReefAngel.StandardATO(PORT_ATO);
  ReefAngel.StandardHeater(PORT_HEATER);

  byte h = hour();
  byte minSpeed = h > 22 || h < 7 ? 30 : 50;
  byte maxSpeed = h > 22 || h < 7 ? 50 : 80;

  runTunzes(minSpeed, maxSpeed);

  // Skimmer waits for a minute before it's turned on
  ReefAngel.Relay.DelayedOn(PORT_SKIMMER, 1);

  ReefAngel.Portal("bubbles");

  ReefAngel.ShowInterface();
}

bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Re: Port active in feeding/water change mode

Post by bubbles »

Have also found that my tunze pumps are not actually adjusting their output. Something is up with the PWM. Strange as the values being read by custom main are changing.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Port active in feeding/water change mode

Post by rimai »

I just tested the code and feeding worked for me... :?
Could it be that you have the tunze ports overridden?
If you have a meter and can check the voltage on the dimming ports, otherwise I'll check the PWM later.
Roberto.
bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Re: Port active in feeding/water change mode

Post by bubbles »

I don't think I've got it overridden anywhere. I remember seeing a thread on relay masking so you can't turn something on/off by accident, that's not part of the default library though is it?

Did I need to upload a new memory file for the new library version? I'm pretty confident this worked fine before the upgrade so perhaps I skipped a step?

I've got a meter, will check the ports when I get home tonight.
bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Re: Port active in feeding/water change mode

Post by bubbles »

Done a little more trouble shooting. Looks like relay 1 is permanently on. It doesn't turn off even when the RA unit thinks it's off.

Both pwm channels aren't working anymore either.

:cry:
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Port active in feeding/water change mode

Post by rimai »

Did you use the ControllerTester code?
Roberto.
bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Re: Port active in feeding/water change mode

Post by bubbles »

No I had done my own. Will try it now though.
bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Re: Port active in feeding/water change mode

Post by bubbles »

Hmmm, now that's interesting. Test shows that everything works ok. All the relays are fine and pwm works as expected.

So it must be a code issue, any thoughts?
User avatar
lnevo
Posts: 5430
Joined: Fri Jul 20, 2012 9:42 am

Port active in feeding/water change mode

Post by lnevo »

Since the controller test worked. I would try generating a new code through the wizard... If that works i would slowly add things back in from your previous code.
bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Re: Port active in feeding/water change mode

Post by bubbles »

Bit of an update on this. I spend the weekend rebuilding my sketch and got everything to the same functionality as before (except custom screen). Everything seemed to work fine and as expected. Yesterday I noticed the same behavior as before without having done any code changes. Also noticed though that the pump does infact turn off for maybe 1 out of 5 times.

So as it stands now I don't think it's a software issue but an intermittent hardware issue.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Port active in feeding/water change mode

Post by rimai »

Humm...
It does look like it may be hardware, but if the controllertester doesn't produce the same behavior, seems a bit strange too...
When you ran the tester, were you able to reproduce this behavior?
Roberto.
bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Re: Port active in feeding/water change mode

Post by bubbles »

No, the tester seemed to run fine. My sketch seemed to run fine for a few days as well. It's only yesterday I noticed my tunze pump running when using feed / water change mode. So far it only seems to be socket 1 on my relay box.
bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Re: Port active in feeding/water change mode

Post by bubbles »

Made a bit of a breakthrough on this today.

I rebuild my sketch from scratch and that seemed to work fine, for a while. Did a new sketch today do just do the PWM values changing and again the pumps were fine. To make a long story short, it looks like my tunzes will run at full speed if the min value is not set to 30. If I have a min/max of 50/100 (LongPulse) running non synced they both run full speed. However if I do the same but 30/100 everything works as expected (different speeds and swap over after 5s duration).

Not sure if it's something particular to my units but happy that I finally figured it out. Anyone else seen this behavior before? I've got 2 x 7095 pumps.
mudcat1
Posts: 133
Joined: Sun Dec 09, 2012 7:23 pm

Re: Port active in feeding/water change mode

Post by mudcat1 »

bubbles wrote:Made a bit of a breakthrough on this today.

I rebuild my sketch from scratch and that seemed to work fine, for a while. Did a new sketch today do just do the PWM values changing and again the pumps were fine. To make a long story short, it looks like my tunzes will run at full speed if the min value is not set to 30. If I have a min/max of 50/100 (LongPulse) running non synced they both run full speed. However if I do the same but 30/100 everything works as expected (different speeds and swap over after 5s duration).

Not sure if it's something particular to my units but happy that I finally figured it out. Anyone else seen this behavior before? I've got 2 x 7095 pumps.
Yes, I have similar behavior with my Tunze 6105. If I set the low value to 30 the pump stops until the value is increased to 36. I always thought it was because the Reef Angel might output different voltage at 30% than the stock Tunes controller at 30% but I didn't have one to test my theory.
bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Re: Port active in feeding/water change mode

Post by bubbles »

Still having relay #1 stay on when feeding and water change modes activated :-(
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: Port active in feeding/water change mode

Post by rimai »

I think it could be the relay. That's the only thing I can think of.
The weird part is that it passes the test... :?
You can send it back for repair.
PM me for details.
Roberto.
bubbles
Posts: 50
Joined: Wed Feb 20, 2013 3:05 pm
Location: Auckland, NZ

Re: Port active in feeding/water change mode

Post by bubbles »

I'll do a double check today of the test suite just to be sure.
Post Reply