Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av DanielM »

Jag startar en annat tråd om specifikt J1939-21 om hur man skickar multimeddelanden via CAN med hjälp utav J1939-21.

Grunderna:
Vi kan börja med grunderna. J1939-21 är alltså ett CAN-bus protokoll för att skicka data fram och tillbaka. J1939-21 formar alltså meddelanden. Det är ingen mjukvara med andra ord, utan snarare regler på hur saker och ting ska se ut.
I J1939-21 så finns det något som heter ACU och ECU. ACU är alltså t.ex. motorer, givare osv. ECU är alltså din dator som är uppkopplad på CAN-bus-nätverket. ECU:n sätter du till en valfri adress igenom att bara säga att du har en adress. Jag väljer att min ECU adress ska vara 0x22. ACU har för nuvarande 0x8D som källadress. ACU har också en destinationsadress, som jag inte vet direkt vad den är. Men i denna frågeställning så fyller den ingen funktion.

Skicka 8 byte data:
Att skicka data med J1939-21 kan enkelt göras igenom att sätta sitt ID och data. ID består utav operation, destination och vart det skickas från någonstans. Datat är alltså det du vill skicka. Max 8 bit.
Notera att J1939-21 använder utökad IT-typ.

Kod: Markera allt

static void write_j1939_message(uint32_t ID, uint8_t data[]) {
	txMessage.frame.idType = dEXTENDED_CAN_MSG_ID_2_0B;
	txMessage.frame.id = ID;
	txMessage.frame.dlc = 8;
	txMessage.frame.data0 = data[0];
	txMessage.frame.data1 = data[1];
	txMessage.frame.data2 = data[2];
	txMessage.frame.data3 = data[3];
	txMessage.frame.data4 = data[4];
	txMessage.frame.data5 = data[5];
	txMessage.frame.data6 = data[6];
	txMessage.frame.data7 = data[7];
	CANSPI_Transmit(&txMessage);
}
Skicka mer än 8 byte data:
För att skicka data som är längre än 8 så börjar man anropa något som heter Transport Protocol. Connexion Management Broadcast Announce Message, även kalalt TP BAM.
Där efter så skickar man sin data i antal korrekt mängder som kallas för Transport Protocol.Data Transfer, men även kallat TP DT

Procedur TP BAM:

Först så skapar man sitt ID för TP BAM. ID skall vara 0x1CEC"DA""SA", där DA är din destination t.ex. ACU adressen och SA är din källa t.ex. ECU adressen.
Där efter fyller du in din data byte1...byte8. Denna TP BAM är viktig för att meddela mottagaren att hur mycket data som kommer skickas och hur många omgångar det kommer skickas.
Markering_064.png
Procedur TP DT:
Efter man har skickat sitt TP BAM till mottagaren så är det bara att skicka sin data vid TP DT.
Här skall ID vara 0x1CEB"DA""SA". Alltså det skiljer sig lite från TP BAM. Där efter fyller man i data som beskriver vilken omgång det är och vad det är för data.
Markering_065.png
Tid mellan meddelanden:
För varje meddelande man skickar så måste man vänta 50 till 100 ms.
Markering_066.png
Praktiken:
Nu tänker jag skicka data. Det jag tänker göra är att ändra ACU:ns källadress till 0x83. Men det fungerar inte för mig.

