8x8 led matrix via RTC DS1302

catcher
Offline
Зарегистрирован: 03.09.2020

Доброго времени суток. Пытаюсь заставить работать матрицу через модуль rtc. В приложенном коде rtc модуль не отвечает. выдает в сериал порт одни нули. Знаю что есть какой то подвох в этом коде, но не понимаю где. Прошу помощи в поиски проблемы.

 

#include <iarduino_RTC.h>
const byte clk = 7;
const byte cdata = 6;
const byte rst = 5;
const byte data_pin = PD2;
const byte st_pin = PD3;
const byte sh_pin = PD4;
iarduino_RTC time(RTC_DS1302,clk,cdata,rst);
unsigned long tm, next_flick, next_switch;
const unsigned int to_flick = 1000;
const unsigned long to_switch = 1000000;

byte line = 0;
byte frame = 0;

const byte data[10][8] = {
{ 0b01111100,
  0b10000010,
  0b10000010,
  0b10000010,
  0b10000010,
  0b10000010,
  0b10000010,
  0b01111100
},
{ 0b00000000,
  0b00100000,
  0b01100000,
  0b10100000,
  0b00100000,
  0b00100000,
  0b00100000,
  0b11111000
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b00000010,
  0b01111100,
  0b10000000,
  0b10000010,
  0b01111100 
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b00000010,
  0b01111100,
  0b00000010,
  0b10000010,
  0b01111100 
},
{ 0b00000000,
  0b10000010,
  0b10000010,
  0b10000010,
  0b01111110,
  0b00000010,
  0b00000010,
  0b00000010
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b10000000,
  0b01111100,
  0b00000010,
  0b10000010,
  0b01111100
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b10000000,
  0b11111100,
  0b10000010,
  0b10000010,
  0b01111100
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b00000100,
  0b00001000,
  0b00010000,
  0b00100000,
  0b01000000
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b10000010,
  0b01111100,
  0b10000010,
  0b10000010,
  0b01111100
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b10000010,
  0b01111110,
  0b00000010,
  0b10000010,
  0b01111100
},
};

void latchOn(){
    digitalWriteFast(st_pin, HIGH); 
    digitalWriteFast(st_pin, LOW);
}

void fill( byte d ){
    for(char i=0; i<8; i++){
        digitalWriteFast(sh_pin, LOW);
        digitalWriteFast(data_pin, d & (1<<i));
        digitalWriteFast(sh_pin, HIGH);
    }
}

void setPinFast(byte pin){
    DDRD |= _BV(pin);
}

void digitalWriteFast(byte pin, byte zod){
    if( zod )
        PORTD |= _BV(pin);
    else
        PORTD &= ~_BV(pin);
}

void clock()
  {
    if(millis()%1000==0){
    Serial.println(time.gettime("d-m-y, H:i:s, D"));
    delay(100);
    }
  }

void setup() {
    setPinFast(data_pin);
    setPinFast(st_pin);
    setPinFast(sh_pin);
    setPinFast(cdata);
    Serial.begin(9600);
    time.begin();
}

void loop() {
    tm = micros();
    if( tm > next_flick ){
        next_flick = tm + to_flick;
        line++;
        if( line == 8 )
            line = 0;
        fill( ~(1<<(7-line)) );
        fill( data[frame][7-line] );
        latchOn();
    }
    tm = micros();
    if( tm > next_switch ){
        next_switch = tm + to_switch;
        //frame = !frame;
        frame++;
        if (frame == 10)
        frame=0;
    }
 clock();
}

 

b707
Offline
Зарегистрирован: 26.05.2017

а вы в этом коде хоть строчку понимаете? - я вот нет...

Помоему тут код от RTC и код от матриц вообще не связан

catcher
Offline
Зарегистрирован: 03.09.2020

Изначально был код для матрицы.

После добавил код для rtc (Функция void clock) и вывожу ее в функции void loop().

Если по отдельности загружать их в ардуино, коды работают.

Но вот как связать, не могу сообразить.

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

Отдельно он у Вас работает? Закомменируйте строки 151-168 и посмотрите, работают ли часы. Отпишитесь. Если нет, то пока не заставите работать, не расскоментируйте - не валите все ошибки в одну кучу.

