RANet Cloud and Lightning

Do you have a question on how to do something.
Ask in here.
rimai
Posts: 12881
Joined: Fri Mar 18, 2011 6:47 pm

Re: RANet Cloud and Lightning

Post by rimai »

No, the lightning can happen whenever you want. The minute we send the trigger, the receiver will create the lightning effect for 5 to 10s.
This will happen even if the lights are full brightness, because the lightning will be trigger based now. But you can control when you want to send the trigger. so you can set it to trigger only when there is a cloud and only in certain clouds and not all of them.
Roberto.
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

ahh then 5 to 10 seconds sounds good
Image
User avatar
cosmith71
Posts: 1437
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City

Re: RANet Cloud and Lightning

Post by cosmith71 »

It's already trigger based. The new version changes the mechanism of the trigger, but not the general principle of operation. The new version has a dedicated byte for the trigger, whereas the older one had the trigger hidden in one of the dimming channels.

The trigger is sent by the checkcloud function in the RA code. The receiver then generates a set of 1 to 4 flashes. The frequency of the trigger depends on the mode chosen.

There are variables in the checkcloud function that can be changed to adjust frequency of lightning, chance of lightning per cloud, etc.

Roberto's code is pretty much identical in the way the lightning is generated and the timing, which is what confuses me.

--Colin
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

Well I tried out my new bluetooth attachment and reloaded the controller code with the dev library and now instead channel 2 is flashing but not channel 1 video attached for the "flash".

response was still very slow but also stepped up and down instead of flashing

https://www.youtube.com/watch?v=eYNWTjKiiYs
Image
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

the new library had another effect, after the storm was over channel 0 and channel 2 shut off completely.
Image
User avatar
cosmith71
Posts: 1437
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City

Re: RANet Cloud and Lightning

Post by cosmith71 »

The old RANet receiver code is incompatible with the new library.
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

Ok, went back to the other library for now. Just noticed something that may be of help.

Where you would expect the lighting to ramp up the whites it is actually flashing off then back on to the level called for in the cloud. At no point during any flash does the light ramp up, like it is working in reverse.
Image
User avatar
cosmith71
Posts: 1437
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City

Re: RANet Cloud and Lightning

Post by cosmith71 »

I'll be off work in a few hours. I'll take a look at it. That does help.
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

In the latest receiver code posted you used a variable for the channels here

Code: Select all

  for (int n=1; n<3; n++)
    {
      int newdata=4095;
      Wire.beginTransmission(0x40);      // Address of the dimming expansion module
      Wire.write(0x8+(4*n));             // 0x8 is channel 0, 0x12 is channel 1, etc.  I'm using channel 1.
      Wire.write(newdata&0xff);          // Send the data 8 bits at a time.  This sends the LSB
      Wire.write(newdata>>8);            // This sends the MSB
      Wire.endTransmission();
    }
In the test code the channels are listed individually

Code: Select all

{

  int a=random(5);
  for (int i=0;i<a;i++)
  {
    newdata=4095;
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*0));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*1));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*2));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    delay(20+random(50));
    newdata=0;
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*0));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*1));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*2));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    delay(30+random(20));
  }
  delay(random(1000));
}
Looking through attempting to understand why one would work but not the other. As you can see I am doing everything in my power to avoid studying for the bar exam I have to take in two weeks
Image
User avatar
cosmith71
Posts: 1437
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City

Re: RANet Cloud and Lightning

Post by cosmith71 »

Yeah, I thought about that. Try this.

Code: Select all

#include <Wire.h>
#include <avr/eeprom.h>

#define BLUE_LED    9
#define WHITE_LED   10

#define BLUE_INTENSITY   255
#define WHITE_INTENSITY  255

#define RANET_MAX_SIZE  64
#define DISCONNECT_TIMEOUT  2000

#define LastFallback0  100 // Memory location for fallback storage

#define RANet_Down    0
#define RANet_OK      1

byte Trigger=150;    // Trigger value for lightning effect
byte TriggerChannel=1;    // Channel to look for the trigger on

byte buffer_index;
byte buffer[128];
char buf[3];
byte bufint, bufsize;
byte RANetData[RANET_MAX_SIZE];
byte RANetCRC;
byte BlueChannel=0;
byte WhiteChannel=0;
byte RANet_Status=RANet_Down;
boolean cable_present=false;

unsigned long lastmillis=millis();
unsigned long lastcablecheck=millis();

void setup()
{
  pinMode(BLUE_LED,OUTPUT);
  pinMode(WHITE_LED,OUTPUT);
  Serial.begin(57600);
  Wire.onReceive(NULL);
  Wire.onRequest(NULL);
  Wire.begin();
  for (int a=0;a<RANET_MAX_SIZE; a++) // Clear array
    RANetData[a]=0; 
  Wire.beginTransmission(0x68);
  Wire.write(0);
  int a=Wire.endTransmission();
  cable_present=(a==0);
  // setup PCA9685 for data receive
  // we need this to make sure it will work if connected ofter controller is booted, so we need to send it all the time.
  Wire.beginTransmission(0x40);
  Wire.write(0);
  Wire.write(0xa1);
  Wire.endTransmission();
}

