Jump to content

Recommended Posts

Как минимум два человека (кроме меня) заинтересованы этой темой. Хорошо иметь возможность писать какой-то свой код, а не быть привязанным к MMJoy2, как бы хорош он ни был. В самом деле, есть DCS BIOS, который про TLE5010 не знает, есть платки Blue Pill (и не только они), которые в чём-то поинтереснее Ардуино... Я немного переписал опубликованный ранее код и убедился, что он на моём самодельном джойстике работает. Вопрос, конечно, насколько эффективно. Скажем, не следует ли заменить shiftIn/shiftOut и/или atan2 на что-то другое.

 

// эти пины использует mmjoy2
#define B6 10
#define B3 14
#define B1 15

// Этими выбираются два датчика TLE5010 
#define SEL1 8 //B4
#define SEL2 9 //B5

void setup() {
  unsigned char sreg;
  Serial.begin(9600);

  /* Save global interrupt flag */
  sreg = SREG;
  /* Disable interrupts */
  //__disable_interrupt();
  cli();     
  TCCR1A = 0x23;
  TCCR1B = 0x19;
  TCCR1C = 0x00;
  OCR1A = 3;
  OCR1B = 1;
  /* Restore global interrupt flag */
  SREG = sreg;

  pinMode(B6, OUTPUT); // B6 
  pinMode(B3, OUTPUT); // B3 
  pinMode(B1, OUTPUT); // B1 

  pinMode(SEL1, OUTPUT); // select
  pinMode(SEL2, OUTPUT); // select

  digitalWrite(SEL1, HIGH);
  digitalWrite(SEL2, HIGH);

}

void loop() {
  unsigned char sreg;
  double angle1=tle5010_angle(SEL1);
  double angle2=tle5010_angle(SEL2);
  delay(1500); 
  Serial.print(round(angle1));
  Serial.print(" ");
  Serial.println(round(angle2));
}


double tle5010_angle(int selection_pin){
  unsigned char xl, xh, yl, yh, crc, dummy;
  int x, y;  

  digitalWrite(selection_pin, LOW); // выбрал устройство
  
  pinMode(B3, OUTPUT); 
  digitalWrite(B1, LOW);
  shiftOut(B3, B1, MSBFIRST, 0); // B00000000 - update command!!
  digitalWrite(B1, HIGH);
  
  dummy = shiftIn(B3, B1, MSBFIRST); //?
     
                          // rw 0=write, 1=read
  unsigned char command;  // rw a3 a2 a1 a0 n2 n1 n0
  command  = 0x85;        //  1  0  0  0  0  1  0  1 = читать 5 байтов, начиная с нулевого
  
  digitalWrite(B1, LOW);  
  shiftOut(B3, B1, MSBFIRST, command);
  digitalWrite(B1, HIGH);

  pinMode(B3, INPUT_PULLUP); 
  digitalWrite(B1, LOW);
  dummy = shiftIn(B3, B1, MSBFIRST);
  xl    = shiftIn(B3, B1, MSBFIRST);
  xh    = shiftIn(B3, B1, MSBFIRST);
  yl    = shiftIn(B3, B1, MSBFIRST);
  yh    = shiftIn(B3, B1, MSBFIRST);
  crc   = shiftIn(B3, B1, MSBFIRST);
  dummy = shiftIn(B3, B1, MSBFIRST);

  digitalWrite(B1, HIGH);
  digitalWrite(selection_pin, HIGH);
  
  x = (int)(xl | (xh <<8));
  y = (int)(yl | (yh <<8));
  double angle = atan2((double)y,(double)x) / M_PI * 180 ;
  return angle;
}

 

Share this post


Link to post
Share on other sites

vvm13ru
так допишите уже и проверку CRC.
 

