Sida 2 av 3

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 12:40:55
av labmaster
Hej toffie!

Ibland är det lätt att röra till saker i onödan, speciellt när man blandar in siffror. När man visar siffror på en display konverteras den binära representationen till två tecken som ofta visas i hexadecimal form. Respektive tecken är egentligen också två binära tal. När du skriver ett hexadecimalt tal i källkoden omvandlar kompilatorn det till ett binärt tal.

Om du har ställt in UART för 8-bitars kommunikation i både sändare och mottagare behöver du inte omvandla de binära talen till två tecken innan du sänder dem. Om mottageran däremot är en terminalemulator så måste du omvandla talen innan du sänder dem annars kan du inte se vad det är för tal som sänds. Det beror ju på att terminalemulatorn är en displayenhet.

Om mottagaren är en annan dator som skall visa mottagna tal på åtta (8) dioder så behöver du inte omvandla till två tecken innan du sänder eftersom båda UART i både sändare och mottagare är inställda att jobba med åtta bitar.

Om du är smart så använder du binära tal som motsvarar en bokstav när du testkör seriekommunikationen mellan din AVR och terminalemulatorn. Då behöver du inte skriva en särskild konverteringsrutin. När du väl konstaterar att seriekommunikationen fungerar så behöver du inte bry dig om den längre. Du kommer i stort sett alltid att veta att det du skickar kommer över till mottagaren givet att det sker via tråd.

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 12:48:47
av jesse
Har bara skummat igenom tråden som hastigast, men det verkar vara total förvirring som råder här.
Om ni inte redan kommit fram till vad du ska göra och hur, så gör så här:

1) ange vad du vill åstadkomma.
2) hur ska det genomföras?

Ska du skicka fyra bitar, åtta bitar, en massa text (t.ex. text som bildar hexadecimala koder) eller vad?

Du måste bryta ner problemet (och processen) så att du förstår vad som sker i varje steg. Och blanda sean inte ihop dessa!

Men innan du kan gå i djupet och börja programmera måste du ju ha koll på hur olika tal och tecken representeras i programspråket C och hur de kan lagras i olika typ av variabler.

t.ex "åtta bitar" , en byte, lagras till exempel i variabeltypen char eller uint8_t.
En bokstav, eller ett tecken, lagras enligt en ascii-tabell i form av en åttabitars variabel, vanligtvis lagras denna i en "char"-variabel.
osv...

en "char"-variabel är i grunden alltid åtta bitar - ettor och nollor. Om den symboliserar ett numeriskt värde (t.ex. 65 eller 66) eller om den symboliserar ett ascii-tecken (t.ex 'A' eller 'B') vet inte kompilatorn/datorn/processorn. För den är en "char" alltid samma sak. Åtta bitar.

talet 65 (decimalt) kan även uttryckas som 'A', hexadecimalt som 0x41 eller binärt som 0b01000001. Det är fortfarande exakt samma sak. åtta bitar. 01000001.

'A' = 65 = 0x41 = 0b01000001.

Som du antagligen redan förstått nu, efter alla inlägg, så hade du alltså helt fel i första inlägget:
Jag skickar ett enstaka tecken, exempelvis "0" (noll).

Detta tecken, i binärt, ser ju ut som 0000.
Nej, nej, nej!

Om nu inte tecknte '0' är 00000000 binärt, vad är det då?

Gå in på ascii-tabellen och kolla.

Leta upp nollan. Du hittar den på position nr 48 i tabellen:

Kod: Markera allt

 ....
45	055	2D	00101101	-	-	 	Minus
46	056	2E	00101110	.	.	 	Punkt
47	057	2F	00101111	/	/	 	Divisionstecken (Slash)
48	060	30	00110000	0	0	 	Siffran 0
49	061	31	00110001	1	1	 	Siffran 1
50	062	32	00110010	2	2	 	Siffran 2
51	063	33	00110011	3	3	 	Siffran 3
....
Tecknet '0' motsvaras alltså av bitmönstret 00110000, vilket är samma sak som 48 decimalt, eller hexadecimalt 0x30.

