PROGMEM

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
Avatar
szitko
Újonc
Újonc
Hozzászólások: 5
Csatlakozott: 2012. november 3. szombat, 6:00

PROGMEM

Hozzászólás Szerző: szitko »

Sziasztok!

Nem találtam ilyen témát ezért nyitottam újat.
Próbálkozom a Flash használatával,de nem igazán értem. Az alábbi kis programot írtam, de sajnos a Soros Monitor csak egyeseket ír ki. Tehát valószínű, hogy a PSTR() makrónál hibáztam, de nem értem mit.

Kód: Egész kijelölése

void loop()
{
  data_p(PSTR("Hello"));
  Serial.println("Test");
}

void data_p(const prog_char *progmem_s)
{
  char c;
  while (c = pgm_read_byte(progmem_s++) !=0) {
      Serial.println(c,DEC);
      delay(1000);
  }
}
Valaki el tudná magyarázni, hogy mit csinálok rosszul?
Előre is köszönöm!
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: PROGMEM

Hozzászólás Szerző: Robert »

Mit szeretnél csinálni?
Milyen fordító? Milyen keretrendszer?

Arduino alatt Tömbként:

Kód: Egész kijelölése

/*
 PROGMEM string demo
 How to store a table of strings in program memory (flash), 
 and retrieve them.

 Information summarized from:
 http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

 Setting up a table (array) of strings in program memory is slightly complicated, but
 here is a good template to follow. 

 Setting up the strings is a two-step process. First define the strings.

*/

#include <avr/pgmspace.h>
prog_char string_0[] PROGMEM = "String 0";   // "String 0" etc are strings to store - change to suit.
prog_char string_1[] PROGMEM = "String 1";
prog_char string_2[] PROGMEM = "String 2";
prog_char string_3[] PROGMEM = "String 3";
prog_char string_4[] PROGMEM = "String 4";
prog_char string_5[] PROGMEM = "String 5";


// Then set up a table to refer to your strings.

PROGMEM const char *string_table[] = 	   // change "string_table" name to suit
{   
  string_0,
  string_1,
  string_2,
  string_3,
  string_4,
  string_5 };

char buffer[30];    // make sure this is large enough for the largest string it must hold

void setup()			  
{
  Serial.begin(9600);
}


void loop()			  
{
  /* Using the string table in program memory requires the use of special functions to retrieve the data.
     The strcpy_P function copies a string from program space to a string in RAM ("buffer"). 
     Make sure your receiving string in RAM  is large enough to hold whatever
     you are retrieving from program space. */


  for (int i = 0; i < 6; i++)
  {
    strcpy_P(buffer, (char*)pgm_read_word(&(string_table[i]))); // Necessary casts and dereferencing, just copy. 
    Serial.println( buffer );
    delay( 500 );
  }
}
Avatar
szitko
Újonc
Újonc
Hozzászólások: 5
Csatlakozott: 2012. november 3. szombat, 6:00

Re: PROGMEM

Hozzászólás Szerző: szitko »

Mit szeretnél csinálni?
A PSTR() makrót megérteni.
Arduino-1.0.4, Arduino UNO R3.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: PROGMEM

Hozzászólás Szerző: Robert »

Using PSTR() is a optimization method to save the text not in SRAM but in the flash.


Azaz ami a pstr() után áll, az nem a SRAM hanem a flashmemóriába kerül mentésre. Csak konstans lehet!
Avatar
szitko
Újonc
Újonc
Hozzászólások: 5
Csatlakozott: 2012. november 3. szombat, 6:00

Re: PROGMEM

Hozzászólás Szerző: szitko »

Tehát ami a PSTR után van, az fordításkor rögtön a flash-be kerül?
Így már kezdem érteni....

Köszönöm.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: PROGMEM

Hozzászólás Szerző: Robert »

Igen.
Így a legegyszerűbb....
borisz
DrótVégénSzéndarab
Hozzászólások: 31
Csatlakozott: 2016. november 26. szombat, 9:39

Re: PROGMEM

Hozzászólás Szerző: borisz »

Sziasztok. Problémám adódott a címben szereplő utasítással. Egy viszonylag egyszerű szinusz jelet szeretnék előállítani, egy led villogtatásához. A program így néz ki:

Kód: Egész kijelölése

#include "avr/pgmspace.h"

const byte sinetable[48] PROGMEM = {128,144,160,176,191,205,218,229,238,245,251,254,255,254,251,245,238,229,218,205,191,176,160,144,128,111,95,79,64,50,37,26,17,10,4,1,0,1,4,10,17,26,37,50,64,79,95,111};

byte szamlalo=0;
byte data=0;

void setup() {
}

void loop() {
  if (szamlalo<46) {
    szamlalo++;
  } else {
    szamlalo=0;
  }
  data=sinetable[szamlalo];
  analogWrite(11, data);
  delay(10);
}
A probléma pedig az, hogy ebben a formában teljes működésképtelen. Össze-vissza villog és változtatja a fényerőt. Próbáltam soros monitoron ellenőrizni a változók értékeit és azt tapasztaltam, hogy a számláló szépen végig számol és utána nullázódik, de a data változó, ami a tömb adott számú értéke lenne az nem változik rendszeresen, sokszor megáll egy értéken és néha ugrik egy teljesen más értékre. Többnyire a tömb alacsony értékein "áll meg".
Aztán kipróbáltam, hogy a tömböt nem a flash memóriába tárolja, hanem csak az SRAM-ban, akkor meg szépen megy.
Kérem segítsetek, mert nem vagyok még tisztában ezzel a PROGMEM utasítással.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: PROGMEM

Hozzászólás Szerző: kapu48 »

Próbál igy:

Kód: Egész kijelölése

#include "avr/pgmspace.h"

const byte sinetable[48] PROGMEM = {128,144,160,176,191,205,218,229,238,245,251,254,255,254,251,245,238,229,218,205,191,176,160,144,128,111,95,79,64,50,37,26,17,10,4,1,0,1,4,10,17,26,37,50,64,79,95,111};

byte szamlalo=0;
byte data=0;

void setup() {
}

void loop() {
  if (szamlalo<46) {
    szamlalo++;
  } else {
    szamlalo=0;
  }

 data = pgm_read_byte_near(sinetable[szamlalo]);
 
  analogWrite(11, data);
  delay(10);
}
https://www.arduino.cc/en/Reference/PROGMEM
borisz
DrótVégénSzéndarab
Hozzászólások: 31
Csatlakozott: 2016. november 26. szombat, 9:39

Re: PROGMEM

Hozzászólás Szerző: borisz »

Sajnos így sem működik. Egy kicsit jobb lett, de még mindig össze-vissza villog. Lassú lenne a flash memória erre a célra? :D
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: PROGMEM

Hozzászólás Szerző: kapu48 »

Ezt megtudod ha debugolsz:

Kód: Egész kijelölése


#include "avr/pgmspace.h"

const byte sinetable[48] PROGMEM = {128,144,160,176,191,205,218,229,238,245,251,254,255,254,251,245,238,229,218,205,191,176,160,144,128,111,95,79,64,50,37,26,17,10,4,1,0,1,4,10,17,26,37,50,64,79,95,111};

byte szamlalo=0;
byte data=0;

void setup() {
	 Serial.begin(9600);
}

void loop() {
  if (szamlalo<46) {
    szamlalo++;
  } else {
    szamlalo=0;
  }

 data = pgm_read_byte_near(sinetable[szamlalo]);
 Serial.print(data);   // ???
 Serial.print(", ");
  analogWrite(11, data);
  delay(10);
}

Avatar
csabeszq
Bitfaragó
Hozzászólások: 678
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: PROGMEM

Hozzászólás Szerző: csabeszq »

Pontosan 1 órajel Atmega alatt a flash kiolvasás, ESP alatt 10x lassabb, mint ramból. Mást rontasz el.

A serial println viszont lassú, nem is kicsit.
borisz
DrótVégénSzéndarab
Hozzászólások: 31
Csatlakozott: 2016. november 26. szombat, 9:39

Re: PROGMEM

Hozzászólás Szerző: borisz »

Növeltem a késleltetést, de így sem javult. A soros monitort nézve ezeket az értékeket kapom:
4,157,157,157,157,12,12,176,12,12,157,12,12,148,0,12,157,32,12,0,12,12,12,12,12,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,12,12,176,12,12,157,12,12,148,0,12,157,0,12,12,12,12,12,12,
Sokszor ismételi a tömb egyes részeit és nem is az egymás után lévőket. Ezt a LED villogása is bizonyítja. A "szamlalo" változó végig számol és utána kezdi megint nulláról.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: PROGMEM

Hozzászólás Szerző: kapu48 »

Serial.print(data); // ???
Csak addig kellene, amíg le ellenőrzi, hogy helyes sorrendben kerülnek beolvasásra az adatok!

Szerintem túl gyors a ritmus, nem győzi követni a szem!
Avatar
csabeszq
Bitfaragó
Hozzászólások: 678
Csatlakozott: 2012. szeptember 5. szerda, 6:00

Re: PROGMEM

Hozzászólás Szerző: csabeszq »

A pgm_read_byte címet kér.

pgm_read_byte(&szinusz[index])

Nem láttam nálad az & jelet.
borisz
DrótVégénSzéndarab
Hozzászólások: 31
Csatlakozott: 2016. november 26. szombat, 9:39

Re: PROGMEM

Hozzászólás Szerző: borisz »

Minden érték váltás közt van a programban 10 millisec várakozás. Én az előbb amit írtam akkor ezt a várakozást átírtam 100-ra, amit még lehet szemmel követni és még szerintem a soros port is elbír.

Ja és tényleg nincs ott & jel. Most hogy beírtam rendesen működik :) Köszönöm, de kérném, hogy egy kicsit bővebben írd le miért kell az oda, mert próbáltam google fordítóval a progmem oldalt értelmezni, de nem sikerült teljes egészében.
Válasz küldése