void loop()
{
  if (cable_present)
  {
    BlueChannel=100;
    WhiteChannel=0;
    analogWrite(WHITE_LED,WHITE_INTENSITY*WhiteChannel/100);
    analogWrite(BLUE_LED,BLUE_INTENSITY*BlueChannel/100);
  }
  else  
  {
    BlueChannel=0;
    WhiteChannel=0;
    while(Serial.available())
    {
      UpdateWhiteChannel();
      char c = Serial.read(); // Read each incoming byte
      buffer[buffer_index]=c; // store in the buffer array
      if (c==10) // if line feed we analyze the payload
      {
        if (buffer_index>25) // only need to analyse if buffer_index is greater than 25, otherwise the payload is broken or corrupt
          if (buffer_index==buffer[1]) // check if payload matches the length the controller sent
          {
            UpdateWhiteChannel();
            RANetCRC=0;
            for (int a=0; a<(buffer_index-2); a++) // calculate CRC
              RANetCRC+=buffer[a];
            UpdateWhiteChannel();
            if (RANetCRC==buffer[buffer_index-2]) // if CRC matches
            {
              UpdateWhiteChannel();
              for (int a=0; a<(buffer_index-2); a++) // Copy buffer to RANetData
                RANetData[a]=buffer[a];
              UpdateWhiteChannel();
              lastmillis=millis();
              //            Serial.print(millis());
              //            Serial.print("\t");
              //            Serial.println(RANetData[2]);
              for (int a=0;a<8;a++)
              {
                if (eeprom_read_byte((unsigned char *) LastFallback0+a)!=RANetData[10+a])
                {
                  eeprom_write_byte((unsigned char *) LastFallback0+a, RANetData[10+a]);
                }
                Wire.beginTransmission(0x38+a);
                Wire.write(~RANetData[2+a]);
                Wire.endTransmission();
              }
              // Check for lightning trigger
              if (RANetData[18+TriggerChannel] == Trigger) Lightning();
              else             // If the trigger has not been sent
              {               
                for (int a=0;a<6;a++)  // send along the data
                {
                  int newdata=(int)(RANetData[18+a]*40.95);
                  Wire.beginTransmission(0x40);
                  Wire.write(0x8+(4*a));
                  Wire.write(newdata&0xff);
                  Wire.write(newdata>>8);
                  Wire.endTransmission();
                }
              }
              UpdateWhiteChannel();
              RANet_Status=RANet_OK;
            }
          }
        buffer_index=255; // reset buffer index
      }
      UpdateWhiteChannel();
      if (buffer_index++>=128) buffer_index=0; // increment index of buffer array. reset index if >=128
    }
    if (millis()-lastmillis>DISCONNECT_TIMEOUT)
    {
      lastmillis=millis();
      //    Serial.println("Disconnected");
      //    Serial.print(millis());
      //    Serial.print("\t");
      //    Serial.println(RANetData[10]);
      for (int a=0;a<8;a++)
      {
        Wire.beginTransmission(0x38+a);
        Wire.write(~eeprom_read_byte((unsigned char *) LastFallback0+a));
        Wire.endTransmission();
      }
      RANet_Status=RANet_Down;
    }
    if (RANet_Status==RANet_Down)
    {
      BlueChannel=0;
      WhiteChannel=millis()%2000<1000?0:100;
      analogWrite(WHITE_LED,WHITE_INTENSITY*WhiteChannel/100);
      analogWrite(BLUE_LED,BLUE_INTENSITY*BlueChannel/100);
    }
  }
}

void UpdateWhiteChannel()
{
  WhiteChannel=sin(radians((millis()%7200)/40))*255;
  BlueChannel=255-(sin(radians((millis()%7200)/40))*255);
  analogWrite(WHITE_LED,WhiteChannel);
  analogWrite(BLUE_LED,BlueChannel);
}

void Lightning()
{
  int a=random(1,5);    // Pick a number of consecutive flashes from 1 to 4.  
  for (int i=0; i<a; i++)
  {
    // Flash on
      int newdata=4095;
      Wire.beginTransmission(0x40);      // Address of the dimming expansion module
      Wire.write(0x8+(4*1));             // 0x8 is channel 0, 0x12 is channel 1, etc.  I'm using channel 1.
      Wire.write(newdata&0xff);          // Send the data 8 bits at a time.  This sends the LSB
      Wire.write(newdata>>8);            // This sends the MSB
      Wire.endTransmission();
      
      Wire.beginTransmission(0x40);      // Address of the dimming expansion module
      Wire.write(0x8+(4*2));             // 0x8 is channel 0, 0x12 is channel 1, etc.  I'm using channel 1.
      Wire.write(newdata&0xff);          // Send the data 8 bits at a time.  This sends the LSB
      Wire.write(newdata>>8);            // This sends the MSB
      Wire.endTransmission();

    int randy=random(20,80);    // Random number for a delay
    if (randy>71) randy=((randy-70)/2)*100;    // Small chance of a longer delay
    delay(randy);                // Wait from 20 to 69 ms, or 100-400 ms

    // Flash off
    
      newdata=0;
      Wire.beginTransmission(0x40);    // Same as above
      Wire.write(0x8+(4*1));
      Wire.write(newdata&0xff);
      Wire.write(newdata>>8);
      Wire.endTransmission();
      
      Wire.beginTransmission(0x40);    // Same as above
      Wire.write(0x8+(4*2));
      Wire.write(newdata&0xff);
      Wire.write(newdata>>8);
      Wire.endTransmission();
    
    delay(random(30,50));                // Wait from 30 to 49 ms 
  }
}
Last edited by cosmith71 on Sat Feb 07, 2015 7:39 pm, edited 1 time in total.
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

with the dev libraries? Im getting a compiling error with the original

Code: Select all

ketch_feb07b.cpp: In function 'void Lightning()':
sketch_feb07b:185: error: redeclaration of 'int newdata'
sketch_feb07b:166: error: 'int newdata' previously declared here
Image
User avatar
cosmith71
Posts: 1437
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City