Om man har en display som använder ascii-tecken så visar den alltså en nolla ('0') om man skickar talet 48 i form av en åtta-bitars byte till displayen.

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 12:52:52
av thebolt
sodjan skrev: - Skickar di bitmönster, använd binära värden.
Det som ska noteras är dock att C inte har något sätt att ange värden binärt, heltal(skonstanter) kan endast ange i bas 8, 10 och 16. Vill man sätta specifika bitar är ofta 16 (hex) att föredra då varje nibble (4-bitar) blir ett tecken.

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 13:03:23
av sodjan
> Det som ska noteras är dock att C inte har något sätt att ange värden binärt,

http://old.nabble.com/How-to-specifiy-b ... 72944.html
http://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html

Även de vanliga C produkterna för PIC (kollade PIC18 och HiTech-C) har så klart
stöd för binära konstanter/värden. Skulle bli lite svårjobbat annars.

Rör inte till det i onödan...

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 14:01:49
av toffie
Sodjan
Underbart beskrivet!

Kod: Markera allt

- Hello : "H1,0<CR>" (För att kolla om AVR'en är "vaken" vilken då svarar på lämplig sätt).
- Restart : "R1,0<CR> (Starta om firmware i AVR'en).
- Status : "S1, 3<CR> (AVR'en svarar med aktuellt status (on/off) för funktion nr 3).
Det är ju helt klart ett sätt att göra ett protokoll. Lätt att läsa är det åtminstone. Men det är väl fortfarande så att det skickas 5*8 bitar i ett sådant kommando, jämfört med om man bara skickar ett ASCII tecken, som blir 8 bitar.

Med det sagt så förstår jag allt du skrivit, det är inte så. Men jag tänker på datamängden. Visserligen kan man ju köra i 115kbps eller något och då går det ju undan. Det blir väl 115000 tecken per sekund, ca? Även om man, som jag kör just nu, använder 9600bps så blir det ju ganska många tecken per sekund.

Om man skulle använda två tecken för kommandot i protokollet, och om man skulle använda följande tecken;

Kod: Markera allt

abcdefghijklmnopqrstuvwxyz0123456789
Så betyder det att man har 36 kombinationer för vardera tecken, dvs 2*36 som blir 1296. Korrekt?
Det kan då finnas maximalt runt 1200 kommandon, det skulle ju vara rätt bra ;)


labmaster
Ibland? Det var till att vara positiv ;)
Enda problemet är att det är lite svårt att skriva exempelvis 0x0F som ett ASCII tecken, vilket gör det svårt att sända utan en konverteringsrutin. Du kanske vet hur?


jesse
Tack för den tankeställaren! Måste erkänna att jag är lite dålig på att tänka ut i detalj vad som ska göras i vissa fall. Brukar inte vara så när det gäller programmering och datorer, men AVR och C är undantaget förmodar jag ;)

Jag kan ju mycket av det du beskriver, jag vet inte varför jag inte tänker på det.

Sidan du länkade till var den bästa ASCII tabell jag sett, tackar för det! :)


Det kommer ju alltid nya frågor, det jag kom på nu var.. Hur skickar man ett <CR> tecken med C kod? exempelvis från en AVR. Med terminalen i AVR Studio finns ju en knapp, så det blir ju inte så svårt ;) Men om man skriver ett eget program, hur gör man då? Finns det något kommando eller vad ska jag skicka för tecken/teckensekvens? I PHP finns ju chr(10) som står för line feed.


Men nu kom jag ju på mer saker.. hur ska jag tolka den inkommande koden? Om vi tar "R1,0<CR>" som exempel. Jag vet exakt hur jag skulle göra i PHP. Jag skulle ta emot koden i en variabel (char i c?), dela den vid kommatecknet (split() i PHP) och ta reda på vilket kommando det gällde i första delen av den splittade variabeln och sedan vad för värde som skulle användas i den andra delen av den splittade variabeln.

Men jag har verkligen ingen aning om hur jag skulle göra det i C?
Först och främst, den buffert jag använder för tillfället tar ju emot en byte (8-bit) och trycker sedan ut den på displayen och tillbaka på UART'en. Ska jag ta varje inkommen byte, lägga de i en char array?

