More Efficient Code Help

For my project, I am reading the hour and minute of the DS3231 RTC. The hour and time are in "now.minute()" and "now.hour()". I need to go from those variables to digitalWrites on output pins. The following code works, but is very inefficient. (Note that my output actually needs to be the inverse of the BCD digital value in those variables - ie "0000" is actually "HIGH-HIGH-HIGH-HIGH".) If I used this method, I would have 60 entries for minutes and 12 entries for hours. There has to be a slicker way to do this. Any suggestions?

  // Minutes :00 => 0000 0000
  if(now.minute() == 0){
  digitalWrite(0, HIGH);
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  }

// Minutes :01 => 0000 0001
  if(now.minute() == 1){
  digitalWrite(0, LOW);
  digitalWrite(1, HIGH);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  }

// Minutes :02 => 0000 0010
  if(now.minute() == 2){
  digitalWrite(0, HIGH);
  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  }

// Minutes :03 => 0000 0011
  if(now.minute() == 3){
  digitalWrite(0, LOW);
  digitalWrite(1, LOW);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, HIGH);
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);
  }

Maybe:
https://forum.arduino.cc/t/executing-multiple-commands-with-1-command/628681/5

Also from the darkages:
https://forum.arduino.cc/t/controlling-multiple-pins-at-the-same-time/88013/2

Added:
As you did not indicate the Arduino uC you are working on, procedures for port writing is uC specific; however this post goes into what would be necessary.
https://forum.arduino.cc/t/portd-on-due/341743/5

What does this mean? Is it too slow?
Paul

Ha... I always say, "working" code is "good" code; which I guess translates to a very negative view on non-working code. But ....
I suspect the Op is looking for something like writing all output drivers on a single PIO port with one command.

Once your program is working, go on to the next program. If you ever have spare time, then go back and rework the first program. Very little can be learned by spending weeks on an old program. The human brain likes NEW stuff!
Paul

I had a typo in my first post. Fixed now.

By inefficient, I meant that the code was very long to write, and seemed a little too brute force. Speed was not really a factor. I also found that this approach is subject to typos.

Direct port manipulation was something I was looking at, but what I was really hoping would work is something like this:

// Write Minutes
digitalWrite(0, now.minute(0));
digitalWrite(1, now.minute(1));
digitalWrite(2, now.minute(2));
digitalWrite(3, now.minute(3));
digitalWrite(4, now.minute(4));
digitalWrite(5, now.minute(5));
digitalWrite(6, now.minute(6));
digitalWrite(7, now.minute(7));

IF you do this, you code is locked into a specific microcontroller IC. Your way, right now will run on most any Arduino.
Paul

Lots of ways to do it... could use a 2D array to hold the BCD values, like this:

uint8_t pins [10][4] = {1, 1, 1, 1,  // 0
                        1, 1, 1, 0,  // 1
                        1, 1, 0, 1,  // 2
                        1, 1, 0, 0,  // 3
                        1, 0, 1, 1,  // 4
                        1, 0, 1, 0,  // 5
                        1, 0, 0, 1,  // 6
                        1, 0, 0, 0,  // 7
                        0, 1, 1, 1,  // 8
                        0, 1, 1, 0}; // 9


void setup()
{
  Serial.begin(115200);
  while (!Serial);
}

void loop()
{
  for (uint8_t hour = 0; hour < 24; hour++)
  {
    uint8_t h_tens = hour / 10;
    uint8_t h_ones = hour % 10;

    for (uint8_t minute = 0; minute < 60; minute++)
    {
      uint8_t m_tens = minute / 10;
      uint8_t m_ones = minute % 10;

      Serial.print(h_tens);
      Serial.print(h_ones);
      Serial.print(":");
      Serial.print(m_tens);
      Serial.println(m_ones);

      Serial.print(pins[h_tens][0]);
      Serial.print(pins[h_tens][1]);
      Serial.print(pins[h_tens][2]);
      Serial.print(pins[h_tens][3]);
      Serial.print(" ");
      Serial.print(pins[h_ones][0]);
      Serial.print(pins[h_ones][1]);
      Serial.print(pins[h_ones][2]);
      Serial.print(pins[h_ones][3]);
      Serial.print(" ");
      Serial.print(pins[m_tens][0]);
      Serial.print(pins[m_tens][1]);
      Serial.print(pins[m_tens][2]);
      Serial.print(pins[m_tens][3]);
      Serial.print(" ");
      Serial.print(pins[m_ones][0]);
      Serial.print(pins[m_ones][1]);
      Serial.print(pins[m_ones][2]);
      Serial.println(pins[m_ones][3]);

      delay(50);
    }
  }

  delay(5000);
}

Just replace the Serial.print with digitalWrite.

Or something like this 6hTdBq - Online C++0x Compiler & Debugging Tool - Ideone.com

Also note that the DS3231 date/time registers are already BCD, it's the library that you use that converts to decimal. You could edit or extend the library to avoid doing this useless conversion.. :wink:

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