Aeyrwbz getKeys

maksmkv
Offline
Зарегистрирован: 07.04.2013

Всем привет. Есть кусок кода - чтение клавиш:

/** Read keydata block from PT6961
  *  @param  *keydata Ptr to Array of PT6961_KEY_MEM (=5) bytes for keydata
  *  @return bool keypress True when at least one key was pressed
  *
  * Note: Due to the hardware configuration the PT6961 key matrix scanner will detect multiple keys pressed at same time,
  *       but this may also result in some spurious keys being set in keypress data array.
  *       It may be best to ignore all keys in those situations. That option is implemented in this method depending on #define setting.  
  */ 
bool PT6961::getKeys(KeyData_t *keydata) {
  int keypress = 0;
  char data;

  // Read keys
  _cs=0;
  wait_us(1);    
  
  // Enable Key Read mode
  _spi.write(_flip(PT6961_DATA_SET_CMD | PT6961_KEY_RD | PT6961_ADDR_INC | PT6961_MODE_NORM)); // Data set cmd, normal mode, auto incr, read data

  for (int idx=0; idx < PT6961_KEY_MEM; idx++) {
    data = _flip(_spi.write(0xFF));    // read keys and correct bitorder

    data = data & PT6961_KEY_MSK; // Mask valid bits
    if (data != 0) {  // Check for any pressed key
      for (int bit=0; bit < 8; bit++) {
        if (data & (1 << bit)) {keypress++;} // Test all significant bits
      }
    }  

    (*keydata)[idx] = data;            // Store keydata after correcting bitorder
  }

  wait_us(1);
  _cs=1;    

  // Restore Data Write mode
  _writeCmd(PT6961_DATA_SET_CMD, PT6961_DATA_WR | PT6961_ADDR_INC | PT6961_MODE_NORM); // Data set cmd, normal mode, auto incr, write data  
      
#if(1)
// Dismiss multiple keypresses at same time
  return (keypress == 1);    
#else
// Allow multiple keypress and accept possible spurious keys
  return (keypress > 0);
#endif  
}


/** Helper to reverse all command or databits. The PT6961 expects LSB first, whereas SPI is MSB first
  *  @param  char data
  *  @return bitreversed data
  */ 
char PT6961::_flip(char data) {
 char value=0;
  
 if (data & 0x01) {value |= 0x80;} ;  
 if (data & 0x02) {value |= 0x40;} ;
 if (data & 0x04) {value |= 0x20;} ;
 if (data & 0x08) {value |= 0x10;} ;
 if (data & 0x10) {value |= 0x08;} ;
 if (data & 0x20) {value |= 0x04;} ;
 if (data & 0x40) {value |= 0x02;} ;
 if (data & 0x80) {value |= 0x01;} ;
 return value;       
}


/** Write command and parameter to PT6961
  *  @param  int cmd Command byte
  *  &Param  int data Parameters for command
  *  @return none
  */  
void PT6961::_writeCmd(int cmd, int data){
    
  _cs=0;
  wait_us(1);    
//  _spi.write(_flip( (cmd & 0xF0) | (data & 0x0F)));  
  _spi.write(_flip( (cmd & PT6961_CMD_MSK) | (data & ~PT6961_CMD_MSK)));   

  wait_us(1);
  _cs=1;          
}  

 