//расчет CRC8
uint8_t MathCRC8(uint8_t crc, uint8_t data)
{
	crc ^= data;
	for (uint8_t bit=0 ; bit<8 ; bit++ ) { if ((crc&0b10000000)!=0) { crc <<= 1; crc ^= 0x1D; } else { crc <<= 1; }; };
	return(crc);
};
//расчет контрольки
//crc = 0xFF;		
//crc = MathCRC8(crc, 0b00000000); //0_0000_000 (update all TLE5011)
//crc = MathCRC8(crc, 0b10001100); //1_0001_100 (read TLE5011 4 bytes)	 
crc = 0xFB;		
crc = MathCRC8(crc, tle5010_lnk[0]);
crc = MathCRC8(crc, tle5010_lnk[1]);
crc = MathCRC8(crc, tle5010_lnk[2]);
crc = MathCRC8(crc, tle5010_lnk[3]);				
crc = (~crc)&(0b11111111);
//проверка контрольки
if (crc == tle5010_lnk[4])
{
  //расчет математики и бла-бла-бла
};

 

9 часов назад, vvm13ru сказал:

command = 0x85; // 1 0 0 0 0 1 0 1 = читать 5 байтов, начиная с нулевого

 

9 часов назад, vvm13ru сказал:

dummy = shiftIn(B3, B1, MSBFIRST);
xl = shiftIn(B3, B1, MSBFIRST);
xh = shiftIn(B3, B1, MSBFIRST);
yl = shiftIn(B3, B1, MSBFIRST);
yh = shiftIn(B3, B1, MSBFIRST);
crc = shiftIn(B3, B1, MSBFIRST);
dummy = shiftIn(B3, B1, MSBFIRST);


и вот эти костыли требуют переосмысления

Share this post


Link to post
Share on other sites

Спасибо.

Что-то CRC у меня не получается.

// standard pins used by mmjoy
#define B6_GEN 10
#define B3_MISO 14
#define B1_SCK 15

// two TLE5010 chips selected by B4 and B5
#define NOT_CHIP_SELECT_1 8 //B4 // имя начинается с NOT, потому что выбрано - LOW, не выбрано - HIGH
#define NOT_CHIP_SELECT_2 9 //B5

void setup() {
  unsigned char sreg;
  Serial.begin(9600);

  /* Save global interrupt flag */
  sreg = SREG;
  /* Disable interrupts */
  //__disable_interrupt();
  cli();     
  TCCR1A = 0x23;
  TCCR1B = 0x19;
  TCCR1C = 0x00;
  OCR1A = 3;
  OCR1B = 1;
  /* Restore global interrupt flag */
  SREG = sreg;

  pinMode(B6_GEN, OUTPUT); // B6_GEN 
  pinMode(B3_MISO, OUTPUT); // B3_MISO 
  pinMode(B1_SCK, OUTPUT); // B1_SCK 

  pinMode(NOT_CHIP_SELECT_1, OUTPUT); // select
  pinMode(NOT_CHIP_SELECT_2, OUTPUT); // select

  digitalWrite(NOT_CHIP_SELECT_1, HIGH);
  digitalWrite(NOT_CHIP_SELECT_2, HIGH);

}

void loop() {
  double angle1=tle5010_angle(NOT_CHIP_SELECT_1);
  double angle2=tle5010_angle(NOT_CHIP_SELECT_2);
  delay(500); 
  Serial.print(" G ");
  Serial.print(round(angle1));
  Serial.print(" ");
  Serial.println(round(angle2));
}


