16x2 lcd i2c with mine engine time lapse project

Forum announcements

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
mateuspj
 
Posts: 9
Joined: Fri Aug 08, 2014 11:02 am

16x2 lcd i2c with mine engine time lapse project

Post by mateuspj »

Hi folks, im want as ask a question. I'm doing a project called mine engine time lapse project thats uses a lcd with keypad 16x2 from DFRobot.
I purchase a Adafruit 16x2 lcd with keypad istead of the DFRobot, and i m finding some problems with compatibility.
I'm want to know if the pin out schematic of the Adafruit LCD keypad kit is the same as DFRobot LCD keypad.
If no, can you guys send to me the pin out schematics.
Thanks.

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by adafruit_support_bill »

Our shield design is completely different from the DFRobot shield. According to their documentation, DFRobot uses the following pins:
Pins 4, 5, 6, 7, 8, 9 and 10 are used to interface with the LCD. Analog Pin 0 is used to read the pushbuttons.
Our shield uses just two pins: SDA & SCL (A4 and A5) for all communication with the shield. You will need to use our library to run it. The library and schematic downloads are available on the Downloads page of the tutorial: https://learn.adafruit.com/rgb-lcd-shield/downloads

User avatar
mateuspj
 
Posts: 9
Joined: Fri Aug 08, 2014 11:02 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by mateuspj »

So I will have to make changes in the program sketch to?. The mini e time lapse sketch use the "LiquidCrystal.h" library.
If I replace "LiquidCrystal.h" library for the adafruit library it wil work?
Thanks., i apreciate the help.

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by adafruit_support_bill »

Our LiquidCrystal library is a superset of the standard one. The only display-related thing you should need to change is the constructor which specifies the pins. The example code with the library will show you how to do that.

The code to read the pushbuttons will need to change also. This is also shown in the library example code.

User avatar
mateuspj
 
Posts: 9
Joined: Fri Aug 08, 2014 11:02 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by mateuspj »

These are some code parts:

Code: Select all

#include "Wire.h"
#include "Adafruit_MCP23017.h" 
#include "Adafruit_RGBLCDShield.h"
#include "EEPROM.h"
#include <avr/pgmspace.h>
#include <RTClib.h>           // See https://github.com/jcw/rtclib
// #include <MemoryFree.h>    // See http://www.arduino.cc/playground/Code/AvailableMemory

//and

// pin for LCD backlight
#define LCD_BACKLIGHT_PIN   10
  // pin for reaing analog key input
#define LCD_KEY_PIN         A0 

//and 

// Display
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
Can you help me fix this?
Thanks.
Last edited by adafruit_support_bill on Fri Aug 08, 2014 1:45 pm, edited 1 time in total.
Reason: please use the </> button when submitting code. press </>, then paste your code between the [code] [/code] tags.

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by adafruit_support_bill »

Use the constructor from the example code. You do not need to define all those pins anymore.

Code: Select all

#include "Wire.h"
#include "Adafruit_MCP23017.h" 
#include "Adafruit_RGBLCDShield.h"
#include "EEPROM.h"
#include <avr/pgmspace.h>
#include <RTClib.h>           // See https://github.com/jcw/rtclib

Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

These may come in handy for controlling your backlight:

Code: Select all

// These #defines make it easy to set the backlight color
#define RED 0x1
#define YELLOW 0x3
#define GREEN 0x2
#define TEAL 0x6
#define BLUE 0x4
#define VIOLET 0x5
#define WHITE 0x7

User avatar
mateuspj
 
Posts: 9
Joined: Fri Aug 08, 2014 11:02 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by mateuspj »

Thanks man, now i can see the program in the lcd screen.
There is only one problem, once the program starts is as if the button forward remains constantly up tight, or permanently pressed.
Do you have any ideia what can be?
Thanks.

User avatar
Franklin97355
 
Posts: 23910
Joined: Mon Apr 21, 2008 2:33 pm

Re: 16x2 lcd i2c with mine engine time lapse project

Post by Franklin97355 »

Could be the button is stuck or perhaps your code is not reading the button correctly.

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by adafruit_support_bill »

Have you modified the button code to use the buttons on the shield? See the code in the example:

Code: Select all

  uint8_t buttons = lcd.readButtons();

  if (buttons) {
    lcd.clear();
    lcd.setCursor(0,0);
    if (buttons & BUTTON_UP) {
      lcd.print("UP ");
      lcd.setBacklight(RED);
    }
    if (buttons & BUTTON_DOWN) {
      lcd.print("DOWN ");
      lcd.setBacklight(YELLOW);
    }
    if (buttons & BUTTON_LEFT) {
      lcd.print("LEFT ");
      lcd.setBacklight(GREEN);
    }
    if (buttons & BUTTON_RIGHT) {
      lcd.print("RIGHT ");
      lcd.setBacklight(TEAL);
    }
    if (buttons & BUTTON_SELECT) {
      lcd.print("SELECT ");
      lcd.setBacklight(VIOLET);
    }
  }

User avatar
mateuspj
 
Posts: 9
Joined: Fri Aug 08, 2014 11:02 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by mateuspj »

Certainly is a code problem.
I'm a beginer in programing, so I have not modified the button code.
This is the button code sketch :

Code: Select all

#define  key_initial_delay   500    // delay between keys on longnently pressed key
#define  key_rate            150    // the base key rate (delay) we start with when long pressing a key

#define  KEY_NONE            255
#define  KEY_RIGHT           0
#define  KEY_UP              1
#define  KEY_DOWN            2
#define  KEY_LEFT            3
#define  KEY_SELECT          4
#define  KEY_MENU            5

#define  key_0_val           50     // right  (old: 30)
#define  key_1_val           225    // up     (old: 240)
#define  key_2_val           400    // down   (old: 360)
#define  key_3_val           600    // left   (old: 580)
#define  key_4_val           800    // select (old: 760) 


byte key = KEY_NONE;
byte oldkey = KEY_NONE;
int analogValue;


  // the dynamically calculated key rate (speed up during the long press)
unsigned long key_rate_dynamic = key_rate;
  // the key amount we send out allready during the long press
unsigned long key_count;
  // the time we started with a key press
unsigned long key_press_start;


 


// ======================================================================================
int lcd_key_pressed() {
    
  analogValue = analogRead(LCD_KEY_PIN);
  
  //switch debounce delay
  delay(4); 
  
  // this calculation gives the button a slight range to allow for a little contact resistance noise.
  // it double checks the keypress. If the two readings are not equal +/-k value after debounce delay, 
  // it tries again. if (adc_key_in > 760)  return btnNONE;  
  if (5 < abs(analogRead(LCD_KEY_PIN) - analogValue)) { 
    
    return KEY_NONE;
  } 
  
  // convert into key press
  key = lcd_get_key(analogValue);    
  
  // no key pressed
  if (key == KEY_NONE) {
    oldkey = KEY_NONE;
    return KEY_NONE;
  } 
    
  // single press detected
  if (key != oldkey) {                
      
        
    // delete the long key flag and the counter because we have a single press
    if (ui_status & B00000100) {
      bitClear(ui_status, 2); // B00000100
      key_count = 0;
      
      // reset the delays for long key presses
      key_rate_dynamic = key_rate;
    }
        
    oldkey = key;  
    if (key >=0) {
      return key;
    }
    
  }
  
  
  // long-key-press
  if (key == oldkey) {
    
    // if we have a long key press
    if (ui_status & B00000100) {
      
      // initial delay and rate delay over?
      if ( (key_press_start + key_initial_delay + (key_count * key_rate_dynamic)) < millis()) {
          
          key_count++;
                    
          // calculate the new key-rate-delay for speed up
          if (key_count > 2) {
            key_rate_dynamic = round(key_rate - (key_count / 3));
            
            // allow no zero values
            if (key_rate_dynamic < 0) {
             key_rate_dynamic = 0; 
            }
          }
          
          return key;
      }
      
    } else {
      // set the long key press flag and remember the time
      ui_status |= B00000100;
      key_press_start = millis();
    }
    
    
  }

  
  return KEY_NONE;
  
}



