Menu for Display

Code looks quite good now. Let me know if you need more assistance.

Oliver

Yes for sure :slight_smile: Thanks a lots ...

The other good question for you will be :slight_smile:

  • If i need print something like data and time (now printed in serial) how I can do ? I can print directly on lcd ? this is a general question for example a result of procedure or something else ...

  • for example another idea for menu that i've in mind is:

  • Device
    --> choose number of device (maybe i can take a part of general serial example). example led
    --> Turn On/Off
    --> Get state and print in serial on lcd

  • Timer
    --> choose number of device ((maybe i can take a part of general serial example)
    --> Enable/Disable Timer
    if enable --> set start time start date and end time and end date
    if disable --> disable timer

but this part i think will be a little bit difficult because i need to implement a timer again ... so I've looked and found some documentation but after im stopped because i start to work on menu :slight_smile: ...

warm regards,
gnux

thanks

  • If i need print something like data and time (now printed in serial) how I can do ? I can print directly on lcd ? this is a general question for example a result of procedure or something else ...

To print the menu on the LCD, just replace the serial graphics handler with the graphics handler for the character lcd. In order to show something, you could design a menu, with read only fields and only one selectable ok button. Any element can made "read only" by adding "r1" to the format string, so

M2_U8NUM(el_dt_year, "c2r1", 0,99,&dt_year);
M2_LABEL(el_dt_sep1, "b1", "-");
M2_U8NUM(el_dt_month, "c2r1", 1,12,&dt_month);
M2_LABEL(el_dt_sep2, "b1", "-");
M2_U8NUM(el_dt_day, "c2r1", 1,31,&dt_day);

will show the date but will not allow to enter any data (M2_LABEL is always read only).
Of course you can also write directly to the LCD screen, no problem.
Tutorial 6 might give a some ideas here (Google Code Archive - Long-term storage for Google Code Project Hosting.)

Oliver

Ok if i not understood bad just change this " m2_es_arduino_serial" with this " m2_es_arduino" in order to enable enable the menu in LCD mode ...

then did this your advise is create a read only menu with only ok button ...

I will try and then I'll you know :slight_smile:

have nice a week,
Andrea

Hi Oliver,
I've create another items on the menu

uint8_t u8dev = 0;
uint8_t u8stato = 0;

void fn_clean_dev(m2_el_fnarg_p fnarg) {
  u8dev = 0;
}

void dev_ok_button(m2_el_fnarg_p fnarg) {
  Serial.println("OK");
}

M2_LABEL(el_num_label1, NULL, "Select Dev:");
M2_U8NUM(el_num_1, NULL, 0, 64, &u8dev);

M2_LABEL(el_num_label2,NULL, "Turn Off/On:");
M2_U8NUM(el_num_2, NULL, 0, 1, &u8stato);

M2_BUTTON(el_num_zero, "f4", " zero ", fn_clean_dev);
M2_BUTTON(el_dev_ok, NULL, "ok", dev_ok_button);
M2_ROOT(el_num_goto_top, "f4", " back ", &top_el_expandable_menu);

M2_LIST(num_list) = { 
    &el_num_label1, &el_num_1, 
    &el_num_label2, &el_num_2, 
    &el_num_zero, &el_num_goto_top, &el_dev_ok
};
M2_GRIDLIST(el_num_menu, "c2", num_list);

But I cannot see the into menu the ok button ... please could you tell kindly If wrong something into the code or it depend from the only four line that I've into display ?
Or is possible define only one button ?

thx gnux

Untitled.png

So I've found the issues :slight_smile: I've reduce the space between "zero" and "back" and now is appear :slight_smile:

M2_BUTTON(el_num_zero, "f4", "zero", fn_clean_dev);
M2_BUTTON(el_dev_ok, NULL, "ok", dev_ok_button);
M2_ROOT(el_num_goto_top, "f4", "back", &top_el_expandable_menu);

so I'll let you know about the next steps :slight_smile:

thanks :slight_smile:
gnux

Good Morning Oliver,
so I've have question for you ...

Using the menu ... Is possible set Timer if yes where in which point i can set it ?

Because I've set timer but i was asking me if the timer is called, or if the software into the loop still inside the menu ...

void loop() {
  Timer();
  m2.checkKey();
  m2.checkKey();
  if ( m2.handleKey() )
    m2.draw();
  m2.checkKey();
  
}

thanks
Gnux

Hi just to say you that I've tried to read from eeprom and pass the value without lcd and it's working ...

#include <Time.h>
#include <TimeAlarms.h>
TimeElements tm,tm1;

String readString;
#include <EEPROM.h>
void setup()
{
  

  
  Serial.begin(9600);
  setTime(1,3,00,23,1,13); // set time to Saturday 8:29:00am Jan 1 2011
  tm.Year = (EEPROM.read(6)+2000-1970);
  tm.Month = EEPROM.read(5);
  tm.Day = EEPROM.read(4);
  tm.Hour =  EEPROM.read(2);
  tm.Minute =  EEPROM.read(3);
  tm.Second = 00;
  tm1.Year = (EEPROM.read(11)+2000-1970);
  tm1.Month = EEPROM.read(10);
  tm1.Day = EEPROM.read(9);
  tm1.Hour = EEPROM.read(7);
  tm1.Minute = EEPROM.read(8);
  tm1.Second = 00;
  Alarm.triggerOnce(makeTime(tm), OnceOnly);
  Alarm.triggerOnce(makeTime(tm1), OnceOnly1);
  // Alarm.timerOnce(makeTime(tm), OnceOnly) ;
  // Serial.println("Make Time");
  Serial.println(makeTime(tm));
  // Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
               // called once after 10 seconds 
}

void  loop(){  
 
  
 
  digitalClockDisplay();
  
  Alarm.delay(1000); // wait one second between clock display
  
  
}

// functions to be called when an alarm triggers:

void OnceOnly(){
  Serial.println("Inizio Timer");  
}

void OnceOnly1(){
  Serial.println("Fine Timer");  
}
void digitalClockDisplay()
{
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(); 
}

void printDigits(int digits)
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

But with the menù doesn't work ...

Thanks for the support,
gnux

Hi

Timer()
The menu procedures will only provide a small delay. So your Timer() procedure should be called as usual in the loop().

EEPROM and m2tklib.
I do not see the full code, so it is difficult to say why the menu is not working.

Oliver

Hi Oliver,
here you are the code :slight_smile:

#include <Time.h>
#include <TimeAlarms.h>
#include <LiquidCrystal.h>	// ensure that the include path is set
#include "M2tk.h"
#include <VirtualWire.h>
#include <Wire.h>
#include <DS1307.h>
#include <EEPROM.h>
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

//Variabili Globali
char dev;
char testo[15];

// usata per mandare il messaggio
char messaggio[15];
// usato nell'index del close del keypad
int ind = 0;
// usato nel keypad
char Tasto;
// usato nel keyoad
unsigned long UltimoTasto = 0;
// usato nel nella procedura seriale
String LeggiStringa;
byte memoria[105];

TimeElements tm0start;
TimeElements tm0stop;
TimeElements tm1start;
TimeElements tm1stop;
TimeElements tm2start;
TimeElements tm2stop;
TimeElements tm3start;
TimeElements tm3stop;
TimeElements tm4start;
TimeElements tm4stop;
TimeElements tm5start;
TimeElements tm5stop;
TimeElements tm6start;
TimeElements tm6stop;
TimeElements tm7start;
TimeElements tm7stop;



void LeggiEeprom()
{
  int ind;
   for (ind =0; ind <= 105 ; ind++)
      {
        memoria[ind] = EEPROM.read(ind);
      }   
}

void Timer()
{
 
     tm0start.Hour =   memoria[2];
     tm0start.Minute = memoria[3];
     tm0start.Second = 00;
     tm0start.Day =   memoria[4];
     tm0start.Month = memoria[5];
     tm0start.Year = ((memoria[6]+2000) - 1970);
  
     Alarm.triggerOnce(makeTime(tm0start), StartTimer0);
     
     
     tm0stop.Hour =   memoria[7];
     tm0stop.Minute = memoria[8];
     tm0stop.Second = 00;
     tm0stop.Day =   memoria[9];
     tm0stop.Month = memoria[10];
     tm0stop.Year = ((memoria[11]+2000) - 1970);
  
    Alarm.triggerOnce(makeTime(tm0stop), StopTimer0);
     
  
  if ( memoria[13] != 0 )
  {
     
  }
  
  if ( memoria[26] != 0 )
  {
     
  }
  
  if ( memoria[39] != 0 )
  {
     
  }
  
  if ( memoria[52] != 0 )
  {
     
  }
  
  if ( memoria[65] != 0 )
  {
     
  }
  
  if ( memoria[78] != 0 )
  {
     
  }
  
  if ( memoria[91] != 0 )
  {
     
  }
  
}


void StartTimer0()
{
  messaggio[0]='1';
  messaggio[1]='0';
  messaggio[2]='#';
  TxMsg(messaggio);
  Serial.println("Start Timer 0");
}

void StopTimer0()
{
  messaggio[0]='*';
  messaggio[1]='0';
  messaggio[2]='#';
  TxMsg(messaggio);
  Serial.println("Stop Timer 0");
}

void DefinizionePin()
{
  //Piedini Utilizzati per Gestire LCD  
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);
  pinMode(A5, INPUT);
  pinMode(13, OUTPUT);
}