Ungefär så här;

Kod: Markera allt

char commandBytes[4];
commandBytes[] = inkommandeByte;
Sätter en char för totalt fyra tecken (R1,0), och sen lägger in varje inkommande byte i denna. Går det? Hur ska jag göra sen, ska jag göra en koll på hur många tecken som finns i commandBytes och när den har 4 bytes, så gör jag en jämförelse på den för att matcha mot ett existerande kommando

Kod: Markera allt

if ( commandBytes == "R1" )
Fast det går ju inte, då måste jag koda för varje olika värde som kan finnas efter kommatecknet också.
Tänker jag helt fel här eller vad ska jag tänka över huvudtaget?

Ett enstaka tecken kan ju kollas med exempelvis;

Kod: Markera allt

if ( commandBytes[3] == "0" )
Där jämför man ju värdet som finns efter kommatecknet. Men hur gör man för att matcha exempelvis två tecken? Eller ska man tänka på något annat sätt?


Jag har som sagt försökt läsa mig till det jag frågar om, men jag har vissa svårigheter som gör att det ibland inte är så lätt att förstå, även om jag läser om samma sak flera gånger. Därav anledningen till att jag frågar er som kan så mycket mer och uppenbarligen är väldigt duktiga på att förklara också.

Men det sagt, jag är inte helt bakom flötet, jag kan ganska mycket om programmering i C men jag vet inte alltid vad för funktioner som finns och vad jag kan använda mig, vilken funktion som kan vara bra att använda vid ett visst tillfälle. Det är något jag har svårt att förstå.

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 14:14:23
av sodjan
> Men det är väl fortfarande så att det skickas 5*8 bitar i ett sådant kommando,
> jämfört med om man bara skickar ett ASCII tecken, som blir 8 bitar.

Är det ett problem ?

> Men jag tänker på datamängden...

Du har inte sagt ett smack om vilka krav du har när det gäller det.
Så självklart har jag helt struntat i det. Om du *har* specifika krav
kring det, så får du ju säga det! Men annars är det ju "bara" att
anpassa hastigheten så att det hela hinns med.

> Hur skickar man ett <CR> tecken med C kod?

"\r". Se även : http://msdn.microsoft.com/en-us/library ... 80%29.aspx
Eller 0x0D eller 0b00001101 eller på vilket annat sätt som passar dig bäst.

> Först och främst, den buffert jag använder för tillfället tar ju emot en byte (8-bit)

Gör den större. Fyll en buffert tills det kommer en <CR> *då* kollar du vilket "kommando"
det var och paramterar o.s.v.

Parametern (efter kommat) kan du konvertera till ett numeriskt värde om du vill. Det beror
ju lite på från kommando till kommando vad det betyder och vad det ska användas till.

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 14:19:50
av sodjan
Många av dina frågor och funderingar har varken med AVR eller C att göra.
Det har enbart med "programmering" att göra. D.v.s att du hade nog haft
samma eller liknande problem och frågor helt oavsett plattform. Förståelsen av
ASCII och olika radix för att representera värden har ju inget med C att göra.

Du säger att du vet hur du hade gjort i PHP, ja men gör på samma sätt då,
fast med de verktyg och funktioner som C erbjuder. Principen så som du
beskrev att du skulle göra det i PHP gäller ju i stor sätt fortfarande. Det
grundläggande "programmeringen" är samma, man gör det bara på lite
olika sätt. Det är bara att hacka på...

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 14:33:17
av Icecap
Du har en bit kvar fortfarande...

"if(commandBytes[3] == "0")"
Tyvärr, går inte! "0" är en sträng som består av minst två tecken efter varandra: 0x30 samt 0x00.
"if(commandBytes[3] == '0')" går dock alldeles utmärkt! Och korrekt är det också...

"if(commandBytes == "R1")"
Jahopp... "R1" är 3 bytes...

0x00 i slutet är det som kallas End-Of-Line (EOL) och den används inom C till att markera att strängen är slut.