double tle5010_angle(int not_chip_select){
  digitalWrite(not_chip_select, LOW); // выбрал устройство
  
  pinMode(B3_MISO, OUTPUT); 
  digitalWrite(B1_SCK, LOW);
  shiftOut(B3_MISO, B1_SCK, MSBFIRST, 0);     // B00000000 - update command!! 
  digitalWrite(B1_SCK, HIGH);                 
  
  unsigned char dummy;
  dummy = shiftIn(B3_MISO, B1_SCK, MSBFIRST); //?
     
                          // rw 0=write, 1=read
  unsigned char command;  // rw a3 a2 a1 a0 n2 n1 n0
  command  = 0x8C;        //  1  0  0  0  1  1  0  0 = читать 4 байта, начиная с первого
                              
  digitalWrite(B1_SCK, LOW);  
  shiftOut(B3_MISO, B1_SCK, MSBFIRST, command);
  digitalWrite(B1_SCK, HIGH);

  pinMode(B3_MISO, INPUT_PULLUP); 
  digitalWrite(B1_SCK, LOW);

  uint8_t xl, xh, yl, yh, calculatedCrc, tleCrc;
  int x, y;  

  xl     = shiftIn(B3_MISO, B1_SCK, MSBFIRST);
  xh     = shiftIn(B3_MISO, B1_SCK, MSBFIRST);
  yl     = shiftIn(B3_MISO, B1_SCK, MSBFIRST);
  yh     = shiftIn(B3_MISO, B1_SCK, MSBFIRST);
  tleCrc = shiftIn(B3_MISO, B1_SCK, MSBFIRST);

  calculatedCrc = 0xFB;    // пробовал также 0 и FF
  calculatedCrc = MathCRC8(calculatedCrc, xl);
  calculatedCrc = MathCRC8(calculatedCrc, xh);
  calculatedCrc = MathCRC8(calculatedCrc, yl);
  calculatedCrc = MathCRC8(calculatedCrc, yh);        
  calculatedCrc = (~calculatedCrc)&(0b11111111);
 
  digitalWrite(B1_SCK, HIGH);
  digitalWrite(not_chip_select, HIGH);
  if(calculatedCrc == tleCrc) Serial.print("="); else Serial.print("!");
  x = (int)(xl | (xh <<8));
  y = (int)(yl | (yh <<8));
  double angle = atan2((double)y,(double)x) / M_PI * 180 ;
  return angle;
}

uint8_t MathCRC8(uint8_t crc, uint8_t data)
{
  crc ^= data;
  for (uint8_t bit=0 ; bit<8 ; bit++ ) { if ((crc&0b10000000)!=0) { crc <<= 1; crc ^= 0x1D; } else { crc <<= 1; }; };
  return(crc);
};

 

Share this post


Link to post
Share on other sites

Было  кое-что лишнее, убрал, теперь CRC считается (см. ниже).

 

Теперь желательно сделать так, чтобы команду 00000000 отправлять сразу на все датчики. Нет, понятно, что сперва выбрать каждый

digitalWrite(not_chip_select, LOW);

потом отправить эту команду, затем развыбрать все, кроме одного, и оттуда взять x и y. Но не будет ли какой тонкости после этого момента... я довольно плохо понимаю то, что  написано в example2 - в смысле, примечание 3 говорит, что первый deactivated. но не говорит, что второй activated ).

 

А ещё интересно понять, как и можно ли из Raspberry Pi эту штуку подключить ( то бишь, как написать для неё аналог вот этого:

  TCCR1A = 0x23;
  TCCR1B = 0x19;
  TCCR1C = 0x00;
  OCR1A = 3;
  OCR1B = 1;

).

 

//http://avia-sim.ru/forum/viewtopic.php?f=28&t=935&p=31106#p31106

// standard pins used by mmjoy
#define B6_GEN 10
#define B3_MISO 14
#define B1_SCK 15

// two TLE5010 chips selected by B4 and B5
#define NOT_CHIP_SELECT_1 8 //B4 // имя начинается с NOT, потому что выбрано - LOW, не выбрано - HIGH
#define NOT_CHIP_SELECT_2 9 //B5

