Jebao Not Functioning with New Library

Related to the development libraries, released by Curt Binder

Posts: 36
Joined: Tue Jul 23, 2013 5:56 pm
PostPosted: Sun Dec 14, 2014 9:13 pm
I've been running the same code for nearly a year to control my Jebao powerhead. I had to replace the powerhead with another Jebao and in doing so wanted to change some of the max speed values in Short and Long PulseMode. I updated the libraries just prior to uploading the changes and now the new Jebao won't run. It turns on full speed while uploading, but as soon as the code runs...nothing. Not sure what has changed that is causing the problem.

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 <RA_Colors.h>
#include <RA_CustomColors.h>
#include <RF.h>
#include <ReefAngel.h>
#include <SunLocation.h>
#include <WaterLevel.h>
#include <DCPump.h>
#include <WiFiAlert.h>

// Custom menus
#include <avr/pgmspace.h>
prog_char menu1_label[] PROGMEM = "Feeding Mode";
prog_char menu2_label[] PROGMEM = "Coral Feeding";
prog_char menu3_label[] PROGMEM = "Water Change";
prog_char menu4_label[] PROGMEM = "ATO Clear";
prog_char menu5_label[] PROGMEM = "Overheat Clear";
prog_char menu6_label[] PROGMEM = "PH Calibration";
prog_char menu7_label[] PROGMEM = "Date / Time";

// Group the menu entries together
PROGMEM const char *menu_items[] = {
  menu1_label, menu2_label, menu3_label,
  menu4_label, menu5_label, menu6_label,
  menu7_label
};

// Define Custom Memory Locations

#define Mem_B_MaintGFO        145
#define Mem_B_MaintCal        146
#define Mem_B_MaintAlk        147
#define Mem_B_MaintWC         148
#define Mem_B_MaintATO        149
#define Mem_B_MaintFeeding    150
#define Mem_B_MaintSkimmer    151
#define Mem_B_PrintDebug      198
#define Mem_B_ResetMemory     199

void init_memory() {
  InternalMemory.write(Mem_B_ResetMemory,false);
}

#define NUMBERS_8x16

////// Place global variable code below here
int ScreenID=1;
////// Place global variable code above here

// Setup on controller startup/reset
void setup()
{
  // This must be the first line
  ReefAngel.Init();

  //Initialize controller
  ReefAngel.InitMenu(pgm_read_word(&(menu_items[0])),SIZE(menu_items)); // Initialize Menu

  // Ports toggled in Feeding Mode
  ReefAngel.FeedingModePorts = Port3Bit | Port5Bit | Port7Bit  | Port8Bit;
  // Ports toggled in Water Change Mode
  ReefAngel.WaterChangePorts = Port2Bit | Port3Bit | Port7Bit | Port8Bit;
  // Ports toggled when Lights On / Off menu entry selected
  ReefAngel.LightsOnPorts = 0;
  // Ports turned off when Overheat temperature exceeded
  ReefAngel.OverheatShutoffPorts = Port4Bit;
  // Use T1 probe as temperature and overheat functions
  ReefAngel.TempProbe = T1_PROBE;
  ReefAngel.OverheatProbe = T1_PROBE;
  ReefAngel.AddWifi();
  // Set the Overheat temperature setting
  InternalMemory.OverheatTemp_write( 830 );

  // Feeeding and Water Change mode speed
  ReefAngel.DCPump.FeedingSpeed=0;
  ReefAngel.DCPump.WaterChangeSpeed=30;

  // Ports that default on
  ReefAngel.Relay.On( Port1 ); ////Jebao Wavemaker
  ReefAngel.Relay.On( Port3 ); ////Reactor
  ReefAngel.Relay.On( Port7 ); ////Filter
  ReefAngel.Relay.On( Port8 ); ////Skimmer

  // Ports that default off
  ReefAngel.Relay.Off( Port5 );

  ////// Place additional initialization code below here
  ReefAngel.RF.UseMemory=false;
  randomSeed(now()/SECS_PER_DAY);

  if (InternalMemory.read(Mem_B_ResetMemory))
    init_memory();
  ////// Place additional initialization code above here
}

