konsolmeny till arduino

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
tecno
Inlägg: 27254
Blev medlem: 6 september 2004, 17:34:45
Skype: tecnobs
Ort: Sparreholm, Södermanland N 59° 4.134', E 16° 49.743'
Kontakt:

Re: konsolmeny till arduino

Inlägg av tecno »

*PyTTY*
Det heter väl PuTTY?
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: konsolmeny till arduino

Inlägg 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")
Larsson90
Inlägg: 646
Blev medlem: 24 december 2008, 21:43:25
Ort: Göteborg

Re: konsolmeny till arduino

Inlägg 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#.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: konsolmeny till arduino

Inlägg 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.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: konsolmeny till arduino

Inlägg 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.
Senast redigerad av jesse 23 januari 2012, 16:56:37, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: konsolmeny till arduino

Inlägg 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?
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: konsolmeny till arduino

Inlägg 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++];.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: konsolmeny till arduino

Inlägg 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...
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: konsolmeny till arduino

Inlägg 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 !
lillmange
Inlägg: 129
Blev medlem: 30 januari 2007, 14:51:37
Ort: Upplands Väsby
Kontakt:

Re: konsolmeny till arduino

Inlägg 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
Användarvisningsbild
Bosen
Inlägg: 1753
Blev medlem: 18 juli 2005, 10:56:31
Ort: Karl Gustav, Varberg
Kontakt:

Re: konsolmeny till arduino

Inlägg 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".
lillmange
Inlägg: 129
Blev medlem: 30 januari 2007, 14:51:37
Ort: Upplands Väsby
Kontakt:

Re: konsolmeny till arduino

Inlägg 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...
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: konsolmeny till arduino

Inlägg 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?
lillmange
Inlägg: 129
Blev medlem: 30 januari 2007, 14:51:37
Ort: Upplands Väsby
Kontakt:

Re: konsolmeny till arduino

Inlägg 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
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: konsolmeny till arduino

Inlägg 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.
Skriv svar