Используется так:


 *   while (1) {
 *    // Check and read keydata
 *    if (pt6961.getKeys(&keydata)) {
 *      pc.printf("Keydata 0..4 = 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\r\n", keydata[0], keydata[1], keydata[2], keydata[3], keydata[4]);
 *
 *      if (keydata[0] == 0x10) { //sw2   
 *        pt6961.cls(); 
 *        pt6961.writeData(all_str);
 *      }  
 *    } 

 

 

Помогите  переписать его под arduino?

 

 

mixail844
Offline
Зарегистрирован: 30.04.2012
помочь не равно написать за вас , 
начните сами , и если будут проблемы ,спрашивайте . или обратитесь в раздел "ищу исполнителя"
maksmkv
Offline
Зарегистрирован: 07.04.2013

Начал делать сам. Основываясь на различных похожих кодах. Почему мой код не работает - пишу по командам согласно datasheet???

https://github.com/maksmkv/PT6961/blob/main/test.ino

Спасибо. 

 

 

b707
Offline
Зарегистрирован: 26.05.2017

В чем выражается " не работает"? Код хотя бы компилируется?

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

Код компилируется, но на дисплее ни чего не отображается. Делаю не через аппаратный spi.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Мошт, ты пока этот код забросишь, и просто попытаешся вывести чонить на дисплей. И не через аппаратный SPI.

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

Это не аппаратный spi. Есть библиотеки, которые отображат символы и работают, но не используют кнопки. Я просто пытаюсь сам сделать все как мануале, но потом добавив кнопки. Правиль но в shiftout подавать char в аиде 0х00 или надо через for задвигать биты?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

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

maksmkv
Offline
Зарегистрирован: 07.04.2013

Все зажег  первые 8 знаков ))) 

#include <Arduino.h>

//    const static char _DISPLAY_6X12 = 0x02;
//    const static char _DISPLAY_7X11 = 0x03;
//    const static char _AUTO_INCREMENT = 0x40;
//    const static char _FIXED_ADDRESS = 0x44;
//    const static char _DISPLAY_OFF = 0x80;
//    const static char _DISPLAY_1_16 = 0x88;
//    const static char _DISPLAY_2_16 = 0x89;
//    const static char _DISPLAY_4_16 = 0x8A;
//    const static char _DISPLAY_10_16 = 0x8B;
//    const static char _DISPLAY_11_16 = 0x8C;
//    const static char _DISPLAY_12_16 = 0x8D;
//    const static char _DISPLAY_13_16 = 0x8E;
//    const static char _DISPLAY_14_16 = 0x8F;


uint8_t DIN = 4; //DIN
uint8_t CLK = 3; //CLK
uint8_t CS = 2; //CS

void command1() //set display to 6x12 segments
{
    digitalWrite(CS, LOW);  //
    digitalWrite(CLK, LOW);
    digitalWrite(DIN, LOW);
      shiftOut(DIN, CLK, LSBFIRST, 0b00000011); // SET COMMAND 1
    digitalWrite(CS, HIGH);  //
    digitalWrite(CLK, HIGH);
    digitalWrite(DIN, HIGH);
    Serial.print("command1\n");
}  

void command2() {
    digitalWrite(CS, LOW);  //
    digitalWrite(CLK, LOW);
    digitalWrite(DIN, LOW);
    shiftOut(DIN, CLK, LSBFIRST, 0b01000000); // SET COMMAND 2 write
    digitalWrite(CS, HIGH);  //
    digitalWrite(CLK, HIGH);
    digitalWrite(DIN, HIGH);
    Serial.print("command2\n");
}

void command3() // Заполнение RAM нулями SET COMMAND 2
{
    digitalWrite(CS, LOW);  //
    digitalWrite(CLK, LOW);
    digitalWrite(DIN, LOW);
    shiftOut(DIN, CLK, LSBFIRST, 0b11000000);
      for(int i=0; i<8; i++)
      {
        shiftOut(DIN, CLK, LSBFIRST, 0b00000000);
      }
    digitalWrite(CS, HIGH);  //
    digitalWrite(CLK, HIGH);
    digitalWrite(DIN, HIGH);
    Serial.print("command3\n");
}

void command4() //display on, max brightness
{
    digitalWrite(CS, LOW);  //
    digitalWrite(CLK, LOW);
    digitalWrite(DIN, LOW);
    shiftOut(DIN, CLK, LSBFIRST, 0b10001111); // SET COMMAND 4
    digitalWrite(CS, HIGH);  //
    digitalWrite(CLK, HIGH);
    digitalWrite(DIN, HIGH);
    Serial.print("command4\n");
}


void setup() {
  pinMode(DIN, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(CS, OUTPUT);

Serial.begin(9600);
  command2();
  command3();
  command1();
  command4();

}

void loop() 
{
  digitalWrite(CS,LOW);
  shiftOut(DIN, CLK, LSBFIRST, byte(0xC0));
  shiftOut(DIN, CLK, LSBFIRST, 0b11111111);
  Serial.print("Code ON\n");
  digitalWrite(CS,HIGH);
}

 

b707
Offline
Зарегистрирован: 26.05.2017

maksmkv пишет:

Все зажег  первые 8 знаков )))

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

