Хронограф : измеритель скорости пули. От простого к сложному

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

расстояние между датчиками, частота ардуины

Helgi000
Offline
Зарегистрирован: 11.03.2015

А можно под редактировать код чтобы можно было выбрать вес пули до сотой грамма. А то в страйкболом используются пули с таким весом.

Например 0.23, 0.25, 0,28, 0.32

И еще о индикации заряда батареи, как понимаю она еще в разработке или решили не реализовывать ее?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ну если скажешь куда вставить индикацию зарядки батареи, а лучше дорисуй в пайнте можно и сделать))

вот интересно какой максимальный вес пули?

a5021
Offline
Зарегистрирован: 07.07.2013

Расстояние там было 8 см? При частоте камня в 24мгц, длительность одного такта = 41.7 нс. Если какая-то волшебная пуля пройдет за это время 8см, то ее скорость должна будет составлять около 2 тысяч километров в секунду (1920, если точно). Двигаясь с подобной скоростью, пуля длиной три миллиметра перекроет датчик на 1.56 наносекунды. Датчики должны обеспечивать отклик на частотах до 0.64 гГц. В принципе, есть ультрабыстрые фотодиоды, которые вполне могли бы работать в этой полосе, но сигнал с них надо вытягивать до логического уровня, что потребует весьма  нетривиальных усилий. В этой связи мне кажется, что со стороны датчиков ограничения возникнут гораздо раньше, чем тактовой атмеги перестанет хватать.

Helgi000
Offline
Зарегистрирован: 11.03.2015

jeka_tm пишет:

вот интересно какой максимальный вес пули?

Минимальный 0.1 но японцы в основном для своих пистолетов продают 0.12 (скорость выстрела в районе 68-80 М/с)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

a5021 у меня в датчиках 70мм

а ограниченая раньше возникнут. но никто не проверял от чего быстрее. частоты камняне хватало, или уже датчики не успевали. для этого нужна наверно воздушка с накачкой, чтобы можно было проверить при разных скоростях

Helgi000 я спрашивал про максимальный

Helgi000
Offline
Зарегистрирован: 11.03.2015

Для пневматики 4.5 самые тяжелые это юджин 1.12 грамма, дла охотничьей пневматики 9мм - самый тяжелый 9.5 грамм.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

всего то. ладно как время будет переделаю. там еще все равно для расчета энергии нужно дописывать

Balaganoff
Offline
Зарегистрирован: 12.07.2011

Модераторы ! Отпишите меня от уведомлений в этой теме ! Никакие кнопки не помогают ))

Пардон за ОФФТОП

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

Потестил наконец хронометр. пистолет пм 

a5021
Offline
Зарегистрирован: 07.07.2013

Убило кого-нибудь ? :)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

нет))

a5021
Offline
Зарегистрирован: 07.07.2013

У вас обнаружились опасные конкуренты. :)

видео

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ага. страшно))) интересно как работает. белые пластины отражатель который чем то засвечивают, возможно ик диапазон

так как отследить точку на таком расстоянии обычными фотодиодами нереально, значит используется камера, 1*96 пикселей например, или выше разрешение. но она должна быть высокоскоростная, да и процессор обрабатывающий тоже

но это мое предположение

a5021
Offline
Зарегистрирован: 07.07.2013

Как я понял, это все же инфракрасные зеркальца. Заявлены измеряемые скорости до 3 тыс. м. / сек.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

серьезный аппарат. стоит наверно тоже соответственно

да и у многих ли есть огнестрел. да и зачем его постоянно обмерять

вот понимаю что гаусс расчету точному не поддается, все равно нужно эксперименты ставить чтобы добится лучших результатов, а тут без хронометра не обойтись

a5021
Offline
Зарегистрирован: 07.07.2013

А я так думаю, что описанная в этой ветке конструкция не особо и хуже.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

этот хронометр  такие скорости не сможет измерить. нужно ставить более быстрый процессор, да и датчики такие скорее всего не успеют

но для любителей пневматики и гауссов подходит))

a5021
Offline
Зарегистрирован: 07.07.2013

Про датчики и процессор я уже здесь умствовал, т.ч. с этим, как раз, все понятно. Важно, что сам принцип и примененный подход работают.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ага)

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

А можно выложить исхлодник рисующий управляющий меню ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

a5021 пишет:

Как я понял, это все же инфракрасные зеркальца. Заявлены измеряемые скорости до 3 тыс. м. / сек.

есть прорези ( две ) для ИК-барьеров , крылья - не держатели антенн , а отражатели
усы "антенн" - не антенны , а держатели отражателей

...и быстрый процессор

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

я думаю это обычные конденсаторы (усы эти),может в составе контура.

под углом они просто для удобства

а дальше стоят все теже два компаратора  (пиковых детектора) всё.

ИК и отражатель  тоже версия нормальная, даже более реальная

но я думая в щелях СВЧ излучатель\приёмник  на 1 транзисторе  а парус отражатель

при проходе  свч контур меняет параметры,а дальше теже компараторы

хотя для этого варианта не нужен отражатель,от пули    в любом случае изменится параметр СВЧ контура

 

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

....... Включает в себя хронограф, ИК светодиодная комплект ........

....... Более высокая точность была достигнута с помощью высокого процессор скорость 48 МГц ........

Для измерения скорости пули нужно стрелять сквозь треугольные рабочие зоны хронографа. Под рабочими зонами прибора расположены фотодатчики, которые определяют точное время пролета пули. Caldwell BALLISTIC PRECISION определяет скорости пуль в диапазоне от 1,5 до 3 047 м/с с погрешностью ±0,25%. Возможно также проводить измерения в фут/с. Такая высокая точность измерений достигается использованием в хронографе высокоскоростного процессора 48 МГц.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

selevo пишет:

А можно выложить исхлодник рисующий управляющий меню ?

это как?

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

jeka_tm пишет:

selevo пишет:

А можно выложить исхлодник рисующий управляющий меню ?

это как?

ну как, там же   есть в программе модуль отображения меню, библиотека работы с дислпеем...

вот   этот кусок и надо.

Кусок ккоторый делает вот это:

http://arduino.ru/sites/default/files/resize/u4939/wp_20150330_22_57_54_...

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
//========================================================================
  //                         Управление первой кнопкой
  //========================================================================
  if(digitalRead(pin_1)==0 && digitalRead(pin_2)==1){
    delay(50);
    if(digitalRead(pin_1)==0 && digitalRead(pin_2)==1){
      test=0;
      switch (display_N) {
      case 0: // если главный экран
        display_N=2;
        Window_2(display_2_menu);
        delay(200);
        break;

      case 1: // если экран статистики
        display_N=0;
        Window_0();
        delay(200);
        break;

      case 2: // если меню настроек
        display_2_menu++;
        if(display_2_menu==5) display_2_menu=0;
        Window_2(display_2_menu);
        delay(200);
        break;

      case 3: // если экран калибровки
        display_3_menu++;
        if(display_3_menu==3) display_3_menu=0;
        Window_3(display_3_menu);
        delay(200);
        break;

      case 4: // если настройка масса
        display_4_menu++;
        if(display_4_menu==3) display_4_menu=0;
        Window_4(display_4_menu);
        delay(200);
        break;

      }
    }
  }

  //========================================================================
  //                         Управление второй кнопкой
  //========================================================================
  if(digitalRead(pin_2)==0 && digitalRead(pin_1)==1){
    delay(50);
    if(digitalRead(pin_2)==0 && digitalRead(pin_1)==1){
      test=0;
      switch (display_N) {
      case 0: 
        first(); 
        break; 
      case 1: 
        Stat();
        break;  
      case 2:
        Settints();
        break;
      case 3:
        Calibr();
        break;
      case 4:
        massa();
        break;
      }
    }
  }

  
  if(test) Test();
}




//========================================================================
//                              Главный экран
//========================================================================
void first(){
  display_N=1;
  Window_1();
}

//========================================================================
//                             Экран статистики
//========================================================================
void Stat(){
  for(byte i=0;i<10;i++){
    DATA [i]=0;
  }
  middle=0;
  Window_1();
}

//========================================================================
//                             Экран настроек
//========================================================================
void Settints(){
  switch (display_2_menu) {

  case 0: // переходим в калибровку
    display_N=3;
    Window_3(display_3_menu);
    delay(200);
    break;

  case 1: // Настройка массы
    display_N=4;
    Window_4(display_4_menu);
    delay(200);
    break;

  case 2: // Скорость/энергия
    energi=!energi;
    EEPROM.write(adr_energi, energi);
    Window_2(display_2_menu);
    break;

  case 3: // Инвертирование
    color=!color;
    EEPROM.write(adr_color, color);
    Window_2(display_2_menu);
    break;

  case 4: // Назад
    display_N=0;
    display_2_menu=0;
    Window_0();
    delay(200);
    break;
  }
}

//========================================================================
//                             Экран калибровки
//========================================================================
void Calibr(){
  switch (display_3_menu) {
  case 0:
    if(calibration<254) calibration++;
    Window_3(display_3_menu);
    break;

  case 1:
    if(calibration>0) calibration--;
    Window_3(display_3_menu);
    break;

  case 2:
    display_N=2;
    Window_2(display_2_menu);
    display_3_menu=0;
    delay(200);
    EEPROM.write(adr_calibr, calibration);
    break;
  }
}

//========================================================================
//                            Управление массой
//========================================================================
void massa(){
  switch (display_4_menu) {
  case 0:
    if(mass<250) mass++;
    Window_4(display_4_menu);
    break;

  case 1:
    if(mass>0) mass--;
    Window_4(display_4_menu);
    break;

  case 2:
    display_N=2;
    Window_2(display_2_menu);
    display_4_menu=0;
    delay(200);
    EEPROM.write(adr_mass, mass);
    break;
  }
}

//========================================================================
//                              Экран настроек
//========================================================================
void Window_2(byte i){
  fillScreen(!color);
  byte n=1;
  n=n<<i;
  Menu(  1, myStrings[0], n&1);
  Menu( 12, myStrings[1], n&2);

  if(energi) Menu( 23, myStrings[3], n&4);
  else       Menu( 23, myStrings[2], n&4);

  Menu( 33, myStrings[4], n&8);
  Menu( 44, myStrings[5], n&16);
  Update();
}

я хз разберешься или нет. я объяснять не буду

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

а сама библиотека работы с дисплеем  1202 ?

самописная или чья-то готовая  или от  n1100  ?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

самописная, часть кода бралась из библиотек

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

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

Не нашёл тут как личные сообщения отправлять...

 

а можно как-то  договориться  сюда (на форум) выложить полностью модуль  работы с менюхами и экраном ?

Думаю людям будет полезно, ускорятся реализации народных поделок

экран 1202 довольно хорош этот - дёшев,доступен и припаивается хорошо.

можно просто при нажатии на меню  загорится светодиод на пине том или ином.

а один из пунктов переход на другой экран меню

ну или просто вырезать из вашего проекта если совсем нет времени и желания.

или за денежку как-то договориться  оформить модуль

можно почтой пообщаться: selevo@mail.ru

 

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да вот весь проект. В том виде как есть, даже с разбивкой по файлам. Разбирайся

Speed_v5.9.8

#include <avr/pgmspace.h>
#include <EEPROM.h>
#define pgm     pgm_read_byte

#define CS      7
#define Data    6
#define Clock   5

#define LCD_X        96
#define LCD_Y        68
#define LCD_String    9
#define swap(a, b) { int t = a; a = b; b = t; }

#define SetYAddr   0xB0
#define SetXAddr4  0x00
#define SetXAddr3  0x10

#define LCD_D         1
#define LCD_C         0

#define pin_1        A2
#define pin_2        A4

#define W   94
#define H   66

#define adr_first   0
#define adr_calibr  2
#define adr_mass    4
#define adr_energi  6
#define adr_color   8
#define adr_safe   10


volatile unsigned long time1 = 0;        //Время срабатывания первого датчика
volatile unsigned long time2 = 0;        //Время срабатывания второго
volatile unsigned long skorost = 0;       //временное число
volatile unsigned long factor = 10000;   //Множитель

volatile bool flag1 = 1;
volatile bool flag2 = 1;

long  middle = 0;
byte  n=0;

byte S = 1;
byte display_N = 0;
byte display_2_menu = 0;
byte display_3_menu = 0;
byte display_4_menu = 0;
byte display_5_menu = 0;

byte calibration;
byte mass;
byte energi;
byte color;

byte test=0;


char* myStrings[8]={ "Калибровка", "Масса", "Скорость", "Энергия", "Инверсия", "Назад",
  "+", "-"};

int DATA [10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  
byte LCD_RAM[LCD_X*LCD_String];

void Start(){          // 1 прерывание
  if(flag1==1){
    time1=micros();
    flag1=0;
  }
}
void End(){          // 2 прерывание
  if(flag2==1){
    time2=micros();
    flag2=0;
  }
}

Font

static const char font[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00 ,  // 0x20   space
  0x00, 0x00, 0x5f, 0x00, 0x00 ,  // 0x21   !
  0x00, 0x07, 0x00, 0x07, 0x00 ,  // 0x22   "
  0x14, 0x7f, 0x14, 0x7f, 0x14 ,  // 0x23   #
  0x24, 0x2a, 0x7f, 0x2a, 0x12 ,  // 0x24   $
  0x23, 0x13, 0x08, 0x64, 0x62 ,  // 0x25   %
  0x36, 0x49, 0x55, 0x22, 0x50 ,  // 0x26   &
  0x00, 0x05, 0x03, 0x00, 0x00 ,  // 0x27   '
  0x00, 0x1c, 0x22, 0x41, 0x00 ,  // 0x28   (
  0x00, 0x41, 0x22, 0x1c, 0x00 ,  // 0x29   )
  0x14, 0x08, 0x3e, 0x08, 0x14 ,  // 0x2a   *
  0x08, 0x08, 0x3e, 0x08, 0x08 ,  // 0x2b   +
  0x00, 0x50, 0x30, 0x00, 0x00 ,  // 0x2c   ,
  0x08, 0x08, 0x08, 0x08, 0x08 ,  // 0x2d   -
  0x00, 0x60, 0x60, 0x00, 0x00 ,  // 0x2e   .
  0x20, 0x10, 0x08, 0x04, 0x02 ,  // 0x2f   /
  0x3e, 0x51, 0x49, 0x45, 0x3e ,  // 0x30   0
  0x00, 0x42, 0x7f, 0x40, 0x00 ,  // 0x31   1
  0x42, 0x61, 0x51, 0x49, 0x46 ,  // 0x32   2
  0x21, 0x41, 0x45, 0x4b, 0x31 ,  // 0x33   3
  0x18, 0x14, 0x12, 0x7f, 0x10 ,  // 0x34   4
  0x27, 0x45, 0x45, 0x45, 0x39 ,  // 0x35   5
  0x3c, 0x4a, 0x49, 0x49, 0x30 ,  // 0x36   6
  0x01, 0x71, 0x09, 0x05, 0x03 ,  // 0x37   7
  0x36, 0x49, 0x49, 0x49, 0x36 ,  // 0x38   8
  0x06, 0x49, 0x49, 0x29, 0x1e ,  // 0x39   9
  0x00, 0x36, 0x36, 0x00, 0x00 ,  // 0x3a   :
  0x00, 0x56, 0x36, 0x00, 0x00 ,  // 0x3b   ;
  0x08, 0x14, 0x22, 0x41, 0x00 ,  // 0x3c   <
  0x14, 0x14, 0x14, 0x14, 0x14 ,  // 0x3d   =
  0x00, 0x41, 0x22, 0x14, 0x08 ,  // 0x3e   >
  0x02, 0x01, 0x51, 0x09, 0x06 ,  // 0x3f   ?
  0x32, 0x49, 0x79, 0x41, 0x3e ,  // 0x40   @
  0x7e, 0x11, 0x11, 0x11, 0x7e ,  // 0x41   A
  0x7f, 0x49, 0x49, 0x49, 0x36 ,  // 0x42   B
  0x3e, 0x41, 0x41, 0x41, 0x22 ,  // 0x43   C
  0x7f, 0x41, 0x41, 0x22, 0x1c ,  // 0x44   D
  0x7f, 0x49, 0x49, 0x49, 0x41 ,  // 0x45   E
  0x7f, 0x09, 0x09, 0x09, 0x01 ,  // 0x46   F
  0x3e, 0x41, 0x49, 0x49, 0x7a ,  // 0x47   G
  0x7f, 0x08, 0x08, 0x08, 0x7f ,  // 0x48   H
  0x00, 0x41, 0x7f, 0x41, 0x00 ,  // 0x49   I
  0x20, 0x40, 0x41, 0x3f, 0x01 ,  // 0x4a   J
  0x7f, 0x08, 0x14, 0x22, 0x41 ,  // 0x4b   K
  0x7f, 0x40, 0x40, 0x40, 0x40 ,  // 0x4c   L
  0x7f, 0x02, 0x0c, 0x02, 0x7f ,  // 0x4d   M
  0x7f, 0x04, 0x08, 0x10, 0x7f ,  // 0x4e   N
  0x3e, 0x41, 0x41, 0x41, 0x3e ,  // 0x4f   O
  0x7f, 0x09, 0x09, 0x09, 0x06 ,  // 0x50   P
  0x3e, 0x41, 0x51, 0x21, 0x5e ,  // 0x51   Q
  0x7f, 0x09, 0x19, 0x29, 0x46 ,  // 0x52   R
  0x46, 0x49, 0x49, 0x49, 0x31 ,  // 0x53   S
  0x01, 0x01, 0x7f, 0x01, 0x01 ,  // 0x54   T
  0x3f, 0x40, 0x40, 0x40, 0x3f ,  // 0x55   U
  0x1f, 0x20, 0x40, 0x20, 0x1f ,  // 0x56   V
  0x3f, 0x40, 0x38, 0x40, 0x3f ,  // 0x57   W
  0x63, 0x14, 0x08, 0x14, 0x63 ,  // 0x58   X
  0x07, 0x08, 0x70, 0x08, 0x07 ,  // 0x59   Y
  0x61, 0x51, 0x49, 0x45, 0x43 ,  // 0x5a   Z
  0x00, 0x7f, 0x41, 0x41, 0x00 ,  // 0x5b   [
  0x02, 0x04, 0x08, 0x10, 0x20 ,  // 0x5c   backslash 
  0x00, 0x41, 0x41, 0x7f, 0x00 ,  // 0x5d   ]
  0x04, 0x02, 0x01, 0x02, 0x04 ,  // 0x5e   ^
  0x40, 0x40, 0x40, 0x40, 0x40 ,  // 0x5f   _
  0x00, 0x01, 0x02, 0x04, 0x00 ,  // 0x60   `
  0x20, 0x54, 0x54, 0x54, 0x78 ,  // 0x61   a
  0x7f, 0x48, 0x44, 0x44, 0x38 ,  // 0x62   b
  0x38, 0x44, 0x44, 0x44, 0x20 ,  // 0x63   c
  0x38, 0x44, 0x44, 0x48, 0x7f ,  // 0x64   d
  0x38, 0x54, 0x54, 0x54, 0x18 ,  // 0x65   e
  0x08, 0x7e, 0x09, 0x01, 0x02 ,  // 0x66   f
  0x0c, 0x52, 0x52, 0x52, 0x3e ,  // 0x67   g
  0x7f, 0x08, 0x04, 0x04, 0x78 ,  // 0x68   h
  0x00, 0x44, 0x7d, 0x40, 0x00 ,  // 0x69   i
  0x20, 0x40, 0x44, 0x3d, 0x00 ,  // 0x6a   j 
  0x7f, 0x10, 0x28, 0x44, 0x00 ,  // 0x6b   k
  0x00, 0x41, 0x7f, 0x40, 0x00 ,  // 0x6c   l
  0x7c, 0x04, 0x18, 0x04, 0x78 ,  // 0x6d   m
  0x7c, 0x08, 0x04, 0x04, 0x78 ,  // 0x6e   n
  0x38, 0x44, 0x44, 0x44, 0x38 ,  // 0x6f   o
  0x7c, 0x14, 0x14, 0x14, 0x08 ,  // 0x70   p
  0x08, 0x14, 0x14, 0x18, 0x7c ,  // 0x71   q
  0x7c, 0x08, 0x04, 0x04, 0x08 ,  // 0x72   r
  0x48, 0x54, 0x54, 0x54, 0x20 ,  // 0x73   s
  0x04, 0x3f, 0x44, 0x40, 0x20 ,  // 0x74   t
  0x3c, 0x40, 0x40, 0x20, 0x7c ,  // 0x75   u
  0x1c, 0x20, 0x40, 0x20, 0x1c ,  // 0x76   v
  0x3c, 0x40, 0x30, 0x40, 0x3c ,  // 0x77   w
  0x44, 0x28, 0x10, 0x28, 0x44 ,  // 0x78   x
  0x0c, 0x50, 0x50, 0x50, 0x3c ,  // 0x79   y
  0x44, 0x64, 0x54, 0x4c, 0x44 ,  // 0x7a   z
  0x00, 0x08, 0x36, 0x41, 0x00 ,  // 0x7b   {
  0x00, 0x00, 0x7f, 0x00, 0x00 ,  // 0x7c   |
  0x00, 0x41, 0x36, 0x08, 0x00 ,  // 0x7d   }
  0x10, 0x08, 0x08, 0x10, 0x08 ,  // 0x7e   ~
  0x00, 0x00, 0x00, 0x00, 0x00 ,  // 0x7f
  0x7e, 0x11, 0x11, 0x11, 0x7e ,  // 0x80   A  // Русские символы
  0x7f, 0x49, 0x49, 0x49, 0x33 ,  // 0x81   Б
  0x7f, 0x49, 0x49, 0x49, 0x36 ,  // 0x82   В  
  0x7f, 0x01, 0x01, 0x01, 0x03 ,  // 0x83   Г  
  0xe0, 0x51, 0x4f, 0x41, 0xff ,  // 0x84   Д  
  0x7f, 0x49, 0x49, 0x49, 0x41 ,  // 0x85   E  
  0x77, 0x08, 0x7f, 0x08, 0x77 ,  // 0x86   Ж  
  0x41, 0x49, 0x49, 0x49, 0x36 ,  // 0x87   З  
  0x7f, 0x10, 0x08, 0x04, 0x7f ,  // 0x88   И  
  0x7c, 0x21, 0x12, 0x09, 0x7c ,  // 0x89   Й  
  0x7f, 0x08, 0x14, 0x22, 0x41 ,  // 0x8A   K  
  0x20, 0x41, 0x3f, 0x01, 0x7f ,  // 0x8B   Л  
  0x7f, 0x02, 0x0c, 0x02, 0x7f ,  // 0x8C   M  
  0x7f, 0x08, 0x08, 0x08, 0x7f ,  // 0x8D   H  
  0x3e, 0x41, 0x41, 0x41, 0x3e ,  // 0x8E   O  
  0x7f, 0x01, 0x01, 0x01, 0x7f ,  // 0x8F   П  
  0x7f, 0x09, 0x09, 0x09, 0x06 ,  // 0x90   P  
  0x3e, 0x41, 0x41, 0x41, 0x22 ,  // 0x91   C
  0x01, 0x01, 0x7f, 0x01, 0x01 ,  // 0x92   T
  0x47, 0x28, 0x10, 0x08, 0x07 ,  // 0x93   У
  0x1c, 0x22, 0x7f, 0x22, 0x1c ,  // 0x94   Ф
  0x63, 0x14, 0x08, 0x14, 0x63 ,  // 0x95   X
  0x7f, 0x40, 0x40, 0x40, 0xff ,  // 0x96   Ц
  0x07, 0x08, 0x08, 0x08, 0x7f ,  // 0x97   Ч
  0x7f, 0x40, 0x7f, 0x40, 0x7f ,  // 0x98   Ш
  0x7f, 0x40, 0x7f, 0x40, 0xff ,  // 0x99   Щ
  0x01, 0x7f, 0x48, 0x48, 0x30 ,  // 0x9A   Ъ
  0x7f, 0x48, 0x30, 0x00, 0x7f ,  // 0x9B   Ы
  0x00, 0x7f, 0x48, 0x48, 0x30 ,  // 0x9C   Э
  0x22, 0x41, 0x49, 0x49, 0x3e ,  // 0x9D   Ь
  0x7f, 0x08, 0x3e, 0x41, 0x3e ,  // 0x9E   Ю
  0x46, 0x29, 0x19, 0x09, 0x7f ,  // 0x9F   Я
  0x20, 0x54, 0x54, 0x54, 0x78 ,  // 0xA0   a
  0x3c, 0x4a, 0x4a, 0x49, 0x31 ,  // 0xA1   б
  0x7c, 0x54, 0x54, 0x54, 0x28 ,  // 0xA2   в
  0x7c, 0x04, 0x04, 0x04, 0x0c ,  // 0xA3   г
  0xe0, 0x54, 0x4c, 0x44, 0xfc ,  // 0xA4   д
  0x38, 0x54, 0x54, 0x54, 0x18 ,  // 0xA5   e
  0x6c, 0x10, 0x7c, 0x10, 0x6c ,  // 0xA6   ж
  0x44, 0x44, 0x54, 0x54, 0x28 ,  // 0xA7   з
  0x7c, 0x20, 0x10, 0x08, 0x7c ,  // 0xA8   и
  0x7c, 0x41, 0x22, 0x11, 0x7c ,  // 0xA9   й
  0x7c, 0x10, 0x10, 0x28, 0x44 ,  // 0xAA   к
  0x20, 0x44, 0x3c, 0x04, 0x7c ,  // 0xAB   л
  0x7c, 0x08, 0x10, 0x08, 0x7c ,  // 0xAC   м
  0x7c, 0x10, 0x10, 0x10, 0x7c ,  // 0xAD   н
  0x38, 0x44, 0x44, 0x44, 0x38 ,  // 0xAE   o
  0x7c, 0x04, 0x04, 0x04, 0x7c ,  // 0xAF   п
  0x7C, 0x14, 0x14, 0x14, 0x08 ,  // 0xB0   p
  0x38, 0x44, 0x44, 0x44, 0x20 ,  // 0xB1   c
  0x04, 0x04, 0x7c, 0x04, 0x04 ,  // 0xB2   т
  0x0C, 0x50, 0x50, 0x50, 0x3C ,  // 0xB3   у
  0x30, 0x48, 0xfc, 0x48, 0x30 ,  // 0xB4   ф
  0x44, 0x28, 0x10, 0x28, 0x44 ,  // 0xB5   x
  0x7c, 0x40, 0x40, 0x40, 0xfc ,  // 0xB6   ц
  0x0c, 0x10, 0x10, 0x10, 0x7c ,  // 0xB7   ч
  0x7c, 0x40, 0x7c, 0x40, 0x7c ,  // 0xB8   ш
  0x7c, 0x40, 0x7c, 0x40, 0xfc ,  // 0xB9   щ
  0x04, 0x7c, 0x50, 0x50, 0x20 ,  // 0xBA   ъ
  0x7c, 0x50, 0x50, 0x20, 0x7c ,  // 0xBB   ы
  0x7c, 0x50, 0x50, 0x20, 0x00 ,  // 0xBC   ь
  0x28, 0x44, 0x54, 0x54, 0x38 ,  // 0xBD   э
  0x7c, 0x10, 0x38, 0x44, 0x38 ,  // 0xBE   ю
  0x08, 0x54, 0x34, 0x14, 0x7c ,  // 0xBF   я
};

//цифры размером 16х32 пикселей
static const char mass16x32[10][64] PROGMEM ={
  { 0xF8, 0xFC, 0xFA, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //0
    0x3F, 0x7F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x3F,
    0xFE, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFE,
    0x1F, 0x3F, 0x5F, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F},
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFC, 0xF8, //1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x3F,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFE,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x1F},
  { 0x00, 0x00, 0x02, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //2
    0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBF, 0x7F, 0x3F,
    0xFE, 0xFF, 0xFE, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
    0x1F, 0x3F, 0x5F, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x40, 0x00, 0x00},
  { 0x00, 0x00, 0x02, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //3
    0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBF, 0x7F, 0x3F,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE,
    0x00, 0x00, 0x40, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F},
  { 0xF8, 0xFC, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFC, 0xF8, //4
    0x3F, 0x7F, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBF, 0x7F, 0x3F,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x1F}, 
  { 0xF8, 0xFC, 0xFA, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x02, 0x00, 0x00, //5
    0x3F, 0x7F, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE,
    0x00, 0x00, 0x40, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F},
  { 0xF8, 0xFC, 0xFA, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x02, 0x00, 0x00, //6
    0x3F, 0x7F, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00,
    0xFE, 0xFF, 0xFE, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE,
    0x1F, 0x3F, 0x5F, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F},
  { 0x00, 0x00, 0x02, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //7
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0x3F,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFE,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x1F},
  { 0xF8, 0xFC, 0xFA, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //8
    0x3F, 0x7F, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBF, 0x7F, 0x3F,
    0xFE, 0xFF, 0xFE, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE,
    0x1F, 0x3F, 0x5F, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F},
  { 0xF8, 0xFC, 0xFA, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xFA, 0xFC, 0xF8, //9
    0x3F, 0x7F, 0xBF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBF, 0x7F, 0x3F,
    0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFE, 0xFF, 0xFE,
    0x00, 0x00, 0x40, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x5F, 0x3F, 0x1F}};

//цифры размером 10х16 пикселей
static const char mass10x16[10][20] PROGMEM ={
   {0x7E, 0x3D, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3D, 0x7E,      // 0 
    0x7F, 0xBE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBE, 0x7F},
   {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE,      // 1
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xFE},
   {0x00, 0x81, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E,      // 2
    0x7F, 0xBE, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0x80, 0x00},
   {0x00, 0x81, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E,      // 3
    0x00, 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F},
   {0x7E, 0xBC, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xBC, 0x7E,      // 4
    0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x3E, 0x7F},
   {0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x81, 0x00,      // 5
    0x00, 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F},
   {0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x81, 0x00,      // 6
    0x7F, 0xBE, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F},
   {0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x3D, 0x7E,      // 7
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x7F},
   {0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E,      // 8
    0x7F, 0xBE, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F},
   {0x7E, 0xBD, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xBD, 0x7E,      // 9
    0x00, 0x80, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xC1, 0xBE, 0x7F}
  };

//картинка линия под которой написано m/s
static const char image[48] PROGMEM ={
  0x00, 0x04, 0xE4, 0xC4, 0x84, 0x04, 0x84, 0xC4, 0xE4, 0x04, 0x04, 0x04,
  0x04, 0x84, 0xE4, 0x04, 0xC4, 0x64, 0x24, 0x24, 0x64, 0xC4, 0x04, 0x00,
  0x00, 0x00, 0xFF, 0x00, 0x01, 0x03, 0x01, 0x00, 0xFF, 0x00, 0xE0, 0x38,
  0x0E, 0x03, 0x00, 0x00, 0x61, 0xC3, 0x82, 0x86, 0xCC, 0x78, 0x00, 0x00}; 

LCD

//========================================================================
//                        Графические функции
//========================================================================
/*
 Clear_LCD();
 Update();
 fillScreen(color);
 drawPixel (x, y, color);
 drawChar(x, y, color, char c);
 drawString(x, y, color, char *str);
 drawLine(x0, y0, x1, y1, color);
 drawFastVLine(x, y, h, color);
 drawFastHLine(x, y, w, color);
 drawRect(x, y, w, h, color);
 drawCircle(x0, y0, r, color);
 drawRoundRect(x, y, w, h, r, color);
 drawTriangle(x0, y0, x1, y1, x2, y2, color);
 drawCircleHelper(x0, y0, r, cornername, color);
 
 fillCircle(x0, y0, r, color);
 fillCircleHelper(x0, y0, r, cornername, delta, color);
 fillRect(x, y, w, h, color);
 fillRoundRect(x, y, w, h, r, color);
 fillTriangle(x0, y0, x1, y1, x2, y2, color);
 
 drawBitmap(x, y, const uint8_t *bitmap, w, h, boolean color);
 */
 
//======================================================Очистка дисплея
void Clear_LCD() {
  for (int index = 0; index < 864 ; index++){
    LCD_RAM[index] = (0x00);
  }
}

//=====================================================Обновить дисплей
void Update(){
  for(byte p = 0; p < 9; p++){
    SendByte(LCD_C, SetYAddr| p); 
    SendByte(LCD_C, SetXAddr4);
    SendByte(LCD_C, SetXAddr3);

    for(byte col=0; col < LCD_X; col++){
      SendByte(LCD_D, LCD_RAM[(LCD_X * p) + col]);
    }
  }
}

//======================================================Заливка экрана
void fillScreen(boolean color) {
  fillRect(0, 0, LCD_X, LCD_Y, color);
}

//===================================================Нарисовать пиксель
void drawPixel (byte x, byte y, boolean color) {
  if ((x < 0) || (x >= LCD_X) || (y < 0) || (y >= LCD_Y)) return;

  if (color) LCD_RAM[x+ (y/8)*LCD_X] |= _BV(y%8);
  else       LCD_RAM[x+ (y/8)*LCD_X] &= ~_BV(y%8); 
}

//=====================================================Нарисовать букву
void drawChar(byte x, byte y, boolean color, unsigned char c) {

  if((x >= LCD_X) ||(y >= LCD_Y) || ((x + 4) < 0) || ((y + 7) < 0))
    return;

  if(c<128)            c = c-32;
  if(c>=144 && c<=175) c = c-48;
  if(c>=128 && c<=143) c = c+16;
  if(c>=176 && c<=191) c = c-48;
  if(c>191)  return;

  for (byte i=0; i<6; i++ ) {
    byte line;
    (i == 5)? line = 0x0 : line = pgm(font+(c*5)+i);
    for (byte j = 0; j<8; j++) {
      (line & 0x1)? drawPixel(x+i, y+j, color) : drawPixel(x+i, y+j, !color);
      line >>= 1;
    }
  }
}

//========================================================Вывод строки
void drawString(byte x, byte y, boolean color, char *str){
  unsigned char type = *str;
  if(type>=128) x=x-3;
  while(*str){ 
    drawChar(x, y, color, *str++);
    unsigned char type = *str;
    (type>=128)? x=x+3 : x=x+6;
  }
}

//====================================================Рисование линии
void drawLine(byte x0, byte y0, byte x1, byte y1, boolean color) {
  int steep = abs(y1 - y0) > abs(x1 - x0);
  if (steep) {
    swap(x0, y0);
    swap(x1, y1);
  }
  if (x0 > x1) {
    swap(x0, x1);
    swap(y0, y1);
  }
  int dx, dy;
  dx = x1 - x0;
  dy = abs(y1 - y0);

  int err = dx / 2;
  int ystep;

  (y0 < y1)?  ystep = 1 : ystep = -1;

  for (; x0<=x1; x0++) {
    (steep)? drawPixel(y0, x0, color) : drawPixel(x0, y0, color);
    err -= dy;
    if (err < 0) {
      y0 += ystep;
      err += dx;
    }
  }
}

//========================================Рисование вертикальной линии
void drawFastVLine(byte x, byte y, byte h, boolean color) {
  drawLine(x, y, x, y+h-1, color);
}

//======================================Рисование горизонтальной линии
void drawFastHLine(byte x, byte y, byte w, boolean color) {
  drawLine(x, y, x+w-1, y, color);
}

//============================================Рисование прямоугольника
void drawRect(byte x, byte y, byte w, byte h, boolean color) {
  drawFastHLine(x, y, w, color);
  drawFastHLine(x, y+h-1, w, color);
  drawFastVLine(x, y, h, color);
  drawFastVLine(x+w-1, y, h, color);
}

void drawCircle(byte x0, byte y0, int16_t r, boolean color) {
  int f = 1 - r;
  int ddF_x = 1;
  int ddF_y = -2 * r;
  int x = 0;
  int y = r;

  drawPixel(x0, y0+r, color);
  drawPixel(x0, y0-r, color);
  drawPixel(x0+r, y0, color);
  drawPixel(x0-r, y0, color);

  while (x<y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;
  
    drawPixel(x0 + x, y0 + y, color);
    drawPixel(x0 - x, y0 + y, color);
    drawPixel(x0 + x, y0 - y, color);
    drawPixel(x0 - x, y0 - y, color);
    drawPixel(x0 + y, y0 + x, color);
    drawPixel(x0 - y, y0 + x, color);
    drawPixel(x0 + y, y0 - x, color);
    drawPixel(x0 - y, y0 - x, color);
  }
}

//===============================Рисование скругленного прямоугольника
void drawRoundRect(byte x, byte y, byte w, byte h, byte r, boolean color) {
  // smarter version
  drawFastHLine(x+r , y , w-2*r, color); // Top
  drawFastHLine(x+r , y+h-1, w-2*r, color); // Bottom
  drawFastVLine( x , y+r , h-2*r, color); // Left
  drawFastVLine( x+w-1, y+r , h-2*r, color); // Right
  // draw four corners
  drawCircleHelper(x+r , y+r , r, 1, color);
  drawCircleHelper(x+w-r-1, y+r , r, 2, color);
  drawCircleHelper(x+w-r-1, y+h-r-1, r, 4, color);
  drawCircleHelper(x+r , y+h-r-1, r, 8, color);
}

//==============================================Рисование треугольника
void drawTriangle(byte x0, byte y0, byte x1, byte y1, byte x2, byte y2, boolean color) {
  drawLine(x0, y0, x1, y1, color);
  drawLine(x1, y1, x2, y2, color);
  drawLine(x2, y2, x0, y0, color);
}

//======================================================Рисование дуги
void drawCircleHelper(byte x0, byte y0, byte r, byte cornername, boolean color) {
  int f = 1 - r;
  int ddF_x = 1;
  int ddF_y = -2 * r;
  int x = 0;
  int y = r;

  while (x<y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;
    if (cornername & 0x4) {
      drawPixel(x0 + x, y0 + y, color);
      drawPixel(x0 + y, y0 + x, color);
    }
    if (cornername & 0x2) {
      drawPixel(x0 + x, y0 - y, color);
      drawPixel(x0 + y, y0 - x, color);
    }
    if (cornername & 0x8) {
      drawPixel(x0 - y, y0 + x, color);
      drawPixel(x0 - x, y0 + y, color);
    }
    if (cornername & 0x1) {
      drawPixel(x0 - y, y0 - x, color);
      drawPixel(x0 - x, y0 - y, color);
    }
  }
}

//========================================Рисование залитой окружности
void fillCircle(byte x0, byte y0, byte r, boolean color) {
  drawFastVLine(x0, y0-r, 2*r+1, color);
  fillCircleHelper(x0, y0, r, 3, 0, color);
}

//======================================================Рисование дуги
void fillCircleHelper(byte x0, byte y0, byte r, byte cornername, byte delta, boolean color) {

  int f = 1 - r;
  int ddF_x = 1;
  int ddF_y = -2 * r;
  int x = 0;
  int y = r;

  while (x<y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;

    if (cornername & 0x1) {
      drawFastVLine(x0+x, y0-y, 2*y+1+delta, color);
      drawFastVLine(x0+y, y0-x, 2*x+1+delta, color);
    }
    if (cornername & 0x2) {
      drawFastVLine(x0-x, y0-y, 2*y+1+delta, color);
      drawFastVLine(x0-y, y0-x, 2*x+1+delta, color);
    }
  }
}

//=====================================Рисование залитый прямоугольник
void fillRect(byte x, byte y, byte w, byte h, boolean color) {
  for (int16_t i=x; i<x+w; i++) {
    drawFastVLine(i, y, h, color);
  }
}

//======================Рисование залитого скругленного прямоугольника
void fillRoundRect(byte x, byte y, byte w, byte h, byte r, boolean color) {
  // smarter version
  fillRect(x+r, y, w-2*r, h, color);

  // draw four corners
  fillCircleHelper(x+w-r-1, y+r, r, 1, h-2*r-1, color);
  fillCircleHelper(x+r , y+r, r, 2, h-2*r-1, color);
}

//=====================================Рисование залитого треугольника
void fillTriangle(byte x0, byte y0, byte x1, byte y1, byte x2, byte y2, boolean color) {

  int a, b, y, last;

  // Sort coordinates by Y order (y2 >= y1 >= y0)
  if (y0 > y1) {
    swap(y0, y1); swap(x0, x1);
  }
  if (y1 > y2) {
    swap(y2, y1); swap(x2, x1);
  }
  if (y0 > y1) {
    swap(y0, y1); swap(x0, x1);
  }

  if(y0 == y2) { // Handle awkward all-on-same-line case as its own thing
    a = b = x0;
    if(x1 < a) a = x1;
    else if(x1 > b) b = x1;
    if(x2 < a) a = x2;
    else if(x2 > b) b = x2;
    drawFastHLine(a, y0, b-a+1, color);
    return;
  }

  int16_t
    dx01 = x1 - x0,
    dy01 = y1 - y0,
    dx02 = x2 - x0,
    dy02 = y2 - y0,
    dx12 = x2 - x1,
    dy12 = y2 - y1,
    sa = 0,
    sb = 0;

  if(y1 == y2) last = y1; // Include y1 scanline
  else last = y1-1; // Skip it

  for(y=y0; y<=last; y++) {
    a = x0 + sa / dy01;
    b = x0 + sb / dy02;
    sa += dx01;
    sb += dx02;
    /* longhand:
a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
    if(a > b) swap(a,b);
    drawFastHLine(a, y, b-a+1, color);
  }

  sa = dx12 * (y - y1);
  sb = dx02 * (y - y0);
  for(; y<=y2; y++) {
    a = x1 + sa / dy12;
    b = x0 + sb / dy02;
    sa += dx12;
    sb += dx02;
    /* longhand:
a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
    if(a > b) swap(a,b);
    drawFastHLine(a, y, b-a+1, color);
  }
}

//======================================================Вывод картинки
void drawBitmap(byte x, byte y, const char *bitmap, byte w, byte h, boolean color) {
  for (int16_t j=0; j<h; j++) {
    for (int16_t i=0; i<w; i++ ) {
      if (pgm(bitmap + i + (j/8)*w) & _BV(j%8)) {
        drawPixel(x+i, y+j, color);
      }
    }
  }
}

//========================================================================
//                        Управление дисплеем
//========================================================================

//=======================================================Управление пинами  
void dWrite(byte pin, byte val){
  byte bit = digitalPinToBitMask(pin);
  volatile byte *out;
  out = portOutputRegister(digitalPinToPort(pin));
  (val)? *out |= bit : *out &=~bit;
}

//=========================================================Отправка 9 байт    
void SendByte(byte mode, byte c){
  dWrite(CS, 0);
  (mode)? dWrite(Data,1) : dWrite(Data,0);
  dWrite(Clock, 1);
  for(byte i=0;i<8;i++){
    dWrite(Clock,0);
    (c & 0x80)? dWrite(Data,1) : dWrite(Data,0);
    dWrite(Clock,1);
    c <<= 1;
  }

  dWrite(Clock, 0);
}

//===================================================Инициализация дисплея
void Inicialize(){
  pinMode(CS,    OUTPUT);
  pinMode(Data,  OUTPUT);
  pinMode(Clock, OUTPUT);

  // Инициализация дисплея
  dWrite(Clock, 0);
  dWrite(Data, 0);
  dWrite(CS, 0);
  delay(20);
  dWrite(CS, 1);

  SendByte(LCD_C,0x2F);            // Power control set(charge pump on/off)
  SendByte(LCD_C,0xA4);   
  SendByte(LCD_C,0xAF);            // экран вкл/выкл
  Clear_LCD();
  Update();
}

//=========================Вывод символа 16х32 пикселя в координаты XY
void simb16x32(byte x, byte y, boolean color, byte c){
  for (byte k=0;k<4;k++){
    for (byte i=0;i<16;i++){
      byte line = pgm(&(mass16x32[c][i+k*16]));
      for (byte j = 0; j<8; j++) {
        (line & 0x01)? drawPixel(x+i, y+j+k*8, color) : drawPixel(x+i, y+j+k*8, !color);
        line >>= 1;
      }
    }
  }
}
//=========================Вывод символа 10х16 пикселя в координаты XY
void simb10x16(byte x, byte y, boolean color, byte c){
  for (byte k=0;k<2;k++){
    for (byte i=0;i<10;i++){
      byte line = pgm(&(mass10x16[c][i+k*10]));
      for (byte j = 0; j<8; j++) {
        (line & 0x01)? drawPixel(x+i, y+j+k*8, color) : drawPixel(x+i, y+j+k*8, !color);
        line >>= 1;
      }
    }
  }
}

LDM

//========================================================================
//                            Главный экран
//========================================================================
void Window_0(){
  fillScreen(!color);
  vyvod(skorost);
  drawRect(S,  S, W, H, color);
  drawRect(S, 12, W, 44, color);
  drawFastVLine(48, 2, 11, color);
  drawFastVLine(48, 56, 11, color);

  drawBitmap(68,33, image, 24, 16, color);
  drawString(13, 57, color, "Меню");
  drawString(55, 57, color, "Данные");

  int_LCD(58, 3, middle);

  if(DATA[0]!=0){
    for(byte i=0;i<=n;i++){
      fillRect(5+i*4,  3,  3,  8, color);
    }
  }
  
  Update();
}

//========================================================================
//                            Экран статистики
//========================================================================
void Window_1(){
  fillScreen(!color);
  drawRect(S,  5,   W, 62, color);
  drawFastVLine(48, 5,  62, color);


  for(byte i=15;i<56;i+=10){
    drawFastHLine(S,  i, W, color);
  }
  for(byte i=0;i<10;i++){
    if((i==0||i==2||i==4||i==6||i==8)&& DATA[i]!=0){
      int_LCD(12,  7+i*5, DATA[i]);
    }
    if((i==1||i==3||i==5||i==7||i==9)&& DATA[i]!=0){
      int_LCD(58,  7+(i-1)*5, DATA[i]);
    }  
  }
  drawString(10, 57, color, "Назад");
  drawString(57, 57, color, "Сброс");
  Update();
}

//========================================================================
//                              Экран настроек
//========================================================================
void Window_2(byte i){
  fillScreen(!color);
  byte n=1;
  n=n<<i;
  Menu(  1, myStrings[0], n&1);
  Menu( 12, myStrings[1], n&2);

  if(energi) Menu( 23, myStrings[3], n&4);
  else       Menu( 23, myStrings[2], n&4);

  Menu( 33, myStrings[4], n&8);
  Menu( 44, myStrings[5], n&16);
  Update();
}

//========================================================================
//                              Экран калиброки
//========================================================================
void Window_3(byte i){
  fillScreen(!color);

  byte n=1;
  n=n<<i;
  Menu( 32, myStrings[6], n&1);
  Menu( 43, myStrings[7], n&2);
  Menu( 54, myStrings[5], n&4);

  vyvod_16(calibration);

  drawString(70, 16, color, "мм");

  Update();
}

//========================================================================
//                         Экран настроек массы
//========================================================================
void Window_4(byte i){
  fillScreen(!color);

  byte n=1;
  n=n<<i;
  Menu( 32, myStrings[6], n&1);
  Menu( 43, myStrings[7], n&2);
  Menu( 54, myStrings[5], n&4);

  vyvod_16(mass);

  drawString(70, 16, color, "гр.");

  Update();
}


//========================================================================
//                  Вывод скорости статистики и средней
//========================================================================
void int_LCD(byte x, byte y, int temp){
  char c4=char(48+temp%10); 
  temp/=10;
  char c3=char(48+temp%10);  
  temp/=10;
  char c2=char(48+temp%10);  
  temp/=10;
  char c1=char(48+temp%10); 

  drawChar(x,    y,  color, c1);
  drawChar(x+6,  y,  color, c2);
  drawChar(x+12, y,  color, c3);
  drawChar(x+17, y,  color, '.');
  drawChar(x+21, y,  color, c4);
}

//========================================================================
//                           Вывод строки меню
//========================================================================
void Menu(byte y, char *str, boolean tap){
  byte h=12;
  byte length=strlen(str);

  unsigned char AN_RU = *str;
  if(AN_RU>128) length=length/2;

  if(tap){
    fillRect(2, y, LCD_X-4, h, color);
    drawString(LCD_X/2-length*3+2, y+2, !color, str);
  }
  else{
    fillRect(2, y, LCD_X-4, h, !color);
    drawString(LCD_X/2-length*3+2, y+2, color, str);
  }
}

//========================================================================
//                         Вывод текущей скорости
//========================================================================
void vyvod(int skor){
  unsigned int temp=skor;                         // переменная для хранения
  unsigned int c4=temp%10;                        // четвертая цифра скорости 
  temp/=10;
  unsigned int c3=temp%10;                        // третья цифра скорости 
  temp/=10;
  unsigned int c2=temp%10;                        // вторая цифра скорости 
  temp/=10;
  unsigned int c1=temp%10;                        // первая цифра скорости

  simb16x32(9,  17, color, c1);
  simb16x32(29, 17, color, c2);
  simb16x32(49, 17, color, c3);
  simb10x16(75, 17, color, c4);
}

//========================================================================
//                         Вывод цифр 10х16
//========================================================================
void vyvod_16(byte n){
  byte temp=n;                 
  byte c3=temp%10;                      
  temp/=10;
  byte c2=temp%10;                     
  temp/=10;
  byte c1=temp%10;   

  if(c1==0){
    simb10x16(38, 8, color, c2);
    simb10x16(51, 8, color, c3);
    if(display_N==4) drawRect(48, 24, 3, 2, color);
  }
  else{
    simb10x16(30, 8, color, c1);
    simb10x16(43, 8, color, c2);
    simb10x16(56, 8, color, c3);
    if(display_N==4) drawRect(53, 24, 3, 2, color);
  }
}



Main


void setup(){
  attachInterrupt(0, Start, RISING);     //Прерывание по нарастающему фронту на D0
  attachInterrupt(1,   End, RISING);     //Прерывание по нарастающему фронту на D1

  Inicialize();
  pinMode(pin_1, INPUT_PULLUP);
  pinMode(pin_2, INPUT_PULLUP);

  if(EEPROM.read(adr_first)==0){
    EEPROM.write(adr_first,  100);
    EEPROM.write(adr_calibr, 100);
    EEPROM.write(adr_energi,  0);
    EEPROM.write(adr_mass  , 100);
    EEPROM.write(adr_color,  0);
    EEPROM.write(adr_safe,   100);
  }

  calibration=EEPROM.read(adr_calibr);
  mass=       EEPROM.read(adr_mass);
  energi=     EEPROM.read(adr_energi);
  color=      EEPROM.read(adr_color);

  if(calibration==255) calibration=100;
  if(mass==255) mass=50;
  if(energi==255) energi=0;
  if(color==255) color=1;

  Window_0();
}



void loop(){
  if(!test) spped();
  
  //========================================================================
  //                         Тестирование датчиков
  //========================================================================
  if(digitalRead(pin_1)==0 && digitalRead(pin_2)==0){
    delay(100);
    if(digitalRead(pin_1)==0 && digitalRead(pin_2)==0){
      test=1;
    }
  }

  //========================================================================
  //                         Управление первой кнопкой
  //========================================================================
  if(digitalRead(pin_1)==0 && digitalRead(pin_2)==1){
    delay(50);
    if(digitalRead(pin_1)==0 && digitalRead(pin_2)==1){
      test=0;
      switch (display_N) {
      case 0: // если главный экран
        display_N=2;
        Window_2(display_2_menu);
        delay(200);
        break;

      case 1: // если экран статистики
        display_N=0;
        Window_0();
        delay(200);
        break;

      case 2: // если меню настроек
        display_2_menu++;
        if(display_2_menu==5) display_2_menu=0;
        Window_2(display_2_menu);
        delay(200);
        break;

      case 3: // если экран калибровки
        display_3_menu++;
        if(display_3_menu==3) display_3_menu=0;
        Window_3(display_3_menu);
        delay(200);
        break;

      case 4: // если настройка масса
        display_4_menu++;
        if(display_4_menu==3) display_4_menu=0;
        Window_4(display_4_menu);
        delay(200);
        break;

      }
    }
  }

  //========================================================================
  //                         Управление второй кнопкой
  //========================================================================
  if(digitalRead(pin_2)==0 && digitalRead(pin_1)==1){
    delay(50);
    if(digitalRead(pin_2)==0 && digitalRead(pin_1)==1){
      test=0;
      switch (display_N) {
      case 0: 
        first(); 
        break; 
      case 1: 
        Stat();
        break;  
      case 2:
        Settints();
        break;
      case 3:
        Calibr();
        break;
      case 4:
        massa();
        break;
      }
    }
  }

  
  if(test) Test();
}




//========================================================================
//                              Главный экран
//========================================================================
void first(){
  display_N=1;
  Window_1();
}

//========================================================================
//                             Экран статистики
//========================================================================
void Stat(){
  for(byte i=0;i<10;i++){
    DATA [i]=0;
  }
  middle=0;
  Window_1();
}

//========================================================================
//                             Экран настроек
//========================================================================
void Settints(){
  switch (display_2_menu) {

  case 0: // переходим в калибровку
    display_N=3;
    Window_3(display_3_menu);
    delay(200);
    break;

  case 1: // Настройка массы
    display_N=4;
    Window_4(display_4_menu);
    delay(200);
    break;

  case 2: // Скорость/энергия
    energi=!energi;
    EEPROM.write(adr_energi, energi);
    Window_2(display_2_menu);
    break;

  case 3: // Инвертирование
    color=!color;
    EEPROM.write(adr_color, color);
    Window_2(display_2_menu);
    break;

  case 4: // Назад
    display_N=0;
    display_2_menu=0;
    Window_0();
    delay(200);
    break;
  }
}

//========================================================================
//                             Экран калибровки
//========================================================================
void Calibr(){
  switch (display_3_menu) {
  case 0:
    if(calibration<254) calibration++;
    Window_3(display_3_menu);
    break;

  case 1:
    if(calibration>0) calibration--;
    Window_3(display_3_menu);
    break;

  case 2:
    display_N=2;
    Window_2(display_2_menu);
    display_3_menu=0;
    delay(200);
    EEPROM.write(adr_calibr, calibration);
    break;
  }
}

//========================================================================
//                            Управление массой
//========================================================================
void massa(){
  switch (display_4_menu) {
  case 0:
    if(mass<250) mass++;
    Window_4(display_4_menu);
    break;

  case 1:
    if(mass>0) mass--;
    Window_4(display_4_menu);
    break;

  case 2:
    display_N=2;
    Window_2(display_2_menu);
    display_4_menu=0;
    delay(200);
    EEPROM.write(adr_mass, mass);
    break;
  }
}

//========================================================================
//                     Рассчет текущей и средней скорости
//========================================================================
void spped(){
  if (flag1==0 && flag2==0){
    skorost = calibration*factor/(time2-time1);  //вычисляем скорость для расстояния между датчиками 7см

    if(DATA[0]==0) {
      n=0;
      DATA[n]=skorost;
    }
    else {
      n++;
      if(n>9){
        for(byte i=0;i<9;i++){
          DATA[i]=DATA[i+1];
        }
        n=9;
      }
      DATA[n]=skorost;
    }

    for(byte i=0;i<n;i++){
      middle=middle+DATA[i];
    }
    if(n!=0) middle=middle/(n+1);
    Window_0();

    delay(100);
    time2=0;
    flag1 = 1;
    flag2 = 1;
  }
}

//========================================================================
//                           Проверка датчиков
//========================================================================

void Test(){
  fillScreen(!color);
  drawRect(10, 25, 75, 15, color);
  fillRect(13, 20, 11, 5, color);
  fillRect(71, 20, 11, 5, color);
  fillRect(13, 40, 11, 5, color);
  fillRect(71, 40, 11, 5, color);
  fillTriangle(75, 55, 65, 50, 65, 60, color);
  fillRect(20, 53, 45, 4, color);
  
  drawString(9, 3, color, "Тест датчиков");
  
  if(flag1==0) fillCircle(18, 32, 4, color);
  if(flag2==0) fillCircle(76, 32, 4, color);
  
  if((micros()-time1) >500000) flag1=1;
  if((micros()-time2) >500000) flag2=1;
  
  for(byte i=0;i<10;i++){
    DATA [i]=0;
  }
  middle=0;

  Update();
}

Всего 1242 строки кода, половина это символы, переменные и графические функции

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

Благодрю,попробую вытащить нужное.

Immortal
Offline
Зарегистрирован: 28.12.2013

Хотелось бы посмотреть на финальную схему.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да какая там схема. мега8 кварц несколько резисторов и пребразователь со стабилизатором. ну и в датчиках ик диоды и фототранзисторы

Immortal
Offline
Зарегистрирован: 28.12.2013

ок, буду смотреть на разводку платы.

А почему экран выбрали именно 1202, а не 5110 под который есть куча либ? Неужели пикселей нехватило?

1202 96x68 pix.
5110 84x48 pix.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

потому что он мне нравится)))

lakec
Offline
Зарегистрирован: 09.10.2015

Есть у кого вариант датчика для огнестрелов ?

han2001
Offline
Зарегистрирован: 09.01.2015

Здравсвуйте. 

Я пока собрал в виде макета на arduino pro micro (ATmega32U4), залил скетч выложенный здесь. Пока полазил по менушке и вроде все отлично, но есть пару вопросов.

1.Когда переходиш по пунктам меню, то в момент перехода с пункта на пункт промаргивает не однородно закрашенный черный экран. Так у всех или только у меня? 

2. В программе хорошо видно, какие выводы управляют экраном, а какие кнопками и их можно переназначить. А где в программе видно, что именно выводы 2 и 3 отвечают за обработку фототранзисторов и можно ли их переназначить на другие выводы?.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

привет

1. не видел такого

2. выводы можно поменять кроме фототранзисторов.

2 и 3 пины это прерывания: в файле main 2 и 3 строка

посмотрел немного свой код, нашел ряд не очень оптимальных решений. например в функцию отрисовки экрана не обязательно передавать пункт  меню, смысла нет, так как переменная все равно глобальная.

можно ускорить отрисовку экрана. поменять функцию SendByte на эту:

//=========================================================Отправка 9 байт   
void SendByte(byte mode, byte c){
  dWrite(CS, 0);
  (mode)? dWrite(Data,1) : dWrite(Data,0);
  dWrite(Clock, 1);
  for(byte i=0;i<8;i++){
    dWrite(Clock,0);
    (c & 0x80)? dWrite(Data,1) : dWrite(Data,0);
    dWrite(Clock,1);
    c <<= 1;
  }
  dWrite(Clock, 0);
}

если еще покопаться можно еще что нибудь оптимизировать

han2001
Offline
Зарегистрирован: 09.01.2015

Уважаемый jeka_tm.

Не знаю интересна вам еще эта тема или нет, но вы как то спрашивали в этом форуме предложения по отрисовке уровня заряда батареи. Так вот если еще интересно, то уровень заряда можно отображать просто в процентах от 0% до 100% в окне количества измерений.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

уровень заряда я уже далал как то. и вроде неплохо получилось, только графически делал

han2001
Offline
Зарегистрирован: 09.01.2015

А можно выложить код обработки и отрисовки уровня заряда батареи, как это реализовано у вас тут?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

там его нет. это количество измерений

видео нашел. код не помню выкладывал или нет

http://www.youtube.com/watch?v=bhSiFH5RnLM

han2001
Offline
Зарегистрирован: 09.01.2015

Кажатся нашел, я так понимаю этот код считывает и отображает уровень заряда

//считаем напряжение
void napr(){
  U = analogRead(accum);
  U = constrain(U, 547, 614);
  U = map(U, 547, 614, 0, 9);

  Goto_XY(80,0);
  for (int i = 0; i<3; i++){
    SendByte(1,pgm_read_byte(&(batt[i])));
  }
  if (U == 9){
    for (int i = 0; i<9; i++){
      SendByte(1,pgm_read_byte(&(batt[3])));
    }
  }
  if (U<9){
    for (int i = 0; i<(9-U); i++){
      SendByte(1,pgm_read_byte(&(batt[2])));
    }
    for (int i = 0; i<U; i++){
      SendByte(1,pgm_read_byte(&(batt[3])));
    }
  }
  SendByte(1,pgm_read_byte(&(batt[2])));
  SendByte(1,pgm_read_byte(&(batt[1])));
}  

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

ага. только это для питания 5В. у меня питалось от аккумулятора через преобразователь на 5В

han2001
Offline
Зарегистрирован: 09.01.2015

Так и я хочу Li-ion аккумулятор запитать через Step-UP преобразователь. Только буду мерять напряжение на самом аккумуляторе (от 3в до 4,2В), а иначе смысл мерить постоянно 5В.

А вы запитывали через делитель или напрямую? 

Да и как вы получили значения 547 и 614 ?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

напрямую. конечно на самом аккумуляторе. значение получил опытным путем. это 2 порога которые выбрал: 3 и 4.2В. вроде так

han2001
Offline
Зарегистрирован: 09.01.2015

Это понятно что опытным путем, меняете напряжение на входе и видите, что видит АЦП в цифрах.  Не с потолка же взяли эти числа ))) Я пока просто учусь. Вот и думаю как посмотреть что видит АЦП в реальном времени и ест ли такие средства у ардуины? Или я не правильно понял принцип?

Все нашел как

han2001
Offline
Зарегистрирован: 09.01.2015
Уважаемый jeka_tm, не подскажите мне в чем проблема?
 
Решил модернизировать вашу программку Speed_v5.9.8 в части отслеживания уровня заряда батареи, я для этого решил пожертвовать счетчиком количества измерени который в верхнем правом углу. Эту шкалу делений использовал для отображения уровня заряда, и вроде бы работает, но не в реальном времени, т.е. шкала обнавляется если выйти в другое меню и потом вернуться на главное. Не подскажите, что в коде не так? Код двух вкладок ниже. Пробовал провести несколько делитанский экспериментов, а именно Window_0 сунуть в loop (), тогда конечно в реале все показывает, но не перейдешь в другии меню. Был бы весьма вам признателен за помощь.
 
//добавил в вкладке Speed_v5.9.8.ino
//считаем напряжение
#define accum        A0
int U = 0;
int a = 0;
void battary() {
              U = analogRead(accum);
              U = constrain(U, 650, 855);
              U = map(U, 650, 855, 0, 9);
              for( a=0;a<=U;a++) fillRect(5+a*4,  3,  3,  8, color);
}
// изменил во вкладке LDM

//========================================================================
//                            Главный экран
//========================================================================
void Window_0(){
  fillScreen(!color);
  vyvod(skorost);
  drawRect(S,  S, W, H, color);
  drawRect(S, 12, W, 44, color);
  drawFastVLine(48, 2, 11, color);
  drawFastVLine(48, 56, 11, color);

  drawBitmap(68,33, image, 24, 16, color);
  drawString(13, 57, color, "Меню");
  drawString(55, 57, color, "Данные");

  int_LCD(58, 3, middle);

/*   if(DATA[0]!=0){
    for(byte i=0;i<=n;i++){
      fillRect(5+i*4,  3,  3,  8, color);
    }
  } */
  
   battary();
 
   Update();
}

 

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

да все просто

в конце loop добавить после :

if(test) Test();

эту строку

if(display_N==0) Window_0();

фото или видео не забудь приложить что получилось