Programming the board

This week was a really big week for me because I was finally able to get the board to communicate with me via LED blinks and a button! My idea was to get the LED to flash based on the number of times I pressed the button.

This involved creating some sort of state machine, as shown below:

There are a total of four states:

State 0, IDLE (essentially our counting state): initially, we are at count = 0, and each time the button is pressed (importantly, not released), we then transition to the PRESSED state.

State 1, PRESSED: this is a transition state. Once the button is released, we immediately transition to the TIMER state. This state is necessary because we only want to increment the counter after the button is pressed AND released.

State 2, TIMER: using a timer, we see if the button is pressed in < timeout. If it is (aka, the button presses are in relatively short succession to one another), we transition back to the PRESSED state and increment our counter. If it isn't (aka, there has been a long pause/break with no button presses), we transition to the FLASH state.

State 3, FLASH (essentially, displaying our count information): here, we go through a blcoking loop of flashing the LED high and low for the total number of times the button has been pressed. Once it has finished flashing, the count will reset and we will return to the IDLE state of our state machine.

An essential step in coding this was making a debouncing function. Pushbuttons generate wonky open/close transitions when pressed due to mechanical and physical issues. Thus, we need to check if the button has really been pressed or if it is simply bouncing between two states and incrementing our count incorrectly (e.g. we only pressed the button twice, but the count is already at 3 or 4). This was done by using a state machine design as well.

I was finally able to upload the code to my device after some trial and error. Initially, I was using the updated Arduino version, but that threw some wonky errors such as : "UPLOAD ERROR: ERROR: 2 UNKNOWN: CANNOT GET PROGRAMMER TOOL: UNDEFINED 'UPLOAD.TOOL' PROPERTY"

Here is a photo of the lit up LED! whoop whoop :)

Here is a youtube video with the demo: https://youtube.com/shorts/v6y7aD3oLZo

Here is the code:



const uint8_t IDLE = 0; 
const uint8_t PRESSED = 1; 
const uint8_t TIMER = 2; 
const uint8_t GET = 3;

//Bouncing controls
const uint8_t UNPUSHED = 1;
const uint8_t PUSHED = 0;
const uint8_t DB_COUNT_THRESHOLD = 100;
uint8_t db_state;
uint8_t db_count;

//Some constants and some resources:
const int BUTTON_TIMEOUT = 1000; //button timeout in milliseconds

const int BUTTON = 14; //pin connected to button 
const int LED = 15;
uint8_t state;  //system state (feel free to use)
uint8_t num_count; //variable for storing the number of times the button has been pressed before timeout
unsigned long timer;  //used for storing millis() readings.

void setup(){
  pinMode(BUTTON, INPUT_PULLUP); //set input pin as an input!
  state = IDLE; //start system in IDLE state!
  pinMode(LED, OUTPUT);

  //initialize num_count
  num_count = 0;

  db_state = UNPUSHED; //start bouncing system as unpushed
  db_count = 0;
}

void loop(){
  number_fsm(db_button(digitalRead(BUTTON))); //Call our FSM every time through the loop.
}

// Bouncing State
uint8_t db_button(uint8_t input){
  if (input != db_state){ //if button state changed
    db_count++; //increment
    if (db_count > DB_COUNT_THRESHOLD){ //only when button count exceeds threshold does button state change
      db_state = !db_state;
    }
  } else {
    db_count = 0;
  }
  return db_state;
}


/*------------------
 * number_fsm Function:
 * It takes in an input (the reading from a switch), and can use
 * state as well as other variables to be your state machine.
 */

void number_fsm(uint8_t input){
  //your logic here!
  //use your inputs and the system's state to update state and perform actions
  //This function should be non-blocking, meaning there should be minimal while loops and other things in it!
  //Feel free to call do_http_GET from this function
  //state variable globally defined at top
  switch(state){
    case IDLE:
      if (!input){ //button pressed
        state = PRESSED;
        num_count = num_count +1;
      } else {
        // Serial.println("IDLE state");
      }
      break; //don't forget break statements
    case PRESSED:
      //another state...etc...
      //do logic here 
      if (input) { //button released
        state = TIMER;
        timer = millis();
        Serial.println("Released, transitioning from PRESSED to TIMER");
      } else {
        // Serial.println("Pressed state");
      }
      break;
    case TIMER:
      if (((millis() - timer) <= BUTTON_TIMEOUT) && (!input)) { //button pressed within timeout
          num_count = num_count + 1;
          state = PRESSED;

      } else if ((millis() - timer) > BUTTON_TIMEOUT){ //button pressed but not within timeout, or button not pressed at all within timeout
          state = GET;
          timer = millis();
      } 
      break;
    case GET:
      //another state!
      for (int i = 0; i < num_count; i++){
        digitalWrite(LED, HIGH);
        delay(200);
        digitalWrite(LED, LOW);
        delay(100);
      }
      num_count = 0;
      state = IDLE;
      break;
  }
}



  

Phone

(203) 507-0590 x12387