Еще один секундомер с выводом на дисплей Nokia 1202

Нет ответов
Iwan73
Offline
Зарегистрирован: 02.11.2013

собрал с ребенком секундомер с выводом на дисплей nokia 1202, 2 кнопки.

считает до 10 часов,потом обнуляется и заново. вот скетч

замечания и исправления только приветствуются, мы еще только учимся


#include <PCF8814.h>
#include <PCF8814_BIG_zifri_10x16.h>
#include <PCF8814_font.h>
#include <MsTimer2.h>

#define Buttons_1_pin   5
#define Buttons_2_pin   4
//#define Buttons_3_pin   19
#define Podsvetka  8

unsigned long startTime=0 ;                    // время старта секундомер
//--- переменные для кнопок ---
byte Buttons=0;                 // номер кнопки
byte Buttons_Flag_1=0;          // флаги состояния кнопок 
byte Buttons_Flag_2=0;
//byte Buttons_Flag_3=0;

byte  ind_ms=0;
byte  ind_Sec=0;
byte ind_Min=0;
byte ind_Chas=0;

PCF8814 Lcd(13,11,10,9);// LCD set SCLK: 13 pin, SDA: 11 pin, CS: 10pin, RESET: 9 pin

void setup() {
  pinMode(Podsvetka,OUTPUT);
  pinMode(Buttons_1_pin,  INPUT);      //инициализация 1 кнопки
  digitalWrite(Buttons_1_pin, HIGH);  //подключить подтягивающий резистор
  pinMode(Buttons_2_pin,   INPUT);    //инициализация 2 кнопки
  digitalWrite(Buttons_2_pin, HIGH);  //подключить подтягивающий резистор
  //pinMode(Buttons_3_pin,   INPUT);    //инициализация 3 кнопки
  // digitalWrite(Buttons_3_pin,HIGH);   //подключить подтягивающий резистор

  Lcd.Init();                          // инициализация дисплея
  digitalWrite(Podsvetka,HIGH);        // включаем подсветку дисплея
  Lcd.GotoXY(3,3);
  Lcd.Print("секундомер");            //выводим  надпись
  Lcd.GotoXY(4,6);
  Lcd.PrintF(PSTR("v - 1.00"));       //выводим  надпись
  // Serial.begin(9600);             // сериал монитор инициализация
  MsTimer2::set(200,Opros_Key);      //инициализация и установка прерываний от MsTimer2 для опроса кнопок   
  MsTimer2::start();                  //запустить таймер2 
}

void loop() {

  switch (Buttons)
  {
  case 1://если нажали кнопку 1
    if (Buttons_Flag_1==1)   // было 1 нажатие
    {
      digitalWrite(Podsvetka,LOW);   //выключаем подсветку дисплея
      // очищаем дисплей 
      Lcd.Clear();  
      digitalWrite(Podsvetka,HIGH); // включили включаем подсветку дисплея
      // очищаем переменные
      ind_Chas=0;
      ind_Min=0;
      ind_Sec=0;
      ind_ms=0;  
      // выводим индикацию  нули
      indikacya(ind_Sec,ind_ms,ind_Min,ind_Chas);   
    }
    if (Buttons_Flag_1==2)  // было второе нажатие
    {
      // выводим индикацию  
      indikacya(ind_Sec,ind_ms,ind_Min,ind_Chas);                             
    }                              
    break;
  case 2:  //если нажали кнопку 2
    if (Buttons_Flag_1==2) break; // если установлен флаг второго нажатия 1 кнопки то выходим
    // очищаем дисплей
    Lcd.Clear();
    //переходим в функцию
    Sekundomer(); 
    break;
    // case 3://если нажали кнопку 3
    //  break;
  default:
    break;
  }
}


