Ввод значения с матричной цифровой клавиатуры

alexval2007
Offline
Зарегистрирован: 10.11.2012

Всем доброго дня. Возникла нужда сделать себе на работу тестер термоподвесок а то ноутбук тяжёлый аккумулятор не держит заряд. Решил собрать себе мобильный тестер на основе ардуино матричной клавиатуры и дисплея 20х4 физическим интерфейсом для обмена с термпоподвесками будет RS485 микросхема max485 подключённая UART ардуино. С протоколом термоподвесок более менее разобрался. Набросал тестовый код вот хочу сделать ввод заводского номера термоподвески с цифровой матричной клавиатуры. Заводской номер может быть от четырех до шести цифр например 5907 потом это значение надо будет вывести в Serial (UART) в виде шестнадцатеричного числа из двух байт 0х17, 0х13 Для пробы было написан код см ниже я тут попытался сохранятькаждое число в массив но выводиться оно по нажатию * по отдельности а мне их нужно все сложить чтобы если я ввожу номер 5907 в масиве он выглядит как 5,9,0,7. Выводится в порт как 0х05, 0х09, 0х00, 0х07 а мне нужно получить два байта 0х17, 0х13.

 

void Apdate_str()
{
  
 if (key != NO_KEY)
 {            
   count++;
               
   if (count==1)
   {
       lcd.setCursor(0, 3);
       lcd.print(F_Key);
       Str1[0] = F_Key;
   } 
   else if (count==2)
   {
       lcd.setCursor(1, 3);
       lcd.print(F_Key);
       Str1[1] = F_Key;
   } 
   else if (count==3)
   {
       lcd.setCursor(2, 3);
       lcd.print(F_Key);
       Str1[2] = F_Key;
   } 
   else if (count==4)
   {
       lcd.setCursor(3, 3);
       lcd.print(F_Key);
       Str1[3] = F_Key;
   } 
   else if (count==5)
   {
       lcd.setCursor(4, 3);
       lcd.print(F_Key);
       Str1[4] = F_Key;
   } 
   else if (count==6)
   {
       lcd.setCursor(5, 3);
       lcd.print(F_Key);
       Str1[5]=F_Key;
   } 
   
   if  (key=='*')
   {
       lcd.setCursor(0, 3);
       lcd.print("      ");

    for (j_=0; j_ < count - 1; j_++)
    { 
     temp1 = Str1[j_];
     Serial.write(temp1);
    }
       count=0;
   } 
   
 }
}





----------------------------------------------------------------------------------------------------------------
/*
   Termotester_mini_atmega328p
   Version: 1.0.0.0
   Release: 12.08.2016
*/

//---------------------------------------------------------------------------
// Подключаем библиотеки:
#include <LiquidCrystalRus.h>
#include <Keypad.h>
//---------------------------------------------------------------------------
//The declaration of constants
#define Max_Adres       255
#define Max_Znambur     999999
#define Max_TX_Buf      15
#define CRC_len         2
#define time_Key_ask    10    //
#define time_Show_RS    300   // 
#define USART_USB_RATE  9600  //  

unsigned int data1=0;
int count=0;
char key1;
char key;
byte CRC_Low = 0xFF;
byte CRC_High = 0xFF;
byte Znambur_Low = 0;
byte Znambur_High = 0;
unsigned char Key_Counter = 0;  
unsigned char Key_Set = 0;  
unsigned char Adres   = 1;  
unsigned int  Znambur = 5907;   
unsigned char temp    = 0;
unsigned int  temp1   = 0;
unsigned int  temp2   = 0;
unsigned char F_Key   = 0;
unsigned char row_t;
char          Last_Key  = 0;
unsigned char KpdState  = 0;
char          i_        = 0;
char          j_        = 0;
unsigned long time_RS   = 0;
unsigned long msNow     = 0;
unsigned long time_Key  = 0;
unsigned char Menu = 0;
unsigned char Select_Cursor[6] = {0,0,0,0,0,0};
unsigned char Menu_Item[6] = {0,0,0,0,0,0};
uint8_t TX_Buf[15];       // Буфер для отправки данных.
//uint8_t RX_Buf[39];     // Буфер для отправки данных.
char Str1[6];

