Garbage reading from Chronodot 2nd time around??

First of all, if I am posting this in the wrong forum, I apologize. (This is so complicated and weird I don't know where to post it!)

The attached photograph shows what I have for a clock so far, rats' nest of wires and all. It uses:

  • An Arduino (of course)
  • Four display units of the kind Adafruit Industries describe as "16x24 Red LED Matrix Panel - Chainable HT1632C Driver" and sell as item #555
  • A Chronodot (for battery backup for the time, and for once-a-minute time checks)
  • A button for setting the time and selecting display modes
  • A speaker for chiming the hours: it's a 16-ohm speaker which I put in series with a 100-ohm resistor
  • The rat's nest of wires you see in the photo
  • A 5V 2A power supply (Adafruit item #276)

The problem I have is really weird.
The Arduino is supposed to read the time from the Chronodot at startup, and again once a minute (you can see the scheduling for this in the code for the clock, which I have attached).
If you look at the grabTime() function in my code, you will see that it rejects garbage times. When I start the Arduino up, it uses grabTime() to read the Chronodot, and reads it all right (you can see today's date in the photo). But then what happens is really weird. It has to do with the once-a-minute checks.
If I have the Arduino hooked up to my laptop, there is no problem: it keeps merrily counting seconds, and you can even see the break in rhythm from the adjustments. But when I disconnect it from the laptop so that it has only the power from the power supply, grabTime() won't work for the once-a-minute checks. (It will, however, work on power-up.)
In my code, you can see these lines:

      else if ((small_unit == 111) && (sync_prep == true)) {
        if (grabTime()) {
          sync_prep = false;
          updateTime = true;
        }
        // else mode = crazy_mode;
      }

That line that I commented out, I did because that was the only way to get the clock to run for more than a minute or two without the laptop. Now it's running well... except that the resynchronization is presumably not working, so I expect drift.

What do you suggest? (Keeping the clock connected to the laptop is sadly not an option.)

bclock_with_rtc_t4.ino (44.8 KB)

  Wire.write(0x0E); // select register
  Wire.write(0b00011100); // write register bitmap, bit 7 is /EOSC

Why do you set the control register to this value? You are setting the INTCN bit which generates an interrupt flag on an alarm match but you don't use the interrupt and appear to be polling the clock. The other two bits have no effect anyway.
Just set the control register to zero and see if that helps.

Pete

el_supremo:
Just set the control register to zero and see if that helps.

It doesn't help.

I notice that the displays are significantly brighter when I have the laptop connected than when I don't.
Maybe not enough juice? I would think that 5 volts 2 amps would be enough juice but maybe not... And why would it be causing this specific effect? Strange...

Sounds like a power problem. When you first read the time, the display is off, hence the power is suffiecient to communicate with the RTC. Afterwards, your display is on, using a LOT of power, giving you all kind of problems. If the display is brighter when you're connected your computer, you have a real power problem.

Try with a bigger power supply 4 Amps or more.

// Per.

It doesn't help.

OK, but my question still stands. Why were you setting the register to 0b00011100 ?

And:

  while(Wire.available())
  { 
    // get components of the time 
    rss = Wire.read();
    rmi = Wire.read();
    rhh = Wire.read();
    rwd = Wire.read();
    rdd = Wire.read();
    rmo = Wire.read();
    ryy = Wire.read();
  }

this won't work. You are reading seven bytes when you are only guaranteed that there is at least one.

Pete

Zapro:
Sounds like a power problem.

Well, according to the folks I got the power supply from, it should have enough juice.
The relevant discussion is here: http://forums.adafruit.com/viewtopic.php?f=47&t=37293

el_supremo:

Just set the control register to zero and see if that helps.

It doesn't help.

OK, but my question still stands. Why were you setting the register to 0b00011100 ?

Because I'm dumb when it comes to hardware. That and that's what it said to do here:
http://docs.macetech.com/doku.php/chronodot

My apologies. I didn't read the code properly. The Wire.requestFrom which precedes that while loop does ask for seven bytes. However, you don't need to read the seven bytes in a while loop and I suspect that the while might cause problems because if the first byte isn't immediately available between the .requestFrom and .available, the loop won't be executed at all and that will foul things up.
Try it without the while loop:

  // get components of the time 
  rss = Wire.read();
  rmi = Wire.read();
  rhh = Wire.read();
  rwd = Wire.read();
  rdd = Wire.read();
  rmo = Wire.read();
  ryy = Wire.read();

I'd suggest that you still zero the status register because you aren't using the alarm interrupts.

Pete

I did some reading.

Firstly, I read about the Wire library, and changed this

while(Wire.available())

to this (or something similar)

if (Wire.available() >= 7)

and it runs (at least the first time).

Second: I read about the Arduino's power requirements, and as it turns out, yes, it is a power problem, but it has nothing to do with amps: I was supplying the wrong voltage (only 5 volts) to the Arduino!

(Please, Adafruit, get your act together!)

It's not exactly adafruit's fault if you connected +5 to Vin and didn't have enough voltage. You could connect the +5V from your power supply to the +5V pin on the arduino, but there seems to be some irrational fear of doing that around here. I say it's irrational because the same "dangerous" situation (reverse bias on the 5V regulator) exists when you power the board from the USB. You could supply the +5V from the supply to BOTH Vin and +5V on the board, this will prevent the on-board regulator from being reverse biased.

if (Wire.available() >= 7)

That has the same problem as using the while loop. If there aren't at least 7 bytes available then you don't read any of them.

Pete

afremont:
It's not exactly adafruit's fault if you connected +5 to Vin and didn't have enough voltage.

Well... the power supply which Adafruit sold me ends in this round thingy which really only fits in one place on the Arduino and doesn't connect to anything "normal" (wires, breadboard holes) anywhere.

I am not happy.

You could connect the +5V from your power supply to the +5V pin on the arduino, but there seems to be some irrational fear of doing that around here. I say it's irrational because the same "dangerous" situation (reverse bias on the 5V regulator) exists when you power the board from the USB. You could supply the +5V from the supply to BOTH Vin and +5V on the board, this will prevent the on-board regulator from being reverse biased.

I have another power supply lying around. It's this big heavy brick thingy with these screw-on thingies to hold the wires in place. I think I'll give it a try.

Ok, I got you. On the big supply, it sounds like it's probably 12V so hook it to Vin. DO NOT HOOK ANYTHING LARGER THAN 5V TO THE +5V PIN. Sorry to yell, but I want to make sure you see that. Bypassing the regulator could lead to great damage if you make a mistake. Anything over +5V is going to be putting things at serious risk.

The big supply is literally as well as figuratively a "black box".

Apparently, it was something from ages ago when I was at college, so I suppose it was for ye olde discrete logic chips, and if I remember correctly, those used 5 volts.

Well... it works now -- sort of, as long as the display isn't too "busy". Now I have it on a low power display mode which only shows 4 digits at a time, and those at the lowest possible brightness. But in a brighter, busier mode, I get display glitches and intermittent bad Chronodot reads.

When I'm not feeling so tired / lazy, what I think I'll do is this: only read the Chronodot once a day, around 04:15. In preparation for this, blank the display at 04:14 -- this will make things easier on the power supply for when I read the Chronodot. Once I have the new time, maybe wait a second or two before displaying it.

None of this should be happening. By any chance are you trying to run the LED displays from the Arduino's regulated 5V?

Do you have adequate decoupling for those LED displays - they need a lot, you may be getting interference
from the display if decoupling is poor and/or the wiring layout isn't nice and tight (run all the wires to the display close together to prevent open loops).

[ oh, and most importantly don't share ground wires between chronodot and the LEDs, thats bound to be bad news. Run ground and power separately to each and keep them apart. ]