Pages: 1 2 [3] 4   Go Down
Author Topic: Hello, I need your help. can anyone have an example code for a graphical display  (Read 9000 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 36
I electronics
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you now it is clear smiley
Logged

Help me please

Offline Offline
Newbie
*
Karma: 0
Posts: 36
I electronics
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, I need help again. My project is almost ready. What is missing is the menu. What would manage. I can not figure out how to make a choice on the program. What I want to start by pressing a button. Help please someone who can. I chose the example of it Libraries below.

Code:
/*

  Radio.pde
 
  GLCD Example

  m2tklib = Mini Interative Interface Toolkit Library
 
  Copyright (C) 2011  olikraus@gmail.com

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <glcd.h> // inform Arduino IDE that we will use GLCD library
#include "M2tk.h"
#include "utility/m2ghglcd.h"

uint8_t uiKeySelectPin = 4;
uint8_t uiKeyDownPin = 3;
uint8_t uiKeyUpPin = 2;
uint8_t uiKeyExitPin = 1;

uint8_t select_color = 0;

void fn_ok(m2_el_fnarg_p fnarg) {
  is_voltmeter = 1;is_fuel = 1;is_temperature = 1;
}

void fn_cancel(m2_el_fnarg_p fnarg) {
  is_voltmeter = 0;is_fuel = 0;is_temperature = 0;
}


M2_LABEL(el_label1, NULL, "voltmeter");
M2_RADIO(el_radio1, "v0", &select_color);

M2_LABEL(el_label2, NULL, "fuel");
M2_RADIO(el_radio2, "v1", &select_color);

M2_LABEL(el_label3, NULL, "temperature");
M2_RADIO(el_radio3, "v2", &select_color);

M2_BUTTON(el_cancel, NULL, "cancel", fn_cancel);
M2_BUTTON(el_ok, NULL, " ok ", fn_ok);

M2_LIST(list) = {
    &el_label1, &el_radio1,
    &el_label2, &el_radio2, 
    &el_label3, &el_radio3,
    &el_cancel, &el_ok
};
M2_GRIDLIST(list_element, "c2",list);
M2tk m2(&list_element, m2_es_arduino, m2_eh_2bs, m2_gh_glcd_ffs);

void setup() {
  m2.setPin(M2_KEY_SELECT, uiKeySelectPin);
  m2.setPin(M2_KEY_NEXT, uiKeyDownPin);
  m2.setPin(M2_KEY_PREV, uiKeyUpPin);
  m2.setPin(M2_KEY_EXIT, uiKeyExitPin); 
}

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

« Last Edit: August 30, 2011, 10:46:17 am by alexssey163 » Logged

Help me please

Offline Offline
Newbie
*
Karma: 0
Posts: 36
I electronics
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I think there should be three independent process void. But how to include them in choosing not understand. I'm just a beginner. smiley-confuse
Logged

Help me please

Offline Offline
Newbie
*
Karma: 0
Posts: 36
I electronics
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried myself Nitsche not work. I do not understand where my mistake.  smiley-sad
Code:
*/

#include <glcd.h> // inform Arduino IDE that we will use GLCD library
#include "M2tk.h"
#include "utility/m2ghglcd.h"

uint8_t uiKeySelectPin = 4;
uint8_t uiKeyDownPin = 3;
uint8_t uiKeyUpPin = 2;
uint8_t uiKeyExitPin = 1;

uint8_t select_color = 0;

uint8_t is_voltmeter = 0;

void fn_ok(m2_el_fnarg_p fnarg) {
  is_voltmeter = 1;
}

void fn_cancel(m2_el_fnarg_p fnarg) {
  is_voltmeter = 0;
}


M2_LABEL(el_label1, NULL, "voltmeter");
M2_RADIO(el_radio1, "v0", &select_color);

M2_LABEL(el_label2, NULL, "fuel");
M2_RADIO(el_radio2, "v1", &select_color);

M2_LABEL(el_label3, NULL, "temperature");
M2_RADIO(el_radio3, "v2", &select_color);

M2_BUTTON(el_cancel, NULL, "cancel", fn_cancel);
M2_BUTTON(el_ok, NULL, " ok ", fn_ok);

M2_LIST(list) = {
    &el_label1, &el_radio1,
    &el_label2, &el_radio2, 
    &el_label3, &el_radio3,
    &el_cancel, &el_ok
};
M2_GRIDLIST(list_element, "c2",list);
M2tk m2(&list_element, m2_es_arduino, m2_eh_2bs, m2_gh_glcd_ffs);


void voltmeter_process(void) {
  digitalWrite(13, HIGH);  // set the LED on
  delay(2000);
  digitalWrite(13, LOW);   // set the LED off
}



void setup() {
  m2.setPin(M2_KEY_SELECT, uiKeySelectPin);
  m2.setPin(M2_KEY_NEXT, uiKeyDownPin);
  m2.setPin(M2_KEY_PREV, uiKeyUpPin);
  m2.setPin(M2_KEY_EXIT, uiKeyExitPin);
  pinMode(13, OUTPUT); 
}

void loop() {
  m2.checkKey();
  if ( m2.handleKey() ) {
      m2.draw();
  }
  if ( is_voltmeter )
  voltmeter_process ();
}
Logged

Help me please

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1516
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Maybe you should more clearly define "choice on the program".
M2_RADIO is fine for choosing values. M2_BUTTON and M2_ROOT are more general and allow to change the display content. But it is difficult to give hints without knowing the background.

Oliver
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 36
I electronics
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for having responded. And the essence of a simple menu. We have three programs 1voltmetr 2toplivo 3temperatura. When you click OK indicates a program. When you cancel a return to the menu. But I guess it's too complicated for my level of knowledge. I'm very sorry sad. smiley-sad
Logged

Help me please

Offline Offline
Newbie
*
Karma: 0
Posts: 36
I electronics
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So far only happened since. Clicking OK runs a program. When you cancel the second program runs.

Code:
*/

#include <glcd.h> // inform Arduino IDE that we will use GLCD library
#include "M2tk.h"
#include "utility/m2ghglcd.h"


uint8_t uiKeySelectPin = 4;
uint8_t uiKeyDownPin = 3;
uint8_t uiKeyUpPin = 2;
uint8_t uiKeyExitPin = 1;

uint8_t select_color = 0;
uint8_t select_priority = 0;
uint8_t is_voltmeter = 0;
uint8_t is_fuel = 0;


void fn_ok(m2_el_fnarg_p fnarg) {
  digitalWrite(8, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(8, LOW);    // set the LED off
  delay(10); tone(6, 440, 200); is_voltmeter = 1; is_fuel = 0;           // wait for a second
  /* accept selection */
}

void fn_cancel(m2_el_fnarg_p fnarg) {
  digitalWrite(8, HIGH);   // set the LED on
  delay(100);              // wait for a second
  digitalWrite(8, LOW);    // set the LED off
  delay(10);tone(6, 140, 200); is_voltmeter = 0; is_fuel = 1;              // wait for a second
  /* discard selection */
}

const char *fn_idx_to_color(uint8_t idx)
{
  if ( idx == 0 )
    return "red";
  else if (idx == 1 )
    return "green";
  return "temp";tone(6, 740, 200);
 
}

const char *fn_idx_to_priority(uint8_t idx)
{
  switch(idx)
  {
    case 0: return "lowest";tone(6, 150, 200);
    case 1: return "low";tone(6, 140, 200);
    case 2: return "medium";tone(6, 130, 200);
    case 3: return "high";tone(6, 120, 200);
   
  }
  return "";
}
M2_LABEL(el_label1, NULL, "voltmeter");
M2_RADIO(el_radio1, "v0", &select_color);

M2_LABEL(el_label2, NULL, "fuel");
M2_RADIO(el_radio2, "v0", &select_color);

M2_LABEL(el_label3, NULL, "Color:");
M2_COMBO(el_combo3, NULL, &select_color, 3, fn_idx_to_color);

M2_LABEL(el_label4, NULL, "Priority: ");
M2_COMBO(el_combo4, "v1", &select_priority, 4, fn_idx_to_priority);

M2_BUTTON(el_cancel, NULL, "cancel", fn_cancel);
M2_BUTTON(el_ok, NULL, " ok ", fn_ok);

M2_LIST(list) = {
    &el_label1, &el_radio1,
    &el_label2, &el_radio2,
    &el_label3, &el_combo3,
    &el_label4, &el_combo4, 
    &el_cancel, &el_ok
};
M2_GRIDLIST(list_element, "c2",list);
M2tk m2(&list_element, m2_es_arduino, m2_eh_4bs, m2_gh_glcd_ffs);

void voltmeter_process(void) {
  digitalWrite(9, HIGH);  // set the LED on
  delay(500);
  digitalWrite(9, LOW);  // set the LED off
  delay(200);
  digitalWrite(9, HIGH);  // set the LED on
  delay(500);
  digitalWrite(9, LOW);   // set the LED off
}
void fuel_process(void) {
  digitalWrite(12, HIGH);  // set the LED on
  delay(50);
  digitalWrite(12, LOW);  // set the LED off
  delay(20);
  digitalWrite(12, HIGH);  // set the LED on
  delay(50);
  digitalWrite(12, LOW);   // set the LED off
}



void setup() {
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
   pinMode(12, OUTPUT);
  m2.setPin(M2_KEY_SELECT, uiKeySelectPin);
  m2.setPin(M2_KEY_NEXT, uiKeyDownPin);
  m2.setPin(M2_KEY_PREV, uiKeyUpPin);
  m2.setPin(M2_KEY_EXIT, uiKeyExitPin); 
}

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


if ( is_fuel )
  fuel_process ();
}
Logged

Help me please

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1516
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But I guess it's too complicated for my level of knowledge. I'm very sorry sad.
Don't be sad. I guess it is more a learning curve. Working with C or C++ in an embedded environment is complicated.

For the first part of my answer, i looked up some resources on finite state machine design for embedded systems.

This one is nice, because it covers the "creative step":
http://ceit.uq.edu.au/content/finite-state-machine-design-so-whats-problem-why-cant-students-get-it

This tutorial is more related to embedded programming:
http://www.splatco.com/fsm_tute/fsm_tute01.htm

I am not sure how to teach you on embedded software design, but maybe you get some ideas from the above links.

second, more specific answer to your problem follows later...

Oliver
Logged

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1516
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So, here is the second part of my answer...

This is what i understand from your problem:
- There are three things to measure (three sensor values)
- You want to be able to select between these measurements (one dialog box for each sensor value)
Your questions might be:
1) How to construct a menu hierarchy for selecting a measurement
2) How to write a program so that measurement and menu (m2tklib) are working in parallel.