Re: RANet Cloud and Lightning

Post by cosmith71 »

Dammit. It's been a long day. :D

I fixed it. Recopy and try again, with the regular, non-dev libraries.

--Colin
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

still just channel 1 and with a flash off instead of ramping up
Image
User avatar
cosmith71
Posts: 1437
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City

Re: RANet Cloud and Lightning

Post by cosmith71 »

One more try for the night. This should flash all three channels.

Code: Select all

#include <Wire.h>
#include <avr/eeprom.h>

#define BLUE_LED    9
#define WHITE_LED   10

#define BLUE_INTENSITY   255
#define WHITE_INTENSITY  255

#define RANET_MAX_SIZE  64
#define DISCONNECT_TIMEOUT  2000

#define LastFallback0  100 // Memory location for fallback storage

#define RANet_Down    0
#define RANet_OK      1

byte Trigger=150;    // Trigger value for lightning effect
byte TriggerChannel=1;    // Channel to look for the trigger on

byte buffer_index;
byte buffer[128];
char buf[3];
byte bufint, bufsize;
byte RANetData[RANET_MAX_SIZE];
byte RANetCRC;
byte BlueChannel=0;
byte WhiteChannel=0;
byte RANet_Status=RANet_Down;
boolean cable_present=false;

unsigned long lastmillis=millis();
unsigned long lastcablecheck=millis();

void setup()
{
  pinMode(BLUE_LED,OUTPUT);
  pinMode(WHITE_LED,OUTPUT);
  Serial.begin(57600);
  Wire.onReceive(NULL);
  Wire.onRequest(NULL);
  Wire.begin();
  for (int a=0;a<RANET_MAX_SIZE; a++) // Clear array
    RANetData[a]=0; 
  Wire.beginTransmission(0x68);
  Wire.write(0);
  int a=Wire.endTransmission();
  cable_present=(a==0);
  // setup PCA9685 for data receive
  // we need this to make sure it will work if connected ofter controller is booted, so we need to send it all the time.
  Wire.beginTransmission(0x40);
  Wire.write(0);
  Wire.write(0xa1);
  Wire.endTransmission();
}

void loop()
{
  if (cable_present)
  {
    BlueChannel=100;
    WhiteChannel=0;
    analogWrite(WHITE_LED,WHITE_INTENSITY*WhiteChannel/100);
    analogWrite(BLUE_LED,BLUE_INTENSITY*BlueChannel/100);
  }
  else  
  {
    BlueChannel=0;
    WhiteChannel=0;
    while(Serial.available())
    {
      UpdateWhiteChannel();
      char c = Serial.read(); // Read each incoming byte
      buffer[buffer_index]=c; // store in the buffer array
      if (c==10) // if line feed we analyze the payload
      {
        if (buffer_index>25) // only need to analyse if buffer_index is greater than 25, otherwise the payload is broken or corrupt
          if (buffer_index==buffer[1]) // check if payload matches the length the controller sent
          {
            UpdateWhiteChannel();
            RANetCRC=0;
            for (int a=0; a<(buffer_index-2); a++) // calculate CRC
              RANetCRC+=buffer[a];
            UpdateWhiteChannel();
            if (RANetCRC==buffer[buffer_index-2]) // if CRC matches
            {
              UpdateWhiteChannel();
              for (int a=0; a<(buffer_index-2); a++) // Copy buffer to RANetData
                RANetData[a]=buffer[a];
              UpdateWhiteChannel();
              lastmillis=millis();
              //            Serial.print(millis());
              //            Serial.print("\t");
              //            Serial.println(RANetData[2]);
              for (int a=0;a<8;a++)
              {
                if (eeprom_read_byte((unsigned char *) LastFallback0+a)!=RANetData[10+a])
                {
                  eeprom_write_byte((unsigned char *) LastFallback0+a, RANetData[10+a]);
                }
                Wire.beginTransmission(0x38+a);
                Wire.write(~RANetData[2+a]);
                Wire.endTransmission();
              }
              // Check for lightning trigger
              if (RANetData[18+TriggerChannel] == Trigger) Lightning();
              else             // If the trigger has not been sent
              {               
                for (int a=0;a<6;a++)  // send along the data
                {
                  int newdata=(int)(RANetData[18+a]*40.95);
                  Wire.beginTransmission(0x40);
                  Wire.write(0x8+(4*a));
                  Wire.write(newdata&0xff);
                  Wire.write(newdata>>8);
                  Wire.endTransmission();
                }
              }
              UpdateWhiteChannel();
              RANet_Status=RANet_OK;
            }
          }
        buffer_index=255; // reset buffer index
      }
      UpdateWhiteChannel();
      if (buffer_index++>=128) buffer_index=0; // increment index of buffer array. reset index if >=128
    }
    if (millis()-lastmillis>DISCONNECT_TIMEOUT)
    {
      lastmillis=millis();
      //    Serial.println("Disconnected");
      //    Serial.print(millis());
      //    Serial.print("\t");
      //    Serial.println(RANetData[10]);
      for (int a=0;a<8;a++)
      {
        Wire.beginTransmission(0x38+a);
        Wire.write(~eeprom_read_byte((unsigned char *) LastFallback0+a));
        Wire.endTransmission();
      }
      RANet_Status=RANet_Down;
    }
    if (RANet_Status==RANet_Down)
    {
      BlueChannel=0;
      WhiteChannel=millis()%2000<1000?0:100;
      analogWrite(WHITE_LED,WHITE_INTENSITY*WhiteChannel/100);
      analogWrite(BLUE_LED,BLUE_INTENSITY*BlueChannel/100);
    }
  }
}

