запись и чтение eeprom что делаю неправильно

ty
Offline
Зарегистрирован: 15.06.2015

если использую для работы с eeprom read / write  все работает но не могу запомнить десятые доли градуса так (все в соответсвии с описанием библиотеки)

если заменяю на put / get компилятор выдает ошибку "no matching function for call to 'EEPROMClass::get(int)' " хотя как я понял из описания библиотеки 

переменная описана как:

float tempON; 

с write/read все работает (что после запятой конечно обрезается) 

// термостат, один датчик DS18B20
//
//  v 0.2 beta

#include <EEPROM.h>
#include <OneWire.h>
#include <LiquidCrystal.h>
#define OUT1 3 // выход для реле 

#include <OLED_I2C.h>

OLED  myOLED(SDA, SCL, 8);

extern uint8_t SmallFont[];
extern uint8_t BigNumbers[];

float tempON;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
OneWire  ds(15); // 15 вход датчика 18b20

// ГРАФИЧАСКИЕ СИМВОЛЫ ДЛЯ ЭКРАНА

byte gradus[8] = {
  0b00110,
  0b01001,
  0b01001,
  0b00110,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};
byte on[8] = {
  0b00000,
  0b00000,
  0b10001,
  0b01110,
  0b01110,
  0b10001,
  0b00000,
  0b00000
};


// ОБРАБОТКА ОШИБОК

void erorr(){     // останавливает работу программы и показываем ошибку
  digitalWrite(OUT1, LOW);   // выключаем реле
  
    while(1){ // крутим бесконечный цикл
      digitalWrite(13, !digitalRead(13));
      delay(500);
    }  
}

// ОПИСАНИ КНОПОК

byte key(){ 
  int val = analogRead(0);
    if (val < 50) return 5;
    else if (val < 150) return 3;
    else if (val < 350) return 4;
    else if (val < 500) return 2;
    else if (val < 800) return 1;
    else return 0;  
    
}

// ВЫВОД НА ЭКРАН В РЕЖИМЕ УСТАНОВКИ ТЕМПЕРАТУРЫ И ЗАДАНИЯ ТЕМПАРАТУРЫ (SV)

void setMenu(){ 
  byte pos;    
  digitalWrite(OUT1, LOW); // выключаем реле
  
   while(1){              // крутим бесконечный цикл      
    byte KEY = key();    // читаем состояние кнопок
    
    lcd.clear(); 
    lcd.setCursor(1, 0);  
    lcd.print("SV: ");
    lcd.blink();
    lcd.setCursor(4, 0); // выводим на экран
    lcd.print(tempON);   //установленное знанчение температуры
    lcd.write(1);        //символ градуса
    lcd.print("C ");
    lcd.setCursor(0, 0);
    
//  TEST OLED

    myOLED.begin();
    myOLED.setFont(SmallFont);
    myOLED.print("SV", 10, 30);
    myOLED.setFont(BigNumbers);
    myOLED.printNumF(tempON, 2, 30, 30);
    myOLED.drawCircle(106, 33, 2); // hor, ver ,size
    myOLED.update();
   
// обработка кнопок 
   if (KEY == 2) {       // если левая кнопка нажата 
        tempON-= 0.5;    // изменяем значение
        if (tempON < 20) tempON = 95; //проверяем пределы
        EEPROM.write(0, tempON); // сохраняем в eeprom
      }
      else if (KEY == 5){  // если правая кнопка нажата 
        tempON+= 0.5;      // изменяем значение
        if (tempON > 95) tempON = 20; //проверяем пределы
        EEPROM.write(0, tempON);  // сохраняем в eeprom   
      }    
  delay(200);
   
  }
}

// ОПРОС ДАТЧИКА