void powerHead() {ReefAngel.WavemakerRandom(Port5,2,5);} // Turn Port5 on/off random cycles that lasts from 5 to 10 secs
             
void loop()
{
  ////// Place your custom code below here
  ReefAngel.StandardHeater( Port4,780,785 );
  ReefAngel.StandardFan ( Port6,785,786 );

  //ATO runs for up to 4 min every 2 hours
  ReefAngel.SingleATO( true,Port2,240,2 );

  ReefAngel.DCPump.DaylightChannel = Sync;

  //Jebao Post Feeding, ReefCrest and Night Time modes
  static unsigned long feeding;
 
  if (ReefAngel.DisplayedMenu==FEEDING_MODE) feeding=now();
 
  if (now()-feeding<3600) {
    // Continue NTM for the 60 minutes
    ReefAngel.PWM.SetDaylight( NutrientTransportMode(40,65,900,true) ); // Nutrient Transport on sync mode
    powerHead();
  }
  //vacation mode
  if ((hour()>9 && hour()<21))
  {
   ReefAngel.PWM.SetDaylight( ShortPulseMode(0,80,900,true));
   powerHead();
  }
  else
  {
   ReefAngel.PWM.SetDaylight( LongPulseMode(0,50,2,true));
   powerHead();
  }

  //ATO timeout alert
  ReefAngel.CustomVar[0]=InternalMemory.read(ATO_Single_Exceed_Flag);
  ReefAngel.CustomVar[7]=255;

  ////// Place your custom code above here

  // This should always be the last line
  ReefAngel.Portal("ReefingHavoc");
  ReefAngel.ShowInterface();
}


// Menu Code
void MenuEntry1(){
  ReefAngel.FeedingModeStart();
}


void MenuEntry2() //"Feed Coral"
{
  // Turns off all pumps (only heater is on) for 15 minuts. Skimmer will turn on for 15 minutes
  // followd by all pumps. 
  // clear the screen
  ReefAngel.ClearScreen(DefaultBGColor);
  ReefAngel.LCD.DrawText(COLOR_MIDNIGHTBLUE, DefaultBGColor, 5, 10, "Coral Feeding");
  ReefAngel.Relay.Off(Port1);
  ReefAngel.Relay.Off(Port3);
  ReefAngel.Relay.Off(Port5);
  ReefAngel.Relay.Off(Port7);
  ReefAngel.Relay.Off(Port8);
  ReefAngel.Relay.Write();
  char msg[8];
  bool done = false;
  int t;
  byte row;

  for ( byte i = 0; i < 2; i++ )
  {
    sprintf(msg, "Phase %d", i+1);
    // leave a blank row and start on the 3rd line
    row = MENU_START_ROW*(i+3);
    ReefAngel.LCD.DrawText(DefaultFGColor, DefaultBGColor, MENU_START_COL, row, msg);
    if ( i == 1 )
    {
      // second time through, we enter phase 2, so shutoff the wavemaker now
      ReefAngel.PWM.SetDaylight( ShortPulseMode(0,45,900,true) );
      ReefAngel.Relay.On(Port1);
      ReefAngel.Relay.On(Port8);
      ReefAngel.Relay.Write();
    }
    // start the feeding timer
    ReefAngel.Timer[FEEDING_TIMER].Start();
    do
    {
      // just loop until the joystick button is pressed or the timer is triggered
      // then break out of the loop and proceed
#if defined WDT || defined WDT_FORCE
      wdt_reset();
#endif  // defined WDT || defined WDT_FORCE
      // update the timer on the screen
      t = ReefAngel.Timer[FEEDING_TIMER].Trigger - now();
      if ( (t >= 0) && ! ReefAngel.Timer[FEEDING_TIMER].IsTriggered() )
      {
        ReefAngel.LCD.Clear(DefaultBGColor,60+(intlength(t)*5),row,100,row+8);
        ReefAngel.LCD.DrawText(DefaultFGColor,DefaultBGColor,60,row,t);
        delay(200);  // to keep from redraw flicker on timer
      }
      else
      {
        done = true;
      }
      if ( ReefAngel.Joystick.IsButtonPressed() )
      {
        // joystick button pressed, so we stop
        done = true;
      }
    }
    while ( ! done );
#if defined WDT || defined WDT_FORCE
    wdt_reset();
#endif  // defined WDT || defined WDT_FORCE
    // reset the variable for the inner do while loop
    done = false;
  }
  // Restore ports & return to the main screen
  ReefAngel.Relay.On(Port3);
  ReefAngel.Relay.On(Port5);
  ReefAngel.Relay.On(Port7);
  ReefAngel.Relay.Write();
  ReefAngel.ExitMenu();
}

