EEPROM запись/чтение

madsun
madsun аватар
Offline
Зарегистрирован: 01.03.2017

проблемы с чтением EEEPROM, может и с записью

В общем :

Скетч использует 27126 байт (88%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 996 байт (48%) динамической памяти, оставляя 1052 байт для локальных переменных. Максимум: 2048 байт

мало места ...

Ужимался где мог, в итоге EEPROM стал лажать почему-то.

Вот что получается при чтении данных (при загрузке контроллера)

time off       [0][-] 0
time on       [1][-] 0
time dt       [2][-] 0
H`% off       [3][-] 0
H`% on       [4][-] 44
H`% D       [5][-] 5
t`C on       [6][-] 28
t`C off       [7][-] 22

 

Прикладываю исходник, проблема в void options_get(), void options_put().

#include <U8glib.h>
#include <IRremote.h>
#include <DHT.h>
#include <EEPROM.h>
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);  // I2C / TWI 
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST); // Fast I2C / TWI 
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);  // Display which does not send AC
IRrecv irrecv(2);
decode_results ir_results;
DHT dht(5,DHT11);

byte xs_dialog=0;

#define xs_sTxt 8
char vs[xs_sTxt];
boolean xs_debug;
char xs_inputText[xs_sTxt]={};
char xs_inputCurrent;
byte xs_inputOperation;
byte xs_inputIndex;
byte xs_inputCarret;
boolean xs_inputChanged=false;

byte st_mode;//0[#]-default 1[*]-options 2[0]-debug 255-sleeping
#define xs_c 8
const char* xs_name[xs_c]={"time off","time on","time dt","H`% off","H`% on","H`% D","t`C on","t`C off"};
unsigned int xs_value[xs_c]={};
boolean xs_enable[xs_c]={};
boolean xs_control[5]={};
unsigned long xs_time[3]={};
int xs_selectedItem=0;
int xs_firstView=0;
int xs_count=xs_c-1;
const int xs_countView=4;
int i,ii,fh,iy;
byte ve=0;

#define xs_pinBuzz 4
boolean xs_buzz=false;
#define xs_pinRelay 3
boolean xs_relayOut=false;
boolean xs_relayCtr=true;
boolean xs_relayMan=false;

void draw(float t, float h) {
  u8g.setColorIndex(1);
  if(st_mode==0){ //default
    if(xs_inputChanged){options_put();xs_inputChanged=false;}
    u8g.setFont(u8g_font_fur49n);
    u8g.setFontPosTop();
    dtostrf(t,2,0,vs);
    u8g.drawStr(4,6,vs);
    u8g.drawFrame(90,0,38,64);
    fh=map(h,0,100,0,62);
    u8g.drawBox(92,62-fh,34,fh);
    u8g.setFont(u8g_font_profont29r);
    u8g.setFontPosTop();
    dtostrf(h,2,0,vs);
    if(h>52){
        u8g.setColorIndex(0);
        u8g.drawStr(94,36,vs);
      }else{
        u8g.drawStr(94,0,vs);
      }
  }else if(st_mode==1){ //options
    if(xs_selectedItem>xs_count){xs_selectedItem=0;xs_firstView=0;}
    if(xs_selectedItem<0){xs_selectedItem=xs_count;xs_firstView=xs_count-4;}
    if(xs_selectedItem>=(xs_firstView+xs_countView)){xs_firstView++;}
    if(xs_selectedItem<xs_firstView){xs_firstView--;}
    fh=u8g.getHeight()/xs_countView;
    ii=xs_firstView;
    for(i=0;i<=xs_countView-1;i++){
      if(ii>xs_count){ii=0;}
      iy=i*(fh+1);
      if(ii==xs_selectedItem){u8g.drawBox(0,iy,2,fh);}
      u8g.setFont(u8g_font_profont15r);
      u8g.setFontPosTop();
      u8g.drawStr(3,iy,xs_name[ii]);
      dtostrf(xs_value[ii],4,0,vs);
      u8g.drawStr(70,iy,vs);
      u8g.drawFrame(110,iy+1,fh-4,fh-4);
      if(xs_enable[ii]){u8g.drawBox(114,iy+5,fh-12,fh-12);}
      ii++;
    }
  }else if(st_mode==2){ //edit
    u8g.setFont(u8g_font_profont15r);
    u8g.setFontPosTop();
    u8g.drawStr(12,4,xs_name[xs_inputIndex]);
    u8g.drawHLine(4,22,80);
    dtostrf(xs_value[xs_inputIndex],8,0,vs);
    u8g.drawStr(1,28,"OLD:");
    u8g.drawStr(18,28,vs);
    u8g.drawStr(1,48,"NEW:");
    u8g.drawStr(48,48,xs_inputText);
    if((xs_inputOperation==0)&&(xs_inputCurrent!='\0')&&(xs_inputCarret<xs_sTxt)){
      xs_inputText[xs_inputCarret]=xs_inputCurrent;
      xs_inputCarret++;
      xs_inputCurrent='\0';
      xs_inputOperation=0;
    }//input0..9
    else if(xs_inputOperation==3){
      xs_inputCarret--;
      xs_inputText[xs_inputCarret]='\0';
      xs_inputOperation=0;
    }//backspace
    else if(xs_inputOperation==2||xs_inputOperation==1){
      if(xs_inputOperation==1){xs_value[xs_inputIndex]=atoi(xs_inputText);}
      input_reset();
      st_mode=1;
    }//cancel/save
    if(xs_inputCarret<0){xs_inputCarret=0;}
  }else if(st_mode==255){ //sleeping on/off
  }else{st_mode=0;} //reset
}

void input_reset(){
  xs_inputOperation=0;
  xs_inputIndex=0;
  xs_inputCarret=0;
  memset(&xs_inputCurrent,0,1);
  memset(&xs_inputText,0,xs_sTxt);
}

void options_put(){
  for(i=0;i<=xs_count;i++){EEPROM.put(i*2,xs_value[i]);}
  ve=0;
  for(ii=0;ii<=8;ii++){bitWrite(ve,ii,xs_enable[ii]);}
  EEPROM.write((i+2)*2,ve);
}
void options_get(){
  for(i=0;i<=xs_count;i++){EEPROM.get(i*2,xs_value[i]);}
  ve=EEPROM.read((i+2)*2);
  for(ii=0;ii<=8;ii++){xs_enable[ii]=bitRead(ve,ii);}
}

void menu_update(){
  if(ir_results.value==0x511DBB || ir_results.value==0xFF629D  ){xs_selectedItem--;xs_buzz=true;}//#up
  if(ir_results.value==0xFFA857 || ir_results.value==0xA3C8EDDB){xs_selectedItem++;xs_buzz=true;}//#down
  if(ir_results.value==0xFF02FD || ir_results.value==0xD7E84B1B){st_mode=2;xs_inputIndex=xs_selectedItem;xs_inputChanged=true;xs_buzz=true;}//#ok"edit"
  if(ir_results.value==0xFFC23D || ir_results.value==0x20FE4DBB){xs_enable[xs_selectedItem]=!xs_enable[xs_selectedItem];xs_inputChanged=true;xs_buzz=true;}//#right "use it"
  if(ir_results.value==0xFF52AD || ir_results.value==0x3EC3FC1B){st_mode=0;xs_buzz=true;}//##"default"
}
void input_update(){
  if(ir_results.value==0xFF4AB5 || ir_results.value==0x1BC0157B){xs_inputCurrent='0';}//#0
  else if(ir_results.value==0xFF6897 || ir_results.value==0xC101E57B){xs_inputCurrent='1';}//#1
  else if(ir_results.value==0xFF9867 || ir_results.value==0x97483BFB){xs_inputCurrent='2';}//#2
  else if(ir_results.value==0xFFB04F || ir_results.value==0xF0C41643){xs_inputCurrent='3';}//#3
  else if(ir_results.value==0xFF30CF || ir_results.value==0x9716BE3F){xs_inputCurrent='4';}//#4
  else if(ir_results.value==0xFF18E7 || ir_results.value==0x3D9AE3F7){xs_inputCurrent='5';}//#5
  else if(ir_results.value==0xFF7A85 || ir_results.value==0x6182021B){xs_inputCurrent='6';}//#6
  else if(ir_results.value==0xFF10EF || ir_results.value==0x8C22657B){xs_inputCurrent='7';}//#7
  else if(ir_results.value==0xFF38C7 || ir_results.value==0x488F3CBB){xs_inputCurrent='8';}//#8
  else if(ir_results.value==0xFF5AA5 || ir_results.value==0x449E79F){xs_inputCurrent='9';}//#9
  else{xs_inputCurrent='\0';}
  if(ir_results.value==0xFF02FD || ir_results.value==0xD7E84B1B){xs_inputOperation=1;xs_buzz=true;}//#ok
  else if(ir_results.value==0xFF52AD || ir_results.value==0x3EC3FC1B){xs_inputOperation=2;xs_buzz=true;}//##"cancel"
  else if(ir_results.value==0xFF22DD || ir_results.value==0x52A3D41F){xs_inputOperation=3;}//#left"backspace"
  else{xs_inputOperation=0;}
}
void state_update(){
  if(ir_results.value==0xFF42BD || ir_results.value==0x32C6FDF7){st_mode=1;}//*"options"
  else if(ir_results.value==0xFF52AD || ir_results.value==0x3EC3FC1B){xs_debug=!xs_debug;}//##"debug"
  else if(ir_results.value==0xFF4AB5 || ir_results.value==0x1BC0157B){xs_relayMan=!xs_relayMan;xs_relayCtr=true;}//#0"close relay"
}
void dialog_update(){
  if(Serial.available()>0){
    xs_dialog=Serial.read();
    if(xs_dialog==49){
      Serial.println("Dialog 1");
      for(i=0;i<=xs_count;i++){
        Serial.print(xs_name[i]);
        Serial.print("   \t[");
        Serial.print(i,DEC);
        Serial.print(xs_enable[i]?"][+] ":"][-] ");
        Serial.println(xs_value[i],DEC);
      }
      xs_dialog=0;
    }
  }
}
void relay_control(int h,int t){
  if(xs_enable[0]&&xs_enable[1]){
    if((((millis()-xs_time[0])/1000)>xs_value[0])&&(!xs_control[0])){
      xs_relayCtr=true;
      xs_control[0]=true;
      xs_time[0]=millis();
      if(xs_debug){
        Serial.print("time on: ");
        Serial.println(millis()-xs_time[0],DEC);
      }
    }else if((((millis()-xs_time[0])/1000)>xs_value[1])&&(xs_control[0])){
      xs_relayCtr=true;
      xs_control[0]=false;
      xs_time[0]=millis();
      if(xs_debug){
        Serial.print("time off: ");
        Serial.println(millis()-xs_time[0],DEC);
      }
    }
  }else{xs_control[0]=false;}//time on/off
  if(xs_enable[3]&&xs_enable[4]){
    if(xs_control[1]&&(h<xs_value[3])){//H% off
      xs_relayCtr=true;
      xs_control[1]=false;
      xs_control[2]=true;
      Serial.println("control-4On");
      xs_time[1]=millis();
    }else if(!xs_control[1]&&(h>xs_value[4])){//H% on
      xs_relayCtr=true;
      xs_control[1]=true;
      Serial.println("control-3On");
    }
    if(xs_control[2]&&xs_enable[2]){
      if(((millis()-xs_time[1])/1000)>xs_value[2]){
        xs_relayCtr=true;xs_control[2]=false;
        Serial.println("control-4Off");}
    }
  }else{xs_control[1]=xs_control[2]=false;}//H`% on/off"
  if(xs_enable[6]&&xs_enable[7]){
    if(xs_control[3]&&(t>xs_value[6])){//t`C off
      xs_relayCtr=true;
      xs_control[3]=false;
      xs_control[4]=true;
      Serial.println("control-7On");
      xs_time[2]=millis();
    }else if(!xs_control[3]&&(t<xs_value[7])){//H% on
      xs_relayCtr=true;
      xs_control[3]=true;
      Serial.println("control-6On");
    }
    if(xs_control[4]&&xs_enable[2]){
      if(((millis()-xs_time[2])/1000)>xs_value[2]){
        xs_relayCtr=true;xs_control[4]=false;
        Serial.println("control-7Off");}
    }
  }else{xs_control[3]=xs_control[4]=false;}//"t`C on/off
  xs_relayOut=xs_control[0]||xs_control[1]||xs_control[3]||xs_relayMan;
  if(xs_relayCtr){
    if(xs_relayOut){
      digitalWrite(xs_pinRelay,HIGH);
      Serial.println("relay open");
    }else{
      digitalWrite(xs_pinRelay,LOW);
      Serial.println("relay close");
    }
    xs_relayCtr=false;
  }
}

void time_update(){
  for(i=0;i<xs_c;i++){xs_time[i]=0;xs_control[i]=false;}
}

void setup() {
  pinMode(xs_pinBuzz,OUTPUT);
  pinMode(xs_pinRelay,OUTPUT);
  irrecv.enableIRIn();
  Serial.begin(9600);
  dht.begin();
  xs_count=xs_c-1;
  options_get();
  input_reset();
  time_update();
}

void loop() {
  float dht11_h=dht.readHumidity();
  float dht11_t=dht.readTemperature();
  relay_control(dht11_h,dht11_t);//control relay output
  dialog_update();
  if(irrecv.decode(&ir_results)){//pult
    if(st_mode==1){menu_update();}
    else if(st_mode==2){input_update();}
    else{state_update();}
    irrecv.resume();
  }
  u8g.firstPage();do{draw(dht11_t,dht11_h);}while(u8g.nextPage());
  if(xs_buzz){tone(xs_pinBuzz,900);}
  delay(50);
  if(xs_buzz){noTone(xs_pinBuzz);xs_buzz=false;}
}

 

madsun
madsun аватар
Offline
Зарегистрирован: 01.03.2017

можно как то ужать u8glib. Пробовал удалять неиспользуемые шрифты, не помогло ?

andriano
andriano аватар
Онлайн
Зарегистрирован: 20.06.2015

На всякий случай: по дэйташиту при записи данных в EEPROM на границе страниц необходимо выдержать паузу 5 мс.

madsun
madsun аватар
Offline
Зарегистрирован: 01.03.2017

может мне 5мс писать одно и то же в одно и то же место EEPROM , а вдруг запишется, либо писать 10 раз с задержкой в 50

madsun
madsun аватар
Offline
Зарегистрирован: 01.03.2017

На каком программаторе прошиваете arduino nano atm328 (AliExpress) и на каком лучше?

Пробовал на AVR (медленно), на Arduino побыстрей.

valera678
Offline
Зарегистрирован: 04.11.2016

madsun пишет:

На каком программаторе прошиваете arduino nano atm328 (AliExpress) и на каком лучше?

Пробовал на AVR (медленно), на Arduino побыстрей.

))))))