void Comunicazione()
{
   Wire.begin();         // Inizializzo la Comunicazione I2C
   Serial.begin(9600);	 // Inizializzo la Seriale
   vw_setup(1200);	 // Inizializzo al Comunicazione TTL su Virtual Wire
   vw_rx_start();        // Start the receiver PLL running
   RTC.start();          // Fai partire il clock
}

void SetOrologio()
{
  setTime(RTC.get(DS1307_HR,true),RTC.get(DS1307_MIN,false),RTC.get(DS1307_SEC,false),RTC.get(DS1307_DATE,false),RTC.get(DS1307_MTH,false),RTC.get(DS1307_YR,false)-2000);
}

void TxMsg(char buffer[15])
{
   vw_send((uint8_t *)buffer, strlen(buffer));
   vw_wait_tx(); // Wait until the whole message is gone
   buffer[0]='\0';
   Serial.println("Comando Inviato");
}

// Forward declaration of the toplevel element
M2_EXTERN_HLIST(top_el_expandable_menu);

/* SetDate 1-1  */
uint8_t dt_day = 1;
uint8_t dt_month = 1;
uint8_t dt_year = 12;
uint8_t dt_min = 1;
uint8_t dt_hour = 1;

void dt_current(void)
{
  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
  Serial.print(":");
  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
  Serial.print(":");
  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
  Serial.print("      ");                 // some space for a more happy life
  Serial.print(RTC.get(DS1307_DATE,false));//read date
  Serial.print("/");
  Serial.print(RTC.get(DS1307_MTH,false));//read month
  Serial.print("/");
  Serial.print(RTC.get(DS1307_YR,false)); //read year
  Serial.println();
}