//--- опрос кнопок ------------------
void Opros_Key() {
  Buttons=0;           // обнуляем
  static unsigned long millis_prev = 0;
  //если кнопка 1 нажата ...
  if(digitalRead(Buttons_1_pin)==LOW)
  {  
    if(millis()-150 > millis_prev)
    {
      Buttons=1;
    }
    millis_prev = millis(); 
    //--- перебор флагов --------------
    if(Buttons==1 && Buttons_Flag_1==2)
    {
      Buttons_Flag_1=0;
    }
    if(Buttons==1 && Buttons_Flag_1==1)
    {
      Buttons_Flag_1=2;
    }
    if(Buttons==1 && Buttons_Flag_1==0)
    {
      Buttons_Flag_1=1;
    } 
  }

  //если кнопка 2 нажата ...
  if(digitalRead(Buttons_2_pin)==LOW)
  { 
    if(millis()-150 > millis_prev)
    {
      Buttons=2;
    }
    millis_prev = millis(); 
    //--- перебор флагов --------------
    if(Buttons==2 && Buttons_Flag_2==2)
    {
      Buttons_Flag_2=0;
    }
    if(Buttons==2 && Buttons_Flag_2==1)
    {
      Buttons_Flag_2=2;
    }
    if(Buttons==2 && Buttons_Flag_2==0)
    {
      Buttons_Flag_2=1;
    }
  }
  /*
  //если кнопка 3 нажата ...
   if(digitalRead(Buttons_3_pin)==LOW)
   { 
   if(millis()-150 > millis_prev)
   {
   Buttons=3;
   }
   millis_prev = millis(); 
   //--- перебор флагов --------------
   if(Buttons==3 && Buttons_Flag_3==2)
   {
   Buttons_Flag_3=0;
   }
   if(Buttons==3 && Buttons_Flag_3==1)
   {
   Buttons_Flag_3=2;
   }
   if(Buttons==3 && Buttons_Flag_3==0)
   {
   Buttons_Flag_3=1;
   }
   }
   */
}

//--- секундомер ----------------------------------------
void  Sekundomer()
{
  startTime = millis();     // запоминаем время старта
  //------ выводим время ----------------------------------
  while(Buttons!=1 && Buttons_Flag_1!=2)   // пока не нажмем кнопку 1 и  флаг не равен 2 крутимся в цикле
  {
    Time();    
    indikacya(ind_Sec,ind_ms,ind_Min,ind_Chas) ;  // выводим индикацию  
  }
}
//----- расчет времени -----------------------
void Time()
{  
  int ms=0;              // милисекунды
  unsigned long Sec=0;   // секунды
  byte Min=0;            // минуты
  byte Chas=0;           // часы
  unsigned long elapsedTime =   millis() - startTime;  // получаем  прошедшее время со старта секундомера
  Sec=elapsedTime / 1000L;                             // получаем секунды
  ms=(int)(elapsedTime % 1000L);                       // получаем милисекунды
  if (Sec>59)                                          //вычисляем минуты
  {
    Min= Sec/60;                                       // в минуте 60 секунд
    Sec=Sec%60;                                        //остаток переписываем  в секунды
  }
  if (Min>59)                                           //вычисляем часы
  {
    Chas= Min/60;                                        // в часе 60 минут
    Min=Min%60;                                          //остаток переписываем  в минуты   
  } 
  // копируем в переменные для последующей обработки в индикации
  ind_Chas = Chas;
  ind_Min = Min;
  ind_Sec = byte(Sec);
  ind_ms = byte(ms);
}
//--- индикация -----------------------------------------------------
void indikacya(byte ind_Sec,byte ind_ms,byte ind_Min, byte ind_Chas)
{
  unsigned char Sm_msec_1=0;
  unsigned char Sm_msec_2=0;
  //секундомер секунды
  unsigned char Sm_sec_1=0;
  unsigned char Sm_sec_2=0;
  //секундомер минуты
  unsigned char Sm_min_1=0;
  unsigned char Sm_min_2=0;
  //секундомер час
  unsigned char Sm_chas_1=0; 
  //__ готовим к выводу секунды __
  if (ind_Sec<10)      // если секунд меньше 10
  {
    Sm_sec_1=0;    // первая цифра 0
    Sm_sec_2=ind_Sec;  // вторая цифра секунды
  }
  if (ind_Sec>=10)     // если секунд больше или равно 10
  {
    Sm_sec_1=ind_Sec/10; // первая цифра - делим на 10
    Sm_sec_2=ind_Sec%10; // вторая цифра  - остаток
  }
  //__ готовим к выводу минуты __
  if (ind_Min<10)  // если минут меньше 10
  {
    Sm_min_1= 0;      // первая цифра 0
    Sm_min_2= ind_Min;    // вторая цифра минуты
  }
  if ( ind_Min>=10)        // если минут больше или равно 10
  {
    Sm_min_1= ind_Min/10;  // первая цифра - делим на 10
    Sm_min_2= ind_Min%10;  // вторая цифра  - остаток
  }
  //__ готовим к выводу милисекунды __
  if (ind_ms>=10)  // если милисекунд больше или равно 10
  {
    Sm_msec_1= 0; // первая цифра 0
    Sm_msec_2= ind_ms/10;// вторая цифра десятки милисекунд(у нас выводится первые 2 цифры из 3)
  }
  if ( ind_ms>=100)  // если милисекунд больше или равно 100
  {
    Sm_msec_1= ind_ms/100;// первая цифра сотни милисекунд
    byte count=ind_ms%100; // перезаписываем остаток
    Sm_msec_2= count/10;// вторая цифра десятки милисекунд
  }
  //___ готовим к выводу часы _____
  Sm_chas_1=ind_Chas;                                       
  if ( ind_Chas==10) // если часы равны 10(значение цифры вывода не превышает 9)
  {
    // обнуляем все переменные индикации времени
    ind_ms=0;
    ind_Sec=0;
    ind_Min=0;
    ind_Chas=0; 
  }
  // выводим на дисплей
  Lcd.char_10X16(Sm_chas_1,1,30);   // выводим значение цифры час
  // разделитель (двоеточие) между час/минуты
  Lcd.Rect (13,28, 14, 29, FILL_ON, PIXEL_ON);// точка 
  Lcd.Rect (13,33, 14, 34, FILL_ON, PIXEL_ON);//точка  
  Lcd.char_10X16(Sm_min_1,17,30);            //минуты
  Lcd.char_10X16(Sm_min_2,29,30);   //минуты
  // разделитель (двоеточие) между  минуты/секунды
  Lcd.Rect (41,28, 42, 29, FILL_ON, PIXEL_ON);// точка 
  Lcd.Rect (41,33, 42, 34, FILL_ON, PIXEL_ON);//точка  
  Lcd.char_10X16(Sm_sec_1,45,30); //секунды
  Lcd.char_10X16(Sm_sec_2,56,30);   //секунды
  // разделитель (двоеточие) между секунды/милисекунды
  Lcd.Rect (68,28, 69, 29, FILL_ON, PIXEL_ON);// точка 
  Lcd.Rect (68,33, 69, 34, FILL_ON, PIXEL_ON);//точка 
  Lcd.char_10X16(Sm_msec_1,72,30);   //милисекунды
  Lcd.char_10X16(Sm_msec_2,83,30);   //милисекунды
}