void setup() {
  unsigned char sreg;
  Serial.begin(9600);

  /* Save global interrupt flag */
  sreg = SREG;
  /* Disable interrupts */
  //__disable_interrupt();
  cli();     
  TCCR1A = 0x23;
  TCCR1B = 0x19;
  TCCR1C = 0x00;
  OCR1A = 3;
  OCR1B = 1;
  /* Restore global interrupt flag */
  SREG = sreg;

  pinMode(B6_GEN, OUTPUT); // B6_GEN 
  pinMode(B3_MISO, OUTPUT); // B3_MISO 
  pinMode(B1_SCK, OUTPUT); // B1_SCK 

  pinMode(NOT_CHIP_SELECT_1, OUTPUT); // select
  pinMode(NOT_CHIP_SELECT_2, OUTPUT); // select

  digitalWrite(NOT_CHIP_SELECT_1, HIGH);
  digitalWrite(NOT_CHIP_SELECT_2, HIGH);

}

void loop() {
  Serial.print(" h ");
  double angle1=tle5010_angle(NOT_CHIP_SELECT_1);
  double angle2=tle5010_angle(NOT_CHIP_SELECT_2);
  Serial.print(round(angle1));
  Serial.print(" ");
  Serial.println(round(angle2));
  delay(200); 
}

double tle5010_angle(int not_chip_select){
  digitalWrite(not_chip_select, LOW); // выбрал устройство
  
  pinMode(B3_MISO, OUTPUT); 
  digitalWrite(B1_SCK, LOW);
  shiftOut(B3_MISO, B1_SCK, MSBFIRST, 0);     // B00000000 - update command!! 

                          // rw 0=write, 1=read
                          // h  h  h  h  l  l  l  l
                          // c  c  c  c  n  n  n  n
  unsigned char command;  // rw a3 a2 a1 a0 n2 n1 n0
  command  = 0x8C;        //  1  0  0  0  1  1  0  0 = читать 4 байта, начиная с первого
  command  = 0b10001100;  //  1  0  0  0  1  1  0  0 = читать 4 байта, начиная с первого
                              
  digitalWrite(B1_SCK, LOW);  
  shiftOut(B3_MISO, B1_SCK, MSBFIRST, command);

  pinMode(B3_MISO, INPUT_PULLUP); 
  digitalWrite(B1_SCK, LOW);

  uint8_t xl, xh, yl, yh, tleCrc;
  int x, y;  

  xl     = shiftIn(B3_MISO, B1_SCK, MSBFIRST);
  xh     = shiftIn(B3_MISO, B1_SCK, MSBFIRST);
  yl     = shiftIn(B3_MISO, B1_SCK, MSBFIRST);
  yh     = shiftIn(B3_MISO, B1_SCK, MSBFIRST);
  tleCrc = shiftIn(B3_MISO, B1_SCK, MSBFIRST);

  digitalWrite(B1_SCK, HIGH);
  digitalWrite(not_chip_select, HIGH);

  if( checkCrc(xl, xh, yl, yh, tleCrc, (uint8_t)0xFB) ) {
    Serial.print("=");
  } else {
    Serial.print("!");
  }

  x = (int)(xl | (xh <<8));
  y = (int)(yl | (yh <<8));
  double angle = atan2((double)y,(double)x) / M_PI * 180 ;
  return angle;
}

int checkCrc(uint8_t xl, uint8_t xh, uint8_t yl, uint8_t yh, uint8_t tleCrc, uint8_t initialCrc) {
  uint8_t calculatedCrc;
  calculatedCrc = initialCrc;    
  calculatedCrc = MathCRC8(calculatedCrc, xl);
  calculatedCrc = MathCRC8(calculatedCrc, xh);
  calculatedCrc = MathCRC8(calculatedCrc, yl);
  calculatedCrc = MathCRC8(calculatedCrc, yh);        
  calculatedCrc = (~calculatedCrc)&(0b11111111);
  return (calculatedCrc == tleCrc);
}

uint8_t MathCRC8(uint8_t crc, uint8_t data)
{
  crc ^= data;
  for (uint8_t bit=0 ; bit<8 ; bit++ ) { 
    if ((crc & 0b10000000)!=0) { 
      crc <<= 1; 
      crc ^= 0x1D; 
    } else { 
      crc <<= 1; 
    }; 
  };
  return(crc);
};

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...