void dt_get_from_RTC(void)
{
  dt_day = RTC.get(DS1307_DATE,false);
  dt_month = RTC.get(DS1307_MTH,false);
  dt_year = (RTC.get(DS1307_YR,false)-2000);
  dt_min = RTC.get(DS1307_MIN,false);
  dt_hour = RTC.get(DS1307_HR,true); 
}

void dt_put_to_RTC(void)
{
  RTC.stop();
  RTC.set(DS1307_DATE,dt_day);
  RTC.set(DS1307_MTH,dt_month);
  RTC.set(DS1307_YR,dt_year);
  RTC.start(); 
  
}

void time_put_to_RTC(void)
{
  RTC.stop();
  RTC.set(DS1307_HR,dt_hour);
  RTC.set(DS1307_MIN,dt_min);
  RTC.start(); 
  SetOrologio();
}
void dt_ok_date(m2_el_fnarg_p fnarg)  
{
  dt_put_to_RTC();
  m2_SetRoot(&top_el_expandable_menu); 
}

void time_ok_button(m2_el_fnarg_p fnarg)
{
  time_put_to_RTC();
  m2_SetRoot(&top_el_expandable_menu); 
}

void view_ok_button(m2_el_fnarg_p fnarg)
{
  dt_current();
  m2_SetRoot(&top_el_expandable_menu);  
}

M2_U8NUM(el_dt_year, "c2", 0,99,&dt_year);
M2_LABEL(el_dt_sep1, "b1", "-");
M2_U8NUM(el_dt_month, "c2", 1,12,&dt_month);
M2_LABEL(el_dt_sep2, "b1", "-");
M2_U8NUM(el_dt_day, "c2", 1,31,&dt_day);

M2_LIST(list_date) = { &el_dt_year, &el_dt_sep1, &el_dt_month, &el_dt_sep2, &el_dt_day };
M2_HLIST(el_date, NULL, list_date);

