[SOLVED] void loop() doesn't detect button release ?

GeorgeFlorian1
Posts: 160
Joined: Thu Jan 31, 2019 2:32 pm

[SOLVED] void loop() doesn't detect button release ?

Postby GeorgeFlorian1 » Mon Mar 04, 2019 2:18 pm

Hello !

I am trying to start AP mode by pressing for 2.5 seconds on a button and it doesn't work.

I use the following to know when I enter the loop so that I know when should I press the button:
  • digitalWrite(LED, HIGH);
  • delay(2000);
These commands work:
  • pushButton.currentState = digitalRead(pushButton.pin);
  • Serial.println(digitalRead(pushButton.pin));
If I push the button it prints 0, which translates to LOW, meaning that the button is pressed.

The problem is that it doesn't enter if(pushButton.currentState == NOT_PRESSED). This means that it doesn't register when I release the button.
I thought that by keeping the button pressed, it will somehow pause the loop to check how long is the button pressed. But it doesn't. This code only gets to check if the button is pressed.

Do you have any idea on how to fix this ?

Consider apFlag = 2 for the code bellow.

Code: Select all

#define LED 2
#define PRESSED LOW
#define NOT_PRESSED HIGH
const unsigned long longPress = 2500;

typedef struct Buttons {
  const byte pin = 27;
  const int debounce = 10;
  unsigned long counter = 0;
  bool previousState = NOT_PRESSED;
  bool currentState;
} Button;

Button pushButton;
void handleLongPress() {
  apFlag = 1;
  SPIFFS.remove("/inputs.txt");
  startAP();
}

void setup() {  
  Serial.begin(115200);
  delay(2000);
  pinMode(LED, OUTPUT);
  pinMode(pushButton.pin,INPUT_PULLUP);
  digitalWrite(LED,LOW);
}

void loop() {
  digitalWrite(LED, HIGH);
  delay(2000);
  Serial.println((String)"apFlag == " + apFlag);  //--- This outputs 2
  pushButton.currentState = digitalRead(pushButton.pin);
  Serial.println(digitalRead(pushButton.pin));
  if(pushButton.currentState != pushButton.previousState) {
    Serial.println("inside `if(pushButton.currentState != pushButton.previousState)`"); 
    delay(pushButton.debounce);
    pushButton.currentState = digitalRead(pushButton.pin);
    if(pushButton.currentState == PRESSED) {
      pushButton.counter=millis();
      Serial.println("pushButton.counter ");
      Serial.println(pushButton.counter);
      }
    if(pushButton.currentState == NOT_PRESSED) {
      unsigned long currentMillis = millis();
      Serial.println("Press time: "); //--- This doesn't show on the Serial Monitor
      Serial.println(currentMillis - pushButton.counter);
      if(((currentMillis - pushButton.counter) >= longPress) && apFlag == 2) {
        handleLongPress();
      } else if(((currentMillis - pushButton.counter) < longPress) && apFlag == 2) 
      ESP.restart(); 
    }
    pushButton.previousState = pushButton.currentState;
  }
  delay(10000);
  if(apFlag == 2) {ESP.restart();}
}
Last edited by GeorgeFlorian1 on Wed Mar 13, 2019 1:58 pm, edited 1 time in total.

Beowulff
Posts: 17
Joined: Fri Mar 01, 2019 2:59 am

Re: void loop() doesn't detect button release ?

Postby Beowulff » Mon Mar 04, 2019 3:25 pm

You need to loop while the button is pressed, and wait for it to be released.

idahowalker
Posts: 166
Joined: Wed Aug 01, 2018 12:06 pm

Re: void loop() doesn't detect button release ?

Postby idahowalker » Mon Mar 04, 2019 8:29 pm

This statement returns a state: digitalRead(pushButton.pin)

If ( digitalRead(pushButton.pin) )
or
if ( !(digitalRead(pushButton.pin)) ) are valid checks of the pin state.

You can also do:

Code: Select all

void fInterruptReadSPIFFs()
{
  BaseType_t xHigherPriorityTaskWoken;
  if ( (xSemaphoreTakeFromISR(sema_DisplaySPIFF_Info, &xHigherPriorityTaskWoken)) == pdTRUE ) // grab semaphore, no wait
  {
    xEventGroupSetBitsFromISR(eg, evtDisplaySPIFF_Info, &xHigherPriorityTaskWoken);
  }
} //void fInterruptReadSPIFFs()
In setup:

Code: Select all

pinMode ( ReadSPIFF_LogPin, INPUT_PULLUP );
  attachInterrupt(digitalPinToInterrupt(ReadSPIFF_LogPin), fInterruptReadSPIFFs, FALLING);
  xTaskCreatePinnedToCore( fDisplaySPIFF_Info, "fDisplaySPIFF_Info", TaskStack10K1, NULL, Priority4, NULL, TaskCore1 ); // assigned to core 1
  sema_DisplaySPIFF_Info = xSemaphoreCreateBinary();
  xSemaphoreGive ( sema_DisplaySPIFF_Info );
  
Runs:

Code: Select all

void fOpenReadSPIFF_FILE( void *pvParameters )
{
  for ( ;; )
  {
    xEventGroupWaitBits (eg, evtOpenReadSPIFF_FILE, pdTRUE, pdTRUE, portMAX_DELAY );
    if ( SIPFFsGood )
    {
      if ( xSemaphoreTake( sema_SPIFF_Read, xTicksToWait0 ) == pdTRUE ) // grab semaphore and place data
      {
        File file = SPIFFS.open ( SPIFF_FileName );
        while (file.available())
        {
          Serial.write(file.read());
        }
        file.close();
        xSemaphoreGive ( sema_SPIFF_Read );
      }
    }
  }
  vTaskDelete ( NULL );
}

GeorgeFlorian1
Posts: 160
Joined: Thu Jan 31, 2019 2:32 pm

Re: void loop() doesn't detect button release ?

Postby GeorgeFlorian1 » Tue Mar 05, 2019 1:44 pm

idahowalker wrote:
Mon Mar 04, 2019 8:29 pm
This statement returns a state: digitalRead(pushButton.pin)

If ( digitalRead(pushButton.pin) )
or
if ( !(digitalRead(pushButton.pin)) ) are valid checks of the pin state.

You can also do:

Code: Select all

void fInterruptReadSPIFFs()
{
  BaseType_t xHigherPriorityTaskWoken;
  if ( (xSemaphoreTakeFromISR(sema_DisplaySPIFF_Info, &xHigherPriorityTaskWoken)) == pdTRUE ) // grab semaphore, no wait
  {
    xEventGroupSetBitsFromISR(eg, evtDisplaySPIFF_Info, &xHigherPriorityTaskWoken);
  }
} //void fInterruptReadSPIFFs()
In setup:

Code: Select all

pinMode ( ReadSPIFF_LogPin, INPUT_PULLUP );
  attachInterrupt(digitalPinToInterrupt(ReadSPIFF_LogPin), fInterruptReadSPIFFs, FALLING);
  xTaskCreatePinnedToCore( fDisplaySPIFF_Info, "fDisplaySPIFF_Info", TaskStack10K1, NULL, Priority4, NULL, TaskCore1 ); // assigned to core 1
  sema_DisplaySPIFF_Info = xSemaphoreCreateBinary();
  xSemaphoreGive ( sema_DisplaySPIFF_Info );
Runs:

Code: Select all

void fOpenReadSPIFF_FILE( void *pvParameters )
{
  for ( ;; )
  {
    xEventGroupWaitBits (eg, evtOpenReadSPIFF_FILE, pdTRUE, pdTRUE, portMAX_DELAY );
    if ( SIPFFsGood )
    {
      if ( xSemaphoreTake( sema_SPIFF_Read, xTicksToWait0 ) == pdTRUE ) // grab semaphore and place data
      {
        File file = SPIFFS.open ( SPIFF_FileName );
        while (file.available())
        {
          Serial.write(file.read());
        }
        file.close();
        xSemaphoreGive ( sema_SPIFF_Read );
      }
    }
  }
  vTaskDelete ( NULL );
}

After posting the original thread, I re-did the void loop() function and ran into Guru Meditation Error. I posted on GitHub and the reply also featured an ISR (Interrupt Service Routine).

I don't quite understand the syntax used for ISR, but I am reading about it. I started with this example.

After some reading I am starting to understand your take on the problem.
I am beginning to understand why I need an interrupt. I think it's because that's how it's supposed to be done when working with action-specified-by-button.

I would love a breakdown of your code, because it is too complex for me.