файл PCF8814_BIG_zifri_10x16.h

#include <avr/pgmspace.h>
 //****** шрифт 10х16 в програмной памяти ****************************
const unsigned char font10x16[26][20] PROGMEM={ 

{0x7E, 0x3D, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3D, 0x7E,
  0x7F, 0xBE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBE, 0x7F} //  0
,{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE} //  1
,{0x00, 0x81, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E,
  0x7F, 0xBE, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0x80, 0x00} //  2
,{0x00, 0x81, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E,
  0x00, 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F} //  3
,{0x7E, 0xBC, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBC, 0x7E,
  0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x3E, 0x7F} // 4
,{0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x81, 0x00,
  0x00, 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F} //  5
,{0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x81, 0x00,
  0x7F, 0xBE, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F} //  6
,{0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3D, 0x7E,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x7F} //  7
,{0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E,
  0x7F, 0xBE, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F} //  8
,{0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E,
  0x00, 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F} //  9
,{0x00, 0x00, 0x00, 0x00, 0x00} //10 0 (space)
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 11 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 12 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 13 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 14 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 15 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 16 &
,{0x06, 0x09, 0x06, 0xF0, 0xF8, 0x0C, 0x0C, 0x0C, 0x0C, 0x18,
  0x00, 0x00, 0x00, 0x07, 0x0F, 0x18, 0x18, 0x18, 0x18, 0x0C} // 17 ' значёк для термометра 'C
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 18 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 19 )
,{0x00, 0x00, 0x00, 0x00, 0x00} // 20 *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 21 +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 22 ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 23 -
,{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0C, 0x1A, 0x16, 0x0C, 0x00, 0x00, 0x00} // 24 .
,{0x20, 0x10, 0x08, 0x04, 0x02} //25 2f /
};

в файле PCF8814.cpp добавлена функция

// Вывод символа 10x16 в текущее место  из программной памяти

 void PCF8814::char_10X16(char c,char x, char y) // вывод символа c-символ,x,y- координата
{
	unsigned char i=0;
	unsigned char j=0;
	unsigned char z=0;
	for ( j= 0; j < 2; j++ ){
    //GotoXY(x,y);
	GotoXY_pix(x,y);
	for ( i = z; i <z+10; i++ )
            {
            SendByte(DATA_LCD_MODE,pgm_read_byte(&(font10x16[c][i])));
            }
	z=z+10;	
	y=y+8;
    //y++;
}
}

в файле PCF8814.h добавлено

void char_10X16(char c,char x, char y);      // Вывод символа 10x16 в текущее место из программной памяти