Who wants a cheap, simple, Arduino-based LED controller?

The 1.0 version of the hardware is released already with an NC clause, which means it cannot be sold commercially (without explicit permission from the license holder, i.e. me). I plan on using the NC clause on future releases as well, if there are any.
 
The 1.0 version of the hardware is released already with an NC clause, which means it cannot be sold commercially (without explicit permission from the license holder, i.e. me). I plan on using the NC clause on future releases as well, if there are any.


So must also change the name in DWZM's controller :D
 
Spuzzum, DWZM, good!!!
we can use i2c for all buttons and liberate the digital pin 18-19, change the pin 11PWM, currently connected to the display, on the digital pin 18.
so we can connect the fan to pin PWM11 and DS18B20 connected on 26-pin analog
Atmega168-328PinMapToDomopes.jpg
 
Last edited:
I just played with the MCP23008 i2clcd circuit DWZM has in his Hydra schematic.. my lcd now works on i2c! :D Pinout's different than the one from adafruit..
http://www.adafruit.com/products/292


I then came across another design.. few pins different again, but it also works with the ADC keypad.. the type I posted above. Amazingly.. it works too.. including the "joystick" as the manufacturer calls it :P.


SchemaDeuligne11.jpg

Deuligne Schematic


MYMCP23008LCDADAPTER.jpg

LCDI2C4Bit Adapter Schematic - Deuligne connections are black and in brackets


My DIP Switch Settings:

Code:
LCDI2C4Bit: 1, 2, 4

1 - on = RW disabled
2 - on = RS
3 - off
4 - on = E
5 - off
6 - off


Deuligne: 3, 5, 6

1 - off = RW disabled
2 - off
3 - on = RS
4 - off
5 - on = E
6 - on = RW enabled

LCDI2C4Bitmode.jpg


LCDI2C4Bit.jpg

LCDI2C4Bit Mode Successful


Deulignemode.jpg


Deuligne.jpg

Deuligne Mode Successful
 
I then tested the LCDI2C "Hello World" script by modifying for use with Deuligne..

Code:
//LCDI2C modified for Deuligne:

// example use of LCDI2C library with the web4robot.com i2C lcd display

#include <Wire.h>
//#include <LCDI2C.h>
#include <Deuligne.h>



//LCDI2C lcd = LCDI2C(2,16,0x4C,1);             // Number of lines and i2c address of the display
Deuligne lcd;


void setup() { 


  lcd.init();                          // Init the display, clears the display
 
  lcd.print("Hello World!");       // Classic Hello World!
 

  
}


void loop()
{
  
}

LCDI2C.jpg

LCDI2C Trial Successful


I then tried the "joystick" test for Deuligne.. same as the ADC Keypad I made earlier.. the one that uses resistors to sense which key is which...

joysticktest.jpg


upkeyok.jpg


downkeyok.jpg


leftkeyok.jpg


rightkeyok.jpg


selectkeyok.jpg

Joystick Test Successful

The keypad settings are actually more responsive than the ones in the script from Nuelectronics for the keypad schematic I built. :)

I love when things I make actually work :D.


Yeah.. had some issues.. and even screwed up "slightly" when wiring the DIP.. should've controlled RW pin connection with positions 1 and 2, instead of 1 and 6. Didn't realize I needed another connection until the input pins on the DIP had already been jumped for each line needing 2 output options. Oh well.. it's only a tester. In fact.. it's on a board salvaged from an old project I don't use anymore.. cheapskate, eh? :D
 
Here's the files for the Deuligne.. including the Arduino library...

http://tronixstuff.wordpress.com/2011/10/07/kit-review-snootlab-deuligne-lcd-arduino-shield/
http://wiki.ultimaker.com/Deuligne_LCD_interface
http://shop.snootlab.com/lang-en/snootlab-shields/135-deuligne.html <--- download tab has schematics, board files, and user guide

https://github.com/Snootlab/Deuligne <--- Deuligne library for Arduino


Sorry.. had to split it up.. couldn't post all in one. Should be something we can work with though.. very adaptable. And look at all the pins it just freed up :).
 
