In the loop?

So, finally making progress on my project, getting things to move in the right direction, buttons are no longer backwards etc.

But, in putting the pieces together I'm definitely missing something basic...

I've got an accelerometer on a digital sensor and it println()s nicely when moved around. But I'm trying to have the hbridge stop pushing the motor when the tilt reaches a set point.

Initially I had a button which called out to a function (outside of the loop) doing the motor driving etc. But as soon as I call the function, the sensor stops responding. Maybe that makes sense. So then I put the motor driving into the loop, but the sensor still stops updating as soon as the button is pushed to initiate travel to the setpoint.

Seems like this should work, but maybe I need some kind of interrupt approach. Any pointers?

void loop() {
  StateA = digitalRead(BtnA);
  //Serial.println(StateA);
  int TiltTemp, PulseTilt, TiltSet;
  PulseTilt = pulseIn(TiltPin,HIGH);
  TiltTemp = ((PulseTilt/10)-500)*8/4; //divide by 4 to take values from 1024 to fit into a byte
  //Serial.print(TiltTemp);
  Serial.println(TiltTemp);


  if (StateA==HIGH && PrevA==LOW && millis() - DnTimeA > Bounce) {
    DnTimeA = millis();
    //Serial.println("Down");
  }

  if (StateA==LOW && PrevA==HIGH && millis() - DnTimeA < Interval && millis() - DnTimeA > Bounce) {
    //Serial.println("SHORT");

//*****
  if (TiltTemp!=TiltSet){
    digitalWrite(Disconnect,HIGH);
    delay(20);

    if (TiltSet < TiltTemp){
      while (TiltSet < TiltTemp) {
        digitalWrite(SwitchHBridge,HIGH);
              Serial.print("Driving HIGH to TiltSet: ");
              Serial.print(TiltSet);
              Serial.print("\t");
              Serial.print(" From: ");
              Serial.print(TiltTemp);
              Serial.println();   
      }
    }
    else {
      while (TiltSet > TiltTemp) {
        digitalWrite(SwitchHBridge,LOW);
              Serial.print("Driving LOW to TiltSet: ");
              Serial.print(TiltSet);
              Serial.print("\t");
              Serial.print(" From: ");
              Serial.print(TiltTemp);
              Serial.println();    
      }
    }
    digitalWrite(Disconnect,LOW);
  }
//*****

  }

  if (StateA==LOW && PrevA==HIGH && millis() - DnTimeA > Interval && millis() - DnTimeA > Bounce) {
    //Serial.println("LONG");
    TiltSet = TiltTemp;
    //    EEPROM.write(1,TiltSet);
    //    Serial.print("TiltSet = ");
    //    Serial.print(TiltSet);
    //    Serial.print("stored");
    //    Serial.println();
  }

  PrevA = StateA;
}
  TiltTemp = ((PulseTilt/10)-500)*8/4; //divide by 4 to take values from 1024 to fit into a byte

A byte will hold 0 to 255. Perhaps show more of your code?

 int TiltTemp, PulseTilt, TiltSet;

PulseTilt = pulseIn(TiltPin,HIGH);
  TiltTemp = ((PulseTilt/10)-500)*8/4; //divide by 4 to take values from 1024 to fit into a byte
...
  if (TiltTemp!=TiltSet){

The variable TiltSet has undefined values. Why bother comparing it to something?

Hey Nick, thanks for the reply. I appreciate the questions.

The BtnA has two functions on a short or long push. Pushing it long is intended to store the current value of the accel (which should be TiltTemp) into TiltSet. Then later the short push will drive the motors until TiltTemp approx equal to TiltSet.

I may not have the eeprom writing and initialization set correctly yet because the code has never had a chance to access those lines... TiltSet has never been set, but it's value is 0 at this point. At this phase of developing the sketch, my goal is to short push the button so that the motor begins to drive, and then tilt the accel by hand until the comparison to TiltSet is true, when hopefully the motor will stop. Then I'll make sure tilting it from the opposite direction also works.

So I think the two questions you asked are good ones, and ones which will be fixed, but at the moment not what's causing the problem. I would post the whole program (actually what's there is all but the initialization header) but I'm on a different computer than the one with the IDE.

The issue at the moment is that as soon as the button is pushed, the motor starts spinning but the sensor stops reporting the acccel value - i.e. TiltTemp doesn't change with tilting. Therefore I can't complete my testing the TiltSet or tilt direction functionality. I thought that was because the routine to drive the motors was outside of the loop, and one I jump out to it by pushing the button the looping stops(?) but now that I've put it inside the loop, the problem persists and I don't understand why.

