Arduino függvénykönyvtár írása

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
Avatar
szegoj
SzínkódFestő
Hozzászólások: 92
Csatlakozott: 2010. február 4. csütörtök, 7:00

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

A <> illetve "" jelölések a library fájl helyére utalnak. <> esetén a library fájl a szokásos helyen található (pl. Arduino library könyvtár), a "" használatával azt jelezzük, hogy a library fájl a tárgykönyvtárban található.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

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

Szorgalmi HF. Haladóknak.
Elvillogja a nevemet. (Elvileg. Gyakorlatban megfelelő HW. híján nem tudtam tesztelni!)

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

// Morse02.ino
  
#include "Morse.h"

 Morse morse(13);
 
char MorseChr;
String mystr = "Kapu 48";
// int mstLen = int(strlen(mystr));
int i;
int it;

void SelectChr(char Morsechr);

void setup()
{
}

void loop()
{
   it =mystr.length();   // it = a mi Stringünk hossza
   for (i = 1; i <= it; i++){      // Végig lépkedünk a karaktereken
       MorseChr = mystr.charAt (i); // Ki emeljük a következő karaktert
       SelectChr(MorseChr);      // Meghívjuk a Villogtató rutinunkat
   } 
   delay(3000);
}
// Karakter keresés és villogtatása.
void SelectChr(char Morsechr) {
  switch (Morsechr) {
  case 'A':  // a	.-
  case 'a':
           morse.dot();morse.dash();
    break;
  case 'B':  // b	-...
  case 'b':
          morse.dash(); morse.dot(); morse.dot(); morse.dot();
    break;
  case 'C':  // c	-.-.
  case 'c':
          morse.dash(); morse.dot(); morse.dash(); morse.dot();
    break;
  case 'D':  // d	-..
  case 'd':
          morse.dash(); morse.dot(); morse.dot();
    break;
  case 'E':  // e	.
  case 'e':
          morse.dot();
    break;
  case 'F':  // f	..-.
  case 'f':
          morse.dot(); morse.dot(); morse.dash(); morse.dot();
    break;
  case 'G':  // g	--.
  case 'g':
           morse.dash(); morse.dash(); morse.dot();
  case 'H':  // h	....
  case 'h':
           morse.dot(); morse.dot(); morse.dot(); morse.dot();
    break;
  case 'I':  // i	..
  case 'i':
           morse.dot(); morse.dot();
    break;
  case 'J':  // j	.---
  case 'j':
           morse.dot();morse.dash(); morse.dash(); morse.dash(); 
    break;
  case 'K':  // k	-.-
  case 'k':
           morse.dash(); morse.dot();morse.dash(); 
    break;
  case 'L':  // l	.-..
  case 'l':
           morse.dot(); morse.dash(); morse.dot(); morse.dot();
    break;
  case 'M':  // m	--
  case 'm':
           morse.dash(); morse.dash(); 
    break;
  case 'N':  // n	-.
  case 'n':
           morse.dash(); morse.dot();
    break;
  case 'O':  // o	---
  case 'o':
           morse.dash(); morse.dash(); morse.dash(); 
    break;
  case 'P':  // p	.--.
  case 'p':
           morse.dot(); morse.dash(); morse.dash(); morse.dot();
    break;
  case 'Q':  // q	--.-
  case 'q':
           morse.dash(); morse.dash(); morse.dot();morse.dash(); 
    break;
  case 'R':  // r	.-.
  case 'r':
           morse.dot(); morse.dash(); morse.dot();
    break;
  case 'S':  // s	...
  case 's':
           morse.dot(); morse.dot(); morse.dot();
    break;
  case 'T':  // t	-
  case 't':
           morse.dash(); 
    break;
  case 'U':  // u	..-
  case 'u':
           morse.dot(); morse.dot();morse.dash(); 
    break;
  case 'V':  // v	...-
  case 'v':
           morse.dot(); morse.dot(); morse.dot();morse.dash(); 
    break;
  case 'W':  // w	.--
  case 'w':
           morse.dot();morse.dash(); morse.dash(); 
    break;
  case 'X':  // x	-..-
  case 'x':
            morse.dash(); morse.dot(); morse.dot();morse.dash(); 
    break;
  case 'Y':  // y	-.--
  case 'y':
          morse.dash(); morse.dot();morse.dash(); morse.dash();
    break;
    // Számok
  case '0':  // 0	-----
          morse.dash(); morse.dash(); morse.dash(); morse.dash(); morse.dash();
    break;
  case '1':  // 1	.----
         morse.dot(); morse.dash(); morse.dash(); morse.dash(); morse.dash();
    break;
  case '2':  // 2	..---
         morse.dot();  morse.dot();  morse.dash(); morse.dash(); morse.dash();
    break;
  case '3':  // 3	...--
         morse.dot();  morse.dot();  morse.dot();  morse.dash(); morse.dash();
    break;
  case '4':  // 4	....-
         morse.dot();  morse.dot();  morse.dot();  morse.dot();  morse.dash(); 
    break;
  case '5':  // 5	.....
         morse.dot();  morse.dot();  morse.dot();  morse.dot();  morse.dot(); 
    break;
  case '6':  // 6	-....
          morse.dash(); morse.dot();  morse.dot();  morse.dot();  morse.dot(); 
    break;
  case '7':  // 7	--...
         morse.dash(); morse.dash();  morse.dot();  morse.dot();  morse.dot();
    break;
  case '8':  // 8	---..
         morse.dash(); morse.dash(); morse.dash();  morse.dot();  morse.dot();
    break;
  case '9':  // 9	----.
         morse.dash(); morse.dash(); morse.dash(); morse.dash();  morse.dot(); 
    break;
  case ' ':  // Spc (szóköz)
           delay(_szv); 
    break;
   // Jelek
  case '/':  // Tört jel [/]	-..-.
          morse.dash();  morse.dot();  morse.dot(); morse.dash();  morse.dot(); 
    break;    
  case '=':  // Egyenlőség jel [=]	-...-
          morse.dash();  morse.dot();  morse.dot();  morse.dot(); morse.dash(); 
    break; 
  case '?':  // Kérdőjel [?]	..--..
           morse.dot();  morse.dot(); morse.dash(); morse.dash(); morse.dot();  morse.dot();  
    break; 
  case '_':  // Alsó vonal [_]	..--.-
           morse.dot();  morse.dot(); morse.dash(); morse.dash();  morse.dot(); morse.dash(); 
    break; 
  case '"':  // Idézőjelek ["]	.-..-.
           morse.dot(); morse.dash();  morse.dot();  morse.dot(); morse.dash(); morse.dot();   
    break; 
   case '.':  // Mondat vége pont [.]	.-.-.-
           morse.dot(); morse.dash();  morse.dot();  morse.dash();  morse.dot(); morse.dash(); 
    break;    
  case '@':  // At jel [@]*	.--.-.
           morse.dot(); morse.dash(); morse.dash();  morse.dot(); morse.dash();  morse.dot(); 
    break; 
  case 39:  // Aposztróf ASCII=39 [']	.----.
           morse.dot(); morse.dash(); morse.dash(); morse.dash(); morse.dash(); morse.dot();  
    break; 
  case '-':  // Kötőjel [-]	-....-
          morse.dash();  morse.dot();  morse.dot();  morse.dot(); morse.dash(); 
    break; 
  case ';':  // Pontos vessző [;]	-.-.-.
          morse.dash();  morse.dot(); morse.dash();  morse.dot(); morse.dash(); morse.dot();  
    break; 
   case '!':  // Felkiáltó jel [!]**	-.-.--
           morse.dash(); morse.dot();  morse.dash();  morse.dot(); morse.dash(); morse.dash(); 
    break;    
  case '(':  // Zárójelek [()]	 -.--.-
  case ')':
           morse.dash();  morse.dot(); morse.dash(); morse.dash();  morse.dot(); morse.dash(); 
    break; 
  case ',':  // Vessző [,]	--..--
          morse.dash(); morse.dash(); morse.dot();  morse.dot();  morse.dash(); morse.dash();  
    break; 
  case ':':  // Kettőspont [:]	---...
          morse.dash(); morse.dash(); morse.dash(); morse.dot();  morse.dot();  morse.dot();  
    break; 
  case '$':  // Dollár [$]	...-..-
           morse.dot();  morse.dot();  morse.dot(); morse.dash(); morse.dot();  morse.dot();  morse.dash();   
    break;    
  }
  delay(_kkoz);   // Karakterek közti szünet.
} 

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