Kod: Markera allt

        /* Skicka TP BAM */
	uint32_t ID_BAM = 0x1CECFF22; // TP BAM ID där 0xFF är destinationen(Broadcast with DA = 255) och 0x22(källan där vi skickar ifrån) är min ACU adress. Jag har själv valt att kalla den för 0x22. Jag kan lika gärna kalla den för 0x8D.
	uint8_t data_BAM[8];
	data_BAM[0] = 0x20; // Kontroll byte - Denna indikerar att vi ska skicka BAM meddelande. 
	data_BAM[1] = 0x9; // Vi ska skicka totalt bytes!
	data_BAM[2] = 0; // Antalet bytes. data_BAM[1] är alltså LSB och data_BAM[2] är MSB.
	data_BAM[3] = 0x2; // Hur många omgångar ska vi skicka. I detta fall två omgångar.
	data_BAM[4] = 0x0; // Används inte
	data_BAM[5] = 0xD8;
	data_BAM[6] = 0xFE;
	data_BAM[7] = 0x0; // data[5] till data[7] är allså PGN nummret. PGN nummret betyder vilken operation vi skall utföra, i detta fall byta källadress på ACU:n. data_BAM[5] är LSB och data_BAM[7] är MSB.
	write_j1939_message(ID_BAM, data_BAM);
	HAL_Delay(100);
	
	/* Skicka omgång 1 */
	uint32_t ID_TP = 0x1CEBFF22; // TP DT ID som skiljer sig inte mycket från TP BAM ID
	uint8_t data1[8] = {0x1, 0x0, 0x0, 0xE0, 0x28, 0x0, 0x81, 0x2}; // Första elementet är alltså omgång 1
	write_j1939_message(ID_TP, data1);
	HAL_Delay(100);
	
	/* Skicka omgång 2 */
	uint8_t data2[8] = {0x2, 0x20, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // Första elementet är omgång 2 där element nummer 3 är 0x80 = Nya källadressen för ACU(nuvarande 
	write_j1939_message(ID_TP, data2);
	HAL_Delay(200);

Om ni undrar vad övriga data betyder på omgångarna så är det dessa typer av data. CA Name är alltså identiteten på ACU:n. Här kan vi bestämma vad ACU:n skall heta och vad den ska ha i för uppgift.
Markering_067.png
Markering_068.png
Byta adress på ACU:
För att byta adress på ACU:n så måste vi alltså skicka 9 bytes. Där dom första 8 bytes är identiteten och uppgifterna på ACU:n.
9:e byte är alltså nya källadressen på ACU:n.

Som du ser här så använder vi PGN = 0xD8 0xFE 0x00 när vi skickar TP BAM för det betyder just Commanded address. Notera att PGN är LSB, inte MSB.
Markering_069.png
Markering_070.png
Frågeställning:
Trots att jag skickar datat ovan så ändras inte min källadress på ACU:n. Varför inte då? Har jag missat något?
Jag har bifogat protokollet.

För det första så KAN jag skriva till den. Jag kan styra min ACU igenom detta. Detta betyder att min ACU fungerar. Men jag kan ändå inte sätta källadressen på den.

Kod: Markera allt

// Write flow between -250 and 250
void write_sonceboz_valve_command(uint8_t DA, uint8_t SA, float flow){
	uint8_t state;
	if (flow > 0) {
		state = 0x1; // Extend
	} else if (flow < 0) {
		state = 0x2; // Retract
	} else {
		state = 0x0; // Neutral
	}
	uint32_t ID = (0x0CFE << 16) | (DA << 8) | SA;
	uint8_t data[8] = {fabsf(flow), 0xFF, state, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
	write_j1939_message(ID, data);
}
TCI SENSE 42 Version 3.0-25-49.pdf
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av sodjan »

Med reservation för att jag har missförstått, men jag tror inte jag har gjort det...

> ACU har för nuvarande 0x8D som källadress.

Nej, den har 0x8D som *adress*.

> ACU har också en destinationsadress...

Nej, den har bara en (1) *adress*. Target och source adresserna finns
bara i meddelanden, inte definitionsmässigt i själva ACU'n. Där finns
enbart *en* adress.

På samma sätt som att *du* ju bara har *ett* namn, oavsett om du skickar
eller tar emot ett brev på posten. Du har ju inte ett namn för att skicka ett
brev och ett annat namn för att ta emot ett brev, eller hur?

Jämför med en IP adress. Du har ju inte två olika IP adresser, en för att ta
emot TCPIP paket och för att skicka. Du har bara *en* IP adress. I själva
TCPIP paketet finns det däremot två fält som är "source" och "target".

Huruvida ACU'ns adress är "source" eller "target" beror enbart på om
meddelandey kommer från (source) eller är på väg till (target) ACU'n.

Men det är inte två olika adresser, rent numeriskt...

> Det jag tänker göra är att ändra ACU:ns källadress till 0x83...
> Första elementet är omgång 2 där element nummer 3 är 0x80 = Nya källadressen...

Det där hänger inte riktigt ihop för mig...

Jag antar att om man ska ändra adress på en ACU som har adress 0x80 till 0x83,
så skickar men ett meddelandet "ändra adress" till "target address" 0x80 och i
själva meddelandet/kommandot ingår nya adressen "0x83" som en del av datat.
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av DanielM »

Tack för upplysningen. Då vet jag att ACU har bara en adress. Men läser du i protokollet som bifogas så kan du se att sonceboz talar om två olika adresser på ACU.

Men jag litar mer på dig än på Sonceboz.
Jag antar att om man ska ändra adress på en ACU som har adress 0x80 till 0x83,
så skickar men ett meddelandet "ändra adress" till "target address" 0x80 och i
själva meddelandet/kommandot ingår nya adressen "0x83" som en del av datat.
Min ACU har adressen 0x8D. Denna får jag vid Adress Claimed ID vid start. Jag vill ändra 0x8D till t.ex 0x80. Målet är att lära sig ändra adress med J1939.

Jag gör ju det. Men inget händer. Det är som att meddelandet går inte fram eller att den förstod inte vad ECU sade.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av sodjan »

> Då vet jag att ACU har bara en adress.

Alltså... Det jag skriver är mina tolkningar och gissningar för vad som jag tycker är rimligt.
Du måste så klart ta det och sedan väga det med annan info och din egen uppfattning.
Du ska absolut inte ta mina punkter som definitiva sanningar...

> Min ACU har adressen 0x8D...

OK. Jag kanske ser fel, men förekommer inte även 0x80 i ditt inlägg? Vad är det?

> Jag vill ändra 0x8D till t.ex 0x80.

OK. Då ska du väl skicka ett "change address" (eller vad det nu kallas) till
"terget address" 0x8D med "0x80" som en del av kommandot.

Men vad betyder i så fall:

> Det jag tänker göra är att ändra ACU:ns källadress till 0x83.

Var kommer 0x83 ifrån?

Skit samma. Det primära som jag vill säga, är att jag tror att du har fel
om du tror att "target" och "source" adress skulle vara *olika* adresser...
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av DanielM »

sodjan skrev: 13 augusti 2020, 00:02:37
Alltså... Det jag skriver är mina tolkningar och gissningar för vad som jag tycker är rimligt.
Du måste så klart ta det och sedan väga det med annan info och din egen uppfattning.
Du ska absolut inte ta mina punkter som definitiva sanningar...
Sluta vara så övertygande då :wink:
OK. Jag kanske ser fel, men förekommer inte även 0x80 i ditt inlägg? Vad är det?
Jag skrev fel. Jag trodde jag hade korrigerat detta. Men glömde detta ord.

> Jag vill ändra 0x8D till t.ex 0x80.
OK. Då ska du väl skicka ett "change address" (eller vad det nu kallas) till
"terget address" 0x8D med "0x80" som en del av kommandot.

Men vad betyder i så fall:
Jo. Men hur gör man ett "change"? Jag tycker jag har redan gjort detta, men ändå ändras källadressen inte.

Felskrivning. Jag vill ändra 0x8D till 0x80. Punkt :)
Skit samma. Det primära som jag vill säga, är att jag tror att du har fel
om du tror att "target" och "source" adress skulle vara *olika* adresser...
Du kan ju titta i protokollet :) finns på en av dom första sidorna. Sök efter "destination address".
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av sodjan »

