<?xml version="1.0" encoding="UTF-8"?>        <rss version="2.0"
             xmlns:atom="http://www.w3.org/2005/Atom"
             xmlns:dc="http://purl.org/dc/elements/1.1/"
             xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
             xmlns:admin="http://webns.net/mvcb/"
             xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
             xmlns:content="http://purl.org/rss/1.0/modules/content/">
        <channel>
            <title>
									DroneBot Workshop Forums - Recent Posts				            </title>
            <link>https://forum.dronebotworkshop.com/</link>
            <description>Discussion board for Robotics, Arduino, Raspberry Pi and other DIY electronics and modules. Join us today!</description>
            <language>en-US</language>
            <lastBuildDate>Fri, 11 Sep 2026 13:35:17 +0000</lastBuildDate>
            <generator>wpForo</generator>
            <ttl>60</ttl>
							                    <item>
                        <title>RE: DS3231RTC in combination with 8 MAX7219</title>
                        <link>https://forum.dronebotworkshop.com/project-help/ds3231rtc-in-combination-with-8-max7219/#post-53226</link>
                        <pubDate>Fri, 11 Sep 2026 13:10:57 +0000</pubDate>
                        <description><![CDATA[Don&#039;t know why, but somehow the pictures didn&#039;t show up. So I hope this will work...]]></description>
                        <content:encoded><![CDATA[<p>Don't know why, but somehow the pictures didn't show up. So I hope this will work...</p>
10968
10970
10971]]></content:encoded>
						                            <category domain="https://forum.dronebotworkshop.com/"></category>                        <dc:creator>Michel</dc:creator>
                        <guid isPermaLink="true">https://forum.dronebotworkshop.com/project-help/ds3231rtc-in-combination-with-8-max7219/#post-53226</guid>
                    </item>
				                    <item>
                        <title>RE: What exactly is VCC, 5V or 3V3?</title>
                        <link>https://forum.dronebotworkshop.com/electronic-components/what-exactly-is-vcc-5v-or-3v3/#post-53225</link>
                        <pubDate>Fri, 11 Sep 2026 10:23:43 +0000</pubDate>
                        <description><![CDATA[The chasm between what he does designing CPUs (hundred billions of transistors) and what we do here connecting an MPU development board to a few breakout boards is... the Pacific ocean.  I&#039;v...]]></description>
                        <content:encoded><![CDATA[<p></p>
<p>Tell him my thank you. Now I see it's not just a cakewalk to analyse a circuit diagram <em>completely</em>. It's much more difficult than a P&amp;ID <span>where pressure, temperature and medium define the pipe class, and the flow rate and max flow velocity define the pipe diameter. In circuitry you may even have to consider interspersions, I learned this week.</span></p>
<p></p>
<p>The chasm between what he does designing CPUs (hundred billions of transistors) and what we do here connecting an MPU development board to a few breakout boards is... the Pacific ocean.  I've never looked into something like you're describing:  a simulator or analyzer.  But I can't help thinking there would be something publicly available.  Personally, I use the <em><strong>Smoke, No Smoke Rule</strong></em><em> - </em>If smoke gets out: Bad.  If smoke stays in the chip:  Good.  I buy in bulk and get the discounts.  &#x1f60e; </p>
<p>Seriously though, I didn't really embrace AI, but was kind of forced into it since Google searches now AI summarize everything up front.  At first, I found it surprising how it seemed to consistently get down to the gist of my questions.  Then, I started doing follow up questions and again, it did a far better job than me drilling into some datasheet that would have been two pages down in the old Google search after all the YT videos.  Besides, I was more paranoid about opening some datasheet website, that might have been a re-post instead of the OEM and have hundreds of advertisements... if I was lucky.</p>
<p>Case in point, for my robot, I wanted 40V worth of batteries, MPU: ESP32-S3, two DRV8825 stepper drivers, two stepper motors and a sensitive 6DoF IMU: LSM6DSV.  I needed some step down voltages devices to play with this.  I'd never run anything much above 12V before.  It first suggested some high-end things ($30+ a piece).  I suggested I wanted something cheaper.  It walked me through why the high-end was very good, but that I could get near as good with two different step devices.  One from 40V to 5V that was good enough to run the into the MPU's 5V and a separate 5V to 3.3V to isolate and clean up the noise for the IMU.  Both of which I had in my Smoking Inventory.  It gave me a circuit diagram and everything with all my pieces.  Because I had mentioned I was concerned about all the motors and MPU making too much noise and screwing with the IMU, it included capacitors and resistors to further filter the noise and went into detail about why and how the parts mattered.  Since I had given dimensions, it suggested things like twisting certain bundles of wires and which device would be better to have close versus having long wire runs.  IOW, I learned a lot from that interaction. </p>
<p></p>
<p>In a first approach I would regard it as a <em>physical</em> pendulum with the center of mass above its pivot point -- actually alternating pivots, and almost constatly changing inertia. A nice challenge.</p>
<p></p>
<p><a href="https://forum.dronebotworkshop.com/neural-networks/building-a-neural-network-from-the-ground-up" target="_blank" rel="noopener">https://forum.dronebotworkshop.com/neural-networks/building-a-neural-network-from-the-ground-up</a></p>
<a href="https://forum.dronebotworkshop.com/user-robot-projects/inqster-the-re-awakening" target="_blank" rel="noopener">https://forum.dronebotworkshop.com/user-robot-projects/inqster-the-re-awakening</a>]]></content:encoded>
						                            <category domain="https://forum.dronebotworkshop.com/"></category>                        <dc:creator>Inq</dc:creator>
                        <guid isPermaLink="true">https://forum.dronebotworkshop.com/electronic-components/what-exactly-is-vcc-5v-or-3v3/#post-53225</guid>
                    </item>
				                    <item>
                        <title>DS3231RTC in combination with 8 MAX7219</title>
                        <link>https://forum.dronebotworkshop.com/project-help/ds3231rtc-in-combination-with-8-max7219/#post-53224</link>
                        <pubDate>Fri, 11 Sep 2026 08:57:11 +0000</pubDate>
                        <description><![CDATA[Finally....:-).
After &#039;burning&#039; two Nano&#039;s and a dozen MAX7219 I finally understood how to do proper wiring and coding. Got my self a clock now ;-). It&#039;s all fed by an old iPhone charger wh...]]></description>
                        <content:encoded><![CDATA[<p>Finally....:-).</p>
<p>After 'burning' two Nano's and a dozen MAX7219 I finally understood how to do proper wiring and coding. Got my self a clock now ;-). It's all fed by an old iPhone charger which provides a stable 5V.  Couldn't find an easy connector to connect the displays, so I had to use wiring. If anyone has a  suggestion, that would be very much appreciated.</p>
<p>Now that I understand how I can manipulate the clock output, I will use that knowledge for trend analysis on my first weather station.</p>
<p>Greetings to you all!</p>
<p>&nbsp;</p>
<div>
<div>
<pre contenteditable="false">/*
This small project connects an Arduino Nano to an Adafruit DS3231 Real Time Clock and eight 8x8 LED matrices.
It's basic, no fancy shifting, it just does what it has to do: presenting time.
The DS3231 uses a back-up battery, so you can power it off, keeping its internal clock running.
Once switched on, it immediately shows accurate time.
Power consumption is 350 mW. At 5V input voltage the maximum measured current was never more than 70mA.
However, when powered up, the displays are initialized and most of the LEDS are briefly fired up at maximum intensity.
There might be a considerable power spike especially using eight matrices.
So always connect the matrices to a separte power supply or you will risc blowing up the ports on your Nano.
*/

#include &lt;Wire.h&gt;

#include &lt;DS3231.h&gt;
//Create the clock
DS3231 clock;
RTCDateTime dt;

#include "LedControl.h"
/*Basic set up for eight- 8x8 LED matrices and the MAX 7219 driver.
Pin 12 is connected to DataIn (orange).
Pin 11 is connected to CS (yellow).
Pin 10 is connected to CLK (purple).
Connecting the pins this way implies the same pin order on both the Nano and the LED modules.
For me this implied les 'thinking' (and faults) when wiring the project.
I even glued several jumper wires together for this purpose: orange-yellow-purple.
Works for me :-).
Pay attention when using the LedControl statement, since the expected sequence of the pins is: DataIn, CLK, CS!
'maxDisplay' indicates the number of 8x8 matrices, in this case 8.
*/
const int maxDisplay = 8;
LedControl lc=LedControl(12,10,11,maxDisplay);

//Variables
int baudrate = 9600;
int delayT=500;//Delaytime
int i;

int numDisplay;//Matrix to be switched on /off. The first matrix has number 0.
int intensDisplay=0;//Intensity of the display, even 0 will produce light!
int hour;
int hourdigit1;
int hourdigit2;
int minute;
int minutedigit1;
int minutedigit2;
int second;
int secondOld = 0;//used for convenience: only display new values each second
int seconddigit1;
int seconddigit2;

//Digits normal horizontal orientation
byte arrayDigit=
{
{0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38}, // 0
{0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x18, 0x10}, // 1
{0x00, 0x7C, 0x08, 0x10, 0x20, 0x40, 0x44, 0x38}, // 2
{0x00, 0x38, 0x44, 0x40, 0x30, 0x40, 0x44, 0x38}, // 3
{0x00, 0x20, 0x20, 0x7C, 0x24, 0x28, 0x30, 0x20}, // 4
{0x00, 0x38, 0x44, 0x40, 0x7C, 0x04, 0x04, 0x7C}, // 5
{0x00, 0x38, 0x44, 0x44, 0x3C, 0x04, 0x44, 0x38}, // 6
{0x00, 0x08, 0x08, 0x08, 0x10, 0x20, 0x40, 0x7C}, // 7
{0x00, 0x38, 0x44, 0x44, 0x28, 0x44, 0x44, 0x38}, // 8
{0x00, 0x38, 0x44, 0x40, 0x78, 0x44, 0x44, 0x38} // 9
};

/*
Digits with a separation mark in front of them.
Use these in addition to the normal digits if you want to use six in stead of eight matrices.
Use one of these digits as the first digit for minutes and seconds.
*/
/*
byte arrayDigitSpecial=
{
{0x00, 0x38, 0x44, 0x45, 0x45, 0x44, 0x44, 0x38},
{0x00, 0x38, 0x10, 0x11, 0x11, 0x10, 0x18, 0x10},
{0x00, 0x7C, 0x08, 0x11, 0x21, 0x40, 0x44, 0x38},
{0x00, 0x38, 0x44, 0x41, 0x31, 0x40, 0x44, 0x38},
{0x00, 0x20, 0x20, 0x7D, 0x25, 0x28, 0x30, 0x20},
{0x00, 0x38, 0x44, 0x41, 0x7D, 0x04, 0x04, 0x7C},
{0x00, 0x38, 0x44, 0x44, 0x3D, 0x04, 0x44, 0x38},
{0x00, 0x08, 0x08, 0x09, 0x11, 0x20, 0x40, 0x7C},
{0x00, 0x38, 0x44, 0x45, 0x29, 0x44, 0x44, 0x38},
{0x00, 0x38, 0x44, 0x41, 0x79, 0x44, 0x44, 0x38}
};
*/

/*
Digits vertical orientation, hours on top, seconds at the bottom
Use these digits if you want a vertical clock display

byte arrayDigit=
{
{0x00, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00},
{0x00, 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, 0x00},
{0x00, 0x00, 0x22, 0x41, 0x49, 0x49, 0x36, 0x00},
{0x00, 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, 0x00},
{0x00, 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, 0x00},
{0x00, 0x00, 0x3E, 0x49, 0x49, 0x49, 0x30, 0x00},
{0x00, 0x00, 0x01, 0x71, 0x09, 0x05, 0x03, 0x00},
{0x00, 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, 0x00},
{0x00, 0x00, 0x06, 0x49, 0x49, 0x49, 0x3E, 0x00}
};
*/

/*
Separte separtion marks between hours/minutes and minutes/seconds.
Use the one you like, or create your own.
*/

byte arrayDigitSeparation=
{
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // no separate separtion marks
{0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00}, // one square dot
{0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00} // two square dots
};

void setup()
{
//Start serial monitor
Serial.begin(baudrate);

//Start DS3231
Serial.println("Initialize DS3231");;
clock.begin();

// Set sketch compiling time
//clock.setDateTime(__DATE__, __TIME__);

//Start MAX72XX
for(numDisplay=0; numDisplay&lt;maxDisplay; numDisplay=numDisplay+1)
{
//Wake up MAX7219
lc.shutdown(numDisplay,false);
//Set intensity 0 en 1 are sufficient
lc.setIntensity(numDisplay,intensDisplay);
//Clear display
lc.clearDisplay(numDisplay);
}
delay(delayT);
}

void loop()
{
dt = clock.getDateTime();
hour=dt.hour;
hourdigit1=round(hour/10);
hourdigit2=hour%10;
minute=dt.minute;
minutedigit1=round(minute/10);
minutedigit2=minute%10;
second=dt.second;
seconddigit1=round(second/10);
seconddigit2=second%10;

/*
*/
if(second!=secondOld)
{
secondOld=second;
Serial.print("Raw data: ");
Serial.print(dt.year); Serial.print("-");
Serial.print(dt.month); Serial.print("-");
Serial.print(dt.day); Serial.print(" ");
Serial.print(dt.hour); Serial.print(":");
Serial.print(dt.minute); Serial.print(":");
Serial.print(dt.second); Serial.println("");

//Write values to matrices
writeDigit(hourdigit1,0);
writeDigit(hourdigit2,1);
writeDigitSeparation(2,2);
writeDigit(minutedigit1,3);
writeDigit(minutedigit2,4);
writeDigitSeparation(2,5);
writeDigit(seconddigit1,6);
writeDigit(seconddigit2,7);
}

}

void writeDigit(int j, int m)
{
for(i=0; i&lt;=7; i=i+1)
{
lc.setRow(m,i,arrayDigit);
}
}

//To be used for vertical orientation
/*
void writeDigitSpecial(int j, int m)
{
for(i=0; i&lt;=7; i=i+1)
{
lc.setRow(m,i,arrayDigitSpecial);
}
}
*/

void writeDigitSeparation(int j, int m)
{
for(i=0; i&lt;=7; i=i+1)
{
lc.setRow(m,i,arrayDigitSeparation);
}
}</pre>
</div>
<br /><br /><br /></div>]]></content:encoded>
						                            <category domain="https://forum.dronebotworkshop.com/"></category>                        <dc:creator>Michel</dc:creator>
                        <guid isPermaLink="true">https://forum.dronebotworkshop.com/project-help/ds3231rtc-in-combination-with-8-max7219/#post-53224</guid>
                    </item>
				                    <item>
                        <title>RE: Position Control of dc motor with encoders</title>
                        <link>https://forum.dronebotworkshop.com/user-robot-projects/position-control-of-dc-motor-with-encoders/#post-53223</link>
                        <pubDate>Thu, 10 Sep 2026 23:40:24 +0000</pubDate>
                        <description><![CDATA[@byron 
Getting a free running motorized wheel with encoders to stop at fixed positions like a stepper motor has been a bit of a diversion motivated by the link in the first post.But the co...]]></description>
                        <content:encoded><![CDATA[<p>@byron </p>
<p>Getting a free running motorized wheel with encoders to stop at fixed positions like a stepper motor has been a bit of a diversion motivated by the link in the first post.<br /><br />But the common thread is that it is a goal seeking system. You have an actual state, a desired state and the difference is able to generate an action that reduces that difference as smoothly and on target as possible.<br /><br />When my webcam based robot turns left or right to put the target in center it needs that smooth motor control to prevent and/or correct overshoot. Actually it may not be putting any target in center but using them to plot an ever changing direction based on its current POSE and the desired POSE (Position and Orientation). You may remember the Python math demo using two or more beacons of known positions to compute the POSE of a robot base.</p>
<p>https://forum.dronebotworkshop.com/artificial-intelligence/code-for-using-beacons-for-determing-location/#post-51586</p>
<p>&nbsp;</p>]]></content:encoded>
						                            <category domain="https://forum.dronebotworkshop.com/"></category>                        <dc:creator>robotBuilder</dc:creator>
                        <guid isPermaLink="true">https://forum.dronebotworkshop.com/user-robot-projects/position-control-of-dc-motor-with-encoders/#post-53223</guid>
                    </item>
				                    <item>
                        <title>RE: What exactly is VCC, 5V or 3V3?</title>
                        <link>https://forum.dronebotworkshop.com/electronic-components/what-exactly-is-vcc-5v-or-3v3/#post-53222</link>
                        <pubDate>Thu, 10 Sep 2026 23:26:00 +0000</pubDate>
                        <description><![CDATA[Hi @inq !

Tell him my thank you. Now I see it&#039;s not just a cakewalk to analyse a circuit diagram completely. It&#039;s much more difficult than a P&amp;ID where pressure, temperature and mediu...]]></description>
                        <content:encoded><![CDATA[<p>Hi @inq !</p>
<p>I pinged him and he replied:</p>
<p>Tell him my thank you. Now I see it's not just a cakewalk to analyse a circuit diagram <em>completely</em>. It's much more difficult than a P&amp;ID <span>where pressure, temperature and medium define the pipe class, and the flow rate and max flow velocity define the pipe diameter. In circuitry you may even have to consider interspersions, I learned this week.</span></p>
<p>I'm doing some work on the Physics of a self-balancing robot</p>
<p>In a first approach I would regard it as a <em>physical</em> pendulum with the center of mass above its pivot point -- actually alternating pivots, and almost constatly changing inertia. A nice challenge. But from aeronautics we know, sufficiently powered everything will fly ;)</p>
<p>Your hint, AI may help is hip nowadays. Interestingly the "three best simulators" advertised in <a title="Top 3 Free ESP32 Simulators for 2026" href="https://youtu.be/_HsZzkSYao0" target="_blank" rel="noopener">this clip</a> offer AI support when inserting enough small coins. I still have some AI-aversion, 25% empty words to hide the holes. My thinking is, a factory like JLCPCB likes orders, so they may facilitate defining PCBs they will produce, an in fact they offer such a system <em>for free</em>.</p>
<p>Well, I'm still not in the position to setup a working circuit diagram, currently only the keyboard wiring and the TCA8418 keypad scan device are in rank of 'increased probability'. ESP32-C6 one notch below (would S3 fit better?), display uncertain, battery indefinite. And it's already week 3 of my one-year-only project.</p>]]></content:encoded>
						                            <category domain="https://forum.dronebotworkshop.com/"></category>                        <dc:creator>Amphitryonoff</dc:creator>
                        <guid isPermaLink="true">https://forum.dronebotworkshop.com/electronic-components/what-exactly-is-vcc-5v-or-3v3/#post-53222</guid>
                    </item>
				                    <item>
                        <title>RE: What exactly is VCC, 5V or 3V3?</title>
                        <link>https://forum.dronebotworkshop.com/electronic-components/what-exactly-is-vcc-5v-or-3v3/#post-53221</link>
                        <pubDate>Thu, 10 Sep 2026 12:57:54 +0000</pubDate>
                        <description><![CDATA[Yes, there are such beasts.  My brother-in-law works for such a company that wrote one and sells it to well-healed customers and also contracts its use by in-house engineers to do the work f...]]></description>
                        <content:encoded><![CDATA[<p></p>
<p>Question: when I piece a circuitry together, are there systems apt to check my sketch (computerised sketch of course) for such faults? Which is the best way to prevent wrong voltage mishaps?</p>
<p></p>
<p>Yes, there are such beasts.  My brother-in-law works for such a company that wrote one and sells it to well-healed customers and also contracts its use by in-house engineers to do the work for other companies.  I pinged him and he replied:</p>
<div style="text-align: center"><span style="font-size: 10pt">He works for:  </span><em><span style="font-size: 10pt">"Cadence Design Systems". Previously, "Synopsys". Analysis is a many-colored horse, so to speak, basically lots of different levels of abstraction. Spice is the electrical equivalent of FEA and simulates at the transistor level. On the far other end are things like Verilog behavioral simulation - abstracts a nand-gate into a functional model and then simulates billions of nand-gate equivalents in the same circuit. Verilog is actually a language, kind of equivalent to C or C++, and the simulators are things like VCS (I think that's a Synopsys product), verisim and so on. There are several different levels of abstraction in between those, and different focuses - behavior vs timing for instance. Everything from Synopsys, Cadence and Mentor (Siemens) are commercial products and very expensive. There are open source type options for some of these. There's an org called "open road asic" (iirc) that tries to make a full suite of freeware chip tools available. I have no idea how good or bad those are, but of course they can't be getting the level of software development thrown at them that the big 3 eda companies put in.</span></em></div>
<p>However, I wouldn't be surprised at all if you simply submitted a sketch to an AI (I use both the free versions of Gemini and ChatGPT) that it could answer very specific questions or even say... "No this will not work and here's why..." </p>
<p>I'm doing some work on the Physics of a self-balancing robot and I've sent MP4 videos to illustrate a behavior that was hard to describe.  It was able evaluate a video.  In another case, it used some extensive trig equations to approximate an angle of something.  The value my simulation was settling on was not that angle by about 10%.  I hand sketched it on paper and showed the geometry and Algebra only solution I used that was coming up the same to 5 significant digits.  It admitted my solution was both exact to theory (vs an estimate) and "more elegant" than its solution.  They love to blow sun-shine.  But the point being in this case was that it deciphered my sketch and hand written solution.  </p>
<p>But also, another point... verify, because its not always right, but it might catch something you didn't.</p>
<p><em>Inq</em></p>]]></content:encoded>
						                            <category domain="https://forum.dronebotworkshop.com/"></category>                        <dc:creator>Inq</dc:creator>
                        <guid isPermaLink="true">https://forum.dronebotworkshop.com/electronic-components/what-exactly-is-vcc-5v-or-3v3/#post-53221</guid>
                    </item>
				                    <item>
                        <title>RE: Hi there I am Michel (or Mike) from the Netherlands!</title>
                        <link>https://forum.dronebotworkshop.com/introductions/hi-there-i-am-michel-or-mike-from-the-netherlands/#post-53220</link>
                        <pubDate>Thu, 10 Sep 2026 07:37:29 +0000</pubDate>
                        <description><![CDATA[Got it robotBuilder!I will post the projects upcoming week.Kind regards,Mike]]></description>
                        <content:encoded><![CDATA[<p>Got it robotBuilder!<br />I will post the projects upcoming week.<br />Kind regards,<br />Mike</p>]]></content:encoded>
						                            <category domain="https://forum.dronebotworkshop.com/"></category>                        <dc:creator>Michel</dc:creator>
                        <guid isPermaLink="true">https://forum.dronebotworkshop.com/introductions/hi-there-i-am-michel-or-mike-from-the-netherlands/#post-53220</guid>
                    </item>
				                    <item>
                        <title>RE: I2C pull-up Resistor Calculation</title>
                        <link>https://forum.dronebotworkshop.com/electronic-components/i2c-pull-up-resistor-calculation/#post-53219</link>
                        <pubDate>Thu, 10 Sep 2026 05:44:22 +0000</pubDate>
                        <description><![CDATA[Nope -- slide 31.
&nbsp;]]></description>
                        <content:encoded><![CDATA[<p>Slide 32</p>
<p>Nope -- slide 31.</p>
<p>&nbsp;</p>]]></content:encoded>
						                            <category domain="https://forum.dronebotworkshop.com/"></category>                        <dc:creator>Amphitryonoff</dc:creator>
                        <guid isPermaLink="true">https://forum.dronebotworkshop.com/electronic-components/i2c-pull-up-resistor-calculation/#post-53219</guid>
                    </item>
				                    <item>
                        <title>RE: Ardruino help tocompile code</title>
                        <link>https://forum.dronebotworkshop.com/arduino/ardruino-clock-help-2/paged/2/#post-53218</link>
                        <pubDate>Thu, 10 Sep 2026 02:10:34 +0000</pubDate>
                        <description><![CDATA[&nbsp;
if we can get this code to compile, I can test it on my test clock. If it works, setting clock &amp; the remote works, I would like to add my chime code to it or add the emote code f...]]></description>
                        <content:encoded><![CDATA[<p>&nbsp;</p>
<p>if we can get this code to compile, I can test it on my test clock. If it works, setting clock &amp; the remote works, I would like to add my chime code to it or add the emote code from this one to my code..</p>
<p>&nbsp;</p>
<pre contenteditable="false">/*
Lee's Clock: Hopefully the final revision. 
In order to use the buttons:
    Hold 'set' to adjust the 'minutes' and 'brightness'.
    Press 'set' to change between twelve and twenty four hour time.
    As of right now the 'hours' button doesn't work so i forced the minutes to cycle to the next hour.
    If you hold any of the first three buttons; it will begin to add faster.
    Set the brightness first and then minutes because holding 'set' pauses the clock.
    Make the minutes one higher than the current time and let go of the 'set' button when the time on the standard you are using hits zero seconds.

I advise against putting any battery on the RTC module as it will consistently overcharge
*/

#include &lt;Wire.h&gt;
#include &lt;RTClib.h&gt; 

RTC_DS3231 rtc;

// Shift Register Hardware Pin Definitions
const int reg_clock = 13; // SRCLK
const int reg_latch = 10; // RCLK
const int reg_data  = 11; // SER (Data In)
const int reg_OE    = 9;  // OE (Output Enable - Hardware PWM Control)

// Exact physical pinout matching your custom PCB panel traces
const int btn_bright = 2; // J6 Pin 5 -&gt; Arduino Pin 2
const int btn_min    = 3; // J6 Pin 4 -&gt; Arduino Pin 3 (Minutes Button with Hour Rollover)
const int btn_set    = 5; // J6 Pin 2 -&gt; Arduino Pin 5 (Set Button)

// Common Anode segment patterns (1 = Segment ON / Sink to GND)
const byte digitPatterns[] = {
  0b01111110, // 0
  0b00110000, // 1
  0b01101101, // 2
  0b01111001, // 3
  0b00110011, // 4
  0b01011011, // 5
  0b01011111, // 6
  0b01110000, // 7
  0b01111111, // 8
  0b01111011  // 9
};

// Global Time variables
int hours = 12, minutes = 14, seconds = 0; // Pre-set to 12:14:00 for easy testing
bool is24Hour = false;

// Chime Flags
bool chimeDoneThisMinute = false; 
int lastCheckedMinute = -1;

// Asynchronous Chime Engine State Variables (Zero Delays)
bool introMelodyActive = false;
unsigned long chimeStateTimer = 0;
int strikeCount = 0;
int totalStrikesNeeded = 0;

// Your exact custom active-low brightness PWM levels
const int brightnessPWM[] = {255, 192, 128, 64, 0}; 
int currentBrightStage = 2;

// Non-blocking button and chime tracking state counters
int setHoldCounter = 0;  
int minHoldCounter = 0;  
int rtcRefreshTimer = 0; 
bool setModeActive = false;

// Tracking variables to prevent display lag and electrical noise
int lastDispSec = -1, lastDispMin = -1, lastDispHr = -1;

void updateDisplayRouting() {
  int displayHours = hours;
  bool isPM = (displayHours &gt;= 12);

  if (!is24Hour) {
    displayHours = displayHours % 12;
    if (displayHours == 0) displayHours = 12;
  }
  
  int onesSec = seconds % 10;
  int tensSec = seconds / 10;
  int onesMin = minutes % 10;
  int tensMin = minutes / 10;
  int onesHr  = displayHours % 10;
  int tensHr  = displayHours / 10;
  
  byte seg0 = digitPatterns;
  byte seg1 = digitPatterns;
  byte seg2 = (tensHr == 0) ? 0b00000000 : digitPatterns;
  byte seg3 = digitPatterns;
  byte seg4 = digitPatterns;
  byte seg5 = digitPatterns;
  
  if (setModeActive) {
    seg2 |= 0b10000000; 
    seg3 |= 0b10000000; 
  }
  
  if (!is24Hour &amp;&amp; isPM) {
    seg5 |= 0b10000000; 
  }

  digitalWrite(reg_latch, LOW);
  shiftOut(reg_data, reg_clock, MSBFIRST, seg5); 
  shiftOut(reg_data, reg_clock, MSBFIRST, seg4); 
  shiftOut(reg_data, reg_clock, MSBFIRST, seg3); 
  shiftOut(reg_data, reg_clock, MSBFIRST, seg2); 
  shiftOut(reg_data, reg_clock, MSBFIRST, seg1); 
  shiftOut(reg_data, reg_clock, MSBFIRST, seg0); 
  digitalWrite(reg_latch, HIGH);
}

void readRTC() {
  DateTime now = rtc.now();
  hours = now.hour();
  minutes = now.minute();
  seconds = now.second();
}

// RESTORED: Uses Native Hardware Serial for your pins 0 and 1 connection
void triggerTrack(byte trackNumber) {
  Serial.write((uint8_t)'t'); 
  delayMicroseconds(50); 
  Serial.write((uint8_t)trackNumber); 
}

void checkChimesAsynchronous() {
  if (minutes != lastCheckedMinute) { 
    chimeDoneThisMinute = false; 
    lastCheckedMinute = minutes; 
  }
  
  if (!chimeDoneThisMinute) {
    if (minutes == 15) { 
      triggerTrack(1); 
      chimeDoneThisMinute = true; 
    }
    else if (minutes == 30) { 
      triggerTrack(2); 
      chimeDoneThisMinute = true; 
    }
    else if (minutes == 45) {
      triggerTrack(3);
      chimeDoneThisMinute = true;
    }
    else if (minutes == 0) { 
      triggerTrack(4); // Start hourly intro melody immediately
      introMelodyActive = true;
      chimeStateTimer = millis(); 
      
      totalStrikesNeeded = hours % 12;
      if (totalStrikesNeeded == 0) totalStrikesNeeded = 12;
      strikeCount = 0;
      chimeDoneThisMinute = true; 
    }
  }

  if (introMelodyActive) {
    unsigned long elapsed = millis() - chimeStateTimer;
    
    // Step 1: Wait out the 26-second intro song
    if (strikeCount == 0 &amp;&amp; elapsed &gt;= 26000) {
      triggerTrack(5); // First hour strike
      strikeCount = 1;
      chimeStateTimer = millis(); 
    }
    // Step 2: Cycle through individual hourly strikes every 3 seconds
    else if (strikeCount &gt; 0 &amp;&amp; strikeCount &lt; totalStrikesNeeded &amp;&amp; elapsed &gt;= 3000) {
      triggerTrack(5); // Consecutive hour strike
      strikeCount++;
      chimeStateTimer = millis();
    }
    // Step 3: Turn off tracking engine when total count completes
    else if (strikeCount &gt;= totalStrikesNeeded) {
      introMelodyActive = false;
    }
  }
}

void handleInputsNoMillis() {
  bool setPressed = (digitalRead(btn_set) == LOW);
  bool minPressed = (digitalRead(btn_min) == LOW);
  bool brightPressed = (digitalRead(btn_bright) == LOW);

  // --- SET BUTTON INITIAL PRESS AND MODE TRANSITION ---
  if (setPressed) {
    if (!setModeActive) {
      setHoldCounter++;
      if (setHoldCounter &gt; 30) { // ~600ms hold requirement reached
        setModeActive = true;
      }
    }
    
    if (setModeActive) {
      // 1. Brightness Toggle
      if (brightPressed) {
        currentBrightStage = (currentBrightStage + 1) % 5;
        analogWrite(reg_OE, brightnessPWM);
        delay(250); // Small mechanical debounce
      }

      // 2. Minutes Step with Automatic Hour Rollover
      if (minPressed) {
        minHoldCounter++;
        
        // Advance instantly on first press. If held past 25 frames (~500ms), scroll every 6 frames (~120ms)
        if (minHoldCounter == 1 || (minHoldCounter &gt; 25 &amp;&amp; minHoldCounter % 6 == 0)) {
          seconds = 0; 
          minutes++;
          
          // Rollover minutes into hours smoothly
          if (minutes &gt;= 60) {
            minutes = 0;
            hours++;
            if (hours &gt;= 24) hours = 0;
          }
          updateDisplayRouting();
        }
      } else {
        minHoldCounter = 0; // Reset scroll acceleration instantly on button release
      }
    }
  } 
  else {
    // --- SET BUTTON RELEASE DETECTED ---
    if (setHoldCounter &gt; 0) {
      if (setModeActive) {
        setModeActive = false;
        rtc.adjust(DateTime(2026, 8, 13, hours, minutes, 0)); // Save strictly on release
      } 
      else if (setHoldCounter &gt; 1 &amp;&amp; setHoldCounter &lt;= 30) {
        is24Hour = !is24Hour; // Short tap changes 12/24 mode formatting
      }
      setHoldCounter = 0; 
      minHoldCounter = 0;
      updateDisplayRouting();
    }
  }
}

void setup() {
  pinMode(reg_clock, OUTPUT); pinMode(reg_latch, OUTPUT); pinMode(reg_data, OUTPUT); pinMode(reg_OE, OUTPUT);
  analogWrite(reg_OE, brightnessPWM);
  
  pinMode(btn_bright, INPUT_PULLUP); 
  pinMode(btn_min,    INPUT_PULLUP); 
  pinMode(btn_set,    INPUT_PULLUP);
  
  Wire.begin(); 
  Serial.begin(38400); // Start native Hardware Serial on pins 0/1 at 38400 baud

  if (!rtc.begin()) {
    while (1); 
  }
  
  // TESTING FEATURE: Forces the RTC memory directly to 12:14:00 on every boot/reset 
  // so you can instantly verify the 12:15:00 chime sound!
  rtc.adjust(DateTime(2026, 8, 13, 12, 14, 0));

  readRTC(); 
  updateDisplayRouting();
}

void loop() {
  handleInputsNoMillis();
  
  if (!setModeActive) { 
    checkChimesAsynchronous();
    
    // Query the RTC hardware via I2C once every 10 loops (~200ms)
    rtcRefreshTimer++;
    if (rtcRefreshTimer &gt;= 10) {
      readRTC();
      rtcRefreshTimer = 0;
    }
  }
  
  // Conditional refresh gate blocks high-frequency trace noise from locking up buttons
  if (seconds != lastDispSec || minutes != lastDispMin || hours != lastDispHr || setModeActive) {
    updateDisplayRouting();
    lastDispSec = seconds;
    lastDispMin = minutes;
    lastDispHr  = hours;
  }
  
  delay(20); </pre>
<p style="text-align: center"><br />M</p>
<pre contenteditable="false">Digit Clock using TPIC6B595 Shift Registers with Menu System and Temperature/Date Display
Modified to include Menu System for setting date and time via IR Remote, temperature, and date display
Original by Adrian Smith with adjustments by Rick Gast, further modified for Menu System and Temp/Date Display
Fixed button release detection to work with Button Library

Leftmost digit is digit 0
7-segment digits 0-9 {Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7} --&gt; {A, B, C, D, E, F, G, DP}
Data fed to rightmost register first, so digit 0 shifts out first

Uses IRremote Library 3.8.0 or later for Remote Control

Button 1 (IR: 0xF807FF00): Enter/Exit Set Mode or move to next menu item 
Button 2 (IR: 0xBF40FF00): Increment value (in Set Mode) 
Button 3 (IR: 0xE619FF00): Decrement value (in Set Mode) 
Button 4 (IR: 0xF609FF00): Toggle 12/24 Hour Mode (Short press, outside Set/Temp Modes) or toggle °C/°F (Short press, in Temp Mode) 

IR: 0xBB44FF00: Toggle Temperature Display (Short press, outside Set Mode)
IR: 0xBC43FF00: Toggle Date Display (Short press, outside Set Mode)
IR: 0xB847FF00: Set Display Brightness (Does not overide Night Dim Setting) 
IR: 0xBA45FF00: Display Test 

Version 1.9.2 - Added separate IR keys for Date and Temperature Displays. Added 8 second timeout. Added Brightness Control via IR
Version 1.9.3 - Added Display Test thru IR

To add IR hardware to the clock, choose the IR Receiver module or component of your liking, 
then connect 3 pins to the Arduino as follows:   Vcc and Gnd are self explanatory.  Connect the signal pin to digital pin 6.
*/

#define DS3231_I2C_ADDR 0x68
#define DS3231_TEMPERATURE_ADDR 0x11

#include &lt;SPI.h&gt;
#include &lt;Wire.h&gt;
#include &lt;RTCIRremote.hpp&gt;lib.h&gt;
#include &lt;
#include &lt;Button.h&gt;  // Button library by Alexander Brevig

const int reg_clock = 13; // SRCK
const int reg_latch = 10; // RCLK
const int reg_data = 11;  // SER_IN
const int reg_OE = 9;     // Output enable; Active LOW for brightness PWM
const int colon_pin = 8;  // Colon LEDs dimming control
const int RECV_PIN = 6;   // IR receiver pin
unsigned long key_value = 0;
uint32_t lastKey = 0;     // Stores last non-repeat IR key
Button button1 = Button(2, BUTTON_PULLUP_INTERNAL); // Set mode
Button button2 = Button(3, BUTTON_PULLUP_INTERNAL); // Toggle date display or increment/navigate up
Button button3 = Button(4, BUTTON_PULLUP_INTERNAL); // Toggle temp display or decrement/navigate down
Button button4 = Button(5, BUTTON_PULLUP_INTERNAL); // 12/24 hour or °C/°F toggle

int brightness = 2; // Display brightness (1-5, 4 was too bright)
int brt = 0;       // Reversed PWM percentage
int set_mode = 0;  // 0: normal, 1: set mode
int twelveH_mode = 1; // 1: 12-hour mode (default), 0: 24-hour mode
int PM = 0;        // PM indicator for 12-hour mode
bool temp_mode = false; // Flag for temperature display mode
bool date_mode = false; // Flag for date display mode
bool dispTest_mode = false; // Flag for display test
int temp_unit = 0; // 0: Celsius (default), 1: Fahrenheit
static unsigned long lastIRTime = 0; // Moved to global for consistent IR debouncing
const unsigned long IR_DEBOUNCE = 750; // Increased to 750ms to reduce intermittent triggers
static int previous_mode = 1; // 0: clock, 1: 12-hour mode
static unsigned long temp_display_start = 0; // Time when temp mode starts
static unsigned long date_display_start = 0; // Time when date mode starts
static unsigned long dispTest_mode_start = 0; // time when display test starts
const unsigned long DISPLAY_TIMEOUT = 8000; // 8 seconds

int menu_state = 0; // 0: Year, 1: Month, 2: Day, 3: Hour, 4: Minute
int set_year = 0;
int set_month = 0;
int set_day = 0;
int set_hour = 0;
int set_min = 0;

RTC_DS3231 rtc;

byte ssddigits = // 7-segment digits, DP off
{
  B11111100,  // 0
  B01100000,  // 1
  B11011010,  // 2
  B11110010,  // 3
  B01100110,  // 4
  B10110110,  // 5
  B10111110,  // 6
  B11100000,  // 7
  B11111110,  // 8
  B11110110   // 9
};

byte ssddigitsDP = // 7-segment digits, DP on
{
  B11111101,  // 0
  B01100001,  // 1
  B11011011,  // 2
  B11110011,  // 3
  B01100111,  // 4
  B10110111,  // 5
  B10111111,  // 6
  B11100001,  // 7
  B11111111,  // 8
  B11110111   // 9
};

byte tempdigits = // C and F with degrees symbol 
{
  B10011101,  // °C
  B10001111   // °F
};

byte menuDisplay = // Menu indicators: "Yr", "Mo", "dA", "Hr", "Mn"
{
  {B01110110, B00001010, B00000000}, // Yr
  {B11001100, B11100100, B00111010}, // Mo
  {B01111010, B11101110, B00000000}, // dA
  {B01101110, B00001010, B00000000}, // Hr
  {B11001100, B11100100, B00101010}  // Mn
};

void setup()
{
  IrReceiver.begin(RECV_PIN, DISABLE_LED_FEEDBACK);
  pinMode(reg_clock, OUTPUT);
  pinMode(reg_latch, OUTPUT);
  pinMode(reg_data, OUTPUT);
  pinMode(reg_OE, OUTPUT);
  pinMode(colon_pin, OUTPUT);
  digitalWrite(reg_OE, LOW);
  digitalWrite(colon_pin, HIGH);
  setBrt();
  uint8_t duty = map(brt, 0, 100, 0, 255);
  analogWrite(reg_OE, duty);
  SPI.begin();
  displayTest();
  delay(3000);
  Wire.begin();
  rtc.begin();
  set_mode = 0;
  twelveH_mode = 1;
  temp_unit = 1; // Default to Fahrenheit
  previous_mode = 1; // Default to 12-hour mode
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Uncomment to set initial time
}

void loop()
{
  if (set_mode == 1)
  {
    setTime();
  }
  else if (temp_mode)
  {
    tempDisplay();
  }
  else if (dispTest_mode)
  {
    displayTest();
  }
  else if (date_mode)
  {
    dateDisplay();
  }
  else if (twelveH_mode)
  {
    twelve_hourMode();
    previous_mode = 1;
  }
  else
  {
    clockDisplay();
    previous_mode = 0;
  }

  checkButtons();
  checkIRinput();
  setBrt();
  uint8_t duty = map(brt, 0, 100, 0, 255);
  analogWrite(reg_OE, duty);
}

// *** Functions *** //

void clockDisplay()
{
  DateTime now = rtc.now();
  int hours = now.hour();
  int minutes = now.minute();
  int seconds = now.second();

  int h1 = hours / 10;
  int h2 = hours % 10;
  int m1 = minutes / 10;
  int m2 = minutes % 10;
  int s1 = seconds / 10;
  int s2 = seconds % 10;

  SPI.beginTransaction(SPISettings(8000000, LSBFIRST, SPI_MODE0));
  digitalWrite(reg_latch, LOW);
  if (hours &lt;= 9)
  {
    SPI.transfer(ssddigits);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigits);
  }
  else
  {
    SPI.transfer(ssddigits);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigits);
  }
  digitalWrite(reg_latch, HIGH);
  SPI.endTransaction();

  if (now.hour() == 23 &amp;&amp; now.minute() == 0 &amp;&amp; now.second() == 0)
  {
    brightness = 1;
    digitalWrite(colon_pin, LOW);
  }
  if (now.hour() == 8 &amp;&amp; now.minute() == 0 &amp;&amp; now.second() == 0)
  {
    brightness = 2;
    digitalWrite(colon_pin, HIGH);
  }
}

void twelve_hourMode()
{
  DateTime now = rtc.now();
  PM = (now.hour() &gt;= 12) ? 1 : 0;
  int hours = now.hour() % 12;
  if (hours == 0) hours = 12;
  int minutes = now.minute();
  int seconds = now.second();

  int h1 = hours / 10;
  int h2 = hours % 10;
  int m1 = minutes / 10;
  int m2 = minutes % 10;
  int s1 = seconds / 10;
  int s2 = seconds % 10;

  SPI.beginTransaction(SPISettings(8000000, LSBFIRST, SPI_MODE0));
  digitalWrite(reg_latch, LOW);
  if (hours &lt;= 9 &amp;&amp; PM == 0)
  {
    SPI.transfer(B00000000);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigits);
  }
  else if (hours &lt;= 9 &amp;&amp; PM == 1)
  {
    SPI.transfer(B00000001);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigits);
  }
  else if (hours &gt;= 10 &amp;&amp; PM == 0)
  {
    SPI.transfer(ssddigits);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigits);
  }
  else
  {
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigitsDP);
    SPI.transfer(ssddigits);
  }
  digitalWrite(reg_latch, HIGH);
  SPI.endTransaction();

  if (now.hour() == 23 &amp;&amp; now.minute() == 0 &amp;&amp; now.second() == 0)
  {
    brightness = 1;
    digitalWrite(colon_pin, LOW);
  }
  if (now.hour() == 8 &amp;&amp; now.minute() == 0 &amp;&amp; now.second() == 0)
  {
    brightness = 2;
    digitalWrite(colon_pin, HIGH);
  }
}

void setTime()
{
  //checkIRinput(); // Commented out, not needed with shared variables
  DateTime now = rtc.now();
  if (menu_state == 0 &amp;&amp; set_mode == 1) 
  {
    set_year = now.year();
    set_month = now.month();
    set_day = now.day();
    set_hour = now.hour();
    set_min = now.minute();
  }

  SPI.beginTransaction(SPISettings(8000000, LSBFIRST, SPI_MODE0));
  digitalWrite(reg_latch, LOW);
  switch (menu_state)
  {
    case 0: // Year
    {
      int y1 = (set_year / 1000) % 10;
      int y2 = (set_year / 100) % 10;
      int y3 = (set_year / 10) % 10;
      int y4 = set_year % 10;
      SPI.transfer(ssddigits);
      SPI.transfer(ssddigits);
      SPI.transfer(ssddigits);
      SPI.transfer(ssddigits);
      SPI.transfer(menuDisplay); // Y
      SPI.transfer(menuDisplay); // r
      break;
    }
    case 1: // Month
    {
      int m1 = set_month / 10;
      int m2 = set_month % 10;
      SPI.transfer(ssddigits);
      SPI.transfer(ssddigits);
      SPI.transfer(B00000000);
      SPI.transfer(menuDisplay); // M
      SPI.transfer(menuDisplay); // M
      SPI.transfer(menuDisplay); // o
      //Serial.print(m1);
      //Serial.print(m2);
      break;
    }
    case 2: // Day
    {
      int d1 = set_day / 10;
      int d2 = set_day % 10;
      SPI.transfer(ssddigits);
      SPI.transfer(ssddigits);
      SPI.transfer(B00000000);
      SPI.transfer(B00000000);
      SPI.transfer(menuDisplay); // d
      SPI.transfer(menuDisplay); // A
      break;
    }
    case 3: // Hour
    {
      int h1 = set_hour / 10;
      int h2 = set_hour % 10;
      SPI.transfer(h1 == 0 ? B00000000 : ssddigits);
      SPI.transfer(ssddigits);
      SPI.transfer(B00000000);
      SPI.transfer(B00000000);
      SPI.transfer(menuDisplay); // H
      SPI.transfer(menuDisplay); // r
      break;
    }
    case 4: // Minute
    {
      int m1 = set_min / 10;
      int m2 = set_min % 10;
      SPI.transfer(ssddigits);
      SPI.transfer(ssddigits);
      SPI.transfer(B00000000);
      SPI.transfer(menuDisplay); // M
      SPI.transfer(menuDisplay); // M
      SPI.transfer(menuDisplay); // n
      break;
    }
  }
  digitalWrite(reg_latch, HIGH);
  SPI.endTransaction();

  if (button2.uniquePress())
  {
    switch (menu_state)
    {
      case 0: set_year = (set_year &lt; 2099) ? set_year + 1 : 2000; break;
      case 1: set_month = (set_month &lt; 12) ? set_month + 1 : 1; break;
      case 2: set_day = (set_day &lt; 31) ? set_day + 1 : 1; break;
      case 3: set_hour = (set_hour &lt; 23) ? set_hour + 1 : 0; break;
      case 4: set_min = (set_min &lt; 59) ? set_min + 1 : 0; break;
    }
    delay(10);
    rtc.adjust(DateTime(set_year, set_month, set_day, set_hour, set_min, 0));
  }

  if (button3.uniquePress())
  {
    switch (menu_state)
    {
      case 0: set_year = (set_year &gt; 2000) ? set_year - 1 : 2099; break;
      case 1: set_month = (set_month &gt; 1) ? set_month - 1 : 12; break;
      case 2: set_day = (set_day &gt; 1) ? set_day - 1 : 31; break;
      case 3: set_hour = (set_hour &gt; 0) ? set_hour - 1 : 23; break;
      case 4: set_min = (set_min &gt; 0) ? set_min - 1 : 59; break;
    }
    delay(10);
    rtc.adjust(DateTime(set_year, set_month, set_day, set_hour, set_min, 0));
  }

  if (button1.uniquePress())
  {
    if (menu_state &lt; 4) 
    {
      menu_state++;
    }
    else
    {
      // Use user-adjusted values, reset seconds to 0
      rtc.adjust(DateTime(set_year, set_month, set_day, set_hour, set_min, 0));
      set_mode = 0;
      menu_state = 0;
      key_value = 0;
      temp_mode = false; // Ensure temp mode off
      date_mode = false; // Ensure date mode off
      temp_display_start = 0; // Reset timeout
      date_display_start = 0; // Reset timeout
      if (twelveH_mode)
        twelve_hourMode();
      else
        clockDisplay();
      return;
    }
  }
}

void setBrt()
{
  if (brightness == 1) brt = 92;
  else if (brightness == 2) brt = 80;
  else if (brightness == 3) brt = 50;
  else if (brightness == 4) brt = 30;
  else if (brightness == 5) brt = 0;
}

void dateDisplay()
{
  DateTime now = rtc.now();
  int month = now.month();
  int day = now.day();
  int year = now.year() % 100; // Last two digits of year

  int m1 = month / 10;
  int m2 = month % 10;
  int d1 = day / 10;
  int d2 = day % 10;
  int y1 = year / 10;
  int y2 = year % 10;

  SPI.beginTransaction(SPISettings(8000000, LSBFIRST, SPI_MODE0));
  digitalWrite(reg_latch, LOW);
  // SPI.transfer(m1 == 0 ? B00000000 : ssddigits);
  SPI.transfer(ssddigits);
  SPI.transfer(ssddigitsDP); // Decimal point after month
  // SPI.transfer(d1 == 0 ? B00000000 : ssddigits);
  SPI.transfer(ssddigits);
  SPI.transfer(ssddigitsDP); // Decimal point after day
  // SPI.transfer(y1 == 0 ? B00000000 : ssddigits);
  SPI.transfer(ssddigits);
  SPI.transfer(ssddigits);
  digitalWrite(reg_latch, HIGH);
  SPI.endTransaction();

  // Check for 8-second timeout
  if (millis() - date_display_start &gt;= DISPLAY_TIMEOUT)
  {
    date_mode = false;
    date_display_start = 0;
    if (previous_mode == 1)
      twelve_hourMode();
    else
      clockDisplay();
  }
}

void tempDisplay()
{
  // Read temperature from DS3231
  Wire.beginTransmission(DS3231_I2C_ADDR);
  Wire.write(DS3231_TEMPERATURE_ADDR);
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDR, 2);
  uint8_t temp_msb = Wire.read();
  uint8_t temp_lsb = Wire.read(); // Read but ignore fractional part
  int temp_display;
  // int offset = -6; // replace the 6 with the number of degrees C it is out (allow 1 hour warm up time)
  if (temp_unit == 1) // Fahrenheit
  {
    temp_display = (temp_msb * 9) / 5 + 32; // Convert to Fahrenheit
  }
  else // Celsius
  {
  // temp_display = temp_msb + offset; // Use integer part only  
    temp_display = temp_msb; // Use integer part only
  }

  int t1 = temp_display / 10;
  int t2 = temp_display % 10;

  SPI.beginTransaction(SPISettings(8000000, LSBFIRST, SPI_MODE0));
  digitalWrite(reg_latch, LOW);
  SPI.transfer(B00000000); // blank digit
  SPI.transfer(B00000000); // blank digit
  SPI.transfer(t1 == 0 ? B00000000 : ssddigits);
  SPI.transfer(ssddigits);
 // SPI.transfer(B11000110); // display °
  SPI.transfer(tempdigits); // °C or °F
  SPI.transfer(B00000000); // blank digit
  digitalWrite(reg_latch, HIGH);
  SPI.endTransaction();

  // Check for 8-second timeout
  if (millis() - temp_display_start &gt;= DISPLAY_TIMEOUT)
  {
    temp_mode = false;
    temp_display_start = 0;
    if (previous_mode == 1)
      twelve_hourMode();
    else
      clockDisplay();
  }
}

void displayTest()
{
  SPI.beginTransaction(SPISettings(8000000, LSBFIRST, SPI_MODE0));
  digitalWrite(reg_latch, LOW);
  SPI.transfer(B11111111);
  SPI.transfer(B11111111);
  SPI.transfer(B11111111);
  SPI.transfer(B11111111);
  SPI.transfer(B11111111);
  SPI.transfer(B11111111);
  digitalWrite(reg_latch, HIGH);
  SPI.endTransaction();

  // Check for 8 second timeout
  if (millis() - dispTest_mode_start &gt;= DISPLAY_TIMEOUT)
  {
    dispTest_mode = false;
    dispTest_mode_start = 0;
    if (previous_mode == 1)
      twelve_hourMode();
    else
      clockDisplay();
  }
}

void checkButtons()
{
  // Handle button 1: Enter set mode only when not in set mode
  if (button1.uniquePress() &amp;&amp; !set_mode)
  {
    SPI.beginTransaction(SPISettings(8000000, LSBFIRST, SPI_MODE0));
    digitalWrite(reg_latch, LOW);
    SPI.transfer(B00000000); // Blank hour 10s
    SPI.transfer(B00000000); // Blank hour 1s
    SPI.transfer(B00000010); // -
    SPI.transfer(B00000010); // -
    SPI.transfer(B00000000); // Blank seconds 10s
    SPI.transfer(B00000000); // Blank seconds 1s
    digitalWrite(reg_latch, HIGH);
    SPI.endTransaction();
    delay(2000);
    set_mode = 1;
    temp_mode = false; // Ensure temp mode is off
    date_mode = false; // Ensure date mode is off
    temp_display_start = 0; // Reset timeout
    date_display_start = 0; // Reset timeout
  }

  // Handle button 2: Toggle date display (outside set mode)
  if (button2.uniquePress() &amp;&amp; !set_mode)
  {
    date_mode = !date_mode;
    if (date_mode)
    {
      temp_mode = false; // Ensure temp mode is off
      temp_display_start = 0; // Reset temp timeout
      date_display_start = millis(); // Start date timeout
      dateDisplay();
    }
    else
    {
      date_display_start = 0; // Reset date timeout
      if (previous_mode == 1)
        twelve_hourMode();
      else
        clockDisplay();
    }
  }

  // Handle button 3: Toggle temperature display (outside set mode)
  if (button3.uniquePress() &amp;&amp; !set_mode)
  {
    temp_mode = !temp_mode;
    if (temp_mode)
    {
      date_mode = false; // Ensure date mode is off
      date_display_start = 0; // Reset date timeout
      temp_display_start = millis(); // Start temp timeout
      tempDisplay();
    }
    else
    {
      temp_display_start = 0; // Reset temp timeout
      if (previous_mode == 1)
        twelve_hourMode();
      else
        clockDisplay();
    }
  }

  // Handle button 4: Toggle 12/24 hour mode (outside set/temp mode) or °C/°F (in temp mode)
  if (button4.uniquePress() &amp;&amp; !set_mode)
  {
    if (temp_mode)
    {
      temp_unit = !temp_unit; // Toggle °C/°F in temp mode
    }
    else
    {
      twelveH_mode = !twelveH_mode; // Toggle 12/24 hour mode
    }
    delay(400);
  }
}

void checkIRinput()
{
  if (set_mode == 1 &amp;&amp; menu_state == 0)
  {
    DateTime now = rtc.now();
    set_year = now.year();
    set_month = now.month();
    set_day = now.day();
    set_hour = now.hour();
    set_min = now.minute();
  }

  if (IrReceiver.decode())
  {
    unsigned long currentTime = millis();
    unsigned long value = IrReceiver.decodedIRData.decodedRawData;

    if (value == 0)
    {
      IrReceiver.resume();
      return;
    }

    if (!(IrReceiver.decodedIRData.flags &amp; IRDATA_FLAGS_IS_REPEAT) &amp;&amp; (currentTime - lastIRTime &gt; IR_DEBOUNCE))
    {
      if (set_mode == 1)
      {
        // Handle IR commands in set mode
        switch (value)
        {
          case 0xF807FF00: // Advance menu state or exit
            if (menu_state &lt; 4)
            {
              menu_state++;
              setTime(); // Update display for new menu state
            }
            else
            {
              rtc.adjust(DateTime(set_year, set_month, set_day, set_hour, set_min, 0));
              set_mode = 0;
              menu_state = 0;
              key_value = 0;
              temp_mode = false;
              date_mode = false;
              temp_display_start = 0;
              date_display_start = 0;
              if (twelveH_mode)
                twelve_hourMode();
              else
                clockDisplay();
              delay(100); // Allow display refresh
            }
            lastIRTime = currentTime;
            break;

          case 0xBF40FF00: // Increment value
            switch (menu_state)
            {
              case 0: set_year = (set_year &lt; 2099) ? set_year + 1 : 2000; break;
              case 1: set_month = (set_month &lt; 12) ? set_month + 1 : 1; break;
              case 2: set_day = (set_day &lt; 31) ? set_day + 1 : 1; break;
              case 3: set_hour = (set_hour &lt; 23) ? set_hour + 1 : 0; break;
              case 4: set_min = (set_min &lt; 59) ? set_min + 1 : 0; break;
            }
            delay(10);
            rtc.adjust(DateTime(set_year, set_month, set_day, set_hour, set_min, 0));
            setTime(); // Update display with new value
            lastIRTime = currentTime;
            break;

          case 0xE619FF00: // Decrement value
            switch (menu_state)
            {
              case 0: set_year = (set_year &gt; 2000) ? set_year - 1 : 2099; break;
              case 1: set_month = (set_month &gt; 1) ? set_month - 1 : 12; break;
              case 2: set_day = (set_day &gt; 1) ? set_day - 1 : 31; break;
              case 3: set_hour = (set_hour &gt; 0) ? set_hour - 1 : 23; break;
              case 4: set_min = (set_min &gt; 0) ? set_min - 1 : 59; break;
            }
            delay(10);
            rtc.adjust(DateTime(set_year, set_month, set_day, set_hour, set_min, 0));
            setTime(); // Update display with new value
            lastIRTime = currentTime;
            break;

          case 0xF609FF00: // Ignored in set mode
            lastIRTime = currentTime;
            break;

          default:
            lastIRTime = currentTime;
            break;
        }
      }
      else
      {
        // Handle IR commands outside set mode
        switch (value)
        {
          case 0xF807FF00: // Enter set mode
            SPI.beginTransaction(SPISettings(8000000, LSBFIRST, SPI_MODE0));
            digitalWrite(reg_latch, LOW);
            SPI.transfer(B00000000); // Blank hour 10s
            SPI.transfer(B00000000); // Blank hour 1s
            SPI.transfer(B00000010); // -
            SPI.transfer(B00000010); // -
            SPI.transfer(B00000000); // Blank seconds 10s
            SPI.transfer(B00000000); // Blank seconds 1s
            digitalWrite(reg_latch, HIGH);
            SPI.endTransaction();
            delay(2000);
            set_mode = 1;
            temp_mode = false;
            date_mode = false;
            temp_display_start = 0;
            date_display_start = 0;
            dispTest_mode_start = 0;
            lastIRTime = currentTime;
            break;

          case 0xB847FF00: // set brightness
            {
              brightness++;
              if (brightness == 6)
              brightness = 1;
              break;
            }
          
          case 0xF609FF00: // Toggle 12/24 hour or °C/°F
            if (temp_mode)
            {
              temp_unit = !temp_unit;
            }
            else
            {
              twelveH_mode = !twelveH_mode;
            }
            lastIRTime = currentTime;
            delay(400);
            break;

          case 0xBB44FF00: // Toggle temperature
            temp_mode = !temp_mode;
            if (temp_mode)
            {
              date_mode = false;
              date_display_start = 0;
              date_display_start = 0;
              temp_display_start = millis();
              tempDisplay();
            }
            else
            {
              temp_display_start = 0;
              if (previous_mode == 1)
                twelve_hourMode();
              else
                clockDisplay();
            }
            lastIRTime = currentTime;
            break;

          case 0xBC43FF00: // Toggle date
            date_mode = !date_mode;
            if (date_mode)
            {
              temp_mode = false;
              temp_display_start = 0;
              dispTest_mode_start = 0;
              date_display_start = millis();
              dateDisplay();
            }
            else
            {
              date_display_start = 0;
              if (previous_mode == 1)
                twelve_hourMode();
              else
                clockDisplay();
            }
            lastIRTime = currentTime;
            break;

        
            case 0xBA45FF00: // Toggle Display Test
            dispTest_mode = !dispTest_mode;
            if (dispTest_mode)
            {
              temp_mode = false;
              date_mode = false;
              temp_display_start = 0;
              date_display_start = 0;
              dispTest_mode_start = millis();
              displayTest();
            }
            else
            {
              dispTest_mode_start = 0;
              if (previous_mode == 1)
                twelve_hourMode();
              else
                clockDisplay();
            }
          default:
            lastIRTime = currentTime;
            break;
        }
      }

      // Clear IR data and resume receiver
      IrReceiver.decodedIRData.decodedRawData = 0; // Clear IR data
      key_value = 0; // Clear key_value
      IrReceiver.resume(); // Prepare for next IR signal
    }
    else
    {
      IrReceiver.resume(); // Clear repeat or debounced signals
    }
  }</pre>]]></content:encoded>
						                            <category domain="https://forum.dronebotworkshop.com/"></category>                        <dc:creator>Lmitchel</dc:creator>
                        <guid isPermaLink="true">https://forum.dronebotworkshop.com/arduino/ardruino-clock-help-2/paged/2/#post-53218</guid>
                    </item>
				                    <item>
                        <title>RE: I2C pull-up Resistor Calculation</title>
                        <link>https://forum.dronebotworkshop.com/electronic-components/i2c-pull-up-resistor-calculation/#post-53217</link>
                        <pubDate>Thu, 10 Sep 2026 00:41:06 +0000</pubDate>
                        <description><![CDATA[Hi @davee !

TY for this reference. Slide 32 on p. 13 shows for the pullup resistors &quot;Typical value 2 kΩ to 10 kΩ&quot;, but that is vs a Vcc of 5V. When I calculate as suggested in &quot;I2C pull-u...]]></description>
                        <content:encoded><![CDATA[<p>Hi @davee !</p>
<p>A more recent (2003) discussion at <a class="wpforo-auto-embeded-link" href="https://www.nxp.com/docs/en/application-note/AN10216.pdf" target="_blank" rel="nofollow noopener">https://www.nxp.com/docs/en/application-note/AN10216.pdf</a> may provide some further insight.</p>
<p>TY for this reference. Slide 32 on p. 13 shows for the pullup resistors "Typical value 2 kΩ to 10 kΩ", but that is vs a Vcc of 5V. When I calculate as suggested in <a title="SLVA689" href="http://www.ti.com/lit/pdf/SLVA689" target="_blank" rel="noopener">"I2C pull-up Resistor Calculation"</a> I get (for Standard Mode) a range from 967 Ω to 2.95 kΩ -- what is at least in the same magnitude but 1:3 apart. My uneducated choice is 2k6, but with the shaky self-confidence of an apprentice chef preparing his first menu for a client in absence of his master.</p>]]></content:encoded>
						                            <category domain="https://forum.dronebotworkshop.com/"></category>                        <dc:creator>Amphitryonoff</dc:creator>
                        <guid isPermaLink="true">https://forum.dronebotworkshop.com/electronic-components/i2c-pull-up-resistor-calculation/#post-53217</guid>
                    </item>
							        </channel>
        </rss>
		