Ik heb een gek probleem. Ik probeer een LTC6811 (12cell BMS chip) aan de gang te krijgen. Uitlezen lukt, het telegram bestaat dan uit 2 bytes met het commandonummer en 2 bytes PEC (CRC). De PECberekening in mijn code werkt dus (groot en deels) naar behoren.
MAAR: als ik registers wil schrijven moet ik de PEC berekenen voor alle bytes die ik stuur. De bijgevoegde afbeelding is wat de datasheet zegt over de berekening van de PEC.
Met 1 word werkt het, dus ik vermoed dat het niet in de for-loop ligt, anders zou het met 1 word ook niet werken. Maar buiten die for-loop zit alleen het extra bitje 0 op de LSB van de PEC. Ik heb uit gekkigheid even geprobeerd dat na elk word te doen, maar zoals verwacht werkte dat niet.
Als ik een register uitlees waar 6 keer 0 in staat krijg ik terug: [255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 194, 18, 0, 0, 0, 0, 0, 0, 194, 18]. Eerst 4 bytes waar ik cmd en pec naar de chip stuur. Dan 0 voor alle 6 de words in dat register met de uitkomst van de pec die de chip berekend heeft. Daarna nog een tweede keer datzelfde omdat ik twee chips in daisychain heb staan. Als ik (0, 0, 0, 0, 0, 0) in mijn PEC berekenig stop krijg ik (174, 34). Dat zou dus (194,18) moeten zijn...
Wie o wie heeft het verlossende woord, want na 2 avonden en anderhalve dag hier naar staren begin ik een beetje scheel te kijken
. Alvast bedankt!
EDIT: opgelost, ik was de eikel, bytes krijgen uit het een, worden sturen naar het ander, en dat even niet helder hebben. Zie laatste post voor meer info
Mijn code:
def PECcalculation(*input):
PEC = [0] * 15
PEC[4] = 1
for value in input:
din = value
for i in range(15, -1, -1): # Iterate from bit 15 to bit 0
# omgekeerd door het woord heen stappen
DIN_i = ((din >> i) & 1)
# In bitjes
IN0 = DIN_i ^ PEC[14]
IN3 = IN0 ^ PEC[2]
IN4 = IN0 ^ PEC[3]
IN7 = IN0 ^ PEC[6]
IN8 = IN0 ^ PEC[7]
IN10 = IN0 ^ PEC[9]
IN14 = IN0 ^ PEC[13]
# PEC bitjes
PEC[14] = IN14
PEC[13] = PEC[12]
PEC[12] = PEC[11]
PEC[11] = PEC[10]
PEC[10] = IN10
PEC[9] = PEC[8]
PEC[8] = IN8
PEC[7] = IN7
PEC[6] = PEC[5]
PEC[5] = PEC[4]
PEC[4] = IN4
PEC[3] = IN3
PEC[2] = PEC[1]
PEC[1] = PEC[0]
PEC[0] = IN0
# list naar int omzetten
PECint = sum(bit << idx for idx, bit in enumerate(PEC))
# 1 bit shiften en 0 in LSB zetten
PECint = PECint * 2
pec0, pec1 = extract_bytes(PECint)
return(pec0, pec1)buckfast_beekeeper
Van Lambiek wordt goede geuze gemaakt.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Enerzijds kan je iets doen als:
PEC = 0b0000000000010000; // check datasheet: ik heb niet geteld;
for bitnr = 0 ... nrofbits-1
PEC = PEC * 2;
DIN = bits[bitnr] ^ PEC[15]
if (DIN) PEC = PEC ^ 0b10001011...1001 // check datasheet
Anderzijds, met een 256 entry tabel kan het "per byte" nog veel sneller.
Afkijken van een werkende library is het makkelijkst.
Ik heb chatgpt de vraag gesteld zonder de taal te vermelden en dan maakt ie python:
def calculate_pec(data: bytes) -> int:
"""Calculate the PEC (Packet Error Code) for LTC6811 using CRC-8 polynomial 0x07."""
pec = 0x41 # LTC6811 starts with PEC seed 0x41
poly = 0x07 # CRC-8 polynomial x^8 + x^2 + x^1 + 1
for byte in data:
pec ^= byte # XOR with input data
for _ in range(8): # Process 8 bits
if pec & 0x80: # If MSB is 1
pec = (pec << 1) ^ poly # Left shift and XOR with polynomial
else:
pec <<= 1 # Left shift only
pec &= 0xFF # Ensure it's an 8-bit value
return pec # Returns 8-bit PEC
# Example usage:
data = bytes([0x00, 0x01, 0x3A]) # Example data to send
pec_result = calculate_pec(data)
print(f"PEC: 0x{pec_result:02X}")
Ik vermoed dat chatgpt het "het is een 8 bit polynomial" gefantaseerd heeft want volgens mij is ie 15 bit...
Op maandag 10 maart 2025 07:41:00 schreef buckfast_beekeeper:
Heb je deze code al eens doorgespit? Dat is de onderliggende library van de LTC6811 library.
Die had ik ook gevonden maar ik gebruik hem niet (ik begrijp graag wat ik doe ipv klakkeloos een library overnemen. Zeker omdat ik nog lerende ben met python). Ik heb wel geprobeerd om het truukje af te kijken maar in die library word een tabel gebruikt (die vervolgens niet te vinden is in die library.....).
Ik had zo het vage vermoeden dat het te maken had met de volgorde van de bytes waarin ik ze behandel. In de datasheet staat een volledige uitwerking van de berekening voor 0x0001 en daar komen alle tussenstappen exact overeen en voor 1 woord klopt het ook. Daarbij kan ik uit de chip makkelijk de uitkomst voor zes woorden aan 0 krijgen met bijkomend voordeel dat dan de volgorde geen bal uitmaakt, het is tenslotte toch allemaal nul.
Dank voor je reactie!
Op maandag 10 maart 2025 07:57:24 schreef rew:
Enerzijds kan je iets doen als:PEC = 0b0000000000010000; // check datasheet: ik heb niet geteld; for bitnr = 0 ... nrofbits-1 PEC = PEC * 2; DIN = bits[bitnr] ^ PEC[15] if (DIN) PEC = PEC ^ 0b10001011...1001 // check datasheetAnderzijds, met een 256 entry tabel kan het "per byte" nog veel sneller.
Afkijken van een werkende library is het makkelijkst.
Ik heb chatgpt de vraag gesteld zonder de taal te vermelden en dan maakt ie python:
def calculate_pec(data: bytes) -> int: """Calculate the PEC (Packet Error Code) for LTC6811 using CRC-8 polynomial 0x07.""" pec = 0x41 # LTC6811 starts with PEC seed 0x41 poly = 0x07 # CRC-8 polynomial x^8 + x^2 + x^1 + 1 for byte in data: pec ^= byte # XOR with input data for _ in range(8): # Process 8 bits if pec & 0x80: # If MSB is 1 pec = (pec << 1) ^ poly # Left shift and XOR with polynomial else: pec <<= 1 # Left shift only pec &= 0xFF # Ensure it's an 8-bit value return pec # Returns 8-bit PEC # Example usage: data = bytes([0x00, 0x01, 0x3A]) # Example data to send pec_result = calculate_pec(data) print(f"PEC: 0x{pec_result:02X}")Ik vermoed dat chatgpt het "het is een 8 bit polynomial" gefantaseerd heeft want volgens mij is ie 15 bit...
Haha ik kom jou ook overal tegen he
Dank!
In die library word een tabel gebruikt ik vervolgens niet in die library kan vinden. Dus dat word ingewikkeld. Daarbij word dit toch redelijk stap voor stap in de datasheet behandeld. En vind ik een berekening toch wel eleganter... Al ben ik op dit punt ook bereid over te stappen naar een tabel. In de eerste instantie had ik andere problemen waardoor ik dus echt zo letterlijk mogelijk de uitleg van de datasheet gevolgd heb.
Ik begrijp graag wat mn code doet, zeker omdat ik nog lerende ben in python. Ik heb vaker te maken gehad met CRC achtige dingen en het is elke keer een geklooi van heb ik jou daar om het aan de gang te krijgen. Al is het tot nu toe altijd wel gelukt.
Ik heb hier ook uitgebreid met chatgpt aan het prutsen geweest. Onderandere met die hulp heb ik dit in elk geval aan de gang gekregen. Ik moest op diverse plekken dingen corrigeren, maar het was een aardige basis. Deze code heb ik ook laten controleren aan de hand van de datasheet en dat zou allemaal moeten kloppen volgens hem.
Ik zal vanavond eens proberen om die code die jij post aan de praat te krijgen. Het is inderdaad een 15bit polynomial en de pec begint ook niet met 0x41. Maar ik mis vanalles en nogwat aan stappen tussendoor. Als ik die berekening goed begrijp moet je echt bitje voor bitje er doorheenstappen en kan je niet (zoals chatgpt hier doet) een heel byte in een keer XOR met de pec... Dit is zo'n gevalletje van ik kan ongeveer volgen wat de code doet, maar hoe dit overeenkomt met wat er in de datasheet staat.... ik heb echt geen flauw benul. Daarom ben ik het handmatig gaan maken, zodat ik snap wat er staat en kan controleren wat er mis gaat als het niet werkt.
EricP
mét CE
Het probleem met CRC ed. is dat er een hele wetenschap achter zit over het berekenen van zo'n ding. Het zit een beetje in de hoek van de cryptografie. Alhoewel ik er wel veel mee gewerkt heb, heb ik het 'begrijpen' een beetje opgegeven - vergt teveel studie.
Er zitten wat foefjes in om te voorkomen dat 2 bitfouten elkaar makkelijk opheffen - wat bij een checksum appeltje-eitje is.
Die tabel is waarschijnlijk gegenereerd op basis van 'halve' berekeningen en dat wordt wel vaker gedaan uit performance overwegingen: als de tabel beperkt is qua omvang en de berekeningen zijn relatief complex, dan is een look-up veel 'goedkoper' dan rekenen. Voor 5 bytes zal het wel niet zo spannend zijn, voor grotere hoeveelheden data kan het aanzienlijk schelen.
buckfast_beekeeper
Van Lambiek wordt goede geuze gemaakt.
Op maandag 10 maart 2025 08:50:43 schreef DaanSteeman:
[...]Die had ik ook gevonden maar ik gebruik hem niet (ik begrijp graag wat ik doe ipv klakkeloos een library overnemen. Zeker omdat ik nog lerende ben met python). Ik heb wel geprobeerd om het truukje af te kijken maar in die library word een tabel gebruikt (die vervolgens niet te vinden is in die library.....).
[...]
Die tabel moet te vinden zijn. Of in het header bestand of in een andere library waarnaar gelinkt wordt. Het meest logische in een header bestand dat door meerdere library's wordt gebruikt.
Wie zoekt die vind? In LTC681X.h vanaf regel 770.
#ifdef MBED
//This needs a PROGMEM = when using with a LINDUINO
const uint16_t crc15Table[256] {0x0,0xc599, 0xceab, 0xb32, 0xd8cf, 0x1d56, 0x1664, 0xd3fd, 0xf407, 0x319e, 0x3aac, // precomputed CRC15 Table
0xff35, 0x2cc8, 0xe951, 0xe263, 0x27fa, 0xad97, 0x680e, 0x633c, 0xa6a5, 0x7558, 0xb0c1,
0xbbf3, 0x7e6a, 0x5990, 0x9c09, 0x973b, 0x52a2, 0x815f, 0x44c6, 0x4ff4, 0x8a6d, 0x5b2e,
0x9eb7, 0x9585, 0x501c, 0x83e1, 0x4678, 0x4d4a, 0x88d3, 0xaf29, 0x6ab0, 0x6182, 0xa41b,
0x77e6, 0xb27f, 0xb94d, 0x7cd4, 0xf6b9, 0x3320, 0x3812, 0xfd8b, 0x2e76, 0xebef, 0xe0dd,
0x2544, 0x2be, 0xc727, 0xcc15, 0x98c, 0xda71, 0x1fe8, 0x14da, 0xd143, 0xf3c5, 0x365c,
0x3d6e, 0xf8f7,0x2b0a, 0xee93, 0xe5a1, 0x2038, 0x7c2, 0xc25b, 0xc969, 0xcf0, 0xdf0d,
0x1a94, 0x11a6, 0xd43f, 0x5e52, 0x9bcb, 0x90f9, 0x5560, 0x869d, 0x4304, 0x4836, 0x8daf,
0xaa55, 0x6fcc, 0x64fe, 0xa167, 0x729a, 0xb703, 0xbc31, 0x79a8, 0xa8eb, 0x6d72, 0x6640,
0xa3d9, 0x7024, 0xb5bd, 0xbe8f, 0x7b16, 0x5cec, 0x9975, 0x9247, 0x57de, 0x8423, 0x41ba,
0x4a88, 0x8f11, 0x57c, 0xc0e5, 0xcbd7, 0xe4e, 0xddb3, 0x182a, 0x1318, 0xd681, 0xf17b,
0x34e2, 0x3fd0, 0xfa49, 0x29b4, 0xec2d, 0xe71f, 0x2286, 0xa213, 0x678a, 0x6cb8, 0xa921,
0x7adc, 0xbf45, 0xb477, 0x71ee, 0x5614, 0x938d, 0x98bf, 0x5d26, 0x8edb, 0x4b42, 0x4070,
0x85e9, 0xf84, 0xca1d, 0xc12f, 0x4b6, 0xd74b, 0x12d2, 0x19e0, 0xdc79, 0xfb83, 0x3e1a, 0x3528,
0xf0b1, 0x234c, 0xe6d5, 0xede7, 0x287e, 0xf93d, 0x3ca4, 0x3796, 0xf20f, 0x21f2, 0xe46b, 0xef59,
0x2ac0, 0xd3a, 0xc8a3, 0xc391, 0x608, 0xd5f5, 0x106c, 0x1b5e, 0xdec7, 0x54aa, 0x9133, 0x9a01,
0x5f98, 0x8c65, 0x49fc, 0x42ce, 0x8757, 0xa0ad, 0x6534, 0x6e06, 0xab9f, 0x7862, 0xbdfb, 0xb6c9,
0x7350, 0x51d6, 0x944f, 0x9f7d, 0x5ae4, 0x8919, 0x4c80, 0x47b2, 0x822b, 0xa5d1, 0x6048, 0x6b7a,
0xaee3, 0x7d1e, 0xb887, 0xb3b5, 0x762c, 0xfc41, 0x39d8, 0x32ea, 0xf773, 0x248e, 0xe117, 0xea25,
0x2fbc, 0x846, 0xcddf, 0xc6ed, 0x374, 0xd089, 0x1510, 0x1e22, 0xdbbb, 0xaf8, 0xcf61, 0xc453,
0x1ca, 0xd237, 0x17ae, 0x1c9c, 0xd905, 0xfeff, 0x3b66, 0x3054, 0xf5cd, 0x2630, 0xe3a9, 0xe89b,
0x2d02, 0xa76f, 0x62f6, 0x69c4, 0xac5d, 0x7fa0, 0xba39, 0xb10b, 0x7492, 0x5368, 0x96f1, 0x9dc3,
0x585a, 0x8ba7, 0x4e3e, 0x450c, 0x8095
};
#else
const uint16_t crc15Table[256] PROGMEM = {0x0,0xc599, 0xceab, 0xb32, 0xd8cf, 0x1d56, 0x1664, 0xd3fd, 0xf407, 0x319e, 0x3aac, // precomputed CRC15 Table
0xff35, 0x2cc8, 0xe951, 0xe263, 0x27fa, 0xad97, 0x680e, 0x633c, 0xa6a5, 0x7558, 0xb0c1,
0xbbf3, 0x7e6a, 0x5990, 0x9c09, 0x973b, 0x52a2, 0x815f, 0x44c6, 0x4ff4, 0x8a6d, 0x5b2e,
0x9eb7, 0x9585, 0x501c, 0x83e1, 0x4678, 0x4d4a, 0x88d3, 0xaf29, 0x6ab0, 0x6182, 0xa41b,
0x77e6, 0xb27f, 0xb94d, 0x7cd4, 0xf6b9, 0x3320, 0x3812, 0xfd8b, 0x2e76, 0xebef, 0xe0dd,
0x2544, 0x2be, 0xc727, 0xcc15, 0x98c, 0xda71, 0x1fe8, 0x14da, 0xd143, 0xf3c5, 0x365c,
0x3d6e, 0xf8f7,0x2b0a, 0xee93, 0xe5a1, 0x2038, 0x7c2, 0xc25b, 0xc969, 0xcf0, 0xdf0d,
0x1a94, 0x11a6, 0xd43f, 0x5e52, 0x9bcb, 0x90f9, 0x5560, 0x869d, 0x4304, 0x4836, 0x8daf,
0xaa55, 0x6fcc, 0x64fe, 0xa167, 0x729a, 0xb703, 0xbc31, 0x79a8, 0xa8eb, 0x6d72, 0x6640,
0xa3d9, 0x7024, 0xb5bd, 0xbe8f, 0x7b16, 0x5cec, 0x9975, 0x9247, 0x57de, 0x8423, 0x41ba,
0x4a88, 0x8f11, 0x57c, 0xc0e5, 0xcbd7, 0xe4e, 0xddb3, 0x182a, 0x1318, 0xd681, 0xf17b,
0x34e2, 0x3fd0, 0xfa49, 0x29b4, 0xec2d, 0xe71f, 0x2286, 0xa213, 0x678a, 0x6cb8, 0xa921,
0x7adc, 0xbf45, 0xb477, 0x71ee, 0x5614, 0x938d, 0x98bf, 0x5d26, 0x8edb, 0x4b42, 0x4070,
0x85e9, 0xf84, 0xca1d, 0xc12f, 0x4b6, 0xd74b, 0x12d2, 0x19e0, 0xdc79, 0xfb83, 0x3e1a, 0x3528,
0xf0b1, 0x234c, 0xe6d5, 0xede7, 0x287e, 0xf93d, 0x3ca4, 0x3796, 0xf20f, 0x21f2, 0xe46b, 0xef59,
0x2ac0, 0xd3a, 0xc8a3, 0xc391, 0x608, 0xd5f5, 0x106c, 0x1b5e, 0xdec7, 0x54aa, 0x9133, 0x9a01,
0x5f98, 0x8c65, 0x49fc, 0x42ce, 0x8757, 0xa0ad, 0x6534, 0x6e06, 0xab9f, 0x7862, 0xbdfb, 0xb6c9,
0x7350, 0x51d6, 0x944f, 0x9f7d, 0x5ae4, 0x8919, 0x4c80, 0x47b2, 0x822b, 0xa5d1, 0x6048, 0x6b7a,
0xaee3, 0x7d1e, 0xb887, 0xb3b5, 0x762c, 0xfc41, 0x39d8, 0x32ea, 0xf773, 0x248e, 0xe117, 0xea25,
0x2fbc, 0x846, 0xcddf, 0xc6ed, 0x374, 0xd089, 0x1510, 0x1e22, 0xdbbb, 0xaf8, 0xcf61, 0xc453,
0x1ca, 0xd237, 0x17ae, 0x1c9c, 0xd905, 0xfeff, 0x3b66, 0x3054, 0xf5cd, 0x2630, 0xe3a9, 0xe89b,
0x2d02, 0xa76f, 0x62f6, 0x69c4, 0xac5d, 0x7fa0, 0xba39, 0xb10b, 0x7492, 0x5368, 0x96f1, 0x9dc3,
0x585a, 0x8ba7, 0x4e3e, 0x450c, 0x8095
};
#endif
#endifOp maandag 10 maart 2025 10:59:35 schreef EricP:
Het probleem met CRC ed. is dat er een hele wetenschap achter zit over het berekenen van zo'n ding. Het zit een beetje in de hoek van de cryptografie. Alhoewel ik er wel veel mee gewerkt heb, heb ik het 'begrijpen' een beetje opgegeven - vergt teveel studie.
Er zitten wat foefjes in om te voorkomen dat 2 bitfouten elkaar makkelijk opheffen - wat bij een checksum appeltje-eitje is.Die tabel is waarschijnlijk gegenereerd op basis van 'halve' berekeningen en dat wordt wel vaker gedaan uit performance overwegingen: als de tabel beperkt is qua omvang en de berekeningen zijn relatief complex, dan is een look-up veel 'goedkoper' dan rekenen. Voor 5 bytes zal het wel niet zo spannend zijn, voor grotere hoeveelheden data kan het aanzienlijk schelen.
Het begrijpen van de berekening heb ik volledig opgegeven
. Maar als ik het vrijwel letterlijk overneem van de datasheet zou ik toch verwachten dat dat goed zou moeten gaan. Wat ook lijkt te kloppen gezien het feit dat het werkt met 1 word. Plus: dan kan ik het checken of het werkt zoals de datasheet beweerd dat het zou moeten werken. Die tabel is echt een complete black box voor mij.
Op maandag 10 maart 2025 11:52:08 schreef buckfast_beekeeper:
[...]
Die tabel moet te vinden zijn. Of in het header bestand of in een andere library waarnaar gelinkt wordt. Het meest logische in een header bestand dat door meerdere library's wordt gebruikt.Wie zoekt die vind? In LTC681X.h vanaf regel 770.
#ifdef MBED //This needs a PROGMEM = when using with a LINDUINO const uint16_t crc15Table[256] {0x0,0xc599, 0xceab, 0xb32, 0xd8cf, 0x1d56, 0x1664, 0xd3fd, 0xf407, 0x319e, 0x3aac, // precomputed CRC15 Table 0xff35, 0x2cc8, 0xe951, 0xe263, 0x27fa, 0xad97, 0x680e, 0x633c, 0xa6a5, 0x7558, 0xb0c1, 0xbbf3, 0x7e6a, 0x5990, 0x9c09, 0x973b, 0x52a2, 0x815f, 0x44c6, 0x4ff4, 0x8a6d, 0x5b2e, 0x9eb7, 0x9585, 0x501c, 0x83e1, 0x4678, 0x4d4a, 0x88d3, 0xaf29, 0x6ab0, 0x6182, 0xa41b, 0x77e6, 0xb27f, 0xb94d, 0x7cd4, 0xf6b9, 0x3320, 0x3812, 0xfd8b, 0x2e76, 0xebef, 0xe0dd, 0x2544, 0x2be, 0xc727, 0xcc15, 0x98c, 0xda71, 0x1fe8, 0x14da, 0xd143, 0xf3c5, 0x365c, 0x3d6e, 0xf8f7,0x2b0a, 0xee93, 0xe5a1, 0x2038, 0x7c2, 0xc25b, 0xc969, 0xcf0, 0xdf0d, 0x1a94, 0x11a6, 0xd43f, 0x5e52, 0x9bcb, 0x90f9, 0x5560, 0x869d, 0x4304, 0x4836, 0x8daf, 0xaa55, 0x6fcc, 0x64fe, 0xa167, 0x729a, 0xb703, 0xbc31, 0x79a8, 0xa8eb, 0x6d72, 0x6640, 0xa3d9, 0x7024, 0xb5bd, 0xbe8f, 0x7b16, 0x5cec, 0x9975, 0x9247, 0x57de, 0x8423, 0x41ba, 0x4a88, 0x8f11, 0x57c, 0xc0e5, 0xcbd7, 0xe4e, 0xddb3, 0x182a, 0x1318, 0xd681, 0xf17b, 0x34e2, 0x3fd0, 0xfa49, 0x29b4, 0xec2d, 0xe71f, 0x2286, 0xa213, 0x678a, 0x6cb8, 0xa921, 0x7adc, 0xbf45, 0xb477, 0x71ee, 0x5614, 0x938d, 0x98bf, 0x5d26, 0x8edb, 0x4b42, 0x4070, 0x85e9, 0xf84, 0xca1d, 0xc12f, 0x4b6, 0xd74b, 0x12d2, 0x19e0, 0xdc79, 0xfb83, 0x3e1a, 0x3528, 0xf0b1, 0x234c, 0xe6d5, 0xede7, 0x287e, 0xf93d, 0x3ca4, 0x3796, 0xf20f, 0x21f2, 0xe46b, 0xef59, 0x2ac0, 0xd3a, 0xc8a3, 0xc391, 0x608, 0xd5f5, 0x106c, 0x1b5e, 0xdec7, 0x54aa, 0x9133, 0x9a01, 0x5f98, 0x8c65, 0x49fc, 0x42ce, 0x8757, 0xa0ad, 0x6534, 0x6e06, 0xab9f, 0x7862, 0xbdfb, 0xb6c9, 0x7350, 0x51d6, 0x944f, 0x9f7d, 0x5ae4, 0x8919, 0x4c80, 0x47b2, 0x822b, 0xa5d1, 0x6048, 0x6b7a, 0xaee3, 0x7d1e, 0xb887, 0xb3b5, 0x762c, 0xfc41, 0x39d8, 0x32ea, 0xf773, 0x248e, 0xe117, 0xea25, 0x2fbc, 0x846, 0xcddf, 0xc6ed, 0x374, 0xd089, 0x1510, 0x1e22, 0xdbbb, 0xaf8, 0xcf61, 0xc453, 0x1ca, 0xd237, 0x17ae, 0x1c9c, 0xd905, 0xfeff, 0x3b66, 0x3054, 0xf5cd, 0x2630, 0xe3a9, 0xe89b, 0x2d02, 0xa76f, 0x62f6, 0x69c4, 0xac5d, 0x7fa0, 0xba39, 0xb10b, 0x7492, 0x5368, 0x96f1, 0x9dc3, 0x585a, 0x8ba7, 0x4e3e, 0x450c, 0x8095 }; #else const uint16_t crc15Table[256] PROGMEM = {0x0,0xc599, 0xceab, 0xb32, 0xd8cf, 0x1d56, 0x1664, 0xd3fd, 0xf407, 0x319e, 0x3aac, // precomputed CRC15 Table 0xff35, 0x2cc8, 0xe951, 0xe263, 0x27fa, 0xad97, 0x680e, 0x633c, 0xa6a5, 0x7558, 0xb0c1, 0xbbf3, 0x7e6a, 0x5990, 0x9c09, 0x973b, 0x52a2, 0x815f, 0x44c6, 0x4ff4, 0x8a6d, 0x5b2e, 0x9eb7, 0x9585, 0x501c, 0x83e1, 0x4678, 0x4d4a, 0x88d3, 0xaf29, 0x6ab0, 0x6182, 0xa41b, 0x77e6, 0xb27f, 0xb94d, 0x7cd4, 0xf6b9, 0x3320, 0x3812, 0xfd8b, 0x2e76, 0xebef, 0xe0dd, 0x2544, 0x2be, 0xc727, 0xcc15, 0x98c, 0xda71, 0x1fe8, 0x14da, 0xd143, 0xf3c5, 0x365c, 0x3d6e, 0xf8f7,0x2b0a, 0xee93, 0xe5a1, 0x2038, 0x7c2, 0xc25b, 0xc969, 0xcf0, 0xdf0d, 0x1a94, 0x11a6, 0xd43f, 0x5e52, 0x9bcb, 0x90f9, 0x5560, 0x869d, 0x4304, 0x4836, 0x8daf, 0xaa55, 0x6fcc, 0x64fe, 0xa167, 0x729a, 0xb703, 0xbc31, 0x79a8, 0xa8eb, 0x6d72, 0x6640, 0xa3d9, 0x7024, 0xb5bd, 0xbe8f, 0x7b16, 0x5cec, 0x9975, 0x9247, 0x57de, 0x8423, 0x41ba, 0x4a88, 0x8f11, 0x57c, 0xc0e5, 0xcbd7, 0xe4e, 0xddb3, 0x182a, 0x1318, 0xd681, 0xf17b, 0x34e2, 0x3fd0, 0xfa49, 0x29b4, 0xec2d, 0xe71f, 0x2286, 0xa213, 0x678a, 0x6cb8, 0xa921, 0x7adc, 0xbf45, 0xb477, 0x71ee, 0x5614, 0x938d, 0x98bf, 0x5d26, 0x8edb, 0x4b42, 0x4070, 0x85e9, 0xf84, 0xca1d, 0xc12f, 0x4b6, 0xd74b, 0x12d2, 0x19e0, 0xdc79, 0xfb83, 0x3e1a, 0x3528, 0xf0b1, 0x234c, 0xe6d5, 0xede7, 0x287e, 0xf93d, 0x3ca4, 0x3796, 0xf20f, 0x21f2, 0xe46b, 0xef59, 0x2ac0, 0xd3a, 0xc8a3, 0xc391, 0x608, 0xd5f5, 0x106c, 0x1b5e, 0xdec7, 0x54aa, 0x9133, 0x9a01, 0x5f98, 0x8c65, 0x49fc, 0x42ce, 0x8757, 0xa0ad, 0x6534, 0x6e06, 0xab9f, 0x7862, 0xbdfb, 0xb6c9, 0x7350, 0x51d6, 0x944f, 0x9f7d, 0x5ae4, 0x8919, 0x4c80, 0x47b2, 0x822b, 0xa5d1, 0x6048, 0x6b7a, 0xaee3, 0x7d1e, 0xb887, 0xb3b5, 0x762c, 0xfc41, 0x39d8, 0x32ea, 0xf773, 0x248e, 0xe117, 0xea25, 0x2fbc, 0x846, 0xcddf, 0xc6ed, 0x374, 0xd089, 0x1510, 0x1e22, 0xdbbb, 0xaf8, 0xcf61, 0xc453, 0x1ca, 0xd237, 0x17ae, 0x1c9c, 0xd905, 0xfeff, 0x3b66, 0x3054, 0xf5cd, 0x2630, 0xe3a9, 0xe89b, 0x2d02, 0xa76f, 0x62f6, 0x69c4, 0xac5d, 0x7fa0, 0xba39, 0xb10b, 0x7492, 0x5368, 0x96f1, 0x9dc3, 0x585a, 0x8ba7, 0x4e3e, 0x450c, 0x8095 }; #endif #endif
Ah oke, hij stond dus in een ander bestand... Ik dacht dat het in de zelfde bestand moet staan. Afijn, ik ben nog druk lerende in python en uberhaupt in dergelijke systemen. Tot nu toe deed ik vrijwel alleen PICjes programeren met picbasic. Dit lijkt er in veel aspecten een hoop op (het blijft toch programeren). Maar dit soort geintjes werkt toch echt wel even heel anders...
Ik heb de tabel in een testprogrammatje gekwakt met bijbehorende code (vertaald door chatgpt om fouten van mijn kant te voorkomen, al heb ik het natuurlijk wel gecheckt of het ergens op leek).
Nu komt er met 1 als input (decimaal) 109362 uit.... Dat past nieteens in een woord!?!?! Ook als ik bitjes weg gooi zodat ik op een 16 bit waarde uit kom klopt er geen ruk van. Als ik er 6 nullen in stop komt er een godsgruwelijk groot getal uit. Dus die code gaat toch niet helemaal lekker.
Ik ben nog aan het expirimenteren om uit te vissen waar dit precies mis gaat. Volgensmij zouden er met die bitshifts bitjes weg moeten vallen maar gaat python daar anders mee om dan C of zoiets...
EDIT: de regel waar het adres in berekend word voor de tabel. Daarbij worden dus de 7 minst significante bits genegeerd. Daarmee word bitje 4 (die op 1 staat bij de initialisatie) dus niet meegerekend. En vervolgens geAND met 0xFF. Dat voorkomt dat de waarde groter is dan 256. Ik neem aan dat dit een gevolg is van hoe de tabel opgebouwd is. Met andere woorden: het zal wel, library zegt dat het werkt. Het adres voor het eerste byte komt uit op 0. in de tabel staat daar ook 0. Dus het eerste byte doet niks. Terwijl als ik de berekening in de datasheet bekijk schuift bij alle bits die 0 zijn wel vanalles en nogwat in de PEC op.
Als ik chatgpt de C code laat draaien komt hij uit op 0x6588. Wat nieteens lijkt op wat de uitkomst zou moeten zijn....
Op maandag 10 maart 2025 07:57:24 schreef rew:
Enerzijds kan je iets doen als:PEC = 0b0000000000010000; // check datasheet: ik heb niet geteld; for bitnr = 0 ... nrofbits-1 PEC = PEC * 2; DIN = bits[bitnr] ^ PEC[15] if (DIN) PEC = PEC ^ 0b10001011...1001 // check datasheetAnderzijds, met een 256 entry tabel kan het "per byte" nog veel sneller.
Afkijken van een werkende library is het makkelijkst.
Ik heb chatgpt de vraag gesteld zonder de taal te vermelden en dan maakt ie python:
def calculate_pec(data: bytes) -> int: """Calculate the PEC (Packet Error Code) for LTC6811 using CRC-8 polynomial 0x07.""" pec = 0x41 # LTC6811 starts with PEC seed 0x41 poly = 0x07 # CRC-8 polynomial x^8 + x^2 + x^1 + 1 for byte in data: pec ^= byte # XOR with input data for _ in range(8): # Process 8 bits if pec & 0x80: # If MSB is 1 pec = (pec << 1) ^ poly # Left shift and XOR with polynomial else: pec <<= 1 # Left shift only pec &= 0xFF # Ensure it's an 8-bit value return pec # Returns 8-bit PEC # Example usage: data = bytes([0x00, 0x01, 0x3A]) # Example data to send pec_result = calculate_pec(data) print(f"PEC: 0x{pec_result:02X}")Ik vermoed dat chatgpt het "het is een 8 bit polynomial" gefantaseerd heeft want volgens mij is ie 15 bit...
Ik ben hier nog even mee aan het stoeien geweest. Er zaten inderdaad wat fantasietjes in. Interessant genoeg komt bij input (0,1) (het commando is altijd een 16 bits waarde. als ik alleen (1) stuur shift hij maar 8 bits en klopt er geen zak van) wel de juiste waarde uit(0x3D6E) dit is de uitkomst voor waarde 1 zoals in de datasheet voorgerekend word en waar mijn huidige code die echt draait ook op uit komt (en waar de chip dus op reageert dus die CRC klopt). Sterker nog, na wat expirimenteren komt jouw code (zei het gecorrigeerd voor gptz'n fantasietjes) telkens precies uit op waar mijn code ook op uit komt. Met andere woorden: met 1 woord (het commandowoord wat alles is wat ik nodig heb om een register te lezen van de chip) komt het goed uit en werkt het hele truukje dus. Maar zodra ik meer dan 1 woord er doorheen fiets klopt de uitkomst niet meer.
De gecorrigeerde code:
def calculate_pec15(data):
"""Calculate the PEC (Packet Error Code) using CRC-15 (0x4599 polynomial)."""
pec = 0x10 # PEC seed (decimal 16)
poly = 0x4599 # CRC-15 polynomial: x^15 + x^14 + x^10 + x^8 + x^7 + x^4 + x^3 + 1
for byte in data:
print("in = ", bin(byte))
print("pecin = ", bin(pec))
pec ^= (byte << 7) # Align input byte with the 15-bit remainder
for _ in range(8): # Process 8 bits
if pec & 0x4000: # If MSB (bit 15) is set
pec = ((pec << 1) ^ poly) & 0x7FFF # XOR with polynomial and mask to 15 bits
else:
pec = (pec << 1) & 0x7FFF # Just shift left and mask to 15 bits
print("out = ", bin(pec))
return pec << 1 # Shift left to make it a full 16-bit PEC valueOpgelost!
Als ik een register uitlees waar 6 keer 0 in staat krijg ik terug: [255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 194, 18, 0, 0, 0, 0, 0, 0, 194, 18]. Eerst 4 bytes waar ik cmd en pec naar de chip stuur. Dan 0 voor alle 6 de words in dat register met de uitkomst van de pec die de chip berekend heeft. Daarna nog een tweede keer datzelfde omdat ik twee chips in daisychain heb staan. Als ik (0, 0, 0, 0, 0, 0) in mijn PEC berekenig stop krijg ik (174, 34). Dat zou dus (194,18) moeten zijn...
Ja DUH, wat ik terugkrijg zijn bytes. 8 bits waardes dus. Wat ik de PECberekening in gooi zijn words... 16 bits. Dus als ik (0, 0, 0, 0, 0, 0) die berekening in knal gaat hij de PEC berekenen voor 6 woorden van elk 16 bits. Dát gaat natuurlijk niet goed. als ik (0, 0, 0) er in fiets krijg ik, je raad het nooit, (18, 194) (bytes zijn geswapt, maar daar houd ik rekening mee).
Conclusie: de PEC klopt, ook met een input van meer dan 1 word. Dat ik sommige registers lees en 255,255,255,255,etc of 0,0,0,0,etc terug krijg. En het schrijven in sommige registers niet lukt ligt in elk geval niet aan de PEC. Maargoed, daar kan ik rustig zelf eerst eens even op gaan puzzelen.
Iedereen dank voor de input, maar ik was gewoon zelf de eikel 
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
De beschrijving in het datasheet gaat er van uit dat data per bit aan dat schuif-xor ding gevoerd wordt. Per byte moet je dat in de juiste volgorde doen, ofwel van hoog naar laag of andersom. Sla jij de boel in words van 16 bits op, moet je de bytes ook nog in de juiste volgorde uit de words halen.
Op dinsdag 11 maart 2025 07:34:36 schreef rew:
De beschrijving in het datasheet gaat er van uit dat data per bit aan dat schuif-xor ding gevoerd wordt. Per byte moet je dat in de juiste volgorde doen, ofwel van hoog naar laag of andersom. Sla jij de boel in words van 16 bits op, moet je de bytes ook nog in de juiste volgorde uit de words halen.
I know, maar daarvan wist ik zeker dat het werkte omdat het met 1 word wel goed ging. Het is een kwestie van acterwaards door dat word heen fietsen, beginnen bij msb en dan naar lsb werken.