Kommunikation mellan olika processorer - Hur gör ni?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Al_Bundy »

Kaggen skrev:
Al_Bundy skrev:De börjar visa rätt tal nu, men ibland blir det 254 igen. Någon som vågar yrka på att det är glappt som gör så att det blir ett större värde än en byte?
Vet inte vad du menar riktigt, 254 ryms i en byte. 256 däremot är större än en byte.

Kan vara vad som helst som är fel. Vad får dig att tro att 254 är fel värde? Vad förväntade du dig istället?

Mest troliga en bugg i din kod, eller att du inte riktigt vet vilka värden du skall få. Felkoppling kanske. Tvivlar på glapp.
Om jag skickar ett tal typ t.e.x. 10 så får jag fram talet 191 eller 203. Det verkar som att den får större värde än vad som ges. Jag ska testa byta RX, TX pinnarna.

Det är inte bugg i min kod. I så fall skulle det vara bugg i Arduino.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Al_Bundy »

TomasL skrev:
Mina protokoll är av följande metoder:
1. Skicka, vänta, kolla. Om inte finns, skicka vänta...kolla. Upprepa.
2. Anropa plats för värde, kolla efter bekräftelse, är bekräftelse OK? -> skicka värde. Om bekräftelse är inte OK, skicka igen, kolla efter bekräftelse, är bekräftelse OK? -> skicka värde. Upprepa.
Detta är knappast något protokoll, kanske dags att lyssna lite och läsa på i stället för att svamla.
Knappast något protokoll? Du menar att många gör fel?

Kan du ge exempel på exempelkod eller pesudokod som visar ett riktigt protokoll?
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46974
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av TomasL »

Så kan ett protokoll se ut:
Header:
Byte 1: 0x55; protokollidentifierare
Byte 2: 0x00; alltid 0x00
Byte3-4: Paketlängd exklusive header och CRC
Payload:
BYte 5: Kommando
Byte 5+1 - 5+xx: Data
CRC:
Byte xx+1 - Byte xx+2 16 Bit CRC

Databyten behöver inte alltid finnas, beroende på vilket kommando man skickar.
Har man fast längd på Payloaden kan man skippa paketlängden


När det gäller kod så kör man naturligtvis allt med interrupt, både att skicka och ta emot.
Man har dessutom en time-out så att man kan detektera avbrott i kommunikationen, dvs har det inte kommit data inom x antal ms så skippar man det hela och startar om.
Man kan även specificera längsta mellanrum mellan två bytes i datagrammet, och även minsta tiden mellan två datagram.
Om man har flera mottagare på linan, som till exempel vid RS485, kan man lägga till adressbytes i början.
Vissa processorer har adressavkodning i hårdvaran, vilken då ofta initieras med att adressbiten är satt på första byten (i de lägena använder man sig av 9-bitars kommunikation i stället för 8-bitars)


Delar av en mottagningsrutin kan till exempel se ut så här:

Kod: Markera allt

