Чудеса при в цикле чтении EEPROM

gooroong
gooroong аватар
Offline
Зарегистрирован: 08.03.2015

Здравствуйте, у меня на MEGA 2560 происходит следующее: программа достаточно большая, но проблема возникает в куске, который читает кусок памяти EEPROM. Ниже приведу кусок программы и "ответ" из терминала. Помогите понять, как такое происходит.

стоит обратить внимание, что непонятно как получается такой результат (обратите, как он выводит переменную addr, которая изменяется по схемее addr+=4; она внезапоно становится равной 67 и перестает изменяться

    byte addr=31;
    if (TestMode) Serial.print(" VClock ");
    for (j=0;j<Valves;j++) {
      ValveClock[j]=EEPROM_float_read(addr);
      addr=addr+4;
      if (TestMode) {
        Serial.print(addr);
        Serial.print("/");
        Serial.print(j);
        Serial.print(" ");
        Serial.print(ValveClock[j]);
        Serial.print("  ");
      }
    }


VClock 35/0 0.75  67/1 0.00  67/2 0.00  67/3 0.00

Функция взята с форума, честно, не особо понимаю вот это "float *y = (float *)&x;", но на форуме сказали, что работает :-)

float EEPROM_float_read(int addr) {    
  byte j;
  byte x[4];
  for(j=0;j<4;j++) x[j] = EEPROM.read(j+addr);
  float *y = (float *)&x;
  return y[0];
}

Когда я взял и закомментил все процедуры, то программа стала работать корректно, затем, я постепенно раскомментировал все процедуры и проблема ушла ровно до первой перезагрузки.

Я недоумеваю!

gooroong
gooroong аватар
Offline
Зарегистрирован: 08.03.2015

ЕПРСТ, что с названием то!!! :-) Если админ сможет со старварского на русский переставить, то ему большое спасибо!

maksim
Offline
Зарегистрирован: 12.02.2012

Ну а что вам мешало проверить, что дело не в этом куске кода???

#include <EEPROM.h>

void setup() 
{ 
  Serial.begin(9600);
  byte Valves = 20;
  float ValveClock[Valves];

  byte addr = 31;
  Serial.print(" VClock ");
  for (byte j = 0; j < Valves; j++) {
    ValveClock[j] = EEPROM_float_read(addr);
    addr += 4;

    Serial.print(addr);
    Serial.print("/");
    Serial.print(j);
    Serial.print(" ");
    Serial.print(ValveClock[j]);
    Serial.print("  ");
  }
}

float EEPROM_float_read(int addr) {    
  byte j;
  byte x[4];
  for(j=0;j<4;j++) x[j] = EEPROM.read(j+addr);
  float *y = (float *)&x;
  return y[0];
}

void loop(){}
... 59/6 0.00  63/7 0.00  67/8 0.00  71/9 0.00  75/10 0.00  79/11 0.00  ....

Скорее всего вы где выходите за пределы масиива или не хватает памяти.

Можете еще так попробовать Запись и чтение EEPROM переменных типа float, unsigned long, long, unsigned int, int.

gooroong
gooroong аватар
Offline
Зарегистрирован: 08.03.2015

м.б. я что то не понимаю, но почему 

addr+=4;

внезапно перестает работать

кстати, я понимаю, что код рабочий, так как я запускал его отдельно.

 

maksim
Offline
Зарегистрирован: 12.02.2012

maksim пишет:

Скорее всего вы где выходите за пределы масиива или не хватает памяти.

gooroong
gooroong аватар
Offline
Зарегистрирован: 08.03.2015

то есть, если при выполнении программы используется много памяти, она начинает "дурить" в переменных

с массивами, все должно быть корректно, так как я проверял процедуру отдельно, а запуск этой процедуры происходит в цикле setup почти в самом начале (сразу после того, как программа устанровит текущее время)

компилятор не ругается на память

Sketch uses 26 648 bytes (10%) of program storage space. Maximum is 253 952 bytes.
Global variables use 4 290 bytes (52%) of dynamic memory, leaving 3 902 bytes for local variables. Maximum is 8 192 bytes.

 

gooroong
gooroong аватар
Offline
Зарегистрирован: 08.03.2015

Я прочесал алгоритм. Он олностью работает без двух процедур, сохраняющих и ичитающих данных из EEPROM, причем отдельно код этих двух процедур работает...

Я грешу на переполнение памяти. Есть ли какие либо средства проверки памяти?

akimov_aleks
Offline
Зарегистрирован: 04.04.2013

попробуй так или так но почемутип выбрал byte?

 byte addr=byte(31);
    if (TestMode) Serial.print(" VClock ");
    for (j=0;j<Valves;j++) {
      ValveClock[j]=EEPROM_float_read(addr);

      addr=addr+byte(4);
      if (TestMode) {
        Serial.print(addr);
        Serial.print("/");
        Serial.print(j);
        Serial.print(" ");
        Serial.print(ValveClock[j]);
        Serial.print("  ");
      }
    }

или

 byte addr=byte(31);

 byte addrz=byte(4);
    if (TestMode) Serial.print(" VClock ");
    for (j=0;j<Valves;j++) {
      ValveClock[j]=EEPROM_float_read(addr);

      addr=addr+addrz;
      if (TestMode) {
        Serial.print(addr);
        Serial.print("/");
        Serial.print(j);
        Serial.print(" ");
        Serial.print(ValveClock[j]);
        Serial.print("  ");
      }
    }

 

gooroong
gooroong аватар
Offline
Зарегистрирован: 08.03.2015

akimov_aleks пишет:

попробуй так или так но почемутип выбрал byte?

Конечно тип in это меня глюк нуля, когда я сюда код переписывал в программе всегда int т.к. он доходит до 1500

Но вот непонятно, как я озвучил выше, почему по отдельности все работает, а вместе - нет :-(