So I tried the Deuligne version in the Typhon script, but used DWZM's buttons instead of the ADC Key buttons... and it works :). Just freed up 4 pins.. and it only took a $5 modification, and very minor changes to the script.. basically just calling Deuligne.h in place of LiquidCrystal.h, replacing the LiquidCrystal(x,x,x,x,x,x,x,x); LCD pin declaraton, and removing the (16,2) when the lcd is initiated.. blank screen otherwise :D.


lcdi2cTyphon.jpg
 
Script with edits... total of 3 lines changed.

Code:
/*
// Typhon firmware
// v0.3 alpha 2011-16-11
// N. Enders, R. Ensminger
//
// This sketch provides firmware for the Typhon LED controller.
// It provides a structure to fade 4 independent channels of LED lighting
// on and off each day, to simulate sunrise and sunset.
//
// Current work in progress:
// - store all LED variables in EEPROM so they are not reset by a loss of power
// - allow for signals to be inverted for buckpucks or other drivers that consider 0 to be "on"
//
// Future developments may include:
// - moon phase simulation
// - storm simulation
// - support for plugin hardware modules for temperature, pH, relay control, etc.
// 
// Sketch developed in Arduino-22
// Requires LiquidCrystal, Wire, EEPROM, EEPROMVar, and Button libraries.
// Button is available here: http://www.arduino.cc/playground/Code/Button
// EEPROMVar is available here: http://www.arduino.cc/playground/uploads/Profiles/EEPROMVar_01.zip
*/

// include the libraries:
#include "Deuligne.h"        ////<------------- changed
#include "Wire.h"
#include "Button.h"
#include "EEPROM.h"
#include "EEPROMVar.h"


/**** Define Variables & Constants ****/
/******************
/*
  The circuit:
 * LCD RS pin to digital pin 8
 * LCD Enable pin to digital pin 7
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 16 (A2)
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
*/
//********************/

// set the RTC's I2C address
#define DS1307_I2C_ADDRESS 0x68
// create the LCD

Deuligne lcd;                ////  <------------- changed

// set up backlight
int bkl         = 6;        // backlight pin
byte bklIdle    = 10;       // PWM value for backlight at idle
byte bklOn      = 70;       // PWM value for backlight when on
int bklDelay    = 10000;    // ms for the backlight to idle before turning off
unsigned long bklTime = 0;  // counter since backlight turned on
// create the menu counter
int menuCount   = 1;
int menuSelect = 0;

//create the plus and minus navigation delay counter with its initial maximum of 250.
byte btnMaxDelay = 200;
byte btnMinDelay = 25;
byte btnMaxIteration = 5;
byte btnCurrIteration;

//create manual override variables
boolean override = false;
byte overmenu = 0;
int overpercent = 0;

// create the buttons
Button menu     = Button(14,BUTTON_PULLDOWN);
Button select   = Button(15,BUTTON_PULLDOWN);
Button plus     = Button(16,BUTTON_PULLDOWN);
Button minus    = Button(17,BUTTON_PULLDOWN);

// LED variables. These control the behavior of lighting. Change these to customize behavoir
int minCounter = 0;         // counter that resets at midnight.
int oldMinCounter = 0;      // counter that resets at midnight.
int oneLed = 9;             // pin for channel 1
int twoLed = 10;            // pin for channel 2
int threeLed = 11;          // pin for channel 3
int fourLed = 3;            // pin for channel 4

int oneVal = 0;             // current value for channel 1
int twoVal = 0;             // current value for channel 2
int threeVal = 0;           // current value for channel 3
int fourVal = 0;            // current value for channel 4

// Variables making use of EEPROM memory:

EEPROMVar<int> oneStartMins = 750;      // minute to start this channel.
EEPROMVar<int> onePhotoPeriod = 720;   // photoperiod in minutes for this channel.
EEPROMVar<int> oneMax = 100;           // max intensity for this channel, as a percentage
EEPROMVar<int> oneFadeDuration = 60;   // duration of the fade on and off for sunrise and sunset for
                                       //    this channel.
EEPROMVar<int> twoStartMins = 810;
EEPROMVar<int> twoPhotoPeriod = 600;
EEPROMVar<int> twoMax = 100;
EEPROMVar<int> twoFadeDuration = 60;

EEPROMVar<int> threeStartMins = 810;
EEPROMVar<int> threePhotoPeriod = 600;
EEPROMVar<int> threeMax = 100;
EEPROMVar<int> threeFadeDuration = 60;
                            
EEPROMVar<int> fourStartMins = 480;
EEPROMVar<int> fourPhotoPeriod = 510;  
EEPROMVar<int> fourMax = 100;          
EEPROMVar<int> fourFadeDuration = 60;  

// variables to invert the output PWM signal,
// for use with drivers that consider 0 to be "on"
// i.e. buckpucks. If you need to provide an inverted 
// signal on any channel, set the appropriate variable to true.
boolean oneInverted = false;
boolean twoInverted = false;
boolean threeInverted = false;
boolean fourInverted = false;

/*
int oneStartMins = 1380;      // minute to start this channel.
int onePhotoPeriod = 120;   // photoperiod in minutes for this channel.
int oneMax = 100;           // max intensity for this channel, as a percentage
int oneFadeDuration = 60;   // duration of the fade on and off for sunrise and sunset for
                                       //    this channel.                                    
int twoStartMins = 800;
int twoPhotoPeriod = 60;
int twoMax = 100;
int twoFadeDuration = 15;

int threeStartMins = 800;
int threePhotoPeriod = 60;
int threeMax = 100;
int threeFadeDuration = 30;
                            
int fourStartMins = 800;
int fourPhotoPeriod = 120;  
int fourMax = 100;          
int fourFadeDuration = 60;  
*/

/****** RTC Functions ******/
/***************************/

// Convert decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convert binary coded decimal to decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// Sets date and time, starts the clock
void setDate(byte second,        // 0-59
             byte minute,        // 0-59
             byte hour,          // 1-23
             byte dayOfWeek,     // 1-7
             byte dayOfMonth,    // 1-31
             byte month,         // 1-12
             byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.endTransmission();
}

// Gets the date and time
void getDate(byte *second,
             byte *minute,
             byte *hour,
             byte *dayOfWeek,
             byte *dayOfMonth,
             byte *month,
             byte *year)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

/****** LED Functions ******/
/***************************/
//function to set LED brightness according to time of day
//function has three equal phases - ramp up, hold, and ramp down

int   setLed(int mins,         // current time in minutes
            int ledPin,        // pin for this channel of LEDs
            int start,         // start time for this channel of LEDs
            int period,        // photoperiod for this channel of LEDs
            int fade,          // fade duration for this channel of LEDs
            int ledMax,        // max value for this channel
            boolean inverted   // true if the channel is inverted
            )  {
  int val = 0;
      
      //fade up
      if (mins > start || mins <= start + fade)  {
        val = map(mins - start, 0, fade, 0, ledMax);
      }
      //fade down
      if (mins > start + period - fade && mins <= start + period)  {
        val = map(mins - (start + period - fade), 0, fade, ledMax, 0);
      }
      //off or post-midnight run.
      if (mins <= start || mins > start + period)  {
        if((start+period)%1440 < start && (start + period)%1440 > mins )
          {
            val=map((start+period-mins)%1440,0,fade,0,ledMax);
          }
        else  
        val = 0; 
      }
    
    
    if (val > ledMax)  {val = ledMax;} 
    if (val < 0) {val = 0; } 
    
  if (inverted) {analogWrite(ledPin, map(val, 0, 100, 255, 0));}
  else {analogWrite(ledPin, map(val, 0, 100, 0, 255));}
  if(override){val=overpercent;}
  return val;
}

/**** Display Functions ****/
/***************************/

//button hold function
int btnCurrDelay(byte curr)
{
  if(curr==btnMaxIteration)
  {
    btnCurrIteration = btnMaxIteration;
    return btnMaxDelay;
  }
  else if(btnCurrIteration ==0)
  {
    return btnMinDelay;
  }
  else
  {
    btnCurrIteration--;
    return btnMaxDelay;
  }
}

