объем EEPROM в китайском DS1307 real time clock module

chk
Offline
Зарегистрирован: 14.04.2013

Имеется китайский модуль I2C RTC DS1307 AT24C32 Real Time Clock Module. 

Из названия следует, что в нем уставлена EEPROM  AT24C32, объем которой 32 кбит = 8 кб. Но в моем экземпляре данный чип промаркирован как ATMLH134  320M. Через wire по стандартному адресу девайса 0x50 успешно записал и считал байт 222 в 10 ячейке, для примера. Возникает вопрос: как узнать объем моего конкретного чипа? даташит на него не нашел. А насиловать его многократной циклической записью с начала, что будет как я понял происходить при превышении конечного адреса, я не хочу. Да и придумывать, что же именно туда писать такое, что потом легко выдаст цикличность - как-то нет желания. Возможно придется это делать, но может кто-н сталкивался уже с подобным и имеет ответ на этот вопрос?

Geronimo
Offline
Зарегистрирован: 06.05.2013

писать 1 2 3 4 5 6 7 8.. как наткнешься на 1 значит все, второй круг

мб там 320 мбит?)

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Надо еще подумать над тем, как адресовать 8кб ячеек. Я когда-то пробовал с ней развлекаться, но дальше записать-прочитать дело не пошло...

/* 
  *  Use the I2C bus with EEPROM 24LC64 
  *  Sketch:    eeprom.pde
  *  
  *  Author: hkhijhe
  *  Date: 01/10/2010
  * 
  *   
  */

  #include <Wire.h> //I2C library

  void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
    int rdata = data;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write(rdata);
    Wire.endTransmission();
  }

  // WARNING: address is a page address, 6-bit end will wrap around
  // also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
  void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddresspage >> 8)); // MSB
    Wire.write((int)(eeaddresspage & 0xFF)); // LSB
    byte c;
    for ( c = 0; c < length; c++)
      Wire.write(data[c]);
    Wire.endTransmission();
  }

  byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
    byte rdata = 0xFF;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,1);
    if (Wire.available()) rdata = Wire.read();
    return rdata;
  }

  // maybe let's not read more than 30 or 32 bytes at a time!
  void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,length);
    int c = 0;
    for ( c = 0; c < length; c++ )
      if (Wire.available()) buffer[c] = Wire.read();
  }


 void setup() 
  {
    char somedata[] = "this is data from the eeprom: "; // data to write
    char somedata0[] = "                 ";
    char somedata1[] = "testing testing 2-nd string..\0";
    
    Wire.begin(); // initialise the connection
    Serial.begin(9600);
    
    i2c_eeprom_write_page(0x50, 0, (byte *)somedata, sizeof(somedata)); // write to EEPROM 
    delay(10); //add a small delay

    //i2c_eeprom_write_page(0x50, 16, (byte *)somedata0, sizeof(somedata0)); // write to EEPROM 
    //delay(10); //add a small delay

    i2c_eeprom_write_page(0x50, 32, (byte *)somedata1, sizeof(somedata1)); // write to EEPROM 
    delay(10); //add a small delay

    Serial.println("Memory written");
  }

 void loop() 
  {
    int addr=0; //first address
    byte b = i2c_eeprom_read_byte(0x50, 0); // access the first address from the memory

    while (b!=0) 
    {
      Serial.print((char)b); //print content to serial port
      addr++; //increase address
      b = i2c_eeprom_read_byte(0x50, addr); //access an address from the memory
    }

    Serial.println(" ");
    delay(2000);

  }

 

chk
Offline
Зарегистрирован: 14.04.2013

ошибся чуток, 32/8 =4, т.е. там 4кб должно быть, если этот чип аналог того что в описании.

а писать последовательно 0, 1, 2, 3.. так только до 255 можно. потом уже надо два байта писать.. и как-то все это учесть. По идее должно сработать, в начале хрень будет другая вместо 0, 1, 2.. после циклической перезаписи. Так-то eeprom вряд ли настолько мелкий по объему, что это дело его убьет.. но все ж хотелось бы наименее затратный и простой способ узнать. Китайцу-продавцу написал еще, вдруг ответит чего и правду)

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

Geronimo
Offline
Зарегистрирован: 06.05.2013

chk пишет:

ошибся чуток, 32/8 =4, т.е. там 4кб должно быть, если этот чип аналог того что в описании.

а писать последовательно 0, 1, 2, 3.. так только до 255 можно. потом уже надо два байта писать.. и как-то все это учесть. По идее должно сработать, в начале хрень будет другая вместо 0, 1, 2.. после циклической перезаписи. Так-то eeprom вряд ли настолько мелкий по объему, что это дело его убьет.. но все ж хотелось бы наименее затратный и простой способ узнать. Китайцу-продавцу написал еще, вдруг ответит чего и правду)

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

зачем до 255, если в дефолте они пустые пиши просто 1 пока 1 не найдешь

там ячейка на 100к перезаписей расчитана, то что ты 1 раз туда просто так запишешь 1 ей погоды не сделает

да и перебрать все не так уж и долго и затратно

chk
Offline
Зарегистрирован: 14.04.2013

о, дошло)) хотя может и не совсем то. что-то я тупанул совсем. можно ж просто записать 1 в начальную ячейку, а дальше читать все подряд, пока не наткнусь на свою единицу=) обнулив перед этим то что в примеред делал, да и вообще проверить надо на всякий случай сначала, пустые ли они все.

Geronimo
Offline
Зарегистрирован: 06.05.2013

а в друг они мусором забиты?

можешь не ту 1 найти

chk
Offline
Зарегистрирован: 14.04.2013

только что закончил с проверкой, мусор был до 29 ячейки, в остальных - 255. почистил. ща пишу проверку на объем..

все проверил, единичка только в начале, и на всякий случай накинул +1 на предполагаемый размер 4кб - показало еще единицу после этого по адресу 4096.

Где-то обсуждалась память DS1307, так вот, если я не пропустил ничего - поздравляю всех обладателей подобных модулей: помимо часов у вас есть EEPROM на 4кбайта. AT24C32 по даташиту имеет миллион циклов перезаписи, что на порядок больше того что у нас в МК. Как с этим дела у моего видимо китайского аналога не знаю, но все равно круто. будет куда чего сохранять, не особо заботясь о ближайших 10-20 годах)) а заменить в случае чего модуль часов намного дешевле и проще, чем дуину со всем, к ней подключенным. Дату и время часы после моих манипуляций показывают как и раньше, с февраля примерно убежали на полторы минуты.

Geronimo
Offline
Зарегистрирован: 06.05.2013

миллион на ячейку или всеко миллион раз записать?

и зачем всю ардуину?

если у тебя Uno то можно только чип заменить, стоит он рублей 400

chk
Offline
Зарегистрирован: 14.04.2013

скорее всего имеется в виду ячейка, остальные ведь не трогаются по идее. написано только это:

Endurance: 1 Million Write Cycles

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

ales2k
Offline
Зарегистрирован: 25.02.2013

Во всю использую  AT24C32 - там 4 килобайта. В библиотеке функция блочной записи работает только с "ровными" блоками и при достижении конца блока начинает писать в него же с начала. После любой записи надо ждать 10-20 мс до следующей операци с AT24C32. А так отличный шустрый и надежный чип.

__Alexander
Offline
Зарегистрирован: 24.10.2012

что то мне не верится что там надпись 320М. может таки 32СМ?

chk
Offline
Зарегистрирован: 14.04.2013

вроде, больше похоже на 32DM... а мне показалось что 320 ))) ну и ладно, главное что все уже стало ясно.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

ales2k пишет:

Во всю использую  AT24C32 - там 4 килобайта. В библиотеке функция блочной записи работает только с "ровными" блоками и при достижении конца блока начинает писать в него же с начала.

Библиотека-то как называется?

ales2k
Offline
Зарегистрирован: 25.02.2013

Библиотека своя на основании примеров

i2ceeprom

i2ceeprom.h 

#ifndef i2ceeprom_h 
#define i2ceeprom_h 

//#define i2ceeprom32_I2C_ADDRESS 0x50 //default address
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

class 
 i2ceeprom {
  public:
    void i2c_eeprom_write_byte( byte deviceaddress, unsigned int eeaddress, byte data );
    void i2c_eeprom_write_block( byte deviceaddress, unsigned int eeaddresspage, void* data, unsigned int length );
    byte i2c_eeprom_read_byte( byte deviceaddress, unsigned int eeaddress );
    void i2c_eeprom_read_buffer( byte deviceaddress, unsigned int eeaddress, void *buffer, byte length );
};
#endif 

i2ceeprom.cpp


#include <i2ceeprom.h> 
#include <Wire.h> //I2C library // A4,A5

// i2ceeprom32 provides 32,768 bits 0x50

  void i2ceeprom::i2c_eeprom_write_byte( byte deviceaddress, unsigned int eeaddress, byte data ) {
    byte rdata = data;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write(rdata);
    Wire.endTransmission();
  }


  void i2ceeprom::i2c_eeprom_write_block( byte deviceaddress, unsigned int eeaddress, void* data, unsigned int length ) {
    const byte* current = reinterpret_cast<const byte*>(data);
    unsigned int c;
    for ( c = 0; c < length; c++)
    {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write(*current++);
    Wire.endTransmission();
    eeaddress++;delay(20);
    }
  }

  byte i2ceeprom::i2c_eeprom_read_byte( byte deviceaddress, unsigned int eeaddress ) {
    byte rdata = 0xFF;
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,(byte)1);
    if (Wire.available()) rdata = Wire.read();
    return rdata;
  }

  // maybe let's not read more than 30 or 32 bytes at a time!
    void i2ceeprom::i2c_eeprom_read_buffer( byte deviceaddress, unsigned int eeaddress, void *buffer, byte length ) {
    byte* current = reinterpret_cast<byte*>(buffer);
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,(byte)length);
    int c = 0;
    for ( c = 0; c < length; c++ )
	if (Wire.available())  *current++ = Wire.read(); 
 }

 

Samodelkin
Offline
Зарегистрирован: 07.06.2012

ales2k, а можно пример использования вашей билиотеки для работы с eeprom.

ales2k
Offline
Зарегистрирован: 25.02.2013


#include <Wire.h> //I2C library
#include <i2ceeprom.h> 

  void setup() 
  {
    char somedata[] = "this is data from the eeprom"; // data to write ABCDEFGHIJKLMNOPQRSTUVWXYZ
    Wire.begin(); // initialise the connection
    Serial.begin(38400);
    i2c_eeprom_write_block(0x50, 0, (byte *)somedata, sizeof(somedata)); // write to EEPROM 

    delay(10); //add a small delay

    Serial.println("Memory written");
  }

  void loop() 
  {
    int addr=0; //first address
    byte b = i2c_eeprom_read_byte(0x50, 0); // access the first address from the memory

    while (b!=0) 
    {
      Serial.print((char)b); //print content to serial port
      addr++; //increase address
      b = i2c_eeprom_read_byte(0x50, addr); //access an address from the memory
    }
    Serial.println(" ");
    delay(200000);
  }

Простой кусочек кода из какогото примера - не помню из какого.
 

 
Samodelkin
Offline
Зарегистрирован: 07.06.2012

Спасибо!!

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

Функция i2c_eeprom_write_block принимает аргумент unsigned int eeaddress, для чего вы перед отпрвавкой eeaddress преобразовываете в int: Wire.write((int)(eeaddress >> 8)); при условии что отправляется  байт? Может преобразовать сразу в байт: Wire.write((byte)(eeaddress >> 8)); Так же обратите внимание на аргумент void* data, при передачи его в функцию вы преобразовываете в byte*: (byte *)somedata а затем внутри функции делаете тоже самое еще раз: const byte* current = reinterpret_cast<const byte*>(data); так может тогда логичнее делать это один раз например только внутри: i2c_eeprom_write_block(0x50, 0, somedata, sizeof(somedata)).

ales2k
Offline
Зарегистрирован: 25.02.2013

По первому пункту абсолютно согласен, не обратил внимания, по второму преобразование внутри функции сделано для совместимости, а пример давний, еще до этого изменения. 

Спасибо за уточнения.

Интересно этот компилятор такие простые ошибки отлавливает при оптимизации выполнения и выкидывает не нужные действия?

ales2k
Offline
Зарегистрирован: 25.02.2013

Офтопик

Может на форуме завести раздел для библиотечек. Я бы поделился накопленными и написанными и подправили косяки заодно. 

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

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

AndyResh
Offline
Зарегистрирован: 08.04.2013

Добрый день!

Будьте любезны, подскажите как при помощи этого кода:


#include <Wire.h> //I2C library
#include <i2ceeprom.h> 

 void setup() 
 {
 char somedata[] = "this is data from the eeprom"; // data to write ABCDEFGHIJKLMNOPQRSTUVWXYZ
 Wire.begin(); // initialise the connection
 Serial.begin(38400);
 i2c_eeprom_write_block(0x50, 0, (byte *)somedata, sizeof(somedata)); // write to EEPROM 

 delay(10); //add a small delay

 Serial.println("Memory written");
 }

 void loop() 
 {
 int addr=0; //first address
 byte b = i2c_eeprom_read_byte(0x50, 0); // access the first address from the memory

 while (b!=0) 
 {
 Serial.print((char)b); //print content to serial port
 addr++; //increase address
 b = i2c_eeprom_read_byte(0x50, addr); //access an address from the memory
 }
 Serial.println(" ");
 delay(200000);
}

сохранять несколько переменных, например: current_day=3; day_X=27; temp_min=18; temp_max=22; light_on=6; light_off=21; и т.д., а затем при необходимости считывать?

Проблема именно в организации сохранения значений при записи, а так же разнесении символов по переменным при считывании.

Будьте добры, посоветуйте.

Для меня это ОЧЕНЬ замечательная находка для сохранения небольших данных при отключении питания.

ОГРОМНОЕ спасибо ales2k за реализацию библиотеки.

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

AndyResh пишет:

Проблема именно в организации сохранения значений при записи, а так же разнесении символов по переменным при считывании.

В чем проблема? Каких символов?

AndyResh
Offline
Зарегистрирован: 08.04.2013

Как выглядит код, который сохранит значения переменных в EEPROM, а затем считает их и присвоит переменным.

AndyResh
Offline
Зарегистрирован: 08.04.2013

Может под каждую переменную выделить свои адреса и писать только в них, а значит и считывать в переменные из конкретных адресов?

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

AndyResh пишет:

Как выглядит код, который сохранит значения переменных в EEPROM, а затем считает их и присвоит переменным.

Как выше в коде показано - так и выглядет.

AndyResh пишет:

Может под каждую переменную выделить свои адреса и писать только в них, а значит и считывать в переменные из конкретных адресов?

А знаете еще другие адекватные варианты?

AndyResh
Offline
Зарегистрирован: 08.04.2013

Ну как вариант, может по аналогии с SD картой получится?

myFile = SD.open("CURRENT.TXT");

  if (myFile) { 
    while (myFile.available()) { 
       // считываем байт входящего файла 
    symbol2 = myFile.read(); 
    array[h] = symbol2; 
    h++; 
   delay(1); 
       } 
     array[h]='\0'; 
     myFile.close(); 
     } 
 char *p;  
 byte t = 0; 
 for( buffer = strtok_r(array, ",.", &p); buffer; buffer = strtok_r(NULL, ",.", &p) )   { 

 Serial.print(t);Serial.print(" = ");Serial.println(atoi(buffer)); 
 delay(1); 
  outArray[t]=atoi(buffer); 
 t++; 
    }
current_day = outArray[1];
day_X = outArray[2];
}

 ну только без myFile.close(); и тому подобного

ales2k
Offline
Зарегистрирован: 25.02.2013

Я бы сделал структуру и сохранял всю структуру целиком, затем читал всю структуру.

По примеру как это сделано с массивом char somedata[] = "this is data from the eeprom";

Никакой существенной разницы.

Только стоит помнить о ресурсе EEPROM примерно 10000 записей в одно место.

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

AndyResh пишет:

Ну как вариант, может по аналогии с SD картой получится?

Этот вариант к адекватным не относится.

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

ales2k пишет:

Я бы сделал структуру и сохранял всю структуру целиком, затем читал всю структуру.

Ну коль начали, продолжеайте. Покажите человеку что такое структура и как ей пользоваться. А то так и будет думать что строка это структура... и пихать в строку переменные вместе с их именами.

ales2k
Offline
Зарегистрирован: 25.02.2013

"Каждый сам творец своего счастья" так что

http://playground.arduino.cc/Code/Struct

 

 

AndyResh
Offline
Зарегистрирован: 08.04.2013

Покажите, пожалуйста, пример с двумя переменными - послужит образцом.

Извините, опоздал с просьбой.

Спасибо, буду читать.

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

Как то так

#include <Wire.h> //I2C library
#include <i2ceeprom.h> 


void setup() 
{
  Wire.begin(); 

  struct DATA    // Cтруктура
  {
    int current_day;
    int day_X;
    byte temp_min;
    byte temp_max;
    int light_on;
    int light_off;
  };


  // Запись
  DATA data;
  // заполняем
  data.current_day = 3;  
  data.day_X = 27;
  data.temp_min = 18;
  data.temp_max = 22;
  data.light_on = 6;
  data.light_off = 21;
  // Сохраняем
  i2c_eeprom_write_block(0x50, 0, &data, sizeof(data)); 
  delay(10); 


  // Чтение
  DATA data_2;   
  // Заполняем data_2 из ЕЕПРОМ
  i2c_eeprom_read_buffer(0x50, 0, &data_2, sizeof(data_2));  
  // Присваиваем переменным
  int current_day = data_2.current_day;     
  int day_X = data_2.day_X;
  byte temp_min = data_2.temp_min;
  byte temp_max = data_2.temp_max;
  int light_on = data_2.light_on;
  int light_off = data_2.light_off;

}

void loop(){}

Обратите внимание на типы переменных, если у вас все типы переменных byte (char), то применять структуры бессысленно.

ales2k
Offline
Зарегистрирован: 25.02.2013

Поправь - ты 2 раза пишешь в EEPROM

И зачем данные структуры переменным присваивать - ими и так пользоваться можно и удобно

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

Поправил, ну так вы же не знаете как потом будут этим пользоваться. Может у AndyResh кода на 2 листа с этими переменными, что ему теперь весь код править...

AndyResh
Offline
Зарегистрирован: 08.04.2013

Гениально! БЛАГОДАРЮ!

Я бы и поправил весь код если бы нужно было, а так - вообще замечтательно!

Как же ВЫ мне помогли, и последующим поколениям тоже.

На примере стало понятно откуда все берется и куда потом деётся.

std
Offline
Зарегистрирован: 05.01.2012

maksim пишет:
кода на 2 листа с этими переменными, что ему теперь весь код править

Ctrl+F7 в редакторе FAR'а :)

AndyResh
Offline
Зарегистрирован: 08.04.2013

std пишет:

maksim пишет:
кода на 2 листа с этими переменными, что ему теперь весь код править

Ctrl+F7 в редакторе FAR'а :)

В IDE Ctrl+F достаточно))

Тут вот какая загогулина получается. Понимаю рассудком, что чудес на свете не бывает, однако...

Создал папку \SOFT\ARDUINO\libraries\i2ceeprom , в нее положил файлы i2ceeprom.h и i2ceeprom.cpp

инклудил, собственно в шапку скетча #include <i2ceeprom.h> , а IDE 1.0.2 ругается:

sketch_LCD1602_RTC_Reley_DHT_31_10_2013.ino: In function 'void setup()':
sketch_LCD1602_RTC_Reley_DHT_31_10_2013:105: error: 'i2c_eeprom_read_buffer' was not declared in this scope

Как буд-то на видит библиотеку. От чего может так получится?

Ниже "портянка" целиком, версия на стадии написания/отладки/дописания


#include <Wire.h>
#include <RTClib.h>
#include <i2ceeprom.h>
#include <LiquidCrystal.h>
#include "DHT.h"

RTC_DS1307 RTC;
DateTime now;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// define variables

#define btnRIGHT  0
#define btnUP    1
#define btnDOWN  2
#define btnLEFT  3
#define btnSELECT 4
#define btnNONE  5

#define ON LOW                        // Реле включено
#define OFF HIGH                      // Реле выключено

int light_state = OFF;                // этой переменной устанавливаем состояние освещения
int current_day = 0;                  // сюда записываем текущий день
int day_X = 24;                       // день на который приходится базовая длина дня с базовым времинем включения

int lastDay = 0;
int lastMonth = 0;
int lastYear = 0;
int lastHour = 0;
int lastMinute = 0;


int lcd_key = 0;
int adc_key_in = 0;
int menuOptions = 3;
int menuOption = 0;

int current_light_on_hours = 3;          //Расчетное время включения освещения в часах
int current_light_on_minutes = 20;       //Расчетное время включения освещения в минутах
int current_light_off_hours = 21;        //Расчетное время выключения освещения в часах
int current_light_off_minutes = 20;      //Расчетное время выключения освещения в минутах

bool resetClock = false;

// define constants
//const int hot1_Pin = 42;              // номер выхода, подключенного к обогреву I
//const int hot2_Pin = 43;              // номер выхода, подключенного к оборгеву II
//const int wind_Pin = 44;              // номер выхода, подключенного к вентилятору ветра
//const int jet_Pin = 45;               // номер выхода, подключенного к вентилятору вытяжки
#define PUMP1_Pin 46                    // номер выхода, подключенного к помпе орашения
//const int pump2_Pin = 47;             // номер выхода, подключенного к помпе подкачки
#define LAMP_Pin 48                     // номер выхода, подключенного к освещению

#define LOW_INTERVAL 20000              // время орашения
#define HIGH_INTERVAL 120000            // время паузы между орашением, ДА-ДА, именно так!

#define DHTPIN_1 22
#define DHTPIN_2 23
#define DHTTYPE DHT22

DHT DHT_1(DHTPIN_1, DHTTYPE);
DHT DHT_2(DHTPIN_2, DHTTYPE);

#define beeper A1
#define shortBeep 100
#define longBeep  500

void setup () {

  pinMode(beeper, OUTPUT);              // режим PIN зумера
  digitalWrite(beeper, LOW); 
  pinMode(LAMP_Pin, OUTPUT);            // режим PIN освещения утро/вечер
  pinMode(PUMP1_Pin, OUTPUT);           // режим PIN помпы орашения

  Wire.begin();
  Serial.begin(9600);
  RTC.begin();
  if (RTC.isrunning()) {
    Serial.println("RTC is running.");
  }
  else if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
  }

  lcd.begin(16,2);                    //стартуем библиотеку экрана

  DHT_1.begin();                      //стартуем библиотеку датчика температуры/влажности 1
  DHT_2.begin();                      //стартуем библиотеку датчика температуры/влажности 2

  struct DATA    // Cтруктура
  {
    int current_day;
    int day_X;
    byte temp_min;
    byte temp_max;
    int light_on;
    int light_off;
  };

  // Чтение
  DATA data_R;   
  // Заполняем data_2 из ЕЕПРОМ
  i2c_eeprom_read_buffer(0x50, 0, &data_R, sizeof(data_R));  
  // Присваиваем переменным
  int current_day = data_R.current_day;     
  int day_X = data_R.day_X;

}


void loop () {
  now = RTC.now();
 if (now.day() != lastDay)  current_day++;            // Текущий день + 1
  button_loop();                                      // Функция слежения за нажатием кнопок

  pumping();                                          // Функция орашения
  lights();                                           // Функция освещения
//  temperatura();                                      // Функция считывания температуры с датчиков и адаптации к выводу
}


void pumping()  {                                     // Процедура цикличности орашения

static unsigned long period= LOW_INTERVAL;            // Текущий интервал орашения
static unsigned long prevMillis=0;

  if( (millis()-prevMillis)>=period)  {
    prevMillis=millis();
    digitalWrite(PUMP1_Pin,!digitalRead(PUMP1_Pin));
                                                       // Меняем интервал через сколько нужно сработать в следующий раз
    period=(period==LOW_INTERVAL)?HIGH_INTERVAL: LOW_INTERVAL;
                                                       // Чередуем LOW_INTERVAL / HIGH_INTERVAL
  } 
}


void temperatura()  {                                  //Процедура считывания температуры и влажности с датчиков и адаптация данных для вывода
   float h_1 = DHT_1.readHumidity();
   float t_1 = DHT_1.readTemperature(); 
   float h_2 = DHT_2.readHumidity();
   float t_2 = DHT_2.readTemperature(); 

/* 
      lcd.setCursor(0,9);
      lcd.print(t_1, 0);
      lcd.print("C");
      lcd.print("|");
      lcd.print(h_1, 0);
      lcd.print("%");

      //lcd.print("|");
      //lcd.print(t_2, 0);
      //lcd.print(":");
      //lcd.print(h_2, 0); 
*/

}


void printDigits(byte digits)    {
  // utility function for digital clock display: prints preceding colon and leading 0
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits,DEC);
}


void digitalClockDisplay()    {

    if (now.minute() != lastMinute || resetClock == true)    {
      lcd.setCursor(0,0);

    if(now.hour() < 10)
      lcd.print('0');
      lcd.print(now.hour(), DEC);
      lcd.print( (now.second() % 2)?" ":":");               // разделитель моргает
      printDigits(now.minute());

      lcd.setCursor(6,0);

    if(now.day() < 10)
      lcd.print('0');
      lcd.print(now.day(), DEC);
      lcd.print("/");

    if(now.month() < 10)
      lcd.print('0');
      lcd.print(now.month(), DEC);
      lcd.print("/");

    int thisYear = now.year();
      lcd.print(thisYear, DEC);

  }
 
      lcd.setCursor(0,1);
    if(current_day < 10)
      lcd.print('0');
      lcd.print(current_day);
      lcd.print("/");
      lcd.print(day_X);

/*

    if(current_light_on_hours < 10)
      lcd.print('0');
      lcd.print(current_light_on_hours);
      lcd.print(":");
    if(current_light_on_minutes < 10)
      lcd.print('0');
      lcd.print(current_light_on_minutes);
      lcd.print("-");
      lcd.print(current_light_off_hours);
      lcd.print(":");
    if(current_light_off_minutes < 10)
      lcd.print('0');
      lcd.print(current_light_off_minutes);
      lcd.print(" ");


      lcd.setCursor(14,1);
    if(current_day < 10)
      lcd.print('0');
      lcd.print(current_day);
*/

  resetClock = false;
  lastDay = now.day();
  lastMonth = now.month();
  lastYear = now.year();
  lastHour = now.hour();
  lastMinute = now.minute();
}


void lights()    {                                      //Функция расчета включения освещения

if (current_day > 0 && current_day <= day_X)    {


if (current_light_on_hours == lastHour && current_light_on_minutes <= lastMinute)  light_state = ON;     //включаем освещение     light_state = HIGH;  - выключаем освещение.

else if (current_light_on_hours < lastHour  &&  lastHour  < current_light_off_hours)  light_state = ON;

else if (current_light_off_hours == lastHour && current_light_off_minutes > lastMinute)  light_state = ON;

else if (current_light_off_hours == lastHour && current_light_off_minutes <= lastMinute)  light_state = OFF;

else if (current_light_off_hours < lastHour)  light_state = OFF;

digitalWrite(LAMP_Pin, light_state);                  // Запись статуса освещения в пин
}


if (current_day > day_X) {

if (current_light_on_hours + 3 == lastHour && current_light_on_minutes <= lastMinute)  light_state = ON;     //включаем освещение     light_state = HIGH;  - выключаем освещение.

else if (current_light_on_hours + 3 < lastHour  &&  lastHour  < current_light_off_hours - 2)  light_state = ON;

else if (current_light_off_hours - 2 == lastHour && current_light_off_minutes > lastMinute)  light_state = ON;

else if (current_light_off_hours - 2 == lastHour && current_light_off_minutes <= lastMinute)  light_state = OFF;

else if (current_light_off_hours - 2 < lastHour)  light_state = OFF;

digitalWrite(LAMP_Pin, light_state);                  // Запись статуса освещения в пин
  }
}


void button_loop()    {
  int button = read_LCD_buttons();
//  digitalClockDisplay();      // Функция обновления часов








  if (button == btnSELECT)    {
    timedBeep(shortBeep,1); 
    selectMenu();
  }
}
 
 
 
 
 void selectScreen()    {
  int button = 0; 
  menuOption = 1;

  while (menuOption <= menuOptions)    {

  digitalClockDisplay();      // Функция обновления часов
  pumping();                                          // Функция орашения - эксперимента ради пробую не останавливать полив на время выбора подменю
  lights();                                           // Функция освещения - эксперимента ради пробую не останавливать полив на время выбора подменю

    button = read_LCD_buttons();

    if (button == btnRIGHT)    {
      timedBeep(shortBeep,1);  

    if (menuOption == 3)  menuOption = 0;

      menuOption++;

      if (menuOption == 1)    {
        lcdClear();
        lcd.print("Current Day");            
      }

      if (menuOption == 2)    {
        lcdClear();
        lcd.print("Day X");            
      }

      if (menuOption == 3)    {
        lcdClear();
        lcd.print("Date/Time");            
//        menuOption = 0;
      }

    }

    if (button == btnLEFT)    {
      timedBeep(shortBeep,1);  

      menuOption--;
      
      if (menuOption < 1)  menuOption = 3;
      
      if (menuOption == 1)    {
        lcdClear();
        lcd.print("Current Day");            
      }

      if (menuOption == 2)    {
        lcdClear();
        lcd.print("Day X");            
      }

      if (menuOption == 3)    {
        lcdClear();
        lcd.print("Date/Time");            
      }
      
    }
  }
 }
 
 
 
 
 

void selectMenu()    {
  int button = 0; 
  menuOption = 1;
  lcdClear();
  lcd.print("Current Day"); 

  while (menuOption <= menuOptions)    {

  pumping();                                          // Функция орашения - эксперимента ради пробую не останавливать полив на время выбора подменю
  lights();                                           // Функция освещения - эксперимента ради пробую не останавливать полив на время выбора подменю

    button = read_LCD_buttons();

    if (button == btnRIGHT)    {
      timedBeep(shortBeep,1);  

    if (menuOption == 3)  menuOption = 0;

      menuOption++;

      if (menuOption == 1)    {
        lcdClear();
        lcd.print("Current Day");            
      }

      if (menuOption == 2)    {
        lcdClear();
        lcd.print("Day X");            
      }

      if (menuOption == 3)    {
        lcdClear();
        lcd.print("Date/Time");            
//        menuOption = 0;
      }

    }

    if (button == btnLEFT)    {
      timedBeep(shortBeep,1);  

      menuOption--;
      
      if (menuOption < 1)  menuOption = 3;
      
      if (menuOption == 1)    {
        lcdClear();
        lcd.print("Current Day");            
      }

      if (menuOption == 2)    {
        lcdClear();
        lcd.print("Day X");            
      }

      if (menuOption == 3)    {
        lcdClear();
        lcd.print("Date/Time");            
      }
      
    }


    if (button == btnSELECT)    {

      if (menuOption == 1)    {
        timedBeep(shortBeep,1);
        setCurrentDay();
        return;
      }

      if (menuOption == 2)    {
        timedBeep(shortBeep,1);
        setDay_X();
        return;
      }

      if (menuOption == 3)    {
        timedBeep(shortBeep,1);
        setDateTime();
        return;
      } 
    }
   }
  }


void setCurrentDay()    {      //Установка текущего дня работы

  int button = 0;

  current_day = getTimerMinutes("Set Current Day", current_day, 366);

  if (current_day >= 0 && current_day < 367)    {

      lcdClear();
      lcd.setCursor(0,1);
//    if (current_day < 100)
//      lcd.print("0");
    if (current_day < 10)
      lcd.print("0");
      lcd.print(current_day);

      if (button == btnRIGHT)    {
        timedBeep(shortBeep,1);

        lcd.setCursor(0,0);
        lcd.print("Current Day Set for");
        delay(500);
        lcdClear();
        return;      
      }
      else    {
        timerCancelled("Current Day");
        lcdClear();
        return;  
      }  
  }    
}


void setDay_X()    {      //Установка деня на который приходится базовая длина дня с базовым времинем включения

  int button = 0;

  day_X = getTimerMinutes("Set Day X", day_X, 366);

  if (day_X >= 0 && day_X < 367)    {

      lcdClear();
      lcd.setCursor(0,1);
//    if (day_X < 100)
//      lcd.print("0");
    if (day_X < 10)
      lcd.print("0");
      lcd.print(day_X);

      if (button == btnRIGHT)    {
        timedBeep(shortBeep,1);

        lcd.setCursor(0,0);
        lcd.print("Day X Set for");
        delay(500);
        lcdClear();
        return;      
      }
      else    {
        timerCancelled("Day X");
        lcdClear();
        return;  
      }  
  }    
}
 

void setDateTime()    {
  int button = 0;

  //get month
  int setMonth = getTimerMinutes("Set Month", lastMonth, 12);
  if (setMonth > 0 && setMonth < 13)    {

    int setDay = getTimerMinutes("Set Day", lastDay, 31);
    if (setDay > 0 && setDay < 32)    {
      //get year
      int setYear = getTimerMinutes("Set Year", lastYear, 2999);
      if (setYear > 2000 && setYear < 3000)    {
        //get hour
//        int thisHour = lastHour;
//        int setHour = getTimerMinutes("Set Hour", thisHour, 23);
        int setHour = getTimerMinutes("Set Hour", lastHour, 23);
        if (setHour >= 0 && setHour < 24)    {
          //get minutes
          int setMinute = getTimerMinutes("Set Minute", lastMinute, 59);
          if (setMinute < 60)    {
            lcdClear();
            lcd.setCursor(0,1);
          //display alarm time
            lcd.print(setHour);
            lcd.print(":");
          if (setMinute < 10)
            lcd.print("0");
            lcd.print(setMinute);

            if (button == btnRIGHT)    {
              timedBeep(shortBeep,1);
              RTC.adjust(DateTime(setYear,setMonth,setDay,setHour,setMinute));                //прописываем дату и время в модуль реал-тайм
              //RTC.adjust(DateTime(2013,9,24,17,37));                //прописываем дату и время в модуль реал-тайм

              lcd.setCursor(0,0);
              lcd.print("Saving...");
              delay(500);
              lcdClear();
              return;      
            }
            else    {
              timerCancelled("");
              return;  
            }  
          }
          else    {
            timerCancelled("");    
          }    
        }    
        else    {
          timerCancelled("");      
        }
      }
      else    {
        timerCancelled("");    
      }    
    }    
    else    {
      timerCancelled("");      
    }
  }
  else    {
    timerCancelled("");      
  }
}
 

// read the buttons
int read_LCD_buttons()    {
  adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  if (adc_key_in < 50)  return btnRIGHT; 
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;  
  return btnNONE;  // when all others fail, return this...

}


int getTimerMinutes(char timerText[], int startNum, int maxCount)    {
  int minutes = startNum;
  int button = 0;
  lcdClear();
  lcd.print(timerText);
  lcd.setCursor(0,1);
  lcd.print(minutes);

  while (button != btnLEFT)    {
    button = read_LCD_buttons();
    Serial.println(button);

/*    if (button == btnLEFT)    {
      if ((minutes + 10) <= maxCount)    {
        timedBeep(shortBeep,1);
        minutes = minutes + 10;
      }
      else    {
        timedBeep(shortBeep,2); 
      }
    }
*/
    if (button == btnUP)    {
      if (minutes < maxCount)    {
        timedBeep(shortBeep,1);
        minutes++;
      }
      else    {
        timedBeep(shortBeep,2); 
      }
    }
    if (button == btnDOWN)    {
      if (minutes > 0)    {
        timedBeep(shortBeep,1);
        minutes--;
      }
      else    {
        timedBeep(shortBeep,2); 
      }  
    } 
    if (button == btnSELECT)    {
      timedBeep(shortBeep,1);
      return minutes; 
    }
    lcd.setCursor(0,1);
    lcd.print(minutes); 
    lcd.print("  ");
  }
  return 0;
}


void timedBeep(int beepTime, int beepCount)  {
  for (int i = 0; i < beepCount; i ++)    {
    digitalWrite(beeper, HIGH);
    delay(beepTime);
    digitalWrite(beeper, LOW);
    delay(beepTime);
  }
}

void lcdClear()    {
  resetClock = true;
  lcd.clear();
  lcd.begin(16,2);
  lcd.setCursor(0,0); 
}


void timerCancelled(char message[])    {
  lcdClear();
  lcd.print(message);
  lcd.print(" Cancelled");
  timedBeep(shortBeep,3);    
}

P.S. В листинге некоторые форумчане могут заметить части своих кодов)) За что им отдельная благодарность!

ales2k
Offline
Зарегистрирован: 25.02.2013

Нужно перезайти в среду разработки

AndyResh
Offline
Зарегистрирован: 08.04.2013

...так ведь несколько раз это делал, пока переименовывал то в FAR'e, то показалось, что что-то с кодировкой внутри библиотек, то перебирал варианты с шапкой: #include <i2ceeprom.h> или #include 'i2ceeprom.h" (DHT у меня только так заработал), и каждый раз рестартил IDE.

Если какая-то банальность или моя невнимательность - придется застрелиться))

А так, может подскажете в каком направлении копать дальше, вроде и в более сложные вопросы приходилось вникать, а тут..?

maksim
Offline
Зарегистрирован: 12.02.2012
//#include <i2ceeprom.h> 


void setup() 
{
....
тыры пыры
....
}

void loop()
{
....
тыры пыры
....
}



void i2c_eeprom_write_block( byte deviceaddress, unsigned int eeaddress, void* data, unsigned int length ) {
  const byte* current = reinterpret_cast<const byte*>(data);
  unsigned int c;
  for ( c = 0; c < length; c++)
  {
    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.write(*current++);
    Wire.endTransmission();
    eeaddress++;
    delay(20);
  }
}


// maybe let's not read more than 30 or 32 bytes at a time!
void i2c_eeprom_read_buffer( byte deviceaddress, unsigned int eeaddress, void *buffer, byte length ) {
  byte* current = reinterpret_cast<byte*>(buffer);
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8)); // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,(byte)length);
  int c = 0;
  for ( c = 0; c < length; c++ )
    if (Wire.available())  *current++ = Wire.read(); 
}

 

AndyResh
Offline
Зарегистрирован: 08.04.2013

О Боже! Что за волшебство?!

С конструкцией

//#include <i2ceeprom.h> 

int current_day = 0      // сюда записываем текущий день
int day_X = 0            // день на который приходится базовая длина дня с базовым времинем включения

struct DATA       // Cтруктура
 {
 int curDay;
 int xDay;
 };

void setup() 
{
....

// Чтение
 DATA data_R;
 // Заполняем data_R из ЕЕПРОМ
 i2c_eeprom_read_buffer(0x50, 0, &data_R, sizeof(data_R));
 // Присваиваем переменным
 current_day = data_R.curDay;
 day_X = data_R.xDay;

....
}

void loop()
{
....
тыры пыры
....
}


void eerprom_write() {

 // Запись
 DATA data_W;
 // заполняем
 data_W.curDay = current_day;
 data_W.xDay = day_X;
 // Сохраняем
 i2c_eeprom_write_block(0x50, 0, &data_W, sizeof(data_W)); 
 delay(10); 

}


void eerprom_read() {

 // Чтение
 DATA data_R;
 // Заполняем data_R из ЕЕПРОМ
 i2c_eeprom_read_buffer(0x50, 0, &data_R, sizeof(data_R));
 // Присваиваем переменным
 current_day = data_R.curDay;
 day_X = data_R.xDay;

}

void i2c_eeprom_write_block( byte deviceaddress, unsigned int eeaddress, void* data, unsigned int length ) {
 const byte* current = reinterpret_cast<const byte*>(data);
 unsigned int c;
 for ( c = 0; c < length; c++)
 {
 Wire.beginTransmission(deviceaddress);
 Wire.write((int)(eeaddress >> 8)); // MSB
 Wire.write((int)(eeaddress & 0xFF)); // LSB
 Wire.write(*current++);
 Wire.endTransmission();
 eeaddress++;
 delay(20);
 }
}


// maybe let's not read more than 30 or 32 bytes at a time!
void i2c_eeprom_read_buffer( byte deviceaddress, unsigned int eeaddress, void *buffer, byte length ) {
 byte* current = reinterpret_cast<byte*>(buffer);
 Wire.beginTransmission(deviceaddress);
 Wire.write((int)(eeaddress >> 8)); // MSB
 Wire.write((int)(eeaddress & 0xFF)); // LSB
 Wire.endTransmission();
 Wire.requestFrom(deviceaddress,(byte)length);
 int c = 0;
 for ( c = 0; c < length; c++ )
 if (Wire.available())&nbsp; *current++ = Wire.read(); 
}

 

все заработало, точнее - откомпелилось.

Проверить на железе нет возможности от RTC до МЕГИ нога отвалилась, а на работе паяльник непредусмотрен должностью))

Вечером отпишусь, как устраню железный баг.

chk
Offline
Зарегистрирован: 14.04.2013

Почитал даташит на еепром этот, там написано что можно писать страницами до 32 байт. глядя на реализацию этого дела, становится понятно, что оно будет пошустрее, чем если писать каждый байт по отдельности - как минимум, не надо передавать в еепром каждый раз адрес. да и отправка адреса устройства по i2c тоже время занимает. Функция записи блока, которая тут валяется вместе с остальными, записывает побайтно из этого блока в еепром. Можно модифицировать. Пока лишь сделал набросок проверочный, может сегодня доделаю и полностью готовый вариант. Как оказалось, можно записать так только 30 байт. Наверно 32 имелось в виду вместе с байтами адреса, которых 2. но в даташите это описали как 32 байта данных. ну и пох. После завершения этой функции надо обождать чуток, я ждал 50мс перед проверочным чтением. Может хватит и 20.

void i2c_eeprom_write_page(byte deviceaddress, unsigned int eeaddress, void* data, unsigned int length)
{
  const byte* current = reinterpret_cast<const byte*>(data);
  unsigned int c;
  
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8)); // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  
  for ( c = 0; c < length; c++)
  {
    Wire.write(*current++);
  }
  Wire.endTransmission();
}

Причем при записи 32 значений последние 2 не записываются, но и не происходит переполнения и записи с начала текущей страницы. Почему так - не знаю.

Если из функции записи блока для каждых 30 байт записывать постранично - будет намного быстрее. Тк помимо прочего еще и delay(20) или около того не нужен после записи каждого байта.

Сделал функцию, но почему-то хрень она записывает. Если размер блока 30 - еще норм. если больше - происходит ерунда. Даже с задержкой в секунду между записями страниц. Есть у кого идеи?

#define PAGE_SIZE 30
void i2c_eeprom_write_block_page(byte deviceaddress, unsigned int eeaddress, void* data, unsigned int length)
{
  const byte* current = reinterpret_cast<const byte*>(data);
  unsigned int bytes_written, page_pos, addr;
  boolean f = true;
  
  bytes_written = 0;
  
  while(f)
  {
   if (length - bytes_written <= PAGE_SIZE) 
     {
       page_pos = length - bytes_written;  f=false;
     }
   else 
     {
       page_pos = PAGE_SIZE;  
     } 
    
   addr = eeaddress + bytes_written;
   
      Wire.beginTransmission(deviceaddress);
      Wire.write((int)(addr >> 8)); // MSB
      Wire.write((int)(addr & 0xFF)); // LSB
  
      for (unsigned int c = 0; c < page_pos; c++)
      {
        Wire.write(*current++);
      }
      Wire.endTransmission();
      delay(1000);
      
   bytes_written += page_pos;   
  }    
}

Здесь какой-то код есть, тоже со страничной записью, но возможно там просто ограничили длину записываемой последовательности, мне так показалось. Чето там немного мудреное для меня, кому интересно посмотрите. Так-то по уму надо заменить цикл с Wire.Write(*data) на Wire.Write(*data, count), но вряд ли это что-то исправит. ночью проверю

http://forum.arduino.cc/index.php?topic=90594.0

AndyResh
Offline
Зарегистрирован: 08.04.2013

Баг железный устранил, однако работать, как планировалось, программа на стала. При запуске дисплей чистый, на кнопки реагирует, по меню ходит, но текущий день (current_day), день Икс (day_X), а так же дата с RTC выглядели ужастно. Так текущий день подгрузился 1501 (неадекватный параметр натолкнул на мысль, что ячейки на EEPROM RTC были заведомо не пусты); дата не отображалась, а при попытке забить ее вручную из меню, писала, что сохранилась, но по факту этого не происходило.

Курю код дальше.

chk
Offline
Зарегистрирован: 14.04.2013

Код по ссылке рабочий. Но каким образом работает там функция записи страницами - никак не пойму. может кто пояснить? там же адрес отправляется один и тот же..

все, дошло. там они этот аргумент функции меняют как переменную в теле функции.... я к такому как-то не привык, не заметил даже. ну примерно ясно теперь. кроме & ~  () вот этого.

так что обновите свой функционал! и задержку можно поискать вместо 50 какую поменьше можно поставить, наверно.

pkv
Offline
Зарегистрирован: 20.08.2013

нашел, все-таки нужную тему..

Пробую добавить библиотеку:

#include <WProgram.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <DS1307.h>
#include <i2ceeprom.h>

Скачут ошибки: 

C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp: In member function 'void i2ceeprom::i2c_eeprom_write_byte(byte, unsigned int, byte)':
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:9: error: 'class TwoWire' has no member named 'write'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:10: error: 'class TwoWire' has no member named 'write'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:11: error: 'class TwoWire' has no member named 'write'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp: In member function 'void i2ceeprom::i2c_eeprom_write_block(byte, unsigned int, void*, unsigned int)':
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:22: error: 'class TwoWire' has no member named 'write'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:23: error: 'class TwoWire' has no member named 'write'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:24: error: 'class TwoWire' has no member named 'write'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp: In member function 'byte i2ceeprom::i2c_eeprom_read_byte(byte, unsigned int)':
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:33: error: 'class TwoWire' has no member named 'write'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:34: error: 'class TwoWire' has no member named 'write'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:37: error: 'class TwoWire' has no member named 'read'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp: In member function 'void i2ceeprom::i2c_eeprom_read_buffer(byte, unsigned int, void*, byte)':
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:45: error: 'class TwoWire' has no member named 'write'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:46: error: 'class TwoWire' has no member named 'write'
C:\Program Files (x86)\arduino-0022\libraries\i2ceeprom\i2ceeprom.cpp:51: error: 'class TwoWire' has no member named 'read'

Что не так?..

ales2k
Offline
Зарегистрирован: 25.02.2013

Помоему у тебя какието проблемы с библиотекой <Wire.h>, попробуй обновить...

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

Потому что IDE у него лохматой 0022 версии.

pkv
Offline
Зарегистрирован: 20.08.2013

maksim пишет:

Потому что IDE у него лохматой 0022 версии.

Максим, а где взять свежее ? Что-то весь сайт перерыл, там только Arduino 1.0.5 и Arduino 1.5.6-r2...

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

с обозначениями у них беда, но 1.0.5 и есть более новая, чем 0022 :)