B4R Code Snippet Various table operation and lookup in PROGMEM

Hi everybody,
with Erel's help and some user's hint I have written this module. Hope it can be useful!

Mauro Zanin

Main code(to test module)
B4X:
#Region Project Attributes
    #AutoFlushLogs: True
    #CheckArrayBounds: True
    #StackBufferSize: 300
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public Serial1 As Serial
    Public tim As Timer
   
End Sub

Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    tim.Initialize("time",2000)
    tim.Enabled=True
    Log("Memory  Start:",AvailableRAM)
End Sub

Sub time
    Dim nr As UInt=3
    statica.GetString(nr)
   
    Log(statica.stringa)
    nr=26
    statica.GetString(nr)
    Log(statica.stringa)
    nr=3
    statica.GetString(nr)
    Log(statica.stringa)
   
    statica.FindString("DR2=")
    Log(statica.stringa)
    Log("Return:",leggilabel("C","DR3"))

    Log("Memory:",AvailableRAM)
End Sub
Sub leggilabel(dummy() As Byte,srcstr() As Byte)As Byte()
   
    Dim tmp(10) As Byte=JoinBytes(Array (srcstr,"=".GetBytes(),0))
       Log("Search for:",tmp)
    statica.FindString(tmp)
    Return statica.stringa
End Sub

Module to declare and access tables:
B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public stringa() As Byte
End Sub

Public Sub GetByte(Index As UInt) As Int
    Return RunNative("getdata", Index)
End Sub
 
public Sub GetString(index As UInt) As Int  'read table via relative index
      RunNative("getdata1", index)
End Sub
public Sub FindString(src() As Byte)  'Lookup table
      RunNative("findstring", src)
      Return
End Sub

#if C
#include <avr/pgmspace.h>
char strx[50];
const PROGMEM int data[] = { //change the data here
           0 ,  1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,
           9 ,  10 ,  11 ,  12 ,  13 ,  14 ,  15 ,
           16 ,  17 ,  18 ,  19 ,  20 ,  21 ,  22 ,
           23 ,  24 ,  24 ,  24 ,  24 ,  24 ,  24 ,
           24 ,  24 ,  24 ,  24 ,  25 ,  26 ,  27 ,
           28 ,  29 ,  30 ,  31 ,  32 ,  33 ,  34 ,
           34 ,  34 ,  34 ,  34 ,  34 ,  34 ,  34 ,
           34 ,  34 ,  35 ,  36 ,  37 ,  38 ,  39 ,
           40 ,  41 ,  42 ,  43 ,  44 ,  44 ,  44 ,
           44 ,  44 ,  44 ,  44 ,  44 ,  44 ,  44 ,
           45 ,  46 ,  47 ,  48 ,  49 ,  50 ,  51 ,
           52 ,  53 ,  54 ,  54 ,  54 ,  54 ,  54 ,
           54 ,  54 ,  54 ,  54 ,  54 ,  55 ,  56 ,
           57 ,  58 ,  59 ,  60 ,  61 ,  62 ,  63 ,
           64 ,  64 ,  64 ,  64 ,  64 ,  64 ,  64 ,
           64 ,  64 ,  64 ,  65 ,  66 ,  67 ,  68 ,
           69 ,  70 ,  71 ,  72 ,  73 ,  74 ,  74 ,
           74 ,  74 ,  74 ,  74 ,  74 ,  74 ,  74 ,
           74 ,  75 ,  76 ,  77 ,  78 ,  79 ,  80 ,
           81 ,  82 ,  83 ,  84 ,  84 ,  84 ,  84 ,
           84 ,  84 ,  84 ,  84 ,  84 ,  84 ,  85 ,
           86 ,  87 ,  88 ,  89 ,  90 ,  91 ,  92 ,
           93 ,  94 ,  94 ,  94 ,  94 ,  94 ,  94 ,
           94 ,  94 ,  94 ,  94 ,  95 ,  96 ,  97 ,
           98 ,  99 ,  100 ,  101 ,  102 ,  103 ,  104 ,
           104 ,  104 ,  104 ,  104 ,  104 ,  104 ,
           104 ,  104 ,  104 ,  105 ,  106 ,  107 ,
           108 ,  109 ,  110 ,  111 ,  112 ,  113 ,
           114 ,  114 ,  114 ,  114 ,  114 ,  114 ,
           114 ,  114 ,  114 ,  114 ,  115 ,  116 ,
           117 ,  118 ,  119 ,  120 ,  121 ,  122 ,
           123 ,  124 ,  124 ,  124 ,  124 ,  124 ,
           124 ,  124 ,  124 ,  124 ,  124 ,  125 ,
           126 ,  127 ,  128 ,  129 ,  130 ,  131 ,
           132 ,  133 ,  134 ,  134 ,  134 ,  134 ,
           134 ,  134 ,  134 ,  134 ,  134 ,  134 ,
           135 ,  136 ,  137 ,  138 ,  139 ,  140 ,
           141 ,  142 ,  143 ,  144 ,  144 ,  144 ,
           144 ,  144 ,  144 ,  144 ,  144 ,  144 ,
           144 ,  145 ,  146 ,  147 ,  148 ,  149 ,
           150 ,  151 ,  152 ,  153 ,  154 ,  154 ,
           154 ,  154 ,  154 ,  154 ,  154 ,  154 ,
           154 ,  154 ,  155 ,  156 ,  157 ,  158 ,
           159 ,  160 ,  161 ,  162 ,  163 ,  164 ,
           164 ,  164 ,  164 ,  164 ,  164 ,  164 ,
           164 ,  164 ,  164 ,  165 ,  166 ,  167 ,
           168 ,  169 ,  170 ,  171 ,  172 ,  173 ,
           174 ,  174 ,  174 ,  174 ,  174 ,  174 ,
           174 ,  174 ,  174 ,  174 ,  175 ,  176 ,
           177 ,  178 ,  179 ,  180 ,  181 ,  182 ,
           183 ,  184 ,  184 ,  184 ,  184 ,  184 ,
           184 ,  184 ,  184 ,  184 ,  184 ,  185 ,
           186 ,  187 ,  188 ,  189 ,  190 ,  191 ,
           192 ,  193 ,  194 ,  194 ,  194 ,  194 ,
           194 ,  194 ,  194 ,  194 ,  194 ,  194 ,
           195 ,  196 ,  197 ,  198 ,  199 ,  200 ,
           201 ,  202 ,  203 ,  204 ,  204 ,  204 ,
           204 ,  204 ,  204 ,  204 ,  204 ,  204 ,
           204 ,  205 ,  206 ,  207 ,  208 ,  209 ,
           210 ,  211 ,  212 ,  213 ,  214 ,  214 ,
           214 ,  214 ,  214 ,  214 ,  214 ,  214 ,
           214 ,  214 ,  215 ,  216 ,  217 ,  218 ,
           219 ,  220 ,  221 ,  222 ,  223 ,  224 ,
           224 ,  224 ,  224 ,  224 ,  224 ,  224 ,
           224 ,  224 ,  224 ,  225 ,  226 ,  227 ,
           228 ,  229 ,  230 ,  231 ,  232 ,  233 ,
           234 ,  234 ,  234 ,  234 ,  234 ,  234 ,
           234 ,  234 ,  234 ,  234 ,  235 ,  236 ,
           237 ,  238 ,  239 ,  240 ,  241 ,  242 ,
           243 ,  244 ,  244 ,  244 ,  244 ,  244 ,
           244 ,  244 ,  244 ,  244 ,  244 ,  245 ,
           246 ,  247 ,  248 ,  249 ,  250 ,  251 ,
           252 ,  253 ,  254 ,  254 ,  254 ,  254 ,
           254 ,  254 ,  254 ,  254 ,  254 ,  254 ,
           255 ,  256 ,  257 ,  258 ,  259 ,  260 ,
           261 ,  262 ,  263 ,  264 ,  264 ,  264 ,
           264 ,  264 ,  264 ,  264 ,  264 ,  264 ,
           264 ,  265 ,  266 ,  267 ,  268 ,  269 ,
           270 ,  271 ,  272 ,  273 ,  274 ,  274 ,
           274 ,  274 ,  274 ,  274 ,  274 ,  274 ,
           274 ,  274 ,  275 ,  276 ,  277 ,  278 ,
           279 ,  280 ,  281 ,  282 ,  283 ,  284 ,
           284 ,  284 ,  284 ,  284 ,  284 ,  284 ,
           284 ,  284 ,  284 ,  285 ,  286 ,  287 ,
           288 ,  289 ,  290 ,  291 ,  292 ,  293 ,
           294 ,  294 ,  294 ,  294 ,  294 ,  294 ,
           294 ,  294 ,  294 ,  294 ,  295 ,  296 ,
           297 ,  298 ,  299 ,  300 ,  301 ,  302 ,
           303 ,  304 ,  304 ,  304 ,  304 ,  304 ,
           304 ,  304 ,  304 ,  304 ,  304 ,  305 ,
           306 ,  307 ,  308 ,  309 ,  310 ,  311 ,
           312 ,  313 ,  314 ,  314 ,  314 ,  314 ,
           314 ,  314 ,  314 ,  314 ,  314 ,  314 ,
           315 ,  316 ,  317 ,  318 ,  319 ,  320 ,
           321 ,  322 ,  323 ,  324 ,  324 ,  324 ,
           324 ,  324 ,  324 ,  324 ,  324 ,  324 ,
           324 ,  325 ,  326 ,  327 ,  328 ,  329 ,
           330 ,  331 ,  332 ,  333 ,  334 ,  334 ,
           334 ,  334 ,  334 ,  334 ,  334 ,  334 ,
           334 ,  334 ,  335 ,  336 ,  337 ,  338 ,
           339 ,  340 ,  341 ,  342 ,  343 ,  344 ,
           344 ,  344 ,  344 ,  344 ,  344 ,  344 ,
           344 ,  344 ,  344 ,  345 ,  346 ,  347 ,
           348 ,  349 ,  350 ,  351 ,  352 ,  353 ,
           354 ,  354 ,  354 ,  354 ,  354 ,  354 ,
           354 ,  354 ,  354 ,  354 ,  355 ,  356 ,
           357 ,  358 ,  359 ,  360 ,  361 ,  362 ,
           363 ,  364 ,  364 ,  364 ,  364 ,  364 ,
           364 ,  364 ,  364 ,  364 ,  364 ,  365 ,
           366 ,  367 ,  368 ,  369 ,  370 ,  371 ,
           372 ,  373 ,  374 ,  374 ,  374 ,  374 ,
           374 ,  374 ,  374 ,  374 ,  374 ,  374 ,
           375 ,  376 ,  377 ,  378 ,  379 ,  380 ,
           381 ,  382 ,  383 ,  384 ,  384 ,  384 ,
           384 ,  384 ,  384 ,  384 ,  384 ,  384 ,
           384 ,  385 ,  386 ,  387 ,  388 ,  389 ,
           390 ,  391 ,  392 ,  393 ,  394 ,  394 ,
           394 ,  394 ,  394 ,  394 ,  394 ,  394 ,
           394 ,  394 ,  395 ,  396 ,  397 ,  398 ,
           399 ,  400 ,  401 ,  402 ,  403 ,  404 ,
           404 ,  404 ,  404 ,  404 ,  404 ,  404 ,
           404 ,  404 ,  404 ,  405 ,  406 ,  407 ,
           408 ,  409 ,  410 ,  411 ,  412 ,  413 ,
           414 ,  414 ,  414 ,  414 ,  414 ,  414 ,
           414 ,  414 ,  414 ,  414 ,  415 ,  416 ,
           417 ,  418 ,  419 ,  420 ,  421 ,  422 ,
           423 ,  424 ,  424 ,  424 ,  424 ,  424 ,
           424 ,  424 ,  424 ,  424 ,  424 ,  425 ,
           426 ,  427 ,  428 ,  429 ,  430 ,  431 ,
           432 ,  433 ,  434 ,  434 ,  434 ,  434 ,
           434 ,  434 ,  434 ,  434 ,  434 ,  434 ,
           435 ,  436 ,  437 ,  438 ,  439 ,  440 ,
           441 ,  442 ,  443 ,  444 ,  444 ,  444 ,
           444 ,  444 ,  444 ,  444 ,  444 ,  444 ,
           444 ,  445 ,  446 ,  447 ,  448 ,  449 ,
           450 ,  451 ,  452 ,  453 ,  454 ,  454 ,
           454 ,  454 ,  454 ,  454 ,  454 ,  454 ,
           454 ,  454 ,  455 ,  456 ,  457 ,  458 ,
           459 ,  460 ,  461 ,  462 ,  463 ,  464 ,
           464 ,  464 ,  464 ,  464 ,  464 ,  464 ,
           464 ,  464 ,  464 ,  465 ,  466 ,  467 ,
           468 ,  469 ,  470 ,  471 ,  472 ,  473 ,
           474 ,  474 ,  474 ,  474 ,  474 ,  474 ,
           474 ,  474 ,  474 ,  474 ,  475 ,  476 ,
           477 ,  478 ,  479 ,  480 ,  481 ,  482 ,
           483 ,  484 ,  484 ,  484 ,  484 ,  484 ,
           484 ,  484 ,  484 ,  484 ,  484 ,  485 ,
           486 ,  487 ,  488 ,  489 ,  490 ,  491 ,
           492 ,  493 ,  494 ,  494 ,  494 ,  494 ,
           494 ,  494 ,  494 ,  494 ,  494 ,  494 ,
           495 ,  496 ,  497 ,  498 ,  499 ,  500 ,
           501 ,  502 ,  503 ,  504 ,  504 ,  504 ,
           504 ,  504 ,  504 ,  504 ,  504 ,  504 ,
           504 ,  505 ,  506 ,  507 ,  508 ,  509 ,
           510 ,  511 ,  512 ,  513 ,  514 ,  514 ,
           514 ,  514 ,  514 ,  514 ,  514 ,  514 ,
           514 ,  514 ,  515 ,  516 ,  517 ,  518 ,
           519 ,  520 ,  521 ,  522 ,  523 ,  524 ,
           524 ,  524 ,  524 ,  524 ,  524 ,  524 ,
           524 ,  524 ,  524 ,  525 ,  525 ,  525 ,
           525 ,  526 ,  526 ,  526 ,  526 ,  527 ,
           527 ,  527 ,  527 ,  528 ,  528 ,  528 ,
           528 ,  528 ,  528 ,  528 ,  528
};

const char string_1[] PROGMEM = "R1=SCHEDA DI TARATURA";
const char string_2[] PROGMEM = "R1A=Generata il:";
const char string_3[] PROGMEM = "R1B=Ore:";
const char string_4[] PROGMEM = "R2=Parametri generali:";
const char string_5[] PROGMEM = "R3=Prodotto in uso           :";
const char string_6[] PROGMEM = "R4=Fotocellula               :";
const char string_7[] PROGMEM = "R5=Reset manuale             :";
const char string_8[] PROGMEM = "R6=Tempo di oscuramento      :";
const char string_9[] PROGMEM = "R7=Stop su errore            :";
const char string_10[] PROGMEM = "R8=Tempo stabilizzazione     :";
const char string_11[] PROGMEM = "R9=Timeout fotocellula       :";
const char string_12[] PROGMEM = "R10=Errore mancata espulsione :";
const char string_13[] PROGMEM = "R11=Tempo sincronismo contatti:";
const char string_14[] PROGMEM = "R12=Inserita";
const char string_15[] PROGMEM = "R13=Disinserita";
const char string_16[] PROGMEM = "R14=Inserito";
const char string_17[] PROGMEM = "R15=Disinserito";
const char string_18[] PROGMEM = "PP1=Parametri prodotto : ";
const char string_19[] PROGMEM = "PP2=Nome:";
const char string_20[] PROGMEM = "PP3=Programma N.        :";
const char string_21[] PROGMEM = "PP4=Sensibilità canale 1:";
const char string_22[] PROGMEM = "PP5=Sensibilità canale 2:";
const char string_23[] PROGMEM = "PP6=Velocità intercett. :";
const char string_24[] PROGMEM = "PP7=Cadenza massima     :";
const char string_25[] PROGMEM = "PP8=Ritardo espulsione  :";
const char string_26[] PROGMEM = "PP9=Durata espulsione   :";
const char string_27[] PROGMEM = "PP10=******* Termine scheda di taratura *******";
const char string_28[] PROGMEM = "DR1=REPORT DEL GIORNO: ";
const char string_29[] PROGMEM = "DR2=ORA        EVENTO";
const char string_30[] PROGMEM = "DR3=&******** Fine Monitoraggio **********";
const char string_31[] PROGMEM = "DR4=SEGNALAZIONE ERRORI";
const char string_32[] PROGMEM = "ERS=&Dispositivo spento-";
const char string_33[] PROGMEM = "ER0=Start monitor-";
const char string_34[] PROGMEM = "ER1=Errore di formato ";
const char string_35[] PROGMEM = "ER2=Entra in programmazione ";
const char string_36[] PROGMEM = "ER3=Canali rumorosi ";
const char string_37[] PROGMEM = "ER4=^Metalim ready ";
const char string_38[] PROGMEM = "ER5=Programmazione remota ";
const char string_39[] PROGMEM = "ER6=Selezionato prodotto N.";
const char string_40[] PROGMEM = "ER7=In aggiornamento";
const char string_41[] PROGMEM = "ER8=Lettura prodotto aggiornato N.";
const char string_42[] PROGMEM = "ER9=Generata nuova scheda di taratura ";
const char string_43[] PROGMEM = "ER10=Aggiornata la scheda di taratura";
const char string_44[] PROGMEM = "ER11=Test periodico ";
const char string_45[] PROGMEM = "ER12=Accesso da terminale- ";
const char string_46[] PROGMEM = "ER13=^Fine programmazione da terminale- ";
const char string_47[] PROGMEM = "ER13A=Uscito da terminale senza modifiche";
const char string_48[] PROGMEM = "ER14=!Allarmi N.:";
const char string_49[] PROGMEM = "ER15=Totale allarmi:";
const char* const string_table[] PROGMEM  = {string_1, string_2, string_3, string_4, string_5, string_6, string_7, string_8, string_9, string_10, string_11, string_12, string_13, string_14, string_15, string_16, string_17, string_18, string_19, string_20, string_21, string_22, string_23, string_24, string_25, string_26, string_27, string_28, string_29, string_30, string_31, string_32, string_33, string_34, string_35, string_36, string_37, string_38, string_39, string_40, string_41, string_42, string_43, string_44, string_45, string_46, string_47, string_48, string_49};

B4R::Object beo1;
B4R::Object* getdata(B4R::Object* o) {
   return beo1.wrapNumber(pgm_read_byte_near(data + o->toLong()));
 }
B4R::Object* getdata1(B4R::Object* o) {

    strcpy_P(strx, (char*)pgm_read_word(&(string_table[o->toLong()]))); // Necessary casts and dereferencing, just copy.
    b4r_statica::_stringa->data = strx;
    int n=0;
    do
      n++;
    while (strx[n]!=0) ;
    b4r_statica::_stringa->length = n;
    return 0;  
}
B4R::Object* findstring(B4R::Object* o) {
    long n=-1;
    B4R::Array* b =(B4R::Array*)B4R::Object::toPointer(o);
    char* testx = (char*)b->data;
    int lgt=(int)b->length;
    do
    {
      n++;
      if (n> 48)
        break;
      if (strncmp_P(testx, (char*)pgm_read_word(&(string_table[n])),lgt)==0) break;
     }  
    while(1);
    strcpy_P(strx, (char*)pgm_read_word(&(string_table[n])));
    b4r_statica::_stringa->data = strx;
    b4r_statica::_stringa->length = strlen(strx);
    return 0;  
}

#end if
 
Last edited:

tigrot

Well-Known Member
Licensed User
Longtime User
I wrote a simple VBnet program reading a table written in a txt file.
I had an old program containing this table so I extracted this conversion table. I use to print description on a log using only a key value(the key is left of equal sign like PP8=). This is the complete table I used as a source, but I extracted a small part:
B4X:
[report]
R1=SCHEDA DI TARATURA
R1A=Generata il:
R1B=Ore:
R2=Parametri generali:
R3=Prodotto in uso           :
R4=Fotocellula               :
R5=Reset manuale             :
R6=Tempo di oscuramento      :
R7=Stop su errore            :
R8=Tempo stabilizzazione     :
R9=Timeout fotocellula       :
R10=Errore mancata espulsione :
R11=Tempo sincronismo contatti:
R12=Inserita
R13=Disinserita
R14=Inserito
R15=Disinserito
PP1=Parametri prodotto :
PP2=Nome:
PP3=Programma N.        :
PP4=Sensibilità canale 1:
PP5=Sensibilità canale 2:
PP6=Velocità intercett. :
PP7=Cadenza massima     :
PP8=Ritardo espulsione  :
PP9=Durata espulsione   :
PP10=******* Termine scheda di taratura *******
DR1=REPORT DEL GIORNO:
DR2=ORA        EVENTO
DR3=&******** Fine Monitoraggio **********
DR4=SEGNALAZIONE ERRORI
ERS=&Dispositivo spento-
ER0=Start monitor-
ER1=Errore di formato
ER2=Entra in programmazione
ER3=Canali rumorosi
ER4=^Metalim ready
ER5=Programmazione remota
ER6=Selezionato prodotto N.
ER7=In aggiornamento
ER8=Lettura prodotto aggiornato N.
ER9=Generata nuova scheda di taratura
ER10=Aggiornata la scheda di taratura
ER11=Test periodico
ER12=Accesso da terminale-
ER13=^Fine programmazione da terminale-
ER13A=Uscito da terminale senza modifiche
ER14=!Allarmi N.:
ER15=Totale allarmi:
[mdiform1]
newdetect=Aggiunge un detector
update=Varia parametri porta
language= Cambia lingua
mode= Modo di lavoro
minimizza= Minimizza in tray
sempre= Minimizza all'avvio
[form3]
Command1=Aggiorna scheda
Command2=Proprietà
Label1(0)=Nome prodotto :
Label1(1)=Programma :
Label1(2)=Sensibilità 1 :
Label1(3)=Sensibilità 2 :
Label1(4)=Vel. Intercettazione :
Label1(5)=Allarmi avvenuti :
Label1(6)=Prodotto N. :
[form4]
Command1=Scrivi
Command2=Annulla
Command3=Applica
Command4=Ripristina
Command5=Abbandona
Command1.tooltiptext=Scrivi le modifiche su metal detector
Command2.tooltiptext=Annulla di questa pagina
Command3.tooltiptext=Accetta le variazioni visualizzate
Command4.tooltiptext=Annulla tutte le variazioni
Command5.tooltiptext=Esce senza variazioni
Label16=Filtraggio
Label15=Espulsione su fotocellula
Label14=Tempo di sincronismo contatti(10ms)
Label13=Debouncer di allarme
Label12=Altri parametri
Label11=Timeout fotocellula
Label10=Errore mancata espulsione
Label9=Stop su errore
Label8=Tempo di stabilizzazione
Label7=Gestione errori
Label6=Echo On/Off
Label5=Reset Manuale
Label4=Prodotto in uso
Label3=Impostazioni
Label1=Password supervisore
Label2=Password utente
Label28=Tempo R1
Label24=Cadenza massima
Label23=Durata espulsione
Label22=Ritardo di attivazione
Label21=Espulsione
Label20=Velocità di intercettazione (ms*10)
Label19=Sensibilità canale 2
Label18=Rilevazione
Label17=Programma di lavoro
Label25=Sensibilità canale 1
Label26=Nome prodotto
Tabstrip1.tabs(1)=Parametri Generali
Tabstrip1.tabs(2)=Parametri Prodotto
Tabstrip1.tabs(3)=Sicurezza
[form5]
caption1=Aggiungi detector
caption2=Modifica detector
label1=Nome Detector
label2=Porta COM
Command1=Cancella
Command3=Applica
Command4=Annulla
F1=Confermi cancellazione del metal detector? Il programma si riavvierà
F2=Impossibile cancellare - un solo detector collegato
[form6]
D0=Password supervisore?
[form8]
Caption=Modifica lingua
Command1=Carica
Command2=Annulla
label1=Pacchetti disponibili:
This is only an example how to keep simple writing long descriptions instead of long litteral from RAM.
These functions are stack memory hungry. I you loop, create a sub to handle each loop of function to allow a stack clear.
 
Top