RS232 comport: ny rad? putChar('\n');

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

RS232 comport: ny rad? putChar('\n');

Inlägg av jesse »

Korkad fråga, kanske, men jag börjar tröttna på mina serieportsterminalprogram i PCn. :evil:

Jag brukar ansluta mina AVR till PC via UART och använder mig av flera olika terminalprogram beroende på vilken dator / vilket OS jag har för tillfället. Det jobbiga är att alla terminalprogram verkar reagera olika på "ny rad", så jag funderat på vad som är det mest vedertagna sättet att signalera "ny rad"... alla terminaler beter sig nämligen olika, och det är inte alltid det går att ändra inställningarna.

om jag skickar '\n' som "ny rad" så kommer "HyperTerminal" att byta rad, men ej börja från början på den raden.

print("Hej\nhej\nhej");

ger

Kod: Markera allt

Hej
   hej
      hej
Då har jag ändrat till \n\r istället - print("Hej\n\rhej\n\rhej");

Kod: Markera allt

Hej
hej
hej
Men i vissa linuxterminaler tolkar både \n och \r som ny rad, var för sig... då får jag

Kod: Markera allt

Hej

hej

hej
Och då får inte texten plats i fönstret....

Jag antar att jag måste leva med detta, men vilket är det vanligaste sättet att skicka data. Det borde väl vara med bara '\n' ? Och så får man försöka anpassa terminalen därefter? (Nästa problem är väl Å,Ä och Ö :x )
Användarvisningsbild
stekern
Inlägg: 453
Blev medlem: 2 november 2008, 08:24:18
Ort: Esbo, Finland

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av stekern »

Jag antar att du menar \r\n och inte \n\r

Jag brukar ha i min putchar rutin följande kod:

Kod: Markera allt

uint8_t uart_putchar(uint8_t c) {
 
    if (c == '\n')
        uart_putchar('\r');
    ...
}
så lägger den automatiskt på \r vid \n

Annars brukar jag ofta låta mcun bara skicka \r och sen låta terminalprogrammet lägga på \n
(finns en sån inställning i hyperterminalen).
Det underlättar sen även egenskrivna tolkningsprogram som bara behöver bry sig om \r
som radbrytare (oavsett om det är windows eller linux)
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av bearing »

Jag är rätt säker på att den där inställningen gör att Hyperterminalen gör om LF (Line Feed '\n') till CR LF (Carriege Return with Line Feed '\r\n'). Men det är ju möjligt att den även gör om ensamma CR till CR LF.

Det är så vitt jag vet LF som används i UNIX, medans CR LF används av Microsoft.

Hittade den här artikeln som verkar bekräfta min uppfattning.
http://en.wikipedia.org/wiki/Newline

Jag ser en fördel av att CR flyttar markören till början av raden utan att flytta den nedåt, då kan man nämligen göra program som t.ex. uppdaterar aktuell rad i realtid.
Användarvisningsbild
stekern
Inlägg: 453
Blev medlem: 2 november 2008, 08:24:18
Ort: Esbo, Finland

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av stekern »

Jag är rätt säker på att den lägger på LF på CR, inställningen heter "Append line feeds to incoming line ends".
Jo, det stämmer att LF är "hoppa till början av ny rad" under unix.

Att använda CR ensamt är dock det som funkar bäst (för mig) under de flesta omständigheterna.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av jesse »

stekern: trodde först att du hade kopierat min kodsnutt, den var nästan identisk... :) det är så den ser ut nu. Men den gör \n\r. Kanske kan testa att vända på den och skriva \r\n om det gör nån skillnad?

med \n\r så tycker alla mina linuxterminaler att dom ska mata fram två rader. Verkar alltså som om de tycker att även \r är en radmatning, fast den borde ignoreras.

\n är väl LF = 0x0d, och \r =CR = 0x0a ???
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av sodjan »

Väldigt rörigt här... :-)

Det är uppenbart att många som aldrig har sett en vanlig skrivmaskin eller
en äldre skrivarmodell har lite svårt att koppla CR res LF till "verkligheten". :-)

LF = "Line Feed", d.v.s matning av "valsen" en rad (tänkt vrida på ratten
till vänster på en vanlig skrivmaskin. Positionen där vagnen ("carriage") står
ändras alltså inte. Alltså helt enligt jesses första exempel !

CR = "Carrage Return", d.v.s retur av vagnen ("carrage") till början av raden.
CR i sig innebär ingen ny rad/line feed! Bara att skrivhuvudet/vagnen/carriage
går tillbaka till läget längst till vänster på raden.

I UNIX är LF markeringen för "new line" i filer, en sorts record-avgränsare.
Främst är det rellevant vid läsning och tolkning av just filer, där ett
ensamt LF utgör rad/post/record avgränsare. Detta blir lite av ett problem
om man t.ex kör en sådan fil direkt ut till en terminal, därav de olika
möjligheterna att automatiskt låta terminalen lägga till en CR efter varje LF.

När det gäller tolkningen av CR och LF av terminalprogram/emulatorer, så
är det rimliga default läget att det fungerar just enligt den ursprungliga
betydelsen av CR resp LF. Alltså så som jesse såg det i sina första två exempel.

Sedan så har de flesta vettiga terminalprogram/emulatorer inställningar för
att justera tokningen av CR, LF, CRLF och så vidare så att det funegrar som man vill.

> med \n\r så tycker alla mina linuxterminaler att dom ska mata fram två rader.

Ja, men det beror på att de har ett inbyggt fel för att vara enklare att använda från UNIX.
D.v.s att de gör både en CR och en LF efter ett ensamt LF.

Sen så kan det ju även vara programvaran/kompilatorn som tolkar "\n" som CRLF,
men det borde väl vara ett ensamt LF !?

> "Append line feeds to incoming line ends".

Synnerligen korkad förklaring. Vad *är* ett "line end" ??
Är det inte just ett "line feed" ("LF") ? I alla fall i UNIX...

> medans CR LF används av Microsoft.

Det har inte ett skit med Microsoft att göra !
Definitionerna av CR och LF är mycket äldre än Microsoft...

Problemet med "\n" är att det inte har en definition. Det kan generera lite
olika tecken/teckensekvenser beroende på vilken plattform det används på.

Om du vill vara helt säker så är det bättre att skriva dit h'0D' och/eller h'0A'
själv istället. Då fungerar det alltid...
Användarvisningsbild
stekern
Inlägg: 453
Blev medlem: 2 november 2008, 08:24:18
Ort: Esbo, Finland

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av stekern »

sodjan skrev:Synnerligen korkad förklaring. Vad *är* ett "line end" ??
Är det inte just ett "line feed" ("LF") ? I alla fall i UNIX...
Tjaa, det får du ta med utvecklarna av hyperterminalen, så står iaf...
sodjan skrev: Det har inte ett skit med Microsoft att göra !
Definitionerna av CR och LF är mycket äldre än Microsoft...
Att de är äldre än Microsoft hindrar väl inte att Microsoft använder det (såväl som andra)
sodjan skrev: Problemet med "\n" är att det inte har en definition. Det kan generera lite
olika tecken/teckensekvenser beroende på vilken plattform det används på.

Om du vill vara helt säker så är det bättre att skriva dit h'0D' och/eller h'0A'
själv istället. Då fungerar det alltid.
Just därför gillar jag att bara skicka '\r' eftersom det är mindre sannolikt (även om det inte är garanterat) att generera olika sekvenser
beroende på underliggande system.
Men jag håller med, vill man vara säker på värdet, skriv 0x0A eller 0x0D.
Men å andra sidan så kan ju den ospecifika '\n' eller '\r' vara bra om man vill att koden skall generera nåt vettigt på en plattform som inte använder ascii.
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av blueint »

\n i Unix-terminal ska ge nyrad+vänsterpositionering. Så en extra \r ska endast upprepa en vänsterpositionering och därmed inte göra någon skillnad.

I annat fall så krävs \r för vänsterpositionering och sedan \n för nyrad.

Kikar man i textfiler för MS-DOS är dom fyllda med \r\n medan unix dito har \n. I MS-DOS används dessutom Ctrl-Z som Slut-På-Fil (EOF) i många lägen, kanske försvunnet iom MS-Win.

Sen i 99,99% av fallen har jag endast sett kombinationen \r\n inte \n\r. Det kan ev ställa till det annars.

LF = Line Feed så vitt jag vet.
Utvecklarna av hyperterminal har fått saker om bakfoten. Det är iaf ett av programmen jag undviker i MS-Win miljö.

CR = \r = 0x0D
LF = \n = 0x0A

http://en.wikipedia.org/wiki/Newline
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av jesse »

jag får väl testa enbart \r och se hur det går... kanske den inte matar på ny rad utan bara skriver över den gamla raden? (tror nog den gör så i Windows HyperTerminal faktiskt).

Nu råkar det gå att skriva char LF = '\n'; och det innebär att den inte kan trycka in fler än ett tecken, och jag antar att det är 0x0a, enligt ASCII-tabellen.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av sodjan »

> Kikar man i textfiler för MS-DOS är dom fyllda med \r\n medan unix dito har \n.

Ja, men det är en lite annan sak/fråga. D.v.s hur man "record-avgränsar" textfiler
i olika system/plattformar. Det har ingenting direkt med att göra hur en terminal
ska/bör hantera CR resp LF. Och det finns flera andra sätt att avgränsa
rader/poster/records än att ha LF eller CR/LF sist på varje rad/record.

Sen så är det så klart så att det finns kopplinger mellan filformatet i Unix
och hur en "Unix-terminal" (vad det nu är för något) hanterar det. Är det
någon speciell terminalemulator ?

> CR = \r = 0x0D
> LF = \n = 0x0A

Ja, förrutom att "\n" betyder "new line" vilket har lite olika betydelse beroende på plattform.
Det betyder inte alltid just (och enbart) 0x0A...
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av blueint »

Ett tips är att definiera radslut i C som "char lf[3];" och sedan använda "strcpy(lf,"\r\n");". Motsvarande i perl vore "$lf="\r\n";" samt "print "Hej".$lf;" osv..

På det sättet kan man hantera olika smaker av \r\n och koncentrera sig på andra saker i programmeringen.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av sodjan »

Dessutom, så länge man håller sig inom en viss "värld" (Microsoft, Unix o.s.v)
så brukar nog de defaults som gäller där fungera help OK... :-)

Verktyg som är specifikt tänkta för att fungera över "gränser" som t.ex
FTP har i sin spec tagit hänsyn till detta och när man t.ex kör ASCII i FTP
så får man den rad-avgränsning som gäller i resp miljö på varje sida.

Andra verktyg som ZIP/UNZIP har flaggor/switchar för att (om man vet
att det är ett problem) ändra LF -> CR/LF eller tvärtom.
Användarvisningsbild
säter
Inlägg: 35339
Blev medlem: 22 februari 2009, 21:16:35
Ort: Säter

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av säter »

Får man ställa en fråga som är helt OT?

Får passa på när expertisen är på plats ang. den utökade ASCII-tabellen.

Varför används ALT-157 för Ø i Windows Anteckningar?
Medan ALT-237 används i DOS?
Är det olika tabeller?
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av blueint »

Finns olika "codepages" för DOS (CP850). Och antagligen samma för grafiskmiljö dito.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: RS232 comport: ny rad? putChar('\n');

Inlägg av sodjan »

OK i denna tabell http://www.asciitabell.se/
så ligger tecknet på andra värden... :-)

PÅ denna sida http://en.wikipedia.org/wiki/%C3%98
nämns inte koderna 157 eller 237 alls...
Skriv svar