Hi,
so, die erste Achse ist beinahe fertig und ich werde demnächst ein Vidscho vom Test hier einstellen. Aber erst muss ich einen Bug lösen der mir von den externen Encodern einen Positionswert liefert der 5 Mal so gross ist wie er eigentlich sein sollte. Da hat mir wohl der Compiler nen Streich gespielt, da die C Logik meines Erachtens nach stimmt.
Auszug aus dem ExtEncoder Kommandoselector (Slave):
Code:
.
.
.
/* POS READ */
case CMD_GETPOS1:
// return Bits 0..6
iResponse = (uint8_t)(snapshot_pos & 0x7F);
break;
case CMD_GETPOS2:
// return Bits 7..13
/* 091120 OM results in slow compiled asm code!
iResponse = (uint8_t)((snapshot_pos>>7) & 0x7F);
*/
// byte0 bit7 and byte1 bit0..5
iResponse = *((uint8_t*)(&snapshot_pos) + 0) >> 7;
iResponse |= (*((uint8_t*)(&snapshot_pos) + 1) & 0x3F) << 1;
break;
case CMD_GETPOS3:
// return Bits 14..20
/* 091120 OM results in slow compiled asm code!
iResponse = (uint8_t)((snapshot_pos>>14) & 0x7F);
*/
// byte1 bit6..7 and byte2 bit 0..4
iResponse = *((uint8_t*)(&snapshot_pos) + 1) >> 6;
iResponse |= (*((uint8_t*)(&snapshot_pos) + 2) & 0x1F) << 2;
break;
/* SPEED READ */
case CMD_GETSPEED1:
// return Bits 0..6
iResponse = (uint8_t)(snapshot_speed & 0x7F);
break;
case CMD_GETSPEED2:
// return Bits 7..13
iResponse = (uint8_t)((snapshot_speed>>7) & 0x7F);
break;
.
.
.
.. und der Master
Code:
// Read signed 14 bit value from encoder
uint8_t eenc_cmd_query14BIT(uint8_t aWR_Mask,uint8_t aRDY_Mask,uint8_t aCmdBase,int16_t* aVal) {
uint8_t iBuf;
int8_t i;
// Query bits 13..7, 6..0 from rotencoder slave of axe X
*aVal = 0UL;
for (i = 1; i >= 0; i--) {
if (P9WI_SlaveQuery(aWR_Mask, aRDY_Mask, aCmdBase + i, &iBuf, EENC_TIMEOUT) != P9WI_OK)
return S_FALSE;
// save data nibbles
*aVal |= (int16_t)(iBuf & 0x7F);
// shift left if not last data nibble
if (i > 0)
*aVal <<= 7;
}
// Check if it is a negative number, bit 13 is "1" in this case
if (*aVal & 0x2000)
*aVal |= 0xC000;
return S_OK;
}
/*
.
.
.
Read signed 21 bit value from encoder
*/
uint8_t eenc_cmd_query21BIT(uint8_t aWR_Mask,uint8_t aRDY_Mask,uint8_t aCmdBase,int32_t* aVal) {
uint8_t iBuf;
int8_t i;
// Query bits 20..14, 13..7, 6..0 from rotencoder slave of axe X
*aVal = 0ULL;
for (i = 2; i >= 0; i--) {
if (P9WI_SlaveQuery(aWR_Mask, aRDY_Mask, aCmdBase + i, &iBuf, EENC_TIMEOUT) != P9WI_OK)
return S_FALSE;
// save data nibbles
*aVal |= (int32_t)(iBuf & 0x7F);
// shift left if not last data nibble
if (i > 0)
*aVal <<= 7;
}
// Check if it is a negative number, bit 20 is "1" in this case
if (*aVal & 0x100000)
*aVal |= 0xFFF00000;
return S_OK;
}
.
.
.
Die Daten werden jeweils zu sieben bit über den Datenbus vom ExtEncoder gepollt und anschliesend im Master wieder zusammengesetzt.
Ich dachte das der Kode so stimmen sollte, aber vielleicht ist der Fehler auch in der Lagereglung.
Den NC integrator habe ich für Linien (G00, G01) fertig und bereits mit compiliert, beschränke mich im Moment aber auf Testcases um die Parameter der Achsverstärker richtig abzustimmen. Der Testcase 3 fährt z.B. mit einer Amplitude von 20mm von der heutigen Position in die positive Richtung und anschliessend wieder auf den Ausgangspunkt zurück.
Der Vorgang wird für zehn verschiedene Vorschubwerte wiederholt F={40, 75, 150, 300, 600, 1200, 2400, ...}
Wenn die Position dann richtig ausgewertet wird, also nicht mehr 5 Mal so gross , werd ich den NC Integrator via Kommandozeile mit ISO Kodes füttern und den Part austesten. Den NC-Integrator hatte ich ja bereits in einem Simulator auf dem PC ausgetestet, der sollte also funktionieren falls der WinAVR Compiler mir nicht wieder einen Streich spielt.
Ok, stay tuned!
Bis zum Vidscho vom Test.
Gruss,
O.
Lesezeichen