Thank you !

idahowalker
Posts: 166
Joined: Wed Aug 01, 2018 12:06 pm

Re: void loop() doesn't detect button release ?

Postby idahowalker » Wed Mar 06, 2019 3:15 am

GeorgeFlorian1 wrote:
Tue Mar 05, 2019 1:44 pm

I would love a breakdown of your code, because it is too complex for me.

Thank you !
Below is a complete working freeRTOS program that I am using, instead of a few code snips. If, after looking it over you got questions, I'll do my best to provide answers.

Code: Select all

#include "esp_system.h" 
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include <CAN_config.h>
#include <ESP32CAN.h>
#include "esp32-hal-ledc.h"
////////////////////////////////////////////////////////////////////////
#define evtCAN_Bus     ( 1 << 1 ) // 1
#define evtServo_Test  ( 1 << 2 ) // 10
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
/* create a hardware timer */
hw_timer_t * timer = NULL;
///////////////////////////////////////////////////////////////////////
/* create event group */
EventGroupHandle_t eg;
///////////////////////////////////////////////////////////////////////
#define TimerDivider 80
#define TaskCore1 1
#define TaskCore0 0
#define OneK 1000
#define TaskStack10K 10000
#define TaskStack10K5 10500
#define TaskStack15K 15000
#define Priority5 5
#define SerialDataBits 115200
#define TIMER_FOUR 3
#define TIMER_WIDTH 16
#define REFRESH_USEC  20000
#define TIMER_FREQUENCY 50
#define InitialServoPositionA 1500
#define Channel_Zero 0
#define Channel_One 1
#define Channel_Two 2
#define Channel_Three 3
#define Channel_Four 4
#define Channel_Five 5
#define Channel_Six 6
#define Channel_Seven 7
#define Channel_Eight 8
#define Channel_Nine 9
#define Channel_Ten 10
#define Channel_Eleven 11
#define Channel_Twleve 12
#define Channel_ZeroPin 23
#define Channel_OnePin 4
#define Channel_TwoPin 12
#define Channel_ThreePin 13
#define Channel_FourPin 14
#define Channel_FivePin 15
#define Channel_SixPin 16
#define Channel_SevenPin 17
#define Channel_EightPin 18
#define Channel_NinePin 19
#define Channel_TenPin 21
#define Channel_ElevenPin 22
#define Channel_12Pin 2
///////////////////////////////////////////////////////////////////////
TickType_t xTicksToWait0 = 0;
TickType_t xTicksToWait3ms = pdMS_TO_TICKS( 3 );
TickType_t QueueReceiveDelayTime = 20;
TickType_t xTicksToWait20 = 20;
TickType_t xSemaphoreTicksToWait30 = 30;
TickType_t xSemaphoreTicksToWait10 = 10;
///////////////////////////////////////////////////////////////////////
CAN_device_t CAN_cfg;
///////////////////////////////////////////////////////////////////////
QueueHandle_t xQ_ServoTorqueInfo;
struct stu_ServoTorqueInfo
{
  int sServo = 0;
  int d1 = 0;
  int d2 = 0;
  int d3 = 0;
  int d4 = 0;
} x_SERVO_INFO;
const int asciiA = 65;
const int asciiB = 66;
const int asciiC = 67;
const int asciiD = 68;
const int asciiE = 69;
const int asciiF = 70;
const int asciiG = 71;
const int asciiH = 72;
const int asciiI = 73;
const int asciiJ = 74;
const int asciiK = 75;
const int asciiL = 76;
bool EOT = true;
struct stuSERVO_ACK
{
  int MsgID = 2;
  int DLC = 8;
  char Servo_ACK = '6';
  char p4 = '0';
} xServo_ACK;
///////////////////////////////////////////////////////////////////////
float timer_width_ticks = pow( 2, TIMER_WIDTH );
///////////////////////////////////////////////////////////////////////
SemaphoreHandle_t sema_CAN_Bus;
SemaphoreHandle_t sema_SERVO_Info;
///////////////////////////////////////////////////////////////////////
////// Recommended servo pins include 2,4,12-19,21-23,25-27,32-33
/*
** ledc: 0  => Group: 0, Channel: 0, Timer: 0
** ledc: 1  => Group: 0, Channel: 1, Timer: 0
** ledc: 2  => Group: 0, Channel: 2, Timer: 1
** ledc: 3  => Group: 0, Channel: 3, Timer: 1
** ledc: 4  => Group: 0, Channel: 4, Timer: 2
** ledc: 5  => Group: 0, Channel: 5, Timer: 2
** ledc: 6  => Group: 0, Channel: 6, Timer: 3
** ledc: 7  => Group: 0, Channel: 7, Timer: 3
** ledc: 8  => Group: 1, Channel: 8, Timer: 0
** ledc: 9  => Group: 1, Channel: 9, Timer: 0
** ledc: 10 => Group: 1, Channel: 10, Timer: 1
** ledc: 11 => Group: 1, Channel: 11, Timer: 1
** ledc: 12 => Group: 1, Channel: 12, Timer: 2
** ledc: 13 => Group: 1, Channel: 13, Timer: 2
** ledc: 14 => Group: 1, Channel: 14, Timer: 3
** ledc: 15 => Group: 1, Channel: 15, Timer: 3
*/
///////////////////////////////////////////////////////////////////////
// timer ISR callback set at 1000X a second
void IRAM_ATTR onTimer()
{
  BaseType_t xHigherPriorityTaskWoken;
  //  iTicCount++;
  xEventGroupSetBitsFromISR(eg, evtCAN_Bus, &xHigherPriorityTaskWoken); //
} // void IRAM_ATTR onTimer()
///////////////////////////////////////////////////////////////////////
void setup()
{
  Serial.begin( SerialDataBits );
  eg = xEventGroupCreate();
  /* set CAN pins, baudrate start can module */
  CAN_cfg.speed = CAN_SPEED_1000KBPS;
  CAN_cfg.tx_pin_id = GPIO_NUM_5; // green wire
  CAN_cfg.rx_pin_id =  GPIO_NUM_34; // white wire
  CAN_cfg.rx_queue = xQueueCreate(3, sizeof(CAN_frame_t));
  ESP32Can.CANInit();
  ledcSetup ( Channel_Zero, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_ZeroPin, Channel_Zero );   //
  ledcWrite (Channel_Zero, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_One, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_OnePin, Channel_One );   //
  ledcWrite (Channel_One, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_Two, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_TwoPin, Channel_Two );   //
  ledcWrite (Channel_Two, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_Three, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_ThreePin, Channel_Three );   //
  ledcWrite (Channel_Three, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_Four, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_FourPin, Channel_Four );   //
  ledcWrite (Channel_Four, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_Five, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_FivePin, Channel_Five );   //
  ledcWrite (Channel_Five, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_Six, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_SixPin, Channel_Six );   //
  ledcWrite (Channel_Six, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_Seven, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_SevenPin, Channel_Seven );   //
  ledcWrite (Channel_Seven, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_Eight, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_EightPin, Channel_Eight );   //
  ledcWrite (Channel_Eight, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_Nine, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_NinePin, Channel_Nine );   //
  ledcWrite (Channel_Nine, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_Ten, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_TenPin, Channel_Ten );   //
  ledcWrite (Channel_Ten, usToTicks ( 0 ) );       //
  ///////////////
  ledcSetup ( Channel_Eleven, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_ElevenPin, Channel_Eleven );   //
  ledcWrite (Channel_Eleven, usToTicks ( 0 ) );       //
  ////////////////////////////////////////////////////////
  ledcSetup ( Channel_Twleve, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( Channel_12Pin, Channel_Twleve );   //
  ledcWrite ( 12, usToTicks ( 0 ) );
  ////////////////////////////////////////////////////////
  xQ_ServoTorqueInfo = xQueueCreate ( 1 , sizeof(stu_ServoTorqueInfo) );
  /////////////////////////// TASK CORE 0
  xTaskCreatePinnedToCore ( Servo_Test, "Servo_Test", TaskStack10K5, NULL, Priority5, NULL, TaskCore0 ); // assigned to core
  sema_SERVO_Info = xSemaphoreCreateBinary();
  xSemaphoreGive ( sema_SERVO_Info );
  //////////////////////////////// TASK CORE 1 ///////////////////////////////////////////////////////////////////////////////////////////////////
  xTaskCreatePinnedToCore ( fCAN_Receive, "fCAN_Receive", TaskStack15K, NULL, Priority5, NULL, TaskCore1 ); // assigned to core
  sema_CAN_Bus = xSemaphoreCreateBinary();
  xSemaphoreGive ( sema_CAN_Bus );
  /////////////////////////////////////////////////////
  timer = timerBegin( TIMER_FOUR, TimerDivider, true );
  timerAttachInterrupt( timer, &onTimer, true );
  timerAlarmWrite(timer, OneK, true);
  timerAlarmEnable(timer);
  ////////////////////////////////////////
} // void setup()
///////////////////////////////////////////////////////////////////////
void loop() {}
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
void fLED_off ()
{
  ledcWrite (Channel_Zero, 0 );
  ledcWrite (Channel_One, 0 );
  ledcWrite (Channel_Two, 0 );
  ledcWrite (Channel_Three, 0 );
  ledcWrite (Channel_Four, 0 );
  ledcWrite (Channel_Five, 0 );
  ledcWrite (Channel_Six, 0 );
  ledcWrite (Channel_Seven, 0 );
  ledcWrite (Channel_Eight, 0 );
  ledcWrite (Channel_Nine, 0 );
  ledcWrite (Channel_Ten, 0 );
  ledcWrite (Channel_Eleven, 0 );
}
///////////////////////////////////////////////////////////////////////
void Servo_Test ( void *pvParameters )
{
  stu_ServoTorqueInfo pxServo_Info;
  for ( ;;)
  {
    xEventGroupWaitBits ( eg, evtServo_Test, pdTRUE, pdTRUE, portMAX_DELAY ) ;
    if ( xSemaphoreTake( sema_SERVO_Info, xSemaphoreTicksToWait30 ) == pdTRUE ) // grab semaphore wait
    {
      xQueueReceive( xQ_ServoTorqueInfo, &pxServo_Info, QueueReceiveDelayTime );
      ledcWrite ( Channel_Twleve, usToTicks ( 2500 ) );
      int t = pxServo_Info.d4;
      t = t + (pxServo_Info.d3 * 10);
      t =  t + (pxServo_Info.d2 * 100);
      t =  t + (pxServo_Info.d1 * 1000);
      // Serial.print ( pxServo_Info.sServo );
      // Serial.print ( " , " );
      // Serial.print ( t );
      //      Serial.print ( " , " );
      //      Serial.print ( t );
      // Serial.println();
      if ( t != 0 )
      {
        t = usToTicks ( t );
        switch ( pxServo_Info.sServo )
        {
          case asciiA:
            ledcWrite (Channel_Zero, t );
            // Serial.println ( " asciiA " );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            break;
          case asciiB:
            ledcWrite (Channel_One, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiB " );
            break;
          case asciiC:
            ledcWrite (Channel_Two, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiC " );
            break;
          case asciiD:
            ledcWrite (Channel_Three, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiD " );
            break;
          case asciiE:
            ledcWrite (Channel_Four, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiE " );
            break;
          case asciiF:
            ledcWrite (Channel_Five, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiF " );
            break;
          case asciiG:
            ledcWrite (Channel_Six, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiG " );
            break;
          case asciiH:
            ledcWrite (Channel_Seven, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiH " );
            break;
          case asciiI:
            ledcWrite (Channel_Eight, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiI " );
            break;
          case asciiJ:
            ledcWrite (Channel_Nine, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiJ " );
            break;
          case asciiK:
            ledcWrite (Channel_Ten, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiK " );
            break;
          case asciiL:
            ledcWrite (Channel_Eleven, t );
            vTaskDelay( pdMS_TO_TICKS( 10 ) );
            // Serial.println ( " asciiL " );
            break;
        }
        vTaskDelay( pdMS_TO_TICKS( 20 ) );
      }
      ledcWrite ( Channel_Twleve, usToTicks ( 0 ) );
      xSemaphoreGive ( sema_SERVO_Info );
    }
  }
  vTaskDelete ( NULL );
}
///////////////////////////////////////////////////////////////////////
int usToTicks(int usec)
{
  return (int)((float)usec / ((float)REFRESH_USEC / (float)timer_width_ticks) * (((float)TIMER_FREQUENCY) / 50.0));
} // int usToTicks(int usec)
///////////////////////////////////////////////////////////////////////
void fCAN_Receive ( void *pvParameters )
{
  CAN_frame_t rx_frame;
  char Current_RCVD[9];
  char Past_RCVD[9];
  for ( ;; )
  {
    xEventGroupWaitBits (eg, evtCAN_Bus, pdTRUE, pdTRUE, portMAX_DELAY) ;
    //Serial.println ( "fCAN_Receive" );
    if ( xSemaphoreTake( sema_CAN_Bus, xTicksToWait0 ) == pdTRUE ) // grab semaphore no wait
    {
      ledcWrite ( Channel_Twleve, usToTicks ( 2500 ) );
       // Serial.println ( "fCAN_Receive 2" );
      // if (xQueueReceive(CAN_cfg.rx_queue, &rx_frame, 3 * portTICK_PERIOD_MS) == pdTRUE)
      if ( (CAN_cfg.rx_queue != NULL) && (uxQueueMessagesWaiting(CAN_cfg.rx_queue)) ) // if queue not null and something is waiting in queue
      {
        Serial.println ( "fCAN_Receive 3" );
        while ( uxQueueMessagesWaiting(CAN_cfg.rx_queue) > 0 )
        {
          if (xQueueReceive(CAN_cfg.rx_queue, &rx_frame, xTicksToWait0) == pdTRUE)
          {
            ledcWrite ( Channel_Twleve, usToTicks ( 0 ) );
            // Serial.println ( " received queue" );
            // ledcWrite (Channel_Ten, usToTicks ( InitialServoPositionA ) );
            if ( rx_frame.MsgID == 1 )
            {
              ledcWrite ( Channel_Twleve, usToTicks ( 2500 ) );
              // Serial.println ( " MsgId OK");
              // ledcWrite (Channel_Nine, usToTicks ( InitialServoPositionA ) );
              if ( rx_frame.data.u8[0] != '6' )
              {
                // Serial.println ( "not 6" );
                if ( rx_frame.data.u8[0] != '3')
                {
                  // Serial.println ( "not 3 ");
                  if ( EOT == false )
                  {
                    ledcWrite ( Channel_Twleve, usToTicks ( 0 ) );
                    x_SERVO_INFO.sServo = rx_frame.data.u8[0];
                    x_SERVO_INFO.d1 = String(char(rx_frame.data.u8[1])).toInt();
                    x_SERVO_INFO.d2 = String(char(rx_frame.data.u8[2])).toInt();
                    x_SERVO_INFO.d3 = String(char(rx_frame.data.u8[3])).toInt();
                    x_SERVO_INFO.d4 = String(char(rx_frame.data.u8[4])).toInt();
                    Current_RCVD[0] =  (char)x_SERVO_INFO.sServo;
                    Current_RCVD[1] = (char)x_SERVO_INFO.d1;
                    Current_RCVD[2] = (char)x_SERVO_INFO.d2;
                    Current_RCVD[3] = (char)x_SERVO_INFO.d3;
                    Current_RCVD[4] = (char)x_SERVO_INFO.d4;
                    // comapre with last received and process if different
                     if ( strcmp ( Current_RCVD,  Past_RCVD ) != 0 )
                     {
//                    Serial.print ( "message begin" );
//                    Serial.print ( ", " );
//                    Serial.print ( rx_frame.data.u8[0] );
//                    Serial.print ( ", " );
//                    Serial.print ( rx_frame.data.u8[1] );
//                    Serial.print ( ", " );
//                    Serial.print ( rx_frame.data.u8[2] );
//                    Serial.print ( ", " );
//                    Serial.print ( rx_frame.data.u8[3] );
//                    Serial.print ( ", " );
//                    Serial.print ( rx_frame.data.u8[4] );
//                    Serial.println ( " message end" );
                    xQueueSend( xQ_ServoTorqueInfo, (void *) &x_SERVO_INFO, xTicksToWait20 );
                    xEventGroupSetBits( eg, evtServo_Test );
                     }
                     strcpy ( Past_RCVD, Current_RCVD ); 
                  }
                } //
              }
              if (rx_frame.data.u8[0] = '3')
              {
//                fLED_off();
                // got a 51 initiate a ACK acknoledge
                EOT = true;
                //                Serial.println ( "got EOT!" );
                ledcWrite ( Channel_Twleve, usToTicks ( 2500 ) );
                vTaskDelay( pdMS_TO_TICKS( 15 ) );
                ledcWrite ( Channel_Twleve, usToTicks ( 0 ) );
                // Serial.println ( "EOT ready" );
                // let control know servo_control is ready
                rx_frame.FIR.B.FF = CAN_frame_std;
                rx_frame.MsgID = xServo_ACK.MsgID;
                rx_frame.FIR.B.DLC = xServo_ACK.DLC;
                rx_frame.data.u8[0] = xServo_ACK.Servo_ACK; // 54
                rx_frame.data.u8[1] = xServo_ACK.p4;
                rx_frame.data.u8[2] = xServo_ACK.p4;
                rx_frame.data.u8[3] = xServo_ACK.p4;
                rx_frame.data.u8[4] = xServo_ACK.p4;
                rx_frame.data.u8[5] = xServo_ACK.p4;
                rx_frame.data.u8[6] = xServo_ACK.p4;
                rx_frame.data.u8[7] = xServo_ACK.p4;
                ESP32Can.CANWriteFrame(&rx_frame);
                //                Serial.println ( "sent eot ack" );
              }
              if (rx_frame.data.u8[0] = '6')
              {
                // got a 54 a ACK
                EOT = false;
                //                Serial.println ( "got ack!" );
                ledcWrite ( Channel_Twleve, usToTicks ( 2500 ) );
                vTaskDelay( pdMS_TO_TICKS( 15 ) );
                ledcWrite ( Channel_Twleve, usToTicks ( 0 ) );
                // Serial.println ( "ready" );
                // let control know servo_control is ready
                rx_frame.FIR.B.FF = CAN_frame_std;
                rx_frame.MsgID = xServo_ACK.MsgID;
                rx_frame.FIR.B.DLC = xServo_ACK.DLC;
                rx_frame.data.u8[0] = xServo_ACK.Servo_ACK; // 54
                rx_frame.data.u8[1] = xServo_ACK.p4;
                rx_frame.data.u8[2] = xServo_ACK.p4;
                rx_frame.data.u8[3] = xServo_ACK.p4;
                rx_frame.data.u8[4] = xServo_ACK.p4;
                rx_frame.data.u8[5] = xServo_ACK.p4;
                rx_frame.data.u8[6] = xServo_ACK.p4;
                rx_frame.data.u8[7] = xServo_ACK.p4;
                ESP32Can.CANWriteFrame(&rx_frame);
                // Serial.println ( "sent ack" );
              } // else
            } //  if ( rx_frame.MsgID == 1 )
          } // if (xQueueReceive(CAN_cfg.rx_queue, &rx_frame, xTicksToWait0) == pdTRUE)
        } //  while ( uxQueueMessagesWaiting(CAN_cfg.rx_queue) > 0 )
      } // if ( (CAN_cfg.rx_queue != NULL) && (uxQueueMessagesWaiting(CAN_cfg.rx_queue)) )
      xSemaphoreGive ( sema_CAN_Bus );
      //
      //       Serial.print( "fCAN_Receive " );
      //      Serial.print(uxTaskGetStackHighWaterMark( NULL ));
      //      Serial.println();
      //      Serial.flush();
    } // if ( xSemaphoreTake( sema_CAN_Bus, xTicksToWait0 ) == pdTRUE ) // grab semaphore no wait
  } // for ( ;; )
  vTaskDelete ( NULL );
} // void fCAN_Receive ( void *pvParameters )
///////////////////////////////////////////////////////////////////////

idahowalker
Posts: 166
Joined: Wed Aug 01, 2018 12:06 pm

Re: void loop() doesn't detect button release ?

Postby idahowalker » Wed Mar 06, 2019 7:08 pm

To the original issue, if you need to detect button press and button release, use 2 interrupts. One interrupt to detect the button press, and the other to detect the button release.

GeorgeFlorian1
Posts: 160
Joined: Thu Jan 31, 2019 2:32 pm

Re: void loop() doesn't detect button release ?

Postby GeorgeFlorian1 » Mon Mar 11, 2019 10:05 am

idahowalker wrote:
Wed Mar 06, 2019 7:08 pm
To the original issue, if you need to detect button press and button release, use 2 interrupts. One interrupt to detect the button press, and the other to detect the button release.
Thank you !
I've learned how to use it by trial and error and changed the concept since then.

Who is online

Users browsing this forum: No registered users and 57 guests