// Morse.h
/*
  Morse.h - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
*/

#ifndef Morse_h
#define Morse_h

  #if defined(ARDUINO) && ARDUINO >= 100
  #include <Arduino.h>
  #else
  #include <WProgram.h>
  #endif
  
// Itt lehet belőni a sebességet
  const int _ti = 250;  // Ti hossza
  const int _ta = _ti * 3;  // Tá hossza
  const int _koz = _ti;  // szünet a jelek között
  const int _kkoz = _ti * 2;  // szünet a karakterek közt
  const int _szv = _ti * 4;  // szünet a szavak között  

class Morse
{
  public:
    Morse(int pin);
    void dot();
    void dash();
    void spc();    // Space
    
  private:
    int _pin;

};

#endif

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

// Morse.cpp
/*
  Morse.cpp - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
*/
// #include <Arduino.h>
// #include "WProgram.h"
#include "Morse.h"

Morse::Morse(int pin)
{
  pinMode(pin, OUTPUT);
  _pin = pin;
}

void Morse::dot()
{
  digitalWrite(_pin, HIGH);
  delay(_ti);
  digitalWrite(_pin, LOW);
  delay(_koz);  
}

void Morse::dash()
{
  digitalWrite(_pin, HIGH);
  delay(_ta);
  digitalWrite(_pin, LOW);
  delay(_koz);
}

void Morse::spc()    // Space
{
  delay(_szv);
}  
Esetleg valakinek van hozzá Arduino és kedve, tesztelhetné!
:wink:

Kicsit javítottam!
8)
A hozzászólást 3 alkalommal szerkesztették, utoljára kapu48 2012. július 24. kedd, 12:09-kor.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

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

Ez a megoldássor (case, szubrutinok), de külső függvénykönyvtár nélkül egy későbbi házi feladat része:). És persze csipogóval...
KERA
Újonc
Újonc
Hozzászólások: 7
Csatlakozott: 2014. március 21. péntek, 11:04

Re: Arduino függvénykönyvtár írása

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

Lehet nem itt kellene kérdeznem de hirtelen közelebbi topicot nem találtam.

Hogy viselkedik az arduino IDE környezet ha külső könyvtárat használnék?
Találtam 2 olyan hw elemet aminek vannak külső támogatása.
Egyik a virtual wire RF modulokhoz. Ezt kényelmesen használom.

Van 2 3 féle a maxim7219/7221 8*8 pont mátrix vezérlőjéhez is.
Ezek érdekesek mivel az egyikhez vannak *.ino minta példák , a másikhoz pedig *.pde.
Az pde kiterjesztésű példa fájlokra mutat a http://playground.arduino.cc/ oldalon a maximok támogatását
taglaló oldal.
Documentation
-------------
There is a tutorial for the library on the [Arduino Playground](http://playground.arduino.cc/Main/LedControl)

Download
--------
The lastest binary version of the Library is always available from the
[LedControl Release Page](https://github.com/wayoda/LedControl/releases)

Az ino-s minták itt vannak: https://github.com/csdexter/MAX7219

Próbálkoztam mindkét könyvtárral de egyiket sem hajlandó lefordítani.
Pontosabban ha a saját mintafájlokat magukba nyitom meg és "importálom" a zipfilét/mappát amiben a *.c *.h filék vannak akkor lefordul.
Saját forrásomban pedig nem.
#akármi.h "héder" fájlokra hivatkozok a forrásban de mikor könyvtárat szúrok be veszek fel akkor magától is beírja az IDE.

Másik fontos kérdés.
Miként tudom a IDE környezetben az aktuálisan használandó külső könyvtárakat "be és kikapcsolni, váltani".
Mikor 1szer beimportáltam akkor már ott van a listájában.Ezt ki lehet törölni?
Más uC esetén az forrás file mellé érdemes bemásolni 1 mappába a többi héder , include stb filét ... (jó persze vannak elérési utak a fejlesztőkben beállíthatóan , ezzel nem akartam játszani).Mert akkor biztos tudja mit keressen és ott vannak egymás mellet, ezért raktam egymás mellé .

Jelen esetben ez is jó megoldás lehet ,hogy a forráskód *.ino mellé másolom a *-h *.c *.stb filéket ?
Miként tudom a "gyári" IDE környezethez vissza térni ?(unistall lehet nem elég mert a saját profilomba (W7 user rejtett mappái) szemetelhet az ardus IDE program.
Ekkor nem lenne felvéve a 2 3 féle külső könyvtár a saját próbálkozásaim által .
Avagy mindig csak az egyikkel foglalkoznék majd csere.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10191
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Arduino függvénykönyvtár írása

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

A pde az az Arduino-0023-ig támogatott, a felett sokminden változott (változó és eljárásneve). Azaz az 1.x.x esetén esetleges a működés.
Emiatt a kiterjesztés is megváltozott: *.ino: Arduino 1.0.0 vagy későbbi programja.

Külső könyvtárat a Arduino/libraries alá kell bemásolni az ottani minták alapján (*.cpp, *.h, keywords.txt és az examples/ alapján).
_Utána_ indítod az Arduinot és felismeri induláskor. Nincs ki/bekapcsolás. Futó Arduino esetén hiába másolod be, nem fésüli újra.

Ha telepítővel Win alatt ment:
Uninstall elindítása és lefutása után
ProgramFiles/Arduinokönyvtár töröl.
%Profiles%/Dokumentumok/Arduino töröl.

Angolul lib telepítés:
http://arduino.cc/en/Guide/Libraries
KERA
Újonc
Újonc
Hozzászólások: 7
Csatlakozott: 2014. március 21. péntek, 11:04

Re: Arduino függvénykönyvtár írása

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

Értem akkor csak a forráskód elején beírt #akármifilenév.h hivatkozáskor használja külső könyvtárat is.
Lehet az IDE importált külső könyvtár listájába felvéve, ha nem hivatkozok a *.h fájlra akkor nem fordítok le mellé.
Akkor inkább az *.INO kiterjesztésű mintapéldákkal rendelkező könyvtárral próbálkozzak.
nor_bee
Újonc
Újonc
Hozzászólások: 4
Csatlakozott: 2016. január 10. vasárnap, 23:43

Re: Arduino függvénykönyvtár írása

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

Ezt a topic-ot találtam témába vágónak így elnézést ha nem ide kellett volna írnom. A library írással kapcsolatban azt szeretném kérdezni, hogy hogyan kell PROGMEM-be fordított konstansokat kezelni. Szét szeretném szedni a kódomat több fájlba, hogy könnyebben átlátható legyen és egy lib-be szeretnék tenni egy komplett menürendszert amiben sok szöveg van.

Ha csak egy sima sketch-ben kezelek progmemet akkor ennek a struktúrának az elérése simán működik (.ino fájl):

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

#include <avr/pgmspace.h>

struct MenuEntryStructure {
      const char *text;                         // pointer to text in progmem (RAM saving)
      unsigned char num_Of_Menuitems;           // char to provide the total number of menuitems in (sub)menu
      unsigned char prev_MenuItem;              // char to previous menuitem in (sub)menu
      unsigned char next_MenuItem;              // char to next menuitem in (sub)menu
      unsigned char onselect_MenuItem;          // char to submenu item when this menuitem is selected
      void (*fp)(void);							// pointer to a selectable function
};

/* MenuStructure for storing in ROM!!!
The numbering: first digit - submenu (0 is main menu) 1-9, second digit: subsub menu 1-9, third digit: menuitem 0-9
At the end of each lines line numbers are provided from 0-end continuously for Array numbers!!!
*/

const char PROGMEM menu_000[14] = "[  FOMENU   ]";      //00
const char PROGMEM menu_001[14] = "Submenu1";       //01
const char PROGMEM menu_002[14] = "Submenu2";       //02
const char PROGMEM menu_003[14] = "Main4";          //03
const char PROGMEM menu_004[14] = "Main5";          //04
const char PROGMEM menu_005[14] = "Main6";          //05
const char PROGMEM menu_006[14] = "Main7";          //06
const char PROGMEM menu_007[14] = "Main8";          //07
const char PROGMEM menu_008[14] = "Main9";          //08
const char PROGMEM menu_009[14] = "Main10";          //09

const char PROGMEM menu_100[14] = "[  SUBENU1  ]";      //10
const char PROGMEM menu_101[14] = "Sub1-2";         //11
const char PROGMEM menu_102[14] = "Sub1-3";         //12
const char PROGMEM menu_103[14] = "Sub1-4";         //13
const char PROGMEM menu_104[14] = "Sub1-5";         //14
const char PROGMEM menu_105[14] = "Return";         //15

const char PROGMEM menu_200[14] = "[  SUBENU2  ]";      //16
const char PROGMEM menu_201[14] = "Sub2-2";         //17
const char PROGMEM menu_202[14] = "Sub2-3";         //18
const char PROGMEM menu_203[14] = "Sub2-4";         //19
const char PROGMEM menu_204[14] = "Sub2-5";         //20
const char PROGMEM menu_205[14] = "Return";         //21

extern const struct MenuEntryStructure PROGMEM lcdmenu [22] = {
  {menu_000, 10, 0, 0, 0, 0},       //pointer to menupoint string, num of items in actual (sub)menu, prev item num
  {menu_001, 10, 1, 2, 10, 0},      //next item num, onselect menuitem num, pointer to onselect function or null
  {menu_002, 10, 1, 3, 16, 0},      //for item number please see remarks at end of menupoint string initialisation lines
  {menu_003, 10, 2, 4, 3, 0},
  {menu_004, 10, 3, 5, 4, 0},
  {menu_005, 10, 4, 6, 5, 0},
  {menu_006, 10, 5, 7, 6, 0},
  {menu_007, 10, 6, 8, 7, 0},
  {menu_008, 10, 7, 9, 8, 0},
  {menu_009, 10, 8, 9, 9, 0},

  {menu_100, 6, 10, 10, 10, 0},
  {menu_101, 6, 11, 12, 11, 0},
  {menu_102, 6, 11, 13, 12, 0},
  {menu_103, 6, 12, 14, 13, 0},
  {menu_104, 6, 13, 15, 14, 0},
  {menu_105, 6, 14, 15, 1, 0},

  {menu_200, 6, 16, 16, 16, 0},
  {menu_201, 6, 17, 18, 17, 0},
  {menu_202, 6, 17, 19, 18, 0},
  {menu_203, 6, 18, 20, 19, 0},
  {menu_204, 6, 19, 21, 20, 0},
  {menu_205, 6, 20, 21, 2, 0},
};

void setup(){
  Serial.begin(57600);
  while(!Serial);
  Serial.println("OK");
}


void loop(){
 
  for (int i = 0; i < 22; i++){
    char * ptr = (char *) pgm_read_word (&(lcdmenu[i].text));
    Serial.println(ptr);
  }
    Serial.flush();
    exit(0);
}
Ezt a struktúra definíciót beletettem egy lib-be.

MenuStruct.h fájl (.ino fájl mellett ugyanabban a könyvtárban):

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

/*
	menustruct.h - Library to build an LCD menustructure in an external source code file

	Created by nor_bee, Jan 5. 2016
	
*/

#ifndef MenuStruct_h
	#define MenuStruct_h
	
	#include "Arduino.h"
	#include <avr/pgmspace.h> // Has to be included in this file as well!!!

	class MenuStruct
	{
		public:
                      
		// Data declarations of variables in cpp file
					  
		struct MenuEntryStructure{
			const char *text;                         // pointer to text in progmem (RAM saving)
			unsigned char num_Of_Menuitems;           // char to provide the total number of menuitems in (sub)menu
			unsigned char prev_MenuItem;              // char to previous menuitem in (sub)menu
			unsigned char next_MenuItem;              // char to next menuitem in (sub)menu
			unsigned char onselect_MenuItem;          // char to submenu item when this menuitem is selected
			void (*fp)(void);
		};

		/* MenuITEM TEXT STORED in ROM!!! PROGMEM attribute will be used in cpp
		The numbering: first digit - submenu (0 is main menu) 1-9, second digit: subsub menu 1-9, third digit: menuitem 0-9
		At the end of each lines line numbers are provided from 0-end continuously for Array numbers!!!
		*/

		char menu_000[14];					//00
		char menu_001[14];					//01
		char menu_002[14];					//02
		char menu_003[14];					//03
		char menu_004[14];					//04
		char menu_005[14];					//05
		char menu_006[14];					//06
		char menu_007[14];					//07
		char menu_008[14];					//08
		char menu_009[14];					//09

		char menu_100[14];					//10
		char menu_101[14];					//11
		char menu_102[14];					//12
		char menu_103[14];					//13
		char menu_104[14];					//14
		char menu_105[14];					//15

		char menu_200[14];					//16
		char menu_201[14];					//17
		char menu_202[14];					//18
		char menu_203[14];					//19
		char menu_204[14];					//20
		char menu_205[14];					//21

    
		struct MenuEntryStructure LCDMENU [22];             // MenuStructure STRUCT ARRAY


//    void MenuItemIext(unsigned char _menuItemNum);
    
		private:											//just for reference until I figure out a valuable function

	};
#endif
MenuStruct.cpp fájl (.ino fájl mellett ugyanabban a könyvtárban):

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


#include "Arduino.h"
#include <avr/pgmspace.h>                       // Has to be in this file as well!!!
#include "MenuStruct.h"

struct MenuEntryStructure {
      const char *text;                         // pointer to text in progmem (RAM saving)
      unsigned char num_Of_Menuitems;           // char to provide the total number of menuitems in (sub)menu
      unsigned char prev_MenuItem;              // char to previous menuitem in (sub)menu
      unsigned char next_MenuItem;              // char to next menuitem in (sub)menu
      unsigned char onselect_MenuItem;          // char to submenu item when this menuitem is selected
      void (*fp)(void);                         // pointer to onselect function
};


/* MenuStructure for storing in ROM!!!
The numbering: first digit - submenu (0 is main menu) 1-9, second digit: subsub menu 1-9, third digit: menuitem 0-9
At the end of each lines line numbers are provided from 0-end continuously for Array numbers!!! */

const char PROGMEM menu_000[14] = "[  FOMENU   ]";			//00
const char PROGMEM menu_001[14] = "Submenu1";				//01
const char PROGMEM menu_002[14] = "Submenu2";				//02
const char PROGMEM menu_003[14] = "Main4";					//03
const char PROGMEM menu_004[14] = "Main5";					//04
const char PROGMEM menu_005[14] = "Main6";					//05
const char PROGMEM menu_006[14] = "Main7";					//06
const char PROGMEM menu_007[14] = "Main8";					//07
const char PROGMEM menu_008[14] = "Main9";					//08
const char PROGMEM menu_009[14] = "Main10";					//09

const char PROGMEM menu_100[14] = "[  SUBENU1  ]";			//10
const char PROGMEM menu_101[14] = "Sub1-2";					//11
const char PROGMEM menu_102[14] = "Sub1-3";					//12
const char PROGMEM menu_103[14] = "Sub1-4";					//13
const char PROGMEM menu_104[14] = "Sub1-5";					//14
const char PROGMEM menu_105[14] = "Return";					//15

const char PROGMEM menu_200[14] = "[  SUBENU2  ]";			//16
const char PROGMEM menu_201[14] = "Sub2-2";					//17
const char PROGMEM menu_202[14] = "Sub2-3";					//18
const char PROGMEM menu_203[14] = "Sub2-4";					//19
const char PROGMEM menu_204[14] = "Sub2-5";					//20
const char PROGMEM menu_205[14] = "Return";					//21

const struct MenuEntryStructure PROGMEM LCDMENU [22] = {
	{menu_000, 10, 0, 0, 0, 0},				//pointer to menupoint string, num of items in actual (sub)menu, prev item num
	{menu_001, 10, 1, 2, 10, 0},			//next item num, onselect menuitem num, pointer to onselect function or null
	{menu_002, 10, 1, 3, 16, 0},            //for item number please see remarks at end of menupoint string initialisation lines
	{menu_003, 10, 2, 4, 3, 0},
	{menu_004, 10, 3, 5, 4, 0},
	{menu_005, 10, 4, 6, 5, 0},
	{menu_006, 10, 5, 7, 6, 0},
	{menu_007, 10, 6, 8, 7, 0},
	{menu_008, 10, 7, 9, 8, 0},
	{menu_009, 10, 8, 9, 9, 0},

	{menu_100, 6, 10, 10, 10, 0},
	{menu_101, 6, 11, 12, 11, 0},
	{menu_102, 6, 11, 13, 12, 0},
	{menu_103, 6, 12, 14, 13, 0},
	{menu_104, 6, 13, 15, 14, 0},
	{menu_105, 6, 14, 15, 1, 0},

	{menu_200, 6, 16, 16, 16, 0},
	{menu_201, 6, 17, 18, 17, 0},
	{menu_202, 6, 17, 19, 18, 0},
	{menu_203, 6, 18, 20, 19, 0},
	{menu_204, 6, 19, 21, 20, 0},
	{menu_205, 6, 20, 21, 2, 0},
};
.ino fájl amivel megpróbáltam a stringeket visszaolvasni:

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

#include <avr/pgmspace.h>
#include "MenuStruct.h"

MenuStruct menustruct;  // Create an instance of MenuStruct class. This makes it's content accessible

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

void loop() {

	unsigned char k;
  
	for(k=0 ; k < 22; k++) {
	  Serial.print((int) k);
    Serial.print(' ');
    strcpy_P(textBuffer, (char*)pgm_read_word(&(menustruct.LCDMENU[k].text))); // Necessary casts and dereferencing, just copy.
    Serial.println(textBuffer);
  }
  Serial.flush();
  exit(0);
}
A kód hibaüzenet nélkül lefordul de sajnos sokkal több RAM-ot fogyaszt mintha egy ino fájlban lenne minden pakolva és emellett nem is azt produkálja amit kellene... Van valakinek abban tapasztalata, hogy Arduino C++ lib-ben hogyan lehet egy osztályban elhelyezett és PROGMEM-be fordított konstansokkal dolgozni? Nagyon érdekelne, hogy mit néztem be... :-) Előre is köszi a segítséget!
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Arduino függvénykönyvtár írása

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

Nem értem minek így túlkomplikálni a beolvasást?

Pedig a példában roppant egyszerű!:
https://www.arduino.cc/en/Reference/PROGMEM

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

 // read back a char
  int len = strlen_P(signMessage);
  for (k = 0; k < len; k++)
  {
    myChar =  pgm_read_byte_near(signMessage + k);
    Serial.print(myChar);
  }

  Serial.println();

És írjál 1 readFlashPrint függvényt, a Menu.cpp állományba.
Amit hívhatsz a loop-ból.

8)
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Arduino függvénykönyvtár írása

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

Sajnos elég sok mindent módosítottam a forráskódodban!
De gondolom az eredménnyel meg leszel elégedve?
Helyfoglalás Megára fordítva:
Sketch uses 3 036 bytes (1%) of program storage space. Maximum is 253 952 bytes.

Global variables use 219 bytes (2%) of dynamic memory, leaving 7 973 bytes for local variables. Maximum is 8 192 bytes.

Terminal:
0 [ FOMENU ] num_Of_Menuitems:10
1 Submenu1 num_Of_Menuitems:10
2 Submenu2 num_Of_Menuitems:10
3 Main4 num_Of_Menuitems:10
4 Main5 num_Of_Menuitems:10
5 Main6 num_Of_Menuitems:10
6 Main7 num_Of_Menuitems:10
7 Main8 num_Of_Menuitems:10
8 Main9 num_Of_Menuitems:10
9 Main10 num_Of_Menuitems:10
10 [ SUBENU1 ] num_Of_Menuitems:6
11 Sub1-2 num_Of_Menuitems:6
12 Sub1-3 num_Of_Menuitems:6
13 Sub1-4 num_Of_Menuitems:6
14 Sub1-5 num_Of_Menuitems:6
15 Return num_Of_Menuitems:6
16 [ SUBENU2 ] num_Of_Menuitems:6
17 Sub2-2 num_Of_Menuitems:6
18 Sub2-3 num_Of_Menuitems:6
19 Sub2-4 num_Of_Menuitems:6
20 Sub2-5 num_Of_Menuitems:6
21 Return num_Of_Menuitems:6

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

// MenuStruct.ino

#include <avr/pgmspace.h>
#include "MenuStruct.h"

MenuStruct menustruct;  // Create an instance of MenuStruct class. This makes it's content accessible

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

void loop() {

   unsigned char k;
   char textBuffer[20];
   
   for(k=0 ; k < 22; k++) {
     Serial.print((int) k);
     Serial.print(' ');
   // strcpy_P(textBuffer, (char*)pgm_read_word(&(menustruct.LCDMENU[k].text))); // Necessary casts and dereferencing, just copy.
     menustruct.getFlashString(k);

   }
   Serial.flush();
   exit(0);
}

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

// MenuStruct.cpp

#include "Arduino.h"
#include <avr/pgmspace.h>                       // Has to be in this file as well!!!
#include "MenuStruct.h"
/*
struct MenuEntryStructure {
 //     const char *text;                         // pointer to text in progmem (RAM saving)
      unsigned char num_Of_Menuitems;           // char to provide the total number of menuitems in (sub)menu
      unsigned char prev_MenuItem;              // char to previous menuitem in (sub)menu
      unsigned char next_MenuItem;              // char to next menuitem in (sub)menu
      unsigned char onselect_MenuItem;          // char to submenu item when this menuitem is selected
     // void (*fp)(void);                         // pointer to onselect function
};
*/

/* MenuStructure for storing in ROM!!!
The numbering: first digit - submenu (0 is main menu) 1-9, second digit: subsub menu 1-9, third digit: menuitem 0-9
At the end of each lines line numbers are provided from 0-end continuously for Array numbers!!! */

const char PROGMEM menuString[][14] = {
      { "[  FOMENU   ]" },        //00
      {  "Submenu1"   },          //01
      {  "Submenu2"    },         //02
      {  "Main4"      },          //03
      {  "Main5"      },          //04
      {  "Main6"       },         //05
      {  "Main7"      },          //06
      {  "Main8"      },          //07
      {  "Main9"      },          //08
      {  "Main10"     },           //09

      {  "[  SUBENU1  ]"  },        //10
      {  "Sub1-2"     },           //11
      {  "Sub1-3"      },          //12
      {  "Sub1-4"      },          //13
      {  "Sub1-5"      },          //14
      {  "Return"      },          //15

      {  "[  SUBENU2  ]" },         //16
      {  "Sub2-2"       },         //17
      {  "Sub2-3"        },        //18
      {  "Sub2-4"        },        //19
      {  "Sub2-5"        },        //20
      {  "Return"        }        //21
 };

const char PROGMEM LCDMENU[][5] = { 
//const struct MenuEntryStructure LCDMENU [22] PROGMEM = {
   { 10, 0, 0, 0, 0},            //pointer to menupoint string, num of items in actual (sub)menu, prev item num
   { 10, 1, 2, 10, 0},         //next item num, onselect menuitem num, pointer to onselect function or null
   { 10, 1, 3, 16, 0},            //for item number please see remarks at end of menupoint string initialisation lines
   { 10, 2, 4, 3, 0},
   { 10, 3, 5, 4, 0},
   { 10, 4, 6, 5, 0},
   { 10, 5, 7, 6, 0},
   { 10, 6, 8, 7, 0},
   { 10, 7, 9, 8, 0},
   { 10, 8, 9, 9, 0},

   { 6, 10, 10, 10, 0},
   { 6, 11, 12, 11, 0},
   { 6, 11, 13, 12, 0},
   { 6, 12, 14, 13, 0},
   { 6, 13, 15, 14, 0},
   { 6, 14, 15, 1, 0},

   { 6, 16, 16, 16, 0},
   { 6, 17, 18, 17, 0},
   { 6, 17, 19, 18, 0},
   { 6, 18, 20, 19, 0},
   { 6, 19, 21, 20, 0},
   { 6, 20, 21, 2, 0}
};

//String charTomb1;

void MenuStruct::getFlashString(uint8_t textindex){
  char ch;
 // charTomb1 = "";
  uint8_t ci = 0; // karakter index

        do{   // Get Flash String
          ch = char(pgm_read_byte(& menuString[textindex][ci++]));
//          charTomb1 += ch;
            Serial.print(ch);
        } while (ch);           // ? 0
      //   Serial.print(' ');
      Serial.print(" num_Of_Menuitems:");
      ci = uint8_t(pgm_read_byte(&LCDMENU[textindex][0]));
     Serial.println(ci);
     //Serial.println("");        
  //Serial.println(charTomb1);
  //Serial.println("");  
}

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

/*
   menustruct.h - Library to build an LCD menustructure in an external source code file

   Created by nor_bee, Jan 5. 2016
   
*/

#ifndef MenuStruct_h
   #define MenuStruct_h
   
   #include "Arduino.h"
   #include <avr/pgmspace.h> // Has to be included in this file as well!!!

   class MenuStruct
   {
      public:
                      
      // Data declarations of variables in cpp file
/**                 
      struct MenuEntryStructure{
        // const char *text;                         // pointer to text in progmem (RAM saving)
         unsigned char num_Of_Menuitems;           // char to provide the total number of menuitems in (sub)menu
         unsigned char prev_MenuItem;              // char to previous menuitem in (sub)menu
         unsigned char next_MenuItem;              // char to next menuitem in (sub)menu
         unsigned char onselect_MenuItem;          // char to submenu item when this menuitem is selected
        // void (*fp)(void);
      };

      /* MenuITEM TEXT STORED in ROM!!! PROGMEM attribute will be used in cpp
      The numbering: first digit - submenu (0 is main menu) 1-9, second digit: subsub menu 1-9, third digit: menuitem 0-9
      At the end of each lines line numbers are provided from 0-end continuously for Array numbers!!!
      */
/*
      char menu_000[14];               //00
      char menu_001[14];               //01
      char menu_002[14];               //02
      char menu_003[14];               //03
      char menu_004[14];               //04
      char menu_005[14];               //05
      char menu_006[14];               //06
      char menu_007[14];               //07
      char menu_008[14];               //08
      char menu_009[14];               //09

      char menu_100[14];               //10
      char menu_101[14];               //11
      char menu_102[14];               //12
      char menu_103[14];               //13
      char menu_104[14];               //14
      char menu_105[14];               //15

      char menu_200[14];               //16
      char menu_201[14];               //17
      char menu_202[14];               //18
      char menu_203[14];               //19
      char menu_204[14];               //20
      char menu_205[14];               //21
*/
    
      //struct MenuEntryStructure LCDMENU [22];             // MenuStructure STRUCT ARRAY
    
      void getFlashString(uint8_t textindex);
      
//    void MenuItemIext(unsigned char _menuItemNum);
    
      private:                                 //just for reference until I figure out a valuable function

   };
#endif

A Structurád beolvasását nem tudtam megoldani! Ezért elvetettem.
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Arduino függvénykönyvtár írása

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

Lefordítottam UNO-ra is:
Sketch uses 2 826 bytes (8%) of program storage space. Maximum is 32 256 bytes.
Global variables use 217 bytes (10%) of dynamic memory, leaving 1 831 bytes for local variables. Maximum is 2 048 bytes.
(Érdekes! kissebb helyet foglal!)

Kicsit tovább fejlesztve:

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

void MenuStruct::getFlashString(uint8_t textindex){
  char ch;
 // charTomb1 = "";
  uint8_t ci = 0; // karakter index

      do{   // Get Flash String
          ch = char(pgm_read_byte(& menuString[textindex][ci++]));
//        charTomb1 += ch;
          Serial.print(ch);
      } while (ch);           // ? 0
      //   Serial.print(' ');
      Serial.print("    LCDMENU: ");
    for(uint8_t i = 0; i < 5; i++){  
      ci = uint8_t(pgm_read_byte(&LCDMENU[textindex][i]));
      Serial.print(ci);
      Serial.print(", "); 
    }       
  //Serial.println(charTomb1);
  Serial.println("");  
}
Terminal:
0 [ FOMENU ] LCDMENU: 10, 0, 0, 0, 0,
1 Submenu1 LCDMENU: 10, 1, 2, 10, 0,
2 Submenu2 LCDMENU: 10, 1, 3, 16, 0,
3 Main4 LCDMENU: 10, 2, 4, 3, 0,
4 Main5 LCDMENU: 10, 3, 5, 4, 0,
5 Main6 LCDMENU: 10, 4, 6, 5, 0,
6 Main7 LCDMENU: 10, 5, 7, 6, 0,
7 Main8 LCDMENU: 10, 6, 8, 7, 0,
8 Main9 LCDMENU: 10, 7, 9, 8, 0,
9 Main10 LCDMENU: 10, 8, 9, 9, 0,
10 [ SUBENU1 ] LCDMENU: 6, 10, 10, 10, 0,
11 Sub1-2 LCDMENU: 6, 11, 12, 11, 0,
12 Sub1-3 LCDMENU: 6, 11, 13, 12, 0,
13 Sub1-4 LCDMENU: 6, 12, 14, 13, 0,
14 Sub1-5 LCDMENU: 6, 13, 15, 14, 0,
15 Return LCDMENU: 6, 14, 15, 1, 0,
16 [ SUBENU2 ] LCDMENU: 6, 16, 16, 16, 0,
17 Sub2-2 LCDMENU: 6, 17, 18, 17, 0,
18 Sub2-3 LCDMENU: 6, 17, 19, 18, 0,
19 Sub2-4 LCDMENU: 6, 18, 20, 19, 0,
20 Sub2-5 LCDMENU: 6, 19, 21, 20, 0,
21 Return LCDMENU: 6, 20, 21, 2, 0,
nor_bee
Újonc
Újonc
Hozzászólások: 4
Csatlakozott: 2016. január 10. vasárnap, 23:43

Re: Arduino függvénykönyvtár írása

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

Kedves Kapu48! Köszönöm a gyors választ! Sajnos nem tudtam korábban visszajelezni. Hamarosan kipróbálom!
nor_bee
Újonc
Újonc
Hozzászólások: 4
Csatlakozott: 2016. január 10. vasárnap, 23:43

Re: Arduino függvénykönyvtár írása

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

Kedves kapu48!

Szépen lefordul és valóban pgmspace-be kerülnek az adatok. Egy fontos kérdés: Miért nem kellett a .h fájlban deklarálni a változókat? Talán ilyenkor automatikusan "private"-ok lesznek?

A struktúra nem bonyolításnak került bele hanem, hogy egy menüpont különböző logikailag összetartozó de különféle típusú adatait csoportosítva le lehessen lekérdezni. (így a későbbi kód átláthatóbb nekem)

Másik kérdésem: A függvény pointerek működnek ha maguk a pointerek progmembe kerülnek?

Ez azért lenne fontos nekem, hogy a tényleges funkcióval bíró menüpontokhoz - ahol a pointer értéke nem NUL, hanem egy kódrészre mutat - egyszerűen hozzá tudjak rendelni egy hívást.

Előre is köszönöm válaszod!
Avatar
kapu48
Elektronbűvölő
Hozzászólások: 3375
Csatlakozott: 2008. augusztus 29. péntek, 6:00

Re: Arduino függvénykönyvtár írása

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

Progmemebe csak Constansokat rakhatsz! Változókat nem!
Ezért nem lehet a Progmembe kerülő strukturában keverni változót.


Fügvényekre mutató tömböt készithetsz amit aztán könyen tudsz indekszelni.
Példa: http://www.hobbielektronika.hu/forum/to ... ml#1918138

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

 void tooglePortA(uint8_t pin);
 void tooglePortB(uint8_t pin);
 void tooglePortC(uint8_t pin);
...
 
 void (* const foo[])(uint8_t) = {tooglePortA, tooglePortB, tooglePortC};

.....
//tooglePortB(27);    // Helyet:
foo[1](27);

nor_bee
Újonc
Újonc
Hozzászólások: 4
Csatlakozott: 2016. január 10. vasárnap, 23:43

Re: Arduino függvénykönyvtár írása

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

Értem, köszi! Csak konstansokból felépülő struktúra volt az eredeti cél. Másik C környezetben működött. Mindig vannak sajátosságok :-)
Válasz küldése