void UpdateWhiteChannel()
{
  WhiteChannel=sin(radians((millis()%7200)/40))*255;
  BlueChannel=255-(sin(radians((millis()%7200)/40))*255);
  analogWrite(WHITE_LED,WhiteChannel);
  analogWrite(BLUE_LED,BlueChannel);
}

void Lightning()
{
  int a=random(5);
  for (int i=0;i<a;i++)
  {
    int newdata=4095;
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*0));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*1));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*2));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    delay(20+random(50));
    newdata=0;
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*0));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*1));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    Wire.beginTransmission(0x40);
    Wire.write(0x8+(4*2));
    Wire.write(newdata&0xff);
    Wire.write(newdata>>8);
    Wire.endTransmission();
    delay(30+random(20));

  }
}
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

and it still only flashes channel one :(
Image
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

Ok if I change the trigger to be sent on channel 2 only channel 2 flashes

No change on the effect still not ramping up.
Image
User avatar
cosmith71
Posts: 1437
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City

Re: RANet Cloud and Lightning

Post by cosmith71 »

Hmmm. Give me a couple of days (one more 12 hour shift today and then some time off).

--Colin
User avatar
cosmith71
Posts: 1437
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City

Re: RANet Cloud and Lightning

Post by cosmith71 »

Lets try this. Use the dev libraries.

On the RA:

Code: Select all

#define NUMBERS_8x16
#define FONT_8x8

#include <SoftwareSerial.h>
#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 <ReefAngel.h>

////// Place global variable code below here
byte DaylightPWMValue=0;   // For cloud code
boolean FireInTheHole=false;    // True if trigger has been sent
byte TriggerChannel=1;          // Dimming expansion channel to look for lightning trigger
byte Trigger=150;               // Value sent to RANet Dimming module to trigger lightning strikes

void DrawCustomMain()
{
  byte x = 6;
  byte y = 2;
  byte t;
  char text[7];
  //static byte vtechmode=0;
  // *********** CHANGE TEMP READOUT COLOR DEPENDENT ON CHILLER STATUS ***********
  int TempColor;        // Color for drawing temperature
  boolean FanOn = ReefAngel.Relay.Status(Port8);    // Get the status of the Chiller relay

  if (FanOn)    
  {
      TempColor = COLOR_RED;   // Red text, too warm, chiller is on
  }
  if (!FanOn)  
  {
      TempColor = COLOR_GREEN;  // Green text, no chiller on
  }
  // ***********************************************************************************

  ReefAngel.LCD.DrawDate(6, 2);
  ReefAngel.LCD.Clear(COLOR_BLACK, 1, 11, 132, 11);
  pingSerial();
  
  ReefAngel.LCD.DrawLargeText(3,255,8,14,"Redneck Reefin!", Font8x8);
  ReefAngel.LCD.DrawLargeText(3,255,8,55,"Jason & Sarah's", Font8x8);
  ReefAngel.LCD.DrawLargeText(3,255,32,64,"Money Pit", Font8x8);
  pingSerial();

  ReefAngel.LCD.DrawText(COLOR_RED,255, 6, 88, "--------------------");

  ReefAngel.LCD.DrawText(COLOR_RED,255, 2, 93, "|");
  ReefAngel.LCD.DrawText(COLOR_RED,255, 2, 103, "|");
  ReefAngel.LCD.DrawText(COLOR_RED,255, 2, 113, "|");
  ReefAngel.LCD.DrawText(COLOR_RED,255, 2, 123, "|");
  ReefAngel.LCD.DrawText(COLOR_RED,255, 126, 93, "|");
  ReefAngel.LCD.DrawText(COLOR_RED,255, 126, 103, "|");
  ReefAngel.LCD.DrawText(COLOR_RED,255, 126, 113, "|");
  ReefAngel.LCD.DrawText(COLOR_RED,255, 126, 123, "|");

  ReefAngel.LCD.DrawLargeText(0,255,8,25,"TANK", Font8x8);
  ConvertNumToString(text, ReefAngel.Params.Temp[T3_PROBE], 10);
  ReefAngel.LCD.DrawLargeText(TempColor, 255, 42, 25, text, Font8x8);
  pingSerial();
  
  ReefAngel.LCD.DrawLargeText(0,255,8,35,"HOOD", Font8x8);
  ConvertNumToString(text, ReefAngel.Params.Temp[T1_PROBE], 10);
  ReefAngel.LCD.DrawLargeText(153, 255, 42, 35, text, Font8x8);
  pingSerial();
  
  ReefAngel.LCD.DrawLargeText(0,255,8,45,"ROOM", Font8x8);
  ConvertNumToString(text, ReefAngel.Params.Temp[T2_PROBE], 10);
  ReefAngel.LCD.DrawLargeText(66, 255, 42, 45, text, Font8x8);

  ReefAngel.LCD.DrawText(0,255,100,25,"pH");
  ConvertNumToString(text, ReefAngel.Params.PH, 100);
  ReefAngel.LCD.DrawLargeText(COLOR_BLACK, 255, 85, 35, text, Num8x16);
  pingSerial();

  byte TempRelay = ReefAngel.Relay.RelayData;
  TempRelay &= ReefAngel.Relay.RelayMaskOff;
  TempRelay |= ReefAngel.Relay.RelayMaskOn;
  ReefAngel.LCD.DrawOutletBox(12, 75, TempRelay);
  pingSerial();
  
  ReefAngel.LCD.Clear(255,46,96,70,104);
  ReefAngel.LCD.Clear(255,106,96,132,104);
  ReefAngel.LCD.DrawText(0,255,8,96, "White=");  
  ReefAngel.LCD.DrawText(197,255,46,96, ReefAngel.PWM.GetChannelValue(1));
  //ReefAngel.PWM.GetDaylightValue()),
  pingSerial();
  
  ReefAngel.LCD.DrawText(0,255,72,96, "Blue=");   
  ReefAngel.LCD.DrawText(3,255,106,96, ReefAngel.PWM.GetChannelValue(0));
  //ReefAngel.PWM.GetActinicValue());


}
void DrawCustomGraph()
{
}


////// 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 
    ReefAngel.AddWaterLevelExpansion();  // Water Level Expansion Module
    ReefAngel.AddRANet();    // Support for RANet wireless accessories
    // Ports toggled in Feeding Mode
    ReefAngel.FeedingModePorts = Port4Bit | Port5Bit | Port6Bit;
    // Ports toggled in Water Change Mode
    ReefAngel.WaterChangePorts = Port1Bit | Port5Bit | Port6Bit;
    // Ports toggled when Lights On / Off menu entry selected
   ReefAngel.LightsOnPorts = Port3Bit;
    // Ports turned off when Overheat temperature exceeded
   ReefAngel.OverheatShutoffPorts = 0;
    // Use T3 probe as temperature and overheat functions
    ReefAngel.TempProbe = T3_PROBE;
    ReefAngel.OverheatProbe = T3_PROBE;


    // Ports that are always on
    ReefAngel.Relay.On( Port2 );
    ReefAngel.Relay.On( Port3 );
    ReefAngel.Relay.On( Port4 );
    ReefAngel.Relay.On( Port7 );
    ////// Place additional initialization code below here
    

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

void loop()
{
    ReefAngel.SingleATOLow( Port1 );
    ReefAngel.WavemakerRandom( Port5,30,100 );
    ReefAngel.WavemakerRandom( Port6,30,100 );
    ReefAngel.StandardFan( Port8 );

    ////// Place your custom code below here
  // Cloud/lightning lighting control
FireInTheHole=false;
ReefAngel.PWM.SetChannel( 0, PWMParabola(9,30,23,00,5,100,5) );    // Set actinic channel
DaylightPWMValue=PWMParabola(10,30,22,0,0,100,0);
CheckCloud();    // Check to see if it's time for a cloud/lightning
if (!FireInTheHole)
{
  ReefAngel.PWM.SetChannel(1,DaylightPWMValue);    // Whites are on channel 1
  ReefAngel.PWM.SetChannel(2,DaylightPWMValue);    // and channel 2
}

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

    // This should always be the last line
    ReefAngel.Portal( "jegillis" );
    ReefAngel.ShowInterface();
}
// Random Cloud/Thunderstorm effects function

void CheckCloud()
{
  // ------------------------------------------------------------
  // Change the values below to customize your cloud/storm effect

  // Frequency in days based on the day of the month - number 2 means every 2 days, for example (day 2,4,6 etc)
  // For testing purposes, you can use 1 and cause the cloud to occur everyday
#define Clouds_Every_X_Days 1 

  // Percentage chance of a cloud happening today
  // For testing purposes, you can use 100 and cause the cloud to have 100% chance of happening
#define Cloud_Chance_per_Day 100

  // Minimum number of minutes for cloud duration.  Don't use max duration of less than 6
#define Min_Cloud_Duration 7

  // Maximum number of minutes for the cloud duration. Don't use max duration of more than 255
#define Max_Cloud_Duration 15

  // Minimum number of clouds that can happen per day
#define Min_Clouds_per_Day 3

  // Maximum number of clouds that can happen per day
#define Max_Clouds_per_Day 4

  // Only start the cloud effect after this setting
  // In this example, start cloud after noon
#define Start_Cloud_After NumMins(12,00)

  // Always end the cloud effect before this setting
  // In this example, end cloud before 9:00pm
#define End_Cloud_Before NumMins(21,00)

  // Percentage chance of a lightning happen for every cloud
  // For testing purposes, you can use 100 and cause the lightning to have 100% chance of happening
#define Lightning_Change_per_Cloud 100

  // Note: Make sure to choose correct values that will work within your PWMSLope settings.
  // For example, in our case, we could have a max of 5 clouds per day and they could last for 50 minutes.
  // Which could mean 250 minutes of clouds. We need to make sure the PWMSlope can accomodate 250 minutes of effects or unforseen resuls could happen.
    // Also, make sure that you can fit double those minutes between Start_Cloud_After and End_Cloud_Before.
  // In our example, we have 510 minutes between Start_Cloud_After and End_Cloud_Before, so double the 250 minutes (or 500 minutes) can fit in that 510 minutes window.
    // It's a tight fit, but it did.

    //#define printdebug // Uncomment this for debug print on Serial Monitor window
#define forcecloudcalculation // Uncomment this to force the cloud calculation to happen in the boot process.

    // Add Random Lightning modes
#define Calm 0    // No lightning
#define Slow 1    // 5 seconds of slow lightning in the middle of a cloud for ELN style (slow response) drivers
#define Fast 2    // 5 seconds of fast lightning in the middle of a cloud for LDD style (fast response) drivers
#define Mega 3    // Lightning throughout the cloud, higher chance as it gets darker
#define Mega2 4   // Like Mega, but with more lightning
  // Set which modes you want to use
  // Example:  { Slow, Fast, Mega, Mega2 } to randomize all four modes.  
  // { Mega2 } for just Mega2.  { Mega, Mega, Fast} for Mega and Fast, with twice the chance of Mega.
  byte LightningModes[] = {Mega};

  // Change the values above to customize your cloud/storm effect
  // ------------------------------------------------------------
  // Do not change anything below here

  static byte cloudchance=255;
  static byte cloudduration=0;
  static int cloudstart=0;
  static byte numclouds=0;
  static byte lightningchance=0;
  static byte cloudindex=0;
  static byte lightningstatus=0;
  static int LastNumMins=0;
  static byte lightningMode=0;
  static boolean chooseLightning=true;

  static time_t DelayCounter=millis();    // Variable for lightning timing.  
  static int DelayTime=random(1000);      // Variable for lightning timimg.

  // Every day at midnight, we check for chance of cloud happening today
  if (hour()==0 && minute()==0 && second()==0) cloudchance=255;

#ifdef forcecloudcalculation
  if (cloudchance==255)
#else
    if (hour()==0 && minute()==0 && second()==1 && cloudchance==255) 
#endif
    {
      randomSeed(millis());    // Seed the random number generator
      //Pick a random number between 0 and 99
      cloudchance=random(100); 
      // if picked number is greater than Cloud_Chance_per_Day, we will not have clouds today
      if (cloudchance>Cloud_Chance_per_Day) cloudchance=0;
      // Check if today is day for clouds. 
      if ((day()%Clouds_Every_X_Days)!=0) cloudchance=0; 
      // If we have cloud today
      if (cloudchance)
      {
        // pick a random number for number of clouds between Min_Clouds_per_Day and Max_Clouds_per_Day
        numclouds=random(Min_Clouds_per_Day,Max_Clouds_per_Day);
        // pick the time that the first cloud will start
        // the range is calculated between Start_Cloud_After and the even distribuition of clouds on this day. 
        cloudstart=random(Start_Cloud_After,Start_Cloud_After+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
        // pick a random number for the cloud duration of first cloud.
        cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
        //Pick a random number between 0 and 99
        lightningchance=random(100);
        // if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
        if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0; 
      }
    }
  // Now that we have all the parameters for the cloud, let's create the effect


  if (cloudchance)
  {
    //is it time for cloud yet?
    if (NumMins(hour(),minute())>=cloudstart && NumMins(hour(),minute())<(cloudstart+cloudduration))
    {
      DaylightPWMValue=ReversePWMSlope(cloudstart,cloudstart+cloudduration,DaylightPWMValue,5,180);
      if (chooseLightning) 
      { 
        lightningMode=LightningModes[random(100)%sizeof(LightningModes)]; 
        chooseLightning=false; 
      } 
      switch (lightningMode) 
      {
      case Calm:
        break;
      case Mega:
        // Lightning chance from beginning of cloud through the end.  Chance increases with darkness of cloud.
        if (lightningchance && random(ReversePWMSlope(cloudstart,cloudstart+cloudduration,100,0,180))<1 && (millis()-DelayCounter)>DelayTime)
        {
          // Send the trigger 
          WriteTrigger();
          
          DelayCounter=millis();    // If we just had a round of flashes, then lets put in a longer delay
          DelayTime=random(1000);   // of up to a second for dramatic effect before we do another round. 
        }
        break;
      case Mega2:
        // Higher lightning chance from beginning of cloud through the end.  Chance increases with darkness of cloud.
        if (lightningchance && random(ReversePWMSlope(cloudstart,cloudstart+cloudduration,100,0,180))<2)
        {
          WriteTrigger();
        }
        break;
      case Fast:
        // 5 seconds of lightning in the middle of the cloud
        if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5 && (millis()-DelayCounter)>DelayTime)
        {
          WriteTrigger();
          
          DelayCounter=millis();    // If we just had a round of flashes, then lets put in a longer delay
          DelayTime=random(1000);   // of up to a second for dramatic effect before we do another round. 
        }
        break;
      case Slow:
        // Slow lightning for 5 seconds in the middle of the cloud.  Suitable for slower ELN style drivers
        if (lightningchance && (NumMins(hour(),minute())==(cloudstart+(cloudduration/2))) && second()<5) 
        {
          if (random(100)<20) lightningstatus=1; 
          else lightningstatus=0;
          if (lightningstatus)
          {
            DaylightPWMValue=100; 
          }
          else 
          {
            DaylightPWMValue=0;
          }
          delay(1);
        }
        break;
      default:
        break;
      }
    } 
    else 
    {
      chooseLightning=true; // Reset the flag to choose a new lightning type
    }

    if (NumMins(hour(),minute())>(cloudstart+cloudduration))
    {
      cloudindex++;
      if (cloudindex < numclouds)
      {
        cloudstart=random(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2),(Start_Cloud_After+(((End_Cloud_Before-Start_Cloud_After)/(numclouds*2))*cloudindex*2))+((End_Cloud_Before-Start_Cloud_After)/(numclouds*2)));
        // pick a random number for the cloud duration of first cloud.
        cloudduration=random(Min_Cloud_Duration,Max_Cloud_Duration);
        //Pick a random number between 0 and 99
        lightningchance=random(100);
        // if picked number is greater than Lightning_Change_per_Cloud, we will not have lightning today
        if (lightningchance>Lightning_Change_per_Cloud) lightningchance=0;
      }
    }
  }

  // Write the times of the next cloud, next lightning, and cloud duration to the screen and into some customvars for the Portal.
  if (LastNumMins!=NumMins(hour(),minute()))
  {
    LastNumMins=NumMins(hour(),minute());
    ReefAngel.LCD.Clear(255,0,120,132,132);
    ReefAngel.LCD.DrawText(0,255,85,110,"Length");
    ReefAngel.LCD.DrawText(0,255,11,110,"Cloud");
    ReefAngel.LCD.DrawText(0,255,11,120,"00:00");
    ReefAngel.LCD.DrawText(0,255,51,110,"Storm");
    ReefAngel.LCD.DrawText(0,255,51,120,"00:00");
    if (cloudchance && (NumMins(hour(),minute())<cloudstart))
    {
      int x=0;
      if ((cloudstart/60)>=10) x=11; 
      else x=17;
      ReefAngel.LCD.DrawText(0,255,x,120,(cloudstart/60));
      ReefAngel.CustomVar[3]=cloudstart/60;    // Write the hour of the next cloud to custom variable for Portal reporting
      if ((cloudstart%60)>=10) x=29; 
      else x=35;
      ReefAngel.LCD.DrawText(0,255,x,120,(cloudstart%60));
      ReefAngel.CustomVar[4]=cloudstart%60;    // Write the minute of the next cloud to custom variable for Portal reporting

    }
    ReefAngel.LCD.DrawText(0,255,90,120,cloudduration);
    ReefAngel.CustomVar[7]=(cloudduration);    // Put the duration of the next cloud in a custom var for the portal
    if (lightningchance) 
    {
      int x=0;
      if (((cloudstart+(cloudduration/2))/60)>=10) x=51; 
      else x=57;
      ReefAngel.LCD.DrawText(0,255,x,120,((cloudstart+(cloudduration/2))/60));
      ReefAngel.CustomVar[5]=(cloudstart+(cloudduration/2))/60;    // Write the hour of the next lightning to a custom variable for the Portal
      if (((cloudstart+(cloudduration/2))%60)>=10) x=69; 
      else x=75;
      ReefAngel.LCD.DrawText(0,255,x,120,((cloudstart+(cloudduration/2))%60));    // Write the minute of the next lightning to a custom variable for the Portal
      ReefAngel.CustomVar[6]=(cloudstart+(cloudduration/2))%60;
    }
  }   
}