Пока же я вижу, что она и не должна работать, хотя точно сказать без схемы соединений нельзя. У Вас перепутан порядок указания пинов в вызове конструктора в строке №8 (если, конечно, пины названы именно так, как соединены)

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А я вообще не понимаю зачем  подпрограмма clock() нужна. Обращаемся к ней 1 раз так и писать в тексте программы. Понимаю - ООП, но логика быть должна ИМХО.

catcher
Offline
Зарегистрирован: 03.09.2020

Все верно, так не работало. переписал без функции void clock

 

void setup() {
    setPinFast(data_pin);
    setPinFast(st_pin);
    setPinFast(sh_pin);
    delay(300);
    Serial.begin(9600);
    time.begin();
}

void loop() {
    tm = micros();
    if( tm > next_flick ){
        next_flick = tm + to_flick;
        line++;
        if( line == 8 )
            line = 0;
        fill( ~(1<<(7-line)) );
        fill( data[frame][7-line] );
        latchOn();
    }
    tm = micros();
    if( tm > next_switch ){
        next_switch = tm + to_switch;
        //frame = !frame;
        frame++;
        if (frame == 10)
        frame=0;
    }
if(millis()%1000==0){                                  
      Serial.println(time.gettime("d-m-Y, H:i:s, D"));
      delay(1);
    }
}

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

catcher
Offline
Зарегистрирован: 03.09.2020

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

Если конечно от этого есть смысл. Но пока не попробуешь не поймешь )))

catcher
Offline
Зарегистрирован: 03.09.2020

Разобрался как функцию написать!

catcher
Offline
Зарегистрирован: 03.09.2020

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

Отдельно он у Вас работает? Закомменируйте строки 151-168 и посмотрите, работают ли часы. Отпишитесь. Если нет, то пока не заставите работать, не расскоментируйте - не валите все ошибки в одну кучу.

Пока же я вижу, что она и не должна работать, хотя точно сказать без схемы соединений нельзя. У Вас перепутан порядок указания пинов в вызове конструктора в строке №8 (если, конечно, пины названы именно так, как соединены)

 

Евгений, спасибо что указали направление проблемы )))

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

catcher пишет:

Все верно, так не работало. переписал без функции void clock

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

Я Вам говорил сделать совсем другое.

Во-вторых, всегда выкладывайте полный код! Сейчас Вы просто потеряли время, т.к. Вам тут же вопрос - Вы поменяли порядок пинов о котором я Вам писал?

catcher
Offline
Зарегистрирован: 03.09.2020

catcher пишет:

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

Отдельно он у Вас работает? Закомменируйте строки 151-168 и посмотрите, работают ли часы. Отпишитесь. Если нет, то пока не заставите работать, не расскоментируйте - не валите все ошибки в одну кучу.

Пока же я вижу, что она и не должна работать, хотя точно сказать без схемы соединений нельзя. У Вас перепутан порядок указания пинов в вызове конструктора в строке №8 (если, конечно, пины названы именно так, как соединены)

 

Евгений, спасибо что указали направление проблемы )))

Сделал вот так:

 

int clock()
  {
    if(millis()%1000==0){                                  
      int a = Serial.println(time.gettime("d-m-Y, H:i:s, D"));
      delay(1);
      return(a);
    }
}

void setup() {
    setPinFast(data_pin);
    setPinFast(st_pin);
    setPinFast(sh_pin);
    delay(300);
    Serial.begin(9600);
    time.begin();
}

void loop() {
    tm = micros();
    if( tm > next_flick ){
        next_flick = tm + to_flick;
        line++;
        if( line == 8 )
            line = 0;
        fill( ~(1<<(7-line)) );
        fill( data[frame][7-line] );
        latchOn();
    }
    tm = micros();
    if( tm > next_switch ){
        next_switch = tm + to_switch;
        //frame = !frame;
        frame++;
        if (frame == 10)
        frame=0;
    }
clock();
}

И все работает )

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

catcher пишет:

Сделал вот так:

И все работает )

Второй раз Вам говорю (третьего не будет): всегда выкладывайте полный код здесь нет конструктора time и ничего не понятно.

Кроме того, насчёт "всё работает" - это Вам так кажется. Тут очевидных ошибок вагон и они будут иногда проявляться, а Вы будете считать их "случайными глюками".

catcher
Offline
Зарегистрирован: 03.09.2020

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

catcher пишет:

Сделал вот так:

И все работает )

Второй раз Вам говорю (третьего не будет): всегда выкладывайте полный код здесь нет конструктора time и ничего не понятно.

