// Arduino Forum member GoForSmoke 12/4/25 free to use code, it compiles, 95% done, 95% to go!
// AVRduino: never use 16 bits to do what 8 bits can do. Uno total RAM = 2048 bytes.
// AVR Code: avoid doing math with mixed variable types... so bytes for pins and most indexes
const byte pots = 2;
byte potIdx = 0; // which pot to read next
const unsigned int averageOver = 10;
unsigned int runningTotal[ pots ] = { 0, 0 };
unsigned int avgRead[ pots ] = { 0, 0 };
unsigned int microsReadLast = 0;
unsigned int microsTweenPotReads = 1024; // can be less than 1000, should be >= 200
const byte potPin[ pots ] = { A0, A1 }; // Potentiometer analog pins
const int midpoint = 511; // Midpoint of 10-bit ADC
const int tolerance = 20; // Acceptable range around midpoint
const byte relays = 2;
const byte relayPin[ relays ] = { 8, 7 }; // Relay pin 8 to A0, Relay pin 7 to A1
byte relayLimits[ relays ][ 2 ] = { 150, 850, 450, 550 };
void setMUX( byte pin ) // change the ADC channel to allow settle time before the next read
{
byte mux = ADMUX;
ADMUX = ( mux & 0xF0 ) | ( pin & 0xF );
}
void setup()
{ // start setup()
for ( byte i = 0; i < relays; i++ )
{
pinMode( relayPin[ i ], OUTPUT); // default start is LOW
}
setMUX( potIdx ); // init
delayMicroseconds( 60 ); // IIRC actual datasheet settle time is ~55 usecs
Serial.begin(115200); // set your Serial Monitor to clear the serial buffer faster than 9600
} // end setup()
void readADCupdateStatus()
{ // start readADCupdateStatus()
static int adcRead;
adcRead = analogRead( potPin[ potIdx ] );
// subtract 1/averageOver of the total and add the read
runningTotal[ potIdx ] -= ( runningTotal[ potIdx ] / averageOver ) + adcRead;
// the new average is 1/averageOver of that
avgRead[ potIdx ] = runningTotal[ potIdx ] / averageOver;
if ( ++potIdx == pots ) potIdx = 0; // next channel
setMUX( potIdx ); // set next channel and settle till next read
} // end readADCupdateStatus()
void runRelays()
{
for ( byte i = 0; i < relays; i++ )
{
// Check if within midpoint range pin 8
if (avgRead[ 0 ] >= (relayLimits[ i ][ 0 ]) && avgRead[ 0 ] <= (relayLimits[ i ][ 1 ]))
{
digitalWrite(relayPin[ i ], HIGH); // Turn relay ON
}
else
{
digitalWrite(relayPin[ i ], LOW); // Turn relay OFF
}
}
}
unsigned int debugLast;
const unsigned int debugWait = 250; // millis
void loop()
{ // start loop()
unsigned int now = micros(); // reads the low 16 bits, 65.535 ms max
if ( now - microsReadLast >= microsTweenPotReads )
{
readADCupdateStatus();
microsReadLast += microsTweenPotReads; // keep interval timing, not >= timing
}
if ( now - debugLast >= debugWait )
{ // start Debug output
debugLast += debugWait;
for ( byte i = 0; i < pots; i++ )
{
Serial.print( "A" );
Serial.print( i );
Serial.print( ": " );
// fill spaces to right-justify ADC print data in columns
if ( avgRead[ i ] < 10 )
{
Serial.print( " " );
}
else
{
if ( avgRead[ i ] < 100 )
{
Serial.print( " " );
}
else
{
if ( avgRead[ i ] < 1000 )
{
Serial.print( " " );
}
else
{
if ( avgRead[ i ] < 10000 )
{
Serial.print( " " );
}
}
}
}
Serial.print( avgRead[ i ] );
Serial.print(" " );
}
Serial.println();
} // end Debug output
runRelays(); // this has no act-interval to add latency and Nooooo Delay!
} // end loop()
/* OUTPUT with sliders not moving and at mebbe 800
A0: 1501 A1: 460
A0: 1273 A1: 460
A0: 1273 A1: 339
A0: 1068 A1: 339
A0: 1068 A1: 230
A0: 883 A1: 230
A0: 883 A1: 132
A0: 717 A1: 132
A0: 717 A1: 43
A0: 567 A1: 43
A0: 567 A1: 6518
A0: 432 A1: 6518
A0: 432 A1: 5791
A0: 311 A1: 5791
A0: 311 A1: 5136
A0: 311 A1: 5136
A0: 202 A1: 5136
A0: 202 A1: 4547
A0: 104 A1: 4547
A0: 104 A1: 4018
A0: 15 A1: 4018
A0: 15 A1: 3541
A0: 6490 A1: 3541
A0: 6490 A1: 3111
A0: 5763 A1: 3111
A0: 5763 A1: 2725
A0: 5108 A1: 2725
A0: 5108 A1: 2377
A0: 4519 A1: 2377
A0: 4519 A1: 2064
A0: 3990 A1: 2064
A0: 3990 A1: 1783
A0: 3513 A1: 1783
A0: 3513 A1: 1529
A0: 3083 A1: 1529
A0: 3083 A1: 1301
A0: 2697 A1: 1301
A0: 2697 A1: 1096
A0: 2349 A1: 1096
A0: 2349 A1: 911
A0: 2036 A1: 911
A0: 2036 A1: 745
A0: 1755 A1: 745
A0: 1755 A1: 595
A0: 1501 A1: 595
A0: 1501 A1: 460
A0: 1273 A1: 460
A0: 1273 A1: 339
A0: 1068 A1: 339
A0: 1068 A1: 230
A0: 883 A1: 230
A0: 883 A1: 132
A0: 717 A1: 132
*/
/* will be extracted scalar version WIP
const byte pots = 2;
byte potIdx = 0; // which pot to read next
const unsigned int averageOver = 10;
unsigned int runningTotal[ pots ] = { 0, 0 };
unsigned int avgRead[ pots ] = { 0, 0 };
const byte potPin[ pots ] = { A0, A1 }; // Potentiometer analog pins
void setup()
{
Serial.begin(115200);
Serial.println("\nonce again with feeling...\n");
}
void readADCupdateStatus()
{ // start readADCupdateStatus()
static int adcRead;
adcRead = analogRead( potPin[ potIdx ] );
// subtract 1/averageOver of the total and add the read
runningTotal[ potIdx ] -= ( runningTotal[ potIdx ] / averageOver ) + adcRead;
// the new average is 1/averageOver of that
avgRead[ potIdx ] = runningTotal[ potIdx ] / averageOver;
if ( ++potIdx == pots ) potIdx = 0; // next channel
setMUX( potIdx ); // set next channel and settle till next read
} // end readADCupdateStatus()
void loop()
*/
// GFS's original
/* from which I will cut and paste, but run verbatim above
// Arduino Forum member GoForSmoke 12/4/25 free to use code, it compiles, 95% done, 95% to go!
// AVRduino: never use 16 bits to do what 8 bits can do. Uno total RAM = 2048 bytes.
// AVR Code: avoid doing math with mixed variable types... so bytes for pins and most indexes
const byte pots = 2;
byte potIdx = 0; // which pot to read next
const unsigned int averageOver = 10;
unsigned int runningTotal[ pots ] = { 0, 0 };
unsigned int avgRead[ pots ] = { 0, 0 };
unsigned int microsReadLast = 0;
unsigned int microsTweenPotReads = 1024; // can be less than 1000, should be >= 200
const byte potPin[ pots ] = { A0, A1 }; // Potentiometer analog pins
const int midpoint = 511; // Midpoint of 10-bit ADC
const int tolerance = 20; // Acceptable range around midpoint
const byte relays = 2;
const byte relayPin[ relays ] = { 8, 7 }; // Relay pin 8 to A0, Relay pin 7 to A1
byte relayLimits[ relays ][ 2 ] = { 150, 850, 450, 550 };
void setMUX( byte pin ) // change the ADC channel to allow settle time before the next read
{
byte mux = ADMUX;
ADMUX = ( mux & 0xF0 ) | ( pin & 0xF );
}
void setup()
{ // start setup()
for ( byte i = 0; i < relays; i++ )
{
pinMode( relayPin[ i ], OUTPUT); // default start is LOW
}
setMUX( potIdx ); // init
delayMicroseconds( 60 ); // IIRC actual datasheet settle time is ~55 usecs
Serial.begin(115200); // set your Serial Monitor to clear the serial buffer faster than 9600
} // end setup()
void readADCupdateStatus()
{ // start readADCupdateStatus()
static int adcRead;
adcRead = analogRead( potPin[ potIdx ] );
// subtract 1/averageOver of the total and add the read
runningTotal[ potIdx ] -= ( runningTotal[ potIdx ] / averageOver ) + adcRead;
// the new average is 1/averageOver of that
avgRead[ potIdx ] = runningTotal[ potIdx ] / averageOver;
if ( ++potIdx == pots ) potIdx = 0; // next channel
setMUX( potIdx ); // set next channel and settle till next read
} // end readADCupdateStatus()
void runRelays()
{
for ( byte i = 0; i < relays; i++ )
{
// Check if within midpoint range pin 8
if (avgRead[ 0 ] >= (relayLimits[ i ][ 0 ]) && avgRead[ 0 ] <= (relayLimits[ i ][ 1 ]))
{
digitalWrite(relayPin[ i ], HIGH); // Turn relay ON
}
else
{
digitalWrite(relayPin[ i ], LOW); // Turn relay OFF
}
}
}
unsigned int debugLast;
const unsigned int debugWait = 250; // millis
void loop()
{ // start loop()
unsigned int now = micros(); // reads the low 16 bits, 65.535 ms max
if ( now - microsReadLast >= microsTweenPotReads )
{
readADCupdateStatus();
microsReadLast += microsTweenPotReads; // keep interval timing, not >= timing
}
if ( now - debugLast >= debugWait )
{ // start Debug output
debugLast += debugWait;
for ( byte i = 0; i < pots; i++ )
{
Serial.print( "A" );
Serial.print( i );
Serial.print( ": " );
// fill spaces to right-justify ADC print data in columns
if ( avgRead[ i ] < 10 )
{
Serial.print( " " );
}
else
{
if ( avgRead[ i ] < 100 )
{
Serial.print( " " );
}
else
{
if ( avgRead[ i ] < 1000 )
{
Serial.print( " " );
}
else
{
if ( avgRead[ i ] < 10000 )
{
Serial.print( " " );
}
}
}
}
Serial.print( avgRead[ i ] );
Serial.print(" " );
}
Serial.println();
} // end Debug output
runRelays(); // this has no act-interval to add latency and Nooooo Delay!
} // end loop()
*/