вопрос про программированию lcd

crecker
Offline
Зарегистрирован: 15.12.2013

Всем привет, 

такой вопрос. Вращаю программой мотор, записываю на SD каждые  8 секунд количество циклов. Хочу,чтобы одновременно их можно  было видеть на дисплее. Скетч такой. x это количество циклов. Серийный порт показывает правильное значение x, а дисплей всегда 0, иногда 2 или "sleep".  Что не  правильно в скетче? 

 

#include <LiquidCrystal_I2C.h> 
#include <TimerOne.h>
#include <Wire.h>  
#include <SD.h>
int sensor=2;//
int motor=3;
volatile unsigned long x = 0;  
LiquidCrystal_I2C lcd (0x20,16 ,2);// 
int l_c_d;
int duty_cycle=200;
#define document "mesure.txt"
int l_c_d; 


void setup()
{
  
  lcd.init();                      
  lcd.backlight(); 
  pinMode(sensor, INPUT); // 
  pinMode(motor,OUTPUT);
  analogWrite(motor,duty_cycle);

  attachInterrupt(0, puls, RISING);
  Serial.begin(9600);
  Serial.println("SD-Card initialized.");
  
  Timer1.initialize(5000000); //  
  Timer1.attachInterrupt(mesure); //  
  
}

void _display()
{

switch (l_c_d)
{
case 0:

  lcd.setCursor(0,1);
  lcd.print(x); 
break;
case 1:

 lcd.setCursor(0,1);
 lcd.print("Sleep"); 
break;
}
}

void  mesure () // 
{
  Serial.print (x);

  
  File myFile = SD.open(document, FILE_WRITE); // 

  if (myFile)   // 
  {
    l_c_d = 1;
    myFile.print (x);
    myFile.close();
    //lcd.print (x);
  }
  else
  {
    l_c_d = 0;
     Serial.println("Error open mesure.txt");
 
  }
}

void loop()
{
  _display();
}

 void puls()
 {
   
   x++;
 }                                  

 

kholonkin
Offline
Зарегистрирован: 14.10.2013

может в порт отправить в  _display()

чтб видеть, какое значение прилетает в эту функцию

kholonkin
Offline
Зарегистрирован: 14.10.2013

я слегка деревянный, не пойму где и как вызывается puls() и mesure ()?

это так, отвелеченный вопрос

crecker
Offline
Зарегистрирован: 15.12.2013

нашел другое решение. 

 

if (millis()-lasttime>=8000)
        { lasttime+=8000;
           mesure();

Теперь значения серийного порта и lcd совпадают

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Ворос.

В библиотеке к lcd есть следующая группа операций:





#if FONT_WIDTH <= 8
  uint8_t data, mask;
#elif FONT_WIDTH <= 16
  uint16_t data, mask; 
#elif FONT_WIDTH <= 32
  uint32_t data, mask;
#endif

при этом, если FONT_WIDTH обьявляется так:





# define FONT_WIDTH  (10)

всё работает. Но если то же значетие читаю и вывожу из массива:





FONT_WIDTH = pgm_read_byte_near(&font_PGM[2]); //0x0A,  10 - ширина

lcd "пустой". Естественно обьявляя FONT_WIDTH как обычную пепеменную.

Причём если подставляю только туда, где результат - истина (#elif FONT_WIDTH <= 16), то тоже работает. Значения в обеих случаях одинаковое, проверял, и там 10 и там. Что я упускаю?

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Добавил переменную чтоб посмотреть какое условие выполняется



#if FONT_WIDTH <= 8
   dis = 8; uint8_t data, mask;
#elif FONT_WIDTH <= 16
  dis = 16; uint16_t data, mask; 
#elif FONT_WIDTH <= 32
  dis = 32; uint32_t data, mask;
#endif

затем печатаю в порт FONT_WIDTH и dis. получается 10 и 8 соответственно. Как так?

FONT_WIDTH <= 16, dis должна быть 16.

если дефайню FONT_WIDTH, то  FONT_WIDTH = 10 ...dis = 16 всё как надо

а если приравниваю к 10,      то  FONT_WIDTH = 10 ...dis = 8, так же не может быть.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

   FONT_WIDTH ни разу не переменная, это дирректива компилятора. Грубо говоря команда компилятору так или иначе сгенерить код. Влияет на код только в процессе компиляции, при работе программы никак не может иметь какое либо воздействие на уже откомпилированный код. Вполне вероятно, что можно объвить переменную с таким же именем, но это будет совсем другая переменная. Думаю, что в вашем случае библиотека написанна так, что если ширина шрифта до 8 пикселей, буферы спрайтов объявляются в библиотеке как 8 бит в длинну (в один байт), a если больше 8 то как двухбайтные слова. Если вы хотите использовать шрифты с различной шириной нужно исправлять библиотеку :-)

hugoboss317
Offline
Зарегистрирован: 21.03.2013

Я как раз этим и занимаюсь, редактирую бибу. Так уж она была написана, что шрифт выбирается один и можно менять только размер. Подобавлял некоторые функции, некоторые подкорректил, дошёл до шрифта... в принципе добавил функцию выбора шрифта, он выбирается, в первых семи байтах инфа по шрифту (ширина, высота и т.п.) - читается, выполняется. Например было:







# define FONT_START     (0x20)
# define FONT_HEIGHT   (16)

чтоб не корректить всю бибу, я это закоментировал и назвал так же переменные, и инициализировал их значениями из шрифта, и всё нормально. Никак не вкурю что не так с #if. если меняю на if (не #if), компелятор просто не видет dis = 8; uint8_t data, mask; и не компелирует. А объявить раньше я не могу т.к. размер будет варироваться.

Мне не ясно почему условие 



#if FONT_WIDTH <= 8

ложь, и выполняеися

 

Всё, я понял что к чему, спасибо что подтолкнули на мысль.