// format a number of minutes into a readable time (24 hr format)
void printMins(int mins,       //time in minutes to print
               boolean ampm    //print am/pm?
              )  {
  int hr = (mins%1440)/60;
  int mn = mins%60;
    if(hr<10){
      lcd.print(" ");
    }
    lcd.print(hr);
    lcd.print(":");
    if(mn<10){
      lcd.print("0");
    }
    lcd.print(mn); 
}

// format hours, mins, secs into a readable time (24 hr format)
void printHMS (byte hr,
               byte mn,
               byte sec      //time to print
              )  
{
  
    if(hr<10){
      lcd.print(" ");
    }
    lcd.print(hr, DEC);
    lcd.print(":");
    if(mn<10){
      lcd.print("0");
    }
    lcd.print(mn, DEC);
    lcd.print(":");
    if(sec<10){
      lcd.print("0");
    }
    lcd.print(sec, DEC);
}
void ovrSetAll(int pct){
    analogWrite(oneLed,map(pct,0,100,0,255));
    analogWrite(twoLed,map(pct,0,100,0,255));
    analogWrite(threeLed,map(pct,0,100,0,255));
    analogWrite(fourLed,map(pct,0,100,0,255));
}

/**** Setup ****/
/***************/

void setup() {
  Wire.begin();
  pinMode(bkl, OUTPUT);
  lcd.init();                        //// <------------- changed
  digitalWrite(bkl, HIGH);
  lcd.print("Typhon-Reef");
  lcd.setCursor(0,1);
  lcd.print("");
  delay(5000);
  lcd.clear();
  analogWrite(bkl,bklIdle);
  btnCurrIteration = btnMaxIteration;
}

/***** Loop *****/
/****************/

void loop() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDate(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  oldMinCounter = minCounter;
  minCounter = hour * 60 + minute;
  
  //reset plus & minus acceleration counters if the button's state has changed
  if(plus.stateChanged())
  {
   btnCurrDelay(btnMaxIteration);
  }
  if(minus.stateChanged())
  {  
    btnCurrDelay(btnMaxIteration);
  }
       
  
  //check & set fade durations
  if(oneFadeDuration > onePhotoPeriod/2 && onePhotoPeriod >0){oneFadeDuration = onePhotoPeriod/2;}
  if(oneFadeDuration<1){oneFadeDuration=1;}
  
  if(twoFadeDuration > twoPhotoPeriod/2 && twoPhotoPeriod >0){twoFadeDuration = twoPhotoPeriod/2;} 
  if(twoFadeDuration<1){twoFadeDuration=1;}
  
  if(threeFadeDuration > threePhotoPeriod/2 && threePhotoPeriod >0){threeFadeDuration = threePhotoPeriod/2;}
  if(threeFadeDuration<1){threeFadeDuration=1;}
  
  if(fourFadeDuration > fourPhotoPeriod/2 && fourPhotoPeriod > 0){fourFadeDuration = fourPhotoPeriod/2;}
  if(fourFadeDuration<1){fourFadeDuration=1;}
  
  //check & set any time functions
  
  
  //set outputs
  if(!override){
  oneVal = setLed(minCounter, oneLed, oneStartMins, onePhotoPeriod, oneFadeDuration, oneMax, oneInverted);
  twoVal = setLed(minCounter, twoLed, twoStartMins, twoPhotoPeriod, twoFadeDuration, twoMax, twoInverted);
  threeVal = setLed(minCounter, threeLed, threeStartMins, threePhotoPeriod, threeFadeDuration, threeMax, threeInverted);
  fourVal = setLed(minCounter, fourLed, fourStartMins, fourPhotoPeriod, fourFadeDuration, fourMax, fourInverted);
  }
  else{
    ovrSetAll(overpercent);
  }
  
  
  //turn the backlight off and reset the menu if the idle time has elapsed
  if(bklTime + bklDelay < millis() && bklTime > 0 ){
    analogWrite(bkl,bklIdle);
    menuCount = 1;
    lcd.clear();
    bklTime = 0;
  }

  //iterate through the menus
  if(menu.uniquePress()){
    analogWrite(bkl,bklOn);
    bklTime = millis();
    if(menuCount < 20){
      menuCount++;
    }else {
      menuCount = 1;
    }
  lcd.clear();
  }
  if(menuCount == 1){
    //main screen turn on!!!
    if (minCounter > oldMinCounter){
      lcd.clear();
    }
    lcd.setCursor(0,0);
    printHMS(hour, minute, second);
    lcd.setCursor(0,1);
    lcd.print(oneVal);
    lcd.setCursor(4,1);
    lcd.print(twoVal);
    lcd.setCursor(8,1);
    lcd.print(threeVal);
    lcd.setCursor(12,1);
    lcd.print(fourVal);
    //debugging function to use the select button to advance the timer by 1 minute
    //if(select.uniquePress()){setDate(second, minute+1, hour, dayOfWeek, dayOfMonth, month, year);}
  }
  
  if(menuCount == 2){
    //Manual Override Menu
    lcd.setCursor(0,0);
    lcd.print("Manual Overrides");
    lcd.setCursor(0,1);
    lcd.print("All: ");
    if(select.uniquePress()){
      if(menuSelect < 3){menuSelect++;}
      else{menuSelect = 0;}
      bklTime = millis();
    }
    
    if(menuSelect == 0){
      lcd.print("Timer");
      override = false;}
    if(menuSelect == 1){
      lcd.print("ON   ");
      overpercent = 100;
      override = true;}
    if(menuSelect == 2){
      lcd.print("OFF  ");
      overpercent = 0;
      override = true;}    
    if(menuSelect == 3){
      override = true;
      lcd.print(overpercent,DEC);
      lcd.print("%  ");
      if(plus.isPressed() && overpercent <100)
        {
          overpercent++;
          delay(btnCurrDelay(btnCurrIteration-1));
          bklTime = millis();
        }
        
        if(minus.isPressed() && overpercent > 0)
        {
          overpercent--;
          delay(btnCurrDelay(btnCurrIteration-1));
          bklTime = millis();
        }
      }
}
  


  if(menuCount == 3){
    //set start time for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Start");
    lcd.setCursor(0,1);
    printMins(oneStartMins, true);
    
    if(plus.isPressed() && oneStartMins < 1440){
        oneStartMins++;
        if(onePhotoPeriod >0){onePhotoPeriod--;}
        else{onePhotoPeriod=1439;}
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && oneStartMins > 0){
        oneStartMins--;
        if(onePhotoPeriod<1439){onePhotoPeriod++;}
        else{onePhotoPeriod=0;}
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 4){
    //set end time for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 End");
    lcd.setCursor(0,1);
    printMins(oneStartMins+onePhotoPeriod, true);
    if(plus.isPressed()){
      if(onePhotoPeriod < 1439){
      onePhotoPeriod++;}
      else{
        onePhotoPeriod=0;
      }
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed()){
      if(onePhotoPeriod >0){
        onePhotoPeriod--;}
      else{
        onePhotoPeriod=1439;
      }
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 5){
    //set fade duration for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Fade");
    lcd.setCursor(0,1);
    printMins(oneFadeDuration, false);
    if(plus.isPressed() && (oneFadeDuration < onePhotoPeriod/2 || oneFadeDuration == 0)){
      oneFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && oneFadeDuration > 1){
      oneFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 6){
    //set intensity for channel one
    lcd.setCursor(0,0);
    lcd.print("Channel 1 Max");
    lcd.setCursor(1,1);
    lcd.print(oneMax);
    lcd.print("  ");
    if(plus.isPressed() && oneMax < 100){
      oneMax++;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && oneMax > 0){
      oneMax--;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 7){
    //set start time for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 Start");
    lcd.setCursor(0,1);
    printMins(twoStartMins, true);
    if(plus.isPressed() && twoStartMins < 1440){
        twoStartMins++;
        if(twoPhotoPeriod >0){twoPhotoPeriod--;}
        else{twoPhotoPeriod=1439;}
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && twoStartMins > 0){
        twoStartMins--;
        if(twoPhotoPeriod<1439){twoPhotoPeriod++;}
        else{twoPhotoPeriod=0;}
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 8){
    //set end time for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 End");
    lcd.setCursor(0,1);
    printMins(twoStartMins+twoPhotoPeriod, true);
    if(plus.isPressed()){
      if(twoPhotoPeriod < 1439){
      twoPhotoPeriod++;}
      else{
        twoPhotoPeriod=0;
      }
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed()){
      if(twoPhotoPeriod >0){
        twoPhotoPeriod--;}
      else{
        twoPhotoPeriod=1439;
      }
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 9){
    //set fade duration for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 Fade");
    lcd.setCursor(0,1);
    printMins(twoFadeDuration, false);
    if(plus.isPressed() && (twoFadeDuration < twoPhotoPeriod/2 || twoFadeDuration == 0)){
      twoFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && twoFadeDuration > 1){
      twoFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 10){
    //set intensity for channel two
    lcd.setCursor(0,0);
    lcd.print("Channel 2 Max");
    lcd.setCursor(1,1);
    lcd.print(twoMax);
    lcd.print("  ");
    if(plus.isPressed() && twoMax < 100){
      twoMax++;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && twoMax > 0){
      twoMax--;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 11){
    //set start time for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 Start");
    lcd.setCursor(0,1);
    printMins(threeStartMins, true);
    if(plus.isPressed() && threeStartMins < 1440){
        threeStartMins++;
        if(threePhotoPeriod >0){threePhotoPeriod--;}
        else{threePhotoPeriod=1439;}
        delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && threeStartMins > 0){
        threeStartMins--;
        if(threePhotoPeriod<1439){threePhotoPeriod++;}
        else{threePhotoPeriod=0;}
        delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 12){
    //set end time for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 End");
    lcd.setCursor(0,1);
    printMins(threeStartMins+threePhotoPeriod, true);
    if(plus.isPressed()){
      if(threePhotoPeriod < 1439){
      threePhotoPeriod++;}
      else{
        threePhotoPeriod=0;
      }
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed()){
      if(threePhotoPeriod >0){
        threePhotoPeriod--;}
      else{
        threePhotoPeriod=1439;
      }
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 13){
    //set fade duration for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 Fade");
    lcd.setCursor(0,1);
    printMins(threeFadeDuration, false);
    if(plus.isPressed() && (threeFadeDuration < threePhotoPeriod/2 || threeFadeDuration == 0)){
      threeFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && threeFadeDuration > 1){
      threeFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 14){
    //set intensity for channel three
    lcd.setCursor(0,0);
    lcd.print("Channel 3 Max");
    lcd.setCursor(1,1);
    lcd.print(threeMax);
    lcd.print("  ");
    if(plus.isPressed() && threeMax < 100){
      threeMax++;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && threeMax > 0){
      threeMax--;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 15){
    //set start time for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 Start");
    lcd.setCursor(0,1);
    printMins(fourStartMins, true);
    if(plus.isPressed() && fourStartMins < 1440){
        fourStartMins++;
        if(fourPhotoPeriod >0){fourPhotoPeriod--;}
        else{fourPhotoPeriod=1439;}
        delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && fourStartMins > 0){
        fourStartMins--;
        if(fourPhotoPeriod<1439){fourPhotoPeriod++;}
        else{fourPhotoPeriod=0;}
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 16){
    //set end time for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 End");
    lcd.setCursor(0,1);
    printMins(fourStartMins+fourPhotoPeriod, true);
    if(plus.isPressed()){
      if(fourPhotoPeriod < 1439){
      fourPhotoPeriod++;}
      else{
        fourPhotoPeriod=0;
      }
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed()){
      if(fourPhotoPeriod >0){
        fourPhotoPeriod--;}
      else{
        fourPhotoPeriod=1439;
      }
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 17){
    //set fade duration for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 Fade");
    lcd.setCursor(0,1);
    printMins(fourFadeDuration, false);
    if(plus.isPressed() && (fourFadeDuration < fourPhotoPeriod/2 || fourFadeDuration == 0)){
      fourFadeDuration++;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && fourFadeDuration > 1){
      fourFadeDuration--;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 18){
    //set intensity for channel four
    lcd.setCursor(0,0);
    lcd.print("Channel 4 Max");
    lcd.setCursor(1,1);
    lcd.print(fourMax);
    lcd.print("   ");
    if(plus.isPressed() && fourMax < 100){
      fourMax++;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && fourMax > 0){
      fourMax--;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  }

  if(menuCount == 19){
    //set hours
    lcd.setCursor(0,0);
    lcd.print("Set Time: Hrs");
    lcd.setCursor(0,1);
    printHMS(hour, minute, second);
    if(plus.isPressed() && hour < 23){
      hour++;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && hour > 0){
      hour--;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }
  
  if(menuCount == 20){
    //set minutes
    lcd.setCursor(0,0);
    lcd.print("Set Time: Mins");
    lcd.setCursor(0,1);
    printHMS(hour, minute, second);
    if(plus.isPressed() && minute < 59){
      minute++;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
    if(minus.isPressed() && minute > 0){
      minute--;
      delay(btnCurrDelay(btnCurrIteration-1));
      bklTime = millis();
    }
  setDate(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
  }
}


Now just needs a temp sensor portion..... :D
 
Seems the library's set up to display a 16x2 display:

From Deuligne.h:
Code:
Deuligne(int devI2CAddress=0xA7, int num_lines=2, int lcdwidth=16, int bufferwidth= 40);

This shows 3 lines in my 16x4 display.. and setting cursor to (0,3) puts it on the second line.. doh!

But adding:
Code:
Deuligne lcd(0xA7, 16, 4);


And now my 4th line is accessible again :D.
 
Spuzzum,

<O:p</O:pJust to say great work!!! I like the different things you are doing to free up more AVR pins in the Typhon, specially the ADC buttons. Like you are doing, some months ago I adapted the MCP23008 LCD interface from the Hydra project and it's working perfectly with my modified Typhon.

<O:p</O:pKeep the good ideas flowing!!!
 
Thanks mm.reefs :)

I can do hardware.. to a point, but coding's not my strong point.. otherwise I'd have a crack at modifying for the adc keys. But I can kinda figure things out sometimes.. just takes me a little while.. day, month, etc... :p I'm better with DOS than c/c++.

But just off the top of my head.. is there a way to disable the backlight option? I'd rather use the PWM channel for LEDs, and just use a dimming pot and an on/off tact switch/button. Push button.. light turns on (or just gets brighter).. do what you need with the menus/display functions, then push button again.. light turns off (or dims back down). That would allow all 6 PWM pins for LEDs. I played by assigning the AREF pin as the backlight pin.. seeing as AREF isn't called in the script I figure it'd be safe.. but not sure really, as it has internal stuffs that I may be screwing up by doing so. I'm not connecting to it.. just using it as a dummy connection in the script.

And another thing I was reading at Arduino's site.. as long as you don't need the serial connection (it's not called in the script).. D0/RX and D1/TX can be used as "regular" digital pins.. relays/sensors/etc...


I also came across something where a guy was using the MCP23008 shift registers for increasing the PWM capabilities.. multiple PWM's off 1 PWM channel. Not too sure how well it works though.. or if I'd want to test on $5 Cree's :D.


But if I can disable the backlight portion of the script.. then I'm a happy man. I'd be even happier if I could figure out how to add the temp sensor portion. Relays seem easy enough.. it's just all the coding for the sensors that'll be an issue for me.....:crazy1:
 
Also, wanted to mention about the eeprom memory...

People in the satellite community use either a 24LC128 (128Kb) or 24LC256 (256Kb) which holds the eeprom memory, along side an atmel8515 which holds the actual flash/program. It would free up the atmega128/328.. and possibly speed up the entire process. I have no idea as to how to code it though.. and I "think" it's connected to i2c.


Just a thought if you're running out of room in the eeprom.

Maybe I'll talk to a friend who used to be into the community.. see if he knows how to go about it.
 
Putting along....

Success at disabling the backlight in the script.. now have 6 PWM channels working.. and full menu to accommodate the full 6 :D. Basically just searched for "bkl", then commented out that line. Frees up the PWM pin.. but now, when key hasn't been pressed.. instead of going back to main screen, it just stays at the menu screen you are on. Minor.. but will try to fix.. "somehow". Maybe set the "select" button to send back to "menuCount == 1".. seeing as the select button isn't actually being used.

I also fixed my LCD requiring (-4, 2) or (-4, 3) to start the columns at (0, 2) and (0, 3). It's in the *.cpp files...


Changed:
Code:
int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };

To:
Code:
int row_offsets[] = { 0x00, 0x40, 0x10, 0x50 };


Now everything works as it should. :)
 
Fixed the display reset function.. changed "bkl" to "display"...


From:
Code:
// set up backlight
int bkl         = 3;        // backlight digital pin 3
byte bklIdle    = 10;       // PWM value for backlight at idle
byte bklOn      = 70;       // PWM value for backlight when on
int bklDelay    = 10000;    // ms for the backlight to idle before turning off
unsigned long bklTime = 0;  // counter since backlight turned on

To:
Code:
// set up backlight
byte displayIdle    = 10;       // PWM value for backlight at idle
int displayDelay    = 10000;    // ms for the backlight to idle before turning off
unsigned long displayTime = 0;  // counter since backlight turned on


From:
Code:
  //turn the backlight off and reset the menu if the idle time has elapsed
  if(bklTime + bklDelay < millis() && bklTime > 0 ){
    analogWrite(bkl,bklIdle);
    menuCount = 1;
    lcd.clear();
    bklTime = 0;
  }

To:
Code:
  //turn the backlight off and reset the menu if the idle time has elapsed
  if(displayTime + displayDelay < millis() && displayTime > 0 ){
    menuCount = 1;
    lcd.clear();
    displayTime = 0;
  }


From:
Code:
  //iterate through the menus
  if(menu.uniquePress()){
    analogWrite(bkl,bklOn);
    bklTime = millis();
    if(menuCount < 28){
      menuCount++;
    }else {
      menuCount = 1;
    }
    lcd.clear();
  }

To:
Code:
  //iterate through the menus
  if(menu.uniquePress()){
    displayTime = millis();
    if(menuCount < 28){
      menuCount++;
    }else {
      menuCount = 1;
    }
    lcd.clear();
  }
 
So here's my modified script.. all 6 PWM channels, and no backlight pin.

Seeing as I managed to get that working, I thought I'd brave it by adding the date as well. Used an example from the Deuligne package, and it worked.

Well.. sort'a :p

It displays the date I set in the script, and it rolled the date at midnight. All good, right? Not so fast. For some reason, it's not keeping the time now.. never mind the date. When reset.. it literally resets back to the time and date set in the script. :headwally:


I think I broke it :spin2:
 

Attachments

So here's my modified script.. all 6 PWM channels, and no backlight pin.

Seeing as I managed to get that working, I thought I'd brave it by adding the date as well. Used an example from the Deuligne package, and it worked.

Well.. sort'a :p

It displays the date I set in the script, and it rolled the date at midnight. All good, right? Not so fast. For some reason, it's not keeping the time now.. never mind the date. When reset.. it literally resets back to the time and date set in the script. :headwally:


I think I broke it :spin2:

:lmao:
do not lose faith ... go on like this you're doing a good job. :thumbsup: congratulations!
I like the electronics I want to work with the community.
I ordered an Arduino board with display, I'm waiting for the shipment arrives.
Then do the tests myself.
now I have only a software simulator for Arduino, it is VirtualBreadboard
 
Thanks Baghyyy... I'm putting along......... :)


I did just find the issue though.. not sure if this is a half-assed backwards fix, but it's a fix....


Replaced
Code:
  second = 0;
  minute = 6;
  hour = 22;
  dayOfWeek = 2;
  dayOfMonth = 12;
  month = 12;
  year = 11;

  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);


With
Code:
//////   Uncomment the following to initially set the time and date
//////   After you load the sketch, the comment out the section again, and reload the sketch 1 more time.
//////   This prevents the sketch from restting back to the beginning. ;)


/*  
  second = 0;
  minute = 6;
  hour = 22;
  dayOfWeek = 2;
  dayOfMonth = 12;
  month = 12;
  year = 11;

  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
*/


Unplugged for a few minutes.. time keeps up :).


Now to look into setting up a menu option for manually adjusting the date. Will take some thinking... :p


After that.. would still like to look into the adc key option. Doesn't look too much different.. but we'll see.
 
Back
Top