// Convert ADC value to key number
// ======================================================================================
int lcd_get_key(unsigned int input) { 
  
  if (input < key_0_val) {
    return 0;
  } else if (input < key_1_val) {
    return 1;          
  } else if (input < key_2_val) {
    return 2;   
  } else if (input < key_3_val) {
    return 3;   
  } else if (input < key_4_val) {
    return 4;   
  } else {
    return KEY_NONE;    
  }
}
Can you please telm what to do, change or replace?
Thanks for the help.

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by adafruit_support_bill »

None of that code is applicable anymore. You can eliminate it.

The Adafruit_RGBLCDShield library implements the button handling. Just call readButton() as below:

Code: Select all

  uint8_t buttons = lcd.readButtons();
The following code shows how to figure out which button(s) have been pressed. You can replace the lcd.print() and lcd.setBacklight() statements with your own code.

Code: Select all

  if (buttons) {
    lcd.clear();
    lcd.setCursor(0,0);
    if (buttons & BUTTON_UP) {
      lcd.print("UP ");
      lcd.setBacklight(RED);
    }
    if (buttons & BUTTON_DOWN) {
      lcd.print("DOWN ");
      lcd.setBacklight(YELLOW);
    }
    if (buttons & BUTTON_LEFT) {
      lcd.print("LEFT ");
      lcd.setBacklight(GREEN);
    }
    if (buttons & BUTTON_RIGHT) {
      lcd.print("RIGHT ");
      lcd.setBacklight(TEAL);
    }
    if (buttons & BUTTON_SELECT) {
      lcd.print("SELECT ");
      lcd.setBacklight(VIOLET);
    }
  }

User avatar
mateuspj
 
Posts: 9
Joined: Fri Aug 08, 2014 11:02 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by mateuspj »

Thanks man, i apreciate that help but a i'm pretty dumb.
I cant figure out where to make this changes.
This is the code; can you help me make some changes in the code, and i just copy and paste in arduino. The problem is only the buttons.
If there is to much time consuming, just forget.
Thanks anyway.

Code: Select all

#include "Wire.h"
#include "LiquidCrystal.h"  
#include "EEPROM.h"
#include "Adafruit_RGBLCDShield.h"
#include <avr/pgmspace.h>
#include <RTClib.h>           // See https://github.com/jcw/rtclib
// #include <MemoryFree.h>    // See http://www.arduino.cc/playground/Code/AvailableMemory
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
uint8_t buttons = lcd.readButtons();

// --------------------------
// Version of the software

#define VERSION             1
#define SUBVERSION          1


// --------------------------
// Arduino pins
  
  // pin to tell the motor drivers to go to sleep
#define MOTOR_SLEEP_PIN     2         
#define MOTOR_STEP_PIN      12
#define MOTOR_DIR_PIN       13

  // shutter and focus connections
#define CAMERA_PIN          3
#define FOCUS_PIN           11 

  // pin for LCD backlight
#define LCD_BACKLIGHT_PIN   10
  // pin for reaing analog key input
#define LCD_KEY_PIN         A0  


  // limit switches for stopping the program
  // one for each side of teh dolly
#define LIMIT_SWITCH_PIN_1  A2  
#define LIMIT_SWITCH_PIN_2  A3  



// --------------------------
// General action status flags:
// 
// B0 = operating mode (0 = shoot-move-shoot; 1 = continuous)
// B1 = camera focussing
// B2 = start cycle immediately
// B3 = camera shooting
// B4 = program running
// B5 = camera post exposure
// B6 = motor slot open
// B7 = motor post delay is active

byte action_status = B0;

// the time we started with an action (focussing, exposure, post delay) 
unsigned long action_start_time;

// --------------------------
// Camera settings

// cycle length of the whole cycle in half seconds (4 * 0.5 = 2 seconds)
unsigned int cycle_length = 4;

// camera shoot counter
unsigned int camera_shoot_count     = 0;
// the focus line will be risen before the exposure is done (in milliseconds)
unsigned int camera_focus_time      = 0;
// the time we want to expose our pictures (in milliseconds)
unsigned int camera_exp_time        = 100;
// time after exposure before the motor is moved (in milliseconds)
unsigned int camera_exp_post        = 200;

// the maximum amount of shots to do (0 = unlimited)
unsigned int camera_shot_max        = 0;

// --------------------------
// defines the camera behaviour
//
// B0 = Focus line high or low while exposing
// B1 =
// B2 =
// B3 =
// B4 =
// B5 =
// B6 =
// B7 =