Answer for 1)
The example below offers three different ways to select between the three sensor values.
* section menu,
* bottom menu bar or
* combo box menu.
So you can see the differences between them, when you compile and download the example code.

Answer for 2)
I have added a parallel process for the measurement. Menu and measurement processes are working together through global variables (see code for details).
As an example,
* sensor value 1 toggles between 0 and 1
* sensor value 2 does nothing (and has the constant value 2)
* sensor value 3 shows 1/10 seconds since reset.

The code below should compile fine on your Arduino Environment:
See http://code.google.com/p/m2tklib/source/browse/arduino/glcd/SensorValues/SensorValues.pde or attachment of this reply.

Oliver



* SensorValues.pde (11.31 KB - downloaded 12 times.)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 36
I electronics
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you very much for helping me. smiley
Logged

Help me please

Offline Offline
Newbie
*
Karma: 0
Posts: 36
I electronics
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello, your code is the menu I liked. So I decided to apply it. Until just wanted to add the program to a voltmeter. But this compilation is a mistake . I tried all the libraries glcd. And I can not understand what was happening.  smiley-confuse С:arduino/-022/libraries/glcd/fonts/systemFont5x7.h:48 error: System5x7 causes a section type conflict
С:arduino/-022/libraries/glcd/fonts/fixednums15x31.h:23 error: fixednums15x31 causes a section type conflict
С:arduino/-022/libraries/glcd/fonts/Arial_14.h:55 error: Arial_14 causes a section type conflict

