Помогите пожалуйста со скетчем

Тема в разделе "Arduino & Shields", создана пользователем Игорь2016, 27 окт 2016.

Метки:
  1. Игорь2016

    Игорь2016 Нерд

    Плата mega2560, часы реального времени ds3231, индикатор tm1637.Код взял в теме "
    Arduino uno часы с температурой на DS3231 и дисплее TM1637".
    отличные получились часы код может кому и пригодится отдельное спасибо Tomasina за помощь в написании кода.

    #include <Wire.h>
    #include "TM1637.h"

    #define DS1307_I2C_ADDRESS 0x68

    #define CLK 2
    #define DIO 3

    TM1637 tm1637(CLK,DIO);

    ///// часы ..
    byte decToBcd(byte val){
    return((val/10*16)+(val%10));
    }

    byte bcdToDec(byte val){
    return((val/16*10)+(val%16));
    }

    void setDateDs1307(byte second, // 0-59
    byte minute, // 0-59
    byte hour, // 1-23
    byte dayOfWeek, // 1-7
    byte dayOfMonth, // 1-28/29/30/31
    byte month, // 1-12
    byte year)// 0-99
    {
    Wire.beginTransmission(DS1307_I2C_ADDRESS);
    Wire.write(0);
    Wire.write(decToBcd(second));
    Wire.write(decToBcd(minute));
    Wire.write(decToBcd(hour));
    Wire.write(decToBcd(dayOfWeek));
    Wire.write(decToBcd(dayOfMonth));
    Wire.write(decToBcd(month));
    Wire.write(decToBcd(year));
    Wire.endTransmission();
    }

    void getDateDs1307(byte *second,
    byte *minute,
    byte *hour,
    byte *dayOfWeek,
    byte *dayOfMonth,
    byte *month,
    byte *year)
    {

    Wire.beginTransmission(DS1307_I2C_ADDRESS);
    Wire.write(0);
    Wire.endTransmission();

    Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

    *second = bcdToDec(Wire.read()&0x7f);
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read()&0x3f);
    *dayOfWeek = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month = bcdToDec(Wire.read());
    *year = bcdToDec(Wire.read());
    }

    float get3231Temp(){
    byte tMSB, tLSB;
    float temp3231;

    Wire.beginTransmission(0x68);
    Wire.write(0x11);
    Wire.endTransmission();
    Wire.requestFrom(0x68, 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;
    }
    /////////////////

    void setup(){
    Wire.begin();
    tm1637.init();
    tm1637.set(4);// яркость, от 0 до 7

    /* // установка часов
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    second = 0;
    minute = 59;
    hour = 21;
    dayOfWeek = 1; // день недели
    dayOfMonth = 11; // день
    month = 4;
    year = 16;

    setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
    */

    }

    void loop(){
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    byte temp = get3231Temp();
    int8_t TimeDisp[4];
    // вывод температуры .. каждые 10 сек на 2 сек
    if(second >=0&& second <=1||
    second >=10&& second <=11||
    second >=20&& second <=21||
    second >=30&& second <=31||
    second >=40&& second <=41||
    second >=50&& second <=51)
    {
    tm1637.point(POINT_OFF);// выключаем точки
    TimeDisp[0]=19;//
    TimeDisp[1]= temp /10;// заполняем массив
    TimeDisp[2]= temp %10;
    TimeDisp[3]=12;// C

    }
    /* // дата else if(second >= 25 && second <= 26 || second >= 45 && second <= 46) { tm1637.point(POINT_OFF); TimeDisp[0] = dayOfMonth / 10; TimeDisp[1] = dayOfMonth % 10; TimeDisp[2] = month / 10; TimeDisp[3] = month % 10; }*/
    /// часы
    else
    {
    tm1637.point(POINT_ON);// включаем точки
    TimeDisp[0]= hour /10;
    TimeDisp[1]= hour %10;
    TimeDisp[2]= minute /10;
    TimeDisp[3]= minute %10;
    }
    tm1637.display(TimeDisp);// отправляем массив на экран
    }


    Но почему то на индикаторе выводит "45:-5" и ни чего не моргает и не движется. До этого пробовал другие скетчи, там было "45: 5" без черточки. Библиотеки все стоят. В программировании очень слабо. Помогите пожалуйста найти ошибку.
     
  2. fogary

    fogary Гик

    Код (C++):
    byte temp = get3231Temp();
    Функция get3231Temp() возвращает тип float, а Вы его в byte пишите. Нехорошо.

    Почему бы немного не изменить текст и вместо:
    Код (C++):
    // вывод температуры .. каждые 10 сек на 2 сек
    if(second >=0&& second <=1||
    second >=10&& second <=11||
    second >=20&& second <=21||
    second >=30&& second <=31||
    second >=40&& second <=41||
    second >=50&& second <=51)
    {
      tm1637.point(POINT_OFF);// выключаем точки
      TimeDisp[0]=19;
      TimeDisp[1]= temp /10;// заполняем массив
      TimeDisp[2]= temp %10;
      TimeDisp[3]=12;// C
    }
    написать так:
    Код (C++):
    // вывод температуры .. каждые 10 сек на 2 сек
    if(second % 10 <= 1)
    {
      tm1637.point(POINT_OFF);// выключаем точки
      TimeDisp[0]=19;
      TimeDisp[1]= temp /10;// заполняем массив
      TimeDisp[2]= temp %10;
      TimeDisp[3]=12;// C
      tm1637.display(TimeDisp);
      delay(2000);
    }
    Время из часов читается правильное?
     
    Последнее редактирование: 27 окт 2016
  3. Tomasina

    Tomasina Сушитель лампочек Модератор

    хм, как-то не припомню своего участия :cool:
     
  4. Игорь2016

    Игорь2016 Нерд

     
    Tomasina нравится это.
  5. Игорь2016

    Игорь2016 Нерд



    Спасибо. Все заработало. И часы и температура. Ошибка была в питании реального времени (нужно 3,3в) и в самом подключении. (scl sda). Код оставил прежний. На этом вылазит ошибка 'TimeDisp' is not captured и замирает температура (не переключается на часы)
    Хотелось бы программно уменьшить температуру. Показывает 29С,а реально 24С.
     
  6. fogary

    fogary Гик

    Максимальное допустимое напряжение питания для DS3231 - 5.5 В. Так что, скорее всего, дело было не в питании.

    Что бы уменьшить значение температуры с 29 до 24:
    Код (C++):
    byte temp = get3231Temp();
    temp -= 5;
    По поводу ошибок, если интересно, попробуйте так (убрал неиспользуемый код):
    Код (C++):
    #include <Wire.h>
    #include "TM1637.h"

    #define DS3231_I2C_ADDRESS 0x68

    #define CLK 2
    #define DIO 3

    TM1637 tm1637(CLK,DIO);

    byte bcdToDec(byte val) {
      return((val / 16 * 10) + (val % 16));
    }

    void getDateDs3231(byte *second, byte *minute, byte *hour) {
      Wire.beginTransmission(DS3231_I2C_ADDRESS);
      Wire.write(0);
      Wire.endTransmission();
      Wire.requestFrom(DS3231_I2C_ADDRESS, 7);  *second = bcdToDec(Wire.read() & 0x7f);
      *minute = bcdToDec(Wire.read());
      *hour = bcdToDec(Wire.read() & 0x3f);
    }

    float get3231Temp() {
      byte tMSB, tLSB;
      float temp3231;

      Wire.beginTransmission(DS3231_I2C_ADDRESS);
      Wire.write(0x11);
      Wire.endTransmission();
      Wire.requestFrom(DS3231_I2C_ADDRESS, 2);
      if(Wire.available()){
        tMSB = Wire.read();
        tLSB = Wire.read();
        temp3231 = (tMSB & B01111111);
        temp3231 += ((tLSB >> 6) * 0.25);
      }
      return temp3231;
    }


    void setup() {
      Wire.begin();
      tm1637.init();
      tm1637.set(4);
    }

    void loop() {
      byte second, minute, hour;
      byte TimeDisp[4];

      getDateDs3231(&second, &minute, &hour);
      if (second % 10 <= 1) {
        byte temp = get3231Temp();
        tm1637.point(POINT_OFF);    TimeDisp[0] = 19;
        TimeDisp[1] = temp / 10;
        TimeDisp[2] = temp % 10;
        TimeDisp[3] = 12;
        tm1637.display(TimeDisp);
        delay(1000);
      } else {
        tm1637.point(POINT_ON);
        TimeDisp[0]= hour / 10;
        TimeDisp[1]= hour % 10;
        TimeDisp[2]= minute / 10;
        TimeDisp[3]= minute % 10;
        tm1637.display(TimeDisp);
      }
      delay(1000);
    }
    Протестировал с выводом в Serial, все работает.
     
  7. Игорь2016

    Игорь2016 Нерд


    Что то у меня ошибка выползает "call of overloaded 'display(byte [4])' is ambiguous"
     
  8. Игорь2016

    Игорь2016 Нерд

    С коррекцией температуры все заработало. Спасибо.
     
  9. fogary

    fogary Гик

    Извиняюсь, мой огрех. В функции loop() вместо "byte TimeDisp[4];" должно быть "int8_t TimeDisp[4];".

    Кстати, в таком виде: "byte temp = get3231Temp();" в переменную будет записываться только целая часть значения температуры, а дробная будет отброшена. Если хотите округлять температуру до целого числа, то надо так: "byte temp = round(get3231Temp());"
     
    Последнее редактирование: 1 ноя 2016
  10. Игорь2016

    Игорь2016 Нерд


    Все заработало. Спасибо. Одно но. Питаю я пока от usb. Если отключить питание,почему то пока не нажмешь сброс на плате,часы не запускаются. Индикатор вообще не горит.Либо повторно скетч выгружаешь,тогда работать начинает.