на швейной машинке побыстрей

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

madsun пишет:

Вот что получается при чтении данных (при загрузке контроллера)

time off       [0][-] 0
time on       [1][-] 0
time dt       [2][-] 0
H`% off       [3][-] 0
H`% on       [4][-] 44
H`% D       [5][-] 5
t`C on       [6][-] 28
t`C off       [7][-] 22

Непонятно 1) где это получается (где Вы это выводите), а также непонятно, 2) что должно получаться.

madsun пишет:

проблема в void options_get(), void options_put().

Если Вы так считаете, то сделайте следующее (совет общий и пригодится всегда, а не только в этой ситуации):

1) поставьте печать в функции сохранения EEPROM

2) поставьте печать в функции чтения из EEPROM

Вы увидите что сохраняете и что что читаете. И сразу станет понятно где проблема - в сохранении/чтении или ещё где. Так Вы за несколько шагов локализуете проблему.

Сделайте это и, если сразу не поймёте в чём беда, то выкладывайте скетч с печатаями и результат печатей - будем смотреть.

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

madsun пишет:

Пробовал на AVR (медленно), на Arduino побыстрей.


Открою страшную тайну - Ардуино это и есть AVR. Самый распространённый недорогой программатор - USBasp, тоже на AVR.

madsun
madsun аватар
Offline
Зарегистрирован: 01.03.2017

ЕвгенийП пишет:

Непонятно 1) где это получается (где Вы это выводите), а также непонятно, 2) что должно получаться.

то что вы видите это и есть после чтения из EEPROM.

ЕвгенийП пишет:

1) поставьте печать в функции сохранения EEPROM

2) поставьте печать в функции чтения из EEPROM

делал и то и другое, отличие заключается в том что нулей не должно быть, а минусы в скобках это массив boolean, который тоже не должен быть пустым

madsun
madsun аватар
Offline
Зарегистрирован: 01.03.2017

Jeka_M пишет:

Открою страшную тайну - Ардуино это и есть AVR. Самый распространённый недорогой программатор - USBasp, тоже на AVR.

Ну к сожалению при переполнении отметки 90% памяти дисплей страшно глючит визуально - полосы искажения (библиотека u8glib), я подумал это из-за программатора, тк 90% это не 99%

madsun
madsun аватар
Offline
Зарегистрирован: 01.03.2017

madsun пишет:

На каком программаторе прошиваете arduino nano atm328 (AliExpress) и на каком лучше?

Пробовал на AVR (медленно), на Arduino побыстрей.

я имел ввиду программтор в ide arduino редакторе , разница то есть наверно какя-то, незря их там столько ?!

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

madsun пишет:

я подумал это из-за программатора, тк 90% это не 99%

Неправильно подумал, это не из-за программатора. Программатор никаким боком не влияет на программу. Он всего лишь загружает эту программу в память микроконтроллера. 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

madsun пишет:

я имел ввиду программтор в ide arduino редакторе , разница то есть наверно какя-то, незря их там столько ?!

Нет никакой разницы, каким программатором загружать программу в микроконтроллер. 

Более того, Вы точно прошиваете программатором? (что-то у меня есть сомнения...) Или просто подключаете Arduino NANO в USB-порт компьютера? Тогда выбирать программатор в Arduino IDE вообще бессмысленно, т.к. эта настройка работает только тогда, когда Ардуина прошивается с помощью настоящего "железного" программатора.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

madsun пишет:

то что вы видите это и есть после чтения из EEPROM.

Я не вижу где это печатается.

madsun пишет:

делал и то и другое, отличие заключается в том что нулей не должно быть, а минусы в скобках это массив boolean, который тоже не должен быть пустым

Я не знаю о чём Вы говорите. Дайте пожалуйста код с операторами печати о которых я говорид и текст, который он печатает. Без этого Вам помочь крайне трудно.

Если по каким-то причинам не хотите - дело Ваше.

 

madsun
madsun аватар
Offline
Зарегистрирован: 01.03.2017

ЕвгенийП пишет:

madsun пишет:

то что вы видите это и есть после чтения из EEPROM.

Я не вижу где это печатается.

madsun пишет:

делал и то и другое, отличие заключается в том что нулей не должно быть, а минусы в скобках это массив boolean, который тоже не должен быть пустым

Я не знаю о чём Вы говорите. Дайте пожалуйста код с операторами печати о которых я говорид и текст, который он печатает. Без этого Вам помочь крайне трудно.

Если по каким-то причинам не хотите - дело Ваше.

 

так обойдусь...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Удачи!

bwn
Offline
Зарегистрирован: 25.08.2014

Del