Code:
/*


  SensorValues.pde


  Provide two alternative ways to show three sensor values.


  GLCD Example


  m2tklib = Mini Interative Interface Toolkit Library
 
  Copyright (C) 2011  olikraus@gmail.com
 
 
  /*==========================================================================*/
/* Includes and menu key definition */
/*==========================================================================*/


#include "M2tk.h"
#include "utility/m2ghglcd.h"
#include "glcd.h"
#include "fonts/allFonts.h"

 unsigned long startMillis;
 
 float opn=4.99;     //опорное напряжение вольты
 float volt;         // переменная в которой храним конечное значение вольт             
 float var0;            // храним промежуточное значение вольт, данные с аналового входа №0 
 int amper ;          //переменная в которой храним конечное значение миллиампер.используем целочисленные значения,и посему интовая переменная
 float var1  ;        // храним промежуточное значение вольт, данные с аналового входа №1


uint8_t uiKeySelectPin = 4;
uint8_t uiKeyDownPin = 3;
uint8_t uiKeyUpPin = 2;
uint8_t uiKeyExitPin = 1;


/*==========================================================================*/
/* Sensor values: Will be set by some measurement processes  */
/*==========================================================================*/


uint32_t value1 = 1;
uint32_t value2 = 2;
uint32_t value3 = 3;


/*==========================================================================*/
/* Active sensor: Output variable by the menu, shows active dialog box  */
/*==========================================================================*/
/* 0: no sensor dialog open */
/* 1: sensor value 1 is on screen */
/* 2: sensor value 2 is on screen */
/* 3: sensor value 3 is on screen */
uint8_t active_sensor = 0;


/*==========================================================================*/
/* is_value_changed: Output variable by the sensor process */
/*==========================================================================*/
/* 0: value did not change */
/* 1: value has changed */
uint8_t is_value_changed = 0;


/*==========================================================================*/
/* Forward declaration of the menu class (required for the callback functions)  */
/*==========================================================================*/
extern M2tk m2;


/*==========================================================================*/
/* Option 1:  Hierachical menu, go back button for each sensor value dialog */
/*==========================================================================*/


/*=== Forward declaration of the root menu for option 1 ===*/
M2_EXTERN_VLIST(el_o1_vlist);


/*=== "Go Back" button, which will be reused for option 1 example menu ===*/


