Press on pressure sensor for over 10 minutes, then activate vibration motor

Hello I would like to seek help on coding. I can create code on vibration once a pressure is detected. However, I would like to create a code that vibration occur when pressure exists for a preset duration(10mins), instead of a immediate stimulation. Urgent help is needed and thank you!

Code that I got:
//Arduino to I/O for RAPID, ABB control
int pressPin = 0; //pressure sensor to Arduino A0
int initReading; //variable for the initial reading,
// of the pressure sensor.
int reading; //variable for storing current pressure
//reading
boolean startUp; //sets up a calibration ‘switch’

int di1Pin = 9; //sends signal to robot controller

void setup()
{
//Serial.begin(9600); //Setup a serial connection for debug.

initReading = 0; //Initialize initReading.
reading = analogRead(pressPin); //Reading equals the value,
//returned by the sensor.
startUp = true; //Initialize the calibration switch to ‘on’
pinMode(di1Pin, OUTPUT); //Pin 9 is set to SEND a signal.

}

void loop()
{
calibrate(); //calls the function defined below

reading = analogRead(pressPin); //Reading equals the value,
//from the sensor
if(reading < initReading*.9) //If reading is less than 90%,
{ //of the initial sensor value,
digitalWrite(di1Pin, HIGH); //send a signal to the controller.
}
else
{
digitalWrite(di1Pin,LOW); //send no signal
}
}

void calibrate() //The first thing to do in the loop,
{
if(startUp == true) //if the calibration switch is on (which it is),
{
initReading = reading; //set initReading equal to the sensor
//value.
startUp = false; //And shut of the calibration switch.
}
}//Arduino to I/O for RAPID, ABB control
int pressPin = 0; //pressure sensor to Arduino A0
int initReading; //variable for the initial reading,
// of the pressure sensor.
int reading; //variable for storing current pressure
//reading
boolean startUp; //sets up a calibration ‘switch’

int di1Pin = 9; //sends signal to robot controller

void setup()
{
//Serial.begin(9600); //Setup a serial connection for debug.

initReading = 0; //Initialize initReading.
reading = analogRead(pressPin); //Reading equals the value,
//returned by the sensor.
startUp = true; //Initialize the calibration switch to ‘on’
pinMode(di1Pin, OUTPUT); //Pin 9 is set to SEND a signal.

}

void loop()
{
calibrate(); //calls the function defined below

reading = analogRead(pressPin); //Reading equals the value,
//from the sensor
if(reading < initReading*.9) //If reading is less than 90%,
{ //of the initial sensor value,
digitalWrite(di1Pin, HIGH); //send a signal to the controller.
}
else
{
digitalWrite(di1Pin,LOW); //send no signal
}
}

void calibrate() //The first thing to do in the loop,
{
if(startUp == true) //if the calibration switch is on (which it is),
{
initReading = reading; //set initReading equal to the sensor
//value.
startUp = false; //And shut of the calibration switch.
}
}

The above code can create vibration once pressure is detected. But I don't know where and how to add the part to count pressure time before vibration occurs.T-T

Start here, urgently.

Please note, you appear to have two setup and two loop functions.
That's not allowed.

Have you did a site search on millis()?

millis() is one of the counters that an Uno has that give elapsed running time of the MCU in milli seconds and can be used as a timing source.

I did not. May I know how can I add this one in my coding? Or how can I amend my code in order to reach my desired outcome? Thank you!!!

//Arduino to I/O for RAPID, ABB control
int pressPin = 0; //pressure sensor to Arduino A0
int initReading; //variable for the initial reading,
// of the pressure sensor.
int reading; //variable for storing current pressure
//reading
boolean startUp; //sets up a calibration ‘switch’

int di1Pin = 9; //sends signal to robot controller

void setup()
{
//Serial.begin(9600); //Setup a serial connection for debug.

initReading = 0; //Initialize initReading.
reading = analogRead(pressPin); //Reading equals the value,
//returned by the sensor.
startUp = true; //Initialize the calibration switch to ‘on’
pinMode(di1Pin, OUTPUT); //Pin 9 is set to SEND a signal.

}

void loop()
{
calibrate(); //calls the function defined below

reading = analogRead(pressPin); //Reading equals the value,
//from the sensor
if(reading < initReading*.9) //If reading is less than 90%,
{ //of the initial sensor value,
digitalWrite(di1Pin, HIGH); //send a signal to the controller.
}
else
{
digitalWrite(di1Pin,LOW); //send no signal
}
}

void calibrate() //The first thing to do in the loop,
{
if(startUp == true) //if the calibration switch is on (which it is),
{
initReading = reading; //set initReading equal to the sensor
//value.
startUp = false; //And shut of the calibration switch.
}
}//Arduino to I/O for RAPID, ABB control
int pressPin = 0; //pressure sensor to Arduino A0
int initReading; //variable for the initial reading,
// of the pressure sensor.
int reading; //variable for storing current pressure
//reading
boolean startUp; //sets up a calibration ‘switch’

int di1Pin = 9; //sends signal to robot controller

void setup()
{
//Serial.begin(9600); //Setup a serial connection for debug.

initReading = 0; //Initialize initReading.
reading = analogRead(pressPin); //Reading equals the value,
//returned by the sensor.
startUp = true; //Initialize the calibration switch to ‘on’
pinMode(di1Pin, OUTPUT); //Pin 9 is set to SEND a signal.

code tags use em

So, the thing I need to do is to delete one set of setup and loop function, then it will work?

Did you look up millis() and try to use millis() or do you just want me to write the code for you?

I looked up millis() but I am a bit confused and sucks as I am a beginner. I would like to get this outcome: [Press on pressure sensor for over 10 minutes, then activate vibration motor]. However, I failed even I worked for a whole day...May I get the code from your for reference? Thank you very very very much!!

You want me to write the code for you, correct?

Yes if it is possible. Thank you!

If you are not going to try, I am not going to help but I'm sure someone will be along shortly to write the code for you.

Anyways, here is some code using a cycle count timer, esp_timer_get_time(), that you might use to get a few clues as to how using millis() is done.

void fDoMoistureDetector( void * parameter )
{
  //wait for a mqtt connection
  while ( !MQTTclient.connected() )
  {
    vTaskDelay( 250 );
  }
  int      TimeToPublish = 5000000; //5000000uS
  int      TimeForADreading = 100 * 1000; // 100mS
  uint64_t TimePastPublish = esp_timer_get_time(); // used by publish
  uint64_t TimeADreading   = esp_timer_get_time();
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 10; //delay for 10mS
  float    RemainingMoisture = 100.0f; //prevents pump turn on during start up
  bool     pumpOn = false;
  uint64_t PumpOnTime = esp_timer_get_time();
  int      PumpRunTime = 11000000;
  uint64_t PumpOffWait = esp_timer_get_time();
  uint64_t PumpOffWaitFor = 60000000; //one minute
  float    lowMoisture = 23.0f;
  float    highMoisture = 40.0f;
  for (;;)
  {
    //read AD values every 100mS.
    if ( (esp_timer_get_time() - TimeADreading) >= TimeForADreading )
    {
      xEventGroupSetBits( eg, evtADCreading );
      TimeADreading = esp_timer_get_time();
    }
    xQueueReceive(xQ_RM, &RemainingMoisture, 0 ); //receive queue stuff no waiting
    //read gpio 0 is water level good. Yes: OK to run pump : no pump off.   remaining moisture good, denergize water pump otherwise energize water pump.
    if ( RemainingMoisture >= highMoisture )
    {
      WaterPump0_off();
    }
    if ( !pumpOn )
    {
      log_i( "not pump on ");
      if ( gpio_get_level( GPIO_NUM_0 ) )
      {
        if ( RemainingMoisture <= lowMoisture )
        {
          //has one minute passed since last pump energize, if so then allow motor to run
          if ( (esp_timer_get_time() - PumpOffWait) >= PumpOffWaitFor )
          {
            WaterPump0_on();
            log_i( "pump on " );
            pumpOn = !pumpOn;
            PumpOnTime = esp_timer_get_time();
          }
        }
        //xSemaphoreGive( sema_RemainingMoisture );
      } else {
        log_i( "water level bad " );
        WaterPump0_off();
        PumpOffWait = esp_timer_get_time();
      }
    } else {
      /*
         pump goes on runs for X seconds then turn off, then wait PumpOffWaitTime before being allowed to energize again
      */
      if ( (esp_timer_get_time() - PumpOnTime) >= PumpRunTime )
      {
        log_i( "pump off " );
        WaterPump0_off(); // after 5 seconds turn pump off
        pumpOn = !pumpOn;
        PumpOffWait = esp_timer_get_time();
      }
    }
    // publish to MQTT every 5000000uS
    if ( (esp_timer_get_time() - TimePastPublish) >= TimeToPublish )
    {
      xQueueOverwrite( xQ_RemainingMoistureMQTT, (void *) &RemainingMoisture );// data for mqtt publish
      TimePastPublish = esp_timer_get_time(); // get next publish time
    }
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
  }
  vTaskDelete( NULL );
}// end fDoMoistureDetector()

//Arduino to I/O for RAPID, ABB control
int pressPin = 0; //pressure sensor to Arduino A0
int initReading; //variable for the initial reading,
// of the pressure sensor.
int reading; //variable for storing current pressure
//reading
boolean startUp; //sets up a calibration ‘switch’
uint64_t PumpOnTime = esp_timer_get_time();
int PumpRunTime = 11000000;

int di1Pin = 9; //sends signal to robot controller

void setup()
{
//Serial.begin(9600); //Setup a serial connection for debug.

initReading = 0; //Initialize initReading.
reading = analogRead(pressPin); //Reading equals the value,
//returned by the sensor.
startUp = true; //Initialize the calibration switch to ‘on’
pinMode(di1Pin, OUTPUT); //Pin 9 is set to SEND a signal.

}

void loop()
{
calibrate(); //calls the function defined below

reading = analogRead(pressPin); //Reading equals the value,
//from the sensor
if(reading < initReading*.9) //If reading is less than 90%,
{ //of the initial sensor value,
digitalWrite(di1Pin, HIGH); //send a signal to the controller.
}
else
{
digitalWrite(di1Pin,LOW); //send no signal
}
}

void calibrate() //The first thing to do in the loop,
{
if(startUp == true) //if the calibration switch is on (which it is),
{
initReading = reading; //set initReading equal to the sensor
//value.
startUp = false; //And shut of the calibration switch.
}
}//Arduino to I/O for RAPID, ABB control
int pressPin = 0; //pressure sensor to Arduino A0
int initReading; //variable for the initial reading,
// of the pressure sensor.
int reading; //variable for storing current pressure
//reading
boolean startUp; //sets up a calibration ‘switch’

for (;:wink:
{
//read AD values every 100mS.
if ( (esp_timer_get_time() - TimeADreading) >= TimeForADreading )
{

  TimeADreading = esp_timer_get_time();
}
xQueueReceive(xQ_RM, &RemainingMoisture, 0 ); 
if ( (esp_timer_get_time() - PumpOffWait) >= PumpOffWaitFor )
      {

        PumpOnTime = esp_timer_get_time();
      
  } else {
   
    PumpOffWait = esp_timer_get_time();
  }Preformatted text

is it a correct solution?

No.

note: code tags <<< learn about them.

Since it doesn't even compile/verify then it isn't a correct solution. At least get your code to verify before posting it here or else post all the error messages you get when you try to verify it. You have to make some effort if you want help.

Steve

 //Off-loop:
    bool state_changed = false;
    unsigned long time_in_state = 0;
    unsigned long last_reading = 0;

    //On-loop:
    if (sensorValue > treshold && !state_changed) {
        time_in_state += millis() - last_reading;
        last_reading = millis();
    }
    else {
        state_changed = true;
        time_in_state = 0;
    }

    if (time_in_state > TIME_REQUIRED) {
      digitalWrite (3, HIGH);
    }

I tried something like this. May I know is it a correct flow? Or how to modify it? Thank you!

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