Go Down

Topic: Homemade Arduino Mega LCD Shield (Read 4043 times) previous topic - next topic

liudr

Just moved the code over to this thread so everyone can read the code. So far that is some progress. You should use "#" button to include code, not quote button:

Code: [Select]
/*
DEVUINO AutoLab: developpement semi-automatique de photos
MAJ : 18/09/2011
*/

/*
Aruino Mega LCD Shield for DIY Jobo Atl by Effixe
  The circuit:
LCD :
* LCD RS pin to digital pin 48
* LCD Enable pin to digital pin 46
* LCD D4 pin to digital pin 44
* LCD D5 pin to digital pin 42
* LCD D6 pin to digital pin 40
* LCD D7 pin to digital pin 38
* LCD R/W pin to ground

  4 push buttons
  Button 01 (prev) to digital pin 41
  Button 02 (next) to digital pin 39
  Button 02 (exe) to digital pin 43
  Button 02 (cancel) to digital pin 37
*/


// Chargement des fonctions

#include <LiquidCrystal.h> // Ecran LCD

// DECLARATION DES CONSTANTES

// création du caractère °
  byte degree[8] = {
  B00010,
  B00101,
  B00010,
  B00000,
  B00000,
  B00000,
  B00000,
};


// Identification des boutons du LCD Arduino Mega
const int B_Prev = 41;
const int B_Next = 39;
const int B_Exe = 43;
const int B_Cancel = 37;


// DECLARATION DES VARIABLES

// Initialisation du LCD
LiquidCrystal lcd(48, 46, 44, 42, 40, 38); //Arduino Mega Shield


// Etat des boutons 
int B_Prev_State=0;
int B_Next_State=0;
int B_Exe_State=0;
int B_Cancel_State=0;

// Affichage du LCD
char * V_LCD_L1="BIENVENUE";
char * V_LCD_L2="DEVUINO V0.6";


int V_Menu=0; // Position dans le menu
int V_Choix=0; // Position actuelle du choix
int V_Choix_Max=2; // Choix max. dans un menu
int Type_Dev = 0; //Type de dev à effectuer
int Temperature = 20;

// SETUP
void setup () {
 

   // Vitesse de transfert avec le port serie
  Serial.begin(9600);
  lcd.createChar(0, degree); // création du caractère spécial °

 
 
  // Parametres des boutons
  pinMode(B_Prev, INPUT);
  pinMode(B_Next, INPUT);
  pinMode(B_Exe, INPUT);
  pinMode(B_Cancel, INPUT);


 
  // Message d'accueil
  lcd.begin(16,2);  //initialisation affichage LCD 16x2 lignes
  lcd.setCursor(3,0);lcd.print(V_LCD_L1);
  lcd.setCursor(4,1);lcd.print(V_LCD_L2);
  delay(2000);
  AfficheMenu(V_Menu);
  AfficheChoix(V_Choix);

  while(Type_Dev == 0){
  PresseBouton();
  }
 
}


void loop() {
 
lcd.print("Dev : "); //debug test
lcd.print(Type_Dev);
}

// AFFICHAGE DES MENUS

void AfficheMenu(int V_Menu) {
 
  lcd.clear();
  // Enumeration de tous les menus et du nombre de choix que chacun propose
  switch (V_Menu) {
    case 0:V_LCD_L1="DEV   |C41|E6|NB"; V_Choix_Max=2;  break;
    case 1:V_LCD_L1="Temp.  |20|25|38"; V_Choix_Max=2;  break;
    case 11:V_LCD_L1="DEV   C41 @ 20"; V_Choix_Max=1;  break;
    case 12:V_LCD_L1="DEV   C41 @ 25"; V_Choix_Max=1;  break;
    case 13:V_LCD_L1="DEV   C41 @ 38"; V_Choix_Max=1;  break;
    case 2:V_LCD_L1="Dev    E6 @ 38"; V_Choix_Max=0;  break;
    case 3:V_LCD_L1="Type  Custom|STD";V_Choix_Max=2;  break;
    case 32:V_LCD_L1="Stand Dev N&B";V_Choix_Max=1;  break;
    case 31:V_LCD_L1="Temp.  + | -";V_Choix_Max=0;  break;
  }
  // Affichage du menu en cours 
  lcd.setCursor(0,0);lcd.print(V_LCD_L1);
  if (V_Menu == 2){lcd.write(0);lcd.print("C");delay(2000);if (B_Exe_State==HIGH){Type_Dev = V_Menu;}}
  if (V_Menu == 11){lcd.write(0);lcd.print("C");delay(2000);if (B_Exe_State==HIGH){Type_Dev = V_Menu;}}
  if (V_Menu == 12){lcd.write(0);lcd.print("C");delay(2000);if (B_Exe_State==HIGH){Type_Dev = V_Menu;}}
  if (V_Menu == 13){lcd.write(0);lcd.print("C");delay(2000);if (B_Exe_State==HIGH){Type_Dev = V_Menu;}}
  if (V_Menu == 31){lcd.print(Temperature);lcd.write(0);lcd.print("C");ChoixTemperature();}
}


