Sida 4 av 5

Re: konsolmeny till arduino

Postat: 23 januari 2012, 11:07:25
av tecno
*PyTTY*
Det heter väl PuTTY?

Re: konsolmeny till arduino

Postat: 23 januari 2012, 12:25:00
av jesse
Nu är jag ingen expert på hur en C-kompilator brukar göra med ett uttryck som detta:

Serial.print("Hello World");

men jag tror det är mycket fördelaktigt i effektivitetssynpunkt om man lagrar texten i flashminnet istället för att skapa en sträng i ramminnet. Detta kan göras med följande uttryck:
You can pass flash-memory based strings to Serial.print() by wrapping them with F(). For example :
Serial.print(F("Hello World"))

To send a single byte, use Serial.write().
Nu tycker jag lösningen med F("Hello World") inte är så smart om man vill kunna skriva ut samma text på flera ställen i programmet (vilket verkar efterfrågas i tråden?). Då borde man ju skicka en pekare till texten i flashminnet och definiera texten separat på en egen rad. Nu vet jag inte hur F() fungerar (anagligen ett macro), men det vore bra om man kunde använda en pekare istället för texten:

I avr-biblioteken finns ju PROGMEM-funktionerna, det är antagligen inte kompatibelt med Arduinos F(), annars hade det kunnat se ut så här:

Kod: Markera allt

char PROGMEM hello = "Hello World!";
Serial.print(F(hello));
Serial.print(F(hello));
Serial.print(F(hello));
Serial.print(F(hello));
Detta måste ju vara ett återkommande "problem" för alla som använder Arduino, så någon måste väl veta hur man gör? Annars kan man givetvis lösa det genom att lägga återkommande texter i en funktion:

Kod: Markera allt

void print_hello(void) {
    Serial.print(F("Hello World"));
}

int main (void) {
    print_hello();
    print_hello();
    print_hello();
    print_hello();
}
Arduino: Serial.print

("Hello World!" kan givetvis bytas ut mot valfri sträng, t.ex. ""\033[0;0f")

Re: konsolmeny till arduino

Postat: 23 januari 2012, 13:30:42
av Larsson90
Vad retunerar F()?
Retunerar den pekaren till strängen så borde man väl kunna göra något likande:

Kod: Markera allt

char * hello = F("Hello world"); 
Serial.print(hello)
OT: Känns lite konstigt att använda char när man vill skapa en sträng, är van vid c/c++/c#.

Re: konsolmeny till arduino

Postat: 23 januari 2012, 16:29:59
av sodjan
Men å andra sidan, borde inte en kompilator alltid skapa sträng *konstanter* i Flash?
D.v.s att i fallet med Serial.print("Hello World"); så kan jag tycka att det inte
ska allokeras något RAM minne för det.

Re: konsolmeny till arduino

Postat: 23 januari 2012, 16:46:08
av jesse
Problemet är att funktionen bara tar emot en pekare, och då förutsätts att data ligger i RAM annars måste man säga till kompialtorn på något vis att den just *vid det här tillfället* ska läsa från flash.

anropet till funktionen funktion("abc") skiljer ju sig inte från anropet funktion(str[])
När jag gör ett litet testprogram så läggs strängen i SRAM innan funktionen anropas (Ja, den ligger där och tar upp utrymme redan från start och verkar hanteras som en global variabel)

Kod: Markera allt

int main(void) {
    while(1) {
        //TODO:: Please write your application code 
		send_data("HELLO ");
		send_data("WORLD!");
    }
}
Dessutom återanvänds inte text om man ska skriva hello på flera ställen:

Kod: Markera allt

		send_data("HELLO ");
		send_data("HELLO ");
		send_data("HELLO ");
Fyller RAM-minnet med tre HALLO-strängar.

Re: konsolmeny till arduino

Postat: 23 januari 2012, 16:55:40
av sodjan
> Problemet är att funktionen bara tar emot en pekare, och då förutsätts att data ligger i RAM

Men tydligan kan ju funktionen även ta en pekare till flash som parameter,
eller hur fungerar F() annars? Alltså så skulle kompilatorn själv kunna ta hand
om det när den ser en konstant på samma sätt som *om* F() används.
D.v.s att den skulle kunna lägga till F() kring argumetet själv. Finns det
något fall då detta skulle vara en nackdel?

Re: konsolmeny till arduino

Postat: 23 januari 2012, 17:05:04
av jesse
Jag vet faktiskt inte hur F() fungerar.
Men när jag programmerar AVR annars så måste jag ha separata "print"-funktioner för att läsa i RAM, EEPROM eller FLASH. Jag har i alla fall inte ännu kommit på hur man skulle kunna använda samma funktion för dessa tre varianter.

Inuti min egna flash_print(char str[]);-funktion finns satsen tecken = pgm_read_byte(str[i++]); istället för att bara läsa innehållet i den adress pekaren pekar på , alltså baratecken = str[i++];.

Re: konsolmeny till arduino

Postat: 23 januari 2012, 17:09:04
av sodjan
Jag vet inte heller hur F() fungerar men det antyddes att den hjälper till med
att flytta konstanten till flash (och spara RAM minne). Det borde betyda att
funktionen även kan ta en pekare till flash som parameter. Eller inte... :-)

Hur som helst, generellt verkar det ju vettigt om konstanter som t.ex "Hello World"
inte i onödan tar upp RAM minne...

Re: konsolmeny till arduino

Postat: 23 januari 2012, 17:18:47
av jesse
Jag hade visst fel i mitt sista påstående (förutom stavfelet HALLO :D ) , GCC kollar visst om två strängkonstanter är lika och lägger dem då på samma adress i SRAM. Inte så korkat alltså.
jesse skrev: Dessutom återanvänds inte text om man ska skriva hello på flera ställen:

Kod: Markera allt

		send_data("HELLO ");
		send_data("HELLO ");
		send_data("HELLO ");
Fyller RAM-minnet med tre HALLO-strängar. = FEL !

Re: konsolmeny till arduino

Postat: 29 januari 2012, 11:48:22
av lillmange
Hej igen

Nu har jag äntligen fått lite tid att testa mer och jag har fått själva "start menyn" att fungera fint.

Nästa grejj blir då att få till en "undermeny" där jag kan ange ett värde som ska sparas.
Detta värde ska vara 1-4 tecken långt.

Min ide är då att inmatningen avslutas med [ENTER] (knappen alltså) för att programmet ska känna av att inmatningen är slut.

Det har föreslagits att använda serialevent och bufferuntil till detta.

Kan någon förklara för mig hur jag gör detta?

Tack!

/Magnus

Re: konsolmeny till arduino

Postat: 29 januari 2012, 13:57:26
av Bosen
det ingen anledning att använda serialevent eller bufferuntil.
I arduino läggs all data från serial i en buffer och du plockar ett tecken i taget med serial.read();
sin är det bara att kolla om serial.read()=='/n' och isåfall är det enter eller rättare sagt "newline".

Re: konsolmeny till arduino

Postat: 30 januari 2012, 21:03:26
av lillmange
Hej,

Tack för tipset.

Jag har skrivit en lite bit på koden som väntar sig en inmatning som ska sluta med /n men jag vet inte riktigt hur jag ska skriva klart koden

Kod: Markera allt

while (menu == 1){                         //medans vi är i meny 1
if (Serial.available() != 0) {            //om det finns indata på serieporten
inByte += Serial.read();                  //läs av serieporten och spara/lägg till i inByte
fan1_pwm = inByte ;                       //spara inByte till fan1_pwm
inByte = (0);                            //rensa inByte
break;
}
Fyll gärna på min kod för att ge förslag på hur jag kan göra.
Fungerar += så som jag har använt det?
Som ni alla vet vid det här laget är jag inte speciellt hemma på det här med arduino programmering så förklara gärna som om det vore för en lågstadieelev...

Re: konsolmeny till arduino

Postat: 30 januari 2012, 21:05:54
av jesse
För det första ska det se ut lite annorlunda:

Kod: Markera allt

while (menu == 1){                         //medans vi är i meny 1
    if (Serial.available() != 0) {            //om det finns indata på serieporten
        inByte += Serial.read();                  //läs av serieporten och spara/lägg till i inByte
        fan1_pwm = inByte ;                       //spara inByte till fan1_pwm
        inByte = (0);                            //rensa inByte
        break;
}
och då ser man att det fattas en }-parentes.. men det var kanske den vi skulle fylla i? :)

På vilket vis sparas inlästa tecken genom satsen inByte += Serial.read();??? Det är ju en addition av ett tal du utför. Dessutom saknas deklaration av variablerna. Utan deklaration har man ingen koll på vad det är för något och om det fungerar. Vad är InByte för typ?

Jag förstår inte alls koden :humm:

Har du läst nån grundkurs i C-programmering?

Re: konsolmeny till arduino

Postat: 30 januari 2012, 22:46:08
av lillmange
Hej,

Detta är altså bara ett utdrag av koden som jag ska använda och då den biten som väntar på/läser serieporten.

+= var en kompis som tipsade mig om att jag kunde använda... han är inte vad vid arduino eller liknande men jobbar som utvecklare.

Själv har jag inte läst många sidor C... men jag tycker det är kul och frågar eller letar på nätet när det tar stopp, vilket händer lite nu och då...

Det jag ville utföra med koden är:

Ta emot flera tecken på serieporten och när en [ENTER] tryckning sker kontrollera värdet (om det är 0, 1-99 eller annat tecken) och spara det har matats in.

/Magnus G

Re: konsolmeny till arduino

Postat: 30 januari 2012, 23:18:08
av sodjan
> += var en kompis som tipsade mig om att jag kunde använda...

Om vi antar att din kompis vet vad "+=" gör, så måste den beskrivning som han
fick av vad som skulle uppnås inte stämma med vad *vi* tror att koden ska göra.

Rimligtsvis borde mottagna tecken samlas "på hög" i någon buffert (normalt
implementerat som en "array", inte bara summeras ihop då ju allt tappas bort.

> Det jag ville utföra med koden är:
> Ta emot flera tecken på serieporten...

Hur ser formtet ut på det som kommer till serieporten?

>... och när en [ENTER] tryckning sker kontrollera värdet...

Vilket "värde"?

> (om det är 0, 1-99 eller annat tecken)

"0" är ett tecken. "1" är ett annat tecken. "99" är *två* tecken.
Eller menar du numeriska värden? Och i så fall, hur skickas värdet?

Det hela beror mycket på frågan ovan, hur formatet ser ut på det som kommer till serieporten.