if(mU1RXGetIntFlag() )
	{	
		INTEnable(INT_U1TX, INT_DISABLED);
		AQL_bus_TX_disable();
		
		while(UARTReceivedDataIsAvailable(RS485_AQL_UART_PORT) ) 
		{
			if ( U1STA & AQLB_COM_ERRORS ) {
				break;
			}
			
			AQLB_Rx_Pointer_u16++;
			if(AQLB_Rx_Pointer_u16 >= AQLB_RX_MAXBUFFER) 
			{
				AQLB_Rx_Pointer_u16 = 0;
				AQL_bus_RX_data.error = AQLB_ERR_BUFFER_FULL;
				global_data.W_Bus_stat.BUFFO_u32++;
				break;			
			}
			AQLB_Rx_data_u16 = U1RXREG;	//ReadUART1();
			
Skall man skicka, så gör man på ett snarlikt sätt
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Al_Bundy »

Så det är så ett protokoll ser ut. Och jag har inte kört med protokoll, bara interrupts?

Jag har gjort så att om den inte kommer inom X tid så skickar den igen och sedan läser av hela tiden.

Du säger "När det gäller kod så kör man naturligtvis allt med interrupt". Kan det vara jag som har tolkat fel och blandat ihop interrupts med protokoll och jag är inte behov av något protokoll egentligen?

Om jag skickar från TX till RX. Finns det sannolikhet att värdet jag skickar kan "missa" att hamna i mottagarens buffert?
Ibland när jag skickar så poff...så kommer den inte fram. Liksom tomt luft bara. Då får jag skicka igen.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46974
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av TomasL »

Kan det vara jag som har tolkat fel och blandat ihop interrupts med protokoll och jag är inte behov av något protokoll egentligen?
Ja du blandar ihop allt, eftersom du inte läser på och inte lyssnar, och jo du MÅSTE ha ett protokoll, annars vet du ju inte hur du skickar dina data.

Beträffande TX sidan,
Slå på interrupt för "Plats i TX-buffer/reg"

I Interruptrutinen fyller du sedan på TX-Buffern/TXREG, tills dess den är full, sedan hoppar du ut ur interruptet.
detta gör du ända tills dess att du skickat alla data, då stänger du av TX-interruptet och slår på RX-interruptet.

Naturligtvis är detta helt beroende på vilka resurser din processor har, så du behöver följaktligen noga läsa databladet för din specifika processor, för att kunna (förhoppningsvis) förstå hur den fungerar, dessutom måste du också läsa på hur ditt utvecklingssystem hanterar det hela, vilka funktioner du skall använda osv, allt detta finns naturligtvis i hjälpsystemet för din utvecklingsmiljö och tillhörande dokumentation.
Senast redigerad av TomasL 22 februari 2015, 11:51:03, redigerad totalt 1 gång.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Al_Bundy »

Vadå "Vet inte hur du skickar din data"? Det finns bara ett sätt att skicka och det är via write();
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Kaggen »

Har du samma baudrate på slaven och mastern?

Du använder software serial på både master och slav? Mastern är kopplad till LCD och skriver ut datan den får från slaven?

Kan hända att när mastern skriver på LCDn så kommer en byte från slaven, vilken den i så fall kan missa om du använder software serial. Jag vet dock inte hur software serial är implementerad i arduino. Gäller att vara försiktig med software serial, processorn måste timea in varenda bit och kan då inte syssla med så mycket annat under tiden. Bättre köra serial via hårdvara. Den genererar ett interrupt som talar om när det finns en byte redo.

Har du testat skicka från slaven enbart till en terminal? Se om det kommer rätt värden där?

Låter dock konstigt om det skulle vara en bugg i arduino. Folk har använt arduino i flera år över hela världen och skickat data mellan olika arduino och skrivit ut på display (är ju liksom steg 1.b efter blinka diod). Varför har inte dom upptäckt samma bugg i så fall?
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46974
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av TomasL »

SNÄLLA!!!!!! läs vad jag skrivit tidigare.
Protokollet talar om hur data skickas, i vilken ordning, i vilket format osv.
Är det Little eller Big endian, skickas CRC, finns det en header, hur lång är payloaden, hur långa är eventuella kommandon, vilka kommandon kan skickas osv.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Al_Bundy »

Kaggen skrev:Har du samma baudrate på slaven och mastern?
Japp. 9600 bauds
Du använder software serial på både master och slav? Mastern är kopplad till LCD och skriver ut datan den får från slaven?
Ja. Master är inkopplad till en LCD. Slaven är inkopplad till en dator.
Kan hända att när mastern skriver på LCDn så kommer en byte från slaven, vilken den i så fall kan missa om du använder software serial. Jag vet dock inte hur software serial är implementerad i arduino. Gäller att vara försiktig med software serial, processorn måste timea in varenda bit och kan då inte syssla med så mycket annat under tiden. Bättre köra serial via hårdvara. Den genererar ett interrupt som talar om när det finns en byte redo.
Det finns en interrupt som talar om att det finns en byte redo :)
Har du testat skicka från slaven enbart till en terminal? Se om det kommer rätt värden där?
Ja, då blir det rätt.
Master -> slave -> master -> slave -> dator: 255 eller högre.
Får master till slave går jättebra.
Men slave till master går inte bra.
Låter dock konstigt om det skulle vara en bugg i arduino. Folk har använt arduino i flera år över hela världen och skickat data mellan olika arduino och skrivit ut på display (är ju liksom steg 1.b efter blinka diod). Varför har inte dom upptäckt samma bugg i så fall?
Jag tycker också att det är konstigt.
Skickar jag talet 22 så hamnar jag runt 252-255.
Skickar jag talet 1 så hamnar jag runt 191-210.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Al_Bundy »

TomasL skrev:SNÄLLA!!!!!! läs vad jag skrivit tidigare.
Protokollet talar om hur data skickas, i vilken ordning, i vilket format osv.
Är det Little eller Big endian, skickas CRC, finns det en header, hur lång är payloaden, hur långa är eventuella kommandon, vilka kommandon kan skickas osv.
Men du förklarar så opedagogiskt så man blir mörkrädd. Sen när man frågar dig så blir du frustrerad.
Jag såg inte att du hade skrivit kod, du har troligtvis redigerat om ditt inlägg.

Ja. Jag ska läsa mer om hur protokoll fungerar.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46974
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av TomasL »

Nä jag blir inte frustrerad, dock blir jag lite irriterad när du inte läser, beträffande pedagogiken, tja det är ju inte en lågstadieklass här, eller????
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Al_Bundy »

Lågstadieklass?
Absolut inte lågstadieklass. Du spottar ut dig av något utan att direkt förklara ingående. Det du har gjort är att förklara att protokoll är inte exempelvis kod, utan något man skriver med papper och penna, eller ritar i MSpaint. Och interrupts är något man skriver med kod, bara kod.

Så nej. Lågstadieklass. No please.
Det är lätt för dig att förstå för du har gjort detta.

Så enligt dig så kan jag ta min penna och skriva på mitt papper hur kommunikationen ska flöda? Inte någon direkt standard att så ska det se ut?
Användarvisningsbild
Icecap
Inlägg: 26648
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Icecap »

Beträffande Little/Big Edian kan man lösa det vid att ha en överföring i textform.

Ska man t.ex. överföra två värden per block (det kan vara <Värde1 kommer här>, <12345>) kan man separera dom med ett lämplig tecken.

Men håller man sig till 1 enda värde (12345) kan man göra som följer:
1: Skriv värdet i ASCII-form till en buffer. Jag använder sprintf() för detta.
2: Skicka en pekare till blocket till rutinen som packar ihop ett block.

Funktionen som packar ihop ett block gör följande:
A: Skicka hela blocket, byte för byte.
B: Avsluta blocket vid att skicka "Slut på meddelandet", i detta fall '\r'.

Mottagningen är lika enkel:
Ta emot alla bytes. Innan de läggs i mottagningsbuffern kollas de om de matchar '\r'.
Gör de det markeras detta i en flagga och den byte läggs INTE till i buffern - men tecknet efter sista mottagna tecken ställs till 0x00.

För att omvandla den mottagna texten kan man använda atoi().

Detta sätt ger ett antal fördelar:
1: Man kan sniffa kommunikationen och se i klartext vad som händer.
2: All Little/Big Edian är som bortblåst.
3: Man kan lägga till en relativ enkel kontroll av mottagningsfel: alla tecken ska ju vara mellan '0' och '9', är de inte det är det något fel.
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Kaggen »

Al_Bundy skrev:Det finns en interrupt som talar om att det finns en byte redo :)
Så då använder du interrupt och lägger den "färdiga" byten i någon buffer då?
Al_Bundy skrev:
Har du testat skicka från slaven enbart till en terminal? Se om det kommer rätt värden där?
Ja, då blir det rätt.
Master -> slave -> master -> slave -> dator: 255 eller högre.
Får master till slave går jättebra.
Men slave till master går inte bra.
...
Jag tycker också att det är konstigt.
Skickar jag talet 22 så hamnar jag runt 252-255.
Skickar jag talet 1 så hamnar jag runt 191-210.
Här fattar jag inte ett skvatt. Vad menar du med "Master -> slave -> master -> slave -> dator: 255 eller högre."?