void fn_o1_go_back(m2_el_fnarg_p fnarg) {
  active_sensor = 0;
  m2.setRoot(&el_o1_vlist);
}
M2_BUTTON(el_o1_go_back, NULL, "Go Back", fn_o1_go_back);


/*=== A simple dialog box, which shows the value ===*/
/*
  +==============+
  | Description: |
  | 0000.0       |
  | [Go Back]    |
  +==============+
  three menus will be defined, one for each sensor value
*/


M2_LABEL(el_o1_v1_desc, NULL, "VOLTS");
M2_U32NUM(el_o1_v1_num, ".1c4r1", &value1);
M2_LIST(list_o1_v1) = { &el_o1_v1_desc, &el_o1_v1_num, &el_o1_go_back};
M2_VLIST(el_o1_v1_vlist, NULL, list_o1_v1);


M2_LABEL(el_o1_v2_desc, NULL, "LITR:");
M2_U32NUM(el_o1_v2_num, ".1c5r2", &value2);
M2_LIST(list_o1_v2) = { &el_o1_v2_desc, &el_o1_v2_num, &el_o1_go_back};
M2_VLIST(el_o1_v2_vlist, NULL, list_o1_v2);


M2_LABEL(el_o1_v3_desc, NULL, "GRADUS:");
M2_U32NUM(el_o1_v3_num, ".1c6r3", &value3);
M2_LIST(list_o1_v3) = { &el_o1_v3_desc, &el_o1_v3_num, &el_o1_go_back};
M2_VLIST(el_o1_v3_vlist, NULL, list_o1_v3);


/*=== A parent selection box allows to select one of the sensor values ===*/


void fn_o1_select1(m2_el_fnarg_p fnarg) {
  active_sensor = 1;
  m2.setRoot(&el_o1_v1_vlist);
}
M2_BUTTON(el_o1_select1, NULL, "VOLTMETER", fn_o1_select1);
void fn_o1_select2(m2_el_fnarg_p fnarg) {
  active_sensor = 2;
  m2.setRoot(&el_o1_v2_vlist);
}
M2_BUTTON(el_o1_select2, NULL, "FUEL", fn_o1_select2);
void fn_o1_select3(m2_el_fnarg_p fnarg) {
  active_sensor = 3;
  m2.setRoot(&el_o1_v3_vlist);
}
M2_BUTTON(el_o1_select3, NULL, "TEMPERATURE", fn_o1_select3);
M2_LIST(list_o1) = { &el_o1_select1, &el_o1_select2, &el_o1_select3 };
M2_VLIST(el_o1_vlist, NULL, list_o1);

M2_ROOT(el_goto_o1, NULL, "Option 1: Parent Menu", &el_o1_vlist);
void fn_o2_start(m2_el_fnarg_p fnarg) {
  active_sensor = 1;
 
}
M2_LIST(list_options) = { &el_goto_o1  };
M2_VLIST(el_options, NULL, list_options);
/*==========================================================================*/
/* Menu constructor */
/*==========================================================================*/


M2tk m2(&el_options, m2_es_arduino, m2_eh_2bs, m2_gh_glcd_ffs);
 
  /*==========================================================================*/
/* Sensor process */
/*==========================================================================*/


/* sensor1 process assignes state of a flashing LED */


uint8_t led_state = 0;
uint32_t next_change = 0;
uint8_t is_flashing = 0;
uint8_t flash_delay = 7;


void sensor1_process(void) {
  // wait until timer as expired
  if ( next_change < millis() ) {
    if ( led_state == 0 ) {
      digitalWrite(12, HIGH);  // set the LED on   
      led_state = 1;
    } else {
      digitalWrite(12, LOW);   // set the LED off
      led_state = 0;
    }
    // wait for x*50ms, were x is between 0 and 9
    next_change = millis() + (flash_delay*50L);
  }
  if ( led_state != value1 ) {
    value1 = led_state;
    is_value_changed = 1;
  }
}


/* sensor1 process does nothing program voltmeter*/


void sensor2_process(void) {
 
 
 GLCD.Init(NON_INVERTED);   // initialise the library, non inverted writes pixels onto a clear screen
   GLCD.ClearScreen();
   GLCD.SelectFont(System5x7);
 gText s1;gText s2;
 
      startMillis = millis();
  while( millis() - startMillis < 1000){
 s1.DefineArea(textAreaTOP);
 s1.SelectFont(fixednums15x31);
 s2.DefineArea(textAreaTOP);
 s2.SelectFont(fixednums15x31);
 
 

var0 = analogRead(0); //переменная для приёма данных с аналогового входа             
  volt =(opn*var0/1024.0);//вычисляем напряжение на входе с делителя
  float U1;         //вводим дополнительную переменную чтоб просчитать напряжение после делителя
  U1=volt*((8200.0+1860.0)/1860.0)/2;  //(opn*var1/1024.0)вычитаем падение напряжения на шунте амперметра
   
    var1 = analogRead(1);//вход для амперметра             
    amper =((opn*var1/1.0240)/.50); //измеряем напряжение в милливольтах и делим на .50 -сопротивление шунта,конечное значение переменной в миллиамперах

   

   
   
    s1.CursorTo(0,0);//ставим курсор в вверхний левый угол.
    s1.print(U1); //выводим вычисленное значение на экран
    GLCD.SelectFont(Arial_14);//библиотека шрифт большой пишем
    GLCD.CursorTo(8,1);//ставим курсор в позицию
    GLCD.Puts("U.volt");//выводим надпись U.volt
   
   
    s2.CursorTo(0,1);
    s2.print(amper);
    GLCD.SelectFont(Arial_14);
    GLCD.CursorTo(8,3);
    GLCD.Puts("mA");
   
    delay(300); //задержка-обновление экрана 3 раза в секунду   
}
}
   
   

 
 
 