M2_ROOT(el_dt_cancel, NULL, "cancel", &top_el_expandable_menu);
M2_BUTTON(el_dt_ok, NULL, "ok", dt_ok_date);
M2_LIST(list_dt_buttons) = {&el_dt_cancel, &el_dt_ok };
M2_HLIST(el_dt_buttons, NULL, list_dt_buttons);

M2_LIST(list_dt) = {&el_date, &el_dt_buttons };
M2_VLIST(el_top_dt, NULL, list_dt);

/* Set time 1-2 ---------------------------------------------------------------------*/

M2_U8NUM(el_dt_hour, "c2", 0,23,&dt_hour);
M2_LABEL(el_dt_c, "b1", ":");
M2_U8NUM(el_dt_min, "c2", 0,59,&dt_min);

M2_LIST(list_time) = { &el_dt_hour, &el_dt_c, &el_dt_min};
M2_HLIST(el_time, NULL, list_time);

M2_ROOT(el_time_cancel, NULL, "cancel", &top_el_expandable_menu);
M2_BUTTON(el_time_ok, NULL, "ok", time_ok_button);
M2_LIST(list_time_buttons) = {&el_time_cancel, &el_time_ok };
M2_HLIST(el_time_buttons, NULL, list_time_buttons);

M2_LIST(list_t) = {&el_time, &el_time_buttons};
M2_VLIST(el_top_time, NULL, list_t);

/* View DateTime 1-3  */
M2_LABEL(el_dt_view, "b1", "DateTimeNow");
M2_LIST(list_view) = {&el_dt_view};
M2_HLIST(el_view, NULL, list_view);

M2_ROOT(el_view_cancel, NULL, "cancel", &top_el_expandable_menu);
M2_BUTTON(el_view_ok, NULL, "ok", view_ok_button);
M2_LIST(list_view_buttons) = {&el_view_cancel, &el_view_ok };
M2_HLIST(el_view_buttons, NULL, list_view_buttons);

M2_LIST(list_v) = {&el_view, &el_view_buttons};
M2_VLIST(el_top_view, NULL, list_v);

/* -------------- DEVICE 2 ----------------------*/

uint8_t u8dev = 0;
uint8_t u8stato = 0;

void fn_clean_dev(m2_el_fnarg_p fnarg) {
  u8dev = 0;
}

void dev_ok_button(m2_el_fnarg_p fnarg) {
  
  if (u8dev <= 9) 
    {
     messaggio[1] = u8dev + 48;  
     messaggio[2] = '#';
     messaggio[3] = '\0';
    }
  
    if (u8dev > 9)
    {
      int x,y;
      y = u8dev/10;
      messaggio[1] = y + 48;
      x = u8dev % 10;
      messaggio[2] = x + 48;
      messaggio[3] = '#';
      messaggio[4] = '\0';
    }    
    
    if (u8stato == 0)
    {
      messaggio[0] ='*';
    }    
    
    if (u8stato == 1)
    {
      messaggio[0] ='1';
    }   
       
  TxMsg(messaggio);
  messaggio[0] = '\0';
}

void dev_stato_button(m2_el_fnarg_p fnarg) {
 // procedura per recuperare lo stato della periferica
 
}

M2_LABEL(el_num_label1, NULL, "Select Dev:");
M2_U8NUM(el_num_1, NULL, 0, 64, &u8dev);

M2_LABEL(el_num_label2,NULL, "Turn Off/On:");
M2_U8NUM(el_num_2, NULL, 0, 1, &u8stato);

M2_BUTTON(el_num_zero, "f4", "zero", fn_clean_dev);
M2_BUTTON(el_dev_ok, NULL, "ok", dev_ok_button);
M2_BUTTON(el_dev_stato, NULL, "stato", dev_stato_button);
M2_ROOT(el_num_goto_top, "f4", "back", &top_el_expandable_menu);

M2_LIST(num_list) = { 
    &el_num_label1, &el_num_1, 
    &el_num_label2, &el_num_2, 
    &el_dev_ok, &el_num_zero, &el_num_goto_top,&el_dev_stato
};
M2_GRIDLIST(el_num_menu, "c2", num_list);


/* main menu */
m2_menu_entry m2_2lmenu_data[] = 
{
  { "DATE/TIME 1", NULL },
  { ". SetDate 1-1", &el_top_dt },
  { ". SetTime 1-2", &el_top_time},
  { ". View DateTime 1-3", &el_top_view},
  { "DEVICES 2", NULL},
  { ". Manage 2-1", &el_num_menu},
  { NULL, NULL },
};