braddo_99:
TiltSet has never been set, but it's value is 0 at this point.

No, it isn't. Its value is undefined. That is, it can be anything.

I thought that was because the routine to drive the motors was outside of the loop, and one I jump out to it by pushing the button the looping stops(?) but now that I've put it inside the loop, the problem persists and I don't understand why.

I don't really follow this talk. You don't "jump out of the loop". Perhaps posting the whole sketch?

OK, I'll post the rest after this reply, thanks for the help.

So, on your reply, I actually did set TiltSet to 0 as you can now see, I had just forgotten, as I had not set it in a previous version but instead was attempting to read it from the eeprom. So, at least for now, that shouldn't be causing any problems.

As for the "in the loop" comment, I was under the impression that if you call a function from inside of the main void loop() function, that the "looping" might stop. Again, the version immediately prior to what I'm posting has the motor driving steps in a function outside of the void loop(). In this version, I moved those motor driving steps inside of the main void loop() to see what effect that might have.

I have some print statements which, when the main program starts, continuously report the value of the accel (TiltTemp) and the TiltSet parameter. That is, they report it until the button is pressed, at which point the print statements stop. This is what I'm trying to get help to troubleshoot - why does the sensor stop sensing the accelerometer?

#include <EEPROM.h>

const int BtnA = 2; // Button A on Pin 2
const long Bounce = 30; // Debounce time in milliseconds
const long Interval = 2500; // Time threshold for button "hold"
const int SwitchHBridge = 4; // Switch drives Darlington on Pin 4
const int Disconnect = 6; // Disconnect the manual switches with relay
const int TiltPin= 8;

int StateA = HIGH; // Current state of button A
int PrevA = HIGH; // Previous state of button A
long DnTimeA = 0; // When did button A get pushed
int TiltSet = 0;


void setup() {
  Serial.begin(9600);
  digitalWrite(BtnA,HIGH);
  pinMode(BtnA, INPUT);
  pinMode(SwitchHBridge,OUTPUT);
  pinMode(Disconnect,OUTPUT);
  pinMode(TiltPin, INPUT);
  //  TiltSet = EEPROM.read(1);
}

void loop() {
  StateA = digitalRead(BtnA);
  //Serial.println(StateA);
  int TiltTemp, PulseTilt, TiltSet;
  PulseTilt = pulseIn(TiltPin,HIGH);
  TiltTemp = ((PulseTilt/10)-500)*8/4; //divide by 4 to take values from 1024 to fit into a byte
  //Serial.print(TiltTemp);
  Serial.println(TiltTemp);


  if (StateA==HIGH && PrevA==LOW && millis() - DnTimeA > Bounce) {
    DnTimeA = millis();
    //Serial.println("Down");
  }

  if (StateA==LOW && PrevA==HIGH && millis() - DnTimeA < Interval && millis() - DnTimeA > Bounce) {
    //Serial.println("SHORT");

//*****
  if (TiltTemp!=TiltSet){
    digitalWrite(Disconnect,HIGH);
    delay(20);

    if (TiltSet < TiltTemp){
      while (TiltSet < TiltTemp) {
        digitalWrite(SwitchHBridge,HIGH);
              Serial.print("Driving HIGH to TiltSet: ");
              Serial.print(TiltSet);
              Serial.print("\t");
              Serial.print(" From: ");
              Serial.print(TiltTemp);
              Serial.println();   
      }
    }
    else {
      while (TiltSet > TiltTemp) {
        digitalWrite(SwitchHBridge,LOW);
              Serial.print("Driving LOW to TiltSet: ");
              Serial.print(TiltSet);
              Serial.print("\t");
              Serial.print(" From: ");
              Serial.print(TiltTemp);
              Serial.println();    
      }
    }
    digitalWrite(Disconnect,LOW);
  }
//*****

  }

  if (StateA==LOW && PrevA==HIGH && millis() - DnTimeA > Interval && millis() - DnTimeA > Bounce) {
    //Serial.println("LONG");
    TiltSet = TiltTemp;
    //    EEPROM.write(1,TiltSet);
    //    Serial.print("TiltSet = ");
    //    Serial.print(TiltSet);
    //    Serial.print("stored");
    //    Serial.println();
  }

  PrevA = StateA;
}

braddo_99:
As for the "in the loop" comment, I was under the impression that if you call a function from inside of the main void loop() function, that the "looping" might stop.

No, function calls are nested. Once you exit the other function you are back to where you were when you called it.

int TiltSet = 0;

...

void loop() {
  StateA = digitalRead(BtnA);
  //Serial.println(StateA);
  int TiltTemp, PulseTilt, TiltSet;

...

You have two TiltSet variables in your sketch, not one. Inside loop, the inner one "shadows" the outer one. This inner one does not retain its value from one iteration of loop to the other, and its value is undefined.

... I actually did set TiltSet to 0 as you can now see, I had just forgotten ...

No, you set a different TiltSet variable to 0, not the one in loop.

OK Nick, thanks again. I only ended up attempting to "pass that variable in" after it didn't seem to be acting like a global variable, but then I think I created another problem by declaring a new one. I think I should be able to get this going.

So, thanks to Nick and Wildbill in another thread, I have a working solution. I had a few issues with initializing variables and also a variable scoping problem (which I still don't understand and will post in a different thread).

The solution was to create a function that checks the position of the accel sensor TiltTemp, and call this function in my while loop instead of just referencing a variable declared outside of the loop. I posted this working code below. I also now have setpoint (TiltSet) being stored in the eeprom on a long button push, and the motors driving in one direction or another until that setpoint is matched.

This approach will work for this kind of sensor, which reports an absolute value of its orientation. However, I'm adding a motor rotation input based on a hall effect sensor next, and that one needs to always be counting regardless of which loop i'm in or whatever else is happening.

#include <EEPROM.h>

const int BtnA = 2; // Button A on Pin 2
const long Bounce = 30; // Debounce time in milliseconds
const long Interval = 2500; // Time threshold for button "hold"
const int SwitchHBridge = 4; // Switch drives Darlington on Pin 4
const int Disconnect = 6; // Disconnect the manual switches with relay
const int TiltPin= 8;

int StateA = HIGH; // Current state of button A
int PrevA = HIGH; // Previous state of button A
long DnTimeA = 0; // When did button A get pushed
int TiltSet = 0;


void setup() {
  Serial.begin(9600);
  digitalWrite(BtnA,HIGH);
  pinMode(BtnA, INPUT);
  pinMode(SwitchHBridge,OUTPUT);
  pinMode(Disconnect,OUTPUT);
  pinMode(TiltPin, INPUT);
  TiltSet = EEPROM.read(1);
}

int TiltTemp (){
  int PulseTilt;
  PulseTilt = pulseIn(TiltPin,HIGH);
  return ((PulseTilt/10)-500)*8/4; //divide by 4 to take values from 1024 to fit into a byte
}

void loop() {
  StateA = digitalRead(BtnA);
  //Serial.println(StateA);


  if (StateA==HIGH && PrevA==LOW && millis() - DnTimeA > Bounce) {
    DnTimeA = millis();
    //Serial.println("Down");
  }

  if (StateA==LOW && PrevA==HIGH && millis() - DnTimeA < Interval && millis() - DnTimeA > Bounce) {
    //Serial.println("SHORT");
    DriveToSetpoint();
  }

  if (StateA==LOW && PrevA==HIGH && millis() - DnTimeA > Interval && millis() - DnTimeA > Bounce) {
    //Serial.println("LONG");
    TiltSet = TiltTemp();
        EEPROM.write(1,TiltSet);
        Serial.print("TiltSet = ");
        Serial.print(TiltSet);
        Serial.println();
  }
  PrevA = StateA;
}


void DriveToSetpoint(){
  if (TiltTemp()!=TiltSet){
    digitalWrite(Disconnect,HIGH);
    //delay(20);
    while (TiltTemp() < TiltSet) {
      digitalWrite(SwitchHBridge,HIGH);
      Serial.print("Driving UP to TiltSet: ");
      Serial.print(TiltSet);
      Serial.print("\t");
      Serial.print(" From: ");
      Serial.print(TiltTemp());
      Serial.println();   
    }
    while (TiltTemp() > TiltSet) {
      digitalWrite(SwitchHBridge,LOW);
      Serial.print("Driving DOWN to TiltSet: ");
      Serial.print(TiltSet);
      Serial.print("\t");
      Serial.print(" From: ");
      Serial.print(TiltTemp());
      Serial.println();    
    }
    digitalWrite(Disconnect,LOW);
  }
} // End DriveToSetpoint