/* sensor3 process assignes a 1/10 seconds since reset */


void sensor3_process(void) {
  uint32_t tmp;
  /* just assign the 1/10 seconds since last reset */
  tmp = millis();
  tmp /= 100;
  if ( value3 != tmp ) {
    value3 = tmp;
    is_value_changed = 1;
  }
}


/* reads active_sensor and writes values to "value1", "value2" or "value3" */
void sensor_process(void)
{
  switch(active_sensor) {
    case 1:
      sensor1_process();
      break;
    case 2:
      sensor2_process();
      break;
    case 3:
      sensor3_process();
      break;
    default:
      break;
  }
}


/*==========================================================================*/
/* Arduino setup & loop */
/*==========================================================================*/


void setup() {
 
  pinMode(12, OUTPUT);
  pinMode(9, OUTPUT);     
  m2.setPin(M2_KEY_SELECT, uiKeySelectPin);
  m2.setPin(M2_KEY_NEXT, uiKeyDownPin);
  m2.setPin(M2_KEY_PREV, uiKeyUpPin);
  m2.setPin(M2_KEY_EXIT, uiKeyExitPin); 
}


void loop() {
  m2.checkKey();
  if ( m2.handleKey() || is_value_changed ) {
      m2.draw();
      is_value_changed = 0;
  }
 
  sensor_process();
}
 
 
 
 
 
 
 
 
 
 
 
Logged

Help me please

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2738
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm really stumped on that one too.
The error shows up whenever a call to SelectFont() is done
down in sensor2_process().

Something very odd (but probably dirt simple) is causing this strange error.
(Still working on locating the issue)

UPDATE:

The problem shows up when using the M2_BUTTON() macro.
I'm not an expert (actually I know pretty much nothing about ) about gcc attributes, so I can't say what was intended with the
parent macro definition of M2_SECTION_PROGMEM
It is defined as

Code:
#define M2_SECTION_PROGMEM __attribute__((section(".progmem.data")))

Other references to __attribute__  that use progmem don't define it that way.
If I change the definition to simply reference the AVR definition PROGMEM instead, the error goes away.
i.e.:
Code:
#define M2_SECTION_PROGMEM PROGMEM

PROGMEM is defined in the system headers as:

Code:
#define __ATTR_PROGMEM__ __attribute__((__progmem__))
#define PROGMEM __ATTR_PROGMEM__

note the difference.
I'm guessing __progmem__ is a "magic" attribute name?

Oliver, can you take a look at this?

--- bill
« Last Edit: September 02, 2011, 08:29:31 pm by bperrybap » Logged

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1516
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, I saw these replies too late.

I am using a different definition of M2_SECTION_PROGMEM to a void a g++ compiler bug, which produces a c++ warning:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734

Using
Code:
#define M2_SECTION_PROGMEM PROGMEM
would be the better definition. The purpose is to put as much as possible of the data into flash rom area.

However, as far as I remember the GLCD API, the problem could be caused by the inclusion of the font files. Arial and SystemFont are also included within m2tklib. So including them again with
Code:
#include "fonts/allFonts.h"
will fail: I guess, because the font definition is in the .h file itself, so you get a double definition.

Fixing this error:
replace
Code:
#include "fonts/allFonts.h"
with
Code:
#include "fonts/fixednums15x31.h"
(whatever other fonts you need, do explicitly include them)

Also replace
Code:
GLCD.SelectFont(System5x7);
with
Code:
GLCD.SelectFont(m2_System5x7);
and do the same with the Arial font. As I said, System and Arial (and only these two!) are included already in m2tklib. See also here:
http://code.google.com/p/m2tklib/wiki/ghref#m2_gh_glcd_ubf

@Bill: If I could request an enhancement for GLCD: Please allow multiple inclusion of font files from different C/C++ sources.

@alexssey163: Another issue in the code is, that you do another init in the sensor_process.
This will init the GLCD very often and in parallel to m2tklib (which also does the GLCD.init)
It is simply not required and it might conflict with m2tklib (two parallel tasks will use the same resource). I also do not know what will happen if you do the init for GLCD multiple times.

