Задать вопрос
seregareal2
@seregareal2

Где ошибка в коде?

все же почти приспособил Arduino к аквариуму, но есть одна проблемма с ds3231, время ведет себя хаотично, то выдает 78 - 89 секунд, то 753 секунды

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

9dfbf7ff8636401380336ad9cec0c9bb.jpgВот видео работы

Сам код

#include <OneWire.h>       //DS18B20
#include <Wire.h>         // For the i2c devices
#include <LiquidCrystal_I2C.h>  // For the LCD


//Для установки времени
//#include <iarduino_RTC.h>    //Для установки времени
//iarduino_RTC time(RTC_DS1307);  //Для установки времени



// LOW   реле включено
// HIGH   реле выключено

LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

#define DS3231_I2C_ADDRESS 104    // RTC is connected, address is Hex68 (Decimal 104)

// SCL - pin A5
// SDA - pin A4
// To set the clock, run the sketch and use the serial monitor.
// Enter T1124154091014; the code will read this and set the clock. See the code for full details.
//
byte seconds, minutes, hours, day, date, month, year;
char weekDay[4];

byte tMSB, tLSB;

// float my_temp; //Переменная для хранения показания температуры с DS3231

char my_array[100];            // Character array for printing something.

OneWire ds(2); // на пине 2 (нужен резистор 4.7 КОм) (DS18B20)


void setup()
{
 
  Wire.begin();
  lcd.init();                      // initialize the lcd

    //time.begin();
    //time.settime(0,59,8,7,11,16,1);  // 0  сек, 51 мин, 21 час, 27, октября, 2015 года, вторник



//Выходы реле

/* Пока ничего нет
pinMode(2, OUTPUT); //Пусто
pinMode(3, OUTPUT); //Пусто
*/


pinMode(4, OUTPUT); //Лента
pinMode(7, OUTPUT); //Мотор


}

void loop()
{
  //watchConsole();


//(DS18B20)

byte data[2];
ds.reset();
ds.write(0xCC);
ds.write(0x44);
delay(750);
ds.reset();
ds.write(0xCC);
ds.write(0xBE);
data[0] = ds.read();
data[1] = ds.read();
int Temp = (data[1]<< 8)+data[0];
Temp = Temp>>4;
//Serial.println(Temp);


// Вывод даты в сериал порт (Проверка времени + температура)

  get3231Date();

/*
  Serial.print(weekDay); Serial.print(", "); Serial.print(date, DEC); Serial.print("/"); Serial.print(month, DEC);
  Serial.print("/"); Serial.print(year, DEC); Serial.print(" - ");
  Serial.print(hours, DEC); Serial.print(":"); Serial.print(minutes, DEC); Serial.print(":"); Serial.print(seconds, DEC);
*/


  // my_temp = (float)get3231Temp();
  // Serial.print(" - Temp: ");
  // Serial.println(my_temp);

  // NOTE: Arduino does NOT implement printing floats to a string.
  // If you use the std C function : sprintf(my_array, "Temp: %4.2f", my_temp), It will NOT CONVERT.
  // So I abandoned this, since I don't need to print the float to the LCD anyway.

//Для таймера


//Мотор

if ( Temp >= 28 )
{
  digitalWrite(7, LOW);
}
else
{
  digitalWrite(7, HIGH);
}


//Лента

if ( hours >= 9 && hours <= 22 ) //В 9 утра включить, в 22 00 выключить
{
  digitalWrite(4, LOW);
}
else
{
  digitalWrite(4, HIGH);
}



 
sprintf(my_array, "Time: %d-%d-%d", hours, minutes, seconds);

// Print a message to the LCD.
  lcd.backlight();  //Включение подсветки
  lcd.setCursor(0,0); //Курсор в нулевую строку
  lcd.print(Temp); //Тект на экране - Температура с DS18B20
  lcd.print(" Temp in akva");
  lcd.setCursor(0,1); //Курсор в 1 строку
  lcd.print(my_array); //Вывод времени
  delay(1000);
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}