> Jag skrev fel.

Ge f-n i att skriva fel! Speciellt i uppgifter som är kritiska för att förstå det hela.

> Sök efter "destination address".

Ja, självklart finns det en "destination address" om du kollar på protokollnivå!

Men du tjatar ju även om att varje pryl ska ha två olika adresser, det har de
högst sannolikt inte. Varför skulle de har det? Finns ingen som helst anledning...

Skit samma, du verkar fortfarande inte fatta.

> Jo. Men hur gör man ett "change"?

Fanns det inte ett kommando för det? Inte vet jag, men jag fattade att du beskrev det så.

> men ändå ändras källadressen inte.

Vad är så väldigt svårt att fatta? Det finns ingen "källadress", utom på protokollnivå.
En ACU har enbart *EN* adress. Den kan kan vara antingen käll- eller måladress,
beroende på riktningen på meddelandet. Men det är enbart i protokollet.

Om ECU skickar till ACU så är ECU "source" och ACU "target".
Om ACU skickar till ECU så är ACU "source" och ECU "target".
Vilket säkert syns i protokollet.

Källadressen kan inte ändras, den finns bara i själva protokollet. En ACU har bara en "adress"
som alltså kan vara antingen käll- eller måladress beroende på vad man gör.

Skit samma, återkom då/om du kan visa att ovanstående inte stämmer.
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av DanielM »

