Проблема с PROGMEM массивом

nosipaxuw
Offline
Зарегистрирован: 24.02.2015

Добрый день.

Есть 2 массива, один в PROGMEM, другой нет.







const static PROGMEM int aa[][8] =
{
  {2, 30, 0}, 		//
  {4, 30, 30}, 		// !
  {9, 30, 60}, 		// "
  {23, 30, 120}, 		// #
  {17, 30, 210}, 		// $
  {22, 30, 300}, 		// %
  {18, 30, 390}, 		// &
  {3, 30, 480}, 		// '
};

int bb[][8] =
{
  {2, 30, 0}, 		//
  {4, 30, 30}, 		// !
  {9, 30, 60}, 		// "
  {23, 30, 120}, 		// #
  {17, 30, 210}, 		// $
  {22, 30, 300}, 		// %
  {18, 30, 390}, 		// &
  {3, 30, 480}, 		// '
};

Мне нужно через функцию прочитать значение:





void readVal(String str0)
{
  int b = str0[0] - 32;
  Serial.println(aa[b][0]);
  Serial.println(bb[b][0]);
}

Получается такая лабуда:





8481
23

А вот если переменной b задать значение (например 3), то всё работает



void readVal(String str0)
{
  int b = 3;
  Serial.println(aa[b][0]);
  Serial.println(bb[b][0]);
}


23
23

Помогите решить проблему, уже весь интернет облазил.

Logik
Offline
Зарегистрирован: 05.08.2014

pgm_read_byte

nevkon
Offline
Зарегистрирован: 20.01.2015

Почему бы не заменить String на char? При передаче выполняете Переменная.toCharArray()

nosipaxuw
Offline
Зарегистрирован: 24.02.2015

Logik пишет:

pgm_read_byte

Но разве у байта максимальное значение не 255? Ну допустим...







void readVal(String str0)
{
  int b = str0[0] - 32;
  Serial.println(pgm_read_byte(aa[b][0]));
  Serial.println(pgm_read_byte(bb[b][0]));
}






0
0

Теперь просто нули.

 

nevkon пишет:

Почему бы не заменить String на char? При передаче выполняете Переменная.toCharArray()

Вот так что ли?



void readVal(char* str0)
{
  int b = str0[0] - 32;
  Serial.println(aa[b][0]);
  Serial.println(bb[b][0]);
}

void setup() {
  Serial.begin(115200);
  
  String s = "#$";
  char a[s.length()];
  s.toCharArray(a, s.length());
  readVal(a);
}


8481
23

Не работает

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013
nosipaxuw
Offline
Зарегистрирован: 24.02.2015

Я уже читал это. Ничего не нашёл.

nevkon
Offline
Зарегистрирован: 20.01.2015

Можно еще так попробовать:

void readVal(byte str0)
{
  int b = str0 - 32;
  Serial.println(aa[b][0]);
  Serial.println(bb[b][0]);
}

void setup() {
  Serial.begin(115200);
  
  String s = "#$";
  byte a[s.length()+1];
  s.getBytes(a, s.length()+1);
  readVal(a[0]);
}

 

nosipaxuw
Offline
Зарегистрирован: 24.02.2015

nevkon пишет:

Можно еще так попробовать:



void readVal(byte str0)
{
  int b = str0 - 32;
  Serial.println(aa[b][0]);
  Serial.println(bb[b][0]);
}

void setup() {
  Serial.begin(115200);
  
  String s = "#$";
  byte a[s.length()+1];
  s.getBytes(a, s.length()+1);
  readVal(a[0]);
}

 

Это ничего не даст, мне нужна строка(ну или массив символов), а тут просто 1 символ

nevkon
Offline
Зарегистрирован: 20.01.2015

Так и перебирайте их при вызове процедуры/функции.

for (int i=0; i <= s.length(); i++){
      readVal(a[i]);
   }

И добавьте вывод в сериал чтобы посмотреть что у вас берется:

Serial.println(a[0]);
Serial.println(a[1]);
Serial.println(a[2]);

 

nosipaxuw
Offline
Зарегистрирован: 24.02.2015

nevkon пишет:

Так и перебирайте их при вызове процедуры/функции.



for (int i=0; i <= s.length(); i++){
      readVal(a[i]);
   }

И добавьте вывод в сериал чтобы посмотреть что у вас берется:



Serial.println(a[0]);
Serial.println(a[1]);
Serial.println(a[2]);

 

Конкретно мне нельзя вызывать функцию несколько раз(это функция вывода строки на печать), а посимвольно работать не будет.

Logik
Offline
Зарегистрирован: 05.08.2014

nosipaxuw пишет:

Но разве у байта максимальное значение не 255? Ну допустим...

... тогда

pgm_read_word

суть одна.



  Serial.println(pgm_read_byte(aa[b][0]));


Найдитн в Вашей строке ошибку, теория по уже данной сылке или здесь на понятном языке http://microsin.net/programming/AVR/avrstudio-gcc-progmem.html

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

pgm_read_word(&aa[b][0])

nosipaxuw
Offline
Зарегистрирован: 24.02.2015

Penni пишет:

pgm_read_word(&aa[b][0])

Огромное спасибо! Всё работает. А что означает символ '&'?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Получаем адрес в памяти. Так то по той ссылке что давал Logik всё расписано в том числе и про &

nosipaxuw
Offline
Зарегистрирован: 24.02.2015

Penni пишет:

Получаем адрес в памяти. Так то по той ссылке что давал Logik всё расписано в том числе и про &

Спасибо, почитаю.

slider
Offline
Зарегистрирован: 17.06.2014

Penni пишет:

pgm_read_word(&aa[b][0])

большое спасибо ! помогло !  пол дня парился почему значения не переносит

а то издвумерного массива шрифтов объявленных в PROGMEM  не копировалось в обычный двумерный массив , именно в цикле копировалась всякая лабуда, только вручную поэлементно копируется.

в цикле применил pgm_read_byte и все заработало , проблема  PROGMEM решена

mass[i][j]=pgm_read_byte ( &lcd_font[i][j] )

b707
Offline
Зарегистрирован: 26.05.2017

slider пишет:

а то издвумерного массива шрифтов объявленных в PROGMEM  не копировалось в обычный двумерный массив ,

Сдается мне, вы какой-то "каменный цветок" рожаете. Зачем сохранять массив во флеше, если во время исполнения вы его все равно копируете в оперативку - это же бред, вы так место занимаете дважды... Почему не использовать значения сразу из ПРОГМЕМ ?

slider
Offline
Зарегистрирован: 17.06.2014

оперативка  нужна как видеоОЗУ в которой будет постоянно что-то меняться, что-то копироваться по мере нужды из прогмем.

////эээ,.... не все так просто...

1. массив в ОЗУ используется как видеопамять много пиксельного простейшего LCD дисплея не имеющего свою. сканирование массива нужно на предельной скорости и постоянно. в программе проще писать в видеоОЗУ , чем хранить море ссылок на прогмем откуда и что выдергивать, да и долго это.

2. копирование на самом деле идет не  1 в 1 , даже в не нужном случае посмотреть все шрифты  на экране . ибо размерности массивов совершенно разные. и еще предстоит  делать побитовые операции чтоб перевернуть шрифты перед закидыванием в ОЗУ.