Не пришло в голову. что процедуры command1, 2 и 4 - практически одинаковые и их можно записать как-то по-приличнее. чем тупо копировать три раза?

maksmkv
Offline
Зарегистрирован: 07.04.2013

Согласен, пока что делаю в тупую, далее переделаю.

 

Не буду создавать новую тему, может подскажите:   есть код от TM168 (единственное различие между мои PT6961 - это у первого совместный вход/выход DIO, а у меня это раздельные порты). 

Почему использую код из http://arduino.ru/forum/proekty/korpus-ot-drs-8300-v-arduino-proektakh   - чтения клавиш:

#define KEY_1   0x0800
#define KEY_2   0x0100
#define KEY_3   0x0008
#define KEY_4   0x0001

//  Чтение состояния кнопок с TM1668
//
	void readKeyData(uint16_t * data) {
	    digitalWrite(PIN_STB, LOW);
	    shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, 0x42);  // чтение данных
	    pinMode(PIN_DIO, INPUT_PULLUP);
	    delayMicroseconds(1);
	    * data = shiftIn(PIN_DIO, PIN_CLK, LSBFIRST) + (shiftIn(PIN_DIO, PIN_CLK, LSBFIRST) << 8);
	    pinMode(PIN_DIO, OUTPUT);
	    digitalWrite(PIN_STB, HIGH);
	}

.........

void loop(){
	//	Читаем состояние кнопок
	// и отрабатываем команды
	//
	static uint16_t keys = 0;
	uint16_t newKeys;
	readKeyData(& newKeys);
	if (keys != newKeys) {
		keys = newKeys;
		if (keys & KEY_1) {	// уменьшить яркость
			decreaseBrightness();
		}
		if (keys & KEY_2) {	// увеличить яркость
			increaseBrightness();
		}
		if (keys & KEY_3)	{	// включить следующий доп. символ
			swicthExtraSymbol(); 
			haveToUpdate = true;
		}
		if (keys & KEY_4)  {	// сбросить время в 0
			m = 0; 
			s = 0; 
			showClock(m, s);
			haveToUpdate = true;
			oldMillis = currMillis;
		}
	}

	//

 

Переделал под свою PT6961:

#define KEY_1   0x0800
#define KEY_2   0x0100
#define KEY_3   0x0008
#define KEY_4   0x0001

uint8_t DIN = 4; //DIN
uint8_t CLK = 3; //CLK
uint8_t CS = 2; //CS

uint8_t DOUT = 5;

void readKeyData(uint16_t * data) {
     
    digitalWrite(CS, LOW);  //
    digitalWrite(CLK, LOW);
    digitalWrite(DIN, LOW);
     shiftOut(DOUT, CLK, LSBFIRST, 0x42);  // чтение данных
     pinMode(DOUT, INPUT);
     delayMicroseconds(1);
     * data = shiftIn(DOUT, CLK, LSBFIRST) + (shiftIn(DOUT, CLK, LSBFIRST) << 8);
    pinMode(DOUT, INPUT);
      digitalWrite(CS, HIGH);  //
    digitalWrite(CLK, HIGH);
    digitalWrite(DIN, HIGH);
}


......

void loop() 
{
  static uint16_t keys = 0;
  uint16_t newKeys; // 2 байта
  readKeyData(& newKeys);
  if (keys != newKeys) {
    keys = newKeys;
    if (keys & KEY_1) 
    {
        Serial.println("Key1");
        }
    if (keys & KEY_2) 
    { 
      Serial.println("Key2");
    }
    if (keys & KEY_3) 
    { 
      Serial.println("Key3");
    }
   
  }
}

 

В консоль выходит:

Key1

Key2

Key3

Хотя, должно выводит в зпависимости от нажатой кнопки

 

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ты не поверишь, выводит он именно то, что должен.  Если это не совпадает с виденьем программиста, то это проблема программиста.  Никак не твоя. Забей.