byte camera_status        = B0;



// --------------------------
// Motor settings



  // motor ramping types
#define RAMPING_LINEAR        0
#define RAMPING_ATANGENS      1
#define RAMPING_SINUS         2


  // used motor ramping
#define MOTOR_RAMP_TYPE       RAMPING_ATANGENS // see the definitions just before this line for possible choices.

  // acceleration and decelleration time (in steps)
unsigned int  motor_ramp            = 500;   
  // total number of pulses for move (1600 steps per rev)
unsigned long motor_steps           = 0;   
  // number of maximum steps the motor is allowed to do  (0 = unlimited)
unsigned long motor_steps_max       = 0; // 0 = no limit
  // delay after motor movement
unsigned int motor_post             = 0; 
  // maximum delay in microsecond (delay between steps at minimum 
  // speed of the motor (start and endphase)). 
unsigned int motor_step_delay_max   = 5000;   
  // minimum delay in microseconds (delay between steps at maximum speed of the motor) 
unsigned int motor_step_delay_min   = 0;    

  // the amount of steps done away from the defined home position
  // clockwise = direction bit low (positive count)
  // anti-clockwise = direction bit high (negative count)
long  home_steps                    = 0;



// General Motor status flags:
//
// B0 = sleep on / off (the pin has to be set inverse --> sleep on = pin low)
// B1 = limit switches on / off
// B2 = 
// B3 = 
// B4 = motor direction
// B5 = 
// B6 = 
// B7 = 
   
byte motor_status  = B11000000;


// the time we started the program
unsigned long program_start_time;

// --------------------------
// Display
// initialize the library with the numbers of the interface pins




// --------------------------
// Timed-Programs (RTC) status flags:
// 
// B0 = timed-program running
// B1 = active programs in the future
// B2 = 
// B3 = 
// B4 = 
// B5 = 
// B6 = 
// B7 = 

byte program_status = B0;

 // the max number of programs available 
#define program_amount    20   

  // the program that is curently edited, 255 = no program is editet
byte current_program =    255;

  // the program that is curently running
byte running_program =    255;

  // the number of programs we have defined;
byte program_count =      0;

// day flags of the programs 
// B0  monday
// B1  tuesday
// B2  wednesday
// B3  thursday
// B4  friday
// B5  saturday
// B6  sunday
// B7  use weekdays (low = use single date)

byte program_weekdays[program_amount]; 

  // start date and time of the program
DateTime program_datetime[program_amount]; 

  // program duration in minutes
unsigned int program_duration[program_amount];
 
// other flags of the programs 
// 
// B0  enabled / disabled
// B1  move back to home
// B2  
// B3  
// B4  
// B5  
// B6  
// B7  

byte program_flag[program_amount];

  // content of the menu (we initialize the array with some items - 
  // fitting the longest possible menu - have a look at mE_program
  // to check the program amount!!! - all programs will be listed in
  // one menu - the longest regular menu is 7 items long)
char lines[20][17]; 




// --------------------------
// User interface 

  // --------------------------
  // Strings of our menu. 
  // This is done to store the strings in in the program flash.
  // If given like this: "some string", the strings would be placed in
  // the RAM.

prog_char string_0  [] PROGMEM = "On ";    
prog_char string_1  [] PROGMEM = "Off";
prog_char string_2  [] PROGMEM = "CW ";   
prog_char string_3  [] PROGMEM = "CCW";
prog_char string_4  [] PROGMEM = "Stp:";
prog_char string_5  [] PROGMEM = "D:";
prog_char string_6  [] PROGMEM = "Program started.";
prog_char string_7  [] PROGMEM = "Program stopped.";   
prog_char string_8  [] PROGMEM = "enabled";
prog_char string_9  [] PROGMEM = "disabled";

prog_char string_10 [] PROGMEM = "Camera";
prog_char string_11 [] PROGMEM = "Motor";
prog_char string_12 [] PROGMEM = "Program";
prog_char string_13 [] PROGMEM = "General";
prog_char string_14 [] PROGMEM = "Settings";
prog_char string_15 [] PROGMEM = "Version info";