uint8_t m2_2lmenu_first;
uint8_t m2_2lmenu_cnt;

M2_2LMENU(el_2lmenu,"l4e1w12",&m2_2lmenu_first,&m2_2lmenu_cnt, m2_2lmenu_data,'+','-','\0');
M2_VSB(el_vsb, "l4w1r1", &m2_2lmenu_first, &m2_2lmenu_cnt);
M2_LIST(list_2lmenu) = { &el_2lmenu, &el_vsb };
M2_HLIST(top_el_expandable_menu, NULL, list_2lmenu);

// m2 object and constructor
M2tk m2(&top_el_expandable_menu, m2_es_arduino_serial, m2_eh_2bs, m2_gh_arduino_serial);

void setup() 
{
  
  LeggiEeprom();
  Comunicazione();
  
  
  
}

void loop() {
  Timer();
  m2.checkKey();
  m2.checkKey();
  if ( m2.handleKey() )
    m2.draw();
  m2.checkKey();
  Timer();
}

Thanks for the support,
gnux

After a quick review of your code i do not yet see a big mistake.

Is the Menu working without EEPROM?
Maybe there is a RAM overflow (too much of RAM consumption).

Oliver

Hi Oliver,
without EEPROM the menu is working ... so it's working also with EEPROM,
but only the timer doesn't works ... so now What I've in mind to try is that:

a) check timer alone --> it's working
b) check the timer with DS1307 and see if it working
c) check timer with DS1307 + a little bit menu and see it's working
d) check timer with EEPROM+DS1307+MENU and see it's working

make sense for you ?

Thanks
Andrea

Hi Oliver ...

I've tried steps by step ... this result ...

a) check timer alone --> it's working --> Ok
b) check the timer with DS1307 and see if it working --> Ok
c) check the timer with eeprom+DS1307 --> Ok
d) check timer with DS1307 + a little bit menu and see it's working -->WITHOUT EEPROM--> not ok
e) check timer with DS1307 + a little bit menu WITH EEPROM --> not ok

So I've tried to move the timer from loop to setup and from setup to loop without any success ....

this below is an example without no more complicated ... maybe you have one sketch that it's working with timer ?

to be honest at this point and don't know what check ... seems that the timer routine is never call ...

/*
 * TimeAlarmExample.pde
 *
 * This example calls alarm functions at 8:30 am and at 5:45 pm (17:45)
 * and simulates turning lights on at night and off in the morning
 * A weekly timer is set for Saturdays at 8:30:30
 *
 * A timer is called every 15 seconds
 * Another timer is called once only after 10 seconds
 *
 * At startup the time is set to Jan 1 2011  8:29 am
 */
#include <Wire.h> 
#include <DS1307.h> 
#include <Time.h>
#include <TimeAlarms.h>
#include <LiquidCrystal.h>	// ensure that the include path is set
#include "M2tk.h"

M2_EXTERN_HLIST(top_el_expandable_menu);


/*======================================================================*/
/* number entry */

uint8_t u8num = 0;
uint32_t u32num = 0;

void fn_num_zero(m2_el_fnarg_p fnarg) {
  u8num = 0;
  u32num = 0;
}

M2_LABEL(el_num_label1, NULL, "U8:");
M2_U8NUM(el_num_1, NULL, 0, 255, &u8num);

M2_LABEL(el_num_label2, NULL, "U32:");
M2_U32NUM(el_num_2, "c5", &u32num);

M2_BUTTON(el_num_zero, "f4", " zero ", fn_num_zero);
M2_ROOT(el_num_goto_top, "f4", " back ", &top_el_expandable_menu);

M2_LIST(num_list) = { 
    &el_num_label1, &el_num_1, 
    &el_num_label2, &el_num_2,  
    &el_num_zero, &el_num_goto_top
};
M2_GRIDLIST(el_num_menu, "c2", num_list);

/*=========================================================================*/
/* edit date dialog */

uint8_t dt_day = 1;
uint8_t dt_month = 1;
uint8_t dt_year = 12;

void dt_ok_fn(m2_el_fnarg_p fnarg)  {
  m2_SetRoot(&top_el_expandable_menu);
}

M2_U8NUM(el_dt_year, "c2", 0,99,&dt_year);
M2_LABEL(el_dt_sep1, "b1", "-");
M2_U8NUM(el_dt_month, "c2", 1,12,&dt_month);
M2_LABEL(el_dt_sep2, "b1", "-");
M2_U8NUM(el_dt_day, "c2", 1,31,&dt_day);