void MenuEntry3() {
  ReefAngel.WaterChangeModeStart();
  ReefAngel.Timer[FEEDING_TIMER].Start();
  if(ReefAngel.Timer[FEEDING_TIMER].Trigger - now() >= 0)
  {
    ReefAngel.PWM.SetDaylight( NutrientTransportMode(30,60,900,true)); // Nutrient Transport on sync mode
  }
  else
    ReefAngel.PWM.SetDaylight( LongPulseMode(0,45,2,true));
}
void MenuEntry4() {
  ReefAngel.ATOClear();
  ReefAngel.DisplayMenuEntry("Clear ATO Timeout");
}
void MenuEntry5() {
  ReefAngel.OverheatClear();
  ReefAngel.DisplayMenuEntry("Clear Overheat");
}
void MenuEntry6() {
  ReefAngel.SetupCalibratePH();
  ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}
void MenuEntry7() {
  ReefAngel.SetupDateTime();
  ReefAngel.DisplayedMenu = ALT_SCREEN_MODE;
}

// Custom Main Screen
void DrawCustomMain() {
  const int NumScreens=3;
  static boolean drawGraph=true;

  // Main Header
  ReefAngel.LCD.DrawText(COLOR_DARKSLATEBLUE, DefaultBGColor, 30, 2 , "SPENCER'S REEF");
  ReefAngel.LCD.DrawDate(5,112);
  ReefAngel.LCD.Clear(COLOR_BLACK, 1, 11, 128, 11);

  // Param Header
  DrawParams(5,14);

  switch (ScreenID) {
  case 0:
    {
      if (drawGraph) {
        ReefAngel.LCD.DrawGraph(5,40);
        drawGraph=false;
      }
      break;
    }
  case 1:
    {
      DrawStatus(5,40);
      break;
    }
  }


  // Date+Time
  // ReefAngel.LCD.DrawDate(5,122);

  if (ReefAngel.Joystick.IsLeft()) {
    ReefAngel.ClearScreen(DefaultBGColor);
    ScreenID--;
    drawGraph=true;
  }
  if (ReefAngel.Joystick.IsRight()) {
    ReefAngel.ClearScreen(DefaultBGColor);
    ScreenID++;
    drawGraph=true;
  }
  if (ScreenID<0) ScreenID=NumScreens-1;
  if (ScreenID>=NumScreens) ScreenID=0;

}

void DrawCustomGraph() {
  if (ScreenID==0)
    ReefAngel.LCD.DrawGraph(5, 40);
}

void DrawParams(int x, int y) {
  char buf[16];

  ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor,x+5,y,"Temp:");
  ReefAngel.LCD.DrawText(COLOR_BLACK,DefaultBGColor,x+80, y, "PH:");
  // Temp and PH
  y+=2;
  ConvertNumToString(buf, ReefAngel.Params.Temp[T2_PROBE], 10);
  ReefAngel.LCD.DrawText(T2TempColor, DefaultBGColor, x+45, y, buf);
  y+=6;
  ConvertNumToString(buf, ReefAngel.Params.Temp[T1_PROBE], 10);
  ReefAngel.LCD.DrawLargeText(T1TempColor, DefaultBGColor, x+5, y, buf, Num8x16);
  ConvertNumToString(buf, ReefAngel.Params.PH, 100);
  ReefAngel.LCD.DrawLargeText(PHColor, DefaultBGColor, x+80, y, buf, Num8x16);
  y+=5;
  ConvertNumToString(buf, ReefAngel.Params.Temp[T3_PROBE], 10);
  ReefAngel.LCD.DrawText(T3TempColor, DefaultBGColor, x+45, y, buf);
}

void DrawStatus(int x, int y) {
  int t=x;

  ReefAngel.LCD.DrawLargeText(COLOR_INDIGO,DefaultBGColor,15,y,"High",Font8x16);
  ReefAngel.LCD.DrawLargeText(COLOR_INDIGO,DefaultBGColor,85,y,"Low",Font8x16);

  if (ReefAngel.HighATO.IsActive()) {
    ReefAngel.LCD.FillCircle(55,y+3,5,COLOR_GREEN);
  }
  else {
    ReefAngel.LCD.FillCircle(55,y+3,5,COLOR_RED);
  }

  if (ReefAngel.LowATO.IsActive()) {
    ReefAngel.LCD.FillCircle(70,y+3,5,COLOR_GREEN);
  }
  else {
    ReefAngel.LCD.FillCircle(70,y+3,5,COLOR_RED);
  }
  y+=12;

}

Posts: 12225
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Sun Dec 14, 2014 9:26 pm
Does your Daylight channels show 0%?
Roberto.

Posts: 36
Joined: Tue Jul 23, 2013 5:56 pm
PostPosted: Mon Dec 15, 2014 6:21 am
Yes
User avatar
Posts: 1426
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City
PostPosted: Mon Dec 15, 2014 7:46 am
Is this the culprit?

Code: Select all
  ReefAngel.DCPump.DaylightChannel = Sync;


Since you're writing directly to the Daylight port and not using DCPump.SetMode, I wonder if the memory settings are over-riding. I wonder if taking this line out, or adding ReefAngel.DCPump.UseMemory=false; after it would help.

--Colin

Posts: 36
Joined: Tue Jul 23, 2013 5:56 pm
PostPosted: Mon Dec 15, 2014 1:16 pm
Colin - that worked. I'm assuming that something changed with the new library that caused the issue. I'm interested in trying out DCPump.Mode for "Else" mode. Does this simply require switching out

ReefAngel.PWM.SetDaylight( ShortPulseMode(0,80,900,true));

for

ReefAngel.DCPump.Mode=Else;
User avatar
Posts: 1426
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City
PostPosted: Mon Dec 15, 2014 2:28 pm
Code: Select all
ReefAngel.DCPump.SetMode(Else,60,30);


Calls ElseMode with range of 60% +/- 30%. So it will randomly run between 30% and 90%. You can change these values as you like, but most Jebaos stop at anything less than 30.

--Colin

Posts: 36
Joined: Tue Jul 23, 2013 5:56 pm
PostPosted: Mon Dec 15, 2014 3:25 pm
This may be a dumb question, but which is better to use - DCPump or PWM.SetDaylight?
User avatar
Posts: 1426
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City
PostPosted: Mon Dec 15, 2014 3:37 pm
DCPump allows easier portal control. It's also easier if you're using more than one pump and want them to run opposite of each other (sync/antisync). On Else mode, for example, when the sync channel goes up, the antisync goes down and vice versa.

For example, here's my pump code. If the portal is set to "custom", it runs either Else or Gyre at different speeds depending on the time of the day. If the portal is set to any other mode, it runs that mode. It's much easier with DCPump.

