<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.tinkernet.ca/index.php?action=history&amp;feed=atom&amp;title=IoT_-_Modular_-_I2C.cpp</id>
	<title>IoT - Modular - I2C.cpp - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.tinkernet.ca/index.php?action=history&amp;feed=atom&amp;title=IoT_-_Modular_-_I2C.cpp"/>
	<link rel="alternate" type="text/html" href="https://wiki.tinkernet.ca/index.php?title=IoT_-_Modular_-_I2C.cpp&amp;action=history"/>
	<updated>2026-05-04T14:47:28Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>https://wiki.tinkernet.ca/index.php?title=IoT_-_Modular_-_I2C.cpp&amp;diff=1551&amp;oldid=prev</id>
		<title>Tinker: Created page with &quot;==#includes, Defines, etc...==  &lt;syntaxhighlight lang=&quot;cpp&quot; line=&quot;1&quot;&gt; #include &quot;libraries.h&quot; #include &quot;functions.h&quot; &lt;/syntaxhighlight&gt;  ==I2C_Test()==  &lt;syntaxhighlight lang=&quot;...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.tinkernet.ca/index.php?title=IoT_-_Modular_-_I2C.cpp&amp;diff=1551&amp;oldid=prev"/>
		<updated>2021-04-30T03:26:50Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;==#includes, Defines, etc...==  &amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt; #include &amp;quot;libraries.h&amp;quot; #include &amp;quot;functions.h&amp;quot; &amp;lt;/syntaxhighlight&amp;gt;  ==I2C_Test()==  &amp;lt;syntaxhighlight lang=&amp;quot;...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==#includes, Defines, etc...==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;libraries.h&amp;quot;&lt;br /&gt;
#include &amp;quot;functions.h&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==I2C_Test()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bool I2C_Test(int SDA, int SCL)&lt;br /&gt;
{&lt;br /&gt;
    debug_SectionTitle(&amp;quot;I2C Test &amp;amp;/or repair...&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    bool SCL_state = (digitalRead(SCL) == HIGH);&lt;br /&gt;
    bool SDA_state = (digitalRead(SDA) == HIGH);&lt;br /&gt;
&lt;br /&gt;
    if (SCL_state &amp;amp;&amp;amp; SDA_state)&lt;br /&gt;
    {&lt;br /&gt;
        debug_LineOut(&amp;quot;I2C is good.&amp;quot;);&lt;br /&gt;
        return (true);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (!SCL_state)&lt;br /&gt;
            debug_Trouble(&amp;quot;SCL is LOW.&amp;quot;);&lt;br /&gt;
        if (!SDA_state)&lt;br /&gt;
            debug_Trouble(&amp;quot;SDA is LOW.&amp;quot;);&lt;br /&gt;
        debug_Action(&amp;quot;Clearing I2C&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        switch (I2C_ClearBus(SDA, SCL))&lt;br /&gt;
        {&lt;br /&gt;
        case 0:&lt;br /&gt;
            debug_LineOut(&amp;quot;I2C is clear.&amp;quot;);&lt;br /&gt;
            return (true);&lt;br /&gt;
            break;&lt;br /&gt;
        case 1:&lt;br /&gt;
            debug_Trouble(&amp;quot;I2C bus error. Could not clear&amp;quot;);&lt;br /&gt;
            debug_Trouble(&amp;quot;SCL clock line held low&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        case 2:&lt;br /&gt;
            debug_Trouble(&amp;quot;I2C bus error. Could not clear SCL clock&amp;quot;);&lt;br /&gt;
            debug_Trouble(&amp;quot;line held low by slave clock stretch&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        case 3:&lt;br /&gt;
            debug_Trouble(&amp;quot;I2C bus error. Could not clear&amp;quot;);&lt;br /&gt;
            debug_Trouble(&amp;quot;SDA data line held low&amp;quot;);&lt;br /&gt;
            break;&lt;br /&gt;
        }&lt;br /&gt;
        debug_Trouble(&amp;quot;++++++++++++++++ STOPPING!!! +++++++++++++++++&amp;quot;);&lt;br /&gt;
        while (true) // Slam on da brakes!&lt;br /&gt;
            blinkLED(100);&lt;br /&gt;
        return (false);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==I2C_ClearBus()==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * This routine turns off the I2C bus and clears it&lt;br /&gt;
 * on return SCA and SCL pins are tri-state inputs.&lt;br /&gt;
 * You need to call Wire.begin() after this to re-enable I2C&lt;br /&gt;
 * This routine does NOT use the Wire library at all.&lt;br /&gt;
 *&lt;br /&gt;
 * returns 0 if bus cleared&lt;br /&gt;
 *         1 if SCL held low.&lt;br /&gt;
 *         2 if SDA held low by slave clock stretch for &amp;gt; 2sec&lt;br /&gt;
 *         3 if SDA held low after 20 clocks.&lt;br /&gt;
 * &lt;br /&gt;
 * Source:  http://www.forward.com.au/pfod/ArduinoProgramming/I2C_ClearBus/index.html&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
int I2C_ClearBus(int SDA, int SCL)&lt;br /&gt;
{&lt;br /&gt;
#if defined(TWCR) &amp;amp;&amp;amp; defined(TWEN)&lt;br /&gt;
    TWCR &amp;amp;= ~(_BV(TWEN)); // Disable the Atmel 2-Wire interface&lt;br /&gt;
                          // so we can control the SDA and SCL pins directly&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
    pinMode(SDA, INPUT_PULLUP); // Make SDA (data) and SCL (clock) pins Inputs with pullup.&lt;br /&gt;
    pinMode(SCL, INPUT_PULLUP);&lt;br /&gt;
&lt;br /&gt;
    delay(2500); // Wait 2.5 secs. This is strictly only necessary on the first power&lt;br /&gt;
    // up of the DS3231 module to allow it to initialize properly,&lt;br /&gt;
    // but is also assists in reliable programming of FioV3 boards as it gives the&lt;br /&gt;
    // IDE a chance to start uploaded the program&lt;br /&gt;
    // before existing sketch confuses the IDE by sending Serial data.&lt;br /&gt;
&lt;br /&gt;
    boolean SCL_LOW = (digitalRead(SCL) == LOW); // Check is SCL is Low.&lt;br /&gt;
    if (SCL_LOW)&lt;br /&gt;
    {             //If it is held low Arduno cannot become the I2C master.&lt;br /&gt;
        return 1; //I2C bus error. Could not clear SCL clock line held low&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    boolean SDA_LOW = (digitalRead(SDA) == LOW); // vi. Check SDA input.&lt;br /&gt;
    int clockCount = 20;                         // &amp;gt; 2x9 clock&lt;br /&gt;
&lt;br /&gt;
    while (SDA_LOW &amp;amp;&amp;amp; (clockCount &amp;gt; 0))&lt;br /&gt;
    { //  vii. If SDA is Low,&lt;br /&gt;
        clockCount--;&lt;br /&gt;
        // Note: I2C bus is open collector so do NOT drive SCL or SDA high.&lt;br /&gt;
        pinMode(SCL, INPUT);        // release SCL pullup so that when made output it will be LOW&lt;br /&gt;
        pinMode(SCL, OUTPUT);       // then clock SCL Low&lt;br /&gt;
        delayMicroseconds(10);      //  for &amp;gt;5uS&lt;br /&gt;
        pinMode(SCL, INPUT);        // release SCL LOW&lt;br /&gt;
        pinMode(SCL, INPUT_PULLUP); // turn on pullup resistors again&lt;br /&gt;
        // do not force high as slave may be holding it low for clock stretching.&lt;br /&gt;
        delayMicroseconds(10); //  for &amp;gt;5uS&lt;br /&gt;
        // The &amp;gt;5uS is so that even the slowest I2C devices are handled.&lt;br /&gt;
        SCL_LOW = (digitalRead(SCL) == LOW); // Check if SCL is Low.&lt;br /&gt;
        int counter = 20;&lt;br /&gt;
        while (SCL_LOW &amp;amp;&amp;amp; (counter &amp;gt; 0))&lt;br /&gt;
        { //  loop waiting for SCL to become High only wait 2sec.&lt;br /&gt;
            counter--;&lt;br /&gt;
            delay(100);&lt;br /&gt;
            SCL_LOW = (digitalRead(SCL) == LOW);&lt;br /&gt;
        }&lt;br /&gt;
        if (SCL_LOW)&lt;br /&gt;
        {             // still low after 2 sec error&lt;br /&gt;
            return 2; // I2C bus error. Could not clear.&lt;br /&gt;
                      // SCL clock line held low by slave clock stretch for &amp;gt;2sec&lt;br /&gt;
        }&lt;br /&gt;
        SDA_LOW = (digitalRead(SDA) == LOW); //   and check SDA input again and loop&lt;br /&gt;
    }&lt;br /&gt;
    if (SDA_LOW)&lt;br /&gt;
    {             // still low&lt;br /&gt;
        return 3; // I2C bus error. Could not clear. SDA data line held low&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // else pull SDA line low for Start or Repeated Start&lt;br /&gt;
    pinMode(SDA, INPUT);        // remove pullup.&lt;br /&gt;
    pinMode(SDA, OUTPUT);       // and then make it LOW i.e. send an I2C Start or Repeated start control.&lt;br /&gt;
                                // When there is only one I2C master a Start or Repeat Start&lt;br /&gt;
                                // has the same function as a Stop and clears the bus.&lt;br /&gt;
                                // A Repeat Start is a Start occurring after a Start with&lt;br /&gt;
                                // no intervening Stop.&lt;br /&gt;
    delayMicroseconds(10);      // wait &amp;gt;5uS&lt;br /&gt;
    pinMode(SDA, INPUT);        // remove output low&lt;br /&gt;
    pinMode(SDA, INPUT_PULLUP); // and make SDA high i.e. send I2C STOP control.&lt;br /&gt;
    delayMicroseconds(10);      // x. wait &amp;gt;5uS&lt;br /&gt;
    pinMode(SDA, INPUT);        // and reset pins as tri-state inputs which is the default state on reset&lt;br /&gt;
    pinMode(SCL, INPUT);&lt;br /&gt;
    return 0; // all ok&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Tinker</name></author>
		
	</entry>
</feed>