M2_LIST(list_date) = { &el_dt_year, &el_dt_sep1, &el_dt_month, &el_dt_sep2, &el_dt_day };
M2_HLIST(el_date, NULL, list_date);

M2_ROOT(el_dt_cancel, NULL, "cancel", &top_el_expandable_menu);
M2_BUTTON(el_dt_ok, NULL, "ok", dt_ok_fn);
M2_LIST(list_dt_buttons) = {&el_dt_cancel, &el_dt_ok };
M2_HLIST(el_dt_buttons, NULL, list_dt_buttons);

M2_LIST(list_dt) = {&el_date, &el_dt_buttons };
M2_VLIST(el_top_dt, NULL, list_dt);

/*=========================================================================*/
/* radio */

uint8_t select_color = 0;

void fn_radio_ok(m2_el_fnarg_p fnarg) {
  /* accept selection */
  m2_SetRoot(&top_el_expandable_menu);
}

void fn_radio_cancel(m2_el_fnarg_p fnarg) {
  /* discard selection */
  m2_SetRoot(&top_el_expandable_menu);
}

M2_LABEL(el_radio_label1, NULL, "red");
M2_RADIO(el_radio_radio1, "v0", &select_color);

M2_LABEL(el_radio_label2, NULL, "green");
M2_RADIO(el_radio_radio2, "v1", &select_color);

M2_LABEL(el_radio_label3, NULL, "blue");
M2_RADIO(el_radio_radio3, "v2", &select_color);

M2_BUTTON(el_radio_cancel, NULL, "cancel", fn_radio_cancel);
M2_BUTTON(el_radio_ok, NULL, "ok", fn_radio_ok);

M2_LIST(list_radio) = { 
    &el_radio_label1, &el_radio_radio1, 
    &el_radio_label2, &el_radio_radio2,  
    &el_radio_label3, &el_radio_radio3, 
    &el_radio_cancel, &el_radio_ok 
};
M2_GRIDLIST(top_el_radio, "c2",list_radio);

/*=========================================================================*/
/* combo */

uint8_t select_priority = 0;

void fn_combo_ok(m2_el_fnarg_p fnarg) {
  /* accept selection */
  m2_SetRoot(&top_el_expandable_menu);
}

void fn_combo_cancel(m2_el_fnarg_p fnarg) {
  /* discard selection */
  m2_SetRoot(&top_el_expandable_menu);
}

const char *fn_idx_to_color(uint8_t idx)
{
  if ( idx == 0 )
    return "red";
  else if (idx == 1 )
    return "green";
  return "blue";
}

const char *fn_idx_to_priority(uint8_t idx)
{
  switch(idx)
  {
    case 0: return "lowest";
    case 1: return "low";
    case 2: return "medium";
    case 3: return "high";
    case 4: return "highest";
  }
  return "";
}


M2_LABEL(el_combo_label1, NULL, "Color:");
M2_COMBO(el_combo_combo1, NULL, &select_color, 3, fn_idx_to_color);

M2_LABEL(el_combo_label2, NULL, "Prio.: ");
M2_COMBO(el_combo_combo2, "v1", &select_priority, 5, fn_idx_to_priority);

M2_BUTTON(el_combo_cancel, NULL, "cancel", fn_combo_cancel);
M2_BUTTON(el_combo_ok, NULL, " ok ", fn_combo_ok);

M2_LIST(list_combo) = { 
    &el_combo_label1, &el_combo_combo1, 
    &el_combo_label2, &el_combo_combo2,  
    &el_combo_cancel, &el_combo_ok 
};
M2_GRIDLIST(top_el_combo, "c2",list_combo);

/*=========================================================================*/
/* main menu */


// Left entry: Menu name. Submenus must have a '.' at the beginning
// Right entry: Reference to the target dialog box (In this example all menus call the toplevel element again
m2_menu_entry m2_2lmenu_data[] = 
{
  { "Numeric", NULL },
  { ". U8 U32", &el_num_menu },
  { ". Date", &el_top_dt },
  { "Radio", &top_el_radio },
  { "Combo", &top_el_combo },
  { NULL, NULL },
};

// The first visible line and the total number of visible lines.
// Both values are written by M2_2LMENU and read by M2_VSB
uint8_t m2_2lmenu_first;
uint8_t m2_2lmenu_cnt;

// M2_2LMENU definition
// Option l4 = four visible lines
// Option e1 = first column has a width of 1 char
// Option w12 = second column has a width of 12 chars