void AfficheChoix(int V_Choix) {

// AFFICHAGE D'UN CHOIX DANSUN{ MENU
  // Enumeration de toutes les possibilites de choix (3 cas)
  switch (V_Choix) {
    case 0:V_LCD_L2="*      ";break;
    case 1:V_LCD_L2="   *   ";break;
    case 2:V_LCD_L2="      *";break;
   
  }
  // Affichage du choix en cours
  lcd.setCursor(9,1);lcd.print(V_LCD_L2);

}



// ETAT DES BOUTONS

void PresseBouton() {
 
delay(100);
    B_Prev_State = digitalRead(B_Prev);
    B_Next_State = digitalRead(B_Next);
    B_Exe_State = digitalRead(B_Exe);
    B_Cancel_State = digitalRead(B_Cancel);
   

        AfficheChoix(V_Choix);
       
    if (B_Prev_State==HIGH) { // Précédent
      if (V_Choix>0) {     
       V_Choix--;
      }
    }
   
    if (B_Next_State==HIGH) {  //  Suivant
        if (V_Choix<V_Choix_Max) {
          V_Choix=V_Choix+1;
        }     
    }
   
    if (B_Exe_State==HIGH) { // Execute
   
       if (V_Menu<40){
       V_Menu=V_Menu*10+(V_Choix+1);
       V_Choix = 0;
       AfficheMenu(V_Menu);

       }
    }
   if (B_Cancel_State==HIGH) { // Cancel
       V_Menu=V_Menu/10;
       V_Choix = 0;
     AfficheMenu(V_Menu);
  }

}
 
  void ChoixTemperature(){
   Serial.print(Temperature);
   while (B_Exe_State==LOW){
 
    if (B_Next_State==HIGH) {
      Temperature=Temperature+1;
    lcd.setCursor(0,13);lcd.print(Temperature);

    }
   if (B_Prev_State==HIGH) {
    Temperature=Temperature-1;
    lcd.setCursor(0,13);lcd.print(Temperature);
   
  }
   }}

Effixe

#16
Sep 26, 2011, 11:26 pm Last Edit: Sep 26, 2011, 11:29 pm by Effixe Reason: 1
Ok, thanks.

is my code clear for you? maybe you want some explanations.

I want to have a choice between 3 types of developing process.
C41, E6 and NB
In C41, i will have choice in 3 temperatures of process 20°C / 25°C / 38°C
in E6, no choice, only 38°C
In NB, Stand Developement and a customs values Temperature and Time.

thats it for my needs for now.

later i will need to create a deeper menu, with many others functions like access to draining pumps (7 pumps), set offset temperature... and maybe later how to access to some data logged on a SD card...

liudr

Thanks for describing the purpose of the code to me. Definitely helpful when reading through it.

Here's what I'm seeing from the code, correct me if I make mistakes:

There are 4 buttons, prev, next, exe (run) and cancel.

You print the menu with AfficheMenu(V_Menu) and print the choice (using a * symbol) with AfficheChoix(V_Choix). You use something like "    *   " on line 2 to indicate what is selected. You print a few selectable things on line 1. so a typical screen shot looks like this, right?
Code: [Select]
DEV   |C41|E6|NB
        *     


In some menus there are as many as three selectable items and in some there are only 1 so the V_Choix_Max determines how many selectable items there are (0-2 represents 1-3 choices you can make), right?

To be continued...

Effixe

#18
Sep 27, 2011, 12:26 am Last Edit: Sep 27, 2011, 12:38 am by Effixe Reason: 1
exactly!
you have totally understand my code and what i want to do.

Yes V_Choix_Max is the maximum choice for the variable.
V for Variable, Choix for Choice and Max for Max ^^


Code: [Select]
DEV   |C41|E6|NB
       *      

Yes! that is what is print on the first picture of the topic and that is what i need.

i think that my code will be inappropriate in future versions, i only have 3 positions for the * symbol and it will not fit perfectly with words longer than 3 characters... I don't know yet how to manage it.
I have a second issue, my function PresseBouton()   (press button listener) is too fast, i have to gently and quickly press my button to move one step, if you hold down it for a long period, it will execute and pass to the next step too quickly. (Am i understandable?)
i'm sorry for my english, it's not my native language.

liudr

Ok, the Pressbutton() was not right. You should not be waiting with delay. Instead, do a while loop

Code: [Select]
start=millis();
while(millis()-start<100)
{
  //sense all buttons
  //if a button is pressed, set that button as pressed and break out of the loop
}


The way to sense button press is to store the button status and then read new status and compare with old, if the old is no push and the new is push, the register as pressed. Then old status becomes push. You didn't store the old button status so you can't tell a button is pressed technically.

Effixe

ok, so, how did i break the loop?
when button status is changed, did i call for a function?


liudr

Code: [Select]
// Outside any functions with other variables
#define UP 0
#define DOWN 1
#define PRESSED 2
#define NOT_PRESSED 3

byte btn1_sensed=NOT_PRESSED; // Use this variable to decide if a button is pressed
byte btn1_prev_state=UP; // Use this to keep button1 previous state
byte btn1_current_state=UP; // Use this to keep button1 current state

// Inside the PressButton function

start=millis();
while(millis()-start<100)
{
  //sense all buttons
  //if a button is pressed, set that button as pressed and break out of the loop
  if ((btn1_prev_state==UP)&&(btn1_current_state==DOWN))
  {
      btn1_sensed=PRESSED;
      break; // This breaks out of the while loop
  }
}

Effixe

Hi Liu, i haven't been here and saw your reply. I've got to work (real work i mean :smiley-roll-sweat:)

so, thank you first.

i'm gonna read and test you code.

Effixe

ok...

i have few questions now  ;)

first, did i have to declare int start=0? because, if i don't do that, i can't compile code.

second, i suppose i have to multiply the number of "if" tests by the numbers of buttons on my board, right? 
Code: [Select]
if ((btn1_prev_state==UP)&&(btn1_current_state==DOWN))

third thing, how did i link my buttons pins to your code? =(
i can't understand how did you listen the digital write signal of the prev button in this case.

Effixe

another question for the future...
May be i will use analog read for pushbuttons (many buttons+resistors on one analog pin, i have saw a tutorial on this) will it be easier to manage? 

liudr


ok...

i have few questions now  ;)

first, did i have to declare int start=0? because, if i don't do that, i can't compile code.

second, i suppose i have to multiply the number of "if" tests by the numbers of buttons on my board, right? 
Code: [Select]
if ((btn1_prev_state==UP)&&(btn1_current_state==DOWN))

third thing, how did i link my buttons pins to your code? =(
i can't understand how did you listen the digital write signal of the prev button in this case.


Yes, you need to declare the variable start.

Yes, you will have as many if statements as you have buttons. Unless you use array of buttons or object-oriented programming, your code grow proportional to the number of buttons.

To link your button pins to my code, you can read one of the examples under the phi_prompt library. You need to go to the 4 button scenario and use the pins your buttons use in place of the following code (phi_prompte_example_int).

Code: [Select]

//Phi-2 shield buttons
#define btn_u 5
#define btn_d 10
#define btn_l 11
#define btn_r 4
#define btn_b 14
#define btn_a 15


The above are up, down, left, right, b, and a buttons' digital pins. Use your own pins on u,d,l,r, and use 0 for b, and a buttons since you don't have 6 buttons.

I have not implemented analog buttons. I know of them and may get to them in a future release. Right now my focus is to incorporate matrix keypads into the input devices and graphical LCD and even possibly serial LCD into output devices.

Go Up