/*
void watchConsole()
{
  if (Serial.available()) {      // Look for char in serial queue and process if found
    if (Serial.read() == 84) {      //If command = "T" Set Date
      set3231Date();
      get3231Date();
      Serial.println(" ");
    }
  }
}
*/



void set3231Date()
{
//T(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year)
//T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99)
//Example: 02-Feb-09 @ 19:57:11 for the 3rd day of the week -> T1157193020209
// T1124154091014
  seconds = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result. 
  minutes = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  hours   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  //day     = (byte) (Serial.read() - 48);
  //date    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  //month   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  //year    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0x00);
  Wire.write(decToBcd(seconds));
  Wire.write(decToBcd(minutes));
  Wire.write(decToBcd(hours));
  //Wire.write(decToBcd(day));
  //Wire.write(decToBcd(date));
  //Wire.write(decToBcd(month));
  //Wire.write(decToBcd(year));
  Wire.endTransmission();
}


void get3231Date()
{
  // send request to receive data starting at register 0
  Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
  Wire.write(0x00); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes

  if(Wire.available()) {
    seconds = Wire.read(); // get seconds
    minutes = Wire.read(); // get minutes
    hours   = Wire.read();   // get hours
    // day     = Wire.read();
    //date    = Wire.read();
    //month   = Wire.read(); //temp month
    //year    = Wire.read();
      
    seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111)); // convert BCD to decimal
    minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111)); // convert BCD to decimal
    hours   = (((hours & B00110000)>>4)*10 + (hours & B00001111)); // convert BCD to decimal (assume 24 hour mode)
    //day     = (day & B00000111); // 1-7
    //date    = (((date & B00110000)>>4)*10 + (date & B00001111)); // 1-31
    //month   = (((month & B00010000)>>4)*10 + (month & B00001111)); //msb7 is century overflow
    //year    = (((year & B11110000)>>4)*10 + (year & B00001111));
  }
  else {
    //oh noes, no data!
  }

/* //Для кормушки, не работать в воскресение (Пока не реализованно)
  switch (day) {
    case 1:
      strcpy(weekDay, "Sun");
      break;
    case 2:
      strcpy(weekDay, "Mon");
      break;
    case 3:
      strcpy(weekDay, "Tue");
      break;
    case 4:
      strcpy(weekDay, "Wed");
      break;
    case 5:
      strcpy(weekDay, "Thu");
      break;
    case 6:
      strcpy(weekDay, "Fri");
      break;
    case 7:
      strcpy(weekDay, "Sat");
      break;
  }

*/

}


//Температурный датчик встроенный в часы (Пока не нужен)

/*
float get3231Temp()
{
  float temp3231;
 
  //temp registers (11h-12h) get updated automatically every 64s
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0x11);
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 2);
  if(Wire.available()) {
    tMSB = Wire.read(); //2's complement int portion
    tLSB = Wire.read(); //fraction portion
  
    temp3231 = (tMSB & B01111111); //do 2's math on Tmsb
    temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8
  }
  else {
    //oh noes, no data!
  }
  
  return temp3231;
}
*/
  • Вопрос задан
  • 359 просмотров
Подписаться 1 Оценить 1 комментарий
Пригласить эксперта
Ответы на вопрос 1
Попробуйте это же в терминал слать.
Есть подозрение, что с часов все отлично, а вот на дисплее шлак остается висеть ибо ширина строки меняется для случаев:
18-47-57
19-5-4    // а вот тут может остаться шлак в виде 57

Надо чистить строку перед записью / делать вывод BCD-кода / принудительно добавлять нули для жесткого формата хх-хх-хх

______
Кстати, вроде можно настроить форматирование для чисел на выводе сразу, только уже не помню как.
Что-то типо такого первое под руку попало:
printf ("\n2.5 Вывод числа 123 с заданной шириной 6 символов:\n");
 {
int d1=123;
   printf ("%6d\n",d1);
 }


___________
Глянул видео - именно то, о чем я и написал. Старые цифры остаются. :)
sprintf(my_array, "Time: %2d-%2d-%2d", hours, minutes, seconds);
попробуй, может так сожрет.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы