Need help with new code

Do you have a question on how to do something.
Ask in here.

Posts: 263
Joined: Wed Jan 01, 2014 7:26 am
PostPosted: Thu Mar 01, 2018 7:12 am
I just added some new expansions, relay expansion and ph expansion. In the process I wrote all new code.

I feel like I must have forgotten something important because I can't control any outlets with the portal and anything set to Auto but that isn't specified in the "Setup" statement to be "On" isn't working.

Also, the Status light flashes about once per second. It's almost like the loop() is crashing each time through.

Can someone take a look and see if they can spot what is going on? Note: I changed password and ddns

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 <InternalEEPROM.h>
#include <RA_Colors.h>
#include <RA_CustomColors.h>
#include <Salinity.h>
#include <RF.h>
#include <IO.h>
#include <ORP.h>
#include <AI.h>
#include <PH.h>
#include <WaterLevel.h>
#include <Humidity.h>
#include <DCPump.h>
#include <PAR.h>
#include <ReefAngel.h>

////// Place global variable code below here
unsigned long offtime = 0UL;
unsigned long alktime = 0UL;

////// Place global variable code above here

void setup()
  // This must be the first line
  ReefAngel.Init();  //Initialize controller
  ReefAngel.Use2014Screen();  // Let's use 2014 Screen
  // Ports toggled in Feeding Mode
  ReefAngel.FeedingModePorts = Port6Bit | Port7Bit | Port8Bit;  // skimmer, return, center vortech
  ReefAngel.FeedingModePortsE[0] = Port2Bit | Port3Bit; // UV, outside vortechs
  // Ports toggled in Water Change Mode
  ReefAngel.WaterChangePorts = Port6Bit | Port7Bit; // skimmer, return
  ReefAngel.WaterChangePortsE[0] = Port2Bit; // UV
  // Ports toggled when Lights On / Off menu entry selected
  ReefAngel.LightsOnPorts = Port5Bit;
  // Ports turned off when Overheat temperature exceeded
  ReefAngel.OverheatShutoffPorts = Port1Bit;
  ReefAngel.OverheatShutoffPortsE[0] = 0;
  // Use T1 probe as temperature and overheat functions
  ReefAngel.TempProbe = T1_PROBE;
  ReefAngel.OverheatProbe = T1_PROBE;

  // Add support for 16 channel PWM board

  // Add support for pH expansion
  // Set the Overheat temperature setting
  InternalMemory.OverheatTemp_write( 820 );

  // Ports that are always on
  ReefAngel.Relay.On( Port5 ); //Lights (controlled by timer inside lights)
  ReefAngel.Relay.On( Port6 ); // skimmer
  ReefAngel.Relay.On( Port7 ); // return
  ReefAngel.Relay.On( Port8 ); // center powerhead
  ReefAngel.Relay.On( Box1_Port2 ); //UV
  ReefAngel.Relay.On( Box1_Port3 ); //outside powerheads
  ReefAngel.Relay.On( Box1_Port7 ); //reactor pump

  ////// Place additional initialization code below here

  //Custom Port Labels
  ReefAngel.CustomLabels[0] = "Heater";   // Port1
  ReefAngel.CustomLabels[1] = "Alkdoser"; // Port2
  ReefAngel.CustomLabels[2] = "Caldoser"; // Port3
  ReefAngel.CustomLabels[3] = "Magdoser"; // Port4
  ReefAngel.CustomLabels[4] = "Lights";  // Port5
  ReefAngel.CustomLabels[5] = "Skimmer";  // Port6
  ReefAngel.CustomLabels[6] = "Return";   // Port7
  ReefAngel.CustomLabels[7] = "CenterV"; // Port8 will stay on via UPS when power is out
  ReefAngel.CustomLabels[8] = "Swabbie";   // Box1_Port1
  ReefAngel.CustomLabels[9] = "UV";       // Box1_Port2
  ReefAngel.CustomLabels[10] = "OutsideV"; // Box1_Port3
  ReefAngel.CustomLabels[11] = "Kalkdoser"; // Box1_Port4
  ReefAngel.CustomLabels[12] = "AutoFeeder"; // Box1_Port5
  ReefAngel.CustomLabels[13] = "WaterChange"; // Box1_Port6
  ReefAngel.CustomLabels[14] = "Reactor"; // Box1_Port7
  ReefAngel.CustomLabels[15] = "FugeLight"; // Box1_Port8

  // so portal always shows custom variables
  ReefAngel.CustomVar[7] = 255;

  ////// Place additional initialization code above here