Code: Select all
// *******************  Pump Control *******************

  if (InternalMemory.DCPumpMode_read()==11)   // If custom mode on Portal
  {
    ReefAngel.DCPump.UseMemory = false;    // Turn off memory control
    ReefAngel.DCPump.SetMode(Else,60,25);  // If nothing changes it in the next few lines, this is what runs.
    if (hour()>=22 || hour()<9) ReefAngel.DCPump.SetMode(Gyre,70,10,31);  // Gyre mode 31 to 60 over 10 minutes from 2200 to 0900
    if (hour()>=9 && hour()<10) ReefAngel.DCPump.SetMode(Gyre,90,10,30);  // Gyre mode 30 to 90 over 10 minutes from 0900 to 1000
    if (hour()>=10 && hour()<11) ReefAngel.DCPump.SetMode(Else,40,10);    // Else mode from 1000 to 1100.  Wake up!
  }
  else ReefAngel.DCPump.UseMemory = true;    //  If it's not custom mode on the portal, then do what mode the portal says.

  ReefAngel.DCPump.DaylightChannel = None;        // Set DCPump sync/antisync for every PWM port
  ReefAngel.DCPump.ActinicChannel = None;
  ReefAngel.DCPump.ExpansionChannel[0] = None;
  ReefAngel.DCPump.ExpansionChannel[1] = None;
  ReefAngel.DCPump.ExpansionChannel[2] = None;
  ReefAngel.DCPump.ExpansionChannel[3] = None;
  ReefAngel.DCPump.ExpansionChannel[4] = Sync;    // Jebao's are hooked up to channels 4 and 5
  ReefAngel.DCPump.ExpansionChannel[5] = AntiSync;


Now, if you don't care about all that, then PWM.SetDaylight works fine. :D

--Colin

Posts: 36
Joined: Tue Jul 23, 2013 5:56 pm
PostPosted: Mon Dec 15, 2014 7:20 pm
So I made the change over to DCPump.SetMode as I'm going to be adding a second Jebao after Christmas. Everything seems to be working correctly with the exception of what I see in the Portal. The logic in my code says Lagoon, but the Portal changes between NutrientTransport and Lagoon when I refresh. Any thoughts?

Code: Select all
void loop()
{
  ReefAngel.DCPump.DaylightChannel = Sync;
  ReefAngel.DCPump.ActinicChannel = None;
  ReefAngel.StandardHeater( Port4,780,785 );
  //ReefAngel.StandardFan ( Port6,785,786 );

  //ATO runs for up to 4 min every 2 hours
  ReefAngel.SingleATO( true,Port2,240,2 );

  //Jebao Post Feeding, ReefCrest and Night Time modes
  static unsigned long feeding;

  if (ReefAngel.DisplayedMenu==FEEDING_MODE) feeding=now();

  if (now()-feeding<3600) {
    // Continue NTM for the 60 minutes
    ReefAngel.DCPump.SetMode( NutrientTransport,85,2000 );
    powerHead();
  }
  else if ((hour()>9 && hour()<21))
  {
     ReefAngel.DCPump.SetMode( ShortPulse,80,1000 );
    powerHead();
  }
  else
  {
    ReefAngel.DCPump.SetMode( Lagoon,40,10 );
    powerHead();
  }

  //ATO timeout alert
  ReefAngel.CustomVar[0]=InternalMemory.read(ATO_Single_Exceed_Flag);
  ReefAngel.CustomVar[7]=255;

  ////// Place your custom code above here

  // This should always be the last line
  ReefAngel.Portal("ReefingHavoc");
  ReefAngel.ShowInterface();
}
User avatar
Posts: 1426
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City
PostPosted: Mon Dec 15, 2014 7:32 pm
Try adding ReefAngel.DCPump.UseMemory=false; at the beginning at your loop.

--Colin
Next

Return to Development Libraries

Who is online

Users browsing this forum: No registered users and 2 guests

cron