Tjadu...Du kan väll titta i protokollet som jag bifogade. Det är ett klippt protokoll som innehåller 24 sidor bara, istället för att skälla.

Den pratar om destinationsadress för ACU och källadress för ACU. Som kan även skrivas in på EEPROM.

Jag börjar tro att dina gissningar lyser en lite svag osäkerhet.
Användarvisningsbild
mrfrenzy
Co Admin
Inlägg: 14858
Blev medlem: 16 april 2006, 17:04:10

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av mrfrenzy »

Serienumret på ACU ska ju vara med i NAME. Har din ACU serienummer verkligen 0?
0 är troligen bara ett exempel dom använder i dokumentationen.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av sodjan »

Jag tänker inte kolla 24 sidor. Citera bara just den del som
talar om destinationsadress och källadress för ACU.
Och som alltså *inte* talar om själva protokollet utan
om de adresser som är lagrade i ACU'n.

*Protokollet* har så klart käll- och måladresser...
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av DanielM »

Sida 9.
By default the ACU industry group is "agricultural and forestry" (industry group number 2). The ACU source address is set by default to 128 (0x80). The ACU will use by default the destination address 34 (0x22). Note that the DA will not be filtered and the ACU will accept commands from any destination address.
Även SA och DA går att spara i ACU's eeprom.
Användarvisningsbild
mrfrenzy
Co Admin
Inlägg: 14858
Blev medlem: 16 april 2006, 17:04:10

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av mrfrenzy »

Det är lite förvirrande språk.
Den texten betyder att dom förutsätter att din ECU har adress 0x22.
ACU tar emot meddelanden FRÅN alla adresser
ACU skickar bara TILL adress 0x22 även om frågan kom från en annan adress.

Om du ska skicka ett meddelande från ECU till ACU blir SA=0x22 och DA=0x80.
När ACU skickar ett meddelande til ECU blir SA=0x80 och DA=0x22

Om din ECU skulle ha adress 0x11 så kommer ACU (felaktigt) ta emot ett meddelande med SA=0x11 och DA=0x80
Svaret kommer den skicka med SA=0x80 och DA=0x22 så du kommer aldrig se det.
Användarvisningsbild
hawkan
Inlägg: 2628
Blev medlem: 14 augusti 2011, 10:27:40

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av hawkan »

Här finns kod att titta på.
https://github.com/coryjfowler/MCP2515_lib som är j1939 utan att det nämns med ett ord (ojfr). Rad 600 finns en "write_id" man kan kolla hur de gör där.
copperhilltech.com har också massor om j1939. Källkod här http://copperhilltech.com/content/jCOM- ... e-Code.zip för exemplet här https://copperhilltech.com/blog/sae-j19 ... der-linux/
Inte exakt vad du frågar efter men om det är något fel du gör kanske koden kan hjälpa till för att jämföra.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43178
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av sodjan »

Ah, OK... Så den DA som man anger i en ACU är inte ACU'ns egen DA, utan en förväntad adress för ECU'n.
Ja det förklarar ju allt. Sen så står det även att denna DA ändå inte används, i och för sig. ACU'n accepterar
meddelanden från vilken avsändare som helst i alla fall, men svarar alltid till 0x22 (eller sannolikt den
konfigurerade DA'n i ACU'n). Hade kanske varit tydligare om denna parameter hade kallats "ECU address"...

Men det betyder att man, rent teoretiskt, kan ändra DA i ACU och ha en annan adress än 0x22 på ECU (?).
Användarvisningsbild
mrfrenzy
Co Admin
Inlägg: 14858
Blev medlem: 16 april 2006, 17:04:10

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av mrfrenzy »

På vissa enheter kan man ändra ECU adress, på andra inte. Det framgår om man läser manualen.
Vissa dieselmotorer till exempel kräver att din ECU (PLC) har adress 23.
DanielM
Inlägg: 2192
Blev medlem: 5 september 2019, 14:19:58

Re: Transport protokoll i J1939-21 - Hur gör man för skicka 9 bytes?

Inlägg av DanielM »

mrfrenzy skrev: 13 augusti 2020, 01:01:07 Serienumret på ACU ska ju vara med i NAME. Har din ACU serienummer verkligen 0?
0 är troligen bara ett exempel dom använder i dokumentationen.
Mitt serienummer är 12. Allt annat stämmer. Jag har testat med olika serienummer men inget verkar fungera.
Skriv svar