Men hela din detektering av protokoll är helt uppåt väggarna. Börja med att fundera på vad du behöver. Jag kan ta ett exempel som jag håller på med just nu:
- Jag behöver ett antal kommandon. I detta fall är det för att styra data till och från ett litet display (finns i en annan tråd). Jag behöver att kunde läsa/skriva intensiteten (ljusstyrkan), vad som visas (text eller grafik), läsa/skriva rullhastighet, knapptryckningar och lite annat.

Så jag börjar här:
enum {Command_Ping, Command_Pong, // Anybody out there?
Command_Set_Intensity, Command_Get_Intensity,
Command_Set_Roll_Speed, Command_Get_Roll_Speed,
Command_Print_Text, Command_Print_Graphic,
Command_Button_Pressed, Command_Button_Released, Command_Button_Short, Command_Button_Long, // Button pressed on display
Command_Increment, Command_Decrement, // Increment/decrement by turning on display
Command_Display_Initiate, // Start display
Command_Set_Value, Command_Get_Value}; // Commands available, will be amended later

Nu har jag en grund att börja på.

För att överföra har jag kommit fram till att ASCII HEX är bra. Jag vill även ha en start och slut-markering av varje block, till det använder jag STX (0x02) och ETX (0x03).

Så ett block som ställer intensiteten kan se ut som följer: (mellanslag infogad för tydlighetens skull enbart)
STX "01" "02" "32" "xx" ETX
"xx" är en checksum i HEX och "xx" anger att det är ASCII-tecknen för dessa tecken som skickas. OK, det finns en "onödig" overhead (alltså omvandling) men erfarenheten har visat mig att det är lönt!

För att skicka ett kommando som betyder "ställ intensiteten på displayen som är av typen <01> till 50%" behövs alltså 10 bytes. Med 19k2 som jag kör tar detta 5,21ms och då jag har ställd den till att köra detta via interrupt kommer tiden det tar bara att vara tiden som det tar att överföra till buffern i minnet.

Dekodningen är enkel:
Kommer det en STX nollas pekaren som visar hur många bytes som är mottagna.
Kommer det en ETX kommer den att meddela att det finns ett mottagit block. I denna flagga finns även en time-out funktion men det kan vi ta en annan dag.
Alla andra bytes läggs i mottagnings-buffern om det finns plats.

När det sedan flaggas för att det finns något att jobba med dekoder main-loopen snabbt meddelandet vid att koda om HEX-värden till bytes och sedan kan man exekvera varje order som man vill och behöver.

Kod: Markera allt

int Hex2Word(char* Source, WORD* Destination, unsigned char Digits)
  {
  if(Digits)
    {
    *Destination = 0; // Start value
    while(Digits)
      {
      *Destination <<= 4; // Shift up value
      if((*Source < '0') || (*Source > 'F') || ((*Source < 'A') && (*Source > '9'))) return(0); // No way it's HEX
      if(*Source >= 'A') *Destination += (*Source - 'A') + 10;
      else               *Destination += (*Source - '0');
      Digits--;
      }
    }
  else return(0); // Went no good
  return(1); // We are happy!
  }
Och hur många data måste du överföra? Har du så stora datamängder behöver du en annan kodning till att börja med men är det vanliga utskrifter är ASCII ytterst trevligt, du kan läsa dom direkt i ett terminalprogram helt enkelt.

För att skriva ut ett HEX-värde i C? printf("%02X", Value); // skriver ut värdet i Value som två HEX-siffror med leading zero om det behövs.
Skriva ut ny rad i C? printf("\r\n"); // ger 'cursorn tillbaka till vänster' + 'Mata till ny rad'. Kombinationen kallas normalt CRLF.

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 15:08:04
av jesse
För att förklara samma sak som Icecap skrev:

Ett tecken skrivs som 'A', 65 eller 0x41. Inte "A".
Citationstecken (") används för strängar. Dessa är oftast arrayer med char, och är praktiska om du verklgien ska hantera en lång rad tecken, men klumpiga om du ska hantera enstaka tecken.

"A" går inte att jämföra med 'A' eller med 65. De är av olika typ.
'A' och 65 går däremot bra att jämföra (de är båda heltal).

'A' är en byte - 8 bitar.

"A" är en array med två positioner. I position noll finns värdet 65 eller 'A'. i posotion ett finns värdet 0 som betyder slut på strängen.

Hade jag varit du så hade jag förenklat koderna till så få tecken som möjligt. Till exempel:

Kod: Markera allt

- Hello : "H\r"    (För att kolla om AVR'en är "vaken" vilken då svarar på lämplig sätt).
- Restart : "R\r"    (Starta om firmware i AVR'en).
- Status : "S\r"    (AVR'en svarar med aktuellt status (on/off) för funktion nr 3).
Eller, om du vill skicka med ett tal mellan 0 och 99 i varje kod:

Kod: Markera allt

"H00\r" hello - processorn svarar med samma siffra (00 t.ex.)
"R00\r" restart - (siffran 00 har ingen betydelse)
"s25\r" status - ber processorn skicka status från ingång nr 25, till exempel.
"\r" i en textsträng betyder alltså <CR> eller 0x0D.

Kod: Markera allt

char commandBytes[4];
commandBytes[] = inkommandeByte;
Det är ett sätt att göra det på. Då skapar du en liten buffert som sedan ska tolkas.
Problemet med en så liten buffert (och med alla buffertar) är att om du får ett fel, så funkar inte nästa kommando heller.
exempel:

Du skickar först "H1,0" <CR> men av någon anledning bryts förbindelsen tillfälligt och du får bara in "H1,"
Din buffert innehåller nu "H1," och väntar på det sista tecknet före CR.
Men en stund senare vill du skriva in "S1,0" <CR>. Då kommer din buffert att få in ett 'S' på fjärde positionen. Resten av budskapet får inte plats i bufferten! Det blir fel igen.. Du har hamnat ur synk.

Ett annat sätt är att tolka inkommande tecken direkt: (fungerar om kommandoraden är väldigt enkel och innehåller få tecken)

1) du väntar på inkommande tecken.
2) ett tecken har kommit in - då kollar du om det är en bokstav mellan 'A' och 'Z'. Om det är det så är det ett kommando.
3) då väntar du dig två tecken till, samt en <CR>.
4) Om något av dessa tecken är en bokstav, så är det ett nytt kommando. - gå tillbaks till (3).
5) kolla att tecknen är siffror och CR. spara dessa.
6) ignorera eventuella konstiga extra styrtecken, t.ex <LF> (0x0A) som ofta skickas av terminalprogram.

Om du får in ett CR (eller något annat oväntat) innan alla tecken är inlästa väljer du att avbryta och vänta på nytt kommando.

ta de två siffrorna som du sparat och utför beräkningen:

value = (siffra1-48) * 10 + (siffra2-48);// nu får du ett heltal mellan 0 och 99.

Nu använder du en vanlig switch-sats för att utföra det inkomna kommandot:

Kod: Markera allt

switch (bokstav) {
    case 'H': 
        // do "home"
    case 'R': 
        // do "reset"
    case 'S': 
        // do "status"
    default :
        // kommandot finns inte.
}

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 15:13:59
av sodjan
> Hade jag varit du så hade jag förenklat koderna till så få tecken som möjligt.

Håller med (även om det var mitt exempel som du "rättade" :-) ).
Det underlättar kodningen i mottagaren, speciellt om den hade
varit skriven i assembler men även i C.

> Du har hamnat ur synk.

Man måste så klart ha logik (timeout eller liknande) som tar han
om det och ser till att "synka" ingen.

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 15:15:16
av labmaster
Att sända 0x0F som ett ascii-tecken är väldigt svårt eftersom 0x0F är fyra ascii-tecken. Men om du menar att du vill sända det binära talet 0x0F så är det inte så svårt. Det är bara att sända iväg det med UART:en så kommer det över till mottagaren som binärt 0x0F. Om mottagaren är en terminaldisplay så kommer du inte se att det är talet 0x0F men om mottagaren är en annan mikrokontroller som skall visa talet på en port där det sitter dioder så är det ok.

Innan du kan få riktigt bra hjälp att lösa ditt problem så måste du specificera vad du har som sändare och mottagare. Annars blir det bara som vanligt en lång gissningstävlan som visserligen redan tycks vara startad till viss del.

Skall du med hjälp av en teckenbaserad terminal sända kommandon till en mikrokontroller?

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 15:28:56
av jesse
sodjan skrev:> Du har hamnat ur synk.

Man måste så klart ha logik (timeout eller liknande) som tar han
om det och ser till att "synka" ingen.
Ja, men då duger det inte med en "dum" buffert som bara fyller på till du får in <CR>. Det var väl mest det jag ville belysa.

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 15:58:30
av sodjan
Tja, bufferten som sådan är alltid "dum", den är bara en
radda med minnesplatser och vet inget om nått.
Koden däremot ska så klart inte vara "dum"... :-)

Men du menar med "buffert" kanske både bufferten som sådan
och också all kod som hanterar bufferten...

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 16:36:12
av jesse
Ja, jag tänker mig en "buffert" som en färdig kodsnutt (med tillhörande array) som har ett väl definierat interface mot övriga programmet där du t.ex. kan läsa tecken , lägga in nya tecken eller "radera" bufferten.

Re: AVR C fråga, bit_is_clear/set vimsig?

Postat: 23 juli 2012, 19:19:51
av toffie
sodjan
Jo det känns som att jag ska "göra på samma sätt", gäller bara att hitta verktygen ;)
Men det är skönt att prata av sig ibland också, man kommer ofta på nya saker och i detta fall lär sig mycket nytt också ;)


Icecap
Ah, skillnaden mellan " och ' är lite svår att komma ihåg, i PHP finns det vissa funktioner för de båda men i grund och botten spelar det ingen roll vilken du vill använda. Jag brukar använda ' eftersom de är snabbare då de inte matchar $variabler.
Icecap skrev:...Men hela din detektering av protokoll är helt uppåt väggarna...
Men det du beskriver är ungefär det jag försöker få till :doh: :D Som sagt, jag är inte så bra på att förklara med de rätta orden ;)

Jag vill ha ett start och slut, jag vill ha ett kodblock däremellan, precis som du skrivit. STX "01" "02" "32" "xx" ETX Sen kan jag nog tänka mig att skippa checksum i början, bara för att hålla det enkelt, men det står på min wishlist ;)

Det är nog här jag fastnat med att jag vill använda HEX, för man skulle ju kunna säga att värdena i kodblocket mellan start och slut är HEX. Men! det behöver ju inte vara det, har jag fått lära mig :D

Att skicka ditt paket mellan processorer borde ju vara ganska enkelt. Man skickar hex värde till UART'en för start 0x02, sen skickar man ASCII i ett flöde 010232xx och slutligen hex värde 0x03 för slut. Är det så man gör kanske? Mottagaren kommer ju "se" samma sak oavsett om man skickar ASCII, HEX eller Binärt.. Har jag lärt mig nåt? :roll: :P

Det blir väl dock problem med en terminalklient på datorn som sagt, eftersom den inte använder start och slut värde så som vi vill. Så det kan bli svårt att "prov-skicka" ett paket från datorn? Det är väl rätt tolkat efter alla inlägg i denna tråden? ;)

Jag förstår dock inte riktigt vad du gör med enum? Missar du inte något? Antingen ett "variabel" namn i början eller slutet av enum funktionen? Samt varför du har med det i inlägget?

Kan det vara så att det första värdet i kodblocket motsvarar index i enum arrayen? Så exempelvis 01 blir funktionen "Command_Pong"?

Det här hör väl kanske inte riktigt till mina frågor, fast det gör på ett sätt.. Men jag vill gärna förstå.. :)
Sen måste jag erkänna att Hex2Word funktionen är ganska oklar för min del. Source förmodar jag är från kodblocket? Är det varje sifferpar eller är det alla siffrorna tillsammans? Destination, ingen aning..

Sen förstår jag inte riktigt IF satsen, om Source är mindre än 0 eller större än F eller mindre än A och större än 9? Så kan det inte vara ett HEX värde? Vänta nu, blir det om Source är mindre än 0, dvs negativt så kan det inte vara HEX.. Om det är större än F, dvs G H I K N V så kan det inte vara HEX.. eller om Source är mindre än A, dvs 0-9, men större än 9, så kan det inte vara HEX.. Wow, stämmer det? haha, jag kanske förstod trots allt :D :D :D :D

Vad gör då nästa IF sats? om Source är större eller likamed 'A' dvs ett numeriskt/heltals värde? så ska destination addera sig själv med (Source - Heltal) + 10.. Vad blir resultatet av det?


På din fråga om hur mycket data som ska överföras kan jag bara svara.. Ingen aning! Nej då, men på ett ungefär som ditt paket med start/slut och ett kodblock. Jag behöver ett lite annorlunda kodblock, för att få in en adressdel till / från också.

STX AT AF KB SK VÄ xx ETX
STX = Start
AT = Mottagaradress
AF = Sändaradress
KB = Kommandobit
SK = Subkommandobit
VÄ = Kommandovärde
xx = CRC
ETX = Slut

Dock skulle jag behöva lite fler funktioner, som visserligen går att lägga in som egna värden direkt, visst.
Men jag har läst på om ett annat projekt som använder RS485 kommunikation, som jag gör. Deras protokoll körs med HEX värden. (sänt som ASCII förmodligen?)

Deras startblock består av följande bitar
R C S S T T T T

På åtta bitar, dvs ett ASCII tecken, ett hex värde liknande 0x00 osv.. Har de fått in fyra olika inställningar.

R = Reply, avsändaren vill ha ett kvitto på att meddelandet har kommit fram
C = Checked, om avsändaren ville ha ett kvitto ändras denna bit av mottagaren när paketet skickas tillbaka
SS och TTTT är kategori bitar, här ställs det in vad för sorts paket det är som skickas.

Deras startblock kan se ut på olika sätt och det finns säkert fler kombinationer men de jag hittar är, 0x00, 0x80, 0xC0, 0xA1, 0xE1, 0x82, 0xC2

Vidare har de ett adressblock som består av följande sträng "255 255 255" värdet kan alltså vara max 255 och som lägst 0.

Sen har de fyra block med vardera två tecken, bas 16, som utgör "meddelande".. Det som vi ovan pratat om en sorts "kod", likt "H00\r".

Till sist har de ett CRC värde beräknat på hela paketet.

Deras paket har ett grafiskt utseende på detta sätt;
Bild

Det är kanske lättare att titta på, deras första byte, 8 bits. Sen adresspaketet med tre värden, vardera på max 255. Fyra meddelandepaket som vardera kan vara en byte samt det slutgiltiga CRC blocket, som även det är på en byte totalt.

De har dokumenterat det som att paketet är 9 bytes totalt.

Nu vill jag inte kopiera deras idé, som för övrigt verkar rätt död eftersom det inte kommit någon uppdatering på 4-5 år.. Men jag gillar själva upplägget och därav själva idén med att jag vill skicka EN byte och dela upp denna i bitar där vardera bit står för en inställning.

Vad säger ni om det? Låter det fortfarande knasigt eller?


jesse
Absolut, ett sätt kolla så man får hela paketet är definitivt rekommenderat och det kommer jag också implementera när tiden kommer för det. Idén jag har för det är att när det första tecknet kommer startas en timer på runt 1ms (vilket säkert går att trimma ner), om det inte kommer in fler tecken så kommer bufferten tömmas och man väntar på nästa sändning istället.


labmaster
Ok, men det är bra att veta!

Ja det kanske blev lite luddigt i början av tråden, men det är främst AVR <-> AVR men jag kommer både behöva men även vilja skriva ett program på datorn för kommunikation mellan dator och AVR. Anledningen är att jag både kan använda det för utveckling av fler kommunikationsmoduler men även för att titta på trafiken.

Så främst AVR <-> AVR :)



Det jag funderar på gällande de protokoll jag tittat på är att deras startbyte kan variera från paket till paket. Kanske skulle man implementera Icecaps version och göra paketets första byte innanför start till en byte liknande deras startbyte. Jag vet inte, jag vet inte..

Men nu har ni i alla fall sett vart jag fått idén ifrån och varför jag ens startade tråden ;) Det blev ett ruskigt långt inlägg, men hoppas inlägget går att läsa ;)