float getTemp(){   // возвращает температуру с датчика
  byte data[12];   // и останавливает программу на секунду
  byte addr[8];  
  
  if (!ds.search(addr)) { //если адрес датчика не получен сообщаем об ошибке
    lcd.clear();
    lcd.print("No sensor."); 
    erorr(); 
  }
  
  ds.reset_search(); 
  if (OneWire::crc8(addr, 7) != addr[7]) {
    lcd.clear();
    lcd.print("Sensor CRC erorr");
    erorr();   
  }
  
  ds.reset();            
  ds.select(addr);        
  ds.write(0x44);      
  delay(500);   
  ds.reset();
  ds.select(addr);    
  ds.write(0xBE);          

  for (int i = 0; i < 9; i++) data[i] = ds.read(); 
  int raw = (data[1] << 8) | data[0]; // Переводим в температуру   
  if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6];  
  
  return raw / 16.0;
}

void setup() {
//  Serial.begin(9600); 
  lcd.createChar(1, gradus);
  lcd.createChar(2, on);
  lcd.begin(16, 2);
  lcd.clear();
  
  pinMode(13, OUTPUT); 
  pinMode(OUT1, OUTPUT);
  
  tempON = EEPROM.read(0); // читаем настройки из еепром
}

void loop() {  
  if (key() == 1) setMenu(); // если нажата кнопка селект, уходим в меню задания температуры
  
  
  float temperature = getTemp(); // читаем температуру
 
  if (temperature < tempON) digitalWrite(OUT1, HIGH); // сверяем температуру 
  else digitalWrite(OUT1, LOW);                         // и управляем выходами
  
// ВЫВОД ИНФОРМАЦИИ НА ЭКРАН В РАБОЧЕМ РЕЖИМЕ 
      
  lcd.setCursor(0, 1); /// вывод на экран заданной температуры
  lcd.print("SV:");
  lcd.print(tempON);
  lcd.write(1);
  lcd.print(" ");

    if (digitalRead(OUT1)) lcd.write(2); // вывод на экран состояние выхода
    else lcd.print(" ");
  
  lcd.setCursor(0, 0); // вывод на экран текущей температуры
  lcd.print("PV:");
  lcd.print(temperature, 1);
  lcd.write(1);
  lcd.print("C");
  lcd.setCursor(9, 1);     
  
//  TEST OLED
  
   myOLED.begin();
   myOLED.setFont(SmallFont);
   myOLED.print("PV", 10, 03);
   myOLED.print("SV", 10, 37); 
    
    if (digitalRead(OUT1)) myOLED.print("*", 14, 13); // h,v
  
   myOLED.setFont(BigNumbers);
   myOLED.printNumF(temperature, 2, 30, 03);
   myOLED.printNumF(tempON, 2, 30, 37);
   myOLED.drawCircle(106, 06, 2); // hor, ver ,size
   myOLED.drawCircle(106, 40, 2); // hor, ver ,size
   myOLED.update();
  }


 

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

Наверно пытаетесь впихнуть четыре байта в один.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

bwn пишет:

Наверно пытаетесь впихнуть четыре байта в один.


А разве архиватор не так работает? Гыыы

ty
Offline
Зарегистрирован: 15.06.2015

bwn пишет:

Наверно пытаетесь впихнуть четыре байта в один.

 

put / get разве не должны работать с fload?

 

Описание:

"

put()

Description

Write any data type or object to the EEPROM.

Syntax

EEPROM.put(address, data)

Parameters

address: the location to write to, starting from 0 (int)

data: the data to write, can be a primitive type (eg. float) or a custom struct

"
 
Если это неправильный путь, как я могу запомнить float?
Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

ty пишет:

read / write

put / get

Так и меняете read на put? Или это просто так написано? У меня на УНО так работает и более того структуры пишутся и читаются целиком, главное не забывать адрес сдвигать на нужное количество байт.

ty
Offline
Зарегистрирован: 15.06.2015

Penni пишет:

ty пишет:

read / write

put / get

Так и меняете read на put? Или это просто так написано? У меня на УНО так работает и более того структуры пишутся и читаются целиком, главное не забывать адрес сдвигать на нужное количество байт.

С синтаксисом разобрался, в отличии от read (адрес) в случае get должно быть (адрес, переменная) т.е. в моем случае 

EEPROM.get(0,tempON); Тогда компилятор не ругается.

У меня только одна переменная для запоминания. Все компилится без ошибок в этом случае, но программа перестала работать, заднная температура не выводится/не читается :( Что я опять неправильно делаю???

 

ty
Offline
Зарегистрирован: 15.06.2015

Все заработало! Спасибо всем, даже точная формулировка вопроса уже помогает найти ответ :)

