X27 stepper using switec library gauge project

Hi again, I am trying to get this gauge code to work. I am having difficulty understanding why the gauge behaves the way it does when I make changes in the void loop(void)...

one question is why is it void loop (void) and not void loop()?

Library used
clearwater SwitecX25 from github

Parts used:
Adafruit stepper x27.168 gauge and needle
Adafruit DC/Stepper Motor Driver Breakout Board
Nano

Code from the library example, tweaked to work as intended, use serial monitor, type in value, needle moves to typed value

//----------------------------------------------------------------------
// https://github.com/clearwater/SwitecX25
// 
// This is an example of using the SwitchX25 library.
// It zero's the motor, sets the position to mid-range
// and waits for serial input to indicate new motor positions.
// 
// Open the serial monitor and try entering values 
// between 0 and 944.
// 
// Note that the maximum speed of the motor will be determined
// by how frequently you call update().  If you put a big slow
// serial.println() call in the loop below, the motor will move
// very slowly!
//----------------------------------------------------------------------

#include <SwitecX25.h>

#define STEPS (180*2)                // reduced to little over 90* + few degrees below 0 tick on gauge

SwitecX25 motor1(STEPS,4,5,6,7);     // For motors connected to digital pins 4,5,6,7

void setup(void)
    {
      // run the motor against the stops
      delay (500);
      motor1.zero();
      delay (300);
      motor1.zero();                // Found consistently on reset the needle does not reset to zero, doing this 2nd reset() it always goes to left endstop and back to zero
     
      motor1.setPosition(60);       // Moves needle towards the "Empty" (first) tick mark on gauge on startup or reset

      Serial.begin(9600);
      Serial.print("Enter a step position from 0 through ");
      Serial.print(STEPS-1);
      Serial.println(".");
      Serial.println("60 = 0, 123 = 1/4, 186 = 1/2, 249 = 3/4, 312 = Full");
    }

void loop(void)
{
  static int nextPos = 0;           // Sets gauge to bottom tick mark on gauge after zero() and motor1.setPosition(60) commands       
  motor1.update();                  // the motor only moves when you call update

  if (Serial.available()) 
  {
    char c = Serial.read();

    if (c==10 || c==13)              // I dont understand how this statement works
      {
      motor1.setPosition(nextPos);
      nextPos = 0;
      } 
    
    else if (c>='0' && c<='9')       // I dont understand how this statement works
      {
      nextPos = 10*nextPos + (c-'0');
      }
  }
}

/*
Values to enter to match marks printed on gauge Face to match with current needle installed
312 = full    +63
249 = 3/4     +63
186 = 1/2     +63
123 = 1/4     +63
60 = empty
 */

So this works just fine, next thing I've been trying for hours is how to get the gauge to perform a "demo" ... go to step 60, wait period of time, go to step 123, wait period of time, go to 249.... then go backwards...
I cannot figure out how to do this...

Next code below it will reset the gauge needle, and goes to position 60 (which is the 1st tick mark on the gauge. tick mark I'm referring to is on the gauge, theirs 4 of them. 1st mark represents empty, 2nd mark represents 1/4, 3rd mark represents 3/4 and 4th mark represents Full.

#include <SwitecX25.h>

#define STEPS (180*2)                // reduced to little over 90* + few degrees below 0 tick on gauge

SwitecX25 motor1(STEPS,4,5,6,7);     // For motors connected to digital pins 4,5,6,7

void setup(void)
    {
      // run the motor against the stops
      delay (500);
      motor1.zero();
      delay (300);
      motor1.zero();                // Found consisantly on reset if gauge is past 1/2 needle does not reset to zero, doing this it always goes to left endstop and back to zero
     
      motor1.setPosition(60);       // Moves needle towards the "Empty" (first) tick mark on gauge on startup or reset

      Serial.begin(9600);
      Serial.print("Enter a step position from 0 through ");
      Serial.print(STEPS-1);
      Serial.println(".");
      Serial.println("60 = 0, 123 = 1/4, 186 = 1/2, 249 = 3/4, 312 = Full");
    }

void loop(void)
{
  static int nextPos = 0;           // Sets gauge to bottom tick mark on gauge after zero() and motor1.setPosition(60) commands       
  motor1.update();                  // the motor only moves when you call update

}

if i add delay(500); and then request new position, it moves the needle at 1 step at a time till it reaches the value:

#include <SwitecX25.h>

#define STEPS (180*2)                // reduced to little over 90* + few degrees below 0 tick on gauge

SwitecX25 motor1(STEPS,4,5,6,7);     // For motors connected to digital pins 4,5,6,7

void setup(void)
    {
      // run the motor against the stops
      delay (500);
      motor1.zero();
      delay (300);
      motor1.zero();                // Found consisantly on reset if gauge is past 1/2 needle does not reset to zero, doing this it always goes to left endstop and back to zero
     
      motor1.setPosition(60);       // Moves needle towards the "Empty" (first) tick mark on gauge on startup or reset

      Serial.begin(9600);
      Serial.print("Enter a step position from 0 through ");
      Serial.print(STEPS-1);
      Serial.println(".");
      Serial.println("60 = 0, 123 = 1/4, 186 = 1/2, 249 = 3/4, 312 = Full");
    }

void loop(void)
{
  static int nextPos = 0;           // Sets gauge to bottom tick mark on gauge after zero() and motor1.setPosition(60) commands       
  motor1.update();                  // the motor only moves when you call update

 delay (500);                 // causes gauge to microstep 1 at a time till it reaches position 123
 motor1.setPosition(nextPos);
 nextPos = 123;
 motor1.update();

}

end goal would be to understand this step, then use a potentiometer and learn the map() to make the gauge move according the analog input, just like the Stepper/Knob Control example. Side note, when I upload that sketch, the stepper motor is very noisy when compared to switecx25 library.

Any pointers or links will be much appreciated, I think I've searched and came full circle lol..

Thanks
Clint

Either way. void before a function name means that the function returns no value. void in the parentheses means that the function accepts no arguments.

1 Like

3 hours later :frowning: I managed to get the gauge to move with the potentiometer...

//----------------------------------------------------------------------
// https://github.com/clearwater/SwitecX25
// 
// This is an example of using the SwitchX25 library.
// It zero's the motor, sets the position to mid-range
// and waits for analog 0 input to indicate new motor positions.
// 
// Open the serial monitor and try entering values
//----------------------------------------------------------------------

#include <SwitecX25.h>

#define STEPS (180*2)                // reduced to little over 90* + few degrees below 0 tick on gauge

SwitecX25 motor1(STEPS,4,5,6,7);     // For motors connected to digital pins 4,5,6,7
int previous = 0;


void setup(void)
    {
      
      // run the motor against the stops
      delay (500);
      motor1.zero();
      delay (500);
      motor1.zero();                // Found consisantly on reset if gauge is past 1/2 needle does not reset to zero, doing this it always goes to left endstop and back to zero
     
      motor1.setPosition(60);       // Moves needle towards the "Empty" (first) tick mark on gauge on startup or reset

      Serial.begin(9600);
      Serial.print("Enter a step position from 0 through ");
      Serial.print(STEPS-1);
      Serial.println(".");
      Serial.println("60 = 0, 123 = 1/4, 186 = 1/2, 249 = 3/4, 312 = Full");
    }

void loop(void)
{
 static int nextPos = 0;           // Sets gauge to bottom tick mark on gauge after zero() and motor1.setPosition(60) commands       
  motor1.update();                  // the motor only moves when you call update
 
  int val = analogRead(0);
  val = map(val, 0, 1023, 0, 312);     // mapped 10k pot to the steps Im limiting the movment to
  Serial.println ("val");
  Serial.println (val);


     if (val>=0)              
      {
      motor1.setPosition(val);
      val = 0;
      } 
    
    else if (val>=315)      
      {
      val = 10*val + (val-'0');
      }
}

/*
Values to enter to match marks prited on gauge Face to match with current needle installed
312 = full    +63
249 = 3/4     +63
186 = 1/2     +63
123 = 1/4     +63
60 = empty
 */

Next I will see how to make the needle not flicker/buzz between 2 values... like some sort of comparison value checker. When testing, sometimes the needle stops on the value, sometimes you can hear the motor move a step back and fourth rapidly.. pretty cool to see the gauge move with analog input :slight_smile:
clint

question on negative value readings:

changed only from

  val = map(val, 0, 1023, 60, 312);

to

  val = map(val, 511, 1023, 60, 312);

for this example to possibly ready only more linear usable values ( I'm currently still using the poteometer) This results in negative values displayed in serial.print... that's fine, but the gauge moves past the minimum setpoint value of 60.. which happens to be the 1st tick mark on the gauge. How does this get past

else if (val<=60)
{
}

thanks again for checking out the progress on this project,
clint

video showing regular map () 0,1023 , 60, 123 code working

editing again, figured out the above question, posting latest code:
still want to figure out how to get buffer or hysteresis so the needle doesn't bounce between 2 values...
say, if its value 612 and almost 611 or 613... it would read 612 but not 610 or 614....

//----------------------------------------------------------------------
// https://github.com/clearwater/SwitecX25
// 
// This is an example of using the SwitchX25 library.
// It zero's the motor, sets the position to mid-range
// and waits for serial input to indicate new motor positions.
// 
// Open the serial monitor and try entering values
//----------------------------------------------------------------------

#include <SwitecX25.h>

#define STEPS (180*2)                // reduced to little over 90* + few degrees below 0 tick on gauge

SwitecX25 motor1(STEPS,4,5,6,7);     // For motors connected to digital pins 4,5,6,7
int previous = 0;
const unsigned long eventInterval = 250;
unsigned long previousTime = 0;

void setup(void)
    {
      
      // run the motor against the stops
      delay (500);
      motor1.zero();
      delay (500);
      motor1.zero();                // Found consisantly on reset if gauge is past 1/2 needle does not reset to zero, doing this it always goes to left endstop and back to zero
     
      motor1.setPosition(60);       // Moves needle towards the "Empty" (first) tick mark on gauge on startup or reset

      Serial.begin(9600);
      Serial.print("Enter a step position from 0 through ");
      Serial.print(STEPS-1);
      Serial.println(".");
      Serial.println("60 = 0, 123 = 1/4, 186 = 1/2, 249 = 3/4, 312 = Full");
    }

void loop(void)
{
  static int nextPos = 0;           // Sets gauge to bottom tick mark on gauge after zero() and motor1.setPosition(60) commands       
  motor1.update();                  // the motor only moves when you call update

   unsigned long currentTime =millis();

//   if (currentTime - previousTime >= eventInterval)
//   {
 
  int val = analogRead(0);
  val = map(val, 512, 1023, (60), 312);
  Serial.println ("val");
  Serial.println (val);


    if (val<=60)                                   //new if statement, dont read negitave values first
    {
      motor1.setPosition(60);
      motor1.update(); 
    }

     if (val>=60)         
      {
      motor1.setPosition(val);
      val = 0;
      } 
    
    else if (val<=60)
      {
 //     val = 10*val + (val-'0');
      }
//      previousTime = currentTime;
//   }  
}

the map function does not constrain the input or the output. In this expression:

  val = map(val, 511, 1023, 60, 312);

if the input is less than 511, the output will be less than 60.

thank you @jremington , I'm not sure what I did when testing the program to get the needle on the gauge to move below 60... I was moving the potentiometer back and fourth and that's when I noticed it going past the value of 60... I think I was trying more than 1 thing at a time and being new, not so smart... which is why I want to start with basic code or example and grow on any of these projects I start.
So far at the moment, Its working as intended with a potentiometer...
Also added an offset to calibrate the needle if needed (based on how values get map() 'ed... I haven't connected this to an actual temp sensor or any other sensor, but just playing around with concepts. I found some library's of hysteresis and median filter but haven't tried them out yet.

clint

I am still stumped on how to set a buffer on analog input... any links to other potential solutions?.

looking to have for example reading of 500
if 500 + or - 2 do nothing
if 500 + or - 3 do this.... not sure how to set the - or + up

still searching,
clint

One possible approach:

int deadband = 2;
int midpoint = 500;
if ((reading < midpoint-deadband) or (reading > midpoint+deadband))
        do_something(reading);

I'm sorry to ask for more after your helping so much. I can follow and understand your code, but integrating it into mine does not work as intended.
(full code)
incldues:
updated code and removed values from loop, and turn them into int value and code runs correctly before attempting to integrate

//----------------------------------------------------------------------
// https://github.com/clearwater/SwitecX25
// 
// This is an example of using the SwitchX25 library.
// 
// **** modified ****
//
///It zero's the motor, sets to desired position of 60 for my gauge
// and waits for analog 0 input to indicate new motor positions from potentiometer.
// Parts Used:
// Adafruit stepper x27.168 gauge and needle
// Adafruit DC/Stepper Motor Driver Breakout Board
// Arduino Nano
// 10k Potentiometer to simulate temperature sensor
//----------------------------------------------------------------------

#include <SwitecX25.h>

#define STEPS (180*2)                // reduced to little over 90* + few degrees below 0 tick on gauge

SwitecX25 motor1(STEPS,4,5,6,7);     // For motors connected to digital pins 4,5,6,7

int gaugeMin = 60;                   // Gauge minimum setpoint
int gaugeMax = 312;                  // Gauge maximum setpoint
int startSensor = 512;               // value 0 - 1023 is input range, value changes start read position

int offset = 0;                      // To calibrate needle to exact mark on gauge at known operating parameter
int previous = 0;

const unsigned long eventInterval = 0;
unsigned long previousTime = 0;

void setup(void)
    {
      
      // run the motor against the stops
      delay (500);
      motor1.zero();
      delay (500);
      motor1.zero();                      // Found consisantly on reset if gauge is past 1/2 needle does not reset to zero, doing this it always goes to left endstop and back to zero
     
      motor1.setPosition(gaugeMin);       // Moves needle towards the "Empty" (first) tick mark on gauge on startup or reset

      Serial.begin(9600);
      Serial.print("Enter a step position from 0 through ");
      Serial.print(STEPS-1);
      Serial.println(".");
      Serial.println("60 = 0, 123 = 1/4, 186 = 1/2, 249 = 3/4, 312 = Full");
    }

void loop(void)
{
  static int nextPos = 0;         // Sets gauge to bottom tick mark on gauge after zero() and motor1.setPosition(60) commands       
  motor1.update();                // the motor only moves when you call update

   unsigned long currentTime =millis();

   if (currentTime - previousTime >= eventInterval)
{

  int val = analogRead(0);
  int deadband = 5;
  int midpoint = val ;
  
  val = map(val, startSensor, 1023, (gaugeMin - offset), (gaugeMax + offset));   // maps 1/2 input to specified range on gauge
  Serial.print ("val = ");
  Serial.println (val);
                            
  if ((val >= gaugeMin) < midpoint-deadband or ((val >= gaugeMin) > midpoint+deadband))
      {
      motor1.setPosition(val - offset);
      val = 0;
      } 
    
    else if (val <= gaugeMin)
      {
        
      }
      previousTime = currentTime;
   }  
}

/*
 * Values to enter to match marks printed on gauge Face to match with current needle installed
 * 312 = full    +63
 * 249 = 3/4     +63
 * 186 = 1/2     +63
 * 123 = 1/4     +63
 * 60 = empty
 */

I've updated to add the recommendation and cannot seem to incorporate it... it to me, should work, but does not and does additional wrong things to code..

If I reset nano with potentiomter at zero position, it reads a value of -195 ( this value is ok, doesn't matter), gauge goes to setpoint of 60, operating as designed.

(next movement, rotate potentiometer)

If I move potentiometer 1 increment on serial.monitor (which would now read-194 , gauge goes to right, the max end of gauge range, (4th tick on gauge face)
Does not operate as intended - it should do nothing till past value of 60 (as it did before)

If I reset nano with potentiometer within 60 - 312 range, it resets, zeros, and goes to valid position (whatever value it was at that was within range), it will still twitch between steps if the potentiometer is between values.

If I continue function testing this code and if I rotate the potentiometer below the serial.monitor value of 60, gauge indicator will go past minimum setpoint of 60

Expected: It should not go below septoint of 60 Elese statement

If I continue function testing this code and if I rotate the potentiometer further and it reaches -1, it goes full max right, the max end of gauge range, (4th tick on gauge face) .

confused at best with this latest code..

if this line on the code change to :

 if (val >= gaugeMin) // < midpoint-deadband or ((val >= gaugeMin) > midpoint+deadband))

gauge behaves as deigned but has the twitch if potvalues displayed on serial.monitor are + or - 1..... code even went to int deadband = 5;

super long reply, but trying to use my 15 yr automotive mechanical profession to give as much detail to a problem/situation when asking for help.

for example my car squeaks, you get no help.... you give lots of info on when car squeaks and how to duplicate it, you get a ,more solid attempt at fixing it and solid chance of fixing it :slight_smile: hope that came across as positive

thanks again,
Clint

Sorry, I can't figure out from your code what you are trying to do. Try to explain what you want to do in clear English, using simple example numbers, then write simple code.

I recommend to spend more time learning about the programming language. There are plenty of tutorials on line that work through simple examples.

Examples of the problems:

Below you get a value from analogRead(), assign "midpoint" to be equal to that value, then change the value itself using the map function. But I don't understand what the map function is supposed to be doing. Can you explain your thinking?

  int val = analogRead(0);
  int deadband = 5;
  int midpoint = val ;
    val = map(val, startSensor, 1023, (gaugeMin - offset), (gaugeMax + offset));

This is not a useful if construction, for the reasons explained below (it may also be missing parentheses, in which case it won't compile):

if ((val >= gaugeMin) < midpoint-deadband or ((val >= gaugeMin) > midpoint+deadband))

Take the first part of that expression. A logical test like (val >= gaugeMin) returns true or false.

Does it make sense, in the second part to ask if true is less than some number?
if (true < midpoint - deadband)

1 Like

The gauge sketch without the deadband additional code, it complies and works exactly as intended with potentiometer, just like the video shows ... the flickering of the needle is just due to the potentiometer being close to 2 values.

if ((val >= gaugeMin) < midpoint-deadband or ((val >= gaugeMin) > midpoint+deadband)
this was my attempt at placing the code from the approach on the buffer you shared.

if ((reading < midpoint-deadband) or (reading > midpoint+deadband))
in my case my reading was (val >= gaugeMin) so i tried to incorporate it... again, novice attempt :slight_smile:

Take the first part of that expression. A logical test like (val >= gaugeMin) returns **true** or **false**.
Does it make sense, in the second part to ask if **true** is less than some number if (true < midpoint - deadband)

the (val >= gaugeMin) code makes sure the gauge inidcatior does not fall below the set stepper count of 60. This puts the indicator on the right spot on the gauge when the potentiometer reads below value of 60.

I will start a new sketch only for serial read of potentiometer and try to figure the value buffer. I was thinking at work that I would need:
to read the input value
wait sometime value
read value again and store it as new int
and then use your approach

clint

mannnn, really proud of myself lol.... many..manny more hours, found the example code I was looking for this buffer... Its hard to search for what you want, when it could be called a few different things.. also doesn't help I have no formal training ..

final code ... lol, never final, now next step with this project is to play with stepper motor speeds..
When I had Serial.print enabled, as the original code stated in the header area, it move slow... it does, but its nice smooth and quiet. (see previous video link)

When I added the debug code from a previous project that you can enable/disable Serial.print with the change of 0 or 1 in the code below, indicator now is at full speed

#define DEBUG 0  // turn On (1) or Off (0) debug & Serial.println

motor runs fast like when it resets. All normal operation, just didn't understand the Serial.print was the cause of the slower moving indicator after zero() function.... anyway, updating with the latest code that works :smiley:

//----------------------------------------------------------------------
// https://github.com/clearwater/SwitecX25
// 
// This is an example of using the SwitchX25 library.
// 
// **** modified ****
//
///It zero's the motor, sets to desired position of 60 for my gauge
// and waits for analog 0 input to indicate new motor positions from potentiometer.
// Parts Used:
// Adafruit stepper x27.168 gauge and needle
// Adafruit DC/Stepper Motor Driver Breakout Board
// Arduino Nano
// 10k Potentiometer to simulate temperature sensor
//
//https://stackoverflow.com/questions/27304043/detect-change-in-arduino-potentiometer for solution to tolerance/buffer
//
//----------------------------------------------------------------------

#include <SwitecX25.h>

#define STEPS (180*2)                // reduced to little over 90* + few degrees below 0 tick on gauge
#define TOLERANCE 3                  // Value to use for tolerance + or - actual reading will update oldVal

#define DEBUG 0                      // turn On (1) or Off (0) debug & Serial.println

#if DEBUG == 1                       // if there is Serial.println, gauge operates sloly and quietly
#define debug(x) Serial.print(x)     // if there is NO Serial.println, gauge moves quickly and quietly to 1st position, but able to hear indicator movment afterwars
#define debugln(x) Serial.println(x)
#else
#define debug(x)
#define debugln(x)
#endif  



SwitecX25 motor1(STEPS,4,5,6,7);     // For motors connected to digital pins 4,5,6,7

int gaugeMin = 60;                   // Gauge minimum setpoint
int gaugeMax = 312;                  // Gauge maximum setpoint
int startSensor = 512;               // value 0 - 1023 is input range, value changes start read position
int oldVal = 0;                      // to store old value

int offset = 0;                      // To calibrate needle to exact mark on gauge at known operating parameter
int previous = 0;

const unsigned long eventInterval = 0;     // Set delay for each indicator step, maybe usefull if a unbaffled fuel tank is used and fuel float moves a lot
unsigned long previousTime = 0;

void setup(void)
    {
      
      // run the motor against the stops
      delay (500);
      motor1.zero();                      // Zero stepper to step 0
      delay (500);
      motor1.zero();                      // Found consisantly on reset if gauge is past 1/2 needle does not reset to zero, doing this it always goes to left endstop and back to zero
     
      motor1.setPosition(gaugeMin);       // Moves needle towards the "Empty" (first) tick mark on gauge on startup or reset if oldVal value is below GaugeMin septoint

      Serial.begin(9600);
    }

void loop(void)
{
  static int nextPos = 0;                                                        // Sets gauge to bottom tick mark on gauge after zero() and motor1.setPosition(60) commands       
  motor1.update();                                                               // the motor only moves when you call update

   unsigned long currentTime =millis();

   if (currentTime - previousTime >= eventInterval)                              // If a delay is required, eventInverval value must be met betfore code runs
{

  int val = analogRead(0);
  
  val = map(val, startSensor, 1023, (gaugeMin - offset), (gaugeMax + offset));   // maps 1/2 input to specified range on gauge
  
  debug ("val = ");
  debugln (val);
  debug ("oldVal = ");
  debugln (oldVal);

    int diff = abs(val - oldVal);

    if(diff > TOLERANCE)
    {
        oldVal = val;                            // only save if the val has changed enough to avoid slowly drifting
    }     
                            
  if (oldVal >= gaugeMin)
      {
      motor1.setPosition(oldVal - offset);
      val = 0;                                    // *****ive commented this out, no change.. purpose?
      } 

    else if (oldVal <= gaugeMin)
      {

      }
      previousTime = currentTime;
   }
}

/*
 * Values to enter to match marks prited on gauge Face to match with current needle installed
 * 312 = full    +63
 * 249 = 3/4     +63
 * 186 = 1/2     +63
 * 123 = 1/4     +63
 * 60 = empty
 */ 

the millis() delay is not being used to do anything at the moment

Video showing gauge with no Serial.prints and its currently connected to little battery supp for power source for this demo

gauge with no serial print = faster movement

clint

I am stuck on getting the builtin led to blink when over a value, and stay on when over a higher value. I copied blink without delay and it didn't work when I attempted to incorporate it in my code. So I did a separate code just to use only the poteometer and the code... it works as expected. Below value of 247 LED is off, at 247+ LED blinks. Over 800 led solid.

int previous = 0;
const unsigned long eventInterval =  500;   // Set delay for each indicator step, maybe usefull if a unbaffled fuel tank is used and fuel float moves a lot
unsigned long previousTime = 0;

const long sensfailblink = 200;
int ledBlink = 247;
int ledSolid = 800;

int ledState = LOW;                   // Blink without delay example, for blinking LED if sensor is unpluged or wire fault (open)

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(LED_BUILTIN, OUTPUT);      // set the LED_BUILTIN as output:
}

void loop() {
  int Val = analogRead (A0);

  unsigned long currentTime = millis();

  if (currentTime - previousTime >= eventInterval)      // eventInverval value must be met betfore code runs
  {
    Serial.print   ("Val = ");
    Serial.println (Val);

    if (Val > ledBlink)                                     // If sensor unplugged or open circuit, turn on LED_BULTIN
    {
      if (currentTime - previousTime >= sensfailblink) {    // Blink without delay example
        previousTime = currentTime;

        if (ledState == LOW)                                // if the LED is off turn it on and vice-versa:
        {
          ledState = HIGH;
        }
        else
        {
          ledState = LOW;
        }

        digitalWrite(LED_BUILTIN, ledState);                // set the LED with the ledState of the variable:

      }
    }

    else
    {
      digitalWrite(LED_BUILTIN, LOW);                      // Turns off LED_BULITIN off when: below value of 240 or if sensor connected
    }

    if (Val  > ledSolid)                                  // "Over Heat" warning value on gauge to turn on LED_BULTIN ****does not work if blink without delay exampele below enabled
    {
      ledState = HIGH;
      digitalWrite(LED_BUILTIN, ledState);                // set the LED with the ledState of the variable:
    }

    
    previousTime = currentTime;                            // Reset time
  }
}

I tried to incorporate that into the current working gauge code however when value exceeds 247, NO led blink, if I continue to rotate the potentiometer to value 300+, it runs that if statement, and LED is on solid... I don/t know what I am missing / where I am failing at

#include <SwitecX25.h>

#define STEPS (180*2)                       // reduced to little over 90* + few degrees below 0 tick on gauge
#define TOLERANCE 2                         // Value to use for tolerance + or - actual reading will update oldVal

#define DEBUG 1                             // turn On (1) or Off (0) debug & Serial.println

#if DEBUG == 1                              // if there is Serial.println, gauge operates slowly and quietly
#define debug(x) Serial.print(x)            // if there is NO Serial.println, gauge moves quickly and quietly to 1st position, but able to hear indicator movment afterwars
#define debugln(x) Serial.println(x)
#else
#define debug(x)
#define debugln(x)
#endif


SwitecX25 motor1(STEPS, 4, 5, 6, 7);        // x27 motor connected to digital pins 4,5,6,7

int ledBlink = 247;                         // Value to Blink LED for "overheat warning", 4th tick on gauge
int ledSolid = 300;                         // Value to turn on LED

int gaugeMin = 60;                          // Gauge minimum setpoint, 1st tick mark on gauge
int gaugeMax = 315;                         // Gauge maximum setpoint, 5th tick mark on gauge
int offset = 0;                             // To calibrate needle to exact mark on gauge at known operating parameter

int oldVal = 0;                             // to store old value

int previous = 0;
const unsigned long eventInterval =  500;   // Set delay for each indicator step, maybe usefull if a unbaffled fuel tank is used and fuel float moves a lot
unsigned long previousTime = 0;

const long sensfailblink = 500;

int ledState = LOW;                   // Blink without delay example, for blinking LED if sensor is unpluged or wire fault (open)

void setup(void)
{

  // run the motor against the stops
  delay (500);
  motor1.zero();                      // Zero stepper to step 0
  delay (500);
  motor1.zero();                      // Found consisantly on reset if gauge is past 1/2 needle does not reset to zero, doing this it always goes to left endstop and back to first mark on gauge

  motor1.setPosition(gaugeMin);       // Moves needle towards the "Empty" (first) tick mark on gauge on startup or reset if oldVal value is below GaugeMin septoint

  Serial.begin(9600);

  pinMode(LED_BUILTIN, OUTPUT);      // set the LED_BUILTIN as output:

}

void loop(void)
{
  static int nextPos = 0;                               // Sets gauge to bottom tick mark on gauge after zero() and motor1.setPosition(60) commands
  motor1.update();                                      // the motor only moves when you call update

  unsigned long currentTime = millis();

  if (currentTime - previousTime >= eventInterval)      // If a delay is required, eventInverval value must be met betfore code runs
  {

    int val = analogRead(A0);
    val = map(val, 0, 1023, 60, 315);


    debug   ("analogRead(0) = ");
    debugln (analogRead(0)), 0 ;
    debug   ("val = ");
    debugln (val);
    debug   ("oldVal = ");
    debugln (oldVal);

    int diff = abs(val - oldVal);

    if (diff > TOLERANCE)
    {
      oldVal = val;                                         // only save if the val has changed enough to avoid slowly drifting a.k.a buffer
    }

    if (oldVal >= gaugeMin)
    {
      motor1.setPosition(oldVal - offset);
    }

    if (oldVal > ledBlink)                                  // Blink LED_BUILTIN
    {
      if (currentTime - previousTime >= sensfailblink) {    // Blink without delay example
        previousTime = currentTime;


        if (ledState == LOW)                                // if the LED is off turn it on and vice-versa:
        {
          ledState = HIGH;
        }
        else
        {
          ledState = LOW;
        }

        digitalWrite(LED_BUILTIN, ledState);                // set the LED with the ledState of the variable:

      }
    }


    if (oldVal  > ledSolid)                              // "Over Heat" warning value on gauge to turn on LED_BULTIN ****does not work if blink without delay exampele below enabled
    {
      ledState = HIGH;
      digitalWrite(LED_BUILTIN, ledState);
    }


    else
    {
      ledState = LOW;
      digitalWrite(LED_BUILTIN, ledState);
    }


    previousTime = currentTime;                            // Reset time
  }
}

if i comment out

//    else
//    {
//      ledState = LOW;
//      digitalWrite(LED_BUILTIN, ledState);
//    }

Led will blink on/after value 247, but if the potentiometer goes lower and if the led was ON at that moment, it stays on, if the led was off at the time the value goes below 247, the led will stay off.

removed potentiometer for this next code, and installed the temp sensor

I also added steinhard formula that is pretty, so far in a boiling pot of water, gauge responds appropriately... 210 is not center of gauge... still working on that.

I changed the else to another if statement and seems to work:

   if  ((oldVal  <= -106) && (oldVal  >= -1000))     //  values used between that the led should be off
    {
      ledState = LOW;
      digitalWrite(LED_BUILTIN, ledState);
    }

and now works as expected. Question, why did the else not work, is this even the right way to go about using state feature?

with the temp sensor connected, LED off, as its within "Normal operating conditions"
with the temp sensor disconnected, LED ON
with the temp sensor connected and temperature reaches above the -105 value i had put in, LED blinks.

So far, i think its working right, having trouble understanding why the ELSE didn't work.... and to boot, if i commented out either "ledBlink" or "ledSolid" if statement, it would work.. strange.

thanks,
Clint

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