REEF2REEF Saltwater and Reef Aquarium Forum

    #ifdef
    SurfBox Aquarium Controller - opensource, Jan 10, 2018
  1. Andrewalex11

    Three MAJOR Changes to the SurfBox have been made and it is really starting to all come together nicely now!

    Graphics!


    A new GFX display has been made, and I'm ready to share with you all how it works!

    Here is a short clip of some GFX displays that the device does so far
    (Sorry for poor video quality)


    This is a NeoPixel Ring (12 Count) using the Adafruit NeoPixel Library and my own custom logic. In order to make it simple to call different animations depending on what state the device is in I figured it would be much simpler to create small modules of each animation and give them addresses. I will now break down the code so you too can implement this into your own personal projects if you do so wish. There are tons of different kinds of NeoPixel break-out boards other than this ring, and the best part is you can wire the DATA_OUT and the DATA_IN together with them to create your own custom designs.

    Code breakdown

    So in order to utilize the same Library as me, you need to include the Adafruit_NeoPixel.h library.

    Code:
    #include <Adafruit_NeoPixel.h>
    Next, you want to declare which pin you will be used to shift data out of to the breakout board, and you also need to declare how many pixels are available.

    Code:
    // Graphics //
    #ifdef __AVR__
      #include <avr/power.h>
    #endif
    #define PIN            21
    #define NUMPIXELS      12
    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
    byte brightness = 15;
    If you notice the #ifdef __AVR__ will determine what kind of microcontroller is being used so the library uses the proper power reduction registers.

    So that was all of our global variables and next is our setup.

    Code:
    // Graphics for ATtiny85
      #if defined (__AVR_ATtiny85__)
        if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
      #endif
    You do NOT need to include this in the setup unless you are in fact using an ATtiny85 Microcontroller. I include it in my setup for the sake of possibly driving my display off of one in the future.

    After that, you just simply call
    Code:
    pixels.begin();
    to initiate your NeoPixels.

    This is where my custom logic really comes into play now.

    First I created a void function with an argument of 1 Byte. This Byte will allow me to create 255 different animations to choose from. I do not anticipate on even coming close to that number of animations so this is a good way to save memory.

    Code:
    void gfxShow(byte b) {
    
    }
    Now that I have the function set up with an argument that is easily used by our logic we can go ahead and set up some sort of boolean statement to utilize the incoming byte as an address for different animations.

    In short a Switch Case statement.

    Code:
    switch(b) {
    
     case 1:
    
     break;
    
    case 2:
    
    break;
    
    // 255 Possible case statements
    
    default:
    
    break;
    
    }
    Now we can just toy around with some animations maybe on a separate development board (if you have one) To create some code for different animations. Then just stick it into one of our case statements and label it.

    Heres the code for some of the animations you see in the video

    Code:
    // // // Graphics // // //
    byte gfxShow(byte b) {
    
      switch(b) {
       
        case 1: // GFX Address 1 - Standby (WiFi Connected)
          for(int i = 1; i < brightness; i++)  {
            for(int j = 0; j < NUMPIXELS; j++) {
              pixels.setPixelColor(j, pixels.Color(0,i,0));
              delay(5);
            }
            pixels.show();
          }
    
          for(int i = brightness; i > 1; i--)  {
            for(int j = 0; j < NUMPIXELS; j++) {
              pixels.setPixelColor(j, pixels.Color(0,i,0));
              delay(5);
            }
           pixels.show();
          }
        break;
    
        case 2: // GFX Address 2 - Aquarium Filling
          for (int i = 0; i < NUMPIXELS; i++) {
            (i == 0) ? pixels.setPixelColor(11, pixels.Color(0,0,0)) : pixels.setPixelColor(i - 1, pixels.Color(0,0,0));
            pixels.setPixelColor(i, pixels.Color(brightness,0,brightness));
            pixels.show();
            delay(50);
          }
        break;
    
        case 3: // GFX Address 2 - Standby (WiFi Not Connected)
          for (int i = 0; i < NUMPIXELS; i++) {
            pixels.setPixelColor(i, pixels.Color(brightness,0,0));
            pixels.show();
            delay(1);
          }
        break;
       }
    }
    // // // End Graphics // // //
    
    Last but not least to call a new animation is now very simple!

    Let's say your Aquarium detected the water level was low and is now filling. We can just include the following code in whatever loop you have that fills and checks the water level to spin a single purple NeoPixel.

    Code:
    gfxShow(2);
    Heres how I have it sitting in my code for reference

    Code:
    while(isLOW) {
          gfxShow(2);
          digitalWrite(ATO_PUMP, HIGH);
          if (digitalRead(FLOAT_SW) == 1) {
            delay(10);
          } else { 
            digitalWrite(ATO_PUMP, LOW);
            isLOW = !isLOW;
          }
    }
    
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice
Loading...