void loop()
  ReefAngel.StandardHeater(Port1); // using internal memory

  if (ReefAngel.Params.PHExp > 840) { // second pH probe is in tank for now so also have it turn off alk and kalk doser
    ReefAngel.Relay.Off(Port2); // turn off alk doser
    ReefAngel.Relay.Off(Box1_Port4); // turn off kalk doser

  if (ReefAngel.Params.PH < 840) {
    ReefAngel.DosingPumpRepeat1( Port2 ); // alk doser
  } else {
    ReefAngel.Relay.Off(Port2);  // safety to turn it off if the pH is too high
  ReefAngel.DosingPumpRepeat2( Port3 ); // cal doser
  ReefAngel.DosingPumpRepeat3( Port4 ); // mag doser

  ReefAngel.StandardLights( Box1_Port1, 9, 0, 9, 5 ); // swabbie, comes on for 5 minutes each morning

  if ((hour() >= 21) || (hour() < 7)) { // run fuge light on reverse photo cycle of main lights
  } else {                             

  if (((hour() == 10) || (hour() == 14) || (hour() == 18) || (hour() == 22)) && (minute() < 1)) { // run autofeeder for 1 minute at 10,2,6,10
  } else {                             
  // lights for invert frag system
  ReefAngel.PWM.SIXTEENChannelPWMSigmoid(2,0,InternalMemory.PWMSlopeEnd0_read()); // Violet channel, startpwm, endpwm, offsets
  ReefAngel.PWM.SIXTEENChannelPWMSigmoid(3,0,InternalMemory.PWMSlopeEnd1_read()); // Royal Blue channel, startpwm, endpwm, offsets
  ReefAngel.PWM.SIXTEENChannelPWMSigmoid(4,0,InternalMemory.PWMSlopeEnd2_read()); // White channel, startpwm, endpwm, offsets
  ReefAngel.PWM.SIXTEENChannelPWMSigmoid(5,0,InternalMemory.PWMSlopeEnd3_read()); // Cool Blue channel, startpwm, endpwm, offsets
  ReefAngel.PWM.SIXTEENChannelPWMSigmoid(6,0,InternalMemory.PWMSlopeEnd4_read(),-60,-60); // Deep Red channel, startpwm, endpwm, offsets
  ReefAngel.PWM.SIXTEENChannelPWMSigmoid(7,0,InternalMemory.PWMSlopeEnd5_read(),-60,-60); // Cyan channel, startpwm, endpwm, offsets
  ReefAngel.PWM.SIXTEENChannelPWMSigmoid(8,0,85); // Fan channel, silent up to 75 or so.

  // Turn off Skimmer if Locker is full
  if (ReefAngel.HighATO.IsActive())
  } else {

  // Turn off things if the power goes out
  if (ReefAngel.LowATO.IsActive())
  { // then power is on
    if (offtime > 0) { // then power was off
      ReefAngel.Relay.On(Port6);  // turn on skimmer
      ReefAngel.Relay.On(Port7);  // turn on return
      offtime = 0UL;
  } else { // then power is off
    // turn off lights, skimmer, return pump after 60 seconds, to conserve UPS power for powerheads
    if (offtime == 0) offtime = now();
    if ((now() - offtime) > 60) { // it has been off for 60 seconds
      ReefAngel.Relay.Off(Port1); // turn off heater
      ReefAngel.Relay.Off(Port2); // turn off alkdoser
      ReefAngel.Relay.Off(Port3); // turn off caldoser
      ReefAngel.Relay.Off(Port4); // turn off magdoser
      ReefAngel.Relay.Off(Port5); // turn off Lights
      ReefAngel.Relay.Off(Port6); // turn off skimmer
      ReefAngel.Relay.Off(Port7); // turn off return pump
      // no need to turn off ports on second power box because it isn't on UPS
      ReefAngel.Relay.On(Port8); // keep on center Vortech

  // This should always be the last line
  ReefAngel.Portal( "AlanM", "MyPassword" );
  ReefAngel.DDNS( "myddns" ); // Your DDNS is

void adjustAlk() {
  // check to see if extra alk or less alk was requested
  // CustomVar is the value read on the checker
  if (ReefAngel.CustomVar[2] > 0) {
    int alkneeded = 150 - ReefAngel.CustomVar[2];
    float alkAdjust = 0;
    if (alkneeded != 0) {
      alkAdjust = 5.71 * (float)alkneeded; // alkAdjust is minutes to run or pause, for 190 gallons volume, 1ppm is 7.6ml for carbonate and 1.33ml/min, so 5.71 minutes per ppm of alk. in carbonate
      //  if adding in bicarbonate double that amount
    } else {
      ReefAngel.CustomVar[2] = 0; // else it must be 0 so reset and do nothing.
      alktime = 0;
    if (alktime == 0) { // it must have just gotten noticed, set the alktime global and initial port status
      if (alkAdjust > 0) {
        alktime = now() + (alkAdjust * 60UL); // should get rounded to integer seconds here
        ReefAngel.Relay.On(Port2); // set it to on
      } else {
        alktime = now() - (alkAdjust * 60UL); // should get rounded to integer seconds here
        ReefAngel.Relay.Off(Port2); // set it to off
    else if (now() > alktime) {
      //ReefAngel.Relay.Override(Port2,2);  // set it back to auto, clear the override
      ReefAngel.Relay.Off(Port2); // turn it off, the default
      ReefAngel.CustomVar[2] = 0; // clear the custom variable
      alktime = 0; // set alktime back to 0
    } else { // must be less than alktime, so keep it on or off depending on if you need to add or subtract alk
      if (alkAdjust > 0) {
      else if (alkAdjust < 0) {
  else {

Posts: 12493
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Thu Mar 01, 2018 8:18 am
That is a bus lock. Something in your expansion bus is causing it.
You also need to change the id of the relay box if you have more than one.
Open the module box and change the dip switches.
Also, ddns server is down, so remove from your code.

Posts: 263
Joined: Wed Jan 01, 2014 7:26 am
PostPosted: Thu Mar 01, 2018 8:39 am
OK. I hit reboot in the ReefAngel Status app to reboot the RA+ and when it came back it isn't flashing and now the portal sees both relay boxes after reboot and I can control them and the pH expansion works, but now my 16 channel dimming expansion isn't doing anything.

I have the main relay box and one relay expansion box. It's an old style with the USB Type B connector on it, not microUSB. That one seems to be set to all three dip switches off which I think is "1", right? Is that OK?

I think the DDNS server is still working for me. I use the ReefAngel Status android app and I'm pointing it at the DDNS name I've always used and it seems to resolve. It isn't getting new Relay Box port labels from the portal when I ask it to update, though, so maybe something is still messed up.

What would I use instead of DDNS to refer to my RA for the app? I've been out of programming them for a few years because it was just working well so I didn't need to change. Also wasn't on the forums for a while. The hazard of hardware that just works.

Posts: 12493
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Thu Mar 01, 2018 11:06 am
Did you add this to your code?
Code: Select all

If relay box is still not working, try all dip switches on the other position.
DDNS server is still resolving. It is just not taking updates anymore.
We switched the portal server to a new linux box and I need to find out how to make it work.
In the mean time, the old server is still up and running with DDNS state frozen.
You probably have static ip if it is still working.
The download of labels on the android app is also broken. Curt is working on that.
You can try the new uapp in the meantime.

Posts: 263
Joined: Wed Jan 01, 2014 7:26 am
PostPosted: Thu Mar 01, 2018 11:13 am
rimai wrote:Did you add this to your code?
Code: Select all

Yes, that's in setup(). And I see it detected at compile time.

I recall that the expansion board is at 0x41 address. Is it possible that this address is also in use by the pH expansion which seems to be working or somehow doesn't work when attached to an expansion hub?

Edit: Relay box expansion is working now after reboot without any code changes. Not sure what caused it to fail at first, but after reboot it started working. If I look in the UApp I do see all of the labels I configured in the portal after pulling them in.
Last edited by AlanM on Thu Mar 01, 2018 11:15 am, edited 1 time in total.

Posts: 12493
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Thu Mar 01, 2018 11:14 am
Yes, 0x41 address.
Run the i2cscanner to see if that is shown as present module.
pH expansion uses a different address.

Posts: 263
Joined: Wed Jan 01, 2014 7:26 am
PostPosted: Thu Mar 01, 2018 12:02 pm
OK. I can do that. Does it keep the same address of 0x41 when it is on the expansion hub?

The pH expansion seems to be wonky a bit. It keeps going to 0.0 reading and then the status light starts flashing, so maybe that's the source of my bus lock earlier.

Posts: 12493
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Thu Mar 01, 2018 12:05 pm

Posts: 263
Joined: Wed Jan 01, 2014 7:26 am
PostPosted: Thu Mar 01, 2018 12:10 pm
Heh, yes that it has the same address or yes that the pH expansion is probably the source of my bus lock? Or both?

I'd bought the pH expansion exactly one year ago and am just now installing it, so it's basically new. Maybe the probe which was stored in the original vial is no good or something?

Posts: 12493
Joined: Fri Mar 18, 2011 6:47 pm
PostPosted: Thu Mar 01, 2018 12:13 pm
I guess yes to both.
Did you also try another port on the hub?

Return to How do I code ...

Who is online

Users browsing this forum: No registered users and 1 guest