M2_2LMENU(el_2lmenu,"l4e1w12",&m2_2lmenu_first,&m2_2lmenu_cnt, m2_2lmenu_data,'+','-','\0');
M2_VSB(el_vsb, "l4w1r1", &m2_2lmenu_first, &m2_2lmenu_cnt);
M2_LIST(list_2lmenu) = { &el_2lmenu, &el_vsb };
M2_HLIST(top_el_expandable_menu, NULL, list_2lmenu);

// m2 object and constructor
M2tk m2(&top_el_expandable_menu, m2_es_arduino_serial, m2_eh_4bs, m2_gh_arduino_serial);
TimeElements tm,tm1;

byte memoria[105];

String readString;
#include <EEPROM.h>
void setup()
{
  LeggiEeprom();
  RTC.stop();
  RTC.set(DS1307_DATE,23);
  RTC.set(DS1307_MTH,01);
  RTC.set(DS1307_YR,2013);
  RTC.set(DS1307_HR,1);
  RTC.set(DS1307_MIN,3);
  RTC.start(); 
  int c;
  
  Serial.begin(9600);
  setTime(RTC.get(DS1307_HR,true),RTC.get(DS1307_MIN,false),RTC.get(DS1307_SEC,false),RTC.get(DS1307_DATE,false),RTC.get(DS1307_MTH,false),RTC.get(DS1307_YR,false)-2000);
  // setTime(1,3,00,23,1,13); // set time to Saturday 8:29:00am Jan 1 2011
  
  tm.Year = (memoria[6]+ 2000) - 1970;
  tm.Month = (memoria[5]);
  tm.Day = memoria[4];
  tm.Hour =  memoria[2];
  tm.Minute =  memoria[3];
  tm.Second = 00;
  tm1.Year = (memoria[11]+2000) -1970;
  tm1.Month = (memoria[10]);
  tm1.Day = (memoria[9]);
  tm1.Hour = (memoria[7]);
  tm1.Minute = (memoria[8]);
  tm1.Second = 00;
  
   Alarm.triggerOnce(makeTime(tm), OnceOnly);
  Alarm.triggerOnce(makeTime(tm1), OnceOnly1);
  
  // Alarm.timerOnce(makeTime(tm), OnceOnly) ;
  // Serial.println("Make Time");
  
  // Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
               // called once after 10 seconds 
}

void  loop(){  
 
   m2.checkKey();
  m2.checkKey();
  if ( m2.handleKey() )
    m2.draw();
  m2.checkKey();
 
  
  // digitalClockDisplay();
  
  // Alarm.delay(1000); // wait one second between clock display
  
  
}

// functions to be called when an alarm triggers:

void OnceOnly(){
  Serial.println("Inizio Timer");  
}

void OnceOnly1(){
  Serial.println("Fine Timer");  
}
void digitalClockDisplay()
{
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(); 
}

void printDigits(int digits)
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

void LeggiEeprom()
{
  int ind;
   for (ind =0; ind <= 105 ; ind++)
      {
        memoria[ind] = EEPROM.read(ind);
      }   
}

thanks
gnux

Hi Oliver,
after one day that work on that ... I can say this:

  • RTC and Arduino Clock are correctly set
  • Without use a timer but only put a standard clock for example clock that change in working
  • With timer for sure the timer are correct but stop to work ...

it's possible that timer is not compatible with menu or viceversa ?

Thanks for the support,

gnux

Hi

Excause me for not reading this thread more often.

I do not know much about the timer itself. What i can say: M2tklib will use

  • digitalRead
  • Serial interface for the Monitor Simulation
    Can this do any harm to your system?

What you could do is to comment out

  m2.checkKey();
  m2.checkKey();
  if ( m2.handleKey() )
    m2.draw();
  m2.checkKey();

and check if things are working again.
Maybe you can also check the timer procedures with some small menu.
If this is working, that it is probably a memory issue.
Which Arduino do you use?

Oliver

No problem Oliver don't worry :slight_smile: thanks for your help and time :slight_smile: I was writing you because during this day I was free time for do the try just it :slight_smile: ...

So due the fact I've note this ... for example without set a timer retriving date and time from RTC it's working ...

void loop() {
  
     
    // Alarm.triggerOnce(makeTime(tm0start), StartTimer0);
     
     
     
     // Alarm.triggerOnce(makeTime(tm0stop), StopTimer0);
  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
  Serial.print(":");
  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
  Serial.print(":");
  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
  Serial.print("      ");                 // some space for a more happy life
  Serial.print(RTC.get(DS1307_DATE,false));//read date
  Serial.print("/");
  Serial.print(RTC.get(DS1307_MTH,false));//read month
  Serial.print("/");
  Serial.print(RTC.get(DS1307_YR,false)); //read year
  Serial.println();
  
  m2.checkKey();
  m2.checkKey();
  if ( m2.handleKey() )
    m2.draw();
  m2.checkKey();
  
}

Then what i mean it that execute the instruction into the loop also ...

I think that is necessary troubleshoot Time.h library , but i don't know if i will be able to this ...
the library menu use some particular resources sorry if I ask you but could be useful tomorrow when i'll try to compare the 2 library ....

so I'm using arduino 2560 mega ...

Thanks for the big support,
have a good night ...
gnux

Schermata 2013-01-22 a 21.45.08.png

Good Morning Oliver,
so, finally it's working :slight_smile: ... after a lots of try I've understand what was really missing ...

a)

setTime(RTC.get(DS1307_HR,true),RTC.get(DS1307_MIN,false),RTC.get(DS1307_SEC,false),RTC.get(DS1307_DATE,false),RTC.get(DS1307_MTH,false),13)

Looking the code you will note that like Year I've explict "13" --> "2013" before there was this :

setTime(RTC.get(DS1307_HR,true),RTC.get(DS1307_MIN,false),RTC.get(DS1307_SEC,false),RTC.get(DS1307_DATE,false),RTC.get(DS1307_MTH,false),(RTC.get(DS1307_YR,false)-2000))

That I think means that doesn't accept the calcution in this way in fact is necessary put (), but I will do other try just to understand ... Maybe I will calculate into a variable and then I will pass the value to the function ...

The other problems was that, into the loop is necessary put

Alarm.delay(1000);

Otherwise the timer will not start ...

Ok with the timer of course but i think is correct there is a little bit delay because off course in background there is the timer that is working ...

So now i will study an efficient manner how to manage the timer ... I'll let you know because I think that you are a very good teacher... I've to found the way for do a input menu for a timer ... :slight_smile: maybe you can help me with this :slight_smile:

my idea is do a menu for a timer structure in this way:

Timer:

  • set timer
    --> select dev
    --> enable / disable
    --> put time start date time
    --> put time stop date time
    (could be the best do start / stop time with only row if is possible)

  • View Timer Set

so for select a dev and enable/disable i think is not a problem ... for the other could be a issues ...
because im not able to manage at the top the menu :frowning:

Thanks and have nice day,
gnux

Hi

Maybe i have not yet fully understood your problem. Do you want to program exactly one timer or more than one timer?

In either case, you need to know, what exactly needs to be entered for one timer.
You mention date and time, start and dev.
But it probably needs to be cut down to atomic data times like byte and words.
So this is probably the first step: To break down the required information to small pieces.
For example in this way:
time: hour (byte, 0..23), minute (byte, 0..59), seconds (0..59)
start: could be represented as a status byte: 0 for timer stopped, 1 for time is running. In that sense the variable should be better called "is_running". By the way it is a good practice to have a naming convention for variables. For example if all boolean variables start with "is_" then they are easily seen in the code. You could also do something like
if ( is_running ) ...
which will be executed if the time "runs"
An open question to me is the mentioned "dev" (select dev). What exactly needs to be selected? How much selectable items are there. Can it be mapped to some integer (byte) variable?

So, again, first step is to break down all this to variables. Then write some nice dialog entries for it.

Once done, the question is: Is there only one timer or are there more timers to handle. Of course the existing dialogs should be reused for each different set of timer configuration variables.

if you need to handle more than one timer, i think it will make sense to study tutorial 8: Google Code Archive - Long-term storage for Google Code Project Hosting.. Tutorial 8 has a configuration menu for the PWM output. Compare your timer data with the PWM output in this tutorial. This tutorial also introduces a top level menu. And: The PWM example is also available in the Arduino IDE (if m2tklib is installed correctly)

Oliver

If Alarm.delay(1000) is causing you a problem because it blocks your code for 1 second then you should consider reducing the delay time or better, only calling Alarm.delay() when it will not interfere with the operation of your program, or both, of course.

I think should be better reduce the delay maybe ...

because otherwise how can the timer start ?

Thanks
gnux