Но OLED дисплей мигает, подскажите, как побороть?

 

Рабочи код:

// термостат, один датчик DS18B20
//
//  v 0.2 beta

#include <EEPROM.h>
#include <OneWire.h>
#include <LiquidCrystal.h>
#define OUT1 3 // выход для реле 

#include <OLED_I2C.h>

OLED  myOLED(SDA, SCL, 8);

extern uint8_t SmallFont[];
extern uint8_t BigNumbers[];

float tempON;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
OneWire  ds(15); // 15 вход датчика 18b20

// ГРАФИЧАСКИЕ СИМВОЛЫ ДЛЯ ЭКРАНА

byte gradus[8] = {
  0b00110,
  0b01001,
  0b01001,
  0b00110,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};
byte on[8] = {
  0b00000,
  0b00000,
  0b10001,
  0b01110,
  0b01110,
  0b10001,
  0b00000,
  0b00000
};


// ОБРАБОТКА ОШИБОК

void erorr(){     // останавливает работу программы и показываем ошибку
  digitalWrite(OUT1, LOW);   // выключаем реле
  
    while(1){ // крутим бесконечный цикл
      digitalWrite(13, !digitalRead(13));
      delay(500);
    }  
}

// ОПИСАНИ КНОПОК

byte key(){ 
  int val = analogRead(0);
    if (val < 50) return 5;
    else if (val < 150) return 3;
    else if (val < 350) return 4;
    else if (val < 500) return 2;
    else if (val < 800) return 1;
    else return 0;  
    
}

// ВЫВОД НА ЭКРАН В РЕЖИМЕ УСТАНОВКИ ТЕМПЕРАТУРЫ И ЗАДАНИЯ ТЕМПАРАТУРЫ (SV)

void setMenu(){ 
  byte pos;    
  digitalWrite(OUT1, LOW); // выключаем реле
  
   while(1){              // крутим бесконечный цикл      
    byte KEY = key();    // читаем состояние кнопок
    
    lcd.clear(); 
    lcd.setCursor(1, 0);  
    lcd.print("SV: ");
    lcd.blink();
    lcd.setCursor(4, 0); // выводим на экран
    lcd.print(tempON);   //установленное знанчение температуры
    lcd.write(1);        //символ градуса
    lcd.print("C ");
    lcd.setCursor(0, 0);
    
//  TEST OLED

    myOLED.begin();
    myOLED.setFont(SmallFont);
    myOLED.print("SV", 10, 30);
    myOLED.setFont(BigNumbers);
    myOLED.printNumF(tempON, 2, 30, 30);
    myOLED.drawCircle(106, 33, 2); // hor, ver ,size
    myOLED.update();
   
// обработка кнопок 
   if (KEY == 2) {       // если левая кнопка нажата 
        tempON-= 0.5;    // изменяем значение
        if (tempON < 20) tempON = 95; //проверяем пределы
        EEPROM.put(0, tempON); // сохраняем в eeprom
      }
      else if (KEY == 5){  // если правая кнопка нажата 
        tempON+= 0.5;      // изменяем значение
        if (tempON > 95) tempON = 20; //проверяем пределы
        EEPROM.put(0, tempON);  // сохраняем в eeprom   
      }    
  delay(200);
   
  }
}

// ОПРОС ДАТЧИКА

float getTemp(){   // возвращает температуру с датчика
  byte data[12];   // и останавливает программу на секунду
  byte addr[8];  
  
  if (!ds.search(addr)) { //если адрес датчика не получен сообщаем об ошибке
    lcd.clear();
    lcd.print("No sensor."); 
    erorr(); 
  }
  
  ds.reset_search(); 
  if (OneWire::crc8(addr, 7) != addr[7]) {
    lcd.clear();
    lcd.print("Sensor CRC erorr");
    erorr();   
  }
  
  ds.reset();            
  ds.select(addr);        
  ds.write(0x44);      
  delay(500);   
  ds.reset();
  ds.select(addr);    
  ds.write(0xBE);          

  for (int i = 0; i < 9; i++) data[i] = ds.read(); 
  int raw = (data[1] << 8) | data[0]; // Переводим в температуру   
  if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6];  
  
  return raw / 16.0;
}