Кроме того, насчёт "всё работает" - это Вам так кажется. Тут очевидных ошибок вагон и они будут иногда проявляться, а Вы будете считать их "случайными глюками".

Евгений, ок приложу переделанный вариант:

#include <iarduino_RTC.h>
const byte data_pin = PD2;
const byte st_pin = PD3;
const byte sh_pin = PD4;
iarduino_RTC time(RTC_DS1302, 8, 10, 9);
unsigned long tm, next_flick, next_switch;
const unsigned int to_flick = 1000;
const unsigned long to_switch = 1000000;

byte line = 0;
byte frame = 0;

const byte data[10][8] = {
{ 0b01111100,
  0b10000010,
  0b10000010,
  0b10000010,
  0b10000010,
  0b10000010,
  0b10000010,
  0b01111100
},
{ 0b00000000,
  0b00100000,
  0b01100000,
  0b10100000,
  0b00100000,
  0b00100000,
  0b00100000,
  0b11111000
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b00000010,
  0b01111100,
  0b10000000,
  0b10000010,
  0b01111100 
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b00000010,
  0b01111100,
  0b00000010,
  0b10000010,
  0b01111100 
},
{ 0b00000000,
  0b10000010,
  0b10000010,
  0b10000010,
  0b01111110,
  0b00000010,
  0b00000010,
  0b00000010
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b10000000,
  0b01111100,
  0b00000010,
  0b10000010,
  0b01111100
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b10000000,
  0b11111100,
  0b10000010,
  0b10000010,
  0b01111100
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b00000100,
  0b00001000,
  0b00010000,
  0b00100000,
  0b01000000
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b10000010,
  0b01111100,
  0b10000010,
  0b10000010,
  0b01111100
},
{ 0b00000000,
  0b01111100,
  0b10000010,
  0b10000010,
  0b01111110,
  0b00000010,
  0b10000010,
  0b01111100
},
};

void latchOn(){
    digitalWriteFast(st_pin, HIGH); 
    digitalWriteFast(st_pin, LOW);
}

void fill( byte d ){
    for(char i=0; i<8; i++){
        digitalWriteFast(sh_pin, LOW);
        digitalWriteFast(data_pin, d & (1<<i));
        digitalWriteFast(sh_pin, HIGH);
    }
}

void setPinFast(byte pin){
    DDRD |= _BV(pin);
}

void digitalWriteFast(byte pin, byte zod){
    if( zod )
        PORTD |= _BV(pin);
    else
        PORTD &= ~_BV(pin);
}

int clock()
  {
    if(millis()%1000==0){
      time.gettime();                                  
      int a = time.seconds;
      delay(0);
      return(a);
    }
}

void setup() {
    setPinFast(data_pin);
    setPinFast(st_pin);
    setPinFast(sh_pin);
    delay(300);
    time.begin();
}

void loop() {
    tm = micros();
    if( tm > next_flick ){
        next_flick = tm + to_flick;
        line++;
        if( line == 8 )
            line = 0;
        fill( ~(1<<(7-line)) );
        fill( data[frame][7-line] );
        latchOn();
    }
    tm = micros();
    if( tm > next_switch ){
        next_switch = tm + to_switch;
        //frame = !frame;
        frame++;
        if (frame == 10)
        frame=0;
    }
clock();
}

Полностью код. Прошу тогда указать на ошибки. Данный код выполняет перебор цифр от 0 до 9 согласно заданной матрице, через 1 секунду, использую функцию micros. Функция Clock просто высчитывает секунды.

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

Судя по всему Вы таки исправили порядок пинов в конструкторе, только не признаётесь :-)

Приём, использованный в строках №150-151 (и в строках №160-161) будет приводить к глюкам примерно каждый час, когда значение micros будет переполняться и начинаться с нуля. Эти глюки я и мел в виду, когда говорил, "Вы будете думать, что они случайны". К сделать правильно см. тему

И, да, строки №№134-136 заменяются одной 

return time.seconds;

catcher
Offline
Зарегистрирован: 03.09.2020

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

Судя по всему Вы таки исправили порядок пинов в конструкторе, только не признаётесь :-)

Приём, использованный в строках №150-151 (и в строках №160-161) будет приводить к глюкам примерно каждый час, когда значение micros будет переполняться и начинаться с нуля. Эти глюки я и мел в виду, когда говорил, "Вы будете думать, что они случайны". К сделать правильно см. тему

И, да, строки №№134-136 заменяются одной 

return time.seconds;