byte ReversePWMSlope(long cstart,long cend,byte PWMStart,byte PWMEnd, byte clength)
{
  long n=elapsedSecsToday(now());
  cstart*=60;
  cend*=60;
  if (n<cstart) return PWMStart;
  if (n>=cstart && n<=(cstart+clength)) return map(n,cstart,cstart+clength,PWMStart,PWMEnd);
  if (n>(cstart+clength) && n<(cend-clength)) return PWMEnd;
  if (n>=(cend-clength) && n<=cend) return map(n,cend-clength,cend,PWMEnd,PWMStart);
  if (n>cend) return PWMStart;
}

void WriteTrigger()
{
  FireInTheHole = true;
  ReefAngel.RANetTrigger(1);
  //ReefAngel.PWM.SetChannel(TriggerChannel, Trigger);  
}
On the receiver module:

Code: Select all

#include <Wire.h>
#include <avr/eeprom.h>

#define BLUE_LED    9
#define WHITE_LED   10

#define BLUE_INTENSITY   255
#define WHITE_INTENSITY  255

#define RANET_MAX_SIZE  68
#define DISCONNECT_TIMEOUT  2000

#define LastFallback0  100 // Memory location for fallback storage

#define RANet_Down    0
#define RANet_OK      1

#define LIGHTNING 1    // Trigger value for lightning strike
#define TRIGGER 62     // Position in payload of trigger byte

byte buffer_index;
byte buffer[128];
char buf[3];
byte bufint, bufsize;
byte RANetData[RANET_MAX_SIZE];
byte RANetCRC;
byte BlueChannel=0;
byte WhiteChannel=0;
byte RANet_Status=RANet_Down;
boolean cable_present=false;

unsigned long lastmillis=millis();
unsigned long lastcablecheck=millis();

void setup()
{
  pinMode(BLUE_LED,OUTPUT);
  pinMode(WHITE_LED,OUTPUT);
  Serial.begin(57600);
  Wire.onReceive(NULL);
  Wire.onRequest(NULL);
  Wire.begin();
  for (int a=0;a<RANET_MAX_SIZE; a++) // Clear array
    RANetData[a]=0; 
  Wire.beginTransmission(0x68);
  Wire.write(0);
  int a=Wire.endTransmission();
  cable_present=(a==0);
  // setup PCA9685 for data receive
  // we need this to make sure it will work if connected ofter controller is booted, so we need to send it all the time.
  Wire.beginTransmission(0x40);
  Wire.write(0);
  Wire.write(0xa1);
  Wire.endTransmission();
}

void loop()
{
  if (cable_present)
  {
    BlueChannel=100;
    WhiteChannel=0;
    analogWrite(WHITE_LED,WHITE_INTENSITY*WhiteChannel/100);
    analogWrite(BLUE_LED,BLUE_INTENSITY*BlueChannel/100);
  }
  else  
  {
    BlueChannel=0;
    WhiteChannel=0;
    while(Serial.available())
    {
      UpdateWhiteChannel();
      char c = Serial.read(); // Read each incoming byte
      buffer[buffer_index]=c; // store in the buffer array
      if (c==10) // if line feed we analyze the payload
      {
        if (buffer_index>25) // only need to analyse if buffer_index is greater than 25, otherwise the payload is broken or corrupt
          if (buffer_index==buffer[1]) // check if payload matches the length the controller sent
          {
            UpdateWhiteChannel();
            RANetCRC=0;
            for (int a=0; a<(buffer_index-2); a++) // calculate CRC
              RANetCRC+=buffer[a];
            UpdateWhiteChannel();
            if (RANetCRC==buffer[buffer_index-2]) // if CRC matches
            {
              UpdateWhiteChannel();
              for (int a=0; a<(buffer_index-2); a++) // Copy buffer to RANetData
                RANetData[a]=buffer[a];
              UpdateWhiteChannel();
              lastmillis=millis();
  //            Serial.print(millis());
  //            Serial.print("\t");
  //            Serial.println(RANetData[2]);
              for (int a=0;a<8;a++)
              {
                if (eeprom_read_byte((unsigned char *) LastFallback0+a)!=RANetData[10+a])
                {
                  eeprom_write_byte((unsigned char *) LastFallback0+a, RANetData[10+a]);
                }
                Wire.beginTransmission(0x38+a);
                Wire.write(~RANetData[2+a]);
                Wire.endTransmission();
              }
              for (int a=0;a<12;a=a+2)    // Step through the 12 bytes of dimming data
              {
                byte newdata=(RANetData[18+a]);    //LSB
                byte newdata1=(RANetData[18+a+1]);  //MSB
                Wire.beginTransmission(0x40);
                Wire.write(0x8+(4*(a/2)));  // Channels 0 through 5
                Wire.write(newdata);    // Write LSB
                Wire.write(newdata1);   // Write MSB
                Wire.endTransmission();
              }
              UpdateWhiteChannel();
              RANet_Status=RANet_OK;
            }
          }
        buffer_index=255; // reset buffer index
      }
      UpdateWhiteChannel();
      if (buffer_index++>=128) buffer_index=0; // increment index of buffer array. reset index if >=128
    }
    if (millis()-lastmillis>DISCONNECT_TIMEOUT)
    {
      lastmillis=millis();
  //    Serial.println("Disconnected");
  //    Serial.print(millis());
  //    Serial.print("\t");
  //    Serial.println(RANetData[10]);
      for (int a=0;a<8;a++)
      {
        Wire.beginTransmission(0x38+a);
        Wire.write(~eeprom_read_byte((unsigned char *) LastFallback0+a));
        Wire.endTransmission();
      }
      RANet_Status=RANet_Down;
    }
    if (RANet_Status==RANet_Down)
    {
        BlueChannel=0;
        WhiteChannel=millis()%2000<1000?0:100;
        analogWrite(WHITE_LED,WHITE_INTENSITY*WhiteChannel/100);
        analogWrite(BLUE_LED,BLUE_INTENSITY*BlueChannel/100);
    }
  }
  if (RANetData[TRIGGER]==LIGHTNING) Lightning();    // Look for lightning trigger
  RANetData[TRIGGER]=0;    // Clear trigger byte.
}

void UpdateWhiteChannel()
{
  WhiteChannel=sin(radians((millis()%7200)/40))*255;
  BlueChannel=255-(sin(radians((millis()%7200)/40))*255);
  analogWrite(WHITE_LED,WhiteChannel);
  analogWrite(BLUE_LED,BlueChannel);
}

void Lightning()
{
  int a=random(1,5);    // Pick a number of consecutive flashes from 1 to 4.  
  for (int i=0; i<a; i++)
  {
    // Flash on
    int newdata=4095;
    Wire.beginTransmission(0x40);      // Address of the dimming expansion module
    Wire.write(0x8+(4*1));             // 0x8 is channel 0, 0x12 is channel 1, etc.  I'm using channel 1.
    Wire.write(newdata&0xff);          // Send the data 8 bits at a time.  This sends the LSB
    Wire.write(newdata>>8);            // This sends the MSB
    Wire.endTransmission();

    Wire.beginTransmission(0x40);      // Address of the dimming expansion module
    Wire.write(0x8+(4*2));             // 0x8 is channel 0, 0x12 is channel 1, etc.  I'm using channel 1.
    Wire.write(newdata&0xff);          // Send the data 8 bits at a time.  This sends the LSB
    Wire.write(newdata>>8);            // This sends the MSB
    Wire.endTransmission();   
    
    int randy=random(20,80);    // Random number for a delay
    if (randy>71) randy=((randy-70)/2)*100;    // Small chance of a longer delay
    delay(randy);                // Wait from 20 to 69 ms, or 100-400 ms
    
    // Flash off
    Wire.beginTransmission(0x40);    // Same as above
    Wire.write(0x8+(4*1));
    Wire.write(RANetData[20]);      // Return to previous value
    Wire.write(RANetData[21]);
    Wire.endTransmission();
    
    Wire.beginTransmission(0x40);    // Same as above
    Wire.write(0x8+(4*2));
    Wire.write(RANetData[22]);      // Return to previous value
    Wire.write(RANetData[23]);
    Wire.endTransmission();

    delay(random(30,50));                // Wait from 30 to 49 ms 
  }
}
Note that this one doesn't necessarily go to black. You should have (fast) flashes that return to the previous white channel values.
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

It's working!! :)

video to follow after I get my youtube app to listen to me :)
Image
jegillis
Posts: 86
Joined: Sat Jan 04, 2014 10:26 am

Re: RANet Cloud and Lightning

Post by jegillis »

Image
User avatar
cosmith71
Posts: 1437
Joined: Fri Mar 29, 2013 3:51 pm
Location: Oklahoma City

Re: RANet Cloud and Lightning

Post by cosmith71 »

Awesome!

I still don't know what was wrong. Had to be something interfering with the trigger on channel 1. The new way is better anyway. :mrgreen:

--Colin
Post Reply