Jag menar att du skall skicka ett hårdkodat värde från slaven direkt till dator "Slave->dator termial". T.ex 65 vilket då borde bli tecknet "A" på terminalen om du skickar binärt eller tecknen "65" om du sickar ASCII.

Dessutom fattar jag inte varför du säger 255 eller högre är rätt, när du sedan säger att du skickar talet 22 eller 1. Högre än 255 innebär ju att talet du skickar är större än 1 byte. Tar du hänsyn till det i mottagaränden?
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Kommunikation mellan olika processorer - Hur gör ni?

Inlägg av Al_Bundy »

"B: Avsluta blocket vid att skicka "Slut på meddelandet", i detta fall '\r'."

Fast jag skickar bara ett tal t.ex 10 och sedan gör jag inget mer. Kan det vara så att jag måste skicka 13 också som är ASCII '\r' direkt efter jag har skickat talet 10.

Sändaren:
mySerial.write(ett tal t.ex. anrop);
while(1)
{
läs av inkommande.
if (inkommande bekäftelse == TRUE)
{
mySerial.write(ett värde nu);
break;
}
delay(X millisekunder);
if (Inget som inkommer?)
{
mySerial.write(ett tal t.ex. anrop);
}
}

Mottagaren:
while(1)
{
läs av
->vad var det för kommando?
->gå till en lista och utför opperationen
->Skicka ett värde tillbaka till sändaren.
-> Och här ska jag avsluta med mySerial.write(13)?
}
Skriv svar