Problem sending data 4 7 digit with clock

Hello,

I’m already sorry for my mistakes, I’m french.

I got a code on the internet to link my digit (4 digit of 7 bytes) with my clock DS1307 V03, and my problem is, the first number of the clock (for example 10h23m, he’ll take 1 for the all digit), so I’ve checked the code for trying to figure it out, I think the problem is due to the transmission, right here :

void sendSerialData (byte registerCount, byte *pValueArray) {
  // Signal to the 595s to listen for data
  digitalWrite (g_pinCommLatch, LOW);

  for (byte reg = registerCount; reg > 0; reg--)
  {
    byte value = pValueArray [reg - 1];

    for (byte bitMask = 128; bitMask > 0; bitMask >>= 1)
    {
      digitalWrite (g_pinClock, LOW);
      digitalWrite (g_pinData, value & bitMask ? HIGH : LOW);
      digitalWrite (g_pinClock, HIGH);
    }
  }
  // Signal to the 595s that I'm done sending
  digitalWrite (g_pinCommLatch, HIGH);
}  // sendSerialData

And here the full code :

#include <Wire.h>                
#include "RTClib.h"              
const int  g_pinData = 8;       
const int  g_pinCommLatch = 9;  
const int  g_pinClock = 10;              

RTC_DS1307 RTC;                  // define RTC variables

byte g_digits [7];             // Definitions of the 7-bit values for displaying digits

int g_numberToDisplay = 0;      // default number being displayed, 0 

const int g_registers = 4;      // Number of shift registers in use, 4

byte g_registerArray [g_registers]; // Array of numbers to pass to shift registers


void setup()
{
   // I2C RTC Setup
   Wire.begin();
   RTC.begin();
   
  /*  Only set the time on compile if the RTC is not running...
  This is used to set the current time from the computer clock
  
  if ( !RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  */

  pinMode (g_pinCommLatch, OUTPUT);       // define 74595 pins as output
  pinMode (g_pinClock, OUTPUT);           // define 74595 pins as output
  pinMode (g_pinData, OUTPUT);            // define 74595 pins as output
  
  Serial.begin (9600);                    // optional, turn on serial monitoring for debugging

  // Setup 7 segment display for number 0 to 9 and other characters
  
  // a - top bar
  // b - top right
  // c - bottom right
  // d - bottom bar
  // e - bottom left
  // f - top right
  // g - middle bar
  
  int a = 1, b = 2, c = 4, d = 8, e = 16, f = 32, g = 64;

  g_digits [0] = a + b + c + d + e + f;
  g_digits [1] = b + c;
  g_digits [2] = a + b + g + e + d;
  g_digits [3] = a + b + g + c + d;
  g_digits [4] = f + g + b + c;
  g_digits [5] = a + f + g + c + d;
  g_digits [6] = a + f + g + c + d + e;
  g_digits [7] = a + b + c;
  g_digits [8] = a + b + c + d + e + f + g;
  g_digits [9] = a + b + c + d + g + f;
  g_digits [90] = a + b + g + f;           // Degree dot
  g_digits [91] = a + f + e + d;           // Capital C
  g_digits [92] = e + g;                   //  r, 80
  g_digits [93] = f + e + g + c;           //  h, 116
  
  g_digits [99] = 0;
  
    
  
} // End of setup() //

// Simple function to send serial data to one or more shift registers by iterating backwards through an array.
// Although g_registers exists, they may not all be being used, hence the input parameter.

void sendSerialData (byte registerCount, byte *pValueArray) {
  // Signal to the 595s to listen for data
  digitalWrite (g_pinCommLatch, LOW);

  for (byte reg = registerCount; reg > 0; reg--)
  {
    byte value = pValueArray [reg - 1];

    for (byte bitMask = 128; bitMask > 0; bitMask >>= 1)
    {
      digitalWrite (g_pinClock, LOW);
      digitalWrite (g_pinData, value & bitMask ? HIGH : LOW);
      digitalWrite (g_pinClock, HIGH);
    }
  }
  // Signal to the 595s that I'm done sending
  digitalWrite (g_pinCommLatch, HIGH);
}  // sendSerialData