I will try to compile and review the code in the next days.

Oliver
Logged

Germany
Offline Offline
Edison Member
*
Karma: 137
Posts: 1516
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

here are some fast code updates from my side, but still produce the conflict error. But i think, this is because of the g++ bug. The GLCD fonts also use PROGMEM, which might lead to the gcc bug under certain condition.
My suggestion would be: First, try to write your program without fixednums. Use the system or Arial font instead (m2_...). If all other things are working, then we could try to switch to fixednums again.


Code:
/*
  SensorValues.pde

  /*==========================================================================*/
/* Includes and menu key definition */
/*==========================================================================*/


#include "M2tk.h"
#include "utility/m2ghglcd.h"
//#include "m2ghglcd.h"
#include "glcd.h"
#include "fonts/fixednums15x31.h"

 unsigned long startMillis;
 
 float opn=4.99;     //??????? ?????????? ??????
 float volt;         // ?????????? ? ??????? ?????? ???????? ???????? ?????             
 float var0;            // ?????? ????????????? ???????? ?????, ?????? ? ????????? ????? No0 
 int amper ;          //?????????? ? ??????? ?????? ???????? ???????? ??????????.?????????? ????????????? ????????,? ?????? ??????? ??????????
 float var1  ;        // ?????? ????????????? ???????? ?????, ?????? ? ????????? ????? No1


uint8_t uiKeySelectPin = 4;
uint8_t uiKeyDownPin = 3;
uint8_t uiKeyUpPin = 2;
uint8_t uiKeyExitPin = 1;


/*==========================================================================*/
/* Sensor values: Will be set by some measurement processes  */
/*==========================================================================*/


uint32_t value1 = 1;
uint32_t value2 = 2;
uint32_t value3 = 3;


/*==========================================================================*/
/* Active sensor: Output variable by the menu, shows active dialog box  */
/*==========================================================================*/
/* 0: no sensor dialog open */
/* 1: sensor value 1 is on screen */
/* 2: sensor value 2 is on screen */
/* 3: sensor value 3 is on screen */
uint8_t active_sensor = 0;


/*==========================================================================*/
/* is_value_changed: Output variable by the sensor process */
/*==========================================================================*/
/* 0: value did not change */
/* 1: value has changed */
uint8_t is_value_changed = 0;


/*==========================================================================*/
/* Forward declaration of the menu class (required for the callback functions)  */
/*==========================================================================*/
extern M2tk m2;


/*==========================================================================*/
/* Option 1:  Hierachical menu, go back button for each sensor value dialog */
/*==========================================================================*/


/*=== Forward declaration of the root menu for option 1 ===*/
M2_EXTERN_VLIST(el_o1_vlist);


/*=== "Go Back" button, which will be reused for option 1 example menu ===*/


void fn_o1_go_back(m2_el_fnarg_p fnarg) {
  active_sensor = 0;
  m2.setRoot(&el_o1_vlist);
}
M2_BUTTON(el_o1_go_back, NULL, "Go Back", fn_o1_go_back);


/*=== A simple dialog box, which shows the value ===*/
/*
  +==============+
  | Description: |
  | 0000.0       |
  | [Go Back]    |
  +==============+
  three menus will be defined, one for each sensor value
*/


M2_LABEL(el_o1_v1_desc, NULL, "VOLTS");
M2_U32NUM(el_o1_v1_num, ".1c4r1", &value1);
M2_LIST(list_o1_v1) = { &el_o1_v1_desc, &el_o1_v1_num, &el_o1_go_back};
M2_VLIST(el_o1_v1_vlist, NULL, list_o1_v1);


M2_LABEL(el_o1_v2_desc, NULL, "LITR:");
M2_U32NUM(el_o1_v2_num, ".1c5r2", &value2);
M2_LIST(list_o1_v2) = { &el_o1_v2_desc, &el_o1_v2_num, &el_o1_go_back};
M2_VLIST(el_o1_v2_vlist, NULL, list_o1_v2);


M2_LABEL(el_o1_v3_desc, NULL, "GRADUS:");
M2_U32NUM(el_o1_v3_num, ".1c6r3", &value3);
M2_LIST(list_o1_v3) = { &el_o1_v3_desc, &el_o1_v3_num, &el_o1_go_back};
M2_VLIST(el_o1_v3_vlist, NULL, list_o1_v3);


/*=== A parent selection box allows to select one of the sensor values ===*/