Евгений, все верно, я тоже думал в эту сторону, поэтому и решил использовать rtc.

А что касается пинов, я просто удалил константы которые были заданы выше и да, изменил порядок в объявлении rtc. Так как не сразу понял, какой идет порядок, если сейчас правильно понял, то там указывается в таком порядке: rst, clk, data.

catcher
Offline
Зарегистрирован: 03.09.2020

return time.seconds; 

Спасибо!

b707
Offline
Зарегистрирован: 26.05.2017

catcher, вы что сделать-то пытаетесь? если я правильно понял, вы подключаете RTC для того, чтобы заменить микрос? - звучит бредово

catcher
Offline
Зарегистрирован: 03.09.2020

b707 пишет:

catcher, вы что сделать-то пытаетесь? если я правильно понял, вы подключаете RTC для того, чтобы заменить микрос? - звучит бредово

На данном этапе я изучаю саму ардуино, сам язык Си, кодинг (как культурное явление) и модули возможные.

Поэтому прошу строго не судить, так я еще чайник в этих вопросах, но тема очень интересна.

Цель кода: заставить переключать значения на матрице через каждые 10 секунд используя модуль rtc.

Сам RTC мне нужен будет в другом проекте, пока я просто пытаюсь слепить что-нибудь из того что есть )

b707
Offline
Зарегистрирован: 26.05.2017

catcher пишет:

Цель кода: заставить переключать значения на матрице через каждые 10 секунд используя модуль rtc.

Сам RTC мне нужен будет в другом проекте, пока я просто пытаюсь слепить что-нибудь из того что есть )

если речь о таких интервалах. как 10 секунд - почему используется микрос? Почему не миллис?

catcher
Offline
Зарегистрирован: 03.09.2020

millis() уже использовал, я же говорю изучаю )))).

Теперь хочу попробовать с rtc )

Исходя из имеющегося кода, есть мысли как это оформить? ))

b707
Offline
Зарегистрирован: 26.05.2017

catcher пишет:

Исходя из имеющегося кода, есть мысли как это оформить? ))

у меня? - конечно нет, это же ваш код

catcher
Offline
Зарегистрирован: 03.09.2020

хорошо, тогда сам.

Но если появятся мысли, буду благодарен )

SLKH
Offline
Зарегистрирован: 17.08.2015

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

Судя по всему Вы таки исправили порядок пинов в конструкторе, только не признаётесь :-)

Приём, использованный в строках №150-151 (и в строках №160-161) будет приводить к глюкам примерно каждый час, когда значение micros будет переполняться и начинаться с нуля. Эти глюки я и мел в виду, когда говорил, "Вы будете думать, что они случайны". К сделать правильно см. тему

И, да, строки №№134-136 заменяются одной 

return time.seconds;

а это if(millis()%1000==0) будет исполняться тогда, когда ему захочется. а не захочет - не будет.

catcher
Offline
Зарегистрирован: 03.09.2020

а это if(millis()%1000==0) будет исполняться тогда, когда ему захочется. а не захочет - не будет.

А с чем это связанно, можете пояснить?

b707
Offline
Зарегистрирован: 26.05.2017

catcher пишет:

а это if(millis()%1000==0) будет исполняться тогда, когда ему захочется. а не захочет - не будет.

А с чем это связанно, можете пояснить?

это условие сработает только если вы проверите миллис ровно в 1000 мс. А если хотя бы на одну мс опоздаете - то все, ждите еще 1000мс до следующего раза.

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

SLKH
Offline
Зарегистрирован: 17.08.2015

b707 пишет:

catcher пишет:

а это if(millis()%1000==0) будет исполняться тогда, когда ему захочется. а не захочет - не будет.

А с чем это связанно, можете пояснить?

это условие сработает только если вы проверите миллис ровно в 1000 мс. А если хотя бы на одну мс опоздаете - то все, ждите еще 1000мс до следующего раза.

и есть вероятность, что оно сработает через много часов или дней.

catcher
Offline
Зарегистрирован: 03.09.2020

b707 пишет:

catcher пишет:

а это if(millis()%1000==0) будет исполняться тогда, когда ему захочется. а не захочет - не будет.

А с чем это связанно, можете пояснить?

это условие сработает только если вы проверите миллис ровно в 1000 мс. А если хотя бы на одну мс опоздаете - то все, ждите еще 1000мс до следующего раза.

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

 

Спасибо за полезную информацию, буду иметь ввиду.