// ======================  Main loop() ======================= 

void loop()
{
  int hour,minute,disp= 0;
   DateTime now = RTC.now();  // Get current time & date

   hour = now.hour();         // break down time to hour
   minute = now.minute();     // break down time to minute
  
  /* Serial output debugging for the date & time 
  
   Serial.print(now.year(), DEC);
   Serial.print('/');
   Serial.print(now.month(), DEC);
   Serial.print('/');
   Serial.print(now.day(), DEC);
   Serial.print(' ');
 */
   delay(1000);
   Serial.print(hour);
   Serial.print(':');
   Serial.print(minute);
   Serial.println();
  
  
  // Push the hour 2 digits to the left by multiplying 100
  
  disp = (hour * 100) + minute;
   
  // Push the numbers to the four digits
 
  if (disp < 10)
  {
    g_registerArray [0] = g_digits [0];
    g_registerArray [1] = g_digits [0];
    g_registerArray [2] = g_digits [0];
    g_registerArray [3] = g_digits [disp];
  }
  else if (disp < 60)
  {
    g_registerArray [0] = g_digits [0];
    g_registerArray [1] = g_digits [0];
    g_registerArray [2] = g_digits [disp / 10];
    g_registerArray [3] = g_digits [disp % 10];
  }
  else if (disp < 960)
  {
    g_registerArray [0] = g_digits [0];
    g_registerArray [1] = g_digits [disp / 100];
    g_registerArray [2] = g_digits [(disp % 100) / 10];
    g_registerArray [3] = g_digits [disp % 10];
  }
  else
  {
    g_registerArray [0] = g_digits [disp / 1000];
    g_registerArray [1] = g_digits [(disp % 1000) / 100];
    g_registerArray [2] = g_digits [(disp % 100) / 10];
    g_registerArray [3] = g_digits [disp % 10];
  }
  sendSerialData (g_registers, g_registerArray);

} // end of loop

I’m a beginner and I’d glad to make a handmade alarm clock. If you want more photo or other thing, just ask me :slight_smile:

Have a good day !

the first number of the clock (for example 10h23m, he'll take 1 for the all digit)

Sorry, it's not a good enough problem description. Try using Google translate.

byte g_digits [7];             // Definitions of the 7-bit values for displaying digits

.
.
.

  g_digits [0] = a + b + c + d + e + f;
  g_digits [1] = b + c;
  g_digits [2] = a + b + g + e + d;
  g_digits [3] = a + b + g + c + d;
  g_digits [4] = f + g + b + c;
  g_digits [5] = a + f + g + c + d;
  g_digits [6] = a + f + g + c + d + e;
  g_digits [7] = a + b + c;
  g_digits [8] = a + b + c + d + e + f + g;
  g_digits [9] = a + b + c + d + g + f;
  g_digits [90] = a + b + g + f;           // Degree dot
  g_digits [91] = a + f + e + d;           // Capital C
  g_digits [92] = e + g;                   //  r, 80
  g_digits [93] = f + e + g + c;           //  h, 116
 
  g_digits [99] = 0;

.
.
.

You declare g_digits as an array of size 8 (0…7) but write it out to size 100 (0…99)?

Aarg, your message hurts so much xD thanks for telling the truth.
I meant, in fact the messages are probably badly received by the card because if it is 9:34 am, the "digit" will only display 9, if it is 3:56 am, it will only display 3, 11:41 pm, only 1, and so on. And it will not display the next numbers. To explain it better, below there is some picture.

Blackfin, Yes, this is because in the original programme there were other sensors, such as a thermometer. But indeed it is useless here, so I removed it but the problem remains the same. Thanks for the reply.

Aarg, your message hurts so much xD thanks for telling the truth.

It shouldn’t hurt, I’m a language teacher so I know how difficult it is to learn and use a second language. Also from a personal perspective, I’ve been trying to learn a second language for 8 years now, and it’s isn’t getting better very fast. :slight_smile:

The additional detail was tremendously helpful. I’ll have a look.

Regardless of the language, I think you could describe the display better. For example when you say “3:56 am, it will only display 3” there are four digits. So which one of the below do you see?

…3
…3.
.3…
3…
3333
0003
1113

Do you see the confusion?

Also it seems that you now have new code. We can’t guess what it looks like now, so post it and explain whether it works, if not what works/doesn’t work.

@OP, can you clarify:

You circuit shows one shift register but you have four digits.

I don't see anything in your code that indicates you're multiplexing the digits. If you have all the anodes connected to the 595 output and the cathodes all tied together to GND it stands to reason all the digits will show the same thing -- the last digit clocked out to the shift register.

In your case, that's going to be the hours digit.

You need to tie the cathodes to GPIOs and rapidly -- like at 30Hz minimum -- clock out a digit, switch that digit's cathode on, then clock out the next digit, switch its cathode on etc and repeat that indefinitely. You can't have a 1-second delay() in your code; the mux code has to run unimpeded or the digits will flicker.

Response to Aarg :

Oh okay, I'm feeling better :smiley: , we can't really now the meaning of a message (text) after all :).
What language do you learn ?

I can see this one : 3333

And here is my new code (It doesn't works) :

#include <Wire.h>                
#include "RTClib.h"              
const int  g_pinData = 8;       
const int  g_pinCommLatch = 9;  
const int  g_pinClock = 10;              

RTC_DS1307 RTC;                  // define RTC variables

byte g_digits [10];             // Definitions of the 7-bit values for displaying digits

int g_numberToDisplay = 0;      // default number being displayed, 0 

const int g_registers = 4;      // Number of shift registers in use, 4

byte g_registerArray [g_registers]; // Array of numbers to pass to shift registers


void setup()
{
   // I2C RTC Setup
   Wire.begin();
   RTC.begin();
   
  /*  Only set the time on compile if the RTC is not running...
  This is used to set the current time from the computer clock
  
  if ( !RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  */

  pinMode (g_pinCommLatch, OUTPUT);       // define 74595 pins as output
  pinMode (g_pinClock, OUTPUT);           // define 74595 pins as output
  pinMode (g_pinData, OUTPUT);            // define 74595 pins as output
  
  Serial.begin (9600);                    // optional, turn on serial monitoring for debugging

  // Setup 7 segment display for number 0 to 9 and other characters
  
  // a - top bar
  // b - top right
  // c - bottom right
  // d - bottom bar
  // e - bottom left
  // f - top right
  // g - middle bar
  
  int a = 1, b = 2, c = 4, d = 8, e = 16, f = 32, g = 64;

  g_digits [0] = a + b + c + d + e + f;
  g_digits [1] = b + c;
  g_digits [2] = a + b + g + e + d;
  g_digits [3] = a + b + g + c + d;
  g_digits [4] = f + g + b + c;
  g_digits [5] = a + f + g + c + d;
  g_digits [6] = a + f + g + c + d + e;
  g_digits [7] = a + b + c;
  g_digits [8] = a + b + c + d + e + f + g;
  g_digits [9] = a + b + c + d + g + f;
  g_digits [10] = 0;
  
    
  
} // End of setup() //

// Simple function to send serial data to one or more shift registers by iterating backwards through an array.
// Although g_registers exists, they may not all be being used, hence the input parameter.

void sendSerialData (byte registerCount, byte *pValueArray) {
  // Signal to the 595s to listen for data
  digitalWrite (g_pinCommLatch, LOW);

  for (byte reg = registerCount; reg > 0; reg--)
  {
    byte value = pValueArray [reg - 1];

    for (byte bitMask = 128; bitMask > 0; bitMask >>= 1)
    {
      digitalWrite (g_pinClock, LOW);
      digitalWrite (g_pinData, value & bitMask ? HIGH : LOW);
      digitalWrite (g_pinClock, HIGH);
    }
  }
  // Signal to the 595s that I'm done sending
  digitalWrite (g_pinCommLatch, HIGH);
}  // sendSerialData

// ======================  Main loop() ======================= 

void loop()
{
  int hour,minute,disp= 0;
   DateTime now = RTC.now();  // Get current time & date

   hour = now.hour();         // break down time to hour
   minute = now.minute();     // break down time to minute
  
  /* Serial output debugging for the date & time 
  
   Serial.print(now.year(), DEC);
   Serial.print('/');
   Serial.print(now.month(), DEC);
   Serial.print('/');
   Serial.print(now.day(), DEC);
   Serial.print(' ');
 */
   delay(1000);
   Serial.print(hour);
   Serial.print(':');
   Serial.print(minute);
   Serial.println();
  
  
  // Push the hour 2 digits to the left by multiplying 100
  
  disp = (hour * 100) + minute;
   
  // Push the numbers to the four digits
 
  if (disp < 10)
  {
    g_registerArray [0] = g_digits [0];
    g_registerArray [1] = g_digits [0];
    g_registerArray [2] = g_digits [0];
    g_registerArray [3] = g_digits [disp];
  }
  else if (disp < 60)
  {
    g_registerArray [0] = g_digits [0];
    g_registerArray [1] = g_digits [0];
    g_registerArray [2] = g_digits [disp / 10];
    g_registerArray [3] = g_digits [disp % 10];
  }
  else if (disp < 960)
  {
    g_registerArray [0] = g_digits [0];
    g_registerArray [1] = g_digits [disp / 100];
    g_registerArray [2] = g_digits [(disp % 100) / 10];
    g_registerArray [3] = g_digits [disp % 10];
  }
  else
  {
    g_registerArray [0] = g_digits [disp / 1000];
    g_registerArray [1] = g_digits [(disp % 1000) / 100];
    g_registerArray [2] = g_digits [(disp % 100) / 10];
    g_registerArray [3] = g_digits [disp % 10];
  }
  sendSerialData (g_registers, g_registerArray);

} // end of loop

And the only part that I don't understand is here :

void sendSerialData (byte registerCount, byte *pValueArray) {
  // Signal to the 595s to listen for data
  digitalWrite (g_pinCommLatch, LOW);

  for (byte reg = registerCount; reg > 0; reg--)
  {
    byte value = pValueArray [reg - 1];

    for (byte bitMask = 128; bitMask > 0; bitMask >>= 1)
    {
      digitalWrite (g_pinClock, LOW);
      digitalWrite (g_pinData, value & bitMask ? HIGH : LOW);
      digitalWrite (g_pinClock, HIGH);
    }
  }
  // Signal to the 595s that I'm done sending
  digitalWrite (g_pinCommLatch, HIGH);
}  // sendSerialData

Response to Blackfin :

I didn't really understand your message, I'm sorry :3
I don't think I did it this way (about cathodes and anodes).
Let me show you my wiring more clearly with these pics.

Thanks again for your response to both of you ! I'm very glad

I would suggest the problem is your wiring.

  1. You need a 0.1uF cap from pin 16 to Gnd.
  2. You have all the common cathodes "turned on" at the same time.
    You need to cycle thru them, you cannot do that when all are connected to Gnd (via resistor) at the same time.
    The solution is:
    Send out digit A information, connect Digit A common cathode to Gnd. Wait a few mS, disconnect the CC.
    Send out digit B information, connect Digit B common cathode to Gnd. Wait a few mS, disconnect the CC.
    Send out digit C information, connect Digit C common cathode to Gnd. Wait a few mS, disconnect the CC.
    Send out digit D information, connect Digit D common cathode to Gnd. Wait a few mS, disconnect the CC.

Repeat.
Do that by adding a NPN transistor between the resistor and Gnd for each digit, and adapt your code to turn on a transistor for each digit when the segments for that digit are ready for display.
N-channel MOSFETs can also be used.
Or a ULN2003/ULN2803.
Adjust the resistor value to account for the voltage across the transistor:
N-channel MOSFET will have the lowest voltage; NPN transistor will have 0.5V to 0.7V; ULN2003 will have ~1V or more.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.