byte NewChar[9];
//массивы для быстрого расчета кода CRC-16
byte srCRCHi[256]={
         0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
         0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
         0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
         0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
         0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
         0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
         0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
         0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
         0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
         0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
         0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
         0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
         0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
         0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
         0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
         0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
         0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
         0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
         0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
         0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
         0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
         0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
         0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
         0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
         0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
         0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
};
 byte srCRCLo[256]={
         0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
         0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
         0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
         0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
         0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
         0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
         0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
         0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
         0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
         0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
         0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
         0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
         0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
         0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
         0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
         0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
         0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
         0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
         0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
         0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
         0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
         0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
         0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
         0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
         0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
         0x43, 0x83, 0x41, 0x81, 0x80, 0x40
};
//---------------------------------------------------------------------------
LiquidCrystalRus lcd(13, 14, 15, 16, 17, 18);// Настроим LСD

// The Keymap
const byte ROWS = 4; // 4 строки
const byte COLS = 4; // 4 столбца
// Define the Keymap
char keys[ROWS][COLS] = 
{
  {'1','2','3','A',},
  {'4','5','6','B',},
  {'7','8','9','C',},
  {'*','0','#','D' }
};

// Строки клавиатуры ROW0, ROW1, ROW2 и ROW3. Подключение к контактам Arduino.
byte rowPins[ROWS] = {3, 4, 6, 7};//
// Столбцы клавиатуры COL0, COL1, COL2 и COL3. Подключение к контактам Arduino.
byte colPins[COLS] = {8, 10, 11, 12};// 
// Создадим клавиатуру
Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
//---------------------------------------------------------------------------
void Adres_next();
void Adress_minus();      
void Adress_plus(); 
void Cursor_minus();      
void Cursor_plus();  
void Cursor_CLR();
void Apdate_Slever();
void Key_Ask();
void ShowMenu();
void Show_RS();
void CLR_RS();
void LCD_Char_Setup();
void Select_Show(char Row_Select);
//---------------------------------------------------------------------------
void Apdate_Slever()
{
  lcd.setCursor(4, 1);  
  lcd.print(Adres, DEC);
  lcd.print("  ");
  
  lcd.setCursor(11, 1);  
  lcd.print(Znambur, DEC);
  lcd.print("   ");
}
//---------------------------------------------------------------------------
void Apdate_str()
{
  
 if (key != NO_KEY)
 {            
   count++;
               
   if (count==1)
   {
       lcd.setCursor(0, 3);
       lcd.print(F_Key);
       Str1[0] = F_Key;
   } 
   else if (count==2)
   {
       lcd.setCursor(1, 3);
       lcd.print(F_Key);
       Str1[1] = F_Key;
   } 
   else if (count==3)
   {
       lcd.setCursor(2, 3);
       lcd.print(F_Key);
       Str1[2] = F_Key;
   } 
   else if (count==4)
   {
       lcd.setCursor(3, 3);
       lcd.print(F_Key);
       Str1[3] = F_Key;
   } 
   else if (count==5)
   {
       lcd.setCursor(4, 3);
       lcd.print(F_Key);
       Str1[4] = F_Key;
   } 
   else if (count==6)
   {
       lcd.setCursor(5, 3);
       lcd.print(F_Key);
       Str1[5]=F_Key;
   } 
   
   if  (key=='*')
   {
       lcd.setCursor(0, 3);
       lcd.print("      ");

    for (j_=0; j_ < count - 1; j_++)
    { 
     temp1 = Str1[j_];
     Serial.write(temp1);
    }
       count=0;
   } 
   
 }
}
//---------------------------------------------------------------------------
void Show_RS()
{
  time_RS = millis() +  time_Show_RS; 
  lcd.setCursor(13, 0);  
  lcd.write(6); 
}
//---------------------------------------------------------------------------
void CLR_RS()
{
  lcd.setCursor(13, 0);  
  lcd.write(32);   
}
//---------------------------------------------------------------------------
void Cursor_Show()
{
  lcd.setCursor(0, 1);  
  lcd.print(" ");
  lcd.setCursor(0, 2);  
  lcd.print(" ");
  lcd.setCursor(0, 3);  
  lcd.print(" "); 
  lcd.setCursor(0, (Select_Cursor[Menu]+1));
  lcd.write(1); 
}
//---------------------------------------------------------------------------
void Select_Show(char Row_Select)
{
  lcd.setCursor(1, 1);  
  lcd.print(" ");
  lcd.setCursor(1, 2);  
  lcd.print(" ");
  lcd.setCursor(1, 3);  
  lcd.print(" ");
  
  if (Row_Select >= 0)
  { 
    lcd.setCursor(1, (Row_Select+1));
    lcd.write(62);
  } 
}
//---------------------------------------------------------------------------
void Cursor_minus()
{
  Select_Cursor [Menu] --;  
  if(Select_Cursor[Menu]==255) Select_Cursor[Menu]=Menu_Item[Menu];
  Cursor_Show();
}
//---------------------------------------------------------------------------
void Cursor_plus()
{
  Select_Cursor[Menu] ++;  
  if(Select_Cursor[Menu]>Menu_Item[Menu]) Select_Cursor[Menu]=0;
  Cursor_Show();
}
//---------------------------------------------------------------------------
void ShowMenu()
{
  switch (Menu)
  {
      case 0:
              lcd.clear();    
              lcd.setCursor(0, 0);  
              lcd.print("Главное меню");
              
              lcd.setCursor(0, 1);  
              lcd.print("  Опрос");
              Cursor_Show();
      break;  
      case 1: 
              lcd.clear();        
              lcd.setCursor(0, 0);
              lcd.print("Опрос");   

              lcd.setCursor(0, 1);              
              lcd.print("Адр:");
              
              lcd.setCursor(9, 1);              
              lcd.print("#:");
                       
              Apdate_Slever();
      break;  
  
      case 2: 
              break;
     case 3:    
              break;
     break;
  }   
}
//---------------------------------------------------------------------------
void Key_Ask()
{
  time_Key = millis() +  time_Key_ask;
  
       key = kpd.getKey();
       key1 = kpd.getKey();
       
  if(key) Last_Key = key; // same as if(key != NO_KEY)
  KpdState = kpd.getState();
  if(2 == kpd.getState())    Last_Key = 'N';

  switch (Menu)
  {
    case 0:    
            switch (key)
            {
              case 'A':   break;                 //назад     
              case 'B':   Menu = Select_Cursor[Menu]+1; Last_Key = 'N';  ShowMenu(); break; //вперед     
              case 'C':   Cursor_plus();  break; //вверх
              case 'D':   Cursor_minus(); break; //вниз
              case '*':   break;                 //записать параметр
              case '#':   break;         
            }     
    break;  
    case 1:    
            switch (key)
            {
              case 'A':   Menu = 0; ShowMenu(); break; //назад     
              case 'B':   break;                       //вперед     
              case 'C':   Adress_plus();  break;       //вверх (+)
              case 'D':   Adress_minus(); break;       //вниз  (-)
              case '*':   Apdate_str(); break;                       //записать параметр
              case '#':   Adres_next(); break;   
          
              case '1':   F_Key = 1; Apdate_str(); break;//F_Key = 1; Fire(); break;
              case '2':   F_Key = 2; Apdate_str(); break;
              case '3':   F_Key = 3; Apdate_str(); break;
              case '4':   F_Key = 4; Apdate_str(); break;
              case '5':   F_Key = 5; Apdate_str(); break;
              case '6':   F_Key = 6; Apdate_str(); break;
              case '7':   F_Key = 7; Apdate_str(); break;
              case '8':   F_Key = 8; Apdate_str(); break;
              case '9':   F_Key = 9; Apdate_str(); break;
              case '0':   F_Key = 0; Apdate_str(); break;
              //case 'N':   break;           
            }      
    break;
    case 2:    
            switch (key)
            {
              case 'A':   Menu = 0; ShowMenu(); break; //назад     
              case 'B':   Select_Show(Select_Cursor[Menu]); Menu = Select_Cursor[Menu]+3; ShowMenu(); break; //вперед     
              case 'C':   Cursor_plus();  break;      //вверх (+)
              case 'D':   Cursor_minus(); break;      //вниз  (-)
              case '*':   break;                      //записать параметр
              case '#':   break;      
            }     
    break;  
    case 3:    
            switch (key)
            {
              case 'A':   Menu = 2;  ShowMenu(); break;//назад     
              case 'B':   break;                       //вперед     
              case 'C':   break;                       //вверх (+)
              case 'D':   break;                       //вниз  (-)
              case '*':   break;                       //записать параметр
              case '#':   break;          
            }     
    break;      
  }  
}
//---------------------------------------------------------------------------
void Adress_plus()
{
  Adres++;
  F_Key = 0;   
  if (Adres > Max_Adres)
  {
   Adres = 1;
  }  
  Apdate_Slever();
}
//---------------------------------------------------------------------------
void Adress_minus()
{
  Adres--;
  F_Key = 0;  
  if (Adres < 1)
  {
    Adres = Max_Adres;
  }  
  Apdate_Slever();
}
//---------------------------------------------------------------------------
//функция вычисляет код CRC-16
//на входе указатель на начало буфера
//и количество байт сообщения (без принятого кода CRC-16)
unsigned int GetCRC16(byte *buf, byte bufsize)
{
  CRC_Low = 0xFF;
  CRC_High = 0xFF;
  byte k;
  byte carry;
  for (k=0; k<bufsize; k++)
  {
    carry = CRC_Low ^ buf[k];
    CRC_Low = CRC_High ^ srCRCHi[carry];
    CRC_High = srCRCLo[carry];
  }
  //return (CRC_High);
  //return((CRC_High<<8)|CRC_Low);
  
}//end GetCRC16()
//---------------------------------------------------------------------------
void Adres_next()//смена адреса подвески по заводскому номеру
{
  if (Menu!=1) return;
  Show_RS();
  //FF 25 05 06 17 13 02 E3 47 
  TX_Buf[0] = 0xFF;
  TX_Buf[1] = 0x25;
  TX_Buf[2] = 0x05;
  TX_Buf[3] = 0x06;
  Znambur_High = highByte(Znambur);
  Znambur_Low = lowByte(Znambur);
  TX_Buf[4] = Znambur_High;//зв№ High
  TX_Buf[5] = Znambur_Low;//зв№ Low 
  TX_Buf[6] = Adres;
  GetCRC16(TX_Buf, 7);
  TX_Buf[7] = CRC_Low;
  TX_Buf[8] = CRC_High;
  
  for (i_=0; i_<7+CRC_len; i_++)
  {
     temp=TX_Buf[i_];
     Serial.write(temp);
  }
  Apdate_Slever();
}
//---------------------------------------------------------------------------
void LCD_Char_Setup()
{
  NewChar[0]=B10000;
  NewChar[1]=B11000;
  NewChar[2]=B11100;
  NewChar[3]=B11110;
  NewChar[4]=B11100;
  NewChar[5]=B11000;
  NewChar[6]=B10000;
  NewChar[7]=B00000;  
  lcd.createChar(0, NewChar);  
   
  NewChar[0]=B11100;
  NewChar[1]=B11100;
  NewChar[2]=B11111;
  NewChar[3]=B11111;
  NewChar[4]=B11111;
  NewChar[5]=B11111;
  NewChar[6]=B11100;
  NewChar[7]=B11100;
  lcd.createChar(1, NewChar);

  NewChar[0]=B11111;
  NewChar[1]=B10000;
  NewChar[2]=B10000;
  NewChar[3]=B10000;
  NewChar[4]=B10000;
  NewChar[5]=B10000;
  NewChar[6]=B10000;
  NewChar[7]=B11111;
  lcd.createChar(2, NewChar);

  NewChar[0]=B11111;
  NewChar[1]=B00000;
  NewChar[2]=B00000;
  NewChar[3]=B00000;
  NewChar[4]=B00000;
  NewChar[5]=B00000;
  NewChar[6]=B00000;
  NewChar[7]=B11111;
  lcd.createChar(3, NewChar);

  NewChar[0]=B11100;
  NewChar[1]=B00100;
  NewChar[2]=B00111;
  NewChar[3]=B00001;
  NewChar[4]=B00001;
  NewChar[5]=B00111;
  NewChar[6]=B00100;
  NewChar[7]=B11100;
  lcd.createChar(4, NewChar);

  NewChar[0]=B01110;
  NewChar[1]=B01010;
  NewChar[2]=B11111;
  NewChar[3]=B11111;
  NewChar[4]=B11111;
  NewChar[5]=B01110;
  NewChar[6]=B00100;
  NewChar[7]=B00100;
  lcd.createChar(5, NewChar);

  NewChar[0]=B01000;
  NewChar[1]=B10100;
  NewChar[2]=B01000;
  NewChar[3]=B01010;
  NewChar[4]=B01010;
  NewChar[5]=B00010;
  NewChar[6]=B00101;
  NewChar[7]=B00010;
  lcd.createChar(6, NewChar);

  NewChar[0]=B00100;
  NewChar[1]=B10101;
  NewChar[2]=B01110;
  NewChar[3]=B00100;
  NewChar[4]=B00100;
  NewChar[5]=B00100;
  NewChar[6]=B00100;
  NewChar[7]=B00100;
  lcd.createChar(7, NewChar);
  
  NewChar[0]=B11111;
  NewChar[1]=B11111;
  NewChar[2]=B11111;
  NewChar[3]=B11111;
  NewChar[4]=B11111;
  NewChar[5]=B11111;
  NewChar[6]=B11111;
  NewChar[7]=B11111;
  lcd.createChar(8, NewChar);
}
//---------------------------------------------------------------------------
void setup() 
{
  lcd.begin(20, 4);//Установим режим дисплея 20х4
  LCD_Char_Setup();//Загрузим специальные символы для дисплэя
  Serial.begin(USART_USB_RATE); 
  kpd.setHoldTime (20) ;        // 
  kpd.setDebounceTime (10) ;    // 
  ShowMenu();
}
//---------------------------------------------------------------------------
void loop() 
{
  ///if (Serial.available() > 0) Rx_Decode(); 
  msNow = millis(); 
  if (time_Key < msNow) Key_Ask();
  if (time_RS  < msNow) CLR_RS();
}
//---------------------------------------------------------------------------

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Через энкодер ввод числа не пытался сделать? Интересней будет.

alexval2007
Offline
Зарегистрирован: 10.11.2012

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

ну лучше так https://www.terraelectronica.ru/news_ushki.php?ID=42 вон схема https://www.terraelectronica.ru/files/news/dz35.gif

Не можешь на 1 аналоговый воткни на 4 аналоговых входа .

http://zelectro.cc/LCD_Keypad_Shield_DIY 

alexval2007
Offline
Зарегистрирован: 10.11.2012

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

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

alexval2007
Offline
Зарегистрирован: 10.11.2012

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ведь перевести в код это ерунда. Если у вас ввод 16 знаков, то помимо этих надо еще добавить две клавиши ЕNTER и DELETE. Но даже это ерунда. Для того что бы нормально написать такую программу надо как минимум организовать двухпоточную систему.

uint8_t non_stop_program1(uint16_t span) {
  static uint32_t future = 0;
  if (millis()<future) return 0;
  future += span;
  return 1;
}
uint8_t non_stop_program2(uint16_t span) {
  static uint32_t future = 0;
  if (millis()<future) return 0;
  future += span;
  return 1;
}
uint8_t non_stop_program3(uint16_t span) {
  static uint32_t future = 0;
  if (millis()<future) return 0;
  future += span;
  return 1;
}


void setup() {
  Serial.begin(9600);
}
void loop() {
  if (non_stop_program1(500))  { 
// Здесь вы организовываете вывод на экран. Вызывается раз в 0.5 сек
    Serial.println("knok");}
  if (non_stop_program2(200))  {
// Здесь вы организовываете ввод с клавиатуры. Вызывается раз в 0.2 сек
  }
  if (non_stop_program3(100))  {
// Здесь сама работа устройства не зависимая от вашего ввода и показа на экран. Вызывается раз в 0.1 сек(может быть по желанию другим)
   }
}

 

toc
Offline
Зарегистрирован: 09.02.2013

qwone, по-моему, в вашей программе нужно исправить:
"Вызывается раз в" заменить на "Вызывается не чаще чем раз в".

Ссылка интересная. Спасибо

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

 toc.Вы самое главное не уловили. Если начнется "Вызывается не чаще чем раз в", то программист туп,и неправильно использует данную конструкцию.  И это раскладка только первого слоя понимания, данной концепции. Дальше процедура вывод на экран распадается на две части. Просто вывод на экран и вывод панели. Панель это то что вы видете внизу на экране монитора: RU, интернет и тому прочее. Опять же мигание организовано курсора. Давольно легко организуется.  

Ввод с клавиатуры тоже распадется на две части. Собственно получение какая клавиша нажата и что в конце концов сделать после нажатия ENTER.

alexval2007
Offline
Зарегистрирован: 10.11.2012

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

/*
   Test_vvod_chisla_atmega328p
   Version: 1.0.0.0
   Release: 25.08.2016
*/
//---------------------------------------------------------------------------
// Подключаем библиотеки:
#include <LiquidCrystal.h>
#include <Keypad.h>
//---------------------------------------------------------------------------
//The declaration of constants
#define time_Key_ask    10    //
#define USART_USB_RATE  9600  //  
unsigned int chislo = 0;
unsigned int chislo_data = 0;
char key;
char key_set = 0;
unsigned int  temp    = 0;
unsigned char row_t;
char Last_Key  = 0;
unsigned char KpdState  = 0;
unsigned long msNow     = 0;
unsigned long time_Key  = 0;
//---------------------------------------------------------------------------
LiquidCrystal lcd(13, 14, 15, 16, 17, 18);// Настроим LСD