prog_char string_16 [] PROGMEM = "Cycle length";
prog_char string_17 [] PROGMEM = "Focus time";
prog_char string_18 [] PROGMEM = "Exp. time";
prog_char string_19 [] PROGMEM = "Focus behav.";
prog_char string_20 [] PROGMEM = "Max. shots";
prog_char string_21 [] PROGMEM = "Post delay";
prog_char string_22 [] PROGMEM = "Test shot";

prog_char string_23 [] PROGMEM = "Motor steps ";
prog_char string_24 [] PROGMEM = "Direction";
prog_char string_25 [] PROGMEM = "Motor home";
prog_char string_26 [] PROGMEM = "Motor sleep";
prog_char string_27 [] PROGMEM = "Max steps";
prog_char string_28 [] PROGMEM = "Ramp";

prog_char string_29 [] PROGMEM = "Operat. mode";
prog_char string_30 [] PROGMEM = "B-Light time";
prog_char string_31 [] PROGMEM = "B-Light powr";
prog_char string_32 [] PROGMEM = "System time ";

prog_char string_33 [] PROGMEM = "Save settgs.";
prog_char string_34 [] PROGMEM = "Autosave";
prog_char string_35 [] PROGMEM = "Reset";

prog_char string_36 [] PROGMEM = "Developers";
prog_char string_37 [] PROGMEM = "(alphabt. o.):";
prog_char string_38 [] PROGMEM = "Airic Lenz,";
prog_char string_39 [] PROGMEM = "Alvarocalvo,";
prog_char string_40 [] PROGMEM = "C.A. Church,";
prog_char string_41 [] PROGMEM = "Marc Lane";
prog_char string_42 [] PROGMEM = "For questions";                
prog_char string_43 [] PROGMEM = "have a look at";                
prog_char string_44 [] PROGMEM = "openmoco.org  ";               
prog_char string_45 [] PROGMEM = "";                // reserve

prog_char string_46 [] PROGMEM = "Press SELECT to";  

prog_char string_47 [] PROGMEM = "";  
prog_char string_48 [] PROGMEM = "";  
prog_char string_49 [] PROGMEM = "";             
prog_char string_50 [] PROGMEM = "";  
prog_char string_51 [] PROGMEM = "";  
prog_char string_52 [] PROGMEM = "";

prog_char string_53 [] PROGMEM = "do a test shot.";  

prog_char string_54 [] PROGMEM = "";
prog_char string_55 [] PROGMEM = "";
prog_char string_56 [] PROGMEM = "";
prog_char string_57 [] PROGMEM = "";
prog_char string_58 [] PROGMEM = "";

prog_char string_59 [] PROGMEM = "Set home";
prog_char string_60 [] PROGMEM = "";

prog_char string_61 [] PROGMEM = "Add program ";
prog_char string_62 [] PROGMEM = "add a program.";

prog_char string_63 [] PROGMEM = "Start time";
prog_char string_64 [] PROGMEM = "Weekdays";
prog_char string_65 [] PROGMEM = "Duration";
prog_char string_66 [] PROGMEM = "Move home";
prog_char string_67 [] PROGMEM = "Status";
prog_char string_68 [] PROGMEM = "Delete";

prog_char string_69 [] PROGMEM = "";
prog_char string_70 [] PROGMEM = "";
prog_char string_71 [] PROGMEM = "";

prog_char string_72 [] PROGMEM = "save settings.";

prog_char string_73 [] PROGMEM = "Autosave settgs:";

prog_char string_74 [] PROGMEM = "reset settings.";
prog_char string_75 [] PROGMEM = "Restoring CFG..";
prog_char string_76 [] PROGMEM = "Restarting..";

prog_char string_77 [] PROGMEM = "set motor home.";

prog_char string_78 [] PROGMEM = "Move to home";
prog_char string_79 [] PROGMEM = "Moving motor to";
prog_char string_80 [] PROGMEM = "home. Stand by.";

prog_char string_81 [] PROGMEM = "Program start:";
prog_char string_82 [] PROGMEM = "M T W T F S S";
prog_char string_83 [] PROGMEM = "Duration:";
prog_char string_84 [] PROGMEM = "Move home @ end:";
prog_char string_85 [] PROGMEM = "Program status:";

prog_char string_86 [] PROGMEM = "delete program.";

prog_char string_87 [] PROGMEM = "high w. shutter";
prog_char string_88 [] PROGMEM = "low w. shutter";

prog_char string_89 [] PROGMEM = "continuous";
prog_char string_90 [] PROGMEM = "shoot-move-shoot";

prog_char string_91 [] PROGMEM = "anti-clockwise";
prog_char string_92 [] PROGMEM = "clockwise";

prog_char string_93 [] PROGMEM = "A limit switch"; 
prog_char string_94 [] PROGMEM = "was triggered!";

prog_char string_95 [] PROGMEM = "Max motor step";
prog_char string_96 [] PROGMEM = "limit reached!";

prog_char string_97 [] PROGMEM = "Max camera shot";
prog_char string_98 [] PROGMEM = "";

prog_char string_99 [] PROGMEM = "Post delay  ";
prog_char string_100[] PROGMEM = "Motor post delay:";

prog_char string_101[] PROGMEM = "Max speed";
prog_char string_102[] PROGMEM = "Max speed delay:";

prog_char string_103[] PROGMEM = "Min speed";
prog_char string_104[] PROGMEM = "Min speed delay:";

prog_char string_105[] PROGMEM = "Lmt-Switches";
prog_char string_106[] PROGMEM = "";

/*
prog_char string_107[] PROGMEM = "Jog";
prog_char string_108[] PROGMEM = "Motor jog:";
prog_char string_109[] PROGMEM = "Up=CW  Down=CCW";
*/


// Now set up a table to refer to the strings (a simple list
// of all the strings we defined)
PROGMEM const char *string_table[] = {   
    string_0,   string_1,   string_2,   string_3,   string_4, 
    string_5,   string_6,   string_7,   string_8,   string_9,   
    string_10,  string_11,  string_12,  string_13,  string_14,  
    string_15,  string_16,  string_17,  string_18,  string_19, 
    string_20,  string_21,  string_22,  string_23,  string_24,
    string_25,  string_26,  string_27,  string_28,  string_29,
    string_30,  string_31,  string_32,  string_33,  string_34,
    string_35,  string_36,  string_37,  string_38,  string_39,
    string_40,  string_41,  string_42,  string_43,  string_44,
    string_45,  string_46,  string_47,  string_48,  string_49,
    string_50,  string_51,  string_52,  string_53,  string_54,
    string_55,  string_56,  string_57,  string_58,  string_59,
    string_60,  string_61,  string_62,  string_63,  string_64,
    string_65,  string_66,  string_67,  string_68,  string_69,
    string_70,  string_71,  string_72,  string_73,  string_74,
    string_75,  string_76,  string_77,  string_78,  string_79,
    string_80,  string_81,  string_82,  string_83,  string_84,
    string_85,  string_86,  string_87,  string_88,  string_89,
    string_90,  string_91,  string_92,  string_93,  string_94,
    string_95,  string_96,  string_97,  string_98,  string_99,
    string_100, string_101, string_102, string_103, string_104,
    string_105, string_106 // , string_107, string_108, string_109   
  }; 


// UI status flags
// 
// B0 = backlight on / off
// B1 = ui repaint flag
// B2 = settings autosave flag
// B3 = settings were changed flag
// B4 = 24h / 12h time (24 = LOW, 12 = HIGH)  not used yet
// B5 = long key press
// B6 = message on screen
// B7 = 

byte ui_status = B11100000;


  // wait time until backlight turns off in milliseconds
unsigned int backlight_wait = 10;
  
  // backlight level in percent
byte backlight_level=100;

  // a variable to remeber when a message started
unsigned long message_start_time; 

// a variable to remeber when a message started
byte message_duration;

  // --------------------------
  // our Real time clock object
RTC_DS1307 RTC;
  // and the current time of the system
DateTime time;

 





