Еще один секундомер с выводом на дисплей Nokia 1202
- Войдите на сайт для отправки комментариев
Втр, 19/08/2014 - 20:31
собрал с ребенком секундомер с выводом на дисплей 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 в текущее место из программной памяти