void setup() {
//  Serial.begin(9600); 
  lcd.createChar(1, gradus);
  lcd.createChar(2, on);
  lcd.begin(16, 2);
  lcd.clear();
  
  pinMode(13, OUTPUT); 
  pinMode(OUT1, OUTPUT);
  
  
  tempON = EEPROM.get(0 , tempON); // читаем настройки из еепром
}

void loop() {  
  if (key() == 1) setMenu(); // если нажата кнопка селект, уходим в меню задания температуры
  
  
  float temperature = getTemp(); // читаем температуру
 
  if (temperature < tempON) digitalWrite(OUT1, HIGH); // сверяем температуру 
  else digitalWrite(OUT1, LOW);                         // и управляем выходами
  
// ВЫВОД ИНФОРМАЦИИ НА ЭКРАН В РАБОЧЕМ РЕЖИМЕ 
      
  lcd.setCursor(0, 1); /// вывод на экран заданной температуры
  lcd.print("SV:");
  lcd.print(tempON);
  lcd.write(1);
  lcd.print(" ");

    if (digitalRead(OUT1)) lcd.write(2); // вывод на экран состояние выхода
    else lcd.print(" ");
  
  lcd.setCursor(0, 0); // вывод на экран текущей температуры
  lcd.print("PV:");
  lcd.print(temperature, 1);
  lcd.write(1);
  lcd.print("C");
  lcd.setCursor(9, 1);     
  
//  TEST OLED
  
   myOLED.begin();
   myOLED.setFont(SmallFont);
   myOLED.print("PV", 10, 03);
   myOLED.print("SV", 10, 37); 
    
    if (digitalRead(OUT1)) myOLED.print("*", 14, 13); // h,v
  
   myOLED.setFont(BigNumbers);
   myOLED.printNumF(temperature, 2, 30, 03);
   myOLED.printNumF(tempON, 2, 30, 37);
   myOLED.drawCircle(106, 06, 2); // hor, ver ,size
   myOLED.drawCircle(106, 40, 2); // hor, ver ,size
   myOLED.update();
  }
Farukh
Offline
Зарегистрирован: 25.09.2015

Доброго время суток дорогие форумчани! у меня такой вопрос сушествует такой аппарат для быстрой чтение и запись данных на EEPROM через ISP? Я сам в этом особо не разбераюсь по этому прошу Вас кто знает пожалуйста помогите

У меня есть счетчик наработки часов у него 6 пин внутреный разем для программирование я хочу изменить его показания уменщить и увеличить но не знаю как 

заранее спасибо

Клапауций 001
Offline
Зарегистрирован: 05.09.2015

Farukh пишет:

У меня есть счетчик наработки часов у него 6 пин внутреный разем для программирование я хочу изменить его показания уменщить и увеличить но не знаю как 

что на счётчике написал производитель?

Farukh
Offline
Зарегистрирован: 25.09.2015

В смысле что написал на счетчике производитель? Яя вас не понял я хочу поменять цифры которые он сохраняет в eeprom чтобы он показал мной выстовленый цифры

Клапауций 001
Offline
Зарегистрирован: 05.09.2015

Farukh пишет:
В смысле что написал на счетчике производитель? Яя вас не понял я хочу поменять цифры которые он сохраняет в eeprom чтобы он показал мной выстовленый цифры

а, я хочу узнать название устройства, которое ты пытаешься хакнуть.

Radjah
Offline
Зарегистрирован: 06.08.2014

> У меня есть черный ящик со штырьками. Как его запрограммировать?

Как-то так.

Клапауций 001
Offline
Зарегистрирован: 05.09.2015

Radjah пишет:

> У меня есть черный ящик со штырьками. Как его запрограммировать?

Как-то так.

станок-ЧПУ и я хочу во вторую смену фигачить левак, что бы хозяин не знал.

не - брешу. кофемашина! - точно, кофемашина.

Farukh
Offline
Зарегистрирован: 25.09.2015

Это счётчик моточасов дизель генератор марки Geko