// ===================================================================================
// Arduino Setup Procedure
// ===================================================================================
void setup() {
  
  //Serial.begin(9600);

  pinMode(MOTOR_DIR_PIN, OUTPUT);
  pinMode(MOTOR_STEP_PIN, OUTPUT);
  pinMode(MOTOR_SLEEP_PIN, OUTPUT);
  
  pinMode(CAMERA_PIN, OUTPUT);
  pinMode(FOCUS_PIN, OUTPUT);

  pinMode(LCD_BACKLIGHT_PIN, OUTPUT);

  // set motor to sleep
  digitalWrite(MOTOR_SLEEP_PIN, LOW);

  
  // init the LCD display
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  lcd.clear();
 

  // did we previously save settings to eeprom?
  // is config saved and has the config has the correct version?
  if ((is_eeprom_saved()) && 
      (is_OK_eeprom_version())) {
    
    load_config();
    
  } else {  
    
    write_config();
    write_eeprom_version();
  } 
   
   
  // enable backlight
  setBacklightLevel();
   
   
  byte scroll_up[8] = {
                      B00100,
                      B01110,
                      B11111,
                      B00100,
                      B00100,
                      B00000,
                      B00000,
                      B00000
                    };

  byte scroll_down[8] = {
                      B00000,
                      B00000,
                      B00000,
                      B00100,
                      B00100,
                      B11111,
                      B01110,
                      B00100
                    };
 
   
  // create the special chars we need for the UI
  lcd.createChar(0, scroll_up);
  lcd.createChar(1, scroll_down);
 
  /*
  Serial.println();
  Serial.print(freeMemory());
  Serial.println(" byte free.");
  */ 
  
  
  // welcome screen 
  lcd.setCursor(3, 0);
  lcd.print("miniEngine");
  lcd.setCursor(6, 1);
  lcd.print("v");
  lcd.print(VERSION);
  lcd.print(".");
  lcd.print(SUBVERSION);
  
  delay(1500);
  

  // RTC Stuff
  Wire.begin();
  RTC.begin();

}





// ===================================================================================
// Arduinos eternal loop procedure
// ===================================================================================
void loop() {
  
  // do the screen stuff
  do_screen();
     
  // programm is running
  if (action_status & B00001000) {
    
    
    // =================================================
    // C O N T I N U O U S   m o d e
    // =================================================
    if (action_status & B10000000) {
      
      // do some continuous steps    
      doMotorContinuous();

      // if it is time or the "start a new cycle immediately" flag is set
      if ((action_status & B00100000) ||
          ((program_start_time + ((unsigned long) cycle_length * 500UL * (unsigned long) camera_shoot_count)) <= millis())) {
             
        // if not exposing right now and not in camera post delay (makes this sense in continuous??)        
        if (!(action_status & B01000000) && 
            !(action_status & B00010000) && 
            !(action_status & B00000100))  { 
          
          // do some continuous steps    
          doMotorContinuous();    
              
          // should we do focussing?    
          if (camera_focus_time > 0) {
            camera_focus();
          } else {
            // shoot camera 
            camera_shoot();
          }
          
        }
        
        // do some continuous steps    
        doMotorContinuous();
        
         // delete the start immediately flag if set
        if (action_status & B00100000) {
          
          // delete the start immediately flag
          bitClear(action_status, 5); // B11011111
        }
      }
      
      // do some continuous steps    
      doMotorContinuous();
      
      
      // is camera focussing right now?
      if (action_status &  B01000000) {
        
        // did we focus the time we wanted to focus?
        if((action_start_time + (unsigned long) camera_focus_time) <= millis()) {
                   
          // stop focussing (this function automatically starts the exposure)
          camera_stop_focus();
        
        } 
      }
      
      // do some continuous steps    
      doMotorContinuous();
            
      // is camera exposing right now?
      if (action_status &  B00010000) {
       
        // did we exposed the time we wanted to expose?
        if((action_start_time + (unsigned long)camera_exp_time) <= millis()) {
                    
          // stop shooting
          camera_stop_shoot();

        } 
      }
      
      // do some continuous steps    
      doMotorContinuous();
      
      // now check the limit switches if we need to stop the program
      // this function is called as late as possible after the key reading because
      // analogRead needs some pre delay time to deliver accurate measurements...
      check_limit_switches();
      
    }
    
    // =================================================
    // S H O O T - M O V E - S H O O T   m o d e
    // =================================================
    else {
    
      // if it is time or the "start a new cycle immediately" flag is set
      if ((action_status & B00100000) ||
          ((program_start_time + ((unsigned long) cycle_length * 500UL * (unsigned long) camera_shoot_count)) <= millis())) {
        
            
        // if not focussing or exposing right now and not in camera or motor post delay        
        if (!(action_status & B01000000) && 
            !(action_status & B00010000) && 
            !(action_status & B00000100) && 
            !(action_status & B00000001) )  { 
          
          // should we do focussing?    
          if (camera_focus_time > 0) {
            camera_focus();
          } else {
            
            // shoot camera 
            camera_shoot();
          }
        }
        
         
        // delete the start immediately flag if set
        if (action_status & B00100000) {
          
          // toggle the start immediately flag to off
          bitClear(action_status, 5);
        }
      }

      
      // is camera focussing right now?
      if (action_status &  B01000000) {
        
        // did we focus the time we wanted to focus?
        if((action_start_time + (unsigned long) camera_focus_time) <= millis()) {
                   
          // stop focussing (this function automatically starts the exposure)
          camera_stop_focus();
        
        } 
      }

      
      // is camera exposing right now?
      if (action_status &  B00010000) {
       
        // did we exposed the time we wanted to expose?
        if((action_start_time + camera_exp_time) <= millis()) {
          
          // stop shooting
          camera_stop_shoot();
          
        } 
      }
     
     
      // post exposure delay
      if (action_status & B00000100) {
      
        // did we exposed the time we wanted to expose?
        if((action_start_time + (unsigned long) camera_exp_time + (unsigned long) camera_exp_post) <= millis()) {
  
          camera_stop_post();
          
        }
        
      }
     
     // time for the engines
     if (action_status & B00000010) {
      
        // do the blocking motor phase with error check
        doMotorPhase(true);
        
        motor_stop();
        
        // now check the limit switches if we need to stop the program
        // this function is called after the blocking motor phase because
        // analogRead needs some pre delay time to deliver accurate
        // measurements...
        check_limit_switches();
        
     } 
     
     
     // motor post delay
     if (action_status & B00000001) {
     
       // did we waited the time we wanted to wait?
        if((action_start_time + (unsigned long) motor_post) <= millis()) {
  
          // clear the waintg flag...
          bitClear(action_status, 0); // B11111110
          
        }
     
     }
   
    } // operation mode
   
         
    // if the programm is running and we are in contiuous mode
    continuous_check();
            
  }  // program is running
  
  // read the time from the RTC (valid for the next loop)
  time = RTC.now(); 
   
  // if the programm is running and we are in contiuous mode
  continuous_check(); 
   
  // the function that checks if we need to start or stop a program
  check_programs();
  
  // if the programm is running and we are in contiuous mode
  continuous_check(); 
  
  // check if there are programs that will be triggered in the future
  // this is done for being able to display this information ("smart P")
  check_programFuture();
  
}




User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by adafruit_support_bill »

Hmmm. That looks like some sort of state machine, and some of the state manipulation is done inside the lcd_key_pressed() function. You may need to keep some parts of that after all.

You might get away with just replacing lcd_get_key() with something like::

Code: Select all

// Convert ADC value to key number
// ======================================================================================
int lcd_get_key(unsigned int input) 
{ 
  uint8_t buttons = lcd.readButtons();

  if (buttons) {
    lcd.clear();
    lcd.setCursor(0,0);
    if (buttons & BUTTON_UP) {
     return 1;
    }
    if (buttons & BUTTON_DOWN) {
      return 2;
    }
    if (buttons & BUTTON_LEFT) {
      return 3;
    }
    if (buttons & BUTTON_RIGHT) {
      return 0;
    }
    if (buttons & BUTTON_SELECT) {
      return 4;
    }
  }
 else {
    return KEY_NONE;    
  }
}
But I don't know how it will interact with what appears to be debounce and repeat code. No guarantees.

User avatar
mateuspj
 
Posts: 9
Joined: Fri Aug 08, 2014 11:02 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by mateuspj »

Thanks Bill.
It doesn t work at all.
Its freese the lcd, and doesnt work any button.
I apreciate the help.

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: 16x2 lcd i2c with mine engine time lapse project

Post by adafruit_support_bill »

Have you contacted the author of the code? He/she might have some insight into how best to adapt it.

Locked
Please be positive and constructive with your questions and comments.

Return to “Announcements”