// The Keymap
const byte ROWS = 4; // 4 строки
const byte COLS = 4; // 4 столбца
// Define the Keymap
char keys[ROWS][COLS] = 
{
  {'1','2','3','A',},
  {'4','5','6','B',},
  {'7','8','9','C',},
  {'*','0','#','D' }
};

// Строки клавиатуры ROW0, ROW1, ROW2 и ROW3. Подключение к контактам Arduino.
byte rowPins[ROWS] = {3, 4, 6, 7};//
// Столбцы клавиатуры COL0, COL1, COL2 и COL3. Подключение к контактам Arduino.
byte colPins[COLS] = {8, 10, 11, 12};// 
// Создадим клавиатуру
Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
//---------------------------------------------------------------------------
void Key_Ask();
//---------------------------------------------------------------------------
void Key_Ask()
{
  time_Key = millis() +  time_Key_ask;
  key = kpd.getKey();
       
  if(key) Last_Key = key; // same as if(key != NO_KEY)
  KpdState = kpd.getState();
  if(2 == kpd.getState())    Last_Key = 'N';
  
  
  switch (key)
  {
    case 'A':   break; 
    case 'B':   break; 
    case 'C':   break;
    case 'D':   break; 
    case '*':   key_set=1; break;
  }
   
   
 if(key_set) 
 {
  //lcd.clear(); 
  lcd.setCursor(0, 0);  
  if(key) 
  {
    temp = temp + 1;
    if(key >= '0' && key <= '9') // ограничим ввод диапазоном ascii смволов от 0 до 9 тоесть только цифры.
    {
      Serial.print(key);
      lcd.setCursor(temp, 0); 
      lcd.print(key);
    }
    
    if(key == '#')
    {
      chislo_data = chislo;
      Serial.println(" ");
      Serial.print("chislo = ");  
      Serial.println(chislo_data);
      Serial.print("HEX = ");
      Serial.println(chislo_data, HEX);
      //lcd.clear();    
      lcd.setCursor(0, 1);  
      lcd.print(chislo_data);
      chislo = 0;
      temp = 0;
      key_set = 0;
    }
    else if(key >= '0' && key <= '9') // ограничим ввод диапазоном ascii смволов от 0 до 9 тоесть только цифры.
    {
        chislo = chislo * 10;         // до 59999
        chislo = chislo + key - 48;   // конвертируем ascii смволы в числа десятичной системы от 0 до 9.
    }
  }
 }
}
//---------------------------------------------------------------------------
void setup() 
{
  lcd.begin(20, 4);//Установим режим дисплея 20х4
  Serial.begin(USART_USB_RATE); 
  kpd.setHoldTime (20) ;        // 
  kpd.setDebounceTime (10) ;    // 
}
//---------------------------------------------------------------------------
void loop() 
{
  msNow = millis(); 
  if (time_Key < msNow) Key_Ask();
}
//---------------------------------------------------------------------------

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

А иначе не получилось бы. Даже если я привел бы свой код по вашей задаче, его все равно приходилось "тереть напильником". И это притом что он у меня очень специфичен. Процентов 50 вы поняли, а остальное нет. Так что вы сделали программу работу, которой вы поняли.

EuBeginer
Offline
Зарегистрирован: 16.11.2015
              {
099       chislo = chislo * 10;         // до 59999
100      сhislo = chislo + key - 48;   // конвертируем ascii смволы в числа десятичной системы от 0 до 9.
101     }

А кто может прокомментировать вот этот фрагмент? Не могу понять каким образом получается ограничение до 59999 и что такое -48???

svm
Offline
Зарегистрирован: 06.11.2016

EuBeginer пишет:

 Не могу понять каким образом получается ограничение до 59999 и что такое -48???

По первому вопросу надо разбираться, а по второму все просто десятичный ASCII код получаемый с клавиатуры для  "0" - 48 , "1" - 49 и т.д (смотри таблицу) ASCII. Чтобы получить из 48 число  0 нужно от 48 отнять 48, а получить 1 из 49 можно так-же 49-48=1.

EuBeginer
Offline
Зарегистрирован: 16.11.2015

Ага усек, понял. А вот относительно *=10??? Я пробовал на практике. Если ввожу 0 то он так и остается на 0ой позиции экрана, а вот если 1-9 тогда происходит как бы сдвиг на разряд. И действительно если ввожу что-то большее 59999, например 60000, то в результате не предсказуемое число высвечивается. Но не пойму как это ограничение получилось, И можно ли например сделать ограничение 999999?

svm
Offline
Зарегистрирован: 06.11.2016

Ограничение скорее всего из за некорректного перевода из десятичных в шестнадцатеричные. По поводу нуля, проверяйте если "0", то писать в следующий разряд индикатора. Посмотрите работу с клавиатурой здесь http://arduino.ru/forum/programmirovanie/kontroller-led-i-klaviatury-fd650v-kak-im-upravlyat#comment-232263 , может, что-то почерпнете. до 9 999 999 работает корректно.

fogary
Offline
Зарегистрирован: 05.03.2016

Похоже автор скобки пропустил, по идеи должно быть так:

сhislo = chislo + (key - 48);

Максимально значение для типа "unsigned int" - 65535, так что ограничение в 999999 с этим типом не получиться, будет нужен "unsigned long int".

svm
Offline
Зарегистрирован: 06.11.2016

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

svm
Offline
Зарегистрирован: 06.11.2016

Сегодня пытался засунуть ардуино,дисплей и клавиатуру в корпус и отказался от этой затеи. Клавиатура занимает в два раза больше места чем все остальное. Взгляд упал на ПДУ от ресивера. В результате родилась идея использовать его вместо клавиатуры. Цифровые кнопки есть, есть типа джойстика и еще пара десятков кнопок "на вырост". Преимущества - резко уменьшаются размеры, не нужно встраивать клавиатуру в корпус, сокращается объем кода (опрос клавиатуры занимает 6% памяти, вместе с дисплеем 14%). Из электроники добавляется только IR приемник, которому необходин всего один пин ардуины. Для сокращения объема кода  вместо стандартной библиотеки  используется урезанная, только для NEC пультов. Но т.к. это самый распространенный вариант, то ничего страшного.

EuBeginer
Offline
Зарегистрирован: 16.11.2015

SVM и FOGARY спасибо! Да надо учить мат часть. Проверил действительно реальное ограничение задается описанием переменных. Приданном раскладе это 65535. Ну а при unsigned long int получатеся 4 294 967 295 (2 в 32й - четыре байта)

Остаюсь с unsigned int.