void fn_o1_select1(m2_el_fnarg_p fnarg) {
  active_sensor = 1;
  m2.setRoot(&el_o1_v1_vlist);
}
M2_BUTTON(el_o1_select1, NULL, "VOLTMETER", fn_o1_select1);
void fn_o1_select2(m2_el_fnarg_p fnarg) {
  active_sensor = 2;
  m2.setRoot(&el_o1_v2_vlist);
}
M2_BUTTON(el_o1_select2, NULL, "FUEL", fn_o1_select2);
void fn_o1_select3(m2_el_fnarg_p fnarg) {
  active_sensor = 3;
  m2.setRoot(&el_o1_v3_vlist);
}
M2_BUTTON(el_o1_select3, NULL, "TEMPERATURE", fn_o1_select3);
M2_LIST(list_o1) = { &el_o1_select1, &el_o1_select2, &el_o1_select3 };
M2_VLIST(el_o1_vlist, NULL, list_o1);

M2_ROOT(el_goto_o1, NULL, "Option 1: Parent Menu", &el_o1_vlist);
void fn_o2_start(m2_el_fnarg_p fnarg) {
  active_sensor = 1;
 
}
M2_LIST(list_options) = { &el_goto_o1  };
M2_VLIST(el_options, NULL, list_options);
/*==========================================================================*/
/* Menu constructor */
/*==========================================================================*/


M2tk m2(&el_options, m2_es_arduino, m2_eh_2bs, m2_gh_glcd_ffs);
 
  /*==========================================================================*/
/* Sensor process */
/*==========================================================================*/


/* sensor1 process assignes state of a flashing LED */


uint8_t led_state = 0;
uint32_t next_change = 0;
uint8_t is_flashing = 0;
uint8_t flash_delay = 7;


void sensor1_process(void) {
  // wait until timer as expired
  if ( next_change < millis() ) {
    if ( led_state == 0 ) {
      digitalWrite(12, HIGH);  // set the LED on   
      led_state = 1;
    } else {
      digitalWrite(12, LOW);   // set the LED off
      led_state = 0;
    }
    // wait for x*50ms, were x is between 0 and 9
    next_change = millis() + (flash_delay*50L);
  }
  if ( led_state != value1 ) {
    value1 = led_state;
    is_value_changed = 1;
  }
}


/* sensor1 process does nothing program voltmeter*/


void sensor2_process(void) {
 
 
 GLCD.Init(NON_INVERTED);   // initialise the library, non inverted writes pixels onto a clear screen
   GLCD.ClearScreen();
   GLCD.SelectFont((const uint8_t *)m2_System5x7);
 gText s1;gText s2;
 
      startMillis = millis();
  while( millis() - startMillis < 1000){
 s1.DefineArea(textAreaTOP);
 s1.SelectFont(fixednums15x31);
 s2.DefineArea(textAreaTOP);
 s2.SelectFont(fixednums15x31);
 
 

var0 = analogRead(0); //?????????? ??? ?????? ?????? ? ??????????? ?????             
  volt =(opn*var0/1024.0);//????????? ?????????? ?? ????? ? ????????
  float U1;         //?????? ?????????????? ?????????? ???? ?????????? ?????????? ????? ????????
  U1=volt*((8200.0+1860.0)/1860.0)/2;  //(opn*var1/1024.0)???????? ??????? ?????????? ?? ????? ??????????
   
    var1 = analogRead(1);//???? ??? ??????????             
    amper =((opn*var1/1.0240)/.50); //???????? ?????????? ? ???????????? ? ????? ?? .50 -????????????? ?????,???????? ???????? ?????????? ? ????????????

   

   
   
    s1.CursorTo(0,0);//?????? ?????? ? ???????? ????? ????.
    s1.print(U1); //??????? ??????????? ???????? ?? ?????
    GLCD.SelectFont((const uint8_t *)m2_Arial14);//?????????? ????? ??????? ?????
    GLCD.CursorTo(8,1);//?????? ?????? ? ???????
    GLCD.Puts("U.volt");//??????? ??????? U.volt
   
   
    s2.CursorTo(0,1);
    s2.print(amper);
    GLCD.SelectFont((const uint8_t *)m2_Arial14);
    GLCD.CursorTo(8,3);
    GLCD.Puts("mA");
   
    delay(300); //????????-?????????? ?????? 3 ???? ? ???????   
}
}
   
   

 
 
 



/* sensor3 process assignes a 1/10 seconds since reset */


void sensor3_process(void) {
  uint32_t tmp;
  /* just assign the 1/10 seconds since last reset */
  tmp = millis();
  tmp /= 100;
  if ( value3 != tmp ) {
    value3 = tmp;
    is_value_changed = 1;
  }
}


/* reads active_sensor and writes values to "value1", "value2" or "value3" */
void sensor_process(void)
{
  switch(active_sensor) {
    case 1:
      sensor1_process();
      break;
    case 2:
      sensor2_process();
      break;
    case 3:
      sensor3_process();
      break;
    default:
      break;
  }
}


/*==========================================================================*/
/* Arduino setup & loop */
/*==========================================================================*/


void setup() {
 
  pinMode(12, OUTPUT);
  pinMode(9, OUTPUT);     
  m2.setPin(M2_KEY_SELECT, uiKeySelectPin);
  m2.setPin(M2_KEY_NEXT, uiKeyDownPin);
  m2.setPin(M2_KEY_PREV, uiKeyUpPin);
  m2.setPin(M2_KEY_EXIT, uiKeyExitPin); 
}


void loop() {
  m2.checkKey();
  if ( m2.handleKey() || is_value_changed ) {
      m2.draw();
      is_value_changed = 0;
  }
 
  sensor_process();
}
 
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 70
Posts: 2738
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, I saw these replies too late.

I am using a different definition of M2_SECTION_PROGMEM to a void a g++ compiler bug, which produces a c++ warning:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734

Using
Code:
#define M2_SECTION_PROGMEM PROGMEM
would be the better definition. The purpose is to put as much as possible of the data into flash rom area.

When I modified the M2_SECTION_PROGMEM defintion to use PROGMEM
The errors in his sketch go away and the code compiled and seem to run ok.
Does the alternate progmem definition cause issues when the avr supplied PROGMEM attribute is used?


Quote
However, as far as I remember the GLCD API, the problem could be caused by the inclusion of the font files. Arial and SystemFont are also included within m2tklib. So including them again with
Code:
#include "fonts/allFonts.h"
will fail: I guess, because the font definition is in the .h file itself, so you get a double definition.

I don't think it should  fail
(haven't tried including a font header multiple times in different modules in quite some time though)
What I noticed in the past was that you potentially get duplicate copies of the font data
included in your final linked image as the data arrays are declared as "static".
(more about this below)

Quote
Fixing this error:
replace
Code:
#include "fonts/allFonts.h"
with
Code:
#include "fonts/fixednums15x31.h"
(whatever other fonts you need, do explicitly include them)
You must mean for the fonts that are not used by m2.
If he included say something that m2 includes, like say the System5x7 font,
I bet he's right back to the same as including "allFonts.h".

Quote
Also replace
Code:
GLCD.SelectFont(System5x7);
with
Code:
GLCD.SelectFont(m2_System5x7);
and do the same with the Arial font. As I said, System and Arial (and only these two!) are included already in m2tklib. See also here:
http://code.google.com/p/m2tklib/wiki/ghref#m2_gh_glcd_ubf

This does not seem like a good thing. It is mixing data definitions from one API and using it another API.
My suggestion is that if m2 must have its own font declarations, then m2 should have an API call to handle it
and not push its definition through the GLCD API.
i.e it seems like users should be calling m2_gh_glcd_set_font() rather than GLCD.SelectFont()

Quote
@Bill: If I could request an enhancement for GLCD: Please allow multiple inclusion of font files from different C/C++ sources.
Yep. I agree that this is currently a really bad deficiency.
It is a well known issue.
And while I totally ditest many things about the current font files and the actual font data
format, it is a major change to correct this. Michael and I discussed this at
great length when were working on v3. We went back and forth on correcting this a few times.
The problem is that as you have seen the data is declared in the .h file. It really should
be in .c files and then have .h file(s) to declare the references to them.
When it is only in header files, if you eliminate the static definition you get
duplicate names and the link fails. With the static you don't get errors and
everything will work but the actual font data ends up being included each time the header is included
in a module.
This is not particularly easy thing to correct and automate in the goofy Arduino IDE world,
and especially on non *nix platforms where you don't have much for real s/w tools available.
I did look at correcting this in v3, but eventually decided to abandon it due
to so many issues with the IDE and trying to keep it simple for Arduino users.
It is also somewhat tied into Thiele's FontCreator2 tool. It generates these font header files.
(It requires an updated FontCreator tool to generate new font files)
There are also some other things that I'd like to fix in the font data format as well
that would simplify the font rendering code.
(Thiele incorrectly shifted bits to the wrong end of a byte when the residual data is less than 8 bits in a byte)
But to make these any of these changes would have broken backward compatibility with v2
which was a very high priority
so Michael and I decided to defer any of those kinds of changes to a future major
update release.
It is definitely something on my list to get resolved as I've been burned by it as well,
especially when using normal Makefiles and C/C+ code vs the Arduino IDE environment.

Quote
@alexssey163: Another issue in the code is, that you do another init in the sensor_process.
This will init the GLCD very often and in parallel to m2tklib (which also does the GLCD.init)
It is simply not required and it might conflict with m2tklib (two parallel tasks will use the same resource). I also do not know what will happen if you do the init for GLCD multiple times.

While not necessary, calling the init routine multiple times should not be an issue.
I haven't done extensive testing on it, but the GLCD library is supposed to handle calling Init() multiple times.
There is no memory that is allocated that will be lost. I have tested it by looping hundreds of times to ensure that
it seems to work, but that is about all the testing I have done but I don't anticipate any issues with calling
the initialization routine more than once.

--- bill